GNOME Bugzilla – Bug 108728
Pango should offer a way to filter monospaced fonts
Last modified: 2004-12-22 21:47:04 UTC
There are plenty of times when an application wants the user to select only a fixed width font. Some more common times: Selecting a terminal font Selecting the default font for displaying email Picking the Fixed Width font in a web browser All font backends seem to support filtering on monospaced or charcell fonts. Pango should allow this field to be searched on as well.
At least until recently, fontconfig hasn't provided useful information on fixed-width fonts. There hsa been some discussion of it recently. (Note that "fixed width" fonts are sometimes dual-width for CJK locales. Characters are either 1 or 2 charcells wide.)
What do you see as the api for this? A couple possibilities I see are: pango_context_list_monospace_families () pango_context_list_families_with_spacing (..., proportional/monospace) pango_context_match_families (..., criteria...)
pango_font_family_is_monospace() (is_fixed_pitch? is_proportional()? Not sure exactly what the name should be, but a getter on PangoFontFamily()) I think even with thousands of families, just listing them all and picking out the ones you want should be fine.
Created attachment 19334 [details] [review] patch.. pango_win32_family_is_monospace and pango_x_family_is_monospace need to be filled in
Test program: #include <pango/pangoft2.h> gint main (gint argc, gchar **argv) { PangoFontFamily **families; gint n_families; gint i; pango_context_list_families (pango_ft2_get_context (72, 72), &families, &n_families); for (i = 0; i < n_families; i++) if (pango_font_family_is_monospace (families[i])) g_print ("%s\n", pango_font_family_get_name (families[i])); return 0; } prints for me: Mitra Mono Luxi Mono Bitstream Vera Sans Mono Lucida Console Courier 10 Pitch Miriam Mono Nimbus Mono L Cursor FreeMono Monospace
Need to think a bit about dual-width CJK fonts .. they are "monospace" for most cases where you want monospace fonts. I'm not sure if they aren't showing up above because: - You don't have any on your system - Fontconfig is still broken in this area - They are listed as something other than FC_MONO. See bug 106624.
I think it's because fontconfig doesn't know anything about dual-width fonts yet. It might soon, but do we want to wait on it? P.S. A fix to my patch: pango_fc_family_is_monospace should return fcfamily->spacing == FC_MONO || fc_family->spacing == FC_CHARCELL;
Following some discussion with Keith, I've filed a fontconfig bug and patch here: http://fontconfig.org/cgi-bin/bugzilla/show_bug.cgi?id=111
Created attachment 19789 [details] [review] updated patch, checks for FC_DUAL
In cvs, fontconfig now supports dual-width spacing, and the above patch checks for it.
Comments on the patch: + return PANGO_FONT_FAMILY_GET_CLASS (family)->is_monospace (family); Probably best to check for NULL; otherwise, preserving bin-compat by removing the padding element has no point. + FcObjectSet *os = FcObjectSetBuild (FC_FAMILY, FC_SPACING, NULL); This poses a problem if different faces in a family have different spacing values ... I think it is OK to assume that one PangoFontFamily has a single spacing family, but we need to not create duplicate entries in the returned array if that assumption fails at the fontconfig levels. A temporary GHashTable could be used to catch duplicates. The standard for FIXME's in Pango is FIXME, not XXX, but a FIXME isn't needed for the X code, simply returning false (or omitting, see above about NULL check) should be fine for this deprecated codebase. I'd really like to see a Win32 implemetntation before we commit this to CVS - it's likely to get forgotten otherwise, and I think should be relatively trivial. Final thought: Considering that we are including dual width fonts, is "is_monospace" still the best name? I think yes - reason being that the standard "Monospace" alias should be dual-width for CJK languages.
Created attachment 21487 [details] [review] updated patch
The patch above fixes the issues with the previous patch that you pointed out. Still need a win32 implementation. With this patch, if two fonts in the same family have different spacing values, the first one encountered wins. Should we favor one over the other? I wasn't sure which it would be if we did. Unfortunately, it's not just a theoretical issue: $ fc-list "" family style spacing | grep -i "luxi mono" Luxi Mono:style=Bold Luxi Mono:style=Regular:spacing=100 Luxi Mono:style=Oblique:spacing=100 Luxi Mono:style=Bold Oblique $ fc-list "" family style spacing | grep -i courier Courier 10 Pitch:style=Bold Italic:spacing=100 Courier 10 Pitch:style=Italic Courier 10 Pitch:style=Regular:spacing=100 Courier 10 Pitch:style=Bold:spacing=100
Did you miss my comment about the check-for-NULL? Can you figure out why Luxi Mono Bold, Courier 10 Pitch Italic aren't getting reported as monospace fonts? I think when you find duplicate families, you should insert insert the faces from the subsequent patterns into the first family object created rather than just dropping the subsequent patterns. On thought, I think what I'd do for windows, is change the "return FALSE" to a g_warning(), commit, then make GtkFontSelection use it. Think we need to force the issue for win32 :-)
> Can you figure out why Luxi Mono Bold, Courier 10 Pitch > Italic aren't getting reported as monospace fonts? Courier 10 Pitch is working for me now. Don't know what the problem was. Luxi Mono Bold has three different advances. Most of the glyphs have advance = 1229, but U+0326 COMBINING COMMA BELOW has advance = 682, and U+201A, U+201E, U+2021 and U+2030 all have advance = 1338.
> I think when you find duplicate families, you should > insert insert the faces from the subsequent patterns into > the first family object created rather than just dropping > the subsequent patterns. I must admit I'm not really sure what you mean by this. Are you suggesting that pango_fc_font_map_list_families also initialize the faces (PangoFcFamily::faces) instead of letting it be done on demand in pango_fc_family_list_faces?
Created attachment 21604 [details] [review] updated patch (doesn't have the faces part I don't get)
Never mind about the comment about duplicate families, I was forgetting that we were doing things in two passes. The only change I'd like to see before committing is that the docs for pango_font_family_is_monospace() should define 'monospace' and warn about dual width fonts; something along the lines of: A monospace font is a font designed for text display where the the characters form a regular grid. For Western languages this would mean that the advance width of all characters are the same, but this categorization also includes Asian fonts which include double-width characters: characters that occupy two grid cells. g_unichar_iswide() returns a result that indicates whether a character is typically double-width in a monospace font. The best way to find out the grid-cell size is to call pango_font_metrics_get_approximate_digit_width(), since the results of pango_font_metrics_get_approximate_char_width() may be affected by double-width characters.
Need win32 implementation (bug 135238). 2003-02-23 Noah Levitt <nlevitt@columbia.edu> * pango/pangowin32-fontmap.c: * pango/pangofc-fontmap.c: * pango/pango-font.h: * pango/fonts.c: New API pango_font_family_is_monospace. (#108728)
Going to resolve this one fixed, win32 implementation is a separate detail.