164 lines
5.2 KiB
D
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|