summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pango/pango-impl-utils.h4
-rw-r--r--pango/pangowin32-fontmap.c54
-rw-r--r--pango/pangowin32-private.h21
-rw-r--r--pango/pangowin32.c712
4 files changed, 60 insertions, 731 deletions
diff --git a/pango/pango-impl-utils.h b/pango/pango-impl-utils.h
index 378f14a1..92a1168e 100644
--- a/pango/pango-impl-utils.h
+++ b/pango/pango-impl-utils.h
@@ -159,7 +159,9 @@ static struct {
static inline G_GNUC_UNUSED const char *
pango_get_ignorable (gunichar ch)
{
- for (int i = 0; i < G_N_ELEMENTS (ignorables); i++)
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (ignorables); i++)
{
if (ch == ignorables[i].ch)
return ignorables[i].nick;
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index 86093544..1c0b70f2 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -670,19 +670,15 @@ create_standard_family (PangoWin32FontMap *win32fontmap,
{
const PangoWin32Face *old_face = 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;
- }
+ if (old_face->coverage != NULL)
+ new_face->coverage = pango_coverage_ref (old_face->coverage);
+ else
+ new_face->coverage = NULL;
new_face->face_name = NULL;
@@ -1115,6 +1111,38 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
return (PangoFont *)win32font;
}
+static 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;
+}
+
+static 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 gchar *
get_family_nameA (const LOGFONTA *lfp)
{
@@ -1543,7 +1571,6 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
PangoFontDescription *description;
PangoWin32Family *win32family;
PangoWin32Face *win32face;
- gint i;
char tmp_for_charset_name[10];
char tmp_for_ff_name[10];
@@ -1594,8 +1621,7 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
win32face->logfontw = *lfp;
win32face->description = description;
- for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++)
- win32face->coverages[i] = NULL;
+ win32face->coverage = NULL;
win32face->face_name = NULL;
@@ -1690,14 +1716,12 @@ G_DEFINE_TYPE (PangoWin32Face, pango_win32_face, PANGO_TYPE_FONT_FACE)
static void
pango_win32_face_finalize (GObject *object)
{
- int j;
PangoWin32Face *win32face = PANGO_WIN32_FACE (object);
pango_font_description_free (win32face->description);
- for (j = 0; j < PANGO_WIN32_N_COVERAGES; j++)
- if (win32face->coverages[j] != NULL)
- pango_coverage_unref (win32face->coverages[j]);
+ if (win32face->coverage != NULL)
+ pango_coverage_unref (win32face->coverage);
g_free (win32face->face_name);
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index 72befca8..9d9a0a73 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -57,17 +57,6 @@
#include "pango-fontset-private.h"
#include "pango-fontmap-private.h"
-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;
-
#define PANGO_TYPE_WIN32_FONT_MAP (_pango_win32_font_map_get_type ())
#define PANGO_WIN32_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_WIN32_FONT_MAP, PangoWin32FontMap))
#define PANGO_WIN32_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_WIN32_FONT_MAP))
@@ -166,7 +155,7 @@ struct _PangoWin32Face
LOGFONTW logfontw;
PangoFontDescription *description;
- PangoCoverage *coverages[PANGO_WIN32_N_COVERAGES];
+ PangoCoverage *coverage;
char *face_name;
gboolean is_synthetic;
@@ -280,14 +269,6 @@ void _pango_win32_fontmap_cache_remove (PangoFontMap *fontmap,
PangoWin32Font *xfont);
_PANGO_EXTERN
-gboolean _pango_win32_get_name_header (HDC hdc,
- struct name_header *header);
-_PANGO_EXTERN
-gboolean _pango_win32_get_name_record (HDC hdc,
- gint i,
- struct name_record *record);
-
-_PANGO_EXTERN
HFONT _pango_win32_font_get_hfont (PangoFont *font);
extern HDC _pango_win32_hdc;
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 09750199..c08ae24b 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -43,11 +43,6 @@
#define MAX_FREED_FONTS 256
-#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;
gboolean _pango_win32_debug = FALSE;
@@ -58,9 +53,6 @@ static PangoFontDescription *pango_win32_font_describe (PangoFont
static PangoFontDescription *pango_win32_font_describe_absolute (PangoFont *font);
static PangoCoverage *pango_win32_font_get_coverage (PangoFont *font,
PangoLanguage *lang);
-static void pango_win32_font_calc_coverage (PangoFont *font,
- PangoCoverage *coverage,
- PangoLanguage *lang);
static void pango_win32_font_get_glyph_extents (PangoFont *font,
PangoGlyph glyph,
PangoRectangle *ink_rect,
@@ -870,62 +862,28 @@ pango_win32_font_describe_absolute (PangoFont *font)
return desc;
}
-static 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;
-}
-
-static PangoCoverage *
-pango_win32_font_entry_get_coverage (PangoWin32Face *face,
- PangoLanguage *lang)
-{
- gint i = pango_win32_coverage_language_classify (lang);
- if (face->coverages[i])
- {
- pango_coverage_ref (face->coverages[i]);
- return face->coverages[i];
- }
-
- return NULL;
-}
-
-static void
-pango_win32_font_entry_set_coverage (PangoWin32Face *face,
- PangoCoverage *coverage,
- PangoLanguage *lang)
-{
- face->coverages[pango_win32_coverage_language_classify (lang)] = pango_coverage_ref (coverage);
-}
-
static PangoCoverage *
pango_win32_font_get_coverage (PangoFont *font,
- PangoLanguage *lang)
+ PangoLanguage *lang G_GNUC_UNUSED)
{
- PangoCoverage *coverage;
- PangoWin32Font *win32font = (PangoWin32Font *)font;
+ PangoWin32Face *win32face = ((PangoWin32Font *)font)->win32face;
- coverage = pango_win32_font_entry_get_coverage (win32font->win32face, lang);
- if (!coverage)
+ if (!win32face->coverage)
{
- coverage = pango_coverage_new ();
- pango_win32_font_calc_coverage (font, coverage, lang);
+ PangoCoverage *coverage = pango_coverage_new ();
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ hb_face_t *hb_face = hb_font_get_face (hb_font);
+ hb_set_t *chars = hb_set_create ();
+ hb_codepoint_t ch = HB_SET_VALUE_INVALID;
+
+ hb_face_collect_unicodes (hb_face, chars);
+ while (hb_set_next(chars, &ch))
+ pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
- pango_win32_font_entry_set_coverage (win32font->win32face, coverage, lang);
+ win32face->coverage = pango_coverage_ref (coverage);
}
- return coverage;
+ return pango_coverage_ref (win32face->coverage);
}
/* Utility functions */
@@ -1206,287 +1164,6 @@ pango_win32_get_item_properties (PangoItem *item,
}
}
-static guint
-get_cmap_offset (HDC hdc,
- guint16 encoding_id)
-{
- guint16 n_tables;
- struct cmap_encoding_subtable *table;
- gint32 res;
- int i;
- guint32 offset;
-
- /* Get The number of encoding tables, at offset 2 */
- res = GetFontData (hdc, CMAP, 2, &n_tables, 2);
- if (res != 2)
- return 0;
-
- n_tables = GUINT16_FROM_BE (n_tables);
-
- table = g_malloc (ENCODING_TABLE_SIZE*n_tables);
-
- res = GetFontData (hdc, CMAP, CMAP_HEADER_SIZE, table, ENCODING_TABLE_SIZE*n_tables);
- if (res != ENCODING_TABLE_SIZE*n_tables)
- return 0;
-
- 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 (encoding_id))
- {
- offset = GUINT32_FROM_BE (table[i].offset);
- g_free (table);
- return offset;
- }
- }
- g_free (table);
- return 0;
-}
-
-static gpointer
-get_format_4_cmap (HDC hdc)
-{
- guint32 offset;
- guint32 res;
- guint16 length;
- guint16 *tbl, *tbl_end;
- 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_cmap_offset (hdc, UNICODE_ENCODING_ID);
- if (offset == 0)
- return NULL;
-
- 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 ||
- GUINT16_FROM_BE (table->format) != 4 ||
- (GUINT16_FROM_BE (table->length) % 2) != 0)
- {
- g_free (table);
- return NULL;
- }
-
- table->format = GUINT16_FROM_BE (table->format);
- table->length = GUINT16_FROM_BE (table->length);
- 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);
- table->range_shift = GUINT16_FROM_BE (table->range_shift);
-
- tbl_end = (guint16 *)((char *)table + length);
- tbl = &table->reserved;
-
- while (tbl < tbl_end)
- {
- *tbl = GUINT16_FROM_BE (*tbl);
- tbl++;
- }
-
- return table;
-}
-
-static guint16 *
-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 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 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 format_4_cmap *table)
-{
- gint32 seg_count = table->seg_count_x_2/2;
- /* Apparently the reseved spot is not reserved for
- the end_count array!? */
- return (&table->arrays[seg_count*0])-1;
-}
-
-static gboolean
-find_segment (struct format_4_cmap *table,
- guint16 wc,
- guint16 *segment)
-{
- guint16 start, end, i;
- guint16 seg_count = table->seg_count_x_2/2;
- guint16 *end_count = get_end_count (table);
- guint16 *start_count = get_start_count (table);
- static guint last = 0; /* Cache of one */ /* MT-safe */
-
- if (last < seg_count &&
- wc >= start_count[last] &&
- wc <= end_count[last])
- {
- *segment = last;
- return TRUE;
- }
-
-
- /* Binary search for the segment */
- start = 0; /* inclusive */
- end = seg_count; /* not inclusive */
- while (start < end)
- {
- /* Look at middle pos */
- i = (start + end)/2;
-
- if (i == start)
- {
- /* We made no progress. Look if this is the one. */
-
- if (wc >= start_count[i] &&
- wc <= end_count[i])
- {
- *segment = i;
- last = i;
- return TRUE;
- }
- else
- return FALSE;
- }
- else if (wc < start_count[i])
- {
- end = i;
- }
- else if (wc > end_count[i])
- {
- start = i;
- }
- else
- {
- /* Found it! */
- *segment = i;
- last = i;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-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;
- gpointer cmap;
-
- if (win32font->win32face->cmap)
- return win32font->win32face->cmap;
-
- pango_win32_font_select_font (font, _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);
-
- return cmap;
-}
-
-static gint
-pango_win32_font_get_type1_glyph_index (PangoFont *font,
- gunichar wc)
-{
- wchar_t unicode[2];
- WORD glyph_index;
- gint32 res;
-
- unicode[0] = wc;
- unicode[1] = 0;
- pango_win32_font_select_font (font, _pango_win32_hdc);
- res = GetGlyphIndicesW (_pango_win32_hdc, unicode, 1, &glyph_index, 0);
- pango_win32_font_done_font (font);
-
- if (res == 1)
- return glyph_index;
- else
- return 0;
-}
-
/**
* pango_win32_font_get_glyph_index:
* @font: a #PangoFont.
@@ -1501,369 +1178,14 @@ gint
pango_win32_font_get_glyph_index (PangoFont *font,
gunichar wc)
{
- PangoWin32Font *win32font = (PangoWin32Font *)font;
- gpointer cmap;
- guint16 glyph;
+ hb_font_t *hb_font = pango_font_get_hb_font (font);
+ hb_codepoint_t glyph = 0;
- if (win32font->win32face->has_cmap)
- {
- /* Do GetFontData magic on font->hfont here. */
- cmap = font_get_cmap (font);
- if (cmap == NULL)
- win32font->win32face->has_cmap = FALSE;
- }
-
- if (!win32font->win32face->has_cmap)
- return pango_win32_font_get_type1_glyph_index (font, wc);
-
- 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 (wc > 0xFFFF)
- return 0;
-
- if (!find_segment (cmap4, ch, &segment))
- return 0;
-
- 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
- {
- 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 ();
+ hb_font_get_nominal_glyph (hb_font, wc, &glyph);
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_font_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_type1_coverage (PangoFont *font,
- PangoCoverage *coverage,
- PangoLanguage *lang)
-{
- GLYPHSET *glyph_set;
- gint32 res;
- guint32 ch;
- guint32 i;
-
- pango_win32_font_select_font (font, _pango_win32_hdc);
- res = GetFontUnicodeRanges(_pango_win32_hdc, NULL);
- if (res == 0)
- goto fail1;
-
- glyph_set = g_malloc (res);
- res = GetFontUnicodeRanges(_pango_win32_hdc, glyph_set);
- if (res == 0)
- goto fail2;
-
- for (i = 0; i < glyph_set->cRanges; i++)
- {
- guint32 end = glyph_set->ranges[i].wcLow + glyph_set->ranges[i].cGlyphs;
-
- for (ch = glyph_set->ranges[i].wcLow; ch < end; ch++)
- if (CH_IS_UNIHAN_BMP (ch))
- pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);
- else
- pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);
- }
-
- fail2:
- g_free (glyph_set);
-
- fail1:
- pango_win32_font_done_font (font);
-}
-
-static void
-pango_win32_font_calc_coverage (PangoFont *font,
- PangoCoverage *coverage,
- PangoLanguage *lang)
-{
- PangoWin32Font *win32font = (PangoWin32Font *)font;
- gpointer cmap;
- guint32 ch;
- guint32 i;
- PangoWin32CoverageLanguageClass cjkv;
- gboolean hide_unihan = FALSE;
- PangoFontDescription *desc;
- gchar *name;
-
- desc = pango_font_describe (font);
- name = pango_font_description_to_string (desc);
- PING (("font:%s lang:%s", name,
- pango_language_to_string (lang)));
- g_free (name);
- pango_font_description_free (desc);
-
- if (win32font->win32face->has_cmap)
- {
- /* Do GetFontData magic on font->hfont here. */
- cmap = font_get_cmap (font);
- if (cmap == NULL)
- win32font->win32face->has_cmap = FALSE;
- }
-
- if (!win32font->win32face->has_cmap)
- {
- pango_win32_font_calc_type1_coverage (font, coverage, lang);
- return;
- }
-
- 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;
- }
-
- PING (("coverage:"));
- if (win32font->win32face->cmap_format == 4)
- {
- 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++)
- {
- if (id_range_offset[i] == 0)
- {
-#ifdef PANGO_WIN32_DEBUGGING
- if (_pango_win32_debug)
- {
- if (end_count[i] == start_count[i])
- g_print ("%04x ", start_count[i]);
- else
- g_print ("%04x:%04x ", start_count[i], end_count[i]);
- }
-#endif
- 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;
-#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)
- {
-#ifdef PANGO_WIN32_DEBUGGING
- 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)
- g_print ("%04x:%04x ", ch0, ch - 1);
- else
- g_print ("%04x ", ch0);
- }
- ch0 = G_MAXUINT;
- }
-#endif
- }
-#ifdef PANGO_WIN32_DEBUGGING
- if (ch0 < G_MAXUINT)
- {
- if (_pango_win32_debug)
- {
- if (ch > ch0 + 2)
- g_print ("%04x:%04x ", ch0, ch - 1);
- else
- g_print ("%04x ", ch0);
- }
- }
-#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 (_pango_win32_debug)
- {
- if (cmap12->groups[i*3+0] == cmap12->groups[i*3+1])
- g_print ("%04x ", cmap12->groups[i*3+0]);
- else
- g_print ("%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)
- g_print ("\n");
-#endif
-}
-
/*
* Swap HarfBuzz-style tags to tags that GetFontData() understands,
* adapted from https://github.com/harfbuzz/harfbuzz/pull/1832,