ftc_size_node_flush( FTC_SizeNode node, FTC_SizeQuery query ) { FT_Size size = node->size; FT_Error error; if ( size->face == query->face ) { FT_Activate_Size( size ); error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); if ( error ) { FT_Done_Size( size ); node->size = NULL; } } else { FT_Done_Size( size ); node->size = NULL; error = ftc_size_node_init( node, query ); } return error; }
ftc_face_node_init( FTC_MruNode ftcnode, FT_Pointer ftcface_id, FT_Pointer ftcmanager ) { FTC_FaceNode node = (FTC_FaceNode)ftcnode; FTC_FaceID face_id = (FTC_FaceID)ftcface_id; FTC_Manager manager = (FTC_Manager)ftcmanager; FT_Error error; node->face_id = face_id; error = manager->request_face( face_id, manager->library, manager->request_data, &node->face ); if ( !error ) { /* destroy initial size object; it will be re-created later */ if ( node->face->size ) FT_Done_Size( node->face->size ); } return error; }
static FT_Error ftc_scaler_lookup_size( FTC_Manager manager, FTC_Scaler scaler, FT_Size *asize ) { FT_Face face; FT_Size size = NULL; FT_Error error; error = FTC_Manager_LookupFace( manager, scaler->face_id, &face ); if ( error ) goto Exit; error = FT_New_Size( face, &size ); if ( error ) goto Exit; FT_Activate_Size( size ); if ( scaler->pixel ) error = FT_Set_Pixel_Sizes( face, scaler->width, scaler->height ); else error = FT_Set_Char_Size( face, scaler->width, scaler->height, scaler->x_res, scaler->y_res ); if ( error ) { FT_Done_Size( size ); size = NULL; } Exit: *asize = size; return error; }
ftc_size_node_done( FTC_SizeNode node ) { if ( node->size ) { FT_Done_Size( node->size ); node->size = NULL; } }
Font::~Font() { if(m_size) { FT_Done_Size(m_size); } delete m_textures; }
ftc_size_node_done( FTC_MruNode ftcnode, FT_Pointer data ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FT_Size size = node->size; FT_UNUSED( data ); if ( size ) FT_Done_Size( size ); }
/* * Class: sage_FreetypeFont * Method: closeFontFace0 * Signature: (J)Z */ JNIEXPORT jboolean JNICALL Java_sage_FreetypeFont_closeFontFace0 (JNIEnv *env, jobject jo, jlong fontPtr) { FTDataStruct* fontData = (FTDataStruct*)(intptr_t) fontPtr; // NOTE: WE CAN ONLY CLOSE THE SIZE SINCE OTHERS MIGHT STILL BE USING THE FACE!!!! // THIS LEAKS MEMORY IF YOU THINK IT'LL CLOSE THE FONT FACE!!!!! // THIS LEAKS MEMORY IF YOU THINK IT'LL CLOSE THE FONT FACE!!!!! //FT_Face face = (FT_Face) facePtr; jboolean rv = FT_Done_Size(fontData->sizePtr) == 0;//FT_Done_Face(face) == 0; free(fontData); return rv; }
xd::font::~font() { // free all textures for (auto i = m_glyph_map.begin(); i != m_glyph_map.end(); ++i) { glDeleteTextures(1, &i->second->texture_id); } // free font sizes for (auto i = m_face->sizes.begin(); i != m_face->sizes.end(); ++i) { FT_Done_Size(i->second); } // free the font handle FT_Done_Face(m_face->handle); }
T42_Size_Done( T42_Size size ) { FT_Face face = size->root.face; T42_Face t42face = (T42_Face)face; FT_ListNode node; node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); if ( node ) { FT_Done_Size( size->ttsize ); size->ttsize = NULL; } }
SkScalerContext_FreeType::~SkScalerContext_FreeType() { if (fFTSize != NULL) { FT_Done_Size(fFTSize); } SkAutoMutexAcquire ac(gFTMutex); if (fFace != NULL) { unref_ft_face(fFace); } if (--gFTCount == 0) { // SkDEBUGF(("FT_Done_FreeType\n")); FT_Done_FreeType(gFTLibrary); SkDEBUGCODE(gFTLibrary = NULL;) }
ftc_size_node_reset( FTC_MruNode ftcnode, FT_Pointer ftcscaler, FT_Pointer ftcmanager ) { FTC_SizeNode node = (FTC_SizeNode)ftcnode; FTC_Scaler scaler = (FTC_Scaler)ftcscaler; FTC_Manager manager = (FTC_Manager)ftcmanager; FT_Done_Size( node->size ); node->scaler = scaler[0]; return ftc_scaler_lookup_size( manager, scaler, &node->size ); }
T42_Size_Done( FT_Size t42size ) /* T42_Size */ { T42_Size size = (T42_Size)t42size; FT_Face face = t42size->face; T42_Face t42face = (T42_Face)face; FT_ListNode node; node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize ); if ( node ) { FT_Done_Size( size->ttsize ); size->ttsize = NULL; } }
ftc_size_node_init( FTC_SizeNode node, FTC_SizeQuery query ) { FT_Face face = query->face; FT_Size size; FT_Error error; node->size = NULL; error = FT_New_Size( face, &size ); if ( !error ) { FT_Activate_Size( size ); error = FT_Set_Pixel_Sizes( query->face, query->width, query->height ); if ( error ) FT_Done_Size( size ); else node->size = size; } return error; }
T42_Face_Init( FT_Stream stream, T42_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params) { FT_Error error; PSNames_Service psnames; PSAux_Service psaux; FT_Face root = (FT_Face)&face->root; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); FT_UNUSED( stream ); face->ttf_face = NULL; face->root.num_faces = 1; face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psnames" ); psnames = (PSNames_Service)face->psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); psaux = (PSAux_Service)face->psaux; /* open the tokenizer, this will also check the font format */ error = T42_Open_Face( face ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index != 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = T42_Err_Invalid_Argument; goto Exit; } /* Now, load the font program into the face object */ /* Init the face object fields */ /* Now set up root face fields */ root->num_glyphs = face->type1.num_glyphs; root->num_charmaps = 0; root->face_index = face_index; root->face_flags = FT_FACE_FLAG_SCALABLE; root->face_flags |= FT_FACE_FLAG_HORIZONTAL; root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; if ( face->type1.font_info.is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: TODO -- add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = face->type1.font_info.family_name; if ( root->family_name ) { char* full = face->type1.font_info.full_name; char* family = root->family_name; if ( full ) { while ( *family && *full == *family ) { family++; full++; } root->style_name = ( *full == ' ' ? full + 1 : (char *)"Regular" ); } else root->style_name = (char *)"Regular"; } else { /* do we have a `/FontName'? */ if ( face->type1.font_name ) { root->family_name = face->type1.font_name; root->style_name = (char *)"Regular"; } } /* no embedded bitmap support */ root->num_fixed_sizes = 0; root->available_sizes = 0; /* Load the TTF font embedded in the T42 font */ error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ), face->ttf_data, face->ttf_size, 0, &face->ttf_face ); if ( error ) goto Exit; FT_Done_Size( face->ttf_face->size ); /* Ignore info in FontInfo dictionary and use the info from the */ /* loaded TTF font. The PostScript interpreter also ignores it. */ root->bbox = face->ttf_face->bbox; root->units_per_EM = face->ttf_face->units_per_EM; root->ascender = face->ttf_face->ascender; root->descender = face->ttf_face->descender; root->height = face->ttf_face->height; root->max_advance_width = face->ttf_face->max_advance_width; root->max_advance_height = face->ttf_face->max_advance_height; root->underline_position = face->type1.font_info.underline_position; root->underline_thickness = face->type1.font_info.underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; /* compute style flags */ root->style_flags = 0; if ( face->type1.font_info.italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) root->style_flags |= FT_STYLE_FLAG_BOLD; if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) root->face_flags |= FT_FACE_FLAG_VERTICAL; #ifdef FT_CONFIG_OPTION_USE_CMAPS { if ( psnames && psaux ) { FT_CharMapRec charmap; T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; FT_CMap_Class clazz; charmap.face = root; /* first of all, try to synthetize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = ft_encoding_unicode; FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); /* now, generate an Adobe Standard encoding when appropriate */ charmap.platform_id = 7; clazz = NULL; switch ( face->type1.encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = ft_encoding_adobe_standard; charmap.encoding_id = 0; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = ft_encoding_adobe_expert; charmap.encoding_id = 1; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = ft_encoding_adobe_custom; charmap.encoding_id = 2; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = ft_encoding_latin_1; charmap.encoding_id = 3; clazz = cmap_classes->unicode; break; default: ; } if ( clazz ) FT_CMap_New( clazz, NULL, &charmap, NULL ); /* Select default charmap */ if (root->num_charmaps) root->charmap = root->charmaps[0]; } } #else /* !FT_CONFIG_OPTION_USE_CMAPS */ /* charmap support -- synthetize unicode charmap if possible */ { FT_CharMap charmap = face->charmaprecs; /* synthesize a Unicode charmap if there is support in the `PSNames' */ /* module */ if ( psnames && psnames->unicode_value ) { error = psnames->build_unicodes( root->memory, face->type1.num_glyphs, (const char**)face->type1.glyph_names, &face->unicode_map ); if ( !error ) { root->charmap = charmap; charmap->face = (FT_Face)face; charmap->encoding = ft_encoding_unicode; charmap->platform_id = 3; charmap->encoding_id = 1; charmap++; } /* XXX: Is the following code correct? It is used in t1objs.c */ /* simply clear the error in case of failure (which really) */ /* means that out of memory or no unicode glyph names */ error = T42_Err_Ok; } /* now, support either the standard, expert, or custom encoding */ charmap->face = (FT_Face)face; charmap->platform_id = 7; /* a new platform id for Adobe fonts? */ switch ( face->type1.encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap->encoding = ft_encoding_adobe_standard; charmap->encoding_id = 0; break; case T1_ENCODING_TYPE_EXPERT: charmap->encoding = ft_encoding_adobe_expert; charmap->encoding_id = 1; break; case T1_ENCODING_TYPE_ARRAY: charmap->encoding = ft_encoding_adobe_custom; charmap->encoding_id = 2; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap->encoding = ft_encoding_latin_1; charmap->encoding_id = 3; break; default: FT_ERROR(( "T42_Face_Init: invalid encoding\n" )); error = T42_Err_Invalid_File_Format; goto Exit; } root->charmaps = face->charmaps; root->num_charmaps = charmap - face->charmaprecs + 1; face->charmaps[0] = &face->charmaprecs[0]; face->charmaps[1] = &face->charmaprecs[1]; } #endif /* !FT_CONFIG_OPTION_USE_CMAPS */ Exit: return error; }
T42_Face_Init( FT_Stream stream, T42_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; FT_Service_PsCMaps psnames; PSAux_Service psaux; FT_Face root = (FT_Face)&face->root; T1_Font type1 = &face->type1; PS_FontInfo info = &type1->font_info; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); FT_UNUSED( stream ); face->ttf_face = NULL; face->root.num_faces = 1; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); face->psnames = psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); psaux = (PSAux_Service)face->psaux; /* open the tokenizer, this will also check the font format */ error = T42_Open_Face( face ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = T42_Err_Invalid_Argument; goto Exit; } /* Now load the font program into the face object */ /* Init the face object fields */ /* Now set up root face fields */ root->num_glyphs = type1->num_glyphs; root->num_charmaps = 0; root->face_index = 0; root->face_flags = FT_FACE_FLAG_SCALABLE | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_GLYPH_NAMES; if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* We only set this flag if we have the patented bytecode interpreter. */ /* There are no known `tricky' Type42 fonts that could be loaded with */ /* the unpatented interpreter. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER root->face_flags |= FT_FACE_FLAG_HINTER; #endif /* XXX: TODO -- add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = info->family_name; /* assume "Regular" style if we don't know better */ root->style_name = (char *)"Regular"; if ( root->family_name ) { char* full = info->full_name; char* family = root->family_name; if ( full ) { while ( *full ) { if ( *full == *family ) { family++; full++; } else { if ( *full == ' ' || *full == '-' ) full++; else if ( *family == ' ' || *family == '-' ) family++; else { if ( !*family ) root->style_name = full; break; } } } } } else { /* do we have a `/FontName'? */ if ( type1->font_name ) root->family_name = type1->font_name; } /* no embedded bitmap support */ root->num_fixed_sizes = 0; root->available_sizes = 0; /* Load the TTF font embedded in the T42 font */ { FT_Open_Args args; args.flags = FT_OPEN_MEMORY; args.memory_base = face->ttf_data; args.memory_size = face->ttf_size; if ( num_params ) { args.flags |= FT_OPEN_PARAMS; args.num_params = num_params; args.params = params; } error = FT_Open_Face( FT_FACE_LIBRARY( face ), &args, 0, &face->ttf_face ); } if ( error ) goto Exit; FT_Done_Size( face->ttf_face->size ); /* Ignore info in FontInfo dictionary and use the info from the */ /* loaded TTF font. The PostScript interpreter also ignores it. */ root->bbox = face->ttf_face->bbox; root->units_per_EM = face->ttf_face->units_per_EM; root->ascender = face->ttf_face->ascender; root->descender = face->ttf_face->descender; root->height = face->ttf_face->height; root->max_advance_width = face->ttf_face->max_advance_width; root->max_advance_height = face->ttf_face->max_advance_height; root->underline_position = (FT_Short)info->underline_position; root->underline_thickness = (FT_Short)info->underline_thickness; /* compute style flags */ root->style_flags = 0; if ( info->italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) root->style_flags |= FT_STYLE_FLAG_BOLD; if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) root->face_flags |= FT_FACE_FLAG_VERTICAL; { if ( psnames && psaux ) { FT_CharMapRec charmap; T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; FT_CMap_Class clazz; charmap.face = root; /* first of all, try to synthesize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); /* now, generate an Adobe Standard encoding when appropriate */ charmap.platform_id = 7; clazz = NULL; switch ( type1->encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.encoding_id = 0; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; charmap.encoding_id = 1; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; charmap.encoding_id = 2; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; charmap.encoding_id = 3; clazz = cmap_classes->unicode; break; default: ; } if ( clazz ) FT_CMap_New( clazz, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if ( root->num_charmaps ) root->charmap = root->charmaps[0]; #endif } } Exit: return error; }
void xd::font::render(const std::string& text, const font_style& style, xd::shader_program::handle shader, const glm::mat4& mvp, glm::vec2 *pos) { // check if we're rendering using this font or a linked font if (style.m_type && style.m_type->length() != 0) { font_map_t::iterator i = m_linked_fonts.find(*style.m_type); if (i == m_linked_fonts.end()) throw invalid_font_type(*style.m_type); font_style linked_style = style; linked_style.m_type = boost::none; i->second->render(text, linked_style, shader, mvp, pos); return; } // check if the font size is already loaded auto it = m_face->sizes.find(style.m_size); if (it == m_face->sizes.end()) { // create a new size FT_Size size; if (FT_New_Size(m_face->handle, &size) != 0) throw font_load_failed(m_filename); // free the size in catch block if something goes wrong try { if (FT_Activate_Size(size) != 0) throw font_load_failed(m_filename); // set the pixel size if (FT_Set_Pixel_Sizes(m_face->handle, 0, style.m_size) != 0) throw font_load_failed(m_filename); // pre-load 7-bit ASCII glyphs for (int i = 0; i < 128; i++) { load_glyph(i, style.m_size); } } catch (...) { // free the size and re-throw FT_Done_Size(size); throw; } // insert the newly loaded size in the map m_face->sizes.insert(std::make_pair(style.m_size, size)); } else { // activate the size FT_Activate_Size(it->second); } // bind to first texture unit glActiveTexture(GL_TEXTURE0); // setup the shader shader->use(); shader->bind_uniform(m_mvp_uniform, mvp); shader->bind_uniform(m_color_uniform, style.m_color); shader->bind_uniform(m_texture_uniform, 0); // is kerning supported FT_Bool kerning = FT_HAS_KERNING(m_face->handle); // render each glyph in the string glm::vec2 text_pos; if (pos) text_pos = *pos; FT_UInt prev_glyph_index = 0; auto i = text.begin(); while (i != text.end()) { // get the unicode code point utf8::uint32_t char_index = utf8::next(i, text.end()); // get the cached glyph, or cache if it is not yet cached const detail::font::glyph& glyph = load_glyph(char_index, style.m_size); // bind the texture glBindTexture(GL_TEXTURE_2D, glyph.texture_id); // check for kerning if (kerning && glyph.glyph_index && prev_glyph_index) { FT_Vector kerning_delta; FT_Get_Kerning(m_face->handle, prev_glyph_index, glyph.glyph_index, FT_KERNING_DEFAULT, &kerning_delta); text_pos.x += kerning_delta.x >> 6; } // calculate exact offset glm::vec2 glyph_pos = text_pos; glyph_pos.x += glyph.offset.x; glyph_pos.y += glyph.offset.y; // add optional letter spacing glyph_pos.x += style.m_letter_spacing/2; // if shadow is enabled, draw the shadow first if (style.m_shadow) { // calculate shadow position glm::vec2 shadow_pos = glyph_pos; shadow_pos.x += style.m_shadow->x; shadow_pos.y += style.m_shadow->y; // calculate shadow color glm::vec4 shadow_color = style.m_shadow->color; shadow_color.a *= style.m_color.a; // bind uniforms shader->bind_uniform(m_color_uniform, shadow_color); shader->bind_uniform(m_position_uniform, shadow_pos); // draw shadow glyph.quad_ptr->render(); // restore the text color shader->bind_uniform(m_color_uniform, style.m_color); } // if outline is enabled, draw outline if (style.m_outline) { // calculate outline color glm::vec4 outline_color = style.m_outline->color; outline_color.a *= style.m_color.a; // bind color shader->bind_uniform(m_color_uniform, outline_color); // draw font multiple times times to draw outline (EXPENSIVE!) for (int x = -style.m_outline->width; x <= style.m_outline->width; x++) { for (int y = -style.m_outline->width; y <= style.m_outline->width; y++) { if (x == 0 && y == 0) continue; shader->bind_uniform(m_position_uniform, glyph_pos + glm::vec2(x, y)); glyph.quad_ptr->render(); } } // restore the text color shader->bind_uniform(m_color_uniform, style.m_color); } // bind uniforms shader->bind_uniform(m_position_uniform, glyph_pos); // draw the glyph glyph.quad_ptr->render(); // advance the position text_pos += glyph.advance; text_pos.x += style.m_letter_spacing; // keep track of previous glyph to do kerning prev_glyph_index = glyph.glyph_index; }
T42_Face_Init( FT_Stream stream, T42_Face face, FT_Int face_index, FT_Int num_params, FT_Parameter* params ) { FT_Error error; PSNames_Service psnames; PSAux_Service psaux; FT_Face root = (FT_Face)&face->root; FT_UNUSED( num_params ); FT_UNUSED( params ); FT_UNUSED( face_index ); FT_UNUSED( stream ); face->ttf_face = NULL; face->root.num_faces = 1; face->psnames = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psnames" ); psnames = (PSNames_Service)face->psnames; face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "psaux" ); psaux = (PSAux_Service)face->psaux; /* open the tokenizer, this will also check the font format */ error = T42_Open_Face( face ); if ( error ) goto Exit; /* if we just wanted to check the format, leave successfully now */ if ( face_index < 0 ) goto Exit; /* check the face index */ if ( face_index != 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = T42_Err_Invalid_Argument; goto Exit; } /* Now, load the font program into the face object */ /* Init the face object fields */ /* Now set up root face fields */ root->num_glyphs = face->type1.num_glyphs; root->num_charmaps = 0; root->face_index = face_index; root->face_flags = FT_FACE_FLAG_SCALABLE; root->face_flags |= FT_FACE_FLAG_HORIZONTAL; root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES; if ( face->type1.font_info.is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; /* XXX: TODO -- add kerning with .afm support */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ root->family_name = face->type1.font_info.family_name; if ( root->family_name ) { char* full = face->type1.font_info.full_name; char* family = root->family_name; if ( full ) { while ( *family && *full == *family ) { family++; full++; } root->style_name = ( *full == ' ' ? full + 1 : (char *)"Regular" ); } else root->style_name = (char *)"Regular"; } else { /* do we have a `/FontName'? */ if ( face->type1.font_name ) { root->family_name = face->type1.font_name; root->style_name = (char *)"Regular"; } } /* no embedded bitmap support */ root->num_fixed_sizes = 0; root->available_sizes = 0; /* Load the TTF font embedded in the T42 font */ error = FT_New_Memory_Face( FT_FACE_LIBRARY( face ), face->ttf_data, face->ttf_size, 0, &face->ttf_face ); if ( error ) goto Exit; FT_Done_Size( face->ttf_face->size ); /* Ignore info in FontInfo dictionary and use the info from the */ /* loaded TTF font. The PostScript interpreter also ignores it. */ root->bbox = face->ttf_face->bbox; root->units_per_EM = face->ttf_face->units_per_EM; root->ascender = face->ttf_face->ascender; root->descender = face->ttf_face->descender; root->height = face->ttf_face->height; root->max_advance_width = face->ttf_face->max_advance_width; root->max_advance_height = face->ttf_face->max_advance_height; root->underline_position = face->type1.font_info.underline_position; root->underline_thickness = face->type1.font_info.underline_thickness; root->internal->max_points = 0; root->internal->max_contours = 0; /* compute style flags */ root->style_flags = 0; if ( face->type1.font_info.italic_angle ) root->style_flags |= FT_STYLE_FLAG_ITALIC; if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD ) root->style_flags |= FT_STYLE_FLAG_BOLD; if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL ) root->face_flags |= FT_FACE_FLAG_VERTICAL; { if ( psnames && psaux ) { FT_CharMapRec charmap; T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes; FT_CMap_Class clazz; charmap.face = root; /* first of all, try to synthetize a Unicode charmap */ charmap.platform_id = 3; charmap.encoding_id = 1; charmap.encoding = FT_ENCODING_UNICODE; FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL ); /* now, generate an Adobe Standard encoding when appropriate */ charmap.platform_id = 7; clazz = NULL; switch ( face->type1.encoding_type ) { case T1_ENCODING_TYPE_STANDARD: charmap.encoding = FT_ENCODING_ADOBE_STANDARD; charmap.encoding_id = 0; clazz = cmap_classes->standard; break; case T1_ENCODING_TYPE_EXPERT: charmap.encoding = FT_ENCODING_ADOBE_EXPERT; charmap.encoding_id = 1; clazz = cmap_classes->expert; break; case T1_ENCODING_TYPE_ARRAY: charmap.encoding = FT_ENCODING_ADOBE_CUSTOM; charmap.encoding_id = 2; clazz = cmap_classes->custom; break; case T1_ENCODING_TYPE_ISOLATIN1: charmap.encoding = FT_ENCODING_ADOBE_LATIN_1; charmap.encoding_id = 3; clazz = cmap_classes->unicode; break; default: ; } if ( clazz ) FT_CMap_New( clazz, NULL, &charmap, NULL ); #if 0 /* Select default charmap */ if (root->num_charmaps) root->charmap = root->charmaps[0]; #endif } } Exit: return error; }
static Font_Info * _font_slave_int_load(const Slave_Msg_Font_Load *msg, Font_Source_Info *fsi) { int error; int val, dv; int ret; Font_Info *fi = calloc(1, sizeof(*fi)); error = FT_New_Size(fsi->face, &(fi->size)); if (!error) FT_Activate_Size(fi->size); fi->fsize = msg->size; fi->dpi = msg->dpi; fi->real_size = msg->size * 64; fi->fsi = fsi; error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi); if (error) error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size); if (error) { int i, maxd = 0x7fffffff; int chosen_size = 0; int chosen_size2 = 0; for (i = 0; i < fsi->face->num_fixed_sizes; i++) { int s, cd; s = fsi->face->available_sizes[i].size; cd = chosen_size - fi->real_size; if (cd < 0) cd = -cd; if (cd < maxd) { maxd = cd; chosen_size = s; chosen_size2 = fsi->face->available_sizes[i].y_ppem; if (maxd == 0) break; } } fi->real_size = chosen_size; error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size); if (error) { error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi); if (error) { /* hack around broken fonts */ fi->real_size = (chosen_size2 / 64) * 60; error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi); if (error) { ERR("Could not choose the font size for font: '%s:%s'.", msg->file, msg->name); FT_Done_Size(fi->size); free(fi); return NULL; } } } } fi->max_h = 0; val = (int)fsi->face->bbox.yMax; if (fsi->face->units_per_EM != 0) { dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM; ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv); } else ret = val; fi->max_h += ret; val = -(int)fsi->face->bbox.yMin; if (fsi->face->units_per_EM != 0) { dv = (fsi->orig_upem * 2048) / fsi->face->units_per_EM; ret = (val * fsi->face->size->metrics.y_scale) / (dv * dv); } else ret = val; fi->max_h += ret; fi->runtime_rend = FONT_REND_REGULAR; if ((msg->rend_flags & FONT_REND_SLANT) && !(fsi->face->style_flags & FT_STYLE_FLAG_ITALIC)) fi->runtime_rend |= FONT_REND_SLANT; if ((msg->rend_flags & FONT_REND_WEIGHT) && !(fsi->face->style_flags & FT_STYLE_FLAG_BOLD)) fi->runtime_rend |= FONT_REND_WEIGHT; return fi; }