📄 tibetan-fc.c
字号:
pres = 0x0010, blws = 0x0020, abvs = 0x0040, psts = 0x0080, clig = 0x0100, dist = 0x0200, blwm = 0x0400, abvm = 0x0800, mkmk = 0x1000};enum properties{ blwf_p = /*(blwf | blws | clig | dist | blwm | mkmk)*/ (abvf | pref | pstf | pres | abvs | psts | abvm), pstf_p = /*(blwf | blws | pref | pres | pstf | psts | clig | dist | blwm)*/ (abvf | abvs | abvm | mkmk), abvf_p = /*(abvf | abvs | clig | dist | abvm | mkmk)*/ (pref | pstf | blwf | pres | blws | psts | blwm), pref_p = /*(pref | pres | clig | dist)*/ (abvf | pstf | blwf | blws | abvs | psts | blwm | abvm | mkmk), default_p = /*(pres | blws | clig | dist | abvm | blwm | mkmk)*/ (pref | blwf |abvf | pstf | abvs | psts)};/* Below we define how a character in the input string is either in the tibetanCharClasses table * (in which case we get its type back), or an unknown object in which case we get _xx (CC_RESERVED) back */static TibetanCharClassget_char_class (gunichar ch){ if (ch < firstChar || ch > lastChar) return CC_RESERVED; return tibetanCharClasses[ch - firstChar];}/* Given an input string of characters and a location in which to start looking * calculate, using the state table, which one is the last character of the syllable * that starts in the starting position. */static glongfind_syllable (const gunichar *chars, glong start, glong char_count){ glong cursor = start; gint8 state = 0; TibetanCharClass charClass; while (cursor < char_count) { charClass = get_char_class (chars[cursor]) & CF_CLASS_MASK; state = tibetanStateTable[state][charClass]; if (state < 0) break; cursor += 1; } return cursor;}static voidmaybe_add_GSUB_feature (PangoOTRuleset *ruleset, PangoOTInfo *info, guint script_index, PangoOTTag tag, gulong property_bit){ guint feature_index; /* 0xffff == default language system */ if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GSUB, tag, script_index, 0xffff, &feature_index)) pango_ot_ruleset_add_feature (ruleset, PANGO_OT_TABLE_GSUB, feature_index, property_bit);}static voidmaybe_add_GPOS_feature (PangoOTRuleset *ruleset, PangoOTInfo *info, guint script_index, PangoOTTag tag, gulong property_bit){ guint feature_index; /* 0xffff == default language system */ if (pango_ot_info_find_feature (info, PANGO_OT_TABLE_GPOS, tag, script_index, 0xffff, &feature_index)) pango_ot_ruleset_add_feature (ruleset, PANGO_OT_TABLE_GPOS, feature_index, property_bit);}/* Rules found in the Open type font features */static PangoOTRuleset *get_ruleset (FT_Face face){ PangoOTRuleset *ruleset; static GQuark ruleset_quark = 0; PangoOTInfo *info = pango_ot_info_get (face); if (!ruleset_quark) ruleset_quark = g_quark_from_string ("pango-tibetan-ruleset"); if (!info) return NULL; ruleset = g_object_get_qdata (G_OBJECT (info), ruleset_quark); if (!ruleset) { PangoOTTag tibetan_tag = FT_MAKE_TAG ('t', 'i', 'b', 't'); guint script_index; ruleset = pango_ot_ruleset_new (info); if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GSUB, tibetan_tag, &script_index)) { maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('p','r','e','f'), pref); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('b','l','w','f'), blwf); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('a','b','v','f'), abvf); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('p','s','t','f'), pstf); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('p','r','e','s'), pres); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('b','l','w','s'), blws); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('a','b','v','s'), abvs); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('p','s','t','s'), psts); maybe_add_GSUB_feature (ruleset, info, script_index, FT_MAKE_TAG ('c','l','i','g'), clig); } if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GPOS, tibetan_tag, &script_index)) { maybe_add_GPOS_feature (ruleset, info, script_index, FT_MAKE_TAG ('d','i','s','t'), dist); maybe_add_GPOS_feature (ruleset, info, script_index, FT_MAKE_TAG ('b','l','w','m'), blwm); maybe_add_GPOS_feature (ruleset, info, script_index, FT_MAKE_TAG ('a','b','v','m'), abvm); maybe_add_GPOS_feature (ruleset, info, script_index, FT_MAKE_TAG ('m','k','m','k'), mkmk); } g_object_set_qdata_full (G_OBJECT (info), ruleset_quark, ruleset, (GDestroyNotify)g_object_unref); } return ruleset;}static PangoGlyphget_index (PangoFcFont *fc_font, gunichar wc){ PangoGlyph index = pango_fc_font_get_glyph (fc_font, wc); if (!index) index = PANGO_GET_UNKNOWN_GLYPH ( wc); return index;}static voidtibetan_engine_shape (PangoEngineShape *engine, PangoFont *font, const char *text, int length, const PangoAnalysis *analysis, PangoGlyphString *glyphs){ PangoFcFont *fc_font; FT_Face face; PangoOTRuleset *ruleset; PangoOTBuffer *buffer; glong n_chars; gunichar *wcs; const char *p; int i; glong syllable; TibetanCharClass charClass; glong cursor = 0; g_return_if_fail (font != NULL); g_return_if_fail (text != NULL); g_return_if_fail (length >= 0); g_return_if_fail (analysis != NULL); fc_font = PANGO_FC_FONT (font); face = pango_fc_font_lock_face (fc_font); if (!face) return; buffer = pango_ot_buffer_new (fc_font); wcs = g_utf8_to_ucs4_fast (text, length, &n_chars); p = text; /* This loop only exits when we reach the end of a run, which may contain * several syllables. */ while (cursor < n_chars) { syllable = find_syllable (wcs, cursor, n_chars); /* shall we add a dotted circle? * If in the position in which the base should be (first char in the string) there is * a character that has the Dotted circle flag (a character that cannot be a base) * then write a dotted circle */ if (get_char_class (wcs[cursor]) & CF_DOTTED_CIRCLE) { pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_DOTTED_CIRCLE), default_p, p - text); } /* If it encounters a digit followed by number pre combining mark, then reorder the two characters * coeng Ro if they are present */ for (i = cursor; i < syllable; i += 1) { charClass = get_char_class (wcs[i]); if ((charClass & CF_DIGIT ) && ( get_char_class (wcs[i+1]) & CF_PREDIGIT)) { pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_PRE_NUMBER_MARK), pref_p, p - text); p = g_utf8_next_char (p); pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pref_p, p - text); i += 1; } else { switch (charClass & CF_POS_MASK) { case CF_POS_ABOVE : pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), abvf_p, p - text); break; case CF_POS_AFTER : pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text); break; case CF_POS_BELOW : pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text); break; default: /* default - any other characters */ pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), default_p, p - text); break; } /* switch */ } p = g_utf8_next_char (p); } /* for */ cursor = syllable; /* move the pointer to the start of next syllable */ } /* while */ /* do gsub processing */ ruleset = get_ruleset (face); if (ruleset != NULL) { pango_ot_ruleset_substitute (ruleset, buffer); pango_ot_ruleset_position (ruleset, buffer); } pango_ot_buffer_output (buffer, glyphs); g_free (wcs); pango_ot_buffer_destroy (buffer); pango_fc_font_unlock_face (fc_font);}static voidtibetan_engine_fc_class_init (PangoEngineShapeClass *class){ class->script_shape = tibetan_engine_shape;}PANGO_ENGINE_SHAPE_DEFINE_TYPE (TibetanEngineFc, tibetan_engine_fc, tibetan_engine_fc_class_init, NULL)voidPANGO_MODULE_ENTRY(init) (GTypeModule *module){ tibetan_engine_fc_register_type (module);}voidPANGO_MODULE_ENTRY(exit) (void){}voidPANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines, int *n_engines){ *engines = script_engines; *n_engines = G_N_ELEMENTS (script_engines);}PangoEngine *PANGO_MODULE_ENTRY(create) (const char *id){ if (!strcmp (id, SCRIPT_ENGINE_NAME)) return g_object_new (tibetan_engine_fc_type, NULL); else return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -