static cairo_status_t _user_font_face_create (cairo_font_face_t **out) { cairo_font_face_t *user_font_face; cairo_font_face_t *fallback_font_face; cairo_status_t status; user_font_face = cairo_user_font_face_create (); cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init); cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph); cairo_user_font_face_set_text_to_glyphs_func (user_font_face, test_scaled_font_text_to_glyphs); /* This also happens to be default font face on cairo_t, so does * not make much sense here. For demonstration only. */ fallback_font_face = cairo_toy_font_face_create ("", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); status = cairo_font_face_set_user_data (user_font_face, &fallback_font_key, fallback_font_face, (cairo_destroy_func_t) cairo_font_face_destroy); if (status) { cairo_font_face_destroy (fallback_font_face); cairo_font_face_destroy (user_font_face); return status; } *out = user_font_face; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t twin_font_face_create_properties (cairo_font_face_t *twin_face, twin_face_properties_t **props_out) { twin_face_properties_t *props; cairo_status_t status; props = malloc (sizeof (twin_face_properties_t)); if (unlikely (props == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); props->stretch = TWIN_STRETCH_NORMAL; props->monospace = FALSE; props->smallcaps = FALSE; status = cairo_font_face_set_user_data (twin_face, &twin_properties_key, props, free); if (unlikely (status)) { free (props); return status; } if (props_out) *props_out = props; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_user_scaled_font_get_implementation (cairo_toy_font_face_t *toy_face, cairo_font_face_t **font_face_out) { static cairo_user_data_key_t twin_font_face_key; cairo_font_face_t *face; cairo_status_t status; face = cairo_font_face_get_user_data (&toy_face->base, &twin_font_face_key); if (!face) { face = _cairo_font_face_twin_create (cairo_toy_font_face_get_slant (&toy_face->base), cairo_toy_font_face_get_weight (&toy_face->base)); status = cairo_font_face_set_user_data (&toy_face->base, &twin_font_face_key, face, (cairo_destroy_func_t) cairo_font_face_destroy); if (status) { cairo_font_face_destroy (face); return status; } } *font_face_out = face; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face, cairo_toy_font_face_t *toy_face) { cairo_status_t status; twin_face_properties_t *props; props = malloc (sizeof (twin_face_properties_t)); if (unlikely (props == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); props->stretch = TWIN_STRETCH_NORMAL; props->monospace = FALSE; props->smallcaps = FALSE; props->slant = toy_face->slant; props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ? TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD; face_props_parse (props, toy_face->family); status = cairo_font_face_set_user_data (twin_face, &twin_properties_key, props, free); if (unlikely (status)) goto FREE_PROPS; return CAIRO_STATUS_SUCCESS; FREE_PROPS: free (props); return status; }
static VALUE cr_freetype_font_face_initialize (VALUE self, VALUE path) { FT_Face freetype_face; FT_Error error; cairo_font_face_t *face; cairo_status_t status; error = FT_New_Face (cr_freetype_library, StringValueCStr(path), 0, &freetype_face); cr_freetype_error_check (error, "failed to open FreeType font", path); cr_freetype_n_faces++; face = cairo_ft_font_face_create_for_ft_face (freetype_face, 0); cr_font_face_check_status (face); status = cairo_font_face_set_user_data (face, &cr_freetype_face_key, freetype_face, (cairo_destroy_func_t) cr_freetype_done_face); if (status != CAIRO_STATUS_SUCCESS) { cairo_font_face_destroy (face); FT_Done_Face (freetype_face); rb_cairo_check_status (status); } DATA_PTR (self) = face; return Qnil; }
static cairo_status_t _user_font_face_create (cairo_font_face_t **out) { static const test_scaled_font_glyph_t glyphs [] = { { 'c', 6, { 0x00, 0x38, 0x44, 0x80, 0x80, 0x80, 0x44, 0x38 } }, { 'a', 6, { 0x00, 0x70, 0x88, 0x3c, 0x44, 0x84, 0x8c, 0x74 } }, { 'i', 1, { 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 } }, { 'r', 6, { 0x00, 0xb8, 0xc4, 0x80, 0x80, 0x80, 0x80, 0x80 } }, { 'o', 7, { 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x44, 0x38 } }, { -1, 8, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, }; cairo_font_face_t *user_font_face; cairo_status_t status; user_font_face = cairo_user_font_face_create (); cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init); cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph); cairo_user_font_face_set_unicode_to_glyph_func (user_font_face, test_scaled_font_unicode_to_glyph); status = cairo_font_face_set_user_data (user_font_face, &test_font_face_glyphs_key, (void*) glyphs, NULL); if (status) { cairo_font_face_destroy (user_font_face); return status; } *out = user_font_face; return CAIRO_STATUS_SUCCESS; }
faceCacheObj *getFontFace(cairoCacheData *cache, char *font) { faceCacheObj *newface = NULL; faceCacheObj *cur=cache->facecache; while(cur) { if(!strcmp(cur->path,font)) return cur; cur = cur->next; } newface = malloc(sizeof(faceCacheObj)); if(FT_New_Face(cache->library, font, 0, &(newface->ftface))) { msSetError(MS_RENDERERERR,"Freetype failed to open font %s","getFontFace()",font); free(newface); return NULL; } newface->next = cache->facecache; cache->facecache = newface; newface->face = cairo_ft_font_face_create_for_ft_face(newface->ftface, 0); cairo_font_face_set_user_data (newface->face, &newface->facekey, &(newface->ftface), (cairo_destroy_func_t) FT_Done_Face); newface->path = msStrdup(font); return newface; }
faceCacheObj *getFontFace(cairoCacheData *cache, const char *font) { faceCacheObj *newface = NULL; faceCacheObj *cur=cache->facecache; while(cur) { if(!strcmp(cur->path,font)) return cur; cur = cur->next; } newface = malloc(sizeof(faceCacheObj)); if(FT_New_Face(cache->library, font, 0, &(newface->ftface))) { msSetError(MS_RENDERERERR,"Freetype failed to open font %s","getFontFace()",font); free(newface); return NULL; } /* Try to select charmap */ if (!newface->ftface->charmap) { if( FT_Select_Charmap(newface->ftface, FT_ENCODING_MS_SYMBOL) ) FT_Select_Charmap(newface->ftface, FT_ENCODING_APPLE_ROMAN ); } newface->next = cache->facecache; cache->facecache = newface; newface->face = cairo_ft_font_face_create_for_ft_face(newface->ftface, 0); cairo_font_face_set_user_data (newface->face, &newface->facekey, &(newface->ftface), (cairo_destroy_func_t) NULL); // we call FT_Done_Face ourselves in freeFaceCache newface->path = msStrdup(font); return newface; }
cairo_face::cairo_face(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face) : face_(face) { static cairo_user_data_key_t key; c_face_ = cairo_ft_font_face_create_for_ft_face(face->get_face(), FT_LOAD_NO_HINTING); cairo_font_face_set_user_data(c_face_, &key, new handle(engine, face), destroy); }
static cairo_font_face_t * get_user_font_face (void) { if (!user_font_face) { cairo_font_face_t *fallback_font_face; user_font_face = cairo_user_font_face_create (); cairo_user_font_face_set_init_func (user_font_face, test_scaled_font_init); cairo_user_font_face_set_render_glyph_func (user_font_face, test_scaled_font_render_glyph); cairo_user_font_face_set_text_to_glyphs_func (user_font_face, test_scaled_font_text_to_glyphs); /* This also happens to be default font face on cairo_t, so does * not make much sense here. For demonstration only. */ fallback_font_face = cairo_toy_font_face_create ("", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_font_face_set_user_data (user_font_face, &fallback_font_key, fallback_font_face, (cairo_destroy_func_t) cairo_font_face_destroy); } return user_font_face; }
void CairoRenderer::SetFontFace(InputStream *pStream) { FT_Face face; static cairo_user_data_key_t key; if (m_cairo_face) { cairo_set_font_face(m_pCairo, NULL); cairo_font_face_destroy(m_cairo_face); m_cairo_face = NULL; } if (pStream) { face = FreeType::OpenFace(pStream); // face will be destroyed by FT_Done_Face if (face) { m_cairo_face = cairo_ft_font_face_create_for_ft_face(face, 0); cairo_font_face_set_user_data(m_cairo_face, &key, face, (cairo_destroy_func_t)FT_Done_Face); } } else m_cairo_face = cairo_toy_font_face_create("unifont", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); if (m_cairo_face) cairo_set_font_face(m_pCairo, m_cairo_face); }
cairo_face::cairo_face(std::shared_ptr<font_library> const& library, face_ptr const& face) : face_(face) { static cairo_user_data_key_t key; c_face_ = cairo_ft_font_face_create_for_ft_face(face->get_face(), FT_LOAD_NO_HINTING); cairo_font_face_set_user_data(c_face_, &key, new handle(library, face), destroy); }
static VALUE cr_user_font_face_initialize (VALUE self) { cairo_font_face_t *face; face = cairo_user_font_face_create (); cr_font_face_check_status (face); cairo_font_face_set_user_data (face, &ruby_object_key, (void *)self, NULL); cairo_user_font_face_set_init_func (face, cr_user_font_face_init_func); cairo_user_font_face_set_render_glyph_func (face, cr_user_font_face_render_glyph_func); cairo_user_font_face_set_text_to_glyphs_func (face, cr_user_font_face_text_to_glyphs_func); cairo_user_font_face_set_unicode_to_glyph_func (face, cr_user_font_face_unicode_to_glyph_func); rb_ivar_set (self, cr_id_init, Qnil); rb_ivar_set (self, cr_id_render_glyph, Qnil); rb_ivar_set (self, cr_id_text_to_glyphs, Qnil); rb_ivar_set (self, cr_id_unicode_to_glyph, Qnil); DATA_PTR (self) = face; return Qnil; }
SkCairoFTTypeface(cairo_font_face_t* fontFace, const SkFontStyle& style, SkFontID id, bool isFixedWidth) : SkTypeface(style, id, isFixedWidth) , fFontFace(fontFace) { cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, NULL); cairo_font_face_reference(fFontFace); }
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) { ASSERT_ARG(buffer, buffer); int error; static FT_Library library = 0; if (!library) { error = FT_Init_FreeType(&library); if (error) { library = 0; return 0; } } FT_Face face; error = FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer->data()), buffer->size(), 0, &face); if (error) return 0; buffer->ref(); cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_ft_face(face, 0); static cairo_user_data_key_t bufferKey; cairo_font_face_set_user_data(fontFace, &bufferKey, buffer, releaseData); return new FontCustomPlatformData(fontFace); }
FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer& buffer) : m_freeTypeFace(freeTypeFace) , m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, 0)) { // FIXME Should we be setting some hinting options here? buffer.ref(); // This is balanced by the buffer->deref() in releaseCustomFontData. static cairo_user_data_key_t bufferKey; cairo_font_face_set_user_data(m_fontFace, &bufferKey, &buffer, static_cast<cairo_destroy_func_t>(releaseCustomFontData)); // Cairo doesn't do FreeType reference counting, so we need to ensure that when // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well. static cairo_user_data_key_t freeTypeFaceKey; cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace, reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face)); }
UserFont::UserFont(SvgFont* instance){ this->face = cairo_user_font_face_create (); cairo_user_font_face_set_init_func (this->face, font_init_cb); cairo_user_font_face_set_render_glyph_func (this->face, font_render_glyph_cb); cairo_user_font_face_set_text_to_glyphs_func(this->face, font_text_to_glyphs_cb); cairo_font_face_set_user_data (this->face, &key, (void*)instance, (cairo_destroy_func_t) NULL); }
SkCairoFTTypeface(const SkFontStyle& style, SkFontID id, bool isFixedWidth, cairo_font_face_t* fontFace, FcPattern* pattern) : SkTypeface(style, id, isFixedWidth) , fFontFace(fontFace) , fPattern(pattern) { cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, this, nullptr); cairo_font_face_reference(fFontFace); #ifdef CAIRO_HAS_FC_FONT if (fPattern) { FcPatternReference(fPattern); } #endif }
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) { ASSERT_ARG(buffer, buffer); buffer->ref(); HFONT font = reinterpret_cast<HFONT>(buffer); cairo_font_face_t* fontFace = cairo_win32_font_face_create_for_hfont(font); if (!fontFace) return 0; static cairo_user_data_key_t bufferKey; cairo_font_face_set_user_data(fontFace, &bufferKey, buffer, releaseData); return new FontCustomPlatformData(fontFace); }
value lime_cairo_ft_font_face_create (value face, int flags) { #ifdef LIME_FREETYPE Font* font = (Font*)val_data (face); cairo_font_face_t* cairoFont = cairo_ft_font_face_create_for_ft_face ((FT_Face)font->face, flags); AutoGCRoot* fontReference = new AutoGCRoot (face); cairo_font_face_set_user_data (cairoFont, &userData, fontReference, gc_user_data); return CFFIPointer (cairoFont, gc_cairo_font_face); #else return 0; #endif }
cairo_font_face_t *Rcairo_set_font_face(int i, const char *file){ cairo_font_face_t *c_face; cairo_status_t status; FT_Face face; FT_Error er; FT_CharMap found = 0; FT_CharMap charmap; int n; /* Ensure that freetype library is ready */ if (!Rcairo_ft_library){ if (FT_Init_FreeType(&Rcairo_ft_library)){ error("Failed to initialize freetype library in Rcairo_set_font_face!\n"); return FALSE; } } er = FT_New_Face(Rcairo_ft_library, file, 0, &face); if ( er == FT_Err_Unknown_File_Format ) { error("Unsupported font file format\n"); return NULL; } else if ( er ) { error("Unknown font problem\n"); return NULL; } for ( n = 0; n < face->num_charmaps; n++ ) { charmap = face->charmaps[n]; if ( charmap->platform_id == TT_PLATFORM_MACINTOSH) { found = charmap; break; } } /* Only do this for symbol font */ if (found && i == 4){ er = FT_Set_Charmap( face, found ); } c_face = cairo_ft_font_face_create_for_ft_face(face,FT_LOAD_DEFAULT); status = cairo_font_face_set_user_data (c_face, &key, face, (cairo_destroy_func_t) FT_Done_Face); if (status) { cairo_font_face_destroy (c_face); FT_Done_Face (face); return NULL; } return c_face; }
static twin_face_properties_t * twin_font_face_create_properties (cairo_font_face_t *twin_face) { twin_face_properties_t *props; props = malloc (sizeof (twin_face_properties_t)); if (unlikely (props == NULL)) return NULL; props->stretch = TWIN_STRETCH_NORMAL; props->slant = CAIRO_FONT_SLANT_NORMAL; props->weight = TWIN_WEIGHT_NORMAL; props->monospace = FALSE; props->smallcaps = FALSE; if (unlikely (cairo_font_face_set_user_data (twin_face, &twin_properties_key, props, free))) { free (props); return NULL; } return props; }
PRUint32 gfxFT2FontBase::GetGlyph(PRUint32 aCharCode) { // FcFreeTypeCharIndex needs to lock the FT_Face and can end up searching // through all the postscript glyph names in the font. Therefore use a // lightweight cache, which is stored on the cairo_font_face_t. cairo_font_face_t *face = cairo_scaled_font_get_font_face(CairoScaledFont()); if (cairo_font_face_status(face) != CAIRO_STATUS_SUCCESS) return 0; // This cache algorithm and size is based on what is done in // cairo_scaled_font_text_to_glyphs and pango_fc_font_real_get_glyph. I // think the concept is that adjacent characters probably come mostly from // one Unicode block. This assumption is probably not so valid with // scripts with large character sets as used for East Asian languages. struct CmapCacheSlot { PRUint32 mCharCode; PRUint32 mGlyphIndex; }; const PRUint32 kNumSlots = 256; static cairo_user_data_key_t sCmapCacheKey; CmapCacheSlot *slots = static_cast<CmapCacheSlot*> (cairo_font_face_get_user_data(face, &sCmapCacheKey)); if (!slots) { // cairo's caches can keep some cairo_font_faces alive past our last // destroy, so the destroy function (free) for the cache must be // callable from cairo without any assumptions about what other // modules have not been shutdown. slots = static_cast<CmapCacheSlot*> (calloc(kNumSlots, sizeof(CmapCacheSlot))); if (!slots) return 0; cairo_status_t status = cairo_font_face_set_user_data(face, &sCmapCacheKey, slots, free); if (status != CAIRO_STATUS_SUCCESS) { // OOM free(slots); return 0; } // Invalidate slot 0 by setting its char code to something that would // never end up in slot 0. All other slots are already invalid // because they have mCharCode = 0 and a glyph for char code 0 will // always be in the slot 0. slots[0].mCharCode = 1; } CmapCacheSlot *slot = &slots[aCharCode % kNumSlots]; if (slot->mCharCode != aCharCode) { slot->mCharCode = aCharCode; slot->mGlyphIndex = gfxFT2LockedFace(this).GetGlyph(aCharCode); } return slot->mGlyphIndex; }
static zend_bool php_cairo_create_ft_font_face(pecl_ft_container *ft_container, cairo_ft_font_face_object *font_face_object, php_stream *stream, zend_bool owned_stream, int load_flags, zend_bool throw_exceptions TSRMLS_DC) { FT_Stream ft_stream; stream_closure *closure; php_stream_statbuf ssbuf; FT_Open_Args open_args; int error; if (php_stream_stat(stream,&ssbuf) < 0) { return 1; } ft_container->ft_face = NULL; ft_container->ft_stream = NULL; font_face_object->closure = NULL; closure = ecalloc(1, sizeof(stream_closure)); closure->stream = stream; closure->owned_stream = owned_stream; #ifdef ZTS closure->TSRMLS_C = TSRMLS_C; #endif ft_stream = pecalloc(1, sizeof(*ft_stream), TRUE); ft_stream->descriptor.pointer = (void *)closure; ft_stream->pos = php_stream_tell(stream); ft_stream->size = ssbuf.sb.st_size; ft_stream->read = php_cairo_ft_read_func; open_args.flags = FT_OPEN_STREAM; open_args.stream = ft_stream; error = FT_Open_Face(ft_container->ft_lib, &open_args, 0, &ft_container->ft_face); if (error) { if (owned_stream) { php_stream_close(stream); } efree(closure); pefree(ft_stream, TRUE); return error; } font_face_object->closure = closure; ft_container->ft_stream = ft_stream; font_face_object->font_face = (cairo_font_face_t *)cairo_ft_font_face_create_for_ft_face(ft_container->ft_face, (int)load_flags); /* Set Cairo to automatically destroy the FT_Face when the cairo_font_face_t is destroyed */ error = cairo_font_face_set_user_data ( font_face_object->font_face, &font_face_object->key, ft_container, (cairo_destroy_func_t) cairo_user_data_callback_ft_free); if (error) { cairo_font_face_destroy (font_face_object->font_face); FT_Done_Face(ft_container->ft_face); pefree(ft_stream, TRUE); return error; } return 0; }
void Drawer::DrawText(std::string& aTexte) { Point Point1 (100,100); FacesMap::iterator IterFont; cairo_text_extents_t te; cairo_font_face_t* Cairo_font_face = NULL; for (IterFont = mFacesMap.begin(); IterFont != mFacesMap.end(); ++IterFont) { cairo_user_data_key_t Key; FT_Face FaceFind = IterFont->second; if (FaceFind) { Cairo_font_face = cairo_ft_font_face_create_for_ft_face (FaceFind,0); cairo_font_face_set_user_data (Cairo_font_face, &Key, FaceFind, NULL); cairo_set_font_size (mCairoDC, 75); cairo_set_source_rgb (mCairoDC, 0.0, 0.0, 0.0); MoveTo(Point1); std::string StrTmp = IterFont->first; StrTmp += "||"; cairo_ft_font_face_set_synthesize (Cairo_font_face, CAIRO_FT_SYNTHESIZE_BOLD); cairo_ft_font_face_set_synthesize (Cairo_font_face, CAIRO_FT_SYNTHESIZE_OBLIQUE); cairo_set_font_face(mCairoDC, Cairo_font_face); cairo_text_path (mCairoDC, StrTmp.c_str()); cairo_fill(mCairoDC); cairo_text_extents(mCairoDC,StrTmp.c_str(),&te); Point1.X += (te.width + 10); MoveTo(Point1); cairo_text_path (mCairoDC, IterFont->first.c_str()); cairo_fill(mCairoDC); Point1.X -= (te.width + 10); Point1.Y += 100; cairo_font_face_set_user_data (Cairo_font_face, &Key, NULL, NULL); cairo_font_face_destroy(Cairo_font_face); } } cairo_user_data_key_t KeyFontSystem; if (mFontSystem) { Cairo_font_face = cairo_ft_font_face_create_for_ft_face (mFontSystem,0); cairo_font_face_set_user_data (Cairo_font_face, &KeyFontSystem, mFontSystem, NULL); cairo_set_font_size (mCairoDC, 75); cairo_set_source_rgb (mCairoDC, 0.0, 0.0, 0.0); MoveTo(Point1); cairo_set_font_face(mCairoDC, Cairo_font_face); cairo_text_path (mCairoDC, "FontSystem"); cairo_fill(mCairoDC); cairo_font_face_set_user_data (Cairo_font_face, &KeyFontSystem, NULL, NULL); cairo_font_face_destroy(Cairo_font_face); } Point1.X -= (100); Point1.Y += 100; cairo_user_data_key_t KeyFontTest; if (mFontTest) { Cairo_font_face = cairo_ft_font_face_create_for_ft_face (mFontTest,0); cairo_font_face_set_user_data (Cairo_font_face, &KeyFontTest, mFontTest, NULL); cairo_set_font_size (mCairoDC, 75); cairo_set_source_rgb (mCairoDC, 0.0, 0.0, 0.0); MoveTo(Point1); cairo_set_font_face(mCairoDC, Cairo_font_face); cairo_text_path (mCairoDC, "FontTest"); cairo_fill(mCairoDC); cairo_font_face_set_user_data (Cairo_font_face, &KeyFontTest, NULL, NULL); cairo_font_face_destroy(Cairo_font_face); } }
~SkCairoFTTypeface() { cairo_font_face_set_user_data(fFontFace, &kSkTypefaceKey, NULL, NULL); cairo_font_face_destroy(fFontFace); }
static cairo_status_t _cairo_quartz_font_get_implementation (cairo_toy_font_face_t *toy_face, cairo_scaled_font_t **font_face_out) { static cairo_user_data_key_t impl_font_face_key; cairo_font_face_t *face; cairo_status_t status; const char *family = toy_face->family; char *full_name = malloc(strlen(family) + 64); // give us a bit of room to tack on Bold, Oblique, etc. CFStringRef cgFontName = NULL; CGFontRef cgFont = NULL; int loop; face = cairo_font_face_get_user_data (&toy_face->base, &impl_font_face_key); if (face) { *font_face_out = face; return CAIRO_STATUS_SUCCESS; } quartz_font_ensure_symbols(); if (! _cairo_quartz_font_symbols_present) return _cairo_error (CAIRO_STATUS_NO_MEMORY); /* handle CSS-ish faces */ if (!strcmp(family, "serif") || !strcmp(family, "Times Roman")) family = "Times"; else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans")) family = "Helvetica"; else if (!strcmp(family, "cursive")) family = "Apple Chancery"; else if (!strcmp(family, "fantasy")) family = "Papyrus"; else if (!strcmp(family, "monospace") || !strcmp(family, "mono")) family = "Courier"; /* Try to build up the full name, e.g. "Helvetica Bold Oblique" first, * then drop the bold, then drop the slant, then drop both.. finally * just use "Helvetica". And if Helvetica doesn't exist, give up. */ for (loop = 0; loop < 5; loop++) { if (loop == 4) family = "Helvetica"; strcpy (full_name, family); if (loop < 3 && (loop & 1) == 0) { if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD) strcat (full_name, " Bold"); } if (loop < 3 && (loop & 2) == 0) { if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC) strcat (full_name, " Italic"); else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE) strcat (full_name, " Oblique"); } if (CGFontCreateWithFontNamePtr) { cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII); cgFont = CGFontCreateWithFontNamePtr (cgFontName); CFRelease (cgFontName); } else { cgFont = CGFontCreateWithNamePtr (full_name); } if (cgFont) break; } if (!cgFont) { /* Give up */ return _cairo_error (CAIRO_STATUS_NO_MEMORY); } face = cairo_quartz_font_face_create_for_cgfont (cgFont); CGFontRelease (cgFont); if (face->status) return face->status; status = cairo_font_face_set_user_data (&toy_face->base, &impl_font_face_key, face, (cairo_destroy_func_t) cairo_font_face_destroy); if (status) { cairo_font_face_destroy (face); return status; } *font_face_out = face; return CAIRO_STATUS_SUCCESS; }
gboolean draw_overview_glyph (cairo_t* context, const char* font_file, gdouble width, gdouble height, gunichar character) { FT_Face face; int error; gdouble units_per_em; gdouble units; gdouble advance; int gid; // private use area if (0xe000 <= character && character <= 0xf8ff) { return FALSE; } // control characters if (character <= 0x001f || (0x007f <= character && character <= 0x008d)) { return FALSE; } if (font_file == NULL) { g_warning("font_file is null"); return FALSE; } gchar text[7]; int length = g_unichar_to_utf8 (character, text); text[length] = '\0'; if (freetype_library == NULL) { error = FT_Init_FreeType (&freetype_library); if (error) { g_warning ("Freetype init error %d.\n", error); return FALSE; } } error = FT_New_Face (freetype_library, font_file, 0, &face); if (error) { g_warning ("Freetype font face error %d\n", error); return FALSE; } units_per_em = face->units_per_EM; units = (height * 0.5) / units_per_em; error = FT_Select_Charmap (face , FT_ENCODING_UNICODE); if (error) { g_warning ("Freetype can not use Unicode, error: %d\n", error); FT_Done_Face (face); return FALSE; } error = FT_Set_Char_Size (face, 0, 64, (int) height, (int) height); if (error) { g_warning ("FT_Set_Char_Size, error: %d.\n", error); FT_Done_Face (face); return FALSE; } error = FT_Set_Pixel_Sizes (face, 0, (int) (height * 0.5)); if (error) { g_warning ("FT_Set_Pixel_Sizes, error: %d.\n", error); FT_Done_Face (face); return FALSE; } gid = FT_Get_Char_Index (face, character); advance = 0; if (gid != 0) { FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE); advance = face->glyph->metrics.horiAdvance; advance *= units; } else { FT_Done_Face (face); return FALSE; } static const cairo_user_data_key_t key; cairo_save (context); cairo_font_face_t* cairo_face = cairo_ft_font_face_create_for_ft_face (face, 0); if (cairo_face == NULL) { g_warning("cairo font face is null"); FT_Done_Face (face); return FALSE; } int status = cairo_font_face_set_user_data (cairo_face, &key, face, (cairo_destroy_func_t) FT_Done_Face); if (status != CAIRO_STATUS_SUCCESS) { cairo_font_face_destroy (cairo_face); FT_Done_Face (face); return FALSE; } cairo_set_font_face (context, cairo_face); cairo_set_font_size (context, height * 0.5); gdouble x = (width - advance) / 2; if (x < 0) { x = 0; } cairo_move_to (context, x, height - 30); cairo_show_text (context, text); cairo_font_face_destroy (cairo_face); cairo_restore (context); // cairo closes the font face and the library must be kept open return TRUE; }