dst/source/patch/font2.d
2025-06-26 13:47:07 -05:00

164 lines
5.2 KiB
D

module patch.font2;
import std.conv : to;
import std.string : toStringz;
import patches : isPatchEnabled;
import config : font2;
import st : xw, xrealloc, die;
import xft_types : XftFont;
import deimos.X11.Xlib : Display;
// Import font cache variables from x module
import x : Fontcache, frc, frclen, frccap, defaultfontsize, usedfontsize;
enum FRC_NORMAL = 0;
enum FRC_ITALIC = 1;
enum FRC_BOLD = 2;
enum FRC_ITALICBOLD = 3;
// External C declarations for Xft and fontconfig functions
extern(C) {
struct FcPattern;
alias FcChar8 = ubyte;
// FcResult as an enum
enum FcResult {
FcResultMatch = 0,
FcResultNoMatch,
FcResultTypeMismatch,
FcResultNoId,
FcResultOutOfMemory
}
// Xft functions
XftFont* XftFontOpenPattern(Display*, FcPattern*);
FcPattern* XftXlfdParse(const(char)*, int, int);
void XftDefaultSubstitute(Display*, int, FcPattern*);
static if (isPatchEnabled!"USE_XFTFONTMATCH_PATCH") {
FcPattern* XftFontMatch(Display*, int, FcPattern*, FcResult*);
}
// Fontconfig functions
void FcPatternDestroy(FcPattern*);
FcPattern* FcNameParse(const(FcChar8)*);
int FcPatternGetDouble(FcPattern*, const(char)*, int, double*);
int FcPatternDel(FcPattern*, const(char)*);
int FcPatternAddDouble(FcPattern*, const(char)*, double);
int FcPatternAddBool(FcPattern*, const(char)*, int);
int FcPatternAddInteger(FcPattern*, const(char)*, int);
void FcConfigSubstitute(void*, FcPattern*, int);
FcPattern* FcFontMatch(void*, FcPattern*, FcResult*);
// Constants
enum FC_PIXEL_SIZE = "pixelsize";
enum FC_SIZE = "size";
enum FC_SCALABLE = "scalable";
enum FC_SLANT = "slant";
enum FC_WEIGHT = "weight";
enum FC_SLANT_ITALIC = 100;
enum FC_SLANT_ROMAN = 0;
enum FC_WEIGHT_BOLD = 200;
enum FcResultMatch = 0;
enum FcMatchPattern = 0;
}
static if (isPatchEnabled!"FONT2_PATCH") {
int xloadsparefont(FcPattern* pattern, int flags) {
FcPattern* match;
FcResult result;
static if (isPatchEnabled!"USE_XFTFONTMATCH_PATCH") {
match = XftFontMatch(xw.dpy, xw.scr, pattern, &result);
} else {
match = FcFontMatch(null, pattern, &result);
}
if (!match) {
return 1;
}
frc[frclen].font = XftFontOpenPattern(xw.dpy, match);
if (!frc[frclen].font) {
FcPatternDestroy(match);
return 1;
}
frc[frclen].flags = flags;
frc[frclen].unicodep = 0;
frclen++;
return 0;
}
void xloadsparefonts() {
FcPattern* pattern;
double fontval;
int fc;
if (frclen != 0)
die("can't embed spare fonts. cache isn't empty");
fc = cast(int)font2.length;
if (fc == 0)
return;
if (frccap < 4 * fc) {
frccap += 4 * fc - frccap;
frc = cast(Fontcache*)xrealloc(frc, frccap * Fontcache.sizeof);
}
foreach (i, fp; font2) {
if (fp[0] == '-')
pattern = XftXlfdParse(fp.toStringz, 0, 0);
else
pattern = FcNameParse(cast(FcChar8*)fp.toStringz);
if (!pattern)
die("can't open spare font %s\n", fp.toStringz);
if (defaultfontsize > 0 && defaultfontsize != usedfontsize) {
if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) ==
FcResultMatch) {
fontval *= usedfontsize / defaultfontsize;
FcPatternDel(pattern, FC_PIXEL_SIZE);
FcPatternDel(pattern, FC_SIZE);
FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval);
} else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) ==
FcResultMatch) {
fontval *= usedfontsize / defaultfontsize;
FcPatternDel(pattern, FC_PIXEL_SIZE);
FcPatternDel(pattern, FC_SIZE);
FcPatternAddDouble(pattern, FC_SIZE, fontval);
}
}
FcPatternAddBool(pattern, FC_SCALABLE, 1);
static if (!isPatchEnabled!"USE_XFTFONTMATCH_PATCH") {
FcConfigSubstitute(null, pattern, FcMatchPattern);
XftDefaultSubstitute(xw.dpy, xw.scr, pattern);
}
if (xloadsparefont(pattern, FRC_NORMAL))
die("can't open spare font %s\n", fp.toStringz);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
if (xloadsparefont(pattern, FRC_ITALIC))
die("can't open spare font %s\n", fp.toStringz);
FcPatternDel(pattern, FC_WEIGHT);
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
if (xloadsparefont(pattern, FRC_ITALICBOLD))
die("can't open spare font %s\n", fp.toStringz);
FcPatternDel(pattern, FC_SLANT);
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
if (xloadsparefont(pattern, FRC_BOLD))
die("can't open spare font %s\n", fp.toStringz);
FcPatternDestroy(pattern);
}
}
}