3 #include <fontconfig/fontconfig.h>
13 static FT_Library lib;
23 if(!FcInit() || (fc=FcInitLoadConfigAndFonts()) == NULL) {
24 fprint(2, "fontconfig initialization failed\n");
25 exits("fontconfig failed");
28 e = FT_Init_FreeType(&lib);
30 fprint(2, "freetype initialization failed: %d\n", e);
31 exits("freetype failed");
34 sysfonts = FcConfigGetFonts(fc, FcSetSystem);
36 xfont = emalloc9p(sysfonts->nfont*sizeof xfont[0]);
37 memset(xfont, 0, sysfonts->nfont*sizeof xfont[0]);
38 for(i=0; i<sysfonts->nfont; i++) {
39 FcChar8 *fullname, *fontfile;
41 FcPattern *pat = sysfonts->fonts[i];
43 if(FcPatternGetString(pat, FC_POSTSCRIPT_NAME, 0, &fullname) != FcResultMatch ||
44 FcPatternGetString(pat, FC_FILE, 0, &fontfile) != FcResultMatch ||
45 FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
48 xfont[nxfont].name = strdup((char*)fullname);
49 xfont[nxfont].fontfile = strdup((char*)fontfile);
50 xfont[nxfont].index = index;
54 FcFontSetDestroy(sysfonts);
69 e = FT_New_Face(lib, f->fontfile, f->index, &face);
71 fprint(2, "load failed for %s (%s) index:%d\n", f->name, f->fontfile, f->index);
74 if(!FT_IS_SCALABLE(face)) {
75 fprint(2, "%s is a non scalable font, skipping\n", f->name);
80 f->unit = face->units_per_EM;
81 f->height = (int)((face->ascender - face->descender) * 1.35);
82 f->originy = face->descender * 1.35; // bbox.yMin (or descender) is negative, because the baseline is y-coord 0
84 for(charcode=FT_Get_First_Char(face, &glyph_index); glyph_index != 0;
85 charcode=FT_Get_Next_Char(face, charcode, &glyph_index)) {
87 int idx = charcode/SubfontSize;
89 if(charcode > Runemax)
97 // libdraw expects U+0000 to be present
102 for(i=0; i<nelem(f->range); i++)
104 f->file[f->nfile++] = i;
110 mksubfont(XFont *xf, char *name, int lo, int hi, int size, int antialias)
114 Memimage *m, *mc, *m1;
120 //Point rect_points[4];
122 e = FT_New_Face(lib, xf->fontfile, xf->index, &face);
124 fprint(2, "load failed for %s (%s) index:%d\n", xf->name, xf->fontfile, xf->index);
128 e = FT_Set_Char_Size(face, 0, size<<6, dpi, dpi);
130 fprint(2, "FT_Set_Char_Size failed\n");
135 pixel_size = (dpi*size)/72.0;
136 w = x = (int)((face->max_advance_width) * pixel_size/xf->unit + 0.99999999);
137 y = (int)((face->ascender - face->descender) * pixel_size/xf->unit + 0.99999999);
138 y0 = (int)(-face->descender * pixel_size/xf->unit + 0.99999999);
140 m = allocmemimage(Rect(0, 0, x*(hi+1-lo)+1, y+1), antialias ? GREY8 : GREY1);
145 mc = allocmemimage(Rect(0, 0, x+1, y+1), antialias ? GREY8 : GREY1);
151 memfillcolor(m, DBlack);
152 memfillcolor(mc, DBlack);
153 fc = malloc((hi+2 - lo) * sizeof fc[0]);
154 sf = malloc(sizeof *sf);
155 if(fc == nil || sf == nil) {
165 //rect_points[0] = mc->r.min;
166 //rect_points[1] = Pt(mc->r.max.x, mc->r.min.y);
167 //rect_points[2] = mc->r.max;
168 //rect_points[3] = Pt(mc->r.min.x, mc->r.max.y);
171 for(i=lo; i<=hi; i++, fc++) {
175 memfillcolor(mc, DBlack);
179 fc->bottom = Dy(m->r);
181 k = FT_Get_Char_Index(face, i);
183 e = FT_Load_Glyph(face, k, FT_LOAD_RENDER|FT_LOAD_NO_AUTOHINT|(antialias ? 0:FT_LOAD_TARGET_MONO));
185 if(e || face->glyph->advance.x <= 0) {
189 drawpjw(m, fc, x, w, y, y - y0);
195 FT_Bitmap *bitmap = &face->glyph->bitmap;
196 uchar *base = byteaddr(mc, mc->r.min);
197 advance = (face->glyph->advance.x+32) >> 6;
199 for(r=0; r < bitmap->rows; r++)
200 memmove(base + r*mc->width*sizeof(u32int), bitmap->buffer + r*bitmap->pitch, bitmap->pitch);
202 memimagedraw(m, Rect(x, 0, x + advance, y), mc,
203 Pt(-face->glyph->bitmap_left, -(y - y0 - face->glyph->bitmap_top)),
210 #ifdef DEBUG_FT_BITMAP
211 for(r=0; r < bitmap->rows; r++) {
213 uchar *span = bitmap->buffer+(r*bitmap->pitch);
214 for(c = 0; c < bitmap->width; c++) {
215 fprint(1, "%02x", span[c]);
221 #ifdef DEBUG_9_BITMAP
222 for(r=0; r < mc->r.max.y; r++) {
224 uchar *span = base+(r*mc->width*sizeof(u32int));
225 for(c = 0; c < Dx(mc->r); c++) {
226 fprint(1, "%02x", span[c]);
234 // round up to 32-bit boundary
235 // so that in-memory data is same
236 // layout as in-file data.
245 m1 = allocmemimage(Rect(0, 0, x, y), antialias ? GREY8 : GREY1);
246 memimagedraw(m1, m1->r, m, m->r.min, memopaque, ZP, S);
252 sf->height = Dy(m1->r);
253 sf->ascent = Dy(m1->r) - y0;