diff --combined src/cairo-ft-font.c index 38b49c4,d0f769a..0000000 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@@ -1204,8 -1204,6 +1204,8 @@@ _render_glyph_outline (FT_Fac case CAIRO_ANTIALIAS_SUBPIXEL: switch (font_options->subpixel_order) { case CAIRO_SUBPIXEL_ORDER_DEFAULT: + case CAIRO_SUBPIXEL_ORDER_NONE: + fprintf( stderr, "libCairo. WARN: Using subpixel antialiasing, but subpixel order is not defined."); case CAIRO_SUBPIXEL_ORDER_RGB: case CAIRO_SUBPIXEL_ORDER_BGR: render_mode = FT_RENDER_MODE_LCD; @@@ -1521,9 -1519,9 +1521,9 @@@ static const cairo_unscaled_font_backen /* #cairo_ft_scaled_font_t */ typedef struct _cairo_ft_scaled_font { - cairo_scaled_font_t base; - cairo_ft_unscaled_font_t *unscaled; - cairo_ft_options_t ft_options; + cairo_scaled_font_t base; + cairo_ft_unscaled_font_t *unscaled; + cairo_ft_options_t ft_options; } cairo_ft_scaled_font_t; const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend; @@@ -1545,36 -1543,62 +1545,36 @@@ _get_pattern_ft_options (FcPattern *pat ft_options.load_flags = FT_LOAD_DEFAULT; ft_options.extra_flags = 0; -#ifndef FC_EMBEDDED_BITMAP -#define FC_EMBEDDED_BITMAP "embeddedbitmap" -#endif - - /* Check whether to force use of embedded bitmaps */ - if (FcPatternGetBool (pattern, - FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch) - bitmap = FcFalse; - - /* disable antialiasing if requested */ - if (FcPatternGetBool (pattern, - FC_ANTIALIAS, 0, &antialias) != FcResultMatch) - antialias = FcTrue; - - if (antialias) { - cairo_subpixel_order_t subpixel_order; - int lcd_filter; - - /* disable hinting if requested */ - if (FcPatternGetBool (pattern, - FC_HINTING, 0, &hinting) != FcResultMatch) - hinting = FcTrue; - - if (FcPatternGetInteger (pattern, - FC_RGBA, 0, &rgba) != FcResultMatch) - rgba = FC_RGBA_UNKNOWN; + int lcd_filter; + if (FcPatternGetInteger (pattern, FC_RGBA, 0, &rgba) == FcResultMatch) + { switch (rgba) { - case FC_RGBA_RGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - break; - case FC_RGBA_BGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - break; - case FC_RGBA_VRGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - break; - case FC_RGBA_VBGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - break; - case FC_RGBA_UNKNOWN: - case FC_RGBA_NONE: - default: - subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - break; - } - - if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) { - ft_options.base.subpixel_order = subpixel_order; - ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; - } + case FC_RGBA_RGB: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; + break; + case FC_RGBA_BGR: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; + break; + case FC_RGBA_VRGB: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; + break; + case FC_RGBA_VBGR: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; + break; + case FC_RGBA_NONE: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_NONE; + break; + case FC_RGBA_UNKNOWN: + default: + ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; + break; + } + } // Fontconfig did not specify subpixel_order. Staying with SUBPIXEL_ORDER_DEAULT; - if (FcPatternGetInteger (pattern, - FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch) - { - switch (lcd_filter) { + if (FcPatternGetInteger (pattern, FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch) + { + switch (lcd_filter) { case FC_LCD_NONE: ft_options.base.lcd_filter = CAIRO_LCD_FILTER_NONE; break; @@@ -1587,159 -1611,115 +1587,159 @@@ case FC_LCD_LEGACY: ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; break; - } } + } // No LCD_FILTER property in Fontconfig - falling back to CAIRO_LCD_FILTER_DEFAULT. -#ifdef FC_HINT_STYLE - if (FcPatternGetInteger (pattern, - FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) - hintstyle = FC_HINT_FULL; - - if (!hinting) - hintstyle = FC_HINT_NONE; + // Checking if antialias property was delivered from FontConfig + if (FcPatternGetBool (pattern, FC_ANTIALIAS, 0, &antialias) == FcResultMatch) + { + // Antialias is defined and is true + if (antialias) { + if ( (ft_options.base.subpixel_order!=CAIRO_SUBPIXEL_ORDER_NONE) ) { + // Returned subpixel_order is defined and defines subpixel antialiasing or no subpixel_order information + ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; + } else { + // Returned subpixel_order is defined and defines grayscale antialiasing + ft_options.base.antialias = CAIRO_ANTIALIAS_GRAY; + } + } else { + ft_options.base.antialias = CAIRO_ANTIALIAS_NONE; + } + } // Antialias not defined in Fontconfig. We are not doing anything - staying with CAIRO_ANTIALIAS_DEFAULT + + // Processing hinting information + // If FontConfig does provide FC_HINTING and it is false, we are not processing the FC_HINT_STYLE property - we assume hintnone + // If Fontconfig does not provide FC_HINTING property, we are assuming it is true, so the FC_HINT_STYLE will be processed + if (FcPatternGetBool (pattern, FC_HINTING, 0, &hinting) != FcResultMatch) + hinting = FcTrue; + + // hinting is false only when Fontconfig verbosely set it to false. + // in such case switching hint_style to CAIRO_HINT_STYLE_NONE + if (!hinting) { + ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; + } +#ifdef FC_HINT_STYLE + // Checking the FC_HINT_STYLE property only if hinting is true + // If hinting is false, hinstyle is already set to CAIRO_HINT_STYLE_NONE + if ( hinting && (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) == FcResultMatch)) { switch (hintstyle) { - case FC_HINT_NONE: - ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; - break; - case FC_HINT_SLIGHT: - ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT; - break; - case FC_HINT_MEDIUM: - default: - ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM; - break; - case FC_HINT_FULL: - ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL; - break; - } -#else /* !FC_HINT_STYLE */ - if (!hinting) { - ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; + case FC_HINT_NONE: + ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; + break; + case FC_HINT_SLIGHT: + ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT; + break; + case FC_HINT_MEDIUM: + default: + ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM; + break; + case FC_HINT_FULL: + ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL; + break; } + } #endif /* FC_HINT_STYLE */ - /* Force embedded bitmaps off if no hinting requested */ - if (ft_options.base.hint_style == CAIRO_HINT_STYLE_NONE) - bitmap = FcFalse; +#ifndef FC_EMBEDDED_BITMAP +#define FC_EMBEDDED_BITMAP "embeddedbitmap" +#endif + + /* Check whether to force use of embedded bitmaps + * If not verbosely requested, we are not forcing the bitmaps off */ + if (FcPatternGetBool (pattern, FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch) + bitmap = FcTrue; - if (!bitmap) - ft_options.load_flags |= FT_LOAD_NO_BITMAP; + /* Force embedded bitmaps off if no hinting requested */ + if (ft_options.base.hint_style == CAIRO_HINT_STYLE_NONE) + bitmap = FcFalse; - } else { - ft_options.base.antialias = CAIRO_ANTIALIAS_NONE; - } + if (!bitmap) + ft_options.load_flags |= FT_LOAD_NO_BITMAP; /* force autohinting if requested */ - if (FcPatternGetBool (pattern, - FC_AUTOHINT, 0, &autohint) != FcResultMatch) - autohint = FcFalse; - - if (autohint) - ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT; + if (FcPatternGetBool (pattern, FC_AUTOHINT, 0, &autohint) == FcResultMatch) { + if (autohint) + ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT; + } - if (FcPatternGetBool (pattern, - FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch) - vertical_layout = FcFalse; + /* force vertical layout if requested */ + if (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout) == FcResultMatch) { + if (vertical_layout) + ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT; + } #ifndef FC_EMBOLDEN #define FC_EMBOLDEN "embolden" #endif - if (FcPatternGetBool (pattern, - FC_EMBOLDEN, 0, &embolden) != FcResultMatch) - embolden = FcFalse; - - if (embolden) - ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN; + + if (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &embolden) == FcResultMatch) { + if (embolden) + ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN; + } *ret = ft_options; } +/** + * Merges the ft_options_t objects and saves the result in options object. + * + * @param other - options returned by Fontconfig + * @param options - options read from xrdb/Xft. Merge result is saved here. + */ static void _cairo_ft_options_merge (cairo_ft_options_t *options, - cairo_ft_options_t *other) + cairo_ft_options_t *other) { int load_flags = other->load_flags; int load_target = FT_LOAD_TARGET_NORMAL; /* clear load target mode */ load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags))); - + if (load_flags & FT_LOAD_NO_HINTING) other->base.hint_style = CAIRO_HINT_STYLE_NONE; - if (other->base.antialias == CAIRO_ANTIALIAS_NONE || - options->base.antialias == CAIRO_ANTIALIAS_NONE) { - options->base.antialias = CAIRO_ANTIALIAS_NONE; - options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; + // If FontConfig returned a setting for subpixel_order, we are using it + // It doesn't matter, what antialais we will have + // if antialias will be ANTIALIAS_NONE, the subpixel_order is ignored + // if antialias will be ANTIALIAS_GRAY or ANTIALIAS_SUBPIXEL, + // then it is taken into account detrmning type of antialias and during rendering + if (other->base.subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) { + options->base.subpixel_order = other->base.subpixel_order; } - if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL && - (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || - options->base.antialias == CAIRO_ANTIALIAS_GRAY)) { - options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; - options->base.subpixel_order = other->base.subpixel_order; + // If Fontconfig returned setting for antialias, we are using it + // At this point it is important to switch AA on or off, if it was specified by Fontconfig. + // The type of antialias (ANTIALIAS_GRAY or ANTIALIAS_SUBPIXEL) is determined later. + if (other->base.antialias != CAIRO_ANTIALIAS_DEFAULT) { + options->base.antialias = other->base.antialias; + } + + // Checking if after the merge we are still using antialiasing + // If so, we have to determine which kind - ANTIALIAS_GRAY or ANTIALIAS_SUBPIXEL + if (options->base.antialias != CAIRO_ANTIALIAS_NONE) { + switch (options->base.subpixel_order) { + case (CAIRO_SUBPIXEL_ORDER_RGB) : + case (CAIRO_SUBPIXEL_ORDER_BGR) : + case (CAIRO_SUBPIXEL_ORDER_VRGB) : + case (CAIRO_SUBPIXEL_ORDER_VBGR) : + options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; + break; + case (CAIRO_SUBPIXEL_ORDER_DEFAULT) : + case (CAIRO_SUBPIXEL_ORDER_NONE): + default: + options->base.antialias = CAIRO_ANTIALIAS_GRAY; + } } - if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT) + if (other->base.hint_style != CAIRO_HINT_STYLE_DEFAULT) options->base.hint_style = other->base.hint_style; - if (other->base.hint_style == CAIRO_HINT_STYLE_NONE) - options->base.hint_style = CAIRO_HINT_STYLE_NONE; - - if (options->base.lcd_filter == CAIRO_LCD_FILTER_DEFAULT) + if (other->base.lcd_filter != CAIRO_LCD_FILTER_DEFAULT) options->base.lcd_filter = other->base.lcd_filter; - if (other->base.lcd_filter == CAIRO_LCD_FILTER_NONE) - options->base.lcd_filter = CAIRO_LCD_FILTER_NONE; - + // Setting LoadFlags if (options->base.antialias == CAIRO_ANTIALIAS_NONE) { if (options->base.hint_style == CAIRO_HINT_STYLE_NONE) load_flags |= FT_LOAD_NO_HINTING; @@@ -1748,30 -1728,30 +1748,30 @@@ load_flags |= FT_LOAD_MONOCHROME; } else { switch (options->base.hint_style) { - case CAIRO_HINT_STYLE_NONE: - load_flags |= FT_LOAD_NO_HINTING; - break; - case CAIRO_HINT_STYLE_SLIGHT: - load_target = FT_LOAD_TARGET_LIGHT; - break; - case CAIRO_HINT_STYLE_MEDIUM: - break; - case CAIRO_HINT_STYLE_FULL: - case CAIRO_HINT_STYLE_DEFAULT: - if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) { - switch (options->base.subpixel_order) { - case CAIRO_SUBPIXEL_ORDER_DEFAULT: - case CAIRO_SUBPIXEL_ORDER_RGB: - case CAIRO_SUBPIXEL_ORDER_BGR: - load_target = FT_LOAD_TARGET_LCD; - break; - case CAIRO_SUBPIXEL_ORDER_VRGB: - case CAIRO_SUBPIXEL_ORDER_VBGR: - load_target = FT_LOAD_TARGET_LCD_V; + case CAIRO_HINT_STYLE_NONE: + load_flags |= FT_LOAD_NO_HINTING; + break; + case CAIRO_HINT_STYLE_SLIGHT: + case CAIRO_HINT_STYLE_MEDIUM: + load_target = FT_LOAD_TARGET_LIGHT; break; + case CAIRO_HINT_STYLE_FULL: + case CAIRO_HINT_STYLE_DEFAULT: + if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) { + switch (options->base.subpixel_order) { + case CAIRO_SUBPIXEL_ORDER_NONE: + case CAIRO_SUBPIXEL_ORDER_DEFAULT: + case CAIRO_SUBPIXEL_ORDER_RGB: + case CAIRO_SUBPIXEL_ORDER_BGR: + load_target = FT_LOAD_TARGET_LCD; + break; + case CAIRO_SUBPIXEL_ORDER_VRGB: + case CAIRO_SUBPIXEL_ORDER_VBGR: + load_target = FT_LOAD_TARGET_LCD_V; + break; + } } - } - break; + break; } } diff --combined src/cairo-xlib-screen.c index f5a3ae6,37e3418..0000000 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@@ -135,7 -135,6 +135,7 @@@ get_integer_default (Display *dpy #ifndef FC_LCD_FILTER #define FC_LCD_FILTER "lcdfilter" #endif + /* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */ #ifndef FC_LCD_NONE #define FC_LCD_NONE 0 @@@ -171,10 -170,7 +171,10 @@@ _cairo_xlib_init_screen_font_options (D xft_hinting = TRUE; if (!get_integer_default (dpy, "hintstyle", &xft_hintstyle)) - xft_hintstyle = FC_HINT_FULL; + /* -1 is an non-existant Fontconfig constant used to differentiate + * the case when no hintstyle property is available. + */ + xft_hintstyle = -1; if (!get_integer_default (dpy, "rgba", &xft_rgba)) { @@@ -246,10 -242,8 +246,10 @@@ case FC_RGBA_VBGR: subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; break; - case FC_RGBA_UNKNOWN: case FC_RGBA_NONE: + subpixel_order = CAIRO_SUBPIXEL_ORDER_NONE; + break; + case FC_RGBA_UNKNOWN: default: subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; } @@@ -273,14 -267,10 +273,14 @@@ } if (xft_antialias) { - if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT) + switch (subpixel_order) { + case CAIRO_SUBPIXEL_ORDER_DEFAULT: + case CAIRO_SUBPIXEL_ORDER_NONE: antialias = CAIRO_ANTIALIAS_GRAY; - else + break; + default: antialias = CAIRO_ANTIALIAS_SUBPIXEL; + } } else { antialias = CAIRO_ANTIALIAS_NONE; } diff --combined src/cairo.h index a1cde78,cf4bc05..0000000 --- a/src/cairo.h +++ b/src/cairo.h @@@ -1032,7 -1032,6 +1032,7 @@@ typedef enum _cairo_font_weight * with red at the top * @CAIRO_SUBPIXEL_ORDER_VBGR: Subpixel elements are arranged vertically * with blue at the top + * @CAIRO_SUBPIXEL_ORDER_NONE: The screen does not have subpixel structure. * * The subpixel order specifies the order of color elements within * each pixel on the display device when rendering with an @@@ -1043,8 -1042,7 +1043,8 @@@ typedef enum _cairo_subpixel_order CAIRO_SUBPIXEL_ORDER_RGB, CAIRO_SUBPIXEL_ORDER_BGR, CAIRO_SUBPIXEL_ORDER_VRGB, - CAIRO_SUBPIXEL_ORDER_VBGR + CAIRO_SUBPIXEL_ORDER_VBGR, + CAIRO_SUBPIXEL_ORDER_NONE } cairo_subpixel_order_t; /**