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

📄 khmer-fc.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
  abvf_p    = /*(abvf | abvs | clig | dist | abvm)*/ (pref | pstf | blwf | pres | blws | psts | blwm),  pref_p    = /*(pref | pres | clig | dist)*/ (abvf | pstf | blwf | blws | abvs | psts | blwm | abvm),  default_p = /*(pres | blws | clig | dist | abvm | blwm)*/ (pref | blwf |abvf | pstf | abvs | psts)};/* Below we define how a character in the input string is either in the khmerCharClasses table * (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear * within the syllable, but are not in the table) we also get their type back, or an unknown object * in which case we get _xx (CC_RESERVED) back */static KhmerCharClassget_char_class (gunichar ch){  if (ch == C_SIGN_ZWJ)    return CC_ZERO_WIDTH_J_MARK;  if (ch == C_SIGN_ZWNJ)    return CC_ZERO_WIDTH_NJ_MARK;  if (ch < firstChar || ch > lastChar)    return CC_RESERVED;  return khmerCharClasses[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;  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 const PangoOTFeatureMap gsub_features[] ={  {"ccmp", PANGO_OT_ALL_GLYPHS},  {"locl", PANGO_OT_ALL_GLYPHS},  {"pref", pref},  {"blwf", blwf},  {"abvf", abvf},  {"pstf", pstf},  {"pres", pres},  {"blws", blws},  {"abvs", abvs},  {"psts", psts},  {"clig", clig},  {"calt", PANGO_OT_ALL_GLYPHS}};static const PangoOTFeatureMap gpos_features[] ={  {"dist", dist},  {"blwm", blwm},  {"abvm", abvm},  {"kern", PANGO_OT_ALL_GLYPHS},  {"mark", PANGO_OT_ALL_GLYPHS},  {"mkmk", PANGO_OT_ALL_GLYPHS}};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;  PangoOTRulesetDescription desc;  const 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 */  desc.script = analysis->script;  desc.language = analysis->language;  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;  ruleset = pango_ot_ruleset_get_for_description (pango_ot_info_get (face), &desc);  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 + -