bool FreeTypeFontInfo::EmbeddedBmpExist(int px) { if (px>=256 || px<0) return false; if (m_ebmps[px]!=-1) return !!m_ebmps[px]; CCriticalSectionLock __lock(CCriticalSectionLock::CS_MANAGER); FTC_ImageTypeRec imgtype={(FTC_FaceID)m_id, px, px, FT_LOAD_DEFAULT}; //构造一个当前大小的imagetype FT_Glyph temp_glyph=NULL; FT_UInt gindex = FTC_CMapCache_Lookup(cmap_cache, (FTC_FaceID)m_id, -1, FT_UInt32(L'0')); //获得0的索引值 FTC_ImageCache_Lookup(image_cache, &imgtype, gindex, &temp_glyph, NULL); if (temp_glyph && temp_glyph->format==FT_GLYPH_FORMAT_BITMAP) //如果可以读到0的点阵 m_ebmps[px]=1; //则该字号存在点阵 else { gindex = FTC_CMapCache_Lookup(cmap_cache, (FTC_FaceID)m_id, -1, FT_UInt32(L'的')); //获得"的"的索引值 if (gindex) FTC_ImageCache_Lookup(image_cache, &imgtype, gindex, &temp_glyph, NULL); //读取“的”的点阵 if (temp_glyph && temp_glyph->format==FT_GLYPH_FORMAT_BITMAP) //如果可以读到0的点阵 m_ebmps[px]=1; //则该字号存在点阵 else m_ebmps[px]=0; } return !!m_ebmps[px]; }
FT_Glyph fb_getglyph(const plot_font_style_t *fstyle, uint32_t ucs4) { FT_UInt glyph_index; FTC_ScalerRec srec; FT_Glyph glyph; FT_Error error; fb_faceid_t *fb_face; fb_fill_scalar(fstyle, &srec); fb_face = (fb_faceid_t *)srec.face_id; glyph_index = FTC_CMapCache_Lookup(ft_cmap_cache, srec.face_id, fb_face->cidx, ucs4); error = FTC_ImageCache_LookupScaler(ft_image_cache, &srec, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT | ft_load_type, glyph_index, &glyph, NULL); if (error != 0) return NULL; return glyph; }
int test_cmap_cache( btimer_t* timer, FT_Face face, void* user_data ) { bcharset_t* charset = (bcharset_t*)user_data; int i, done = 0; FT_UNUSED( face ); if ( !cmap_cache ) { if ( FTC_CMapCache_New(cache_man, &cmap_cache) ) return 0; } TIMER_START( timer ); for ( i = 0; i < charset->size; i++ ) { if ( FTC_CMapCache_Lookup( cmap_cache, font_type.face_id, 0, charset->code[i] ) ) done++; } TIMER_STOP( timer ); return done; }
FT_UInt FTDemo_Get_Index( FTDemo_Handle* handle, FT_UInt32 charcode ) { FTC_FaceID face_id = handle->scaler.face_id; PFont font = handle->current_font; return FTC_CMapCache_Lookup( handle->cmap_cache, face_id, font->cmap_index, charcode ); }
std::vector<Handler<BitmapGlyph> > FreeType::lookupBitmap(Font& font, float size, std::vector<unsigned int> const& ucs4, float& ascent, float& descent, float& height) { Font::RawFaceSession rfs(font); FT_Face face = rfs.face(); FT_Face face__; FTC_ScalerRec scaler; { scaler.face_id = face; scaler.width = 0; scaler.height = FLOAT_TO_26_6( size ); scaler.pixel = 0; scaler.x_res=72; //XXX scaler.y_res=72; //XXX } FTC_Manager_LookupFace(this->cache_, face, &face__); { FT_Size size; FTC_Manager_LookupSize(this->cache_, &scaler, &size); ascent = FLOAT_FROM_26_6(size->metrics.ascender); descent = FLOAT_FROM_26_6(size->metrics.descender); height = FLOAT_FROM_26_6(size->metrics.height); } std::vector<Handler<BitmapGlyph> > ret; ret.reserve(ucs4.size()); for(unsigned int const& u : ucs4) { unsigned int const gindex = FTC_CMapCache_Lookup(this->cmap_, face, font.unicodeCharmapIndex(), u); FT_Glyph glyph; { FT_Glyph glyph_orig; FTC_ImageCache_LookupScaler(this->image_, &scaler, 0, gindex, &glyph_orig, nullptr); FT_Glyph_Copy(glyph_orig, &glyph); } if(glyph->format != FT_GLYPH_FORMAT_BITMAP ) { FT_Vector_ vec; vec.x = 0; vec.y = 0; FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, &vec, 1); } ret.push_back( Handler<BitmapGlyph>(new BitmapGlyph(reinterpret_cast<FT_BitmapGlyph>(glyph))) ); } return ret; }
unsigned int FreeType::lookupGlyphIndex(Font& font, unsigned int ucs4) { Font::RawFaceSession rfs(font); FT_Face face = rfs.face(); return FTC_CMapCache_Lookup(this->cmap_, face, font.unicodeCharmapIndex(), ucs4); }
void vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text) { FTC_FaceID face_id = (FTC_FaceID)font; FT_Face face; FTC_Manager_LookupFace(font->ftcmanager, face_id, &face); FT_Int charmap_index; charmap_index = FT_Get_Charmap_Index(face->charmap); FT_Glyph glyph; FT_Bool use_kerning = FT_HAS_KERNING(face); FT_UInt glyph_index, previous = 0; int pen_x = x; int pen_y = y + size; FTC_ScalerRec scaler; scaler.face_id = face_id; scaler.width = size; scaler.height = size; scaler.pixel = 1; FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; while (*text) { glyph_index = FTC_CMapCache_Lookup(font->cmapcache, (FTC_FaceID)font, charmap_index, *text); if (use_kerning && previous && glyph_index) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); pen_x += delta.x >> 6; } if (!texture_atlas_exists(font->tex_atlas, glyph_index)) { FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL); if (!atlas_add_glyph(font->tex_atlas, glyph_index, (FT_BitmapGlyph)glyph, size)) { continue; } } bp2d_rectangle rect; int bitmap_left, bitmap_top; int advance_x, advance_y; int glyph_size; texture_atlas_get(font->tex_atlas, glyph_index, &rect, &bitmap_left, &bitmap_top, &advance_x, &advance_y, &glyph_size); const float draw_scale = size/(float)glyph_size; vita2d_draw_texture_tint_part_scale(font->tex_atlas->tex, pen_x + bitmap_left * draw_scale, pen_y - bitmap_top * draw_scale, rect.x, rect.y, rect.w, rect.h, draw_scale, draw_scale, color); pen_x += (advance_x >> 16) * draw_scale; pen_y += (advance_y >> 16) * draw_scale; previous = glyph_index; text++; }
int _PGFT_LoadGlyph(FontGlyph *glyph, PGFT_char character, const FontRenderMode *mode, void *internal) { static FT_Vector delta = {0, 0}; FT_Render_Mode rmode = (mode->render_flags & FT_RFLAG_ANTIALIAS ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); FT_Vector strong_delta = {0, 0}; FT_Glyph image = 0; FT_Glyph_Metrics *ft_metrics; TextContext *context = (TextContext *)internal; FT_UInt32 load_flags; FT_UInt gindex; FT_Fixed rotation_angle = mode->rotation_angle; /* FT_Matrix transform; */ FT_Vector h_bearing_rotated; FT_Vector v_bearing_rotated; FT_Vector h_advance_rotated; FT_Vector v_advance_rotated; FT_Error error = 0; /* * Calculate the corresponding glyph index for the char */ gindex = FTC_CMapCache_Lookup(context->charmap, context->id, -1, (FT_UInt32)character); glyph->glyph_index = gindex; /* * Get loading information */ load_flags = get_load_flags(mode); /* * Load the glyph into the glyph slot */ if (FT_Load_Glyph(context->font, glyph->glyph_index, (FT_Int)load_flags) || FT_Get_Glyph(context->font->glyph, &image)) goto cleanup; /* * Perform any outline transformations */ if (mode->style & FT_STYLE_STRONG) { FT_UShort x_ppem = context->font->size->metrics.x_ppem; FT_Fixed bold_str; FT_BBox before; FT_BBox after; bold_str = FX16_CEIL_TO_FX6(mode->strength * x_ppem); FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &before); if (FT_Outline_Embolden(&((FT_OutlineGlyph)image)->outline, bold_str)) goto cleanup; FT_Outline_Get_CBox(&((FT_OutlineGlyph)image)->outline, &after); strong_delta.x += ((after.xMax - after.xMin) - (before.xMax - before.xMin)); strong_delta.y += ((after.yMax - after.yMin) - (before.yMax - before.yMin)); } if (context->do_transform) { if (FT_Glyph_Transform(image, &context->transform, &delta)) { goto cleanup; } } /* * Finished with outline transformations, now replace with a bitmap */ error = FT_Glyph_To_Bitmap(&image, rmode, 0, 1); if (error) { goto cleanup; } if (mode->style & FT_STYLE_WIDE) { FT_Bitmap *bitmap = &((FT_BitmapGlyph)image)->bitmap; int w = bitmap->width; FT_UShort x_ppem = context->font->size->metrics.x_ppem; FT_Pos x_strength; x_strength = FX16_CEIL_TO_FX6(mode->strength * x_ppem); /* FT_Bitmap_Embolden returns an error for a zero width bitmap */ if (w > 0) { error = FT_Bitmap_Embolden(context->lib, bitmap, x_strength, (FT_Pos)0); if (error) { goto cleanup; } strong_delta.x += INT_TO_FX6(bitmap->width - w); } else { strong_delta.x += x_strength; } } /* Fill the glyph */ ft_metrics = &context->font->glyph->metrics; h_advance_rotated.x = ft_metrics->horiAdvance + strong_delta.x; h_advance_rotated.y = 0; v_advance_rotated.x = 0; v_advance_rotated.y = ft_metrics->vertAdvance + strong_delta.y; if (rotation_angle != 0) { FT_Angle counter_rotation = INT_TO_FX6(360) - rotation_angle; FT_Vector_Rotate(&h_advance_rotated, rotation_angle); FT_Vector_Rotate(&v_advance_rotated, counter_rotation); } glyph->image = (FT_BitmapGlyph)image; glyph->width = INT_TO_FX6(glyph->image->bitmap.width); glyph->height = INT_TO_FX6(glyph->image->bitmap.rows); h_bearing_rotated.x = INT_TO_FX6(glyph->image->left); h_bearing_rotated.y = INT_TO_FX6(glyph->image->top); fill_metrics(&glyph->h_metrics, ft_metrics->horiBearingX, ft_metrics->horiBearingY, &h_bearing_rotated, &h_advance_rotated); if (rotation_angle == 0) { v_bearing_rotated.x = ft_metrics->vertBearingX - strong_delta.x / 2; v_bearing_rotated.y = ft_metrics->vertBearingY; } else { /* * Adjust the vertical metrics. */ FT_Vector v_origin; v_origin.x = (glyph->h_metrics.bearing_x - ft_metrics->vertBearingX + strong_delta.x / 2); v_origin.y = (glyph->h_metrics.bearing_y + ft_metrics->vertBearingY); FT_Vector_Rotate(&v_origin, rotation_angle); v_bearing_rotated.x = glyph->h_metrics.bearing_rotated.x - v_origin.x; v_bearing_rotated.y = v_origin.y - glyph->h_metrics.bearing_rotated.y; } fill_metrics(&glyph->v_metrics, ft_metrics->vertBearingX, ft_metrics->vertBearingY, &v_bearing_rotated, &v_advance_rotated); return 0; /* * Cleanup on error */ cleanup: if (image) { FT_Done_Glyph(image); } return -1; }