summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2005-04-28 17:20:05 +0000
committerTor Lillqvist <tml@src.gnome.org>2005-04-28 17:20:05 +0000
commit3fc02e41c1efd23af4eb0e34af0fd6fa2783ead6 (patch)
treef65fd16983d0eae7d3d4fcc2fcf5dce17e2b133d
parent6aee1049a38fc25f25e2ed14a6ed303cc647556a (diff)
downloadpango-3fc02e41c1efd23af4eb0e34af0fd6fa2783ead6.tar.gz
Correct parameters passed to MultiByteToWideChar(). Pass -1 as source
2005-04-28 Tor Lillqvist <tml@novell.com> * pango/pangocairo-win32font.c (pango_cairo_win32_font_get_font_face): Correct parameters passed to MultiByteToWideChar(). Pass -1 as source string length so that the target string gets zero-terminated. Size of target array is in number of WCHARs, not number of bytes. Add support to pangowin32 for TrueType fonts with coverage outside the BMP. Fix handling of surrogate pairs in the Uniscribe shaper. (#302238) * pango/pangowin32-private.h (PangoWin32Face): Rename the unicode_table field to cmap. Keep track of its format (4 or 12). (format_12_cmap): Add struct for a format 12 cmap. * pango/pangowin32.c: Corresponding changes. Rename internal functions a bit. (get_format_12_cmap): New function, reads a format 12 cmap. (font_get_cmap): Look for both format 12 (which is preferred) and format 4 cmaps. (pango_win32_font_get_glyph_index, pango_win32_font_calc_coverage): Handle also format 12 cmaps. * modules/basic/basic-win32.c: Handle surrogate pairs in wchar_t strings properly. (unichar_index): New function. Given a wchar_t string and an index into it, calculate the index of the corresponding Unicode character. Each surrogate pair in the wchar_t is just one Unicode character. (set_up_pango_log_clusters, itemize_shape_and_place): Use unichar_index() instead of direct index into wchar_t string.
-rw-r--r--ChangeLog33
-rw-r--r--ChangeLog.pre-1-1033
-rw-r--r--modules/basic/basic-win32.c45
-rw-r--r--pango/pangocairo-win32font.c4
-rw-r--r--pango/pangowin32-fontmap.c6
-rw-r--r--pango/pangowin32-private.h22
-rw-r--r--pango/pangowin32.c359
7 files changed, 361 insertions, 141 deletions
diff --git a/ChangeLog b/ChangeLog
index a47a5668..3cdf462a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2005-04-28 Tor Lillqvist <tml@novell.com>
+
+ * pango/pangocairo-win32font.c (pango_cairo_win32_font_get_font_face):
+ Correct parameters passed to MultiByteToWideChar(). Pass -1 as
+ source string length so that the target string gets
+ zero-terminated. Size of target array is in number of WCHARs, not
+ number of bytes.
+
+ Add support to pangowin32 for TrueType fonts with coverage outside
+ the BMP. Fix handling of surrogate pairs in the Uniscribe
+ shaper. (#302238)
+
+ * pango/pangowin32-private.h (PangoWin32Face): Rename the
+ unicode_table field to cmap. Keep track of its format (4 or 12).
+ (format_12_cmap): Add struct for a format 12 cmap.
+
+ * pango/pangowin32.c: Corresponding changes. Rename internal
+ functions a bit.
+ (get_format_12_cmap): New function, reads a format 12 cmap.
+ (font_get_cmap): Look for both format 12 (which is preferred) and
+ format 4 cmaps.
+ (pango_win32_font_get_glyph_index,
+ pango_win32_font_calc_coverage): Handle also format 12 cmaps.
+
+ * modules/basic/basic-win32.c: Handle surrogate pairs in wchar_t
+ strings properly.
+ (unichar_index): New function. Given a wchar_t string and an index
+ into it, calculate the index of the corresponding Unicode
+ character. Each surrogate pair in the wchar_t is just one Unicode
+ character.
+ (set_up_pango_log_clusters, itemize_shape_and_place): Use
+ unichar_index() instead of direct index into wchar_t string.
+
Wed Apr 27 15:45:06 2005 Manish Singh <yosh@gimp.org>
* examples/cairoview.c: Update to new Cairo API for writing out PNGs.
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index a47a5668..3cdf462a 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,36 @@
+2005-04-28 Tor Lillqvist <tml@novell.com>
+
+ * pango/pangocairo-win32font.c (pango_cairo_win32_font_get_font_face):
+ Correct parameters passed to MultiByteToWideChar(). Pass -1 as
+ source string length so that the target string gets
+ zero-terminated. Size of target array is in number of WCHARs, not
+ number of bytes.
+
+ Add support to pangowin32 for TrueType fonts with coverage outside
+ the BMP. Fix handling of surrogate pairs in the Uniscribe
+ shaper. (#302238)
+
+ * pango/pangowin32-private.h (PangoWin32Face): Rename the
+ unicode_table field to cmap. Keep track of its format (4 or 12).
+ (format_12_cmap): Add struct for a format 12 cmap.
+
+ * pango/pangowin32.c: Corresponding changes. Rename internal
+ functions a bit.
+ (get_format_12_cmap): New function, reads a format 12 cmap.
+ (font_get_cmap): Look for both format 12 (which is preferred) and
+ format 4 cmaps.
+ (pango_win32_font_get_glyph_index,
+ pango_win32_font_calc_coverage): Handle also format 12 cmaps.
+
+ * modules/basic/basic-win32.c: Handle surrogate pairs in wchar_t
+ strings properly.
+ (unichar_index): New function. Given a wchar_t string and an index
+ into it, calculate the index of the corresponding Unicode
+ character. Each surrogate pair in the wchar_t is just one Unicode
+ character.
+ (set_up_pango_log_clusters, itemize_shape_and_place): Use
+ unichar_index() instead of direct index into wchar_t string.
+
Wed Apr 27 15:45:06 2005 Manish Singh <yosh@gimp.org>
* examples/cairoview.c: Update to new Cairo API for writing out PNGs.
diff --git a/modules/basic/basic-win32.c b/modules/basic/basic-win32.c
index b4c99a97..2ffc090b 100644
--- a/modules/basic/basic-win32.c
+++ b/modules/basic/basic-win32.c
@@ -557,7 +557,7 @@ dump_glyphs_and_log_clusters (gboolean rtl,
for (j = 0, charix = charix0; j < itemlen; j++, charix++)
{
if (j == 0 || log_clusters[j-1] != log_clusters[j])
- printf (" Cluster %d: chars %d--",
+ printf (" Cluster %d: wchar_t %d--",
clusterix, charix);
if (j == itemlen - 1 || log_clusters[j] != log_clusters[j+1])
{
@@ -581,8 +581,24 @@ dump_glyphs_and_log_clusters (gboolean rtl,
#endif /* BASIC_WIN32_DEBUGGING */
+static int
+unichar_index (wchar_t *wtext,
+ int ix)
+{
+ int i, index;
+
+ index = 0;
+ for (i = 0; i < ix; i++)
+ /* Ignore the low surrogate */
+ if (!(wtext[i] >= 0xDC00 && wtext[i] < 0xE000))
+ index++;
+
+ return index;
+}
+
static void
-set_up_pango_log_clusters (gboolean rtl,
+set_up_pango_log_clusters (wchar_t *wtext,
+ gboolean rtl,
int itemlen,
WORD *usp_log_clusters,
int nglyphs,
@@ -598,13 +614,13 @@ set_up_pango_log_clusters (gboolean rtl,
* log_clusters array forwards.
*/
int glyph0 = 0;
- first_char_in_cluster = itemlen - 1;
+ first_char_in_cluster = unichar_index (wtext, itemlen - 1);
for (j = itemlen - 1; j >= 0; j--)
{
if (j < itemlen - 1 && usp_log_clusters[j+1] != usp_log_clusters[j])
{
/* Cluster starts */
- first_char_in_cluster = j;
+ first_char_in_cluster = unichar_index (wtext, j);
}
if (j == 0)
{
@@ -615,7 +631,7 @@ set_up_pango_log_clusters (gboolean rtl,
else if (usp_log_clusters[j-1] == usp_log_clusters[j])
{
/* Cluster continues */
- first_char_in_cluster = j-1;
+ first_char_in_cluster = unichar_index (wtext, j-1);
}
else
{
@@ -637,7 +653,7 @@ set_up_pango_log_clusters (gboolean rtl,
if (j > 0 && usp_log_clusters[j-1] != usp_log_clusters[j])
{
/* Cluster starts */
- first_char_in_cluster = j;
+ first_char_in_cluster = unichar_index (wtext, j);
}
if (j == itemlen - 1)
{
@@ -753,16 +769,21 @@ itemize_shape_and_place (PangoFont *font,
ABC abc;
int script = items[item].a.eScript;
int ng;
+ int char_offset;
memset (advances, 0, sizeof (advances));
memset (offsets, 0, sizeof (offsets));
memset (&abc, 0, sizeof (abc));
+ /* Note that itemlen is number of wchar_t's i.e. surrogate pairs
+ * count as two!
+ */
itemlen = items[item+1].iCharPos - items[item].iCharPos;
+ char_offset = unichar_index (wtext, items[item].iCharPos);
#ifdef BASIC_WIN32_DEBUGGING
if (pango_win32_debug)
- printf (" Item %d: iCharPos=%d eScript=%d (%s) %s%s%s%s%s%s%s chars %d--%d (%d)\n",
+ printf (" Item %d: iCharPos=%d eScript=%d (%s) %s%s%s%s%s%s%s wchar_t %d--%d (%d)\n",
item, items[item].iCharPos, script,
lang_name (scripts[script]->langid),
scripts[script]->fComplex ? "complex" : "simple",
@@ -801,9 +822,10 @@ itemize_shape_and_place (PangoFont *font,
ng = glyphs->num_glyphs;
pango_glyph_string_set_size (glyphs, ng + nglyphs);
- set_up_pango_log_clusters (items[item].a.fRTL, itemlen, log_clusters,
+ set_up_pango_log_clusters (wtext,
+ items[item].a.fRTL, itemlen, log_clusters,
nglyphs, glyphs->log_clusters + ng,
- items[item].iCharPos);
+ char_offset);
if ((*script_place) (hdc, &script_cache[script], iglyphs, nglyphs,
visattrs, &items[item].a,
@@ -846,7 +868,7 @@ itemize_shape_and_place (PangoFont *font,
#ifdef BASIC_WIN32_DEBUGGING
if (pango_win32_debug)
{
- printf (" Pango log_clusters (%d), char index:", analysis->level);
+ printf (" Pango log_clusters (level:%d), char index:", analysis->level);
for (glyphix = 0; glyphix < glyphs->num_glyphs; glyphix++)
printf ("%d ", glyphs->log_clusters[glyphix]);
printf ("\n");
@@ -917,7 +939,6 @@ text_is_simple (const char *text,
long wlen;
wtext = (wchar_t *) g_utf8_to_utf16 (text, length, NULL, &wlen, NULL);
-
if (wtext == NULL)
return TRUE;
@@ -927,7 +948,7 @@ text_is_simple (const char *text,
#ifdef BASIC_WIN32_DEBUGGING
if (pango_win32_debug)
- printf ("text_is_simple: %.*s (%ld chars): %s\n",
+ printf ("text_is_simple: %.*s (%ld wchar_t): %s\n",
MIN (length, 10), text, wlen, retval ? "YES" : "NO");
#endif
diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c
index ff9b5d85..3807f1f1 100644
--- a/pango/pangocairo-win32font.c
+++ b/pango/pangocairo-win32font.c
@@ -83,8 +83,8 @@ pango_cairo_win32_font_get_font_face (PangoCairoFont *font)
memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
- win32font->logfont.lfFaceName, strlen (win32font->logfont.lfFaceName),
- logfontw.lfFaceName, sizeof(logfontw.lfFaceName)))
+ win32font->logfont.lfFaceName, -1,
+ logfontw.lfFaceName, G_N_ELEMENTS (logfontw.lfFaceName)))
logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
cwfont->font_face = cairo_win32_font_face_create_for_logfontw (&logfontw);
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 98057170..a618c0ae 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -143,12 +143,13 @@ pango_win32_enum_proc (LOGFONT *lfp,
{
LOGFONT lf;
+ PING(("%s", lfp->lfFaceName));
+
if (fontType != TRUETYPE_FONTTYPE)
return 1;
lf = *lfp;
- PING(("%s", lf.lfFaceName));
EnumFontFamiliesExA (pango_win32_hdc, &lf,
(FONTENUMPROC) pango_win32_inner_enum_proc,
lParam, 0);
@@ -755,7 +756,8 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++)
win32face->coverages[i] = NULL;
win32face->logfont = *lfp;
- win32face->unicode_table = NULL;
+ win32face->cmap_format = 0;
+ win32face->cmap = NULL;
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index 6bb1389e..40916e4f 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -161,7 +161,8 @@ struct _PangoWin32Face
PangoCoverage *coverages[PANGO_WIN32_N_COVERAGES];
char *face_name;
- gpointer unicode_table;
+ guint16 cmap_format;
+ gpointer cmap;
GSList *cached_fonts;
};
@@ -194,15 +195,17 @@ struct _PangoWin32GlyphInfo
#define UNICODE_ENCODING_ID 1
#define UCS4_ENCODING_ID 10
+/* All the below structs must be packed! */
+
struct cmap_encoding_subtable
-{ /* Must be packed! */
+{
guint16 platform_id;
guint16 encoding_id;
guint32 offset;
};
-struct type_4_cmap
-{ /* Must be packed! */
+struct format_4_cmap
+{
guint16 format;
guint16 length;
guint16 language;
@@ -216,6 +219,17 @@ struct type_4_cmap
guint16 arrays[1];
};
+struct format_12_cmap
+{
+ guint16 format;
+ guint16 reserved;
+ guint32 length;
+ guint32 language;
+ guint32 count;
+
+ guint32 groups[1];
+};
+
struct name_header
{
guint16 format_selector;
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index a295941e..5c231f43 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -34,6 +34,11 @@
#define PANGO_WIN32_UNKNOWN_FLAG 0x10000000
+#define CH_IS_UNIHAN_BMP(ch) ((ch) >= 0x3400 && (ch) <= 0x9FFF)
+#define CH_IS_UNIHAN(ch) (CH_IS_UNIHAN_BMP (ch) || \
+ ((ch) >= 0x20000 && (ch) <= 0x2A6DF) || \
+ ((ch) >= 0x2F800 && (ch) <= 0x2FA1F))
+
HDC pango_win32_hdc;
OSVERSIONINFO pango_win32_os_version_info;
gboolean pango_win32_debug = FALSE;
@@ -1091,7 +1096,8 @@ pango_win32_get_item_properties (PangoItem *item,
}
static guint
-get_unicode_mapping_offset (HDC hdc)
+get_cmap_offset (HDC hdc,
+ guint16 encoding_id)
{
guint16 n_tables;
struct cmap_encoding_subtable *table;
@@ -1100,8 +1106,8 @@ get_unicode_mapping_offset (HDC hdc)
guint32 offset;
/* Get The number of encoding tables, at offset 2 */
- res = GetFontData (hdc, CMAP, 2, &n_tables, sizeof (guint16));
- if (res != sizeof (guint16))
+ res = GetFontData (hdc, CMAP, 2, &n_tables, 2);
+ if (res != 2)
return 0;
n_tables = GUINT16_FROM_BE (n_tables);
@@ -1115,7 +1121,7 @@ get_unicode_mapping_offset (HDC hdc)
for (i = 0; i < n_tables; i++)
{
if (table[i].platform_id == GUINT16_TO_BE (MICROSOFT_PLATFORM_ID) &&
- table[i].encoding_id == GUINT16_TO_BE (UNICODE_ENCODING_ID))
+ table[i].encoding_id == GUINT16_TO_BE (encoding_id))
{
offset = GUINT32_FROM_BE (table[i].offset);
g_free (table);
@@ -1126,31 +1132,33 @@ get_unicode_mapping_offset (HDC hdc)
return 0;
}
-static struct type_4_cmap *
-get_unicode_mapping (HDC hdc)
+static gpointer
+get_format_4_cmap (HDC hdc)
{
guint32 offset;
guint32 res;
guint16 length;
guint16 *tbl, *tbl_end;
- struct type_4_cmap *table;
+ struct format_4_cmap *table;
/* FIXME: Could look here at the CRC for the font in the DC
and return a cached copy if the same */
- offset = get_unicode_mapping_offset (hdc);
+ offset = get_cmap_offset (hdc, UNICODE_ENCODING_ID);
if (offset == 0)
return NULL;
- res = GetFontData (hdc, CMAP, offset + 2, &length, sizeof (guint16));
- if (res != sizeof (guint16))
+ res = GetFontData (hdc, CMAP, offset + 2, &length, 2);
+ if (res != 2)
return NULL;
length = GUINT16_FROM_BE (length);
table = g_malloc (length);
res = GetFontData (hdc, CMAP, offset, table, length);
- if (res != length)
+ if (res != length ||
+ GUINT16_FROM_BE (table->format) != 4 ||
+ (GUINT16_FROM_BE (table->length) % 2) != 0)
{
g_free (table);
return NULL;
@@ -1164,12 +1172,6 @@ get_unicode_mapping (HDC hdc)
table->entry_selector = GUINT16_FROM_BE (table->entry_selector);
table->range_shift = GUINT16_FROM_BE (table->range_shift);
- if (table->format != 4)
- {
- g_free (table);
- return NULL;
- }
-
tbl_end = (guint16 *)((char *)table + length);
tbl = &table->reserved;
@@ -1183,28 +1185,28 @@ get_unicode_mapping (HDC hdc)
}
static guint16 *
-get_id_range_offset (struct type_4_cmap *table)
+get_id_range_offset (struct format_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_cmap *table)
+get_id_delta (struct format_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_cmap *table)
+get_start_count (struct format_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_cmap *table)
+get_end_count (struct format_4_cmap *table)
{
gint32 seg_count = table->seg_count_x_2/2;
/* Apparently the reseved spot is not reserved for
@@ -1212,11 +1214,10 @@ get_end_count (struct type_4_cmap *table)
return (&table->arrays[seg_count*0])-1;
}
-
static gboolean
-find_segment (struct type_4_cmap *table,
- guint16 wc,
- guint16 *segment)
+find_segment (struct format_4_cmap *table,
+ guint16 wc,
+ guint16 *segment)
{
guint16 start, end, i;
guint16 seg_count = table->seg_count_x_2/2;
@@ -1274,22 +1275,85 @@ find_segment (struct type_4_cmap *table,
return FALSE;
}
-static struct type_4_cmap *
-font_get_unicode_table (PangoFont *font)
+static gpointer
+get_format_12_cmap (HDC hdc)
+{
+ guint32 offset;
+ guint32 res;
+ guint32 length;
+ guint32 *tbl, *tbl_end;
+ struct format_12_cmap *table;
+
+ offset = get_cmap_offset (hdc, UCS4_ENCODING_ID);
+ if (offset == 0)
+ return NULL;
+
+ res = GetFontData (hdc, CMAP, offset + 4, &length, 4);
+ if (res != 4)
+ return NULL;
+ length = GUINT32_FROM_BE (length);
+
+ table = g_malloc (length);
+
+ res = GetFontData (hdc, CMAP, offset, table, length);
+ if (res != length)
+ {
+ g_free (table);
+ return NULL;
+ }
+
+ table->format = GUINT16_FROM_BE (table->format);
+ table->length = GUINT32_FROM_BE (table->length);
+ table->language = GUINT32_FROM_BE (table->language);
+ table->count = GUINT32_FROM_BE (table->count);
+
+ if (table->format != 12 ||
+ (table->length % 4) != 0 ||
+ table->length > length ||
+ table->length < 16 + table->count * 12)
+ {
+ g_free (table);
+ return NULL;
+ }
+
+ tbl_end = (guint32 *) ((char *) table + length);
+ tbl = table->groups;
+
+ while (tbl < tbl_end)
+ {
+ *tbl = GUINT32_FROM_BE (*tbl);
+ tbl++;
+ }
+
+ return table;
+}
+
+static gpointer
+font_get_cmap (PangoFont *font)
{
PangoWin32Font *win32font = (PangoWin32Font *)font;
- struct type_4_cmap *table;
+ gpointer cmap;
- if (win32font->win32face->unicode_table)
- return (struct type_4_cmap *)win32font->win32face->unicode_table;
+ if (win32font->win32face->cmap)
+ return win32font->win32face->cmap;
pango_win32_font_select_font (font, pango_win32_hdc);
- table = get_unicode_mapping (pango_win32_hdc);
+
+ /* Prefer the format 12 cmap */
+ if ((cmap = get_format_12_cmap (pango_win32_hdc)) != NULL)
+ {
+ win32font->win32face->cmap_format = 12;
+ win32font->win32face->cmap = cmap;
+ }
+ else if ((cmap = get_format_4_cmap (pango_win32_hdc)) != NULL)
+ {
+ win32font->win32face->cmap_format = 4;
+ win32font->win32face->cmap = cmap;
+ }
+
pango_win32_font_done_font (font);
-
- win32font->win32face->unicode_table = table;
- return table;
+ return cmap;
}
/**
@@ -1305,40 +1369,67 @@ gint
pango_win32_font_get_glyph_index (PangoFont *font,
gunichar wc)
{
- struct type_4_cmap *table;
- guint16 *id_range_offset;
- guint16 *id_delta;
- guint16 *start_count;
- guint16 segment;
- guint16 id;
- guint16 ch = wc;
+ PangoWin32Font *win32font = (PangoWin32Font *)font;
+ gpointer cmap;
guint16 glyph;
/* Do GetFontData magic on font->hfont here. */
- table = font_get_unicode_table (font);
+ cmap = font_get_cmap (font);
- if (table == NULL)
+ if (cmap == NULL)
return 0;
+
+ if (win32font->win32face->cmap_format == 4)
+ {
+ struct format_4_cmap *cmap4 = cmap;
+ guint16 *id_range_offset;
+ guint16 *id_delta;
+ guint16 *start_count;
+ guint16 segment;
+ guint16 id;
+ guint16 ch = wc;
- if (!find_segment (table, ch, &segment))
- return 0;
+ if (wc > 0xFFFF)
+ return 0;
- id_range_offset = get_id_range_offset (table);
- id_delta = get_id_delta (table);
- start_count = get_start_count (table);
+ if (!find_segment (cmap4, ch, &segment))
+ return 0;
- if (id_range_offset[segment] == 0)
- glyph = (id_delta[segment] + ch) % 65536;
- else
- {
- id = *(id_range_offset[segment]/2 +
- (ch - start_count[segment]) +
- &id_range_offset[segment]);
- if (id)
- glyph = (id_delta[segment] + id) %65536;
+ id_range_offset = get_id_range_offset (cmap4);
+ id_delta = get_id_delta (cmap4);
+ start_count = get_start_count (cmap4);
+
+ if (id_range_offset[segment] == 0)
+ glyph = (id_delta[segment] + ch) % 65536;
else
- glyph = 0;
+ {
+ id = *(id_range_offset[segment]/2 +
+ (ch - start_count[segment]) +
+ &id_range_offset[segment]);
+ if (id)
+ glyph = (id_delta[segment] + id) %65536;
+ else
+ glyph = 0;
+ }
+ }
+ else if (win32font->win32face->cmap_format == 12)
+ {
+ struct format_12_cmap *cmap12 = cmap;
+ guint32 i;
+
+ glyph = 0;
+ for (i = 0; i < cmap12->count; i++)
+ {
+ if (cmap12->groups[i*3+0] <= wc && wc <= cmap12->groups[i*3+1])
+ {
+ glyph = cmap12->groups[i*3+2] + (wc - cmap12->groups[i*3+0]);
+ break;
+ }
+ }
}
+ else
+ g_assert_not_reached ();
+
return glyph;
}
@@ -1441,14 +1532,10 @@ pango_win32_font_calc_coverage (PangoFont *font,
PangoCoverage *coverage,
PangoLanguage *lang)
{
- struct type_4_cmap *table;
- guint16 *id_range_offset;
- guint16 *start_count;
- guint16 *end_count;
- guint16 seg_count;
- guint16 id;
+ PangoWin32Font *win32font = (PangoWin32Font *)font;
+ gpointer cmap;
guint32 ch;
- int i;
+ guint32 i;
PangoWin32CoverageLanguageClass cjkv;
gboolean hide_unihan = FALSE;
@@ -1465,70 +1552,87 @@ pango_win32_font_calc_coverage (PangoFont *font,
}
/* Do GetFontData magic on font->hfont here. */
-
- table = font_get_unicode_table (font);
-
- if (table == NULL)
+ cmap = font_get_cmap (font);
+ if (cmap == NULL)
{
PING(("no table"));
return;
}
- seg_count = table->seg_count_x_2/2;
- end_count = get_end_count (table);
- start_count = get_start_count (table);
- id_range_offset = get_id_range_offset (table);
-
PING (("coverage:"));
- for (i = 0; i < seg_count; i++)
+ if (win32font->win32face->cmap_format == 4)
{
- if (id_range_offset[i] == 0)
+ struct format_4_cmap *cmap4 = cmap;
+ guint16 *id_range_offset;
+ guint16 *start_count;
+ guint16 *end_count;
+ guint16 seg_count;
+ guint16 id;
+
+ seg_count = cmap4->seg_count_x_2/2;
+ end_count = get_end_count (cmap4);
+ start_count = get_start_count (cmap4);
+ id_range_offset = get_id_range_offset (cmap4);
+
+ for (i = 0; i < seg_count; i++)
{
-#ifdef PANGO_WIN32_DEBUGGING
- if (pango_win32_debug)
+ if (id_range_offset[i] == 0)
{
- if (end_count[i] == start_count[i])
- printf ("%04x ", start_count[i]);
- else
- printf ("%04x:%04x ", start_count[i], end_count[i]);
- }
+#ifdef PANGO_WIN32_DEBUGGING
+ if (pango_win32_debug)
+ {
+ if (end_count[i] == start_count[i])
+ printf ("%04x ", start_count[i]);
+ else
+ printf ("%04x:%04x ", start_count[i], end_count[i]);
+ }
#endif
- for (ch = start_count[i];
- ch <= end_count[i];
- ch++)
- 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
- {
+ for (ch = start_count[i]; ch <= end_count[i]; ch++)
+ if (hide_unihan && CH_IS_UNIHAN_BMP (ch))
+ 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;
+ guint32 ch0 = G_MAXUINT;
#endif
- for (ch = start_count[i];
- ch <= end_count[i];
- ch++)
- {
- if (ch == 0xFFFF)
- break;
-
- id = *(id_range_offset[i]/2 +
- (ch - start_count[i]) +
- &id_range_offset[i]);
- if (id)
+ for (ch = start_count[i]; ch <= end_count[i]; ch++)
{
+ if (ch == 0xFFFF)
+ break;
+
+ id = *(id_range_offset[i]/2 +
+ (ch - start_count[i]) +
+ &id_range_offset[i]);
+ if (id)
+ {
#ifdef PANGO_WIN32_DEBUGGING
- if (ch0 == G_MAXUINT)
- ch0 = ch;
+ if (ch0 == G_MAXUINT)
+ ch0 = ch;
+#endif
+ if (hide_unihan && CH_IS_UNIHAN_BMP (ch))
+ 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 (pango_win32_debug)
+ {
+ if (ch > ch0 + 2)
+ printf ("%04x:%04x ", ch0, ch - 1);
+ else
+ printf ("%04x ", ch0);
+ }
+ ch0 = G_MAXUINT;
+ }
#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 (ch0 < G_MAXUINT)
{
if (pango_win32_debug)
{
@@ -1537,24 +1641,37 @@ pango_win32_font_calc_coverage (PangoFont *font,
else
printf ("%04x ", ch0);
}
- ch0 = G_MAXUINT;
}
#endif
}
+ }
+ }
+ else if (win32font->win32face->cmap_format == 12)
+ {
+ struct format_12_cmap *cmap12 = cmap;
+
+ for (i = 0; i < cmap12->count; i++)
+ {
#ifdef PANGO_WIN32_DEBUGGING
- if (ch0 < G_MAXUINT)
+ if (pango_win32_debug)
{
- if (pango_win32_debug)
- {
- if (ch > ch0 + 2)
- printf ("%04x:%04x ", ch0, ch - 1);
- else
- printf ("%04x ", ch0);
- }
+ if (cmap12->groups[i*3+0] == cmap12->groups[i*3+1])
+ printf ("%04x ", cmap12->groups[i*3+0]);
+ else
+ printf ("%04x:%04x ", cmap12->groups[i*3+0], cmap12->groups[i*3+1]);
}
#endif
+ for (ch = cmap12->groups[i*3+0]; ch <= cmap12->groups[i*3+1]; ch++)
+ {
+ if (hide_unihan && CH_IS_UNIHAN (ch))
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);
+ else
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
+ }
}
}
+ else
+ g_assert_not_reached ();
#ifdef PANGO_WIN32_DEBUGGING
if (pango_win32_debug)
printf ("\n");