Beispiel #1
0
PangoGlyph
mozilla_decoder_get_glyph   (PangoFcDecoder *decoder,
                             PangoFcFont    *fcfont,
                             guint32         wc)
{
    MozillaDecoderPrivate *priv = MOZILLA_DECODER_GET_PRIVATE(decoder);

    PangoGlyph retval = 0;
    PRUnichar inchar = wc;
    PRInt32 inlen = 1;
    char outchar[2] = {0,0};
    PRInt32 outlen = 2;

    priv->uEncoder->Convert(&inchar, &inlen, outchar, &outlen);
    if (outlen != 1) {
        printf("Warning: mozilla_decoder_get_glyph doesn't support more than one character conversions.\n");
        return 0;
    }

    FT_Face face = pango_fc_font_lock_face(fcfont);

#ifdef DEBUG_CUSTOM_ENCODER
    char *filename;
    FcPatternGetString(fcfont->font_pattern, FC_FILE, 0, (FcChar8 **)&filename);
    printf("filename is %s\n", filename);
#endif

    // Make sure to set the right charmap before trying to get the
    // glyph
    if (priv->cmap) {
        if (!strcmp(priv->cmap, "mac_roman")) {
            FT_Select_Charmap(face, ft_encoding_apple_roman);
        }
        else if (!strcmp(priv->cmap, "unicode")) {
            FT_Select_Charmap(face, ft_encoding_unicode);
        }
        else {
            printf("Warning: Invalid charmap entry for family %s\n",
                   priv->family);
        }
    }

    // Standard 8 bit to glyph translation
    if (!priv->is_wide) {
        FcChar32 blah = PRUint8(outchar[0]);
        retval = FT_Get_Char_Index(face, blah);
#ifdef DEBUG_CUSTOM_ENCODER
        printf("wc 0x%x outchar[0] 0x%x index 0x%x retval 0x%x face %p\n",
               wc, outchar[0], blah, retval, (void *)face);
#endif
    }
    else {
        printf("Warning: We don't support .wide fonts!\n");
        retval = 0;
    }

    pango_fc_font_unlock_face(fcfont);

    return retval;
}
Beispiel #2
0
std::string FontSupport::fontPath(PangoFont *font)
{
  PANGO_LOCK;

  PangoFcFont *f = (PangoFcFont *)font;
  FT_Face face = pango_fc_font_lock_face(f);

  std::string result;
  if (face->stream->pathname.pointer)
    result = (const char *)face->stream->pathname.pointer;

  pango_fc_font_unlock_face(f);

  return result;
}
Beispiel #3
0
void text_widget_set_text ( struct TEXT_WIDGET_HANDLE handle,
			    const char* text, int length )
{
  if ( handle.d == NULL || handle.d->layout == NULL )
    return;

  pango_layout_set_markup( handle.d->layout, text, length );

  // The idea here is to make sure that the VGFont contains
  // all the glyphs at the proper size so that when we want
  // to draw, we can can just call vgDrawGlyphs (well, maybe
  // not since PangoGlyphInfo is not an array of glyph
  // indexes; aww).
  PangoLayoutIter* li = pango_layout_get_iter( handle.d->layout );
  do {
    PangoLayoutRun* run = pango_layout_iter_get_run( li );
    if ( run == NULL )
      continue;
    PangoFont* font = run->item->analysis.font;
    // Well, you can see how C is not the most ideal language for
    // abstraction. Have to read the documentation to discover
    // that this font is a PangoFcFont.
    FT_Face face = pango_fc_font_lock_face( (PangoFcFont*)font );
    if ( face != NULL ) {
      struct VG_DATA* vg_data = face->size->generic.data;
      if ( vg_data == NULL ) {
	vg_data = vg_data_new();
	face->size->generic.data = vg_data;
	face->size->generic.finalizer = vg_data_free;
      }
      int g;
      for ( g = 0; g < run->glyphs->num_glyphs; g++ ) {
	int byte = run->glyphs->glyphs[g].glyph / 8;
	int bit  = 1 << ( run->glyphs->glyphs[g].glyph & 0x7 );
	if ( ! ( vg_data->cmap[byte] & bit  ) ) {
	  vg_data->cmap[byte] |= bit;
	  add_char( vg_data->font, face, run->glyphs->glyphs[g].glyph );
	}
      }
      pango_fc_font_unlock_face( (PangoFcFont*)font );
    }
  } while ( pango_layout_iter_next_run( li ) );

  pango_layout_iter_free( li );
}
Beispiel #4
0
static void
gimp_text_render_vectors (PangoFont     *font,
                          PangoGlyph     pango_glyph,
                          FT_Int32       flags,
                          FT_Matrix     *trafo,
                          gint           x,
                          gint           y,
                          RenderContext *context)
{
  const FT_Outline_Funcs  outline_funcs =
  {
    moveto,
    lineto,
    conicto,
    cubicto,
    0,
    0
  };

  FT_Face   face;
  FT_Glyph  glyph;

  face = pango_fc_font_lock_face (PANGO_FC_FONT (font));

  FT_Load_Glyph (face, (FT_UInt) pango_glyph, flags);

  FT_Get_Glyph (face->glyph, &glyph);

  if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
    {
      FT_OutlineGlyph outline_glyph = (FT_OutlineGlyph) glyph;

      context->offset_x = (gdouble) x / PANGO_SCALE;
      context->offset_y = (gdouble) y / PANGO_SCALE;

      FT_Outline_Decompose (&outline_glyph->outline, &outline_funcs, context);
    }

  FT_Done_Glyph (glyph);

  pango_fc_font_unlock_face (PANGO_FC_FONT (font));
}
JNIEXPORT void JNICALL 
Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
  (JNIEnv *env, jobject obj __attribute__((unused)), jint rightGlyph,
   jint leftGlyph, jlong fnt, jfloatArray p)
{
  FT_Face ft_face;
  FT_Vector kern;
  PangoFcFont *font;

  font = JLONG_TO_PTR(PangoFcFont, fnt);
  ft_face = pango_fc_font_lock_face( font );
  g_assert (ft_face != NULL);
  FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );

  pango_fc_font_unlock_face( font );

  jfloat *pelements = (*env)->GetPrimitiveArrayCritical(env, p, NULL);
  pelements[0] = (jfloat)kern.x/64.0;
  pelements[1] = (jfloat)kern.y/64.0;
  (*env)->ReleasePrimitiveArrayCritical (env, p, pelements, 0);
}
JNIEXPORT jdoubleArray JNICALL 
Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
(JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
{
  FT_Face ft_face;
  jdouble *values;
  jdoubleArray retArray = NULL;
  PangoFcFont *font;

  font = JLONG_TO_PTR(PangoFcFont, fnt);
  ft_face = pango_fc_font_lock_face( font );

  g_assert (ft_face != NULL);

  FT_Set_Transform( ft_face, NULL, NULL );

  if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
    {
      pango_fc_font_unlock_face( font );
      printf("Couldn't load glyph %i\n", glyphIndex);
      return NULL;
    }

  retArray = (*env)->NewDoubleArray (env, 8);
  values = (*env)->GetDoubleArrayElements (env, retArray, NULL);

  values[0] = 0;
  values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
  values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
  values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
  values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
  values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
  values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
  values[7] = 0;

  (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
  pango_fc_font_unlock_face( font );

  return retArray;
}
Beispiel #7
0
/**
 * pango_ot_buffer_new
 * @font: a #PangoFcFont
 *
 * Creates a new #PangoOTBuffer for the given OpenType font.
 *
 * Return value: the newly allocated #PangoOTBuffer, which should
 *               be freed with pango_ot_buffer_destroy().
 *
 * Since: 1.4
 **/ 
PangoOTBuffer *
pango_ot_buffer_new (PangoFcFont *font)
{
  /* We lock the font here immediately for the silly reason
   * of getting the FT_Memory; otherwise we'd have to
   * add a new operation to PangoFcFontmap; callers will
   * probably already have the font locked, however,
   * so there is little performance penalty.
   */
  PangoOTBuffer *buffer = g_slice_new (PangoOTBuffer);
  FT_Face face = pango_fc_font_lock_face (font);

  if (hb_buffer_new (face->memory, &buffer->buffer) != FT_Err_Ok)
    g_warning ("Allocation of HB_Buffer failed"); /* this doesn't happen */

  buffer->font = g_object_ref (font);
  buffer->applied_gpos = FALSE;
  buffer->rtl = FALSE;
  buffer->zero_width_marks = FALSE;

  pango_fc_font_unlock_face (font);

  return buffer;
}
Beispiel #8
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);
}
Beispiel #9
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);
}
JNIEXPORT jobject JNICALL 
Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
 (JNIEnv *env, jobject obj __attribute__((unused)), jint glyphIndex, jlong fnt)
{
  generalpath *path;
  jobject gp;
  FT_Outline_Funcs ftCallbacks =
    {
      (FT_Outline_MoveToFunc) _moveTo,
      (FT_Outline_LineToFunc) _lineTo,
      (FT_Outline_ConicToFunc) _quadTo,
      (FT_Outline_CubicToFunc) _curveTo,
      0,
      0
    };
  PangoFcFont *font;
  FT_Face ft_face;
  FT_Glyph glyph;

  font = JLONG_TO_PTR(PangoFcFont, fnt);
  ft_face = pango_fc_font_lock_face( font );

  g_assert (ft_face != NULL);

  path = g_malloc0 (sizeof (generalpath));
  g_assert(path != NULL);
  path->env = env;

  path->px = path->py = 0.0;
  path->sx = 1.0/64.0;
  path->sy = -1.0/64.0;

  {  /* create a GeneralPath instance */
    jclass cls;
    jmethodID method;
    
    cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
    method = (*env)->GetMethodID (env, cls, "<init>", "()V");
    gp = path->obj = (*env)->NewObject (env, cls, method);
  }
	      
  if(FT_Load_Glyph(ft_face,
		   (FT_UInt)(glyphIndex),
		   FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
    {
      pango_fc_font_unlock_face( font );
      g_free(path); 
      return NULL;
    }

  FT_Get_Glyph( ft_face->glyph, &glyph );
  if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
    {
      FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
			    &ftCallbacks, path);
    }
  else
    {
      char format[5];

      format[0] = (glyph->format & 0xFF000000) >> 24;
      format[1] = (glyph->format & 0x00FF0000) >> 16;
      format[2] = (glyph->format & 0x0000FF00) >> 8;
      format[3] = (glyph->format & 0x000000FF);
      format[4] = '\0';
      printf("WARNING: Unable to create outline for font %s %s of format %s\n",
	     ft_face->family_name, ft_face->style_name, format);
    }
  FT_Done_Glyph( glyph );
  
  pango_fc_font_unlock_face( font );

  g_free(path); 

  return gp; 
}
Beispiel #11
0
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);
}
static boolean pango_textlayout(textspan_t * span, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;
    PostscriptAlias *pA;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
#ifdef HAVE_PANGO_FONT_MAP_CREATE_CONTEXT
	context = pango_font_map_create_context (fontmap);
#else
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
#endif
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, span->font->name) != 0 || fontsize != span->font->size) {
	fontname = span->font->name;
	fontsize = span->font->size;
	pango_font_description_free (desc);

	pA = span->font->postscript_alias;
	if (pA) {
	    psfnt = fnt = gv_fmap[pA->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (pA);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((span->font) && (flags = span->font->flags)) {
	unsigned char buf[BUFSIZ];
	agxbuf xb;

	agxbinit(&xb, BUFSIZ, buf);
	agxbput(&xb,"<span");

	if (flags & HTML_BF)
	    agxbput(&xb," weight=\"bold\"");
	if (flags & HTML_IF)
	    agxbput(&xb," style=\"italic\"");
	if (flags & HTML_UL)
	    agxbput(&xb," underline=\"single\"");
	if (flags & HTML_S)
	    agxbput(&xb," strikethrough=\"true\"");
	agxbput (&xb,">");

	if (flags & HTML_SUP)
	    agxbput(&xb,"<sup>");
	if (flags & HTML_SUB)
	    agxbput(&xb,"<sub>");

	agxbput (&xb,xml_string0(span->str, TRUE));

	if (flags & HTML_SUB)
	    agxbput(&xb,"</sub>");
	if (flags & HTML_SUP)
	    agxbput(&xb,"</sup>");

	agxbput (&xb,"</span>");
	if (!pango_parse_markup (agxbuse(&xb), -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = span->str;
	    attrs = NULL;
	}
	agxbfree (&xb);
    }
    else {
	text = span->str;
	attrs = NULL;
    }
#else
    text = span->str;
#endif

    layout = pango_layout_new (context);
    span->layout = (void *)layout;    /* layout free with textspan - see labels.c */
    span->free_layout = pango_free_layout;    /* function for freeing pango layout */

    pango_layout_set_text (layout, text, -1);
    pango_layout_set_font_description (layout, desc);
#ifdef ENABLE_PANGO_MARKUP
    if (attrs)
	pango_layout_set_attributes (layout, attrs);
#endif

    pango_layout_get_extents (layout, NULL, &logical_rect);

    /* if pango doesn't like the font then it sets width=0 but height = garbage */
    if (logical_rect.width == 0)
	logical_rect.height = 0;

    textlayout_scale = POINTS_PER_INCH / (FONT_DPI * PANGO_SCALE);
    span->size.x = (int)(logical_rect.width * textlayout_scale + 1);    /* round up so that width/height are never too small */
    span->size.y = (int)(logical_rect.height * textlayout_scale + 1);

    /* FIXME  -- Horrible kluge !!! */

    /* For now we are using pango for single line blocks only.
     * The logical_rect.height seems to be too high from the font metrics on some platforms.
     * Use an assumed height based on the point size.
     */

    span->size.y = (int)(span->font->size * 1.1 + .5);

    /* The y offset from baseline to 0,0 of the bitmap representation */
#if !defined(WIN32) && defined PANGO_VERSION_MAJOR && (PANGO_VERSION_MAJOR >= 1)
    span->yoffset_layout = pango_layout_get_baseline (layout) * textlayout_scale;
#else
    {
	/* do it the hard way on rhel5/centos5 */
	PangoLayoutIter *iter = pango_layout_get_iter (layout);
	span->yoffset_layout = pango_layout_iter_get_baseline (iter) * textlayout_scale;
    }
#endif

    /* The distance below midline for y centering of text strings */
    span->yoffset_centerline = 0.2 * span->font->size;

    if (logical_rect.width == 0)
	return FALSE;
    return TRUE;
}
Beispiel #13
0
void text_widget_draw_text ( struct TEXT_WIDGET_HANDLE handle )
{
  if ( handle.d == NULL || handle.d->layout == NULL )
    return;

  vgSetPaint( handle.d->foreground, VG_FILL_PATH );

  vgSeti( VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE );
  vgLoadIdentity();
#if 0
  // Overscan (in dots, evidently).
  vgTranslate( 14.f, 8.f );
#endif
  // Offset in mm.
  vgScale( handle.d->dpmm_x, handle.d->dpmm_y );
  // Move to the corner.
  vgTranslate( handle.d->x_mm, handle.d->y_mm );
  // Back to dots.
  vgScale( 1.f/handle.d->dpmm_x, 1.f/handle.d->dpmm_y );

  int height = PANGO_PIXELS( pango_layout_get_height( handle.d->layout ) );

  PangoLayoutIter* li = pango_layout_get_iter( handle.d->layout );
  do {
    PangoLayoutRun* run = pango_layout_iter_get_run( li );
    if ( run == NULL )
      continue;

    PangoRectangle logical_rect;
    int baseline_pango = pango_layout_iter_get_baseline( li );
    int baseline_pixel = PANGO_PIXELS( baseline_pango );
    pango_layout_iter_get_run_extents( li, NULL, &logical_rect );
    int x_pixel = PANGO_PIXELS( logical_rect.x );

    PangoFont* pg_font = run->item->analysis.font;

    FT_Face face = pango_fc_font_lock_face( (PangoFcFont*)pg_font );

    if ( face != NULL ) {

      struct VG_DATA* vg_data = face->size->generic.data;
      if ( vg_data != NULL ) {
	// About the only extra attribute we can manage is the foreground
	// color. But, it might be nice to render a background color
	// to see just how badly the text is fitted into the widget
	// box.
	GSList* attr_item = run->item->analysis.extra_attrs;
	while ( attr_item ) {
	  PangoAttribute* attr = attr_item->data;
	  switch ( attr->klass->type ) {
	  case PANGO_ATTR_FOREGROUND:
	    {
	      PangoColor color = ((PangoAttrColor*)attr)->color;
	      VGfloat new_color[] = { (float)color.red / 65535.f,
				      (float)color.green / 65535.f,
				      (float)color.blue / 65535.f, 1.f };
	      VGPaint new_paint = vgCreatePaint();
	      vgSetParameterfv( new_paint, VG_PAINT_COLOR, 4, new_color );
	      vgSetPaint( new_paint, VG_FILL_PATH );
	      vgDestroyPaint( new_paint );
	    }
	    break;
	  default:
	    printf( "\tHmm. Unknown attribute: %d\n", attr->klass->type );
	  }
	  attr_item = attr_item->next;
	}

	// Note: inverted Y coordinate
	VGfloat point[2] = { x_pixel, height - baseline_pixel };
	vgSetfv( VG_GLYPH_ORIGIN, 2, point );
	VGFont vg_font = vg_data->font;
	int g;
	for ( g = 0; g < run->glyphs->num_glyphs; g++ ) {
	  vgDrawGlyph( vg_font, run->glyphs->glyphs[g].glyph, VG_FILL_PATH,
		       VG_TRUE );
	}

	if ( vgGetPaint( VG_FILL_PATH ) != handle.d->foreground ) {
	  vgSetPaint( handle.d->foreground, VG_FILL_PATH );
	}
      }
      pango_fc_font_unlock_face( (PangoFcFont*)pg_font );
    }
  } while ( pango_layout_iter_next_run( li ) );
  // Iterators are not free.
  pango_layout_iter_free( li);
}
void doDrawGlyphs(PangoRenderer* renderer, PangoFont* font, PangoGlyphString* glyphs, int px, int py) {
    Renderer* ren = RENDERER(renderer);
    if (!ren->m_runs) return;
    std::vector<ViewdoTextRun>& runs = *(ren->m_runs);
    const float s = ren->m_scale;

    PangoColor* fg = pango_renderer_get_color(renderer, PANGO_RENDER_PART_FOREGROUND);
    //PangoColor* bg = pango_renderer_get_color(renderer, PANGO_RENDER_PART_BACKGROUND);

    float red = !fg ? 0.0f : fg->red / 65536.0f;
    float green = !fg ? 0.0f : fg->green / 65536.0f;
    float blue = !fg ? 0.0f : fg->blue / 65536.0f;

    PangoFontDescription* desc = pango_font_describe(font);
    unsigned int fontHash = pango_font_description_hash(desc);
    pango_font_description_free(desc);

    FT_Face face = pango_fc_font_lock_face((PangoFcFont*) font);

    PangoGlyphUnit layoutX = px;
    PangoGlyphUnit layoutY = py;
    ViewdoGlyphCache& cache = ViewdoGlyphCache::instance();

    for (int i = 0; i < glyphs->num_glyphs; i++) {
        PangoGlyphInfo* gi = glyphs->glyphs + i;

        if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG) {
            // XXX: Draw the fallback square.
            continue;
        }

        unsigned int glyph = gi->glyph;
        PangoRectangle r;
        
        pango_font_get_glyph_extents(font, glyph, &r, 0);
        pango_extents_to_pixels(&r, 0);

        float w = r.width;
        float h = r.height;

        if (w <= 0.f && h <= 0.f) {
            // Space.
            layoutX += gi->geometry.width;
            continue;
        }

        // Load and render the glyph. We probably need to just tell the font to cache it
        // and then grab the coordinates of it.
        const ViewdoGlyph& cachedGlyph = cache.findOrCreate(gi->glyph, fontHash, face);
        
        // Walk our existing runs and try to find one with the same color and page.
        // XXX: Fastpath try and use the run from the last glyph.
        ViewdoTextRun* run = nullptr;
        for (auto i = runs.begin(); i != runs.end(); i++) {
            if (i->m_page == cachedGlyph.m_page && i->m_red == red && i->m_green == green && i->m_blue == blue) {
                run = &(*i);
                break;
            }
        }
        if (!run) {
            runs.push_back(ViewdoTextRun(cachedGlyph.m_page, red, green, blue));
            run = &(runs[runs.size() - 1]);
        }

        float x = PANGO_PIXELS(layoutX + gi->geometry.x_offset) + cachedGlyph.m_offsetLeft;
        float y = PANGO_PIXELS(layoutY + gi->geometry.y_offset) - cachedGlyph.m_offsetTop;

        // Append ourselves onto this run.
        addPoint(run->m_geometry,
            x, y,
            cachedGlyph.m_x0, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y,
            cachedGlyph.m_x1, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x, y + cachedGlyph.m_height,
            cachedGlyph.m_x0, cachedGlyph.m_y1,
            s);

        // Triangle 2.
        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y,
            cachedGlyph.m_x1, cachedGlyph.m_y0,
            s);

        addPoint(run->m_geometry,
            x, y + cachedGlyph.m_height,
            cachedGlyph.m_x0, cachedGlyph.m_y1,
            s);

        addPoint(run->m_geometry,
            x + cachedGlyph.m_width, y + cachedGlyph.m_height,
            cachedGlyph.m_x1, cachedGlyph.m_y1,
            s);

        layoutX += gi->geometry.width;
    }

    pango_fc_font_unlock_face((PangoFcFont*) font);
}
Beispiel #15
0
/* analysis->shape_engine has the PangoEngine... */
static void 
indic_engine_shape (PangoEngineShape *engine,
		    PangoFont        *font,
		    const char       *text,
		    gint              length,
		    const PangoAnalysis *analysis,
		    PangoGlyphString *glyphs)
{
  PangoFcFont *fc_font;
  FT_Face face;
  PangoOTRuleset *gsub_ruleset, *gpos_ruleset;
  PangoOTBuffer *buffer;
  glong i, n_chars, n_glyphs;
  gulong *tags = NULL;
  gunichar *wc_in = NULL, *wc_out = NULL;
  glong *utf8_offsets = NULL;
  glong *indices = NULL;
  IndicEngineFc *indic_shape_engine = NULL;
  const PangoIndicInfo *indic_info = NULL;
  MPreFixups *mprefixups;

  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;

  indic_shape_engine = (IndicEngineFc *) engine;

  indic_info = indic_shape_engine->indicInfo;

  wc_in    = expand_text (text, length, &utf8_offsets, &n_chars);
 
  n_glyphs = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, NULL, NULL, NULL, NULL);
  
  wc_out  = g_new (gunichar, n_glyphs);
  indices = g_new (glong,    n_glyphs);
  tags    = g_new (gulong,   n_glyphs);

  n_glyphs  = indic_ot_reorder (wc_in, utf8_offsets, n_chars, indic_info->classTable, wc_out, indices, tags, &mprefixups);
  
  pango_glyph_string_set_size (glyphs, n_glyphs);
  buffer = pango_ot_buffer_new (fc_font);

  set_glyphs(font, wc_out, tags, n_glyphs, buffer,
	     (indic_info->classTable->scriptFlags & SF_PROCESS_ZWJ) != 0);

  /* do gsub processing */
  gsub_ruleset = get_gsub_ruleset (face, indic_info);
  if (gsub_ruleset != NULL)
    pango_ot_ruleset_substitute (gsub_ruleset, buffer);

  /* Fix pre-modifiers for some scripts before base consonant */
  if (mprefixups)
    {
      indic_mprefixups_apply (mprefixups, buffer);
      indic_mprefixups_free (mprefixups);
    }

  /* do gpos processing */
  gpos_ruleset = get_gpos_ruleset (face, indic_info);
  if (gpos_ruleset != NULL)
    pango_ot_ruleset_position (gpos_ruleset, buffer);

  pango_ot_buffer_output (buffer, glyphs);

  /* Get the right log_clusters values */
  for (i = 0; i < glyphs->num_glyphs; i += 1)
    glyphs->log_clusters[i] = indices[glyphs->log_clusters[i]];

  pango_fc_font_unlock_face (fc_font);

  pango_ot_buffer_destroy (buffer);
  g_free (tags);
  g_free (indices);
  g_free (wc_out);
  g_free (wc_in);
  g_free (utf8_offsets);
}
Beispiel #16
0
  gulong *properties = NULL;
  glong n_chars;
  gunichar *wcs;
  const char *p;
  int cluster = 0;
  gboolean rtl = analysis->level % 2 != 0;
  gboolean reverse;
  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, rtl);
  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);

  reverse = !rtl ^ (analysis->gravity == PANGO_GRAVITY_NORTH || analysis->gravity == PANGO_GRAVITY_WEST);
  Arabic_Assign_Properties (wcs, properties, n_chars, reverse);

  g_free (wcs);
