summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2008-05-27 00:29:10 +0000
committerTor Lillqvist <tml@src.gnome.org>2008-05-27 00:29:10 +0000
commit76101786c159b8bdfdb711332ec4ccb73812e729 (patch)
treed89c0be56027df493c54aae1c60777cb3475918b
parent3c3df8f0f19f6fb87931bd68b8dbb61bc3af0de0 (diff)
downloadpango-76101786c159b8bdfdb711332ec4ccb73812e729.tar.gz
Synthesize also Bold and Bold Italic (or Oblique) faces when feasible.
2008-05-27 Tor Lillqvist <tml@novell.com> * pango/pangowin32-fontmap.c: Synthesize also Bold and Bold Italic (or Oblique) faces when feasible. Don't synthesize these for decorative or script fonts. Kill the magic code snippet mentioned below. Instead, explicitly create font families for the standard pseudo fonts that correspond to the first existing font of the corresponding built-in alias list. Use the face style name Oblique for slanted sans and monospace fonts, not Italic. svn path=/trunk/; revision=2639
-rw-r--r--ChangeLog10
-rw-r--r--pango/pangowin32-fontmap.c247
2 files changed, 186 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 264cbcc3..888d72d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2008-05-27 Tor Lillqvist <tml@novell.com>
+ * pango/pangowin32-fontmap.c: Synthesize also Bold and Bold Italic
+ (or Oblique) faces when feasible. Don't synthesize these for
+ decorative or script fonts. Kill the magic code snippet mentioned
+ below. Instead, explicitly create font families for the standard
+ pseudo fonts that correspond to the first existing font of the
+ corresponding built-in alias list. Use the face style name Oblique
+ for slanted sans and monospace fonts, not Italic.
+
+2008-05-27 Tor Lillqvist <tml@novell.com>
+
* pango/pangowin32-fontmap.c (pango_win32_family_list_faces):
Prune duplicated face names. Makes the GTK+ font selector look a
bit saner for the "sans", "serif" and "monospace" standard pseudo
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 3ee1d1d1..21c7583e 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -90,6 +90,9 @@ static void pango_win32_insert_font (PangoWin32FontMap
LOGFONTW *lfp,
gboolean is_synthetic);
+static PangoWin32Family *pango_win32_get_font_family (PangoWin32FontMap *win32fontmap,
+ const char *family_name);
+
static const char *pango_win32_face_get_face_name (PangoFontFace *face);
static PangoWin32FontMap *default_fontmap = NULL;
@@ -210,28 +213,64 @@ pango_win32_enum_proc (LOGFONTW *lfp,
typedef struct _ItalicHelper
{
+ const char *style;
+ gboolean (*check) (const LOGFONTW *lf);
+ void (*modify) (LOGFONTW *lf);
PangoWin32FontMap *fontmap;
- GSList *list;
-} ItalicHelper;
+ GSList *list;
+} SynthesizeHelper;
+
+static gboolean
+slanted_feasible (const LOGFONTW *lfp)
+{
+ return (((lfp->lfPitchAndFamily & 0xF0) == FF_MODERN ||
+ (lfp->lfPitchAndFamily & 0xF0) == FF_ROMAN ||
+ (lfp->lfPitchAndFamily & 0xF0) == FF_SWISS) &&
+ !lfp->lfItalic);
+}
static void
-ensure_italic (gpointer key,
- gpointer value,
- gpointer user_data)
+italicize (LOGFONTW *lfp)
{
- ItalicHelper *helper = (ItalicHelper *)user_data;
+ lfp->lfItalic = 1;
+}
+
+static gboolean
+bold_feasible (const LOGFONTW *lfp)
+{
+ return (((lfp->lfPitchAndFamily & 0xF0) == FF_MODERN ||
+ (lfp->lfPitchAndFamily & 0xF0) == FF_ROMAN ||
+ (lfp->lfPitchAndFamily & 0xF0) == FF_SWISS) &&
+ lfp->lfWeight == FW_NORMAL);
+}
+
+static void
+boldify (LOGFONTW *lfp)
+{
+ lfp->lfWeight = FW_BOLD;
+}
+
+static void
+synthesize_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ SynthesizeHelper *helper = (SynthesizeHelper *)user_data;
const LOGFONTW *lfp = (const LOGFONTW *) value;
LOGFONTW *lfpnew;
- if (!lfp->lfItalic)
+ if (helper->check (lfp))
{
- /* We have a non-italic variant, look if there is an italic */
+ /* We have "normal" variant, look if we need to synthesize the required style */
LOGFONTW logfontw = *lfp;
- logfontw.lfItalic = 1;
+ helper->modify (&logfontw);
if (!g_hash_table_lookup (helper->fontmap->fonts, &logfontw))
{
- /* Remember the italic variant to be added later */
- PING (("synthesizing italic: %S wt=%ld", lfp->lfFaceName, lfp->lfWeight));
+ PING (("synthesizing %s %s%S wt=%ld",
+ helper->style,
+ lfp->lfItalic ? "Italic " : "",
+ lfp->lfFaceName,
+ lfp->lfWeight));
lfpnew = g_new (LOGFONTW, 1);
*lfpnew = logfontw;
helper->list = g_slist_append (helper->list, lfpnew);
@@ -240,11 +279,89 @@ ensure_italic (gpointer key,
}
static void
+synthesize_faces (PangoWin32FontMap *win32fontmap,
+ const char *style,
+ gboolean (*check_func) (const LOGFONTW *lfp),
+ void (*modify_func) (LOGFONTW *lfp))
+{
+ SynthesizeHelper helper = { style, check_func, modify_func, win32fontmap, NULL };
+ GSList *list;
+
+ g_hash_table_foreach (win32fontmap->fonts, synthesize_foreach, &helper);
+
+ /* Process the list of LOGFONTWs for the synthesized fonts */
+ list = helper.list;
+ while (list)
+ {
+ pango_win32_insert_font (win32fontmap, (LOGFONTW *)list->data, TRUE);
+ g_free (list->data);
+ list = list->next;
+ }
+ g_slist_free (helper.list);
+}
+
+static void
+create_standard_family (PangoWin32FontMap *win32fontmap,
+ const char *standard_family_name)
+{
+ int i;
+ int n_aliases;
+ char **aliases;
+
+ pango_lookup_aliases (standard_family_name, &aliases, &n_aliases);
+ for (i = 0; i < n_aliases; i++)
+ {
+ PangoWin32Family *existing_family = g_hash_table_lookup (win32fontmap->families, aliases[i]);
+
+ if (existing_family)
+ {
+ PangoWin32Family *new_family = pango_win32_get_font_family (win32fontmap, standard_family_name);
+ GSList *p = existing_family->faces;
+
+ new_family->is_monospace = existing_family->is_monospace;
+
+ while (p)
+ {
+ const PangoWin32Face *old_face = (const PangoWin32Face *) p->data;
+ PangoWin32Face *new_face = g_object_new (PANGO_WIN32_TYPE_FACE, NULL);
+ int j;
+
+ new_face->logfontw = old_face->logfontw;
+ new_face->description = pango_font_description_copy_static (old_face->description);
+ pango_font_description_set_family_static (new_face->description, standard_family_name);
+
+ for (j = 0; j < PANGO_WIN32_N_COVERAGES; j++)
+ {
+ if (old_face->coverages[j] != NULL)
+ new_face->coverages[j] = pango_coverage_ref (old_face->coverages[j]);
+ else
+ new_face->coverages[j] = NULL;
+ }
+
+ new_face->is_synthetic = TRUE;
+
+ new_face->has_cmap = old_face->has_cmap;
+ new_face->cmap_format = old_face->cmap_format;
+ new_face->cmap = old_face->cmap;
+
+ new_face->cached_fonts = NULL;
+
+ new_family->faces = g_slist_append (new_family->faces, new_face);
+
+ p = p->next;
+ }
+ return;
+ }
+ }
+ /* XXX What to do if none of the members of aliases for standard_family_name
+ * exists on this machine?
+ */
+}
+
+static void
_pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
{
LOGFONTW logfont;
- ItalicHelper helper = { win32fontmap, NULL };
- GSList *list;
win32fontmap->families = g_hash_table_new ((GHashFunc) case_insensitive_str_hash,
(GEqualFunc) case_insensitive_str_equal);
@@ -260,18 +377,16 @@ _pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
(FONTENUMPROCW) pango_win32_enum_proc,
(LPARAM) win32fontmap, 0);
- /* Create synthetic italic entries */
- g_hash_table_foreach (win32fontmap->fonts, ensure_italic, &helper);
+ /* Create synthetic Italic faces */
+ synthesize_faces (win32fontmap, "Italic", slanted_feasible, italicize);
- /* Process the list of LOGFONTWs for synthesized italic fonts */
- list = helper.list;
- while (list)
- {
- pango_win32_insert_font (win32fontmap, (LOGFONTW *)list->data, TRUE);
- g_free (list->data);
- list = list->next;
- }
- g_slist_free (helper.list);
+ /* Create synthetic Bold (and Bold Italic) faces */
+ synthesize_faces (win32fontmap, "Bold", bold_feasible, boldify);
+
+ /* Create synthetic "Sans", "Serif" and "Monospace" families */
+ create_standard_family (win32fontmap, "Sans");
+ create_standard_family (win32fontmap, "Serif");
+ create_standard_family (win32fontmap, "Monospace");
win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (_pango_win32_hdc, LOGPIXELSY)) * 72.0;
}
@@ -980,10 +1095,12 @@ pango_win32_font_description_from_logfontw (const LOGFONTW *lfp)
family = get_family_nameW (lfp);
- if (!lfp->lfItalic)
- style = PANGO_STYLE_NORMAL;
- else
+ if ((lfp->lfPitchAndFamily & 0xF0) == FF_ROMAN && lfp->lfItalic)
style = PANGO_STYLE_ITALIC;
+ else if (lfp->lfItalic)
+ style = PANGO_STYLE_OBLIQUE;
+ else
+ style = PANGO_STYLE_NORMAL;
variant = PANGO_VARIANT_NORMAL;
@@ -1054,6 +1171,27 @@ charset_name (int charset)
}
}
+static char *
+ff_name (int ff)
+{
+ static char num[10];
+
+ switch (ff)
+ {
+#define CASE(x) case FF_##x: return #x
+ CASE (DECORATIVE);
+ CASE (DONTCARE);
+ CASE (MODERN);
+ CASE (ROMAN);
+ CASE (SCRIPT);
+ CASE (SWISS);
+#undef CASE
+ default:
+ sprintf (num, "%d", ff);
+ return num;
+ }
+}
+
static void
pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
LOGFONTW *lfp,
@@ -1064,10 +1202,14 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
PangoWin32Family *win32family;
PangoWin32Face *win32face;
gint i;
- gchar *p;
- PING (("face=%S,charset=%s,it=%d,wt=%ld,ht=%ld",
- lfp->lfFaceName, charset_name (lfp->lfCharSet), lfp->lfItalic, lfp->lfWeight, lfp->lfHeight));
+ PING (("face=%S,charset=%s,it=%s,wt=%ld,ht=%ld,ff=%s",
+ lfp->lfFaceName,
+ charset_name (lfp->lfCharSet),
+ lfp->lfItalic ? "yes" : "no",
+ lfp->lfWeight,
+ lfp->lfHeight,
+ ff_name (lfp->lfPitchAndFamily & 0xF0)));
/* Ignore Symbol fonts (which don't have any Unicode mapping
* table). We could also be fancy and use the PostScript glyph name
@@ -1120,49 +1262,12 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
win32family =
pango_win32_get_font_family (win32fontmap,
pango_font_description_get_family (win32face->description));
+ if ((lfp->lfPitchAndFamily & 0xF0) == FF_MODERN)
+ win32family->is_monospace = TRUE;
+
win32family->faces = g_slist_append (win32family->faces, win32face);
- PING (("g_slist_length(win32family->faces)=%d", g_slist_length (win32family->faces)));
-
-#if 1 /* Thought pango.aliases would make this code unnecessary, but no. */
- /*
- * There are magic family names coming from the X implementation.
- * They can be simply mapped to lfPitchAndFamily flag of the logfont
- * struct. These additional entries should probably only be references
- * to the respective entry created above. Thy are simply using the
- * same entry at the moment and it isn't crashing on g_free () ???
- * Maybe a memory leak ...
- */
- switch (lfp->lfPitchAndFamily & 0xF0)
- {
- case FF_MODERN : /* monospace */
- PING (("monospace"));
- win32family->is_monospace = TRUE; /* modify before reuse */
- win32family = pango_win32_get_font_family (win32fontmap, "monospace");
- win32family->faces = g_slist_append (win32family->faces, win32face);
- break;
- case FF_ROMAN : /* serif */
- PING (("serif"));
- win32family = pango_win32_get_font_family (win32fontmap, "serif");
- win32family->faces = g_slist_append (win32family->faces, win32face);
- break;
- case FF_SWISS : /* sans */
- PING (("sans"));
- win32family = pango_win32_get_font_family (win32fontmap, "sans");
- win32family->faces = g_slist_append (win32family->faces, win32face);
- break;
- }
-
- /* Some other magic names */
- /* Recognize just "courier" for "courier new" */
- p = g_utf16_to_utf8 (win32face->logfontw.lfFaceName, -1, NULL, NULL, NULL);
- if (p && g_ascii_strcasecmp (p, "courier new") == 0)
- {
- win32family = pango_win32_get_font_family (win32fontmap, "courier");
- win32family->faces = g_slist_append (win32family->faces, win32face);
- }
- g_free (p);
-#endif
+ PING (("g_slist_length(win32family->faces)=%d", g_slist_length (win32family->faces)));
}
/* Given a LOGFONTW and size, make a matching LOGFONTW corresponding to