[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