FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription) : m_pattern(pattern) , m_fallbacks(0) , m_size(fontDescription.computedPixelSize()) , m_syntheticBold(false) , m_syntheticOblique(false) , m_fixedWidth(false) , m_scaledFont(0) , m_orientation(fontDescription.orientation()) { RefPtr<cairo_font_face_t> fontFace = adoptRef(cairo_ft_font_face_create_for_pattern(m_pattern.get())); initializeWithFontFace(fontFace.get(), fontDescription); int spacing; if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch && spacing == FC_MONO) m_fixedWidth = true; if (fontDescription.weight() >= FontWeightBold) { // The FC_EMBOLDEN property instructs us to fake the boldness of the font. FcBool fontConfigEmbolden = FcFalse; if (FcPatternGetBool(pattern, FC_EMBOLDEN, 0, &fontConfigEmbolden) == FcResultMatch) m_syntheticBold = fontConfigEmbolden; // Fallback fonts may not have FC_EMBOLDEN activated even though it's necessary. int weight = 0; if (!m_syntheticBold && FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) == FcResultMatch) m_syntheticBold = m_syntheticBold || weight < FC_WEIGHT_DEMIBOLD; } }
explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset, double dpi_x, double dpi_y) : font(cairo, offset), m_pattern(pattern) { cairo_matrix_t fm; cairo_matrix_t ctm; cairo_matrix_init_scale(&fm, size(dpi_x), size(dpi_y)); cairo_get_matrix(m_cairo, &ctm); auto fontface = cairo_ft_font_face_create_for_pattern(m_pattern); auto opts = cairo_font_options_create(); m_scaled = cairo_scaled_font_create(fontface, &fm, &ctm, opts); cairo_font_options_destroy(opts); cairo_font_face_destroy(fontface); auto status = cairo_scaled_font_status(m_scaled); if (status != CAIRO_STATUS_SUCCESS) { throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status)); } auto lock = make_unique<utils::ft_face_lock>(m_scaled); auto face = static_cast<FT_Face>(*lock); if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) { return; } else if (FT_Select_Charmap(face, FT_ENCODING_BIG5) == FT_Err_Ok) { return; } else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) { return; } lock.reset(); }
const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { #if defined(USE_FREETYPE) FcResult fresult; FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->platformData()); if (!prim->m_fallbacks) prim->m_fallbacks = FcFontSort(NULL, prim->m_pattern, FcTrue, NULL, &fresult); FcFontSet* fs = prim->m_fallbacks; for (int i = 0; i < fs->nfont; i++) { FcPattern* fin = FcFontRenderPrepare(NULL, prim->m_pattern, fs->fonts[i]); cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin); FontPlatformData alternateFont(fontFace, font.fontDescription().computedPixelSize(), false, false); cairo_font_face_destroy(fontFace); alternateFont.m_pattern = fin; SimpleFontData* sfd = getCachedFontData(&alternateFont); if (sfd->containsCharacters(characters, length)) return sfd; } #endif return 0; }
static cairo_font_face_t * pango_cairo_fc_font_create_font_face (PangoCairoFont *cfont) { PangoFcFont *fcfont = (PangoFcFont *) (cfont); return cairo_ft_font_face_create_for_pattern (fcfont->font_pattern); }
// Takes a Claro font and creates a Cairo font object for use with a Cairo context. static cairo_font_face_t * claro_ft2_cairo_font_create(claro_font_backend_t * backend, claro_font_t * font) { cairo_font_face_t * font_face; g_return_val_if_fail(backend != NULL, NULL); g_return_val_if_fail(font != NULL, NULL); font_face = cairo_ft_font_face_create_for_pattern ((FcPattern *)((claro_font_pattern_t *)font->native)->native); return font_face; }
static cairo_scaled_font_t * create_scaled_font (cairo_t * cr) { FcPattern *pattern, *resolved; FcResult result; cairo_font_face_t *font_face; cairo_scaled_font_t *scaled_font; cairo_font_options_t *font_options; cairo_matrix_t font_matrix, ctm; double pixel_size; font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); pattern = FcPatternCreate (); FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)"Bitstream Vera Sans"); FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE); FcConfigSubstitute (NULL, pattern, FcMatchPattern); cairo_ft_font_options_substitute (font_options, pattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (NULL, pattern, &result); /* set layout to vertical */ FcPatternDel (resolved, FC_VERTICAL_LAYOUT); FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue); FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size); font_face = cairo_ft_font_face_create_for_pattern (resolved); cairo_matrix_init_translate (&font_matrix, 10, 30); cairo_matrix_rotate (&font_matrix, M_PI_2/3); cairo_matrix_scale (&font_matrix, pixel_size, pixel_size); cairo_get_matrix (cr, &ctm); scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, font_options); cairo_font_options_destroy (font_options); cairo_font_face_destroy (font_face); FcPatternDestroy (pattern); FcPatternDestroy (resolved); return scaled_font; }
void FontSysData::Init(Font font, int angle) { LLOG("FontSysData::Init " << font << ", " << angle); FcPattern *p = CreateFcPattern(font); cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(p); FcPatternDestroy(p); cairo_matrix_t font_matrix[1], ctm[1]; cairo_matrix_init_identity(ctm); cairo_matrix_init_scale(font_matrix, font.GetHeight(), font.GetHeight()); if(angle) cairo_matrix_rotate(font_matrix, -angle * M_2PI / 3600); cairo_font_options_t *opt = cairo_font_options_create(); scaled_font = cairo_scaled_font_create(font_face, font_matrix, ctm, opt); cairo_font_options_destroy(opt); cairo_font_face_destroy(font_face); }
FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription) : m_pattern(pattern) , m_fallbacks(0) , m_size(fontDescription.computedPixelSize()) , m_syntheticBold(false) , m_syntheticOblique(false) , m_fixedWidth(false) { PlatformRefPtr<cairo_font_face_t> fontFace = adoptPlatformRef(cairo_ft_font_face_create_for_pattern(m_pattern.get())); initializeWithFontFace(fontFace.get()); int spacing; if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing) == FcResultMatch && spacing == FC_MONO) m_fixedWidth = true; if (fontDescription.weight() >= FontWeightBold) { // The FC_EMBOLDEN property instructs us to fake the boldness of the font. FcBool fontConfigEmbolden; if (FcPatternGetBool(pattern, FC_EMBOLDEN, 0, &fontConfigEmbolden) == FcResultMatch) m_syntheticBold = fontConfigEmbolden; } }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); FcPattern *pattern; cairo_font_face_t *font_face; cairo_font_extents_t font_extents; cairo_font_options_t *font_options; cairo_status_t status; char *filename; int face_count; struct stat stat_buf; xasprintf (&filename, "%s/%s", ctx->srcdir, FONT); if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) { cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename); return CAIRO_TEST_FAILURE; } pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count); free (filename); if (! pattern) { cairo_test_log (ctx, "FcFreeTypeQuery failed.\n"); return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY); } font_face = cairo_ft_font_face_create_for_pattern (pattern); FcPatternDestroy (pattern); status = cairo_font_face_status (font_face); if (status) { cairo_test_log (ctx, "Error creating font face for %s: %s\n", filename, cairo_status_to_string (status)); return cairo_test_status_from_status (ctx, status); } if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) { cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n", cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT); cairo_font_face_destroy (font_face); return CAIRO_TEST_FAILURE; } cairo_set_font_face (cr, font_face); cairo_font_face_destroy (font_face); font_options = cairo_font_options_create (); #define CHECK_FONT_EXTENTS(comment) do {\ cairo_test_status_t test_status; \ test_status = check_font_extents (ctx, cr, (comment)); \ if (test_status != CAIRO_TEST_SUCCESS) { \ cairo_font_options_destroy (font_options); \ return test_status; \ } \ } while (0) cairo_font_extents (cr, &font_extents); CHECK_FONT_EXTENTS ("default"); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_ON"); cairo_move_to (cr, 1, font_extents.ascent - 1); cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */ cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_NONE"); cairo_show_text (cr, "the "); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_SLIGHT"); cairo_show_text (cr, "quick "); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_MEDIUM"); cairo_show_text (cr, "brown"); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_FULL"); cairo_show_text (cr, " fox"); /* Switch from show_text to text_path/fill to exercise bug #7889 */ cairo_text_path (cr, " jumps over a lazy dog"); cairo_fill (cr); /* And test it rotated as well for the sake of bug #7888 */ cairo_translate (cr, width, height); cairo_rotate (cr, M_PI); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT); cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_OFF"); cairo_move_to (cr, 1, font_extents.height - font_extents.descent - 1); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_NONE"); cairo_show_text (cr, "the "); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_SLIGHT"); cairo_show_text (cr, "quick"); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_MEDIUM"); cairo_show_text (cr, " brown"); cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL); cairo_set_font_options (cr, font_options); CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_FULL"); cairo_show_text (cr, " fox"); cairo_text_path (cr, " jumps over"); cairo_text_path (cr, " a lazy dog"); cairo_fill (cr); cairo_font_options_destroy (font_options); return CAIRO_TEST_SUCCESS; }
static cairo_status_t create_scaled_font (cairo_t * cr, cairo_scaled_font_t **out) { FcPattern *pattern, *resolved; FcResult result; cairo_font_face_t *font_face; cairo_scaled_font_t *scaled_font; cairo_font_options_t *font_options; cairo_matrix_t font_matrix, ctm; cairo_status_t status; double pixel_size; font_options = cairo_font_options_create (); cairo_get_font_options (cr, font_options); pattern = FcPatternCreate (); if (pattern == NULL) return CAIRO_STATUS_NO_MEMORY; FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *)CAIRO_TEST_FONT_FAMILY " Sans"); FcPatternAddDouble (pattern, FC_PIXEL_SIZE, TEXT_SIZE); FcConfigSubstitute (NULL, pattern, FcMatchPattern); cairo_ft_font_options_substitute (font_options, pattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (NULL, pattern, &result); if (resolved == NULL) { FcPatternDestroy (pattern); return CAIRO_STATUS_NO_MEMORY; } /* set layout to vertical */ FcPatternDel (resolved, FC_VERTICAL_LAYOUT); FcPatternAddBool (resolved, FC_VERTICAL_LAYOUT, FcTrue); FcPatternGetDouble (resolved, FC_PIXEL_SIZE, 0, &pixel_size); font_face = cairo_ft_font_face_create_for_pattern (resolved); cairo_matrix_init_translate (&font_matrix, 10, 30); cairo_matrix_rotate (&font_matrix, M_PI_2/3); cairo_matrix_scale (&font_matrix, pixel_size, pixel_size); cairo_get_matrix (cr, &ctm); scaled_font = cairo_scaled_font_create (font_face, &font_matrix, &ctm, font_options); cairo_font_options_destroy (font_options); cairo_font_face_destroy (font_face); FcPatternDestroy (pattern); FcPatternDestroy (resolved); status = cairo_scaled_font_status (scaled_font); if (status) { cairo_scaled_font_destroy (scaled_font); return status; } *out = scaled_font; return CAIRO_STATUS_SUCCESS; }
void ScreenPainter::drawGlyph(const GlyphLayout gl) { bool showControls = (m_item->doc()->guidesPrefs().showControls) && (gl.glyph == font().char2CMap(QChar(' ')) || gl.glyph >= ScFace::CONTROL_GLYPHS); #if CAIRO_HAS_FC_FONT if (m_painter->fillMode() == 1 && m_painter->maskMode() <= 0 && !showControls) { m_painter->save(); setupState(false); cairo_t* cr = m_painter->context(); double r, g, b; m_painter->brush().getRgbF(&r, &g, &b); cairo_set_source_rgba(cr, r, g, b, m_painter->brushOpacity()); m_painter->setRasterOp(m_painter->blendModeFill()); if (m_fontPath != font().fontFilePath() || m_faceIndex != font().faceIndex() || m_cairoFace == NULL) { m_fontPath = font().fontFilePath(); m_faceIndex = font().faceIndex(); // A very ugly hack as we can’t use the font().ftFace() because // Scribus liberally calls FT_Set_CharSize() with all sorts of // crazy values, breaking any subsequent call to the layout // painter. FIXME: drop the FontConfig dependency here once // Scribus font handling code is made sane! FcPattern *pattern = FcPatternBuild(NULL, FC_FILE, FcTypeString, QFile::encodeName(font().fontFilePath()).data(), FC_INDEX, FcTypeInteger, font().faceIndex(), NULL); m_cairoFace = cairo_ft_font_face_create_for_pattern(pattern); FcPatternDestroy(pattern); } cairo_set_font_face(cr, m_cairoFace); cairo_set_font_size(cr, fontSize()); cairo_scale(cr, gl.scaleH, gl.scaleV); cairo_glyph_t glyph = { gl.glyph, 0, 0 }; cairo_show_glyphs(cr, &glyph, 1); m_painter->restore(); return; } #endif m_painter->save(); setupState(false); bool fr = m_painter->fillRule(); m_painter->setFillRule(false); uint gid = gl.glyph; if (showControls) { bool stroke = false; if (gid >= ScFace::CONTROL_GLYPHS) gid -= ScFace::CONTROL_GLYPHS; else gid = 32; QTransform chma, chma4; FPointArray outline; if (gid == SpecialChars::TAB.unicode()) { outline = m_item->doc()->symTab.copy(); chma4.translate(gl.xadvance - fontSize() * gl.scaleH * 0.7, -fontSize() * gl.scaleV * 0.5); } else if (gid == SpecialChars::COLBREAK.unicode()) { outline = m_item->doc()->symNewCol.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.6); } else if (gid == SpecialChars::FRAMEBREAK.unicode()) { outline = m_item->doc()->symNewFrame.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.6); } else if (gid == SpecialChars::PARSEP.unicode()) { outline = m_item->doc()->symReturn.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.8); } else if (gid == SpecialChars::LINEBREAK.unicode()) { outline = m_item->doc()->symNewLine.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.4); } else if (gid == SpecialChars::NBSPACE.unicode() || gid == 32) { stroke = (gid == 32); outline = m_item->doc()->symNonBreak.copy(); chma4.translate(0, -fontSize() * gl.scaleV * 0.4); } else if (gid == SpecialChars::NBHYPHEN.unicode()) { outline = font().glyphOutline(font().char2CMap(QChar('-')), fontSize()); chma4.translate(0, -fontSize() * gl.scaleV); } else if (gid == SpecialChars::SHYPHEN.unicode()) { outline.resize(0); outline.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6); stroke = true; } else if (gid == SpecialChars::OBJECT.unicode()) { //for showing marks entries as control chars outline.resize(0); outline.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6); stroke = true; } else // ??? { outline.resize(0); outline.addQuadPoint(0, -10, 0, -10, 0, -9, 0, -9); outline.addQuadPoint(0, -9, 0, -9, 1, -9, 1, -9); outline.addQuadPoint(1, -9, 1, -9, 1, -10, 1, -10); outline.addQuadPoint(1, -10, 1, -10, 0, -10, 0, -10); } chma.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0); outline.map(chma * chma4); m_painter->setupPolygon(&outline, true); QColor oldBrush = m_painter->brush(); // FIXME /* p->setBrush( (flags & ScLayout_SuppressSpace) ? Qt::green : PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor);*/ m_painter->setBrush(PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor); if (stroke) { QColor tmp = m_painter->pen(); m_painter->setStrokeMode(1); m_painter->setPen(m_painter->brush(), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); m_painter->setLineWidth(fontSize() * gl.scaleV / 20.0); m_painter->strokePath(); m_painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); } else { m_painter->setFillMode(1); m_painter->fillPath(); } m_painter->setBrush(oldBrush); } else { m_painter->translate(0, -(fontSize() * gl.scaleV)); double scaleH = gl.scaleH * fontSize() / 10.0; double scaleV = gl.scaleV * fontSize() / 10.0; m_painter->scale(scaleH, scaleV); FPointArray outline = font().glyphOutline(gid); m_painter->setupPolygon(&outline, true); if (outline.size() > 3) m_painter->fillPath(); } m_painter->setFillRule(fr); m_painter->restore(); }
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); }
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); }