summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2002-09-21 11:28:59 +0000
committerTor Lillqvist <tml@src.gnome.org>2002-09-21 11:28:59 +0000
commitc418148dcb0964ac602c7f6104d24e51df07d813 (patch)
tree829ddccbbe912cbff4b5e46d1759dfcb209e9875 /pango
parent162c80f96a88224bd11097c1a421a0d01371c4e8 (diff)
downloadpango-c418148dcb0964ac602c7f6104d24e51df07d813.tar.gz
Distribute specifically pango.aliases and pango.modules, not the whole
2002-09-21 Tor Lillqvist <tml@iki.fi> * pango-zip.sh.in: Distribute specifically pango.aliases and pango.modules, not the whole etc/pango which might contain editor backup files. * pango/pangowin32-private.h * pango/pangowin32*.c: Rename DEBUGGING to PANGO_WIN32_DEBUGGING. Use plain printf instrad of g_print in the PING macro for debugging output (to avoid UTF-8 requirement). * pango/pangowin32.h: Guard against redefinition of _WIN32_WINNT. * pango/pangowin32-private.h: Remove the FS_VIETNAMESE define, not needed. Rename PangoWin32Font::face to win32face. Add enum PangoWin32CoverageLanguageClass, used to classify PangoLanguages that might have locale-specific coverage of fonts (i.e. CJKV). Change PangoWin32Face::coverage into an array, coverages. Move some TrueType macro and struct defines from pangowin32.c here. Rename them a bit to match the names used in the specs better. Add declarations for new functions (see below). * pango/pangowin32.c (pango_win32_get_hfont): Convert LOGFONT::lfFaceName to UTF-8 before printing. (pango_win32_render): Revert the change from 2002-09-05. Characters not in a font are supposed to show up at this stage as invalid glyphs (usually a box). It's up to the higher layers to filter out TABs and other characters that shouldn't be visible. (pango_win32_get_name_header, pango_win32_get_name_record): New functions, to read the name table header and records from a TrueType font. (font_name_in): New function, checks if a font has a name in one of the spoecial-case languages, or actually locales (zh_TW, zh_CN, ja, ko, vi). Checks the TrueType name table. (pango_win32_font_calc_coverage): Take a PangoLanguage parameter, too. Use it to decide whether to hide the Unified CJKV Ideographs block in case the font is not for the specified locale. If so, the coverage for these characters is set to PANGO_COVERAGE_APPROXIMATE. * pango/pangowin32-fontmap.c: Remove PangoWin32FontMap::faces, unused. Remove dead _WE_WANT_GLOBAL_ALIASES_ code. Rename parent_class to font_map_parent_class to match pangox-fontmap.c. (get_family_name, get_family_name_lowercase): New functions. Search for an English name for a TrueType font, in case the font name in LOGFONT::lfFaceName is non-ASCII. (Can one assume that if it is ASCII, it is the English name? Do some TrueType fonts have different names in French, German, etc, and does the system return these if the locale is set to use French, German, etc?) (pango_win32_insert_font): Don't store LOGFONTs that differ only in charset. What charset we specify when calling CreateFontIndirect() is irrelevant, as we are going to use ExtTextOutW() anyway, i.e. Unicode. Use the English family name from get_family_name_lowercase(), not the one returned in the LOGFONT from font enumeration. Bypass the code that sets up the mapping for monospace, serif and sans, and the recignition of plain "courier" for "courier new". We need a pango.aliases anyhow, so let it handle that. (pango_win32_coverage_language_classify): New function. (pango_win32_font_entry_set_coverage, pango_win32_font_entry_get_coverage): Take also a PangoLanguage parameter, use the corresponding entry in the PangoWin32Face::coverages array. * pango/pango-utils.c (pango_get_lib_subdirectory, pango_get_sysconf_subdirectory): Fix doc comment on Win32 behaviour.
Diffstat (limited to 'pango')
-rw-r--r--pango/pango-utils.c9
-rw-r--r--pango/pangowin32-fontmap.c475
-rw-r--r--pango/pangowin32-private.h140
-rw-r--r--pango/pangowin32.c308
-rw-r--r--pango/pangowin32.h2
5 files changed, 551 insertions, 383 deletions
diff --git a/pango/pango-utils.c b/pango/pango-utils.c
index bdb13cdb..29593ea2 100644
--- a/pango/pango-utils.c
+++ b/pango/pango-utils.c
@@ -648,7 +648,8 @@ G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
*
* On Unix, returns the name of the "pango" subdirectory of SYSCONFDIR
* (which is set at compile time). On Win32, returns a subdirectory of
- * the Pango installation directory.
+ * the Pango installation directory (which is deduced at run time from
+ * the DLL's location, or stored in the Registry).
*
* Return value: the Pango sysconf directory. The returned string should
* not be freed.
@@ -674,9 +675,9 @@ pango_get_sysconf_subdirectory (void)
*
* On Unix, returns the name of the "pango" subdirectory of LIBDIR
* (which is set at compile time). On Win32, returns the Pango
- * installation directory (which is set at installation time, and
- * stored in the registry). The returned string should not be
- * freed.
+ * installation directory (which is deduced at run time from the DLL's
+ * location, or stored in the Registry). The returned string should
+ * not be freed.
*
* Return value: the Pango lib directory. The returned string should
* not be freed.
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 45b8e68f..5f70f5d2 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -51,12 +51,9 @@ struct _PangoWin32FontMap
PangoWin32FontCache *font_cache;
GQueue *freed_fonts;
- /* Map Pango family names tp PangoWin32Family structs */
+ /* Map Pango family names to PangoWin32Family structs */
GHashTable *families;
- /* Maps the family and style of a face to a PangoWin32Face struct */
- GHashTable *faces;
-
/* Map LOGFONTS (taking into account only the lfFaceName, lfItalic
* and lfWeight fields) to PangoWin32SizeInfo structs.
*/
@@ -109,14 +106,10 @@ static void pango_win32_font_map_list_families (PangoFontMap
static void pango_win32_fontmap_cache_clear (PangoWin32FontMap *win32fontmap);
-#ifdef _WE_WANT_GLOBAL_ALIASES_
-static void pango_win32_font_map_read_aliases (PangoWin32FontMap *win32fontmap);
-#endif
-
static void pango_win32_insert_font (PangoWin32FontMap *fontmap,
LOGFONT *lfp);
-static PangoFontClass *parent_class; /* Parent class structure for PangoWin32FontMap */
+static PangoFontClass *font_map_parent_class; /* Parent class structure for PangoWin32FontMap */
static GType
pango_win32_font_map_get_type (void)
@@ -146,9 +139,9 @@ pango_win32_font_map_get_type (void)
return object_type;
}
-/* A hash function for LOGFONTs that takes into consideration
- * only those fields that indicate a specific .ttf file is in
- * use. Dunno how correct this is.
+/* A hash function for LOGFONTs that takes into consideration only
+ * those fields that indicate a specific .ttf file is in use:
+ * lfFaceName, lfItalic and lfWeight. Dunno how correct this is.
*/
static guint
@@ -179,9 +172,8 @@ static void
pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
{
win32fontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
- win32fontmap->size_infos = g_hash_table_new (logfont_nosize_hash, logfont_nosize_equal);
- win32fontmap->faces = g_hash_table_new ((GHashFunc)pango_font_description_hash,
- (GEqualFunc)pango_font_description_equal);
+ win32fontmap->size_infos =
+ g_hash_table_new (logfont_nosize_hash, logfont_nosize_equal);
win32fontmap->n_fonts = 0;
}
@@ -190,7 +182,7 @@ pango_win32_font_map_class_init (PangoFontMapClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
- parent_class = g_type_class_peek_parent (class);
+ font_map_parent_class = g_type_class_peek_parent (class);
object_class->finalize = pango_win32_font_map_finalize;
class->load_font = pango_win32_font_map_load_font;
@@ -226,7 +218,10 @@ pango_win32_enum_proc (LOGFONT *lfp,
lf = *lfp;
- EnumFontFamiliesExA (pango_win32_hdc, &lf, (FONTENUMPROC) pango_win32_inner_enum_proc, lParam, 0);
+ PING(("%s", lf.lfFaceName));
+ EnumFontFamiliesExA (pango_win32_hdc, &lf,
+ (FONTENUMPROC) pango_win32_inner_enum_proc,
+ lParam, 0);
return 1;
}
@@ -251,7 +246,7 @@ pango_win32_font_map_for_display (void)
if (fontmap != NULL)
return PANGO_FONT_MAP (fontmap);
- fontmap = (PangoWin32FontMap *)g_type_create_instance (PANGO_TYPE_WIN32_FONT_MAP);
+ fontmap = (PangoWin32FontMap *) g_type_create_instance (PANGO_TYPE_WIN32_FONT_MAP);
fontmap->font_cache = pango_win32_font_cache_new ();
fontmap->freed_fonts = g_queue_new ();
@@ -260,10 +255,6 @@ pango_win32_font_map_for_display (void)
logfont.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc, 0, 0);
-#ifdef _WE_WANT_GLOBAL_ALIASES_
- pango_win32_font_map_read_aliases (fontmap);
-#endif
-
fontmap->resolution = PANGO_SCALE / GetDeviceCaps (pango_win32_hdc, LOGPIXELSY) * 72.0;
return PANGO_FONT_MAP (fontmap);
@@ -296,8 +287,7 @@ pango_win32_font_map_finalize (GObject *object)
pango_win32_font_cache_free (win32fontmap->font_cache);
- /* ??? */
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (font_map_parent_class)->finalize (object);
}
/*
@@ -305,8 +295,8 @@ pango_win32_font_map_finalize (GObject *object)
*/
static void
pango_win32_family_list_faces (PangoFontFamily *family,
- PangoFontFace ***faces,
- int *n_faces)
+ PangoFontFace ***faces,
+ int *n_faces)
{
PangoWin32Family *win32family = PANGO_WIN32_FAMILY (family);
@@ -380,9 +370,9 @@ list_families_foreach (gpointer key,
}
static void
-pango_win32_font_map_list_families (PangoFontMap *fontmap,
+pango_win32_font_map_list_families (PangoFontMap *fontmap,
PangoFontFamily ***families,
- int *n_families)
+ int *n_families)
{
GSList *family_list = NULL;
GSList *tmp_list;
@@ -415,7 +405,7 @@ pango_win32_font_map_list_families (PangoFontMap *fontmap,
static PangoWin32Family *
pango_win32_get_font_family (PangoWin32FontMap *win32fontmap,
- const char *family_name)
+ const char *family_name)
{
PangoWin32Family *win32family = g_hash_table_lookup (win32fontmap->families, family_name);
if (!win32family)
@@ -490,237 +480,169 @@ pango_win32_font_map_load_font (PangoFontMap *fontmap,
if (!result)
{
- PangoWin32Font *win32font;
-
- PING((""));
- win32font = pango_win32_font_new (fontmap, &best_match->logfont, size);
+ PangoWin32Font *win32font = pango_win32_font_new (fontmap, &best_match->logfont, size);
+
win32font->fontmap = fontmap;
- win32font->entry = best_match;
+ win32font->win32face = best_match;
best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, win32font);
result = (PangoFont *)win32font;
}
}
+ else
+ PING(("no best match!"));
}
g_free (name);
return result;
}
-#if _WE_WANT_GLOBAL_ALIASES_
-static void
-pango_win32_font_map_read_alias_file (PangoWin32FontMap *win32fontmap,
- const char *filename)
+static gchar *
+get_family_name (LOGFONT *lfp)
{
- PangoWin32Face *face = NULL;
- FILE *infile;
- char **faces;
- int lineno = 0;
- int nfaces;
- int i;
-
- infile = fopen (filename, "r");
- if (infile)
- {
- GString *line_buf = g_string_new (NULL);
- GString *tmp_buf = g_string_new (NULL);
-
- while (pango_read_line (infile, line_buf))
- {
- PangoWin32Family *family_entry;
- PangoStyle style;
- PangoVariant variant;
- PangoWeight weight;
- PangoStretch stretch;
-
- const char *p = line_buf->str;
-
- lineno++;
-
- if (!pango_skip_space (&p))
- continue;
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ HFONT hfont;
+ HFONT oldhfont;
- face = g_object_new g_object_new (PANGO_WIN32_TYPE_FACE, NULL);
- face->n_fonts = 0;
- face->description = pango_font_description_new ();
-
- g_string_ascii_down (tmp_buf);
- pango_font_description_set_family (face->description, tmp_buf->str);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ struct name_header header;
+ struct name_record record;
- if (!pango_parse_style (tmp_buf->str, &style, TRUE))
- goto error;
- pango_font_description_set_style (font_entry->description, style);
+ gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
+ gint name_ix;
+ gchar *codeset;
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ gchar *string = NULL;
+ gchar *name;
- if (!pango_parse_variant (tmp_buf->str, &variant, TRUE))
- goto error;
- pango_font_description_set_variant (font_entry->description, variant);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ gint i, l;
+ gsize nbytes;
- if (!pango_parse_weight (tmp_buf->str, &weight, TRUE))
- goto error;
- pango_font_description_set_weight (font_entry->description, weight);
-
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ /* If lfFaceName is ASCII, assume it is the common (English) name
+ * for the font. Is this valid? Do some TrueType fonts have
+ * different names in French, German, etc, and does the system
+ * return these if the locale is set to use French, German, etc?
+ */
+ l = strlen (lfp->lfFaceName);
+ for (i = 0; i < l; i++)
+ if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
+ break;
- if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE))
- goto error;
- pango_font_description_set_stretch (font_entry->description, stretch);
+ if (i == l)
+ return g_strdup (lfp->lfFaceName);
- if (!pango_scan_string (&p, tmp_buf))
- goto error;
+ if ((hfont = CreateFontIndirect (lfp)) == NULL)
+ goto fail0;
+
+ if ((oldhfont = SelectObject (pango_win32_hdc, hfont)) == NULL)
+ goto fail1;
- /* Remove excess whitespace and check for complete fields */
+ if (!pango_win32_get_name_header (pango_win32_hdc, &header))
+ goto fail2;
+
+ PING (("%d name records", header.num_records));
-
- faces = g_strsplit (tmp_buf->str, ",", -1);
- nfaces = 0;
- for (i = 0; faces[i]; i++)
- {
- char *trimmed = pango_trim_string (faces[i]);
- g_free (faces[i]);
- faces[i] = trimmed;
- nfaces++;
- }
- font_entry->lfp = g_new0 (LOGFONT, nfaces);
- font_entry->n_fonts = nfaces;
- for (i = 0; i < nfaces; i++)
- {
- strcpy (font_entry->lfp[i].lfFaceName, faces[i]);
-
- /* Set LOGFONT properties based on the PangoFontDescription */
- if (font_entry->description.style == PANGO_STYLE_OBLIQUE ||
- font_entry->description.style == PANGO_STYLE_ITALIC)
- font_entry->lfp[i].lfItalic = TRUE;
-
- /* Quantize weight */
- if (font_entry->description.weight <=
- (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2)
- font_entry->lfp[i].lfWeight = FW_ULTRALIGHT;
- else if (font_entry->description.weight <=
- (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2)
- font_entry->lfp[i].lfWeight = FW_LIGHT;
- else if (font_entry->description.weight <=
- (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2)
- font_entry->lfp[i].lfWeight = FW_NORMAL;
- else if (font_entry->description.weight <=
- (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2)
- font_entry->lfp[i].lfWeight = FW_BOLD;
- else if (font_entry->description.weight <=
- (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2)
- font_entry->lfp[i].lfWeight = FW_ULTRABOLD;
- else
- font_entry->lfp[i].lfWeight = FW_HEAVY;
-
- font_entry->lfp[i].lfQuality = ANTIALIASED_QUALITY;
-
- /* Stretch ? */
-
- /* Charset is ignored anyway when used with the widechar
- * API?
- */
- font_entry->lfp[i].lfCharSet = DEFAULT_CHARSET;
- }
- g_strfreev (faces);
-
- /* Insert the font entry into our structures */
+ for (i = 0; i < header.num_records; i++)
+ {
+ if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
+ goto fail2;
- family_entry = pango_win32_get_family_entry (win32fontmap, font_entry->description.family_name);
- family_entry->font_entries = g_slist_prepend (family_entry->font_entries, font_entry);
- win32fontmap->n_fonts++;
+ if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
+ continue;
- g_free (font_entry->description.family_name);
- font_entry->description.family_name = family_entry->family_name;
- font_entry->cached_fonts = NULL;
- font_entry->coverage = NULL;
- }
+ PING(("platform:%d encoding:%d language:%04x name_id:%d",
+ record.platform_id, record.encoding_id, record.language_id, record.name_id));
+
+ if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
+ record.platform_id == ISO_PLATFORM_ID)
+ unicode_ix = i;
+ else if (record.platform_id == MACINTOSH_PLATFORM_ID &&
+ record.encoding_id == 0 && /* Roman */
+ record.language_id == 0) /* English */
+ mac_ix = i;
+ else if (record.platform_id == MICROSOFT_PLATFORM_ID)
+ if ((microsoft_ix == -1 ||
+ PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
+ (record.encoding_id == SYMBOL_ENCODING_ID ||
+ record.encoding_id == UNICODE_ENCODING_ID ||
+ record.encoding_id == UCS4_ENCODING_ID))
+ microsoft_ix = i;
+ }
- if (ferror (infile))
- g_warning ("Error reading '%s': %s", filename, g_strerror(errno));
+ if (microsoft_ix >= 0)
+ name_ix = microsoft_ix;
+ else if (mac_ix >= 0)
+ name_ix = mac_ix;
+ else if (unicode_ix >= 0)
+ name_ix = unicode_ix;
+ else
+ goto fail2;
+
+ if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
+ goto fail2;
+
+ string = g_malloc (record.string_length + 1);
+ if (GetFontData (pango_win32_hdc, NAME,
+ header.string_storage_offset + record.string_offset,
+ string, record.string_length) != record.string_length)
+ goto fail2;
+
+ string[record.string_length] = '\0';
+
+ if (name_ix == microsoft_ix)
+ if (record.encoding_id == SYMBOL_ENCODING_ID ||
+ record.encoding_id == UNICODE_ENCODING_ID)
+ codeset = "UTF-16BE";
+ else
+ codeset = "UCS-4BE";
+ else if (name_ix == mac_ix)
+ codeset = "MacRoman";
+ else /* name_ix == unicode_ix */
+ codeset = "UCS-4BE";
+
+ name = g_convert (string, record.string_length, "UTF-8", codeset, NULL, &nbytes, NULL);
+ if (name == NULL)
+ goto fail2;
+ g_free (string);
- goto out;
+ PING(("%s", name));
- error:
- if (font_entry)
- {
- if (font_entry->lfp)
- g_free (font_entry->lfp);
- if (font_entry->description.family_name)
- g_free (font_entry->description.family_name);
- g_free (font_entry);
- }
+ SelectObject (pango_win32_hdc, oldhfont);
+ DeleteObject (hfont);
- g_warning ("Error parsing line %d of alias file '%s'", lineno, filename);
+ return name;
- out:
- g_string_free (tmp_buf, TRUE);
- g_string_free (line_buf, TRUE);
+ fail2:
+ g_free (string);
+ SelectObject (pango_win32_hdc, oldhfont);
- fclose (infile);
- }
+ fail1:
+ DeleteObject (hfont);
+
+ fail0:
+ return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
}
-static void
-pango_win32_font_map_read_aliases (PangoWin32FontMap *win32fontmap)
+static gchar *
+get_family_name_lowercase (LOGFONT *lfp)
{
- char **files;
- char *files_str = pango_config_key_get ("PangoWin32/AliasFiles");
- char *home;
- char *tmp_str;
- int n;
-
- if (!files_str)
- {
- home = g_get_home_dir ();
- if (home && *home)
- files_str = g_strconcat (home, "\\.pangowin32_aliases;", NULL);
-
- tmp_str = g_strconcat (files_str, pango_get_sysconf_subdirectory (),
- "\\pangowin32.aliases",
- NULL);
- g_free (files_str);
- files_str = tmp_str;
- }
-
- files = pango_split_file_list (files_str);
-
- n = 0;
- while (files[n])
- n++;
+ gchar *family = get_family_name (lfp);
+ gchar *lower = g_ascii_strdown (family, -1);
- while (n-- > 0)
- pango_win32_font_map_read_alias_file (fontmap, files[n]);
-
- g_strfreev (files);
- g_free (files_str);
+ g_free (family);
+ return lower;
}
-#endif /* __WE_WANT_GLOVAL_ALIASES__ */
-
-/* This inserts the given font into the SizeInfo table.
- * If a SizeInfo already exists with the same typeface name, then the
- * fontname is added to the SizeInfos list of fontnames, else a new SizeInfo
- * is created and inserted in the table.
+/* This inserts the given font into the size_infos table. If a SizeInfo
+ * already exists with the same typeface name, then the font is added
+ * to the SizeInfos list, else a new SizeInfo is created and inserted
+ * in the table.
*/
static void
pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
LOGFONT *lfp)
{
- LOGFONT *lfp2;
+ LOGFONT *lfp2 = NULL;
PangoFontDescription *description;
- char *family_name;
- GSList *tmp_list;
+ gchar *family_name;
PangoWin32Family *font_family;
PangoWin32Face *win32face;
PangoWin32SizeInfo *size_info;
@@ -728,17 +650,13 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
PangoVariant variant;
PangoWeight weight;
PangoStretch stretch;
- int i;
+ GSList *tmp_list;
+ gint i;
- PING(("lfp.face=%s,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight));
+ PING(("face=%s,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight));
/* First insert the LOGFONT into the list of LOGFONTs for the typeface name
*/
- lfp2 = g_new (LOGFONT, 1);
- *lfp2 = *lfp;
- /* lfp2->lfFaceName is an array of CHAR, change inplace */
- for (i = 0; i < LF_FACESIZE; i++)
- lfp2->lfFaceName[i] = g_ascii_tolower (lfp2->lfFaceName[i]);
size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp);
if (!size_info)
{
@@ -746,15 +664,47 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
size_info = g_new (PangoWin32SizeInfo, 1);
size_info->logfonts = NULL;
+ lfp2 = g_new (LOGFONT, 1);
+ *lfp2 = *lfp;
g_hash_table_insert (win32fontmap->size_infos, lfp2, size_info);
}
+ else
+ {
+ /* Don't store logfonts that differ only in charset
+ */
+ tmp_list = size_info->logfonts;
+ while (tmp_list)
+ {
+ LOGFONT *rover = tmp_list->data;
+
+ /* We know that lfWeight, lfItalic and lfFaceName match. We
+ * don't check lfHeight and lfWidth, those are used
+ * when creating a font.
+ */
+ if (rover->lfEscapement == lfp->lfEscapement &&
+ rover->lfOrientation == lfp->lfOrientation &&
+ rover->lfUnderline == lfp->lfUnderline &&
+ rover->lfStrikeOut == lfp->lfStrikeOut)
+ return;
+
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ if (lfp2 == NULL)
+ {
+ lfp2 = g_new (LOGFONT, 1);
+ *lfp2 = *lfp;
+ }
size_info->logfonts = g_slist_prepend (size_info->logfonts, lfp2);
- /* Convert the LOGFONT into a PangoFontDescription */
-
- family_name = lfp2->lfFaceName;
-
+ PING(("g_slist_length(size_info->logfonts)=%d", g_slist_length(size_info->logfonts)));
+
+ family_name = get_family_name_lowercase (lfp);
+
+ /* Convert the LOGFONT into a PangoFontDescription
+ */
if (!lfp2->lfItalic)
style = PANGO_STYLE_NORMAL;
else
@@ -762,9 +712,9 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
variant = PANGO_VARIANT_NORMAL;
- /* The PangoWeight values PANGO_WEIGHT_* map exactly do Windows FW_* values.
- * Is this on purpose? Quantize the weight to exact PANGO_WEIGHT_*
- * values. Is this a good idea?
+ /* The PangoWeight values PANGO_WEIGHT_* map exactly do Windows FW_*
+ * values. Is this on purpose? Quantize the weight to exact
+ * PANGO_WEIGHT_* values. Is this a good idea?
*/
if (lfp2->lfWeight == FW_DONTCARE)
weight = PANGO_WEIGHT_NORMAL;
@@ -795,7 +745,10 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
pango_font_description_get_weight (win32face->description) == weight &&
pango_font_description_get_stretch (win32face->description) == stretch &&
pango_font_description_get_variant (win32face->description) == variant)
- return;
+ {
+ PING(("returning early"));
+ return;
+ }
tmp_list = tmp_list->next;
}
@@ -807,20 +760,18 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
pango_font_description_set_stretch (description, stretch);
pango_font_description_set_variant (description, variant);
- /*
- * Create the FontFace
- */
win32face = g_object_new (PANGO_WIN32_TYPE_FACE, NULL);
win32face->description = description;
win32face->cached_fonts = NULL;
- win32face->coverage = NULL;
+
+ for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++)
+ win32face->coverages[i] = NULL;
win32face->logfont = *lfp;
win32face->unicode_table = NULL;
- for (i = 0; i < LF_FACESIZE; i++)
- win32face->logfont.lfFaceName[i] = g_ascii_tolower (win32face->logfont.lfFaceName[i]);
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
+#if 0 /* Use pango.aliases instead */
/*
* There are magic family names coming from the X implementation.
* They can be simply mapped to lfPitchAndFamily flag of the logfont
@@ -832,16 +783,19 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
switch (lfp->lfPitchAndFamily & (0x0F << 4)) /* bit 4...7 */
{
case FF_MODERN : /* monospace */
+ PING(("monospace"));
font_family = pango_win32_get_font_family (win32fontmap, "monospace");
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
break;
case FF_ROMAN : /* serif */
+ PING(("serif"));
font_family = pango_win32_get_font_family (win32fontmap, "serif");
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
break;
case FF_SWISS : /* sans */
+ PING(("sans"));
font_family = pango_win32_get_font_family (win32fontmap, "sans");
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
@@ -857,6 +811,7 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
}
+#endif
}
/* Given a LOGFONT and size, make a matching LOGFONT corresponding to
@@ -919,11 +874,29 @@ pango_win32_make_matching_logfont (PangoFontMap *fontmap,
*out = *lfp; /* Whatever. We need to pass something... */
}
+gint
+pango_win32_coverage_language_classify (PangoLanguage *lang)
+{
+ if (pango_language_matches (lang, "zh-tw"))
+ return PANGO_WIN32_COVERAGE_ZH_TW;
+ else if (pango_language_matches (lang, "zh-cn"))
+ return PANGO_WIN32_COVERAGE_ZH_CN;
+ else if (pango_language_matches (lang, "ja"))
+ return PANGO_WIN32_COVERAGE_JA;
+ else if (pango_language_matches (lang, "ko"))
+ return PANGO_WIN32_COVERAGE_KO;
+ else if (pango_language_matches (lang, "vi"))
+ return PANGO_WIN32_COVERAGE_VI;
+ else
+ return PANGO_WIN32_COVERAGE_UNSPEC;
+}
+
void
pango_win32_font_entry_set_coverage (PangoWin32Face *face,
- PangoCoverage *coverage)
+ PangoCoverage *coverage,
+ PangoLanguage *lang)
{
- face->coverage = pango_coverage_ref (coverage);
+ face->coverages[pango_win32_coverage_language_classify (lang)] = pango_coverage_ref (coverage);
}
static PangoFontDescription *
@@ -989,12 +962,14 @@ pango_win32_face_get_type (void)
}
PangoCoverage *
-pango_win32_font_entry_get_coverage (PangoWin32Face *face)
+pango_win32_font_entry_get_coverage (PangoWin32Face *face,
+ PangoLanguage *lang)
{
- if (face->coverage)
+ gint i = pango_win32_coverage_language_classify (lang);
+ if (face->coverages[i])
{
- pango_coverage_ref (face->coverage);
- return face->coverage;
+ pango_coverage_ref (face->coverages[i]);
+ return face->coverages[i];
}
return NULL;
@@ -1002,7 +977,7 @@ pango_win32_font_entry_get_coverage (PangoWin32Face *face)
void
pango_win32_font_entry_remove (PangoWin32Face *face,
- PangoFont *font)
+ PangoFont *font)
{
face->cached_fonts = g_slist_remove (face->cached_fonts, font);
}
@@ -1025,8 +1000,8 @@ pango_win32_font_map_get_font_cache (PangoFontMap *font_map)
}
void
-pango_win32_fontmap_cache_add (PangoFontMap *fontmap,
- PangoWin32Font *win32font)
+pango_win32_fontmap_cache_add (PangoFontMap *fontmap,
+ PangoWin32Font *win32font)
{
PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap);
@@ -1042,8 +1017,8 @@ pango_win32_fontmap_cache_add (PangoFontMap *fontmap,
}
void
-pango_win32_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoWin32Font *win32font)
+pango_win32_fontmap_cache_remove (PangoFontMap *fontmap,
+ PangoWin32Font *win32font)
{
PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap);
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index f0d21914..dc1f5faa 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -2,7 +2,7 @@
* pangowin32-private.h:
*
* Copyright (C) 1999 Red Hat Software
- * Copyright (C) 2000 Tor Lillqvist
+ * Copyright (C) 2000-2002 Tor Lillqvist
* Copyright (C) 2001 Alexander Larsson
*
* This library is free software; you can redistribute it and/or
@@ -24,30 +24,38 @@
#ifndef __PANGOWIN32_PRIVATE_H__
#define __PANGOWIN32_PRIVATE_H__
-#define DEBUGGING 0
+/* Define if you want copious debugging output. */
+/* #define PANGO_WIN32_DEBUGGING 1 */
-#if defined(DEBUGGING) && DEBUGGING
+#ifdef PANGO_WIN32_DEBUGGING
#ifdef __GNUC__
#define PING(printlist) \
-(g_print ("%s:%d ", __PRETTY_FUNCTION__, __LINE__), \
- g_print printlist, \
- g_print ("\n"))
+(printf ("%s:%d ", __PRETTY_FUNCTION__, __LINE__), \
+ printf printlist, \
+ printf ("\n"))
#else
#define PING(printlist) \
-(g_print ("%s:%d ", __FILE__, __LINE__), \
- g_print printlist, \
- g_print ("\n"))
+(printf ("%s:%d ", __FILE__, __LINE__), \
+ printf printlist, \
+ printf ("\n"))
#endif
-#else /* !DEBUGGING */
+#else /* !PANGO_WIN32_DEBUGGING */
#define PING(printlist)
#endif
#include "pango-modules.h"
#include "pangowin32.h"
-#ifndef FS_VIETNAMESE
-#define FS_VIETNAMESE 0x100
-#endif
+typedef enum
+ {
+ PANGO_WIN32_COVERAGE_UNSPEC,
+ PANGO_WIN32_COVERAGE_ZH_TW,
+ PANGO_WIN32_COVERAGE_ZH_CN,
+ PANGO_WIN32_COVERAGE_JA,
+ PANGO_WIN32_COVERAGE_KO,
+ PANGO_WIN32_COVERAGE_VI,
+ PANGO_WIN32_N_COVERAGES
+ } PangoWin32CoverageLanguageClass;
typedef struct _PangoWin32Font PangoWin32Font;
typedef struct _PangoWin32Face PangoWin32Face;
@@ -68,7 +76,7 @@ struct _PangoWin32Font
gint tm_descent;
gint tm_overhang;
- PangoWin32Face *entry;
+ PangoWin32Face *win32face;
/* If TRUE, font is in cache of recently unused fonts and not otherwise
* in use.
@@ -83,8 +91,7 @@ struct _PangoWin32Face
LOGFONT logfont;
PangoFontDescription *description;
- PangoCoverage *coverage;
-
+ PangoCoverage *coverages[PANGO_WIN32_N_COVERAGES];
char *face_name;
gpointer unicode_table;
@@ -99,24 +106,95 @@ struct _PangoWin32GlyphInfo
};
-PangoWin32Font *pango_win32_font_new (PangoFontMap *fontmap,
- const LOGFONT *lfp,
- int size);
-PangoMap * pango_win32_get_shaper_map (PangoLanguage *lang);
-void pango_win32_make_matching_logfont (PangoFontMap *fontmap,
- const LOGFONT *lfp,
- int size,
- LOGFONT *out);
-PangoCoverage * pango_win32_font_entry_get_coverage (PangoWin32Face *face);
+/* TrueType defines: */
+
+#define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
+ (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
+
+#define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
+#define CMAP_HEADER_SIZE 4
+
+#define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
+#define NAME_HEADER_SIZE 6
+
+#define ENCODING_TABLE_SIZE 8
+
+#define APPLE_UNICODE_PLATFORM_ID 0
+#define MACINTOSH_PLATFORM_ID 1
+#define ISO_PLATFORM_ID 2
+#define MICROSOFT_PLATFORM_ID 3
+
+#define SYMBOL_ENCODING_ID 0
+#define UNICODE_ENCODING_ID 1
+#define UCS4_ENCODING_ID 10
+
+struct cmap_encoding_subtable
+{ /* Must be packed! */
+ guint16 platform_id;
+ guint16 encoding_id;
+ guint32 offset;
+};
+
+struct type_4_cmap
+{ /* Must be packed! */
+ guint16 format;
+ guint16 length;
+ guint16 language;
+ guint16 seg_count_x_2;
+ guint16 search_range;
+ guint16 entry_selector;
+ guint16 range_shift;
+
+ guint16 reserved;
+
+ guint16 arrays[1];
+};
+
+struct name_header
+{
+ guint16 format_selector;
+ guint16 num_records;
+ guint16 string_storage_offset;
+};
+
+struct name_record
+{
+ guint16 platform_id;
+ guint16 encoding_id;
+ guint16 language_id;
+ guint16 name_id;
+ guint16 string_length;
+ guint16 string_offset;
+};
+
+PangoWin32Font *pango_win32_font_new (PangoFontMap *fontmap,
+ const LOGFONT *lfp,
+ int size);
+PangoMap * pango_win32_get_shaper_map (PangoLanguage *lang);
+void pango_win32_make_matching_logfont (PangoFontMap *fontmap,
+ const LOGFONT *lfp,
+ int size,
+ LOGFONT *out);
+PangoCoverage * pango_win32_font_entry_get_coverage (PangoWin32Face *face,
+ PangoLanguage *lang);
void pango_win32_font_entry_set_coverage (PangoWin32Face *face,
- PangoCoverage *coverage);
+ PangoCoverage *coverage,
+ PangoLanguage *lang);
void pango_win32_font_entry_remove (PangoWin32Face *face,
- PangoFont *font);
+ PangoFont *font);
+
+void pango_win32_fontmap_cache_add (PangoFontMap *fontmap,
+ PangoWin32Font *xfont);
+void pango_win32_fontmap_cache_remove (PangoFontMap *fontmap,
+ PangoWin32Font *xfont);
+
+gint pango_win32_coverage_language_classify (PangoLanguage *lang);
-void pango_win32_fontmap_cache_add (PangoFontMap *fontmap,
- PangoWin32Font *xfont);
-void pango_win32_fontmap_cache_remove (PangoFontMap *fontmap,
- PangoWin32Font *xfont);
+gboolean pango_win32_get_name_header (HDC hdc,
+ struct name_header *header);
+gboolean pango_win32_get_name_record (HDC hdc,
+ gint i,
+ struct name_record *record);
extern HDC pango_win32_hdc;
extern OSVERSIONINFO pango_win32_os_version_info;
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index b355fde2..5bf3c6d3 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -60,7 +60,8 @@ static PangoFontDescription *pango_win32_font_describe (PangoFont
static PangoCoverage *pango_win32_font_get_coverage (PangoFont *font,
PangoLanguage *lang);
static void pango_win32_font_calc_coverage (PangoFont *font,
- PangoCoverage *coverage);
+ PangoCoverage *coverage,
+ PangoLanguage *lang);
static PangoEngineShape *pango_win32_font_find_shaper (PangoFont *font,
PangoLanguage *lang,
guint32 ch);
@@ -92,7 +93,10 @@ pango_win32_get_hfont (PangoFont *font)
win32font->hfont = pango_win32_font_cache_load (cache, &win32font->logfont);
if (!win32font->hfont)
{
- g_warning ("Cannot load font '%s\n", win32font->logfont.lfFaceName);
+ gchar *face_utf8 = g_locale_to_utf8 (win32font->logfont.lfFaceName,
+ -1, NULL, NULL, NULL);
+ g_warning ("Cannot load font '%s\n", face_utf8);
+ g_free (face_utf8);
return NULL;
}
@@ -232,15 +236,15 @@ pango_win32_font_new (PangoFontMap *fontmap,
* Render a PangoGlyphString onto a Windows DC
*/
void
-pango_win32_render (HDC hdc,
- PangoFont *font,
- PangoGlyphString *glyphs,
- int x,
- int y)
+pango_win32_render (HDC hdc,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ int x,
+ int y)
{
HFONT old_hfont = NULL;
HFONT hfont;
- int i, num_valid_glyphs;
+ int i;
guint16 *glyph_indexes;
INT *dX;
@@ -255,23 +259,16 @@ pango_win32_render (HDC hdc,
glyph_indexes = g_new (guint16, glyphs->num_glyphs);
dX = g_new (INT, glyphs->num_glyphs);
- num_valid_glyphs = 0;
for (i = 0; i <glyphs->num_glyphs; i++)
{
- /* Prevent from displaying squares for nonexistent glyphs */
- if (glyphs->glyphs[i].glyph != 0)
- {
- /* Glyph is actually handled */
- glyph_indexes[num_valid_glyphs] = glyphs->glyphs[i].glyph;
- dX[num_valid_glyphs] = glyphs->glyphs[i].geometry.width / PANGO_SCALE;
- num_valid_glyphs++;
- }
+ glyph_indexes[i] = glyphs->glyphs[i].glyph;
+ dX[i] = glyphs->glyphs[i].geometry.width / PANGO_SCALE;
}
ExtTextOutW (hdc, x, y,
ETO_GLYPH_INDEX,
NULL,
- glyph_indexes, num_valid_glyphs,
+ glyph_indexes, glyphs->num_glyphs,
dX);
SelectObject (hdc, old_hfont); /* restore */
@@ -350,8 +347,8 @@ pango_win32_font_get_glyph_extents (PangoFont *font,
}
static PangoFontMetrics *
-pango_win32_font_get_metrics (PangoFont *font,
- PangoLanguage *language)
+pango_win32_font_get_metrics (PangoFont *font,
+ PangoLanguage *language)
{
HFONT hfont;
TEXTMETRIC tm;
@@ -453,8 +450,8 @@ pango_win32_font_finalize (GObject *object)
if (win32font->hfont != NULL)
pango_win32_font_cache_unload (cache, win32font->hfont);
- if (win32font->entry)
- pango_win32_font_entry_remove (win32font->entry, PANGO_FONT (win32font));
+ if (win32font->win32face)
+ pango_win32_font_entry_remove (win32font->win32face, PANGO_FONT (win32font));
g_hash_table_destroy (win32font->glyph_info);
@@ -469,7 +466,7 @@ pango_win32_font_describe (PangoFont *font)
PangoFontDescription *desc;
PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
- desc = pango_font_description_copy (win32font->entry->description);
+ desc = pango_font_description_copy (win32font->win32face->description);
pango_font_description_set_size (desc, win32font->size);
return desc;
@@ -491,28 +488,28 @@ pango_win32_get_shaper_map (PangoLanguage *lang)
}
static PangoCoverage *
-pango_win32_font_get_coverage (PangoFont *font,
+pango_win32_font_get_coverage (PangoFont *font,
PangoLanguage *lang)
{
PangoCoverage *coverage;
PangoWin32Font *win32font = (PangoWin32Font *)font;
- coverage = pango_win32_font_entry_get_coverage (win32font->entry);
+ coverage = pango_win32_font_entry_get_coverage (win32font->win32face, lang);
if (!coverage)
{
coverage = pango_coverage_new ();
- pango_win32_font_calc_coverage (font, coverage);
+ pango_win32_font_calc_coverage (font, coverage, lang);
- pango_win32_font_entry_set_coverage (win32font->entry, coverage);
+ pango_win32_font_entry_set_coverage (win32font->win32face, coverage, lang);
}
return coverage;
}
static PangoEngineShape *
-pango_win32_font_find_shaper (PangoFont *font,
+pango_win32_font_find_shaper (PangoFont *font,
PangoLanguage *lang,
- guint32 ch)
+ guint32 ch)
{
PangoMap *shape_map = NULL;
@@ -546,10 +543,10 @@ pango_win32_get_unknown_glyph (PangoFont *font)
* Render a #PangoLayoutLine onto a device context
*/
void
-pango_win32_render_layout_line (HDC hdc,
- PangoLayoutLine *line,
- int x,
- int y)
+pango_win32_render_layout_line (HDC hdc,
+ PangoLayoutLine *line,
+ int x,
+ int y)
{
GSList *tmp_list = line->runs;
PangoRectangle overall_rect;
@@ -650,10 +647,10 @@ pango_win32_render_layout_line (HDC hdc,
* Render a #PangoLayoutLine onto an X drawable
*/
void
-pango_win32_render_layout (HDC hdc,
- PangoLayout *layout,
- int x,
- int y)
+pango_win32_render_layout (HDC hdc,
+ PangoLayout *layout,
+ int x,
+ int y)
{
PangoRectangle logical_rect;
GSList *tmp_list;
@@ -776,48 +773,11 @@ pango_win32_get_item_properties (PangoItem *item,
}
}
-
-
-/* Various truetype defines: */
-
-#define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
- (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
-
-#define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
-#define CMAP_HEADER_SIZE 4
-#define ENCODING_TABLE_SIZE 8
-#define TABLE_4_HEADER_SIZE (sizeof (guint16)*6)
-
-#define UNICODE_PLATFORM_ID 3
-#define UNICODE_SPECIFIC_ID 1
-
-#pragma pack(1)
-
-struct encoding_table { /* Must be packed! */
- guint16 platform_id;
- guint16 encoding_id;
- guint32 offset;
-};
-
-struct type_4_table { /* Must be packed! */
- guint16 format;
- guint16 length;
- guint16 version;
- guint16 seg_count_x_2;
- guint16 search_range;
- guint16 entry_selector;
- guint16 range_shift;
-
- guint16 reserved;
-
- guint16 arrays[1];
-};
-
static guint
get_unicode_mapping_offset (HDC hdc)
{
guint16 n_tables;
- struct encoding_table *table;
+ struct cmap_encoding_subtable *table;
gint32 res;
int i;
guint32 offset;
@@ -837,8 +797,8 @@ get_unicode_mapping_offset (HDC hdc)
for (i = 0; i < n_tables; i++)
{
- if (table[i].platform_id == GUINT16_TO_BE (UNICODE_PLATFORM_ID) &&
- table[i].encoding_id == GUINT16_TO_BE (UNICODE_SPECIFIC_ID))
+ if (table[i].platform_id == GUINT16_TO_BE (MICROSOFT_PLATFORM_ID) &&
+ table[i].encoding_id == GUINT16_TO_BE (UNICODE_ENCODING_ID))
{
offset = GUINT32_FROM_BE (table[i].offset);
g_free (table);
@@ -849,14 +809,14 @@ get_unicode_mapping_offset (HDC hdc)
return 0;
}
-static struct type_4_table *
+static struct type_4_cmap *
get_unicode_mapping (HDC hdc)
{
guint32 offset;
guint32 res;
guint16 length;
guint16 *tbl, *tbl_end;
- struct type_4_table *table;
+ struct type_4_cmap *table;
/* FIXME: Could look here at the CRC for the font in the DC
and return a cached copy if the same */
@@ -881,7 +841,7 @@ get_unicode_mapping (HDC hdc)
table->format = GUINT16_FROM_BE (table->format);
table->length = GUINT16_FROM_BE (table->length);
- table->version = GUINT16_FROM_BE (table->version);
+ table->language = GUINT16_FROM_BE (table->language);
table->seg_count_x_2 = GUINT16_FROM_BE (table->seg_count_x_2);
table->search_range = GUINT16_FROM_BE (table->search_range);
table->entry_selector = GUINT16_FROM_BE (table->entry_selector);
@@ -906,28 +866,28 @@ get_unicode_mapping (HDC hdc)
}
static guint16 *
-get_id_range_offset (struct type_4_table *table)
+get_id_range_offset (struct type_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
return &table->arrays[seg_count*3];
}
static guint16 *
-get_id_delta (struct type_4_table *table)
+get_id_delta (struct type_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
return &table->arrays[seg_count*2];
}
static guint16 *
-get_start_count (struct type_4_table *table)
+get_start_count (struct type_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
return &table->arrays[seg_count*1];
}
static guint16 *
-get_end_count (struct type_4_table *table)
+get_end_count (struct type_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
/* Apparently the reseved spot is not reserved for
@@ -937,9 +897,9 @@ get_end_count (struct type_4_table *table)
static gboolean
-find_segment (struct type_4_table *table,
- guint16 wc,
- guint16 *segment)
+find_segment (struct type_4_cmap *table,
+ guint16 wc,
+ guint16 *segment)
{
guint16 start, end, i;
guint16 seg_count = table->seg_count_x_2/2;
@@ -997,21 +957,21 @@ find_segment (struct type_4_table *table,
return FALSE;
}
-static struct type_4_table *
+static struct type_4_cmap *
font_get_unicode_table (PangoFont *font)
{
PangoWin32Font *win32font = (PangoWin32Font *)font;
HFONT hfont;
- struct type_4_table *table;
+ struct type_4_cmap *table;
- if (win32font->entry->unicode_table)
- return (struct type_4_table *)win32font->entry->unicode_table;
+ if (win32font->win32face->unicode_table)
+ return (struct type_4_cmap *)win32font->win32face->unicode_table;
hfont = pango_win32_get_hfont (font);
SelectObject (pango_win32_hdc, hfont);
table = get_unicode_mapping (pango_win32_hdc);
- win32font->entry->unicode_table = table;
+ win32font->win32face->unicode_table = table;
return table;
}
@@ -1029,7 +989,7 @@ gint
pango_win32_font_get_glyph_index (PangoFont *font,
gunichar wc)
{
- struct type_4_table *table;
+ struct type_4_cmap *table;
guint16 *id_range_offset;
guint16 *id_delta;
guint16 *start_count;
@@ -1066,11 +1026,106 @@ pango_win32_font_get_glyph_index (PangoFont *font,
return glyph;
}
+gboolean
+pango_win32_get_name_header (HDC hdc,
+ struct name_header *header)
+{
+ if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) != sizeof (*header))
+ return FALSE;
+
+ header->num_records = GUINT16_FROM_BE (header->num_records);
+ header->string_storage_offset = GUINT16_FROM_BE (header->string_storage_offset);
+
+ return TRUE;
+}
+
+gboolean
+pango_win32_get_name_record (HDC hdc,
+ gint i,
+ struct name_record *record)
+{
+ if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
+ record, sizeof (*record)) != sizeof (*record))
+ return FALSE;
+
+ record->platform_id = GUINT16_FROM_BE (record->platform_id);
+ record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
+ record->language_id = GUINT16_FROM_BE (record->language_id);
+ record->name_id = GUINT16_FROM_BE (record->name_id);
+ record->string_length = GUINT16_FROM_BE (record->string_length);
+ record->string_offset = GUINT16_FROM_BE (record->string_offset);
+
+ return TRUE;
+}
+
+static gboolean
+font_has_name_in (PangoFont *font,
+ PangoWin32CoverageLanguageClass cjkv)
+{
+ HFONT hfont, oldhfont;
+ struct name_header header;
+ struct name_record record;
+ gint i;
+ gboolean retval = FALSE;
+
+ if (cjkv == PANGO_WIN32_COVERAGE_UNSPEC)
+ return TRUE;
+
+ hfont = pango_win32_get_hfont (font);
+ oldhfont = SelectObject (pango_win32_hdc, hfont);
+
+ if (!pango_win32_get_name_header (pango_win32_hdc, &header))
+ {
+ SelectObject (pango_win32_hdc, oldhfont);
+ return FALSE;
+ }
+
+ for (i = 0; i < header.num_records; i++)
+ {
+ if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
+ {
+ SelectObject (pango_win32_hdc, oldhfont);
+ return FALSE;
+ }
+
+ if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
+ continue;
+
+ PING(("platform:%d encoding:%d language:%04x name_id:%d",
+ record.platform_id, record.encoding_id, record.language_id, record.name_id));
+
+ if (record.platform_id == MICROSOFT_PLATFORM_ID)
+ if ((cjkv == PANGO_WIN32_COVERAGE_ZH_TW &&
+ record.language_id == MAKELANGID (LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL))
+ ||
+ (cjkv == PANGO_WIN32_COVERAGE_ZH_CN &&
+ record.language_id == MAKELANGID (LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED))
+ ||
+ (cjkv == PANGO_WIN32_COVERAGE_JA &&
+ PRIMARYLANGID (record.language_id) == LANG_JAPANESE)
+ ||
+ (cjkv == PANGO_WIN32_COVERAGE_KO &&
+ PRIMARYLANGID (record.language_id) == LANG_KOREAN)
+ ||
+ (cjkv == PANGO_WIN32_COVERAGE_VI &&
+ PRIMARYLANGID (record.language_id) == LANG_VIETNAMESE))
+ {
+ PING (("yep:%d:%04x", cjkv, record.language_id));
+ retval = TRUE;
+ break;
+ }
+ }
+
+ SelectObject (pango_win32_hdc, oldhfont);
+ return retval;
+}
+
static void
pango_win32_font_calc_coverage (PangoFont *font,
- PangoCoverage *coverage)
+ PangoCoverage *coverage,
+ PangoLanguage *lang)
{
- struct type_4_table *table;
+ struct type_4_cmap *table;
guint16 *id_range_offset;
guint16 *start_count;
guint16 *end_count;
@@ -1078,13 +1133,30 @@ pango_win32_font_calc_coverage (PangoFont *font,
guint16 id;
guint32 ch;
int i;
+ PangoWin32CoverageLanguageClass cjkv;
+ gboolean hide_unihan = FALSE;
+
+ PING(("font:%s lang:%s",
+ pango_font_description_to_string (pango_font_describe (font)),
+ pango_language_to_string (lang)));
+
+ cjkv = pango_win32_coverage_language_classify (lang);
+
+ if (cjkv != PANGO_WIN32_COVERAGE_UNSPEC && !font_has_name_in (font, cjkv))
+ {
+ PING(("hiding UniHan chars"));
+ hide_unihan = TRUE;
+ }
/* Do GetFontData magic on font->hfont here. */
table = font_get_unicode_table (font);
if (table == NULL)
- return;
+ {
+ PING(("no table"));
+ return;
+ }
seg_count = table->seg_count_x_2/2;
end_count = get_end_count (table);
@@ -1095,13 +1167,25 @@ pango_win32_font_calc_coverage (PangoFont *font,
{
if (id_range_offset[i] == 0)
{
+#ifdef PANGO_WIN32_DEBUGGING
+ if (end_count[i] == start_count[i])
+ PING (("\\u%04x", start_count[i]));
+ else
+ PING (("\\u%04x:\\u%04x", start_count[i], end_count[i]));
+#endif
for (ch = start_count[i];
ch <= end_count[i];
ch++)
- pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
+ if (hide_unihan && ch >= 0x3400 && ch <= 0x9FAF)
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);
+ else
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
}
else
{
+#ifdef PANGO_WIN32_DEBUGGING
+ guint32 ch0 = G_MAXUINT;
+#endif
for (ch = start_count[i];
ch <= end_count[i];
ch++)
@@ -1110,8 +1194,36 @@ pango_win32_font_calc_coverage (PangoFont *font,
(ch - start_count[i]) +
&id_range_offset[i]);
if (id)
- pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
+ {
+#ifdef PANGO_WIN32_DEBUGGING
+ if (ch0 == G_MAXUINT)
+ ch0 = ch;
+#endif
+ if (hide_unihan && ch >= 0x3400 && ch <= 0x9FAF)
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);
+ else
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
+ }
+#ifdef PANGO_WIN32_DEBUGGING
+ else if (ch0 < G_MAXUINT)
+ {
+ if (ch > ch0 + 2)
+ PING (("\\u%04x:\\u%04x", ch0, ch - 1));
+ else
+ PING (("\\u%04x", ch0));
+ ch0 = G_MAXUINT;
+ }
+#endif
+ }
+#ifdef PANGO_WIN32_DEBUGGING
+ if (ch0 < G_MAXUINT)
+ {
+ if (ch > ch0 + 2)
+ PING (("\\u%04x:\\u%04x", ch0, ch - 1));
+ else
+ PING (("\\u%04x", ch0));
}
+#endif
}
}
}
diff --git a/pango/pangowin32.h b/pango/pangowin32.h
index fc5e0955..6c2f2651 100644
--- a/pango/pangowin32.h
+++ b/pango/pangowin32.h
@@ -31,7 +31,9 @@
G_BEGIN_DECLS
#define STRICT
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 /* To get ClearType-related macros */
+#endif
#include <windows.h>
#undef STRICT