void ass_face_set_size(FT_Face face, double size) { TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); double mscale = 1.; FT_Size_RequestRec rq; FT_Size_Metrics *m = &face->size->metrics; // VSFilter uses metrics from TrueType OS/2 table // The idea was borrowed from asa (http://asa.diac24.net) if (os2) { int ft_height = 0; if (hori) ft_height = hori->Ascender - hori->Descender; if (!ft_height) ft_height = os2->sTypoAscender - os2->sTypoDescender; /* sometimes used for signed values despite unsigned in spec */ int os2_height = (short)os2->usWinAscent + (short)os2->usWinDescent; if (ft_height && os2_height) mscale = (double) ft_height / os2_height; } memset(&rq, 0, sizeof(rq)); rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; rq.width = 0; rq.height = double_to_d6(size * mscale); rq.horiResolution = rq.vertResolution = 0; FT_Request_Size(face, &rq); m->ascender /= mscale; m->descender /= mscale; m->height /= mscale; }
static void face_set_size(FT_Face face, double size) { #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1)) TT_HoriHeader *hori = FT_Get_Sfnt_Table(face, ft_sfnt_hhea); TT_OS2 *os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); double mscale = 1.; FT_Size_RequestRec rq; FT_Size_Metrics *m = &face->size->metrics; // VSFilter uses metrics from TrueType OS/2 table // The idea was borrowed from asa (http://asa.diac24.net) if (hori && os2) { int hori_height = hori->Ascender - hori->Descender; int os2_height = os2->usWinAscent + os2->usWinDescent; if (hori_height && os2_height) mscale = (double)hori_height / os2_height; } memset(&rq, 0, sizeof(rq)); rq.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; rq.width = 0; rq.height = double_to_d6(size * mscale); rq.horiResolution = rq.vertResolution = 0; FT_Request_Size(face, &rq); m->ascender /= mscale; m->descender /= mscale; m->height /= mscale; #else FT_Set_Char_Size(face, 0, double_to_d6(size), 0, 0); #endif }
float FontInstance::GetHeight(void) { ScopedLock Sl(Lock); FT_Size_Request Size; FT_Request_Size(Face,Size); return (float)Size->height/64.0f; };
T42_Size_Request( T42_Size size, FT_Size_Request req ) { T42_Face face = (T42_Face)size->root.face; FT_Error error; FT_Activate_Size( size->ttsize ); error = FT_Request_Size( face->ttf_face, req ); if ( !error ) ( (FT_Size)size )->metrics = face->ttf_face->size->metrics; return error; }
T42_Size_Request( FT_Size t42size, /* T42_Size */ FT_Size_Request req ) { T42_Size size = (T42_Size)t42size; T42_Face face = (T42_Face)t42size->face; FT_Error error; FT_Activate_Size( size->ttsize ); error = FT_Request_Size( face->ttf_face, req ); if ( !error ) t42size->metrics = face->ttf_face->size->metrics; return error; }
s16 fsLowLevelAPI::drawFreeTypeFont(void* image, u16 image_width, u16 image_height, // void* font_info, u32 font_index, u16 font_size, s16 x, s16 y, const wchar_t* str) { FT_Face face = *(reinterpret_cast<FT_Face*>(static_cast<u32*>(font_info) + 1) + font_index); FT_Size_RequestRec size_req; size_req.type = FT_SIZE_REQUEST_TYPE_CELL; size_req.width = 0; size_req.height = font_size << 6; size_req.horiResolution = 0; size_req.vertResolution = 0; if (FT_Request_Size(face, &size_req)) { return -1; } if (image) { s32 pen_x = x; s32 pen_y = y + static_cast<s32>(face->ascender * face->size->metrics.y_ppem / face->units_per_EM); RasterInfo raster_info; raster_info.image = image; raster_info.width = image_width; FT_Raster_Params raster_params = {}; raster_params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT | FT_RASTER_FLAG_CLIP; raster_params.gray_spans = static_cast<FT_Raster_Span_Func>(rasterSpanFunc); raster_params.user = &raster_info; raster_params.clip_box.yMin = pen_y - image_height; raster_params.clip_box.yMax = pen_y; FT_GlyphSlot glyph_slot = face->glyph; for ( ; *str != L'\0'; str++) { if (FT_Load_Char(face, *str, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP)) { return -1; } if (glyph_slot->format != FT_GLYPH_FORMAT_OUTLINE) { return -1; } raster_params.clip_box.xMin = -pen_x; raster_params.clip_box.xMax = image_width - pen_x; raster_info.pen_x = pen_x; raster_info.pen_y = pen_y; if (FT_Outline_Render(s_freetype, &glyph_slot->outline, &raster_params)) { return -1; } pen_x += glyph_slot->advance.x >> 6; } return pen_x - x; } else {
unsigned int draw_freetype_font(char** image, unsigned* image_width, unsigned* image_height, void* font_info, unsigned long font_index, size_t font_size, unsigned int x, unsigned int y, const char* cstr) { size_t len = strlen(cstr) + 1; wchar_t* str = new wchar_t[len]; wmemset(str, 0, len); utf8ToWchar(str, len, cstr); if(!font_info)return -1; FT_Face face = *(reinterpret_cast<FT_Face*>(font_info) + font_index); FT_Size_RequestRec size_req; size_req.type = FT_SIZE_REQUEST_TYPE_CELL; size_req.width = 0; size_req.height = font_size << 6; size_req.horiResolution = 0; size_req.vertResolution = 0; if (FT_Request_Size(face, &size_req)) { return -1; } if (*image) { unsigned int pen_x = x; unsigned int pen_y = y + static_cast<unsigned int>(face->ascender * face->size->metrics.y_ppem / face->units_per_EM); RasterInfo raster_info; raster_info.image = *image; raster_info.width = *image_width; FT_Raster_Params raster_params = {}; raster_params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT | FT_RASTER_FLAG_CLIP; raster_params.gray_spans = static_cast<FT_Raster_Span_Func>(rasterSpanFunc); raster_params.user = &raster_info; raster_params.clip_box.yMin = pen_y - *image_height; raster_params.clip_box.yMax = pen_y; FT_GlyphSlot glyph_slot = face->glyph; for ( ; *str != L'\0'; str++) { if (FT_Load_Char(face, *str, FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP)) { return -1; } if (glyph_slot->format != FT_GLYPH_FORMAT_OUTLINE) { return -1; } raster_params.clip_box.xMin = -pen_x; raster_params.clip_box.xMax = *image_width - pen_x; raster_info.pen_x = pen_x; raster_info.pen_y = pen_y; if (FT_Outline_Render(s_freetype, &glyph_slot->outline, &raster_params)) { return -1; } pen_x += glyph_slot->advance.x >> 6; } return pen_x - x; } else {