From f87842d08afd04e38773be961d9088a85706e948 Mon Sep 17 00:00:00 2001 From: Jeff Teunissen Date: Mon, 25 Mar 2019 03:50:10 -0400 Subject: [PATCH] Turn on hinting and subpixel rendering for Cairo. There's no good reason not to enable subpixel rendering and hinting. Leaving it off makes GNUstep apps look worse than everything else, in exchange for having -advancementForGlyph: be totally consistent, which may not even be necessary. So, yeah, let's just turn this stuff on. I reused the subpixel default from back-art to preserve configs, and added a GSFontHinting default to control text hinting. Use 0 for whatever Cairo defaults to, 1 for off, 2 for slight hinting, 3 for medium hinting, or 4 for full hinting. --- Source/cairo/CairoFontInfo.m | 56 +++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/Source/cairo/CairoFontInfo.m b/Source/cairo/CairoFontInfo.m index a38092e..23f3f3a 100644 --- a/Source/cairo/CairoFontInfo.m +++ b/Source/cairo/CairoFontInfo.m @@ -51,6 +51,10 @@ cairo_matrix_t font_matrix; cairo_matrix_t ctm; cairo_font_options_t *options; + cairo_hint_metrics_t metrics = CAIRO_HINT_METRICS_ON; + cairo_hint_style_t style = CAIRO_HINT_STYLE_DEFAULT; + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + int hinting = 0, subpixel = 0; if (![super setupAttributes]) { @@ -78,16 +82,48 @@ return NO; } - // We must not leave the hinting settings as their defaults, - // because if we did, that would mean using the surface defaults - // which might or might not use hinting (xlib does by default.) - // - // Since we make measurements outside of the context of a surface - // (-advancementForGlyph:), we need to ensure that the same - // hinting settings are used there as when we draw. For now, - // just force hinting to be off. - cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_ON); - cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE); + if ((hinting = [ud integerForKey: @"GSFontHinting"])) + { /* + * This part is only here to debug disabling the use of hinting for + * metrics, because doing so causes menus to get cut off on the right. + */ + switch (hinting >> 4) + { + case 1: + metrics = CAIRO_HINT_METRICS_OFF; + break; + case 2: + metrics = CAIRO_HINT_METRICS_ON; + break; + } + + switch (hinting & 0x0f) + { + case 1: + style = CAIRO_HINT_STYLE_NONE; + break; + case 2: + style = CAIRO_HINT_STYLE_SLIGHT; + break; + case 3: + style = CAIRO_HINT_STYLE_MEDIUM; + break; + case 4: + style = CAIRO_HINT_STYLE_FULL; + break; + } + } + cairo_font_options_set_hint_metrics(options, metrics); + cairo_font_options_set_hint_style(options, style); + + if ((subpixel = [ud integerForKey: @"back-art-subpixel-text"])) + { + cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL); + cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_RGB); + + if (subpixel == 2) + cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_BGR); + } _scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options); cairo_font_options_destroy(options);