static boolean pango_textlayout(textpara_t * para, char **fontpath)
{
    static char buf[1024];  /* returned in fontpath, only good until next call */
    static PangoFontMap *fontmap;
    static PangoContext *context;
    static PangoFontDescription *desc;
    static char *fontname;
    static double fontsize;
    static gv_font_map* gv_fmap;
    char *fnt, *psfnt = NULL;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    cairo_font_options_t* options;
    PangoFont *font;
#ifdef ENABLE_PANGO_MARKUP
    PangoAttrList *attrs;
    GError *error = NULL;
    int flags;
#endif
    char *text;
    double textlayout_scale;

    if (!context) {
	fontmap = pango_cairo_font_map_new();
	gv_fmap = get_font_mapping(fontmap);
	context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP(fontmap));
	options=cairo_font_options_create();
	cairo_font_options_set_antialias(options,CAIRO_ANTIALIAS_GRAY);
	cairo_font_options_set_hint_style(options,CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(options,CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_subpixel_order(options,CAIRO_SUBPIXEL_ORDER_BGR);
	pango_cairo_context_set_font_options(context, options);
	pango_cairo_context_set_resolution(context, FONT_DPI);
	cairo_font_options_destroy(options);
	g_object_unref(fontmap);
    }

    if (!fontname || strcmp(fontname, para->fontname) != 0 || fontsize != para->fontsize) {
	fontname = para->fontname;
	fontsize = para->fontsize;
	pango_font_description_free (desc);

	if (para->postscript_alias) {
	    psfnt = fnt = gv_fmap[para->postscript_alias->xfig_code].gv_font;
	    if(!psfnt)
		psfnt = fnt = pango_psfontResolve (para->postscript_alias);
	}
	else
	    fnt = fontname;

	desc = pango_font_description_from_string(fnt);
        /* all text layout is done at a scale of FONT_DPI (nominaly 96.) */
        pango_font_description_set_size (desc, (gint)(fontsize * PANGO_SCALE));

        if (fontpath && (font = pango_font_map_load_font(fontmap, context, desc))) {  /* -v support */
	    const char *fontclass;

	    fontclass = G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(font));

	    buf[0] = '\0';
	    if (psfnt) {
		strcat(buf, "(ps:pango  ");
		strcat(buf, psfnt);
		strcat(buf, ") ");
	    }
	    strcat(buf, "(");
	    strcat(buf, fontclass);
	    strcat(buf, ") ");
#ifdef HAVE_PANGO_FC_FONT_LOCK_FACE
	    if (strcmp(fontclass, "PangoCairoFcFont") == 0) {
	        FT_Face face;
	        PangoFcFont *fcfont;
	        FT_Stream stream;
	        FT_StreamDesc streamdesc;
	        fcfont = PANGO_FC_FONT(font);
	        face = pango_fc_font_lock_face(fcfont);
	        if (face) {
		    strcat(buf, "\"");
		    strcat(buf, face->family_name);
		    strcat(buf, ", ");
		    strcat(buf, face->style_name);
		    strcat(buf, "\" ");
    
		    stream = face->stream;
		    if (stream) {
			streamdesc = stream->pathname;
			if (streamdesc.pointer)
			    strcat(buf, (char*)streamdesc.pointer);
		        else
			    strcat(buf, "*no pathname available*");
		    }
		    else
			strcat(buf, "*no stream available*");
		}
	        pango_fc_font_unlock_face(fcfont);
	    }
	    else
#endif
	    {
    		PangoFontDescription *tdesc;
		char *tfont;
		
	        tdesc = pango_font_describe(font);
	        tfont = pango_font_description_to_string(tdesc);
	        strcat(buf, "\"");
	        strcat(buf, tfont);
	        strcat(buf, "\" ");
	        g_free(tfont);
	    }
            *fontpath = buf;
        }
    }

#ifdef ENABLE_PANGO_MARKUP
    if ((para->font) && (flags = para->font->flags)) {
	char* markup = N_NEW(strlen(para->str) + sizeof(FULL_MARKUP), char);
	strcpy(markup,"<span");

	if (flags & HTML_BF)
	    strcat(markup," weight=\"bold\"");
	if (flags & HTML_IF)
	    strcat(markup," style=\"italic\"");
	if (flags & HTML_UL)
	    strcat(markup," underline=\"single\"");
	strcat (markup,">");

	if (flags & HTML_SUP)
	    strcat(markup,"<sup>");
	if (flags & HTML_SUB)
	    strcat(markup,"<sub>");

	strcat (markup,para->str);

	if (flags & HTML_SUB)
	    strcat(markup,"</sub>");
	if (flags & HTML_SUP)
	    strcat(markup,"</sup>");

	strcat (markup,"</span>");
	if (!pango_parse_markup (markup, -1, 0, &attrs, &text, NULL, &error)) {
	    fprintf (stderr, "Error - pango_parse_markup: %s\n", error->message);
	    text = para->str;
	    attrs = NULL;
	}
	free (markup);
    }
Beispiel #18
0
/**
 * pango_ot_buffer_output
 * @buffer: a #PangoOTBuffer
 * @glyphs: a #PangoGlyphString
 *
 * Exports the glyphs in a #PangoOTBuffer into a #PangoGlyphString.  This is
 * typically used after the OpenType layout processing is over, to convert the
 * resulting glyphs into a generic Pango glyph string.
 *
 * Since: 1.4
 **/ 
void
pango_ot_buffer_output (PangoOTBuffer    *buffer,
			PangoGlyphString *glyphs)
{
  FT_Face face;
  PangoOTInfo *info;
  HB_GDEF gdef = NULL;
  unsigned int i;
  int last_cluster;

  face = pango_fc_font_lock_face (buffer->font);
  g_assert (face);
  
  /* Copy glyphs into output glyph string */
  pango_glyph_string_set_size (glyphs, buffer->buffer->in_length);

  last_cluster = -1;
  for (i = 0; i < buffer->buffer->in_length; i++)
    {
      HB_GlyphItem item = &buffer->buffer->in_string[i];
      
      glyphs->glyphs[i].glyph = item->gindex;

      glyphs->log_clusters[i] = item->cluster;
      if (glyphs->log_clusters[i] != last_cluster)
	glyphs->glyphs[i].attr.is_cluster_start = 1;
      else
	glyphs->glyphs[i].attr.is_cluster_start = 0;

      last_cluster = glyphs->log_clusters[i];
    }

  info = pango_ot_info_get (face);
  gdef = pango_ot_info_get_gdef (info);
  
  /* Apply default positioning */
  for (i = 0; i < (unsigned int)glyphs->num_glyphs; i++)
    {
      if (glyphs->glyphs[i].glyph)
	{
	  PangoRectangle logical_rect;
	  
	  FT_UShort property;

	  if (buffer->zero_width_marks &&
	      gdef &&
	      HB_GDEF_Get_Glyph_Property (gdef, glyphs->glyphs[i].glyph, &property) == FT_Err_Ok &&
	      (property == HB_GDEF_MARK || (property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS) != 0))
	    {
	      glyphs->glyphs[i].geometry.width = 0;
	    }
	  else
	    {
	      pango_font_get_glyph_extents ((PangoFont *)buffer->font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
	      glyphs->glyphs[i].geometry.width = logical_rect.width;
	    }
	}
      else
	glyphs->glyphs[i].geometry.width = 0;
  
      glyphs->glyphs[i].geometry.x_offset = 0;
      glyphs->glyphs[i].geometry.y_offset = 0;
    }

  if (buffer->rtl)
    {
      /* Swap all glyphs */
      swap_range (glyphs, 0, glyphs->num_glyphs);
    }

  if (buffer->applied_gpos)
    {
      if (buffer->rtl)
	apply_gpos_rtl (glyphs, buffer->buffer->positions);
      else
	apply_gpos_ltr (glyphs, buffer->buffer->positions);
    }
  else
    pango_fc_font_kern_glyphs (buffer->font, glyphs);

  pango_fc_font_unlock_face (buffer->font);
}