示例#1
0
static void
set_glyphs (PangoFont      *font,
	    const gunichar *wcs,
	    gulong         *tags,
	    glong           n_glyphs,
	    PangoOTBuffer  *buffer,
	    gboolean        process_zwj)
{
  gint i;
  PangoFcFont *fc_font;

  g_assert (font);

  fc_font = PANGO_FC_FONT (font);

  for (i = 0; i < n_glyphs; i++)
    {
      guint glyph;

      if (pango_is_zero_width (wcs[i]) &&
	  (!process_zwj || wcs[i] != 0x200D))
	glyph = PANGO_GLYPH_EMPTY;
      else
        {
	  glyph = pango_fc_font_get_glyph (fc_font, wcs[i]);

	  if (!glyph)
	    glyph = PANGO_GET_UNKNOWN_GLYPH ( wcs[i]);
	}
      pango_ot_buffer_add_glyph (buffer, glyph, tags[i], i);
    }
}
示例#2
0
static void
tibetan_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);
}
示例#3
0
static void
khmer_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);
}
示例#4
0
文件: syriac-fc.c 项目: soubok/libset
static void
syriac_engine_shape (PangoEngineShape *engine,
		     PangoFont        *font,
		     const char       *text,
		     gint              length,
		     const PangoAnalysis *analysis,
		     PangoGlyphString *glyphs)
{
  PangoFcFont *fc_font;
  FT_Face face;
  PangoOTRulesetDescription desc;
  const PangoOTRuleset *ruleset;
  PangoOTBuffer *buffer;
  gulong *properties = NULL;
  glong n_chars;
  gunichar *wcs;
  const char *p;
  int cluster = 0;
  int i;

  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);
  pango_ot_buffer_set_rtl (buffer, analysis->level % 2 != 0);
  pango_ot_buffer_set_zero_width_marks (buffer, TRUE);

  wcs = g_utf8_to_ucs4_fast (text, length, &n_chars);
  properties = g_new0 (gulong, n_chars);

  syriac_assign_properties (wcs, properties, n_chars);

  g_free (wcs);

  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;

	  if (analysis->level % 2)
	    g_unichar_get_mirror_char (c, &c);

	  glyph = pango_fc_font_get_glyph (fc_font, c);
	}

      if (!glyph)
	glyph = PANGO_GET_UNKNOWN_GLYPH (wc);

      pango_ot_buffer_add_glyph (buffer, glyph, properties[i], cluster);

      p = g_utf8_next_char (p);
    }

  g_free (properties);

  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);

  pango_ot_buffer_destroy (buffer);

  pango_fc_font_unlock_face (fc_font);
}