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; }
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)); }
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); }
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); }
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); }
/** * 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; }
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; }
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); }
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; }
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 (); }
static PyObject * pycairo_get_scaled_font (PycairoContext *o) { return PycairoScaledFont_FromScaledFont ( cairo_scaled_font_reference (cairo_get_scaled_font (o->ctx))); }
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); }