cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
				      cairo_scaled_font_t		*scaled_font,
				      unsigned long			 scaled_font_glyph_index,
				      const char *			 utf8,
				      int				 utf8_len,
                                      cairo_scaled_font_subsets_glyph_t *subset_glyph)
{
    cairo_sub_font_t key, *sub_font;
    cairo_scaled_glyph_t *scaled_glyph;
    cairo_font_face_t *font_face;
    cairo_matrix_t identity;
    cairo_font_options_t font_options;
    cairo_scaled_font_t	*unscaled_font;
    cairo_int_status_t status;
    int max_glyphs;
    cairo_bool_t type1_font;

    /* Lookup glyph in unscaled subsets */
    if (subsets->type != CAIRO_SUBSETS_SCALED) {
        key.is_scaled = FALSE;
        _cairo_sub_font_init_key (&key, scaled_font);
	sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts,
					     &key.base);
        if (sub_font != NULL) {
            status = _cairo_sub_font_lookup_glyph (sub_font,
						   scaled_font_glyph_index,
						   utf8, utf8_len,
						   subset_glyph);
	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
                return status;
        }
    }

    /* Lookup glyph in scaled subsets */
    key.is_scaled = TRUE;
    _cairo_sub_font_init_key (&key, scaled_font);
    sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts,
					 &key.base);
    if (sub_font != NULL) {
	status = _cairo_sub_font_lookup_glyph (sub_font,
					       scaled_font_glyph_index,
					       utf8, utf8_len,
					       subset_glyph);
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    return status;
    }

    /* Glyph not found. Determine whether the glyph is outline or
     * bitmap and add to the appropriate subset.
     *
     * glyph_index 0 (the .notdef glyph) is a special case. Some fonts
     * will return CAIRO_INT_STATUS_UNSUPPORTED when doing a
     * _scaled_glyph_lookup(_GLYPH_INFO_PATH). Type1-fallback creates
     * empty glyphs in this case so we can put the glyph in a unscaled
     * subset. */
    if (scaled_font_glyph_index == 0 ||
	_cairo_font_face_is_user (scaled_font->font_face)) {
	status = CAIRO_STATUS_SUCCESS;
    } else {
	_cairo_scaled_font_freeze_cache (scaled_font);
	status = _cairo_scaled_glyph_lookup (scaled_font,
					     scaled_font_glyph_index,
					     CAIRO_SCALED_GLYPH_INFO_PATH,
					     &scaled_glyph);
	_cairo_scaled_font_thaw_cache (scaled_font);
    }
    if (_cairo_int_status_is_error (status))
        return status;

    if (status == CAIRO_INT_STATUS_SUCCESS &&
	subsets->type != CAIRO_SUBSETS_SCALED &&
	! _cairo_font_face_is_user (scaled_font->font_face))
    {
        /* Path available. Add to unscaled subset. */
        key.is_scaled = FALSE;
        _cairo_sub_font_init_key (&key, scaled_font);
	sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts,
					     &key.base);
        if (sub_font == NULL) {
            font_face = cairo_scaled_font_get_font_face (scaled_font);
            cairo_matrix_init_identity (&identity);
            _cairo_font_options_init_default (&font_options);
            cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
            cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
            unscaled_font = cairo_scaled_font_create (font_face,
                                                      &identity,
                                                      &identity,
                                                      &font_options);
	    if (unlikely (unscaled_font->status))
		return unscaled_font->status;

            subset_glyph->is_scaled = FALSE;
            type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font);
            if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) {
                max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT;
                subset_glyph->is_composite = TRUE;
            } else {
                max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT;
                subset_glyph->is_composite = FALSE;
            }

            status = _cairo_sub_font_create (subsets,
					     unscaled_font,
					     subsets->num_sub_fonts,
					     max_glyphs,
					     subset_glyph->is_scaled,
					     subset_glyph->is_composite,
					     &sub_font);

            if (unlikely (status)) {
		cairo_scaled_font_destroy (unscaled_font);
                return status;
	    }

            status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
                                               &sub_font->base);

            if (unlikely (status)) {
		_cairo_sub_font_destroy (sub_font);
                return status;
	    }
	    if (!subsets->unscaled_sub_fonts_list)
		subsets->unscaled_sub_fonts_list = sub_font;
	    else
		subsets->unscaled_sub_fonts_list_end->next = sub_font;
	    subsets->unscaled_sub_fonts_list_end = sub_font;
	    subsets->num_sub_fonts++;
        }
    } else {
        /* No path available. Add to scaled subset. */
        key.is_scaled = TRUE;
        _cairo_sub_font_init_key (&key, scaled_font);
	sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts,
					     &key.base);
        if (sub_font == NULL) {
            subset_glyph->is_scaled = TRUE;
            subset_glyph->is_composite = FALSE;
            if (subsets->type == CAIRO_SUBSETS_SCALED)
                max_glyphs = INT_MAX;
            else
                max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT;

            status = _cairo_sub_font_create (subsets,
					     cairo_scaled_font_reference (scaled_font),
					     subsets->num_sub_fonts,
					     max_glyphs,
					     subset_glyph->is_scaled,
					     subset_glyph->is_composite,
					     &sub_font);
            if (unlikely (status)) {
		cairo_scaled_font_destroy (scaled_font);
                return status;
	    }

            status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
                                               &sub_font->base);
            if (unlikely (status)) {
		_cairo_sub_font_destroy (sub_font);
                return status;
	    }
	    if (!subsets->scaled_sub_fonts_list)
		subsets->scaled_sub_fonts_list = sub_font;
	    else
		subsets->scaled_sub_fonts_list_end->next = sub_font;
	    subsets->scaled_sub_fonts_list_end = sub_font;
	    subsets->num_sub_fonts++;
        }
    }

    return _cairo_sub_font_map_glyph (sub_font,
				      scaled_font_glyph_index,
				      utf8, utf8_len,
				      subset_glyph);
}
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
{
    // Check for self-assignment.
    if (this == &other)
        return *this;

    m_size = other.m_size;
    m_syntheticBold = other.m_syntheticBold;
    m_syntheticOblique = other.m_syntheticOblique;

    if (other.m_scaledFont)
        cairo_scaled_font_reference(other.m_scaledFont);
    if (m_scaledFont)
        cairo_scaled_font_destroy(m_scaledFont);
    m_scaledFont = other.m_scaledFont;

    if (other.m_font)
        g_object_ref(other.m_font);
    if (m_font)
        g_object_unref(m_font);
    m_font = other.m_font;

    if (other.m_context)
        g_object_ref(other.m_context);
    if (m_context)
        g_object_unref(m_context);
    m_context = other.m_context;

    return *this;
}
static cairo_status_t
_cairo_default_context_set_scaled_font (void *abstract_cr,
                                        cairo_scaled_font_t *scaled_font)
{
    cairo_default_context_t *cr = abstract_cr;
    cairo_bool_t was_previous;
    cairo_status_t status;

    if (scaled_font == cr->gstate->scaled_font)
        return CAIRO_STATUS_SUCCESS;

    was_previous = scaled_font == cr->gstate->previous_scaled_font;

    status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face);
    if (unlikely (status))
        return status;

    status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix);
    if (unlikely (status))
        return status;

    _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options);

    if (was_previous)
        cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font);

    return CAIRO_STATUS_SUCCESS;
}
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
{
    // Check for self-assignment.
    if (this == &other)
        return *this;

    m_font = other.m_font;
    m_size = other.m_size;
    m_syntheticBold = other.m_syntheticBold;
    m_syntheticOblique = other.m_syntheticOblique;
    m_useGDI = other.m_useGDI;

    if (other.m_fontFace)
        cairo_font_face_reference(other.m_fontFace);
    if (m_fontFace)
        cairo_font_face_destroy(m_fontFace);
    m_fontFace = other.m_fontFace;

    if (other.m_scaledFont)
        cairo_scaled_font_reference(other.m_scaledFont);
    if (m_scaledFont)
        cairo_scaled_font_destroy(m_scaledFont);
    m_scaledFont = other.m_scaledFont;

    return *this;
}
示例#5
0
 CairoFont::CairoFont(cairo_scaled_font_t* fontface)
 {
     mFontFace=fontface;
     cairo_scaled_font_reference(mFontFace);
     cairo_scaled_font_extents(mFontFace,&mFontExtents);
     SetFontColor(Color(0,0,0,255));
 }
示例#6
0
文件: editor.c 项目: anarsoul/weston
static struct text_layout *
text_layout_create(void)
{
	struct text_layout *layout;
	cairo_surface_t *surface;
	cairo_t *cr;

	layout = malloc(sizeof *layout);
	if (!layout)
		return NULL;

	layout->glyphs = NULL;
	layout->num_glyphs = 0;

	layout->clusters = NULL;
	layout->num_clusters = 0;

	surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
	cr = cairo_create(surface);
	cairo_set_font_size(cr, font_size);
	cairo_select_font_face(cr, font_name, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
	layout->font = cairo_get_scaled_font(cr);
	cairo_scaled_font_reference(layout->font);

	cairo_destroy(cr);
	cairo_surface_destroy(surface);

	return layout;
}
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other)
{
    // Check for self-assignment.
    if (this == &other)
        return *this;

    m_size = other.m_size;
    m_syntheticBold = other.m_syntheticBold;
    m_syntheticOblique = other.m_syntheticOblique;
    m_fixedWidth = other.m_fixedWidth;
    m_pattern = other.m_pattern;
    m_orientation = other.m_orientation;
    m_horizontalOrientationMatrix = other.m_horizontalOrientationMatrix;

    if (m_fallbacks) {
        FcFontSetDestroy(m_fallbacks);
        // This will be re-created on demand.
        m_fallbacks = 0;
    }

    if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
        cairo_scaled_font_destroy(m_scaledFont);
    m_scaledFont = cairo_scaled_font_reference(other.m_scaledFont);

    m_harfBuzzFace = other.m_harfBuzzFace;

    return *this;
}
void
ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
{
  MOZ_ASSERT(!mScaledFont);

  mScaledFont = font;
  cairo_scaled_font_reference(mScaledFont);
}
示例#9
0
static int
cr_get_scaled_font (lua_State *L) {
    cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT);
    cairo_scaled_font_t **font = create_scaledfont_userdata(L);
    *font = cairo_get_scaled_font(*obj);
    cairo_scaled_font_reference(*font);
    return 1;
}
void FontPlatformData::platformDataInit(const FontPlatformData& source)
{
    m_font = source.m_font;
    m_useGDI = source.m_useGDI;
    m_scaledFont = 0;

    if (source.m_scaledFont)
        m_scaledFont = cairo_scaled_font_reference(source.m_scaledFont);
}
示例#11
0
gfxFT2FontBase::gfxFT2FontBase(cairo_scaled_font_t *aScaledFont,
                               gfxFontEntry *aFontEntry,
                               const gfxFontStyle *aFontStyle)
    : gfxFont(aFontEntry, aFontStyle),
      mScaledFont(aScaledFont),
      mSpaceGlyph(0),
      mHasMetrics(PR_FALSE)
{
    cairo_scaled_font_reference(mScaledFont);
}
示例#12
0
/**
 * cairo_scaled_font_create:
 * @font_face: a #cairo_font_face_t
 * @font_matrix: font space to user space transformation matrix for the
 *       font. In the simplest case of a N point font, this matrix is
 *       just a scale by N, but it can also be used to shear the font
 *       or stretch it unequally along the two axes. See
 *       cairo_set_font_matrix().
 * @ctm: user to device transformation matrix with which the font will
 *       be used.
 * @options: options to use when getting metrics for the font and
 *           rendering with it.
 * 
 * Creates a #cairo_scaled_font_t object from a font face and matrices that
 * describe the size of the font and the environment in which it will
 * be used.
 * 
 * Return value: a newly created #cairo_scaled_font_t. Destroy with
 *  cairo_scaled_font_destroy()
 **/
cairo_scaled_font_t *
cairo_scaled_font_create (cairo_font_face_t          *font_face,
			  const cairo_matrix_t       *font_matrix,
			  const cairo_matrix_t       *ctm,
			  const cairo_font_options_t *options)
{
    cairo_status_t status;
    cairo_scaled_font_map_t *font_map;
    cairo_scaled_font_t key, *scaled_font = NULL;

    if (font_face->status)
	return (cairo_scaled_font_t *)&_cairo_scaled_font_nil;

    font_map = _cairo_scaled_font_map_lock ();
    if (font_map == NULL)
	goto UNWIND;
    
    _cairo_scaled_font_init_key (&key, font_face,
				 font_matrix, ctm, options);

    /* Return existing scaled_font if it exists in the hash table. */
    if (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
				  (cairo_hash_entry_t**) &scaled_font))
    {
	_cairo_scaled_font_map_unlock ();
	return cairo_scaled_font_reference (scaled_font);
    }

    /* Otherwise create it and insert it into the hash table. */
    status = font_face->backend->scaled_font_create (font_face, font_matrix,
						     ctm, options, &scaled_font);
    if (status)
	goto UNWIND_FONT_MAP_LOCK;

    status = _cairo_hash_table_insert (font_map->hash_table,
				       &scaled_font->hash_entry);
    if (status)
	goto UNWIND_SCALED_FONT_CREATE;

    _cairo_scaled_font_map_unlock ();

    return scaled_font;

UNWIND_SCALED_FONT_CREATE:
    /* We can't call _cairo_scaled_font_destroy here since it expects
     * that the font has already been successfully inserted into the
     * hash table. */
    _cairo_scaled_font_fini (scaled_font);
    free (scaled_font);
UNWIND_FONT_MAP_LOCK:
    _cairo_scaled_font_map_unlock ();
UNWIND:
    return NULL;
}
const FontPlatformData& FontPlatformData::platformDataAssign(const FontPlatformData& other)
{
    m_font = other.m_font;
    m_useGDI = other.m_useGDI;

    if (m_scaledFont && m_scaledFont != hashTableDeletedFontValue())
        cairo_scaled_font_destroy(m_scaledFont);

    m_scaledFont = cairo_scaled_font_reference(other.m_scaledFont);

    return *this;
}
static cairo_int_status_t
_cairo_meta_surface_show_glyphs (cairo_scaled_font_t	*scaled_font,
				 cairo_operator_t	operator,
				 cairo_pattern_t	*pattern,
				 void			*abstract_surface,
				 int			source_x,
				 int			source_y,
				 int			dest_x,
				 int			dest_y,
				 unsigned int		width,
				 unsigned int		height,
				 const cairo_glyph_t	*glyphs,
				 int			num_glyphs)
{
    cairo_meta_surface_t *meta = abstract_surface;
    cairo_command_show_glyphs_t *command;

    command = malloc (sizeof (cairo_command_show_glyphs_t));
    if (command == NULL)
	return CAIRO_STATUS_NO_MEMORY;

    command->type = CAIRO_COMMAND_SHOW_GLYPHS;
    command->scaled_font = cairo_scaled_font_reference (scaled_font);
    command->operator = operator;
    _cairo_pattern_init_copy (&command->pattern.base, pattern);
    command->source_x = source_x;
    command->source_y = source_y;
    command->dest_x = dest_x;
    command->dest_y = dest_y;
    command->width = width;
    command->height = height;

    command->glyphs = malloc (sizeof (cairo_glyph_t) * num_glyphs);
    if (command->glyphs == NULL) {
	_cairo_pattern_fini (&command->pattern.base);
	free (command);
        return CAIRO_STATUS_NO_MEMORY;
    }
    memcpy (command->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);

    command->num_glyphs = num_glyphs;

    if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
	_cairo_pattern_fini (&command->pattern.base);
	free (command->glyphs);
	free (command);
	return CAIRO_STATUS_NO_MEMORY;
    }

    return CAIRO_STATUS_SUCCESS;
}
示例#15
0
cairo_scaled_font_t* createScaledFontForFont(const wxFont* wxfont)
{
    ASSERT(wxfont && wxfont->Ok());

    cairo_scaled_font_t* scaledFont = NULL;
    PangoFont* pangoFont = createPangoFontForFont(wxfont);
    
#if PANGO_VERSION_CHECK(1,18,0)
    if (pangoFont)
        scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(pangoFont)));
#endif

    return scaledFont;
}
示例#16
0
void
ScaledFontBase::SetCairoScaledFont(cairo_scaled_font_t* font)
{
  MOZ_ASSERT(!mScaledFont);

  if (font == mScaledFont)
    return;
 
  if (mScaledFont)
    cairo_scaled_font_destroy(mScaledFont);

  mScaledFont = font;
  cairo_scaled_font_reference(mScaledFont);
}
FontPlatformData::FontPlatformData(const FontPlatformData& source)
    : m_font(source.m_font)
    , m_size(source.m_size)
    , m_fontFace(0)
    , m_scaledFont(0)
    , m_syntheticBold(source.m_syntheticBold)
    , m_syntheticOblique(source.m_syntheticOblique)
    , m_useGDI(source.m_useGDI)
{
    if (source.m_fontFace)
        m_fontFace = cairo_font_face_reference(source.m_fontFace);

    if (source.m_scaledFont)
        m_scaledFont = cairo_scaled_font_reference(source.m_scaledFont);
}
示例#18
0
static cairo_status_t
test_scaled_font_init (cairo_scaled_font_t  *scaled_font,
		       cairo_t              *cr,
		       cairo_font_extents_t *extents)
{
    cairo_set_font_face (cr,
			 cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
							&fallback_font_key));

    cairo_scaled_font_set_user_data (scaled_font,
				     &fallback_font_key,
				     cairo_scaled_font_reference (cairo_get_scaled_font (cr)),
				     (cairo_destroy_func_t) cairo_scaled_font_destroy);

    cairo_font_extents (cr, extents);

    return CAIRO_STATUS_SUCCESS;
}
示例#19
0
static cairo_time_t
do_hash_table (cairo_t *cr, int width, int height, int loops)
{
    /*
     * Microsoft C Compiler complains that:
     * error C2466: cannot allocate an array of constant size 0
     * so we add an unused element to make it happy
     */
    cairo_scaled_font_t *active_fonts[ACTIVE_FONTS + 1];
    cairo_matrix_t m;
    int i;

    cairo_matrix_init_identity (&m);

    /* Touch HOLDOVERS scaled fonts to fill up the holdover list. */
    for (i = 0; i < HOLDOVERS; i++) {
	m.yy = m.xx * (i + 1);
	cairo_set_font_matrix (cr, &m);
	cairo_get_scaled_font (cr);
    }

    /*
     * Reference some scaled fonts so that they will be kept in the
     * scaled fonts map. We want LIVE_ENTRIES elements in the font
     * map, but cairo keeps HOLDOVERS recently used fonts in it and we
     * will be activating a new font in the cr context, so we just
     * keep references to ACTIVE_FONTS fonts.
     *
     * Note: setting LIVE_ENTRIES == HOLDOVERS+1 means that we keep no
     * font in active_fonts and the slowness is caused by the holdover
     * fonts only.
     */
    for (i = 0; i < ACTIVE_FONTS; i++) {
	cairo_scaled_font_t *scaled_font;

	m.yy = m.xx * (i + 1);
	cairo_set_font_matrix (cr, &m);

	scaled_font = cairo_get_scaled_font (cr);
	active_fonts[i] = cairo_scaled_font_reference (scaled_font);
    }

    cairo_perf_timer_start ();
    cairo_perf_set_thread_aware (cr, FALSE);

    while (loops--) {
	if (loops == 0)
    	    cairo_perf_set_thread_aware (cr, TRUE); 
	m.xx += 1.0;

	/* Generate ITER new scaled fonts per loop */
	for (i = 0; i < ITER; i++) {
	    m.yy = m.xx * (i + 1);
	    cairo_set_font_matrix (cr, &m);
	    cairo_get_scaled_font (cr);
	}
    }

    cairo_perf_timer_stop ();

    for (i = 0; i < ACTIVE_FONTS; i++)
	cairo_scaled_font_destroy (active_fonts[i]);

    return cairo_perf_timer_elapsed ();
}
示例#20
0
static PyObject *
pycairo_get_scaled_font (PycairoContext *o) {
  return PycairoScaledFont_FromScaledFont (
	   cairo_scaled_font_reference (cairo_get_scaled_font (o->ctx)));
}
示例#21
0
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const UChar *characters, int length)
    : m_context(0)
    , m_font(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
{
    FontPlatformData::init();

    const UChar character = characters[0];

    char const *family;
    switch (fontDescription.genericFamily()) {
        case FontDescription::SerifFamily:
            family = "serif";
            break;
        case FontDescription::SansSerifFamily:
            family = "sans";
            break;
        case FontDescription::MonospaceFamily:
            family = "monospace";
            break;
        case FontDescription::NoFamily:
        case FontDescription::StandardFamily:
        default:
            family = "sans";
            break;
    }

    m_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(m_fontMap));

    PangoFontDescription* description = pango_font_description_new();

    pango_font_description_set_absolute_size(description, fontDescription.computedSize() * PANGO_SCALE);
    if (fontDescription.weight() >= FontWeight600)
        pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
    if (fontDescription.italic())
        pango_font_description_set_style(description, PANGO_STYLE_ITALIC);

    pango_font_description_set_family(description, family);
    pango_context_set_font_description(m_context, description);

    PangoFontset *fset = pango_font_map_load_fontset (m_fontMap, m_context, description, NULL); 

    // Get the font from the fontset which contains the best glyph for this character
    m_font = pango_fontset_get_font(fset, (guint)character);

#if PANGO_VERSION_CHECK(1,18,0)
    if (m_font)
        m_scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font)));
#else
    // This compatibility code for older versions of Pango is not well-tested.
    if (m_font) {
        PangoFcFont* fcfont = PANGO_FC_FONT(m_font);
        cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
        double size;
        if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
          size = 12.0;
        cairo_matrix_t fontMatrix;
        cairo_matrix_init_scale(&fontMatrix, size, size);
        cairo_font_options_t* fontOptions;
        if (pango_cairo_context_get_font_options(m_context))
          fontOptions = cairo_font_options_copy(pango_cairo_context_get_font_options(m_context));
        else
          fontOptions = cairo_font_options_create();
        cairo_matrix_t ctm;
        cairo_matrix_init_identity(&ctm);
        m_scaledFont = cairo_scaled_font_create(face, &fontMatrix, &ctm, fontOptions);
        cairo_font_options_destroy(fontOptions);
        cairo_font_face_destroy(face);
    }
#endif

    pango_font_description_free(description);
}
static cairo_int_status_t
_cairo_recording_surface_show_text_glyphs (void				*abstract_surface,
					   cairo_operator_t		 op,
					   const cairo_pattern_t	*source,
					   const char			*utf8,
					   int				 utf8_len,
					   cairo_glyph_t		*glyphs,
					   int				 num_glyphs,
					   const cairo_text_cluster_t	*clusters,
					   int				 num_clusters,
					   cairo_text_cluster_flags_t	 cluster_flags,
					   cairo_scaled_font_t		*scaled_font,
					   cairo_clip_t			*clip)
{
    cairo_status_t status;
    cairo_recording_surface_t *recording_surface = abstract_surface;
    cairo_command_show_text_glyphs_t *command;

    command = malloc (sizeof (cairo_command_show_text_glyphs_t));
    if (unlikely (command == NULL))
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    status = _command_init (recording_surface,
			    &command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
			    op, clip);
    if (unlikely (status))
	goto CLEANUP_COMMAND;

    status = _cairo_pattern_init_snapshot (&command->source.base, source);
    if (unlikely (status))
	goto CLEANUP_COMMAND;

    command->utf8 = NULL;
    command->utf8_len = utf8_len;
    command->glyphs = NULL;
    command->num_glyphs = num_glyphs;
    command->clusters = NULL;
    command->num_clusters = num_clusters;

    if (utf8_len) {
	command->utf8 = malloc (utf8_len);
	if (unlikely (command->utf8 == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto CLEANUP_ARRAYS;
	}
	memcpy (command->utf8, utf8, utf8_len);
    }
    if (num_glyphs) {
	command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (glyphs[0]));
	if (unlikely (command->glyphs == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto CLEANUP_ARRAYS;
	}
	memcpy (command->glyphs, glyphs, sizeof (glyphs[0]) * num_glyphs);
    }
    if (num_clusters) {
	command->clusters = _cairo_malloc_ab (num_clusters, sizeof (clusters[0]));
	if (unlikely (command->clusters == NULL)) {
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	    goto CLEANUP_ARRAYS;
	}
	memcpy (command->clusters, clusters, sizeof (clusters[0]) * num_clusters);
    }

    command->cluster_flags = cluster_flags;

    command->scaled_font = cairo_scaled_font_reference (scaled_font);

    status = _cairo_array_append (&recording_surface->commands, &command);
    if (unlikely (status))
	goto CLEANUP_SCALED_FONT;

    return CAIRO_STATUS_SUCCESS;

  CLEANUP_SCALED_FONT:
    cairo_scaled_font_destroy (command->scaled_font);
  CLEANUP_ARRAYS:
    free (command->utf8);
    free (command->glyphs);
    free (command->clusters);

    _cairo_pattern_fini (&command->source.base);
  CLEANUP_COMMAND:
    _cairo_clip_fini (&command->header.clip);
    free (command);
    return status;
}
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
    : m_context(0)
    , m_font(0)
    , m_size(fontDescription.computedSize())
    , m_syntheticBold(false)
    , m_syntheticOblique(false)
    , m_scaledFont(0)
{
    FontPlatformData::init();

    CString stored_family = familyName.string().utf8();
    char const* families[] = {
      stored_family.data(),
      NULL
    };

    switch (fontDescription.genericFamily()) {
    case FontDescription::SerifFamily:
        families[1] = "serif";
        break;
    case FontDescription::SansSerifFamily:
        families[1] = "sans";
        break;
    case FontDescription::MonospaceFamily:
        families[1] = "monospace";
        break;
    case FontDescription::NoFamily:
    case FontDescription::StandardFamily:
    default:
        families[1] = "sans";
        break;
    }

    PangoFontDescription* description = pango_font_description_new();
    pango_font_description_set_absolute_size(description, fontDescription.computedSize() * PANGO_SCALE);

    // FIXME: Map all FontWeight values to Pango font weights.
    if (fontDescription.weight() >= FontWeight600)
        pango_font_description_set_weight(description, PANGO_WEIGHT_BOLD);
    if (fontDescription.italic())
        pango_font_description_set_style(description, PANGO_STYLE_ITALIC);

#if PANGO_VERSION_CHECK(1,21,5)   // deprecated in 1.21
    m_context = pango_font_map_create_context(m_fontMap);
#else
    m_context = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(m_fontMap));
#endif
    for (unsigned int i = 0; !m_font && i < G_N_ELEMENTS(families); i++) {
        pango_font_description_set_family(description, families[i]);
        pango_context_set_font_description(m_context, description);
        m_font = pango_font_map_load_font(m_fontMap, m_context, description);
    }

#if PANGO_VERSION_CHECK(1,18,0)
    if (m_font)
        m_scaledFont = cairo_scaled_font_reference(pango_cairo_font_get_scaled_font(PANGO_CAIRO_FONT(m_font)));
#else
    // This compatibility code for older versions of Pango is not well-tested.
    if (m_font) {
        PangoFcFont* fcfont = PANGO_FC_FONT(m_font);
        cairo_font_face_t* face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
        double size;
        if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
            size = 12.0;
        cairo_matrix_t fontMatrix;
        cairo_matrix_init_scale(&fontMatrix, size, size);
        cairo_font_options_t* fontOptions;
        if (pango_cairo_context_get_font_options(m_context))
            fontOptions = cairo_font_options_copy(pango_cairo_context_get_font_options(m_context));
        else
            fontOptions = cairo_font_options_create();
        cairo_matrix_t ctm;
        cairo_matrix_init_identity(&ctm);
        m_scaledFont = cairo_scaled_font_create(face, &fontMatrix, &ctm, fontOptions);
        cairo_font_options_destroy(fontOptions);
        cairo_font_face_destroy(face);
    }
#endif
    pango_font_description_free(description);
}
cairo_private cairo_status_t
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
				      cairo_scaled_font_t		*scaled_font,
				      unsigned long			 scaled_font_glyph_index,
                                      cairo_scaled_font_subsets_glyph_t *subset_glyph)
{
    cairo_sub_font_t key, *sub_font;
    cairo_scaled_glyph_t *scaled_glyph;
    cairo_font_face_t *font_face;
    cairo_matrix_t identity;
    cairo_font_options_t font_options;
    cairo_scaled_font_t	*unscaled_font;
    cairo_status_t status;
    int max_glyphs;
    cairo_bool_t type1_font;

    /* Lookup glyph in unscaled subsets */
    if (subsets->type != CAIRO_SUBSETS_SCALED) {
        key.is_scaled = FALSE;
        _cairo_sub_font_init_key (&key, scaled_font);
        if (_cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base,
                                        (cairo_hash_entry_t **) &sub_font))
        {
            status = _cairo_sub_font_lookup_glyph (sub_font,
                                                   scaled_font_glyph_index,
                                                   subset_glyph);
            if (status == CAIRO_STATUS_SUCCESS)
                return CAIRO_STATUS_SUCCESS;
        }
    }

    /* Lookup glyph in scaled subsets */
    key.is_scaled = TRUE;
    _cairo_sub_font_init_key (&key, scaled_font);
    if (_cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base,
                                  (cairo_hash_entry_t **) &sub_font))
    {
        status = _cairo_sub_font_lookup_glyph (sub_font,
                                               scaled_font_glyph_index,
                                               subset_glyph);
        if (status == CAIRO_STATUS_SUCCESS)
            return CAIRO_STATUS_SUCCESS;
    }

    /* Glyph not found. Determine whether the glyph is outline or
     * bitmap and add to the appropriate subset */
    status = _cairo_scaled_glyph_lookup (scaled_font,
                                         scaled_font_glyph_index,
					 CAIRO_SCALED_GLYPH_INFO_PATH,
                                         &scaled_glyph);
    if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
        return status;

    if (status == 0 && subsets->type != CAIRO_SUBSETS_SCALED) {
        /* Path available. Add to unscaled subset. */
        key.is_scaled = FALSE;
        _cairo_sub_font_init_key (&key, scaled_font);
        if (! _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base,
                                        (cairo_hash_entry_t **) &sub_font))
        {
            font_face = cairo_scaled_font_get_font_face (scaled_font);
            cairo_matrix_init_identity (&identity);
            _cairo_font_options_init_default (&font_options);
            cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE);
            cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF);
            unscaled_font = cairo_scaled_font_create (font_face,
                                                      &identity,
                                                      &identity,
                                                      &font_options);
	    if (unscaled_font->status)
		return unscaled_font->status;

            subset_glyph->is_scaled = FALSE;
            type1_font = FALSE;
#if CAIRO_HAS_FT_FONT
            type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font);
#endif
            if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) {
                max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT;
                subset_glyph->is_composite = TRUE;
            } else {
                max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT;
                subset_glyph->is_composite = FALSE;
            }

            sub_font = _cairo_sub_font_create (subsets,
                                               unscaled_font,
                                               subsets->num_sub_fonts++,
                                               max_glyphs,
                                               subset_glyph->is_scaled,
                                               subset_glyph->is_composite);
            if (sub_font == NULL) {
		cairo_scaled_font_destroy (unscaled_font);
                return CAIRO_STATUS_NO_MEMORY;
	    }

            status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts,
                                               &sub_font->base);
            if (status) {
		_cairo_sub_font_destroy (sub_font);
                return status;
	    }
        }
    } else {
        /* No path available. Add to scaled subset. */
        key.is_scaled = TRUE;
        _cairo_sub_font_init_key (&key, scaled_font);
        if (! _cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base,
                                        (cairo_hash_entry_t **) &sub_font))
        {
            subset_glyph->is_scaled = TRUE;
            subset_glyph->is_composite = FALSE;
            if (subsets->type == CAIRO_SUBSETS_SCALED)
                max_glyphs = INT_MAX;
            else
                max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT;

            sub_font = _cairo_sub_font_create (subsets,
                                               cairo_scaled_font_reference (scaled_font),
                                               subsets->num_sub_fonts++,
                                               max_glyphs,
                                               subset_glyph->is_scaled,
                                               subset_glyph->is_composite);
            if (sub_font == NULL) {
		cairo_scaled_font_destroy (scaled_font);
                return CAIRO_STATUS_NO_MEMORY;
	    }

            status = _cairo_hash_table_insert (subsets->scaled_sub_fonts,
                                               &sub_font->base);
            if (status) {
		_cairo_sub_font_destroy (sub_font);
                return status;
	    }
        }
    }

    return _cairo_sub_font_map_glyph (sub_font,
                                      scaled_font_glyph_index,
                                      subset_glyph);
}