[pango: 1/2] PangoWin32: Use hb_font_get_nominal_glyph



commit 0673d8017dcd0f0e9ce5ec98e8f34f6582ca56fc
Author: Khaled Hosny <khaledhosny eglug org>
Date:   Sat Jul 27 13:45:00 2019 +0000

    PangoWin32: Use hb_font_get_nominal_glyph
    
    Use hb_font_get_nominal_glyph in pango_win32_font_get_glyph_index
    (deprecated), to better match what Pango is actually using internally.

 pango/pango-impl-utils.h   |   4 +-
 pango/pangowin32-fontmap.c |  54 +++-
 pango/pangowin32-private.h |  21 +-
 pango/pangowin32.c         | 712 ++-------------------------------------------
 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;
 
@@ -279,14 +268,6 @@ _PANGO_EXTERN
 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);
 
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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]