⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 khmer-fc.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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;  KhmerCharClass charClass;  while (cursor < char_count)    {      charClass = get_char_class (chars[cursor]) & CF_CLASS_MASK;      state = khmerStateTable[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);}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-khmer-ruleset");  if (!info)    return NULL;  ruleset = g_object_get_qdata (G_OBJECT (info), ruleset_quark);  if (!ruleset)    {      PangoOTTag khmer_tag = FT_MAKE_TAG ('k', 'h', 'm', 'r');      guint script_index;      ruleset = pango_ot_ruleset_new (info);      if (pango_ot_info_find_script (info, PANGO_OT_TABLE_GSUB,				      khmer_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,				      khmer_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 voidkhmer_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;  KhmerCharClass 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)    {      /* write a pre vowel or the pre part of a split vowel first       * and look out for coeng + ro. RO is the only vowel of type 2, and       * therefore the only one that requires saving space before the base.       */      glong coengRo = -1;  /* There is no Coeng Ro, if found this value will change */      syllable = find_syllable (wcs, cursor, n_chars);      for (i = cursor; i < syllable; i += 1)	{	  charClass = get_char_class (wcs[i]);	  /* if a split vowel, write the pre part. In Khmer the pre part	   * is the same for all split vowels, same glyph as pre vowel C_VOWEL_E	   */	  if (charClass & CF_SPLIT_VOWEL)	    {	      pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_VOWEL_E), pref_p, p - text);	      break; /* there can be only one vowel */	    }	  /* if a vowel with pos before write it out */	  if (charClass & CF_POS_BEFORE)	    {	      pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pref_p, p - text);	      break; /* there can be only one vowel */	    }	  /* look for coeng + ro and remember position	   * works because coeng + ro is always in front of a vowel (if there is a vowel)	   * and because CC_CONSONANT2 is enough to identify it, as it is the only consonant	   * with this flag	   */	  if ((charClass & CF_COENG) && (i + 1 < syllable) &&	     ((get_char_class (wcs[i + 1]) & CF_CLASS_MASK) == CC_CONSONANT2))	    {	      coengRo = i;	    }	}      /* write coeng + ro if found  */      if (coengRo > -1)	{	  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_COENG), pref_p, p - text);	  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, C_RO), pref_p, p - text);	}      /* 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);	}      /* copy what is left to the output, skipping before vowels and      * coeng Ro if they are present      */      for (i = cursor; i < syllable; i += 1)	{	  charClass = get_char_class (wcs[i]);	  /* skip a before vowel, it was already processed */	  if (charClass & CF_POS_BEFORE)	    {	      p = g_utf8_next_char (p);	      continue;	    }	  /* skip coeng + ro, it was already processed */	  if (i == coengRo)	    {	      p = g_utf8_next_char (p);	      i += 1;	      p = g_utf8_next_char (p);	      continue;	    }	  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:		  /* assign the correct flags to a coeng consonant		  * Consonants of type 3 are taged as Post forms and those type 1 as below forms		  */		if ((charClass & CF_COENG) && i + 1 < syllable)		  {		    if ((get_char_class (wcs[i + 1]) & CF_CLASS_MASK) == CC_CONSONANT3)		      {			pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text);			p = g_utf8_next_char (p);			i += 1;			pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), pstf_p, p - text);			break;		      }		    else		      {			pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			p = g_utf8_next_char (p);			i += 1;			pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			break;		      }		  }		  /* if a shifter is followed by an above vowel change the shifter to below form,		  * an above vowel can have two possible positions i + 1 or i + 3		  * (position i+1 corresponds to unicode 3, position i+3 to Unicode 4)		  * and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two		  * different positions, right after the shifter or after a vowel (Unicode 4)		  */		  if ((charClass & CF_SHIFTER) && (i + 1 < syllable))		    {		      if (get_char_class (wcs[i + 1]) & CF_ABOVE_VOWEL)			{			  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			  break;			}		      if (i + 2 < syllable &&			  (wcs[i + 1] == C_VOWEL_AA) &&			  (wcs[i + 2] == C_SIGN_NIKAHIT) )			{			  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			  break;			}		      if (i + 3 < syllable && (get_char_class (wcs[i + 3]) & CF_ABOVE_VOWEL) )			{			  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			  break;			}		      if (i + 4 < syllable &&			  (wcs[i + 3] == C_VOWEL_AA) &&			  (wcs[i + 4] == C_SIGN_NIKAHIT) )			{			  pango_ot_buffer_add_glyph (buffer, get_index (fc_font, wcs[i]), blwf_p, p - text);			  break;			}		    }		  /* 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 voidkhmer_engine_fc_class_init (PangoEngineShapeClass *class){  class->script_shape = khmer_engine_shape;}PANGO_ENGINE_SHAPE_DEFINE_TYPE (KhmerEngineFc, khmer_engine_fc,				khmer_engine_fc_class_init, NULL)voidPANGO_MODULE_ENTRY(init) (GTypeModule *module){  khmer_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 (khmer_engine_fc_type, NULL);  else    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -