[HarfBuzz] harfbuzz: Branch 'pango'

Simon Hausmann hausmann at kemper.freedesktop.org
Mon Jul 9 12:25:49 PDT 2007


 pango/pango-harfbuzz.c |  286 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 211 insertions(+), 75 deletions(-)

New commits:
diff-tree 52cb8939644203c9dd5366b7aca17e7ba285511e (from 111b709dc95c903129b054feacc33dc40983942a)
Author: Simon Hausmann <shausman at trolltech.com>
Date:   Mon Jul 9 08:30:17 2007 +0200

    Get basic functionality up.

diff --git a/pango/pango-harfbuzz.c b/pango/pango-harfbuzz.c
index 7d4437b..cd1b00d 100644
--- a/pango/pango-harfbuzz.c
+++ b/pango/pango-harfbuzz.c
@@ -30,6 +30,7 @@
 #include <pango/pango-ot.h>
 
 #include <harfbuzz-external.h>
+#include <harfbuzz-shaper.h>
 
 /* No extra fields needed */
 typedef PangoEngineShape      BasicEngineHarfBuzz;
@@ -38,6 +39,11 @@ typedef PangoEngineShapeClass BasicEngin
 #define SCRIPT_ENGINE_NAME "BasicScriptEngineHarfBuzz"
 #define RENDER_TYPE PANGO_RENDER_TYPE_FC
 
+#define HB_FIXED_TO_PANGO(value) \
+    (value * (PANGO_SCALE / 64))
+#define PANGO_TO_HB_FIXED(value) \
+    (value / (PANGO_SCALE / 64))
+
 static PangoEngineScriptInfo basic_scripts[] = {
   /* In fact any script we don't know how to shape can go here */
   { PANGO_SCRIPT_COMMON,   "" }
@@ -52,26 +58,140 @@ static PangoEngineInfo script_engines[] 
   }
 };
 
-static const PangoOTFeatureMap gsub_features[] =
+static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft)
 {
-  {"ccmp", PANGO_OT_ALL_GLYPHS},
-  {"locl", PANGO_OT_ALL_GLYPHS},
-  {"liga", PANGO_OT_ALL_GLYPHS},
-  {"clig", PANGO_OT_ALL_GLYPHS}
-};
+    hb_uint32 i;
+    HB_Glyph *glyphPtr = glyphs;
+    PangoFcFont *fc_font = PANGO_FC_FONT (font->faceData);
+
+    for (i = 0; i < length; ++i) {
+        gunichar ch;
+        if (HB_IsHighSurrogate(string[i]) && i < length - 1
+            && HB_IsLowSurrogate(string[i + 1])) {
+            ch = HB_SurrogateToUcs4(string[i], string[i + 1]);
+        } else {
+            ch = string[i];
+        }
+
+        if (rightToLeft)
+            g_unichar_get_mirror_char(ch, &ch);
+
+        *glyphPtr = pango_fc_font_get_glyph(fc_font, ch);
+        ++glyphPtr;
+    }
+
+    *numGlyphs = glyphPtr - glyphs;
 
-static const PangoOTFeatureMap gpos_features[] =
+    return TRUE;
+}
+
+static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags)
 {
-  {"kern", PANGO_OT_ALL_GLYPHS},
-  {"mark", PANGO_OT_ALL_GLYPHS},
-  {"mkmk", PANGO_OT_ALL_GLYPHS}
-};
+    PangoFont *pfont = PANGO_FONT (font->faceData);
+    hb_uint32 i;
+
+    for (i = 0; i < numGlyphs; ++i) {
+        PangoRectangle rect;
+        pango_font_get_glyph_extents(pfont, glyphs[i], NULL, &rect);
+        advances[i] = PANGO_TO_HB_FIXED(rect.width);
+    }
+}
 
-static const PangoOTFeatureMap vertical_gsub_features[] =
+static HB_Bool hb_canRender(HB_Font font, const HB_UChar16 *string, hb_uint32 length)
 {
-  {"ccmp", PANGO_OT_ALL_GLYPHS},
-  {"locl", PANGO_OT_ALL_GLYPHS},
-  {"vert", PANGO_OT_ALL_GLYPHS}
+    return TRUE;
+}
+
+static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
+{
+}
+
+HB_Error hb_getPointInOutline(HB_Font font, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints)
+{
+}
+
+void hb_getGlyphMetrics(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics)
+{
+}
+
+HB_Fixed hb_getFontMetric(HB_Font font, HB_FontMetric metric)
+{
+}
+
+const HB_FontClass hb_fontClass = {
+    hb_stringToGlyphs, hb_getAdvances, hb_canRender,
+    hb_getPointInOutline, hb_getGlyphMetrics, hb_getFontMetric
+};
+
+static HB_Script scriptMap[67] = {
+    /* not included PANGO_SCRIPT_INVALID_CODE = -1 */
+    HB_Script_Common,
+    HB_Script_Inherited,
+    HB_Script_Arabic,
+    HB_Script_Armenian,
+    HB_Script_Bengali,
+    /*HB_Script_Bopomofo,*/ HB_Script_Common,
+    /*HB_Script_Cherokee,*/ HB_Script_Common,
+    /*HB_Script_Coptic,*/ HB_Script_Common,
+    HB_Script_Cyrillic,
+    /*HB_Script_Deseret,*/ HB_Script_Common,
+    HB_Script_Devanagari,
+    /*HB_Script_Ethiopic,*/ HB_Script_Common,
+    HB_Script_Georgian,
+    /*HB_Script_Gothic,*/ HB_Script_Common,
+    HB_Script_Greek,
+    HB_Script_Gujarati,
+    HB_Script_Gurmukhi,
+    /*HB_Script_Han,*/ HB_Script_Common,
+    HB_Script_Hangul,
+    HB_Script_Hebrew,
+    /*HB_Script_Hiragana,*/ HB_Script_Common,
+    HB_Script_Kannada,
+    /*HB_Script_Katakana,*/ HB_Script_Common,
+    HB_Script_Khmer,
+    HB_Script_Lao,
+    /*HB_Script_Latin,*/ HB_Script_Common,
+    HB_Script_Malayalam,
+    /*HB_Script_Mongolian,*/ HB_Script_Common,
+    HB_Script_Myanmar,
+    HB_Script_Ogham,
+    /*HB_Script_Old_italic,*/ HB_Script_Common,
+    HB_Script_Oriya,
+    HB_Script_Runic,
+    HB_Script_Sinhala,
+    HB_Script_Syriac,
+    HB_Script_Tamil,
+    HB_Script_Telugu,
+    HB_Script_Thaana,
+    HB_Script_Thai,
+    HB_Script_Tibetan,
+    /*HB_Script_Canadian_aboriginal,*/ HB_Script_Common,
+    /*HB_Script_Yi,*/ HB_Script_Common,
+    /*HB_Script_Tagalog,*/ HB_Script_Common,
+    /*HB_Script_Hanunoo,*/ HB_Script_Common,
+    /*HB_Script_Buhid,*/ HB_Script_Common,
+    /*HB_Script_Tagbanwa,*/ HB_Script_Common,
+    /*HB_Script_Braille,*/ HB_Script_Common,
+    /*HB_Script_Cypriot,*/ HB_Script_Common,
+    /*HB_Script_Limbu,*/ HB_Script_Common,
+    /*HB_Script_Osmanya,*/ HB_Script_Common,
+    /*HB_Script_Shavian,*/ HB_Script_Common,
+    /*HB_Script_Linear_b,*/ HB_Script_Common,
+    /*HB_Script_Tai_le,*/ HB_Script_Common,
+    /*HB_Script_Ugaritic,*/ HB_Script_Common,
+    /*HB_Script_New_tai_lue,*/ HB_Script_Common,
+    /*HB_Script_Buginese,*/ HB_Script_Common,
+    /*HB_Script_Glagolitic,*/ HB_Script_Common,
+    /*HB_Script_Tifinagh,*/ HB_Script_Common,
+    /*HB_Script_Syloti_nagri,*/ HB_Script_Common,
+    /*HB_Script_Old_persian,*/ HB_Script_Common,
+    /*HB_Script_Kharoshthi,*/ HB_Script_Common,
+    /*HB_Script_Unknown,*/ HB_Script_Common,
+    /*HB_Script_Balinese,*/ HB_Script_Common,
+    /*HB_Script_Cuneiform,*/ HB_Script_Common,
+    /*HB_Script_Phoenician,*/ HB_Script_Common,
+    /*HB_Script_Phags_pa,*/ HB_Script_Common,
+    /*HB_Script_Nko*/ HB_Script_Common
 };
 
 static void
@@ -91,6 +211,17 @@ basic_engine_shape (PangoEngineShape *en
   const char *p;
   int cluster = 0;
   int i;
+  HB_Face hbFace;
+  HB_FontRec hbFont;
+  HB_ShaperItem shaper_item;
+  gunichar2 *utf16;
+  long utf16len = 0;
+  HB_Glyph *hb_glyphs;
+  HB_GlyphAttributes *hb_attributes;
+  HB_Fixed *hb_advances;
+  HB_FixedPoint *hb_offsets;
+  unsigned short *hb_logClusters;
+
 
   g_return_if_fail (font != NULL);
   g_return_if_fail (text != NULL);
@@ -102,72 +233,77 @@ basic_engine_shape (PangoEngineShape *en
   if (!face)
     return;
 
-  buffer = pango_ot_buffer_new (fc_font);
-  pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
-
-  n_chars = g_utf8_strlen (text, length);
-  pango_glyph_string_set_size (glyphs, n_chars);
-
-  p = text;
-  for (i=0; i < n_chars; i++)
-    {
-      gunichar wc;
-      PangoGlyph glyph;
-
-      wc = g_utf8_get_char (p);
-
-      if (g_unichar_type (wc) != G_UNICODE_NON_SPACING_MARK)
-	cluster = p - text;
-
-      if (pango_is_zero_width (wc))
-        glyph = PANGO_GLYPH_EMPTY;
-      else
-        {
-	  gunichar c = wc;
+  utf16 = g_utf8_to_utf16(text, length, NULL, &utf16len, NULL);
 
-	  if (analysis->level % 2)
-	    g_unichar_get_mirror_char (c, &c);
+  hbFace = HB_NewFace(face, hb_getSFntTable);
 
-	  glyph = pango_fc_font_get_glyph (fc_font, c);
-	}
+  hbFont.klass = &hb_fontClass;
+  hbFont.userData = 0;
+  hbFont.faceData = fc_font;
+  hbFont.x_ppem  = face->size->metrics.x_ppem;
+  hbFont.y_ppem  = face->size->metrics.y_ppem;
+  hbFont.x_scale = face->size->metrics.x_scale;
+  hbFont.y_scale = face->size->metrics.y_scale;
+
+  shaper_item.kerning_applied = FALSE;
+  shaper_item.string = utf16;
+  shaper_item.stringLength = utf16len;
+  shaper_item.item.script = scriptMap[analysis->script];
+  shaper_item.item.pos = 0;
+  shaper_item.item.length = shaper_item.stringLength;
+  shaper_item.item.bidiLevel = analysis->level;
+  shaper_item.shaperFlags = 0;
+  shaper_item.font = &hbFont;
+  shaper_item.face = hbFace;
+  shaper_item.num_glyphs = shaper_item.item.length;
+  shaper_item.glyphIndicesPresent = FALSE;
+  shaper_item.initialGlyphCount = 0;
+
+  hb_glyphs = g_new(HB_Glyph, shaper_item.num_glyphs);
+  hb_attributes = g_new(HB_GlyphAttributes, shaper_item.num_glyphs);
+  hb_advances = g_new(HB_Fixed, shaper_item.num_glyphs);
+  hb_offsets = g_new(HB_FixedPoint, shaper_item.num_glyphs);
+  hb_logClusters = g_new(unsigned short, shaper_item.num_glyphs);
+
+  while (1) {
+      hb_glyphs = g_renew(HB_Glyph, hb_glyphs, shaper_item.num_glyphs);
+      hb_attributes = g_renew(HB_GlyphAttributes, hb_attributes, shaper_item.num_glyphs);
+      hb_advances = g_renew(HB_Fixed, hb_advances, shaper_item.num_glyphs);
+      hb_offsets = g_renew(HB_FixedPoint, hb_offsets, shaper_item.num_glyphs);
+      hb_logClusters = g_renew(unsigned short, hb_logClusters, shaper_item.num_glyphs);
+
+      memset(hb_glyphs, 0, shaper_item.num_glyphs * sizeof(HB_Glyph));
+      memset(hb_attributes, 0, shaper_item.num_glyphs * sizeof(HB_GlyphAttributes));
+      memset(hb_advances, 0, shaper_item.num_glyphs * sizeof(HB_Fixed));
+      memset(hb_offsets, 0, shaper_item.num_glyphs * sizeof(HB_FixedPoint));
+
+      shaper_item.glyphs = hb_glyphs;
+      shaper_item.attributes = hb_attributes;
+      shaper_item.advances = hb_advances;
+      shaper_item.offsets = hb_offsets;
+      shaper_item.log_clusters = hb_logClusters;
 
-      if (!glyph)
-	glyph = PANGO_GET_UNKNOWN_GLYPH (wc);
-
-      pango_ot_buffer_add_glyph (buffer, glyph, 0, cluster);
-
-      p = g_utf8_next_char (p);
-    }
-
-  desc.script = analysis->script;
-  desc.language = analysis->language;
-
-  if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
-    {
-      desc.n_static_gsub_features = G_N_ELEMENTS (vertical_gsub_features);
-      desc.static_gsub_features = vertical_gsub_features;
-      desc.n_static_gpos_features = 0;
-      desc.static_gpos_features = NULL;
-    }
-  else
-    {
-      desc.n_static_gsub_features = G_N_ELEMENTS (gsub_features);
-      desc.static_gsub_features = gsub_features;
-      desc.n_static_gpos_features = G_N_ELEMENTS (gpos_features);
-      desc.static_gpos_features = gpos_features;
-    }
-
-  /* TODO populate other_features from analysis->extra_attrs */
-  desc.n_other_features = 0;
-  desc.other_features = NULL;
+      if (HB_ShapeItem(&shaper_item))
+          break;
+  }
 
-  ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc);
+  pango_glyph_string_set_size(glyphs, shaper_item.num_glyphs);
+  for (i = 0; i < shaper_item.num_glyphs; ++i) {
+      glyphs->glyphs[i].glyph = shaper_item.glyphs[i];
+      glyphs->glyphs[i].geometry.width = HB_FIXED_TO_PANGO(shaper_item.advances[i]);
+      glyphs->glyphs[i].geometry.x_offset = HB_FIXED_TO_PANGO(shaper_item.offsets[i].x);
+      glyphs->glyphs[i].geometry.y_offset = HB_FIXED_TO_PANGO(shaper_item.offsets[i].y);
+      glyphs->glyphs[i].attr.is_cluster_start = shaper_item.attributes[i].clusterStart;
+      glyphs->log_clusters[i] = shaper_item.log_clusters[i];
+  }
 
-  pango_ot_ruleset_substitute (ruleset, buffer);
-  pango_ot_ruleset_position (ruleset, buffer);
-  pango_ot_buffer_output (buffer, glyphs);
+  g_free(hb_glyphs);
+  g_free(hb_attributes);
+  g_free(hb_advances);
+  g_free(hb_offsets);
+  g_free(hb_logClusters);
 
-  pango_ot_buffer_destroy (buffer);
+  g_free(utf16);
 
   pango_fc_font_unlock_face (fc_font);
 }



More information about the HarfBuzz mailing list