hi, I vote for adding embeddedbitmap option to official fontconfig. Several distros have shiped patched version of fontconfig which adds an option like rh_prefer_bitmap or embeddedbitmap. Because we need a way to explictly tell Xft/Cairo to load bitmaps embedded in fonts or not. And for cairo, if i want to cairo transform a font to pretend as an oblique one, and when i disable antialias for the font, then cairo will always load embedded bitmaps if available, latter cairo(exactly to say it's freetype) will be unable to transform the font glyphs because they are bitmaps. If option embeddedbitmap is available, we can tell freetype to load outlines rather than embedded bitmaps by set embeddedbitmap to false and then can transform font glyphs as expected. Xft is smart enough in this case, it add FC_LOAD_NO_BITMAP to load flags when loading glyphs. But that is not easily to implement in cairo, because cairo doesn't handle FC_MATRIX itself. Mike FABIAN wrote: > For details please see > > http://bugzilla.novell.com/show_bug.cgi?id=118727 > > This patch makes two small changes to the rule for artificial > emboldening in /etc/fonts/fonts.conf: > > 1) > don't check for "weight >= 200" but for "weight > 100", > i.e. instead of > > <!-- check to see if the pattern requests bold --> > <test target="pattern" name="weight" compare="more_eq"> > <int>200</int> > </test> > > use > > <!-- check to see if the pattern requests bold --> > <test target="pattern" name="weight" compare="more"> > <int>100</int> > </test> > > This is necessary to make <strong>foo</strong> appear bold > in firefox. When checking "weight >= 200", emboldening will work for > > <span style="font-weight:bold;">foo</span> > > in firefox but not for <strong>foo</strong> > > (To make it a better readable I used "<const>medium</const>" > instead of "<int>100</int>". This makes no functional difference > it only enhances the readability). > > 2) > in addition to setting "embolden" to "true", also set > "weight" to "bold", i.e. add: > > <!-- > set weight to bold > needed for applications using Xft directly, e.g. Firefox, ... > --> > <edit name="weight" mode="assign"> > <const>bold</const> > </edit> > > to the rule. This is necessary to make artificial emboldening > work in applications who do no (yet) use cairo but use > Xft directly[1] > > Footnotes: > [1] to make this work Xft needs to have the patch for embedded bitmap > support and artificial emboldening applied which I attach here as well > for reference. > > > > ------------------------------------------------------------------------ > > diff -ru fontconfig-2.3.2.20050721.orig/fonts.conf.in fontconfig-2.3.2.20050721/fonts.conf.in > --- fontconfig-2.3.2.20050721.orig/fonts.conf.in 2005-04-21 21:03:53.000000000 +0200 > +++ fontconfig-2.3.2.20050721/fonts.conf.in 2005-09-27 15:04:33.000000000 +0200 > @@ -346,16 +361,26 @@ > <match target="font"> > <!-- check to see if the font is just regular --> > <test name="weight" compare="less_eq"> > - <int>100</int> > + <const>medium</const> > </test> > <!-- check to see if the pattern requests bold --> > - <test target="pattern" name="weight" compare="more_eq"> > - <int>200</int> > + <test target="pattern" name="weight" compare="more"> > + <const>medium</const> > </test> > - <!-- set the embolden flag --> > + <!-- > + set the embolden flag > + needed for applications using cairo, e.g. gucharmap, gedit, ... > + --> > <edit name="embolden" mode="assign"> > <bool>true</bool> > </edit> > + <!-- > + set weight to bold > + needed for applications using Xft directly, e.g. Firefox, ... > + --> > + <edit name="weight" mode="assign"> > + <const>bold</const> > + </edit> > </match> > > > > > ------------------------------------------------------------------------ > > diff -urN xc/lib/Xft.old/xftfreetype.c xc/lib/Xft/xftfreetype.c > --- xc/lib/Xft.old/xftfreetype.c 2004-03-12 19:29:52.000000000 +0800 > +++ xc/lib/Xft/xftfreetype.c 2004-04-01 17:15:35.376042784 +0800 > @@ -379,6 +379,7 @@ > FcChar32 hash, *hashp; > FT_Face face; > int nhash; > + FcBool bitmap; > > if (!info) > return FcFalse; > @@ -501,8 +502,22 @@ > */ > fi->load_flags = FT_LOAD_DEFAULT; > > +#ifndef XFT_EMBEDDED_BITMAP > +#define XFT_EMBEDDED_BITMAP "embeddedbitmap" > +#endif > + > + switch (FcPatternGetBool (pattern, XFT_EMBEDDED_BITMAP, 0, &bitmap)) { > + case FcResultNoMatch: > + bitmap = FcFalse; > + break; > + case FcResultMatch: > + break; > + default: > + goto bail1; > + } > + > /* disable bitmaps when anti-aliasing or transforming glyphs */ > - if (fi->antialias || fi->transform) > + if ((!bitmap && fi->antialias) || fi->transform) > fi->load_flags |= FT_LOAD_NO_BITMAP; > > /* disable hinting if requested */ > @@ -658,6 +673,19 @@ > default: > goto bail1; > } > + > + /* > + * Check for weight > + */ > + switch (FcPatternGetInteger (pattern, FC_WEIGHT, 0, &fi->weight_value)) { > + case FcResultNoMatch: > + fi->weight_value = FC_WEIGHT_MEDIUM; > + break; > + case FcResultMatch: > + break; > + default: > + goto bail1; > + } > > /* > * Step over hash value in the structure > @@ -969,6 +997,54 @@ > font->max_glyph_memory = max_glyph_memory; > font->use_free_glyphs = info->use_free_glyphs; > > + /* > + * Extra bitmap strokes > + */ > + font->extra_strokes = 0; > + font->extra_advanceX = 0; > + if (fi->weight_value >= FC_WEIGHT_DEMIBOLD && > + (face->style_flags & FT_STYLE_FLAG_BOLD) == 0) > + { > + font->extra_strokes = > + 32 + FT_MulDiv (fi->xsize, fi->weight_value - 160, 1600); > + > + if (fi->weight_value >= FC_WEIGHT_BOLD) > + font->extra_advanceX = > + (font->extra_strokes > 64)? font->extra_strokes : 64; > + } > + > + /* > + * CJK fixed widths fields > + */ > + font->long_advance.x = 0; > + font->long_advance.y = 0; > + font->short_advance.x = 0; > + font->short_advance.y = 0; > + if (font->info.spacing == FC_MONO && fi->char_width == 0 && > + (fi->load_flags & FT_LOAD_VERTICAL_LAYOUT) == 0 && > + (fi->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH) != 0) > + { > + if (!FT_Select_Charmap (face, ft_encoding_unicode)) > + { > + font->long_advance.x = > + face->size->metrics.max_advance + font->extra_advanceX; > + if (fi->transform) > + FT_Vector_Transform (&font->long_advance, &fi->matrix); > + font->long_advance.x = (font->long_advance.x + 32) >> 6; > + font->long_advance.y = (font->long_advance.y + 32) >> 6; > + > + if (font->long_advance.x > 0) > + font->short_advance.x = (font->long_advance.x + 1) >> 1; > + else > + font->short_advance.x = font->long_advance.x >> 1; > + > + if (font->long_advance.y > 0) > + font->short_advance.y = (font->long_advance.y + 1) >> 1; > + else > + font->short_advance.y = font->long_advance.y >> 1; > + } > + } > + > _XftUnlockFile (fi->file); > > return &font->public; > diff -urN xc/lib/Xft.old/xftglyphs.c xc/lib/Xft/xftglyphs.c > --- xc/lib/Xft.old/xftglyphs.c 2004-03-12 04:48:19.000000000 +0800 > +++ xc/lib/Xft/xftglyphs.c 2004-04-01 17:15:35.381042024 +0800 > @@ -216,6 +216,7 @@ > bottom = FLOOR( glyphslot->metrics.horiBearingY - glyphslot->metrics.height ); > } > > + right += CEIL(font->extra_strokes); > width = TRUNC(right - left); > height = TRUNC( top - bottom ); > > @@ -223,7 +224,8 @@ > * Try to keep monospace fonts ink-inside > * XXX transformed? > */ > - if (font->info.spacing != FC_PROPORTIONAL && !font->info.transform) > + if (font->info.spacing != FC_PROPORTIONAL && !font->info.transform && > + font->long_advance.x == 0 && font->long_advance.y == 0) > { > if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT) > { > @@ -264,12 +266,26 @@ > > xftg->metrics.width = width; > xftg->metrics.height = height; > - xftg->metrics.x = -TRUNC(left); > + xftg->metrics.x = -TRUNC(left) + TRUNC((font->extra_strokes +32) * 1/2); > xftg->metrics.y = TRUNC(top); > > if (font->info.spacing != FC_PROPORTIONAL) > { > - if (font->info.transform) > + if (font->long_advance.x != 0 || font->long_advance.y != 0) > + { > + if (glyphslot->metrics.horiAdvance > > + face->size->metrics.max_advance * 3/4) > + { > + xftg->metrics.xOff = font->long_advance.x; > + xftg->metrics.yOff = -font->long_advance.y; > + } > + else > + { > + xftg->metrics.xOff = font->short_advance.x; > + xftg->metrics.yOff = -font->short_advance.y; > + } > + } > + else if (font->info.transform) > { > if (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT) > { > @@ -301,6 +317,15 @@ > } > else > { > + if (font->extra_advanceX > 0 && > + (font->info.load_flags & FT_LOAD_VERTICAL_LAYOUT) == 0) > + { > + glyphslot->advance.x = > + glyphslot->metrics.horiAdvance + font->extra_advanceX; > + glyphslot->advance.y = 0; > + if (font->info.transform) > + FT_Vector_Transform (&glyphslot->advance, &font->info.matrix); > + } > xftg->metrics.xOff = TRUNC(ROUND(glyphslot->advance.x)); > xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y)); > } > @@ -403,6 +428,53 @@ > continue; > } > > + if (font->extra_strokes > 0) > + { > + int extra = font->extra_strokes; > + int degree; > + int i, h, g, d, k; > + > + if (glyphslot->format == ft_glyph_format_bitmap) > + extra += 8; > + extra *= hmul; > + degree = TRUNC(CEIL(extra)); > + > + for (i = 0; i < degree; i++) > + { > + d = (i == 0)? (extra % 64) : 64; > + if (d == 0) > + d = 64; > + for (h = 0; h < height; h++) > + { > + unsigned char *pos = bufBitmap + h * pitch; > + k = pitch; > + if (font->info.antialias) > + { > + if (i > 0) > + while (--k > 0) > + pos[k] = (pos[k] > pos[k - 1])? pos[k] : pos[k - 1]; > + else > + { > + while (--k > 0) > + { > + g = pos[k]; > + g += d * ((pos[k - 1] > 0)? pos[k - 1]/64 : g/128); > + pos[k] = (g > 0xff)? 0xff : g; > + } > + g = pos[0] + pos[0] * d / 128; > + pos[0] = (g > 0xff)? 0xff : g; > + } > + } > + else > + { > + while (--k > 0) > + pos[k] = pos[k] | (pos[k] >> 1) | (pos[k - 1] << 7); > + pos[0] = pos[0] | (pos[0] >> 1); > + } > + } > + } > + } > + > if (XftDebug() & XFT_DBG_GLYPH) > { > printf ("glyph %d:\n", (int) glyphindex); > diff -urN xc/lib/Xft.old/xftint.h xc/lib/Xft/xftint.h > --- xc/lib/Xft.old/xftint.h 2004-03-12 04:48:19.000000000 +0800 > +++ xc/lib/Xft/xftint.h 2004-04-01 17:15:35.383041720 +0800 > @@ -120,6 +120,7 @@ > int spacing; > FcBool minspace; > int char_width; > + int weight_value; > }; > > /* > @@ -156,6 +157,16 @@ > unsigned long glyph_memory; > unsigned long max_glyph_memory; > FcBool use_free_glyphs; /* Use XRenderFreeGlyphs */ > + /* > + * CJK fixed widths infomation > + */ > + FT_Vector long_advance; > + FT_Vector short_advance; > + /* > + * Extra bitmap strokes > + */ > + int extra_strokes; > + int extra_advanceX; > } XftFontInt; > > typedef enum _XftClipType { > diff -urN xc/lib/Xft.old/xftname.c xc/lib/Xft/xftname.c > --- xc/lib/Xft.old/xftname.c 2004-03-12 04:48:19.000000000 +0800 > +++ xc/lib/Xft/xftname.c 2004-04-01 17:10:22.294638392 +0800 > @@ -33,7 +33,7 @@ > > #define NUM_OBJECT_TYPES (sizeof _XftObjectTypes / sizeof _XftObjectTypes[0]) > > -FcBool _XftNameInitialized; > +FcBool _XftNameInitialized =FcFalse; > > void > _XftNameInit (void) > > > ------------------------------------------------------------------------ > > > > ------------------------------------------------------------------------ > > _______________________________________________ > Fontconfig mailing list > Fontconfig@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/fontconfig -------------- next part -------------- A non-text attachment was scrubbed... Name: fontconfig-add-embedded-bitmap-option.diff Type: text/x-patch Size: 2629 bytes Desc: not available Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20050929/63d40d39/fontconfig-add-embedded-bitmap-option.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: cairo-ft-font-embbedbitmap-options.diff Type: text/x-patch Size: 784 bytes Desc: not available Url : http://lists.freedesktop.org/archives/fontconfig/attachments/20050929/63d40d39/cairo-ft-font-embbedbitmap-options.bin