void FontBuilder::CacheSymbol(wchar_t s) { CacheData* data = wcache[curSize][curFace][s]; if (!data) { FT_UInt glyphIndex = FT_Get_Char_Index(curFace, s); FT_Error error = FT_Load_Glyph(curFace, glyphIndex, 0); if (error) out_error() << L"Error occured while loading a glyph" << std::endl; if (curFace->glyph->format != FT_GLYPH_FORMAT_BITMAP) { error = FT_Render_Glyph(curFace->glyph, FT_RENDER_MODE_NORMAL); if (error) out_error() << L"Error occured while rendering a glyph" << std::endl; } FT_GlyphSlot slot = curFace->glyph; data = new CacheData; data->width = slot->bitmap.width; data->height = slot->bitmap.rows; if (data->width*data->height > 0) { data->buffer = new unsigned char[data->width*data->height]; memcpy(data->buffer, slot->bitmap.buffer, data->width*data->height); } data->x_offset = slot->bitmap_left; data->y_offset = slot->bitmap_top; data->x_advance = slot->advance.x >> 6; data->y_advance = slot->advance.y >> 6; wcache[curSize][curFace][s] = data; }
const bitmap* freetype::get_bitmap(unsigned int char_code) const { implement::cache& cache = impl_->get_cache(); if (cache.find(char_code) != cache.end()) return &cache[char_code]; FT_GlyphSlot glyph = impl_->load_glyph(char_code); if (!glyph || 0 != FT_Render_Glyph(glyph, impl_->property_.render_mode)) return nullptr; bitmap* bitmap = &cache[char_code]; unsigned int buffer_length = glyph->bitmap.rows * glyph->bitmap.pitch; bitmap->left = glyph->bitmap_left; bitmap->top = glyph->bitmap_top - ascender(); bitmap->width = glyph->bitmap.width; bitmap->height = glyph->bitmap.rows; bitmap->advance = REAL(glyph->linearHoriAdvance, 16); bitmap->pitch = glyph->bitmap.pitch; bitmap->pixel_mode = glyph->bitmap.pixel_mode; bitmap->buffer = reinterpret_cast<unsigned char*>( memcpy(new unsigned char [buffer_length], glyph->bitmap.buffer, buffer_length)); return bitmap; }
void loadchar(unsigned int uc) { FT_Bitmap* bitmap; unsigned int index; ubyte *Tex, *Texsrc; int wid = (int)pow(2, ceil(log2(32 * stretch))); index = FT_Get_Char_Index(fontface, uc); FT_Load_Glyph(fontface, index, FT_LOAD_DEFAULT); FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL); bitmap = &(slot->bitmap); Texsrc = bitmap->buffer; Tex = new ubyte[wid * wid * 4]; memset(Tex, 0, wid * wid * 4 * sizeof(ubyte)); for (unsigned int i = 0; i < bitmap->rows; i++) { for (unsigned int j = 0; j < bitmap->width; j++) { Tex[(i * wid + j) * 4 + 0] = Tex[(i * wid + j) * 4 + 1] = Tex[(i * wid + j) * 4 + 2] = 255U; Tex[(i * wid + j) * 4 + 3] = *Texsrc; Texsrc++; } } glGenTextures(1, &chars[uc].tex); glBindTexture(GL_TEXTURE_2D, chars[uc].tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wid, wid, 0, GL_RGBA, GL_UNSIGNED_BYTE, Tex); delete[] Tex; chars[uc].aval = true; chars[uc].width = bitmap->width; chars[uc].height = bitmap->rows; chars[uc].advance = slot->advance.x >> 6; chars[uc].xpos = slot->bitmap_left; chars[uc].ypos = slot->bitmap_top; }
euint32 FontRenderer::draw_letter(wchar_t _letter, vptr _target, euint32 _width) { FT_GlyphSlot slot = m_ft_face->glyph; FT_UInt glyph_index; FT_UInt error; glyph_index = FT_Get_Char_Index( m_ft_face, _letter ); error = FT_Load_Glyph( m_ft_face, glyph_index, FT_LOAD_DEFAULT ); if ( error ) { return 0; } /// 加粗函数 FT_Outline_Embolden( &m_ft_face->glyph->outline, 100 ); error = FT_Render_Glyph( m_ft_face->glyph, FT_RENDER_MODE_NORMAL ); if ( error ) { return 0; } return draw_text( &slot->bitmap, _target, 0, 0, _width); }
Glyph Font::renderGlyph(char glyph, float font_size) { if(m_rendered_symbols[(int)glyph].find(font_size) != m_rendered_symbols[(int)glyph].end()) { return m_rendered_symbols[(int)glyph].at(font_size); } Glyph new_glyph; FT_UInt char_index = FT_Get_Char_Index(m_font_face, glyph); if(FT_Load_Glyph(m_font_face, char_index, FT_LOAD_DEFAULT) || FT_Render_Glyph(m_font_face->glyph, FT_RENDER_MODE_NORMAL)) return new_glyph; FT_Bitmap& bitmap = m_font_face->glyph->bitmap; new_glyph.bearing.x = m_font_face->glyph->metrics.horiBearingX / 64; new_glyph.bearing.y = m_font_face->glyph->metrics.horiBearingY / 128; new_glyph.advance = m_font_face->glyph->metrics.horiAdvance / 64; glGenTextures(1, &new_glyph.texture); glBindTexture(GL_TEXTURE_2D, new_glyph.texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); checkGLError(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap.width, bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap.buffer); checkGLError(); new_glyph.id = glyph; new_glyph.dimensions = glm::vec2(bitmap.width, bitmap.rows); m_rendered_symbols[(int)glyph][font_size] = new_glyph; return new_glyph; }
static void draw_text(FT_Face face, FT_Vector * pen, FT_Matrix * matrix, const unsigned char *out, int len, int color, struct rectangle *box) { FT_ULong ch; FT_Error ans; FT_GlyphSlot slot = face->glyph; int i; for (i = 0; i < len; i += 2) { ch = (out[i] << 8) | out[i + 1]; if (ch == 10) continue; /* transform */ FT_Set_Transform(face, matrix, pen); /* get glyph image */ ans = FT_Load_Char(face, ch, FT_LOAD_NO_BITMAP); if (ans) continue; ans = FT_Render_Glyph(face->glyph, ft_render_mode_normal); if (ans) continue; /* draw bitmap */ if (!box) draw_bitmap(&slot->bitmap, slot->bitmap_left, screen_height - slot->bitmap_top); else set_text_box(&slot->bitmap, slot->bitmap_left, screen_height - slot->bitmap_top, box); /* increment pen position */ pen->x += slot->advance.x; pen->y += slot->advance.y; } }
/** * Caches the given font glyph in the instance font texture buffer. * * This routine renders and stores the requested glyph's bitmap and relevant information into its own quickly addressible * structure within an instance-specific map. * * @param charCode The requested glyph's character code. * @return A pointer to the allocated font structure. */ ftgxCharData *FreeTypeGX::cacheGlyphData(wchar_t charCode) { FT_UInt gIndex; uint16_t textureWidth = 0, textureHeight = 0; gIndex = FT_Get_Char_Index( ftFace, charCode ); if (!FT_Load_Glyph(ftFace, gIndex, FT_LOAD_DEFAULT )) { FT_Render_Glyph( ftSlot, FT_RENDER_MODE_NORMAL ); if(ftSlot->format == FT_GLYPH_FORMAT_BITMAP) { FT_Bitmap *glyphBitmap = &ftSlot->bitmap; textureWidth = adjustTextureWidth(glyphBitmap->width, this->textureFormat); textureHeight = adjustTextureHeight(glyphBitmap->rows, this->textureFormat); this->fontData[charCode] = (ftgxCharData){ ftSlot->bitmap_left, ftSlot->advance.x >> 6, gIndex, textureWidth, textureHeight, ftSlot->bitmap_top, ftSlot->bitmap_top, glyphBitmap->rows - ftSlot->bitmap_top, NULL }; this->loadGlyphData(glyphBitmap, &this->fontData[charCode]); return &this->fontData[charCode]; }
void Freetype::drawText(const char *txt, unsigned int x, unsigned int y) { int error; while (*txt) { FT_UInt glyph_index; glyph_index = FT_Get_Char_Index(_face, *txt); if ((error = FT_Load_Glyph(_face, glyph_index, FT_LOAD_DEFAULT))) continue; if ((error = FT_Render_Glyph(_face->glyph, FT_RENDER_MODE_NORMAL))) continue; my_draw_bitmap(&_slot->bitmap, x + _slot->bitmap_left, y - _slot->bitmap_top, _slot, _size); x += _slot->advance.x >> 6; y += _slot->advance.y >> 6; x += _padding; txt++; } }
BitmapRef FTFont::Glyph(char32_t glyph) { if(!check_face()) { return Font::Default()->Glyph(glyph); } if (FT_Load_Char(face_.get(), glyph, FT_LOAD_NO_BITMAP) != FT_Err_Ok) { Output::Error("Couldn't load FreeType character %d", glyph); } if (FT_Render_Glyph(face_->glyph, FT_RENDER_MODE_MONO) != FT_Err_Ok) { Output::Error("Couldn't render FreeType character %d", glyph); } FT_Bitmap const& ft_bitmap = face_->glyph->bitmap; assert(face_->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); size_t const pitch = std::abs(ft_bitmap.pitch); int const width = ft_bitmap.width; int const height = ft_bitmap.rows; BitmapRef bm = Bitmap::Create(nullptr, width, height, 0, DynamicFormat(8,8,0,8,0,8,0,8,0,PF::Alpha)); uint8_t* data = reinterpret_cast<uint8_t*>(bm->pixels()); int dst_pitch = bm->pitch(); for(int row = 0; row < height; ++row) { for(int col = 0; col < width; ++col) { unsigned c = ft_bitmap.buffer[pitch * row + (col/8)]; unsigned bit = 7 - (col%8); data[row * dst_pitch + col] = (c & (0x01 << bit)) ? 255 : 0; } } return bm; }
//------------------------------------------------------------------------------------------------------- StringManager::BChar* StringManager::_LoadChar(wchar_t wchar) { //参考http://my.unix-center.net/~Simon_fu/?p=385 bool space = false; if( L' ' == wchar ) { space = true; wchar = L'_'; } FT_Load_Glyph(m_FT_Face, FT_Get_Char_Index( m_FT_Face, wchar ), FT_LOAD_DEFAULT);//FT_LOAD_FORCE_AUTOHINT| FT_LOAD_TARGET_NORMAL); //得到字模 FT_Glyph glyph; FT_Get_Glyph( m_FT_Face->glyph, &glyph ); //转化成位图 FT_Render_Glyph( m_FT_Face->glyph, FT_RENDER_MODE_LCD ); FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 ); FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph; //取道位图数据 FT_Bitmap& bitmap=bitmap_glyph->bitmap; //重新计算数据 float scale = static_cast<float>(bitmap.rows) / static_cast<float>(m_FT_Face->glyph->metrics.height);//计算文本高宽缩放到bitmap高宽的缩放比 int beginY = Math::Ceil( m_FT_Face->glyph->metrics.horiBearingY * scale );//y偏移 //FT_Done_Glyph(glyph); vector2d size = vector2d(bitmap.width, bitmap.rows); return NEW BChar(beginY, size, glyph, space); }
RasterizedGlyph get(uint32_t codePoint, Vector2i subpixeloffset64) { FT_Error error = FT_Load_Glyph(m_face, codePoint, // the glyph_index in the font file FT_LOAD_NO_HINTING // by default hb load fonts without hinting ); if (error != FT_Err_Ok) { debug(LOG_FATAL, "unable to load glyph"); } FT_GlyphSlot slot = m_face->glyph; FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_LCD); FT_Bitmap ftBitmap = slot->bitmap; RasterizedGlyph g; g.buffer.reset(new unsigned char[ftBitmap.pitch * ftBitmap.rows]); memcpy(g.buffer.get(), ftBitmap.buffer, ftBitmap.pitch * ftBitmap.rows); g.width = ftBitmap.width / 3; g.height = ftBitmap.rows; g.bearing_x = slot->bitmap_left; g.bearing_y = slot->bitmap_top; g.pitch = ftBitmap.pitch; return g; }
static void TestFace( FT_Face face ) { unsigned int gid; int load_flags = FT_LOAD_DEFAULT; if ( check_outlines && FT_IS_SCALABLE( face ) ) load_flags = FT_LOAD_NO_BITMAP; if ( nohints ) load_flags |= FT_LOAD_NO_HINTING; FT_Set_Char_Size( face, 0, font_size, 72, 72 ); for ( gid = 0; gid < face->num_glyphs; gid++ ) { if ( check_outlines && FT_IS_SCALABLE( face ) ) { if ( !FT_Load_Glyph( face, gid, load_flags ) ) FT_Outline_Decompose( &face->glyph->outline, &outlinefuncs, NULL ); } else FT_Load_Glyph( face, gid, load_flags ); if ( rasterize ) FT_Render_Glyph( face->glyph, ft_render_mode_normal ); } FT_Done_Face( face ); }
FTTextureGlyph::FTTextureGlyph (FT_GlyphSlot glyph, int id, int xOffset, int yOffset, GLsizei width, GLsizei height) : FTGlyph (glyph), destWidth(0), destHeight(0), glTextureID(id) { err = FT_Render_Glyph (glyph, FT_RENDER_MODE_NORMAL); if (err || glyph->format != ft_glyph_format_bitmap) return; FT_Bitmap bitmap = glyph->bitmap; destWidth = bitmap.width; destHeight = bitmap.rows; if (destWidth && destHeight) { #ifndef USE_GLES1 glPushClientAttrib (GL_CLIENT_PIXEL_STORE_BIT); glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); #endif glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glBindTexture (GL_TEXTURE_2D, glTextureID); glTexSubImage2D (GL_TEXTURE_2D, 0, xOffset, yOffset, destWidth, destHeight, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.buffer); #ifndef USE_GLES1 glPopClientAttrib(); #endif } uv[0].X (static_cast<float>(xOffset) / static_cast<float>(width)); uv[0].Y (static_cast<float>(yOffset) / static_cast<float>(height)); uv[1].X (static_cast<float> (xOffset + destWidth) / static_cast<float>(width)); uv[1].Y (static_cast<float> (yOffset + destHeight) / static_cast<float>(height)); pos.X (glyph->bitmap_left); pos.Y (glyph->bitmap_top); }
int glyphinfo(FT_Face face, FT_ULong ul) { FT_UInt glyph_index; FT_GlyphSlot slot = face->glyph; int error; glyph_index = FT_Get_Char_Index(face, ul); error = FT_Load_Glyph( face, /* handle to face object */ glyph_index, /* glyph index */ FT_LOAD_DEFAULT ); /* load flags, see below */ if ( error ) { printf("FT_Load_Glyph() failed: %d (0x%08X)\n", error, error); return -1; } error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); if ( error ) { printf("FT_Render_Glyph() failed: %d (0x%08X)\n", error, error); return -1; } if (face->glyph->advance.x <= HALF_WIDTH_MAX) { return HALF_WIDTH; } else { return DOUBLE_WIDTH; } }
void FreeTypeFont::doFillGlyphCache(GlyphCache& cache, const std::vector<char32_t>& characters) #endif { /** @bug Crash when atlas is too small */ /* Get glyph codes from characters */ std::vector<FT_UInt> charIndices; charIndices.resize(characters.size()+1); charIndices[0] = 0; std::transform(characters.begin(), characters.end(), charIndices.begin()+1, [this](const char32_t c) { return FT_Get_Char_Index(ftFont, c); }); /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */ std::sort(charIndices.begin(), charIndices.end()); charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end()); /* Sizes of all characters */ std::vector<Vector2i> charSizes; charSizes.reserve(charIndices.size()); for(FT_UInt c: charIndices) { CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, c, FT_LOAD_DEFAULT) == 0); charSizes.push_back(Vector2i(ftFont->glyph->metrics.width, ftFont->glyph->metrics.height)/64); } /* Create texture atlas */ const std::vector<Rectanglei> charPositions = cache.reserve(charSizes); /* Render all characters to the atlas and create character map */ unsigned char* pixmap = new unsigned char[cache.textureSize().product()](); /** @todo Some better way for this */ #ifndef MAGNUM_TARGET_GLES2 Image2D image(ImageFormat::Red, ImageType::UnsignedByte, cache.textureSize(), pixmap); #else Image2D image(Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ? ImageFormat::Red : ImageFormat::Luminance, ImageType::UnsignedByte, cache.textureSize(), pixmap); #endif for(std::size_t i = 0; i != charPositions.size(); ++i) { /* Load and render glyph */ /** @todo B&W only if radius != 0 */ FT_GlyphSlot glyph = ftFont->glyph; CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0); CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0); /* Copy rendered bitmap to texture image */ const FT_Bitmap& bitmap = glyph->bitmap; CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2); CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2); for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout) for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout) pixmap[yout*cache.textureSize().x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin]; /* Insert glyph parameters into cache */ cache.insert(charIndices[i], Vector2i(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()), charPositions[i]); } /* Set cache image */ cache.setImage({}, image); }
void FTFont::Render(Bitmap& bmp, int const x, int const y, Color const& color, unsigned const glyph) { if(!check_face()) { Font::Default()->Render(bmp, x, y, color, glyph); return; } if (FT_Load_Char(face_.get(), glyph, FT_LOAD_NO_BITMAP) != FT_Err_Ok) { Output::Error("Couldn't load FreeType character %d\n", glyph); return; } if (FT_Render_Glyph(face_->glyph, FT_RENDER_MODE_MONO) != FT_Err_Ok) { Output::Error("Couldn't render FreeType character %d\n", glyph); return; } FT_Bitmap const& ft_bitmap = face_->glyph->bitmap; assert(face_->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); size_t const pitch = std::abs(ft_bitmap.pitch); for(int row = 0; row < ft_bitmap.rows; ++row) { for(size_t col = 0; col < pitch; ++col) { unsigned c = ft_bitmap.buffer[pitch * row + col]; for(int bit = 7; bit >= 0; --bit) { if(c & (0x01 << bit)) { bmp.SetPixel(x + col * 8 + (7 - bit), y + row, color); } } } } }
void renderString(SDL_Surface *screen, char *glyphs, int x, int y) { int error; int c; int cx = x; int cy = y; for(c = 0;c<strlen(glyphs);c++) { if(glyphs[c] == '\n') { cy+=60; cx = x; continue; } int glyph_index = FT_Get_Char_Index( face, glyphs[c]); error = FT_Load_Glyph( face, glyph_index, 0 ); // Load 'A' glyph with default parameters (0) if(error) { continue; } error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); // Can haz bitmap? if(error) { continue; } int i, j; for(i = 0; i<face->glyph->bitmap.rows;i++) for(j = 0;j<face->glyph->bitmap.width;j++) put_pixel(screen,face->glyph->bitmap.buffer[i*face->glyph->bitmap.pitch+j],cx+j,cy+i+(32-face->glyph->bitmap.rows)); cx += face->glyph->bitmap.width+5; } }
int FreeType::plotGlyph(GlyphDescr* f, Glyph* g) { unsigned int glyphIndex = FT_Get_Char_Index(m_face, f->c); int r = FT_Load_Glyph(m_face, glyphIndex, FT_LOAD_DEFAULT); if (r) { clc::Log::error(LOG_NAME, "FT_Load_Glyph failed: %d", r); return -1; } if (m_face->glyph->format != FT_GLYPH_FORMAT_BITMAP) { r = FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_NORMAL); if (r) { clc::Log::error(LOG_NAME, "FT_Render_Glyph failed: %d", r); return -1; } } FT_GlyphSlot slot = m_face->glyph; g->w = slot->bitmap.width; g->h = slot->bitmap.rows; g->bitmap = new uint8_t[g->w * g->h]; memcpy(g->bitmap, slot->bitmap.buffer, g->w * g->h); g->offsetX = slot->bitmap_left; g->offsetY = slot->bitmap_top; g->advanceX = slot->advance.x >> 6; g->advanceY = slot->advance.y >> 6; g->height = m_face->size->metrics.height >> 6; return 0; }
cv::Mat SampleGenetator::genSample(const wchar_t wc, const uchar bgColor, const uchar fgColor) { cv::Mat result; FT_UInt glyph_index = FT_Get_Char_Index(face, wc); FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); FT_GlyphSlot slot = face->glyph; int rows = slot->bitmap.rows; int cols = slot->bitmap.width; result = cv::Mat(rows, cols, CV_8UC1); result.setTo(bgColor); for (int row = 0; row < rows; ++row) { for (int col = 0; col < cols; ++col) { const int offset = row * slot->bitmap.pitch + col; if (slot->bitmap.buffer[offset]) { result.at<uchar>(row, col) = fgColor; } } } return result; }
FontPixelBuffer FontEngine_Freetype::get_font_glyph_subpixel(int glyph) { FontPixelBuffer font_buffer; FT_GlyphSlot slot = face->glyph; FT_UInt glyph_index; // Get glyph index glyph_index = FT_Get_Char_Index(face, glyph); FT_Error error; error = FT_Load_Glyph(face, glyph_index, FT_LOAD_TARGET_LCD ); if (error) return font_buffer; error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD); font_buffer.glyph = glyph; // Set Increment pen position font_buffer.increment.x = (slot->advance.x+32) >> 6; font_buffer.increment.y = (slot->advance.y+32) >> 6; if (error || slot->bitmap.rows == 0 || slot->bitmap.width == 0) return font_buffer; // Set destination offset font_buffer.offset.x = slot->bitmap_left; font_buffer.offset.y = -slot->bitmap_top; int src_width = slot->bitmap.width; int src_height = slot->bitmap.rows; int src_pitch = slot->bitmap.pitch; // Convert the bitmap PixelBuffer pixelbuffer(src_width/3, src_height, tf_rgba8); font_buffer.buffer = pixelbuffer; font_buffer.buffer_rect = pixelbuffer.get_size(); font_buffer.empty_buffer = false; unsigned char *src_data = slot->bitmap.buffer; unsigned char *pixel_data = (unsigned char *) font_buffer.buffer.get_data(); int dest_pitch = font_buffer.buffer.get_pitch(); // For 8bit bitmaps for (int ycnt = 0; ycnt < src_height; ycnt++) { unsigned char *dest_data = pixel_data; for (int xcnt = 0; xcnt < src_width/3; xcnt++) { *(dest_data++)= src_data[xcnt*3+2]; *(dest_data++)= src_data[xcnt*3+1]; *(dest_data++)= src_data[xcnt*3+0]; *(dest_data++)= 0; } pixel_data += dest_pitch; src_data += src_pitch; } return font_buffer; }
void draw_string(gfx_context_t * ctx, int x, int y, uint32_t fg, char * string) { slot = face->glyph; int pen_x = x, pen_y = y, i = 0; int len = strlen(string); int error; for (i = 0; i < len; ++i) { FT_UInt glyph_index; glyph_index = FT_Get_Char_Index( face, string[i]); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); if (error) { printf("Error loading glyph for '%c'\n", string[i]); continue; } slot = (face)->glyph; if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { error = FT_Render_Glyph((face)->glyph, FT_RENDER_MODE_NORMAL); if (error) { printf("Error rendering glyph for '%c'\n", string[i]); continue; } } draw_char(&slot->bitmap, pen_x + slot->bitmap_left, pen_y - slot->bitmap_top, fg, ctx); pen_x += slot->advance.x >> 6; pen_y += slot->advance.y >> 6; } }
TTF_Font* TTF_New_Memory_Face(const FT_Byte* file_base, FT_Long file_size, int ptsize) { TTF_Font *font = (TTF_Font*)malloc(sizeof *font); if (font == NULL) E_Exit("TTF: Out of memory"); memset(font, 0, sizeof(*font)); if (FT_New_Memory_Face(library, file_base, file_size, 0, &font->face)) E_Exit("TTF: Couldn't init font"); FT_Face face = font->face; if (!FT_IS_SCALABLE(face)) // Make sure that our font face is scalable (global metrics) E_Exit("TTF: Font is not scalable"); for (int i = 0; i < face->num_charmaps; i++) // Set charmap for loaded font { FT_CharMap charmap = face->charmaps[i]; if (charmap->platform_id == 3 && charmap->encoding_id == 1) // Windows Unicode { FT_Set_Charmap(face, charmap); break; } } TTF_SetCharSize(font, ptsize); bool fontOK = false; if (!FT_Load_Glyph(face, 0, FT_LOAD_DEFAULT)) // Test pixel mode if (!FT_Render_Glyph(font->face->glyph, FT_RENDER_MODE_NORMAL)) // Render the glyph if (font->face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) fontOK = true; if (!fontOK) E_Exit("TTF: Font is not 8 bits gray scale"); return font; }
static c_glyph* LoadGlyph(TTF_Font* font, Uint8 ch) { c_glyph* cached = &font->cache[ch]; if (cached->pixmap.buffer) // If already cached return cached; FT_Face face = font->face; if (FT_Load_Glyph(face, FT_Get_Char_Index(face, cpMap[ch]), FT_LOAD_NO_AUTOHINT)) return 0; FT_GlyphSlot glyph = face->glyph; FT_Glyph_Metrics* metrics = &glyph->metrics; cached->minx = FT_FLOOR(metrics->horiBearingX); cached->maxx = FT_CEIL(metrics->horiBearingX+metrics->width); cached->maxy = FT_FLOOR(metrics->horiBearingY); cached->miny = cached->maxy-FT_CEIL(metrics->height); cached->yoffset = font->ascent-cached->maxy; if (FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL)) // Render the glyph return 0; FT_Bitmap* src = &glyph->bitmap; // Copy information to cache FT_Bitmap* dst = &cached->pixmap; memcpy(dst, src, sizeof(*dst)); if (dst->rows != 0) { int len = dst->pitch*dst->rows; dst->buffer = (unsigned char *)malloc(len); if (!dst->buffer) return 0; memcpy(dst->buffer, src->buffer, len); } return cached; }
Bitmap FreetypeFontProvider::GetGlyphBitmap(wchar_t code) { unsigned int index = 0; int rc = 0; if ( FontProvider::HasGlyph(code) || (index = FT_Get_Char_Index(m_font_face, code)) == 0 ) { return FontProvider::GetGlyphBitmap(code); } if ( FT_Load_Glyph(m_font_face, index, /*m_render_mode == FT_RENDER_MODE_MONO? 0:*/ FT_LOAD_FORCE_AUTOHINT) ) { throw std::runtime_error("[FreetypeFontProvider::GetGlyphBitmap] Can't load character glyph"); } if ( m_font_face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) { FT_Render_Mode render_mode = m_render_mode; if ( (rc = FT_Render_Glyph(m_font_face->glyph, render_mode)) != 0 ) { //ShowMessageBox(to_string(rc)); //FT_Err_Unknown_File_Format; throw std::runtime_error("[FreetypeFontProvider::GetGlyphBitmap] Can't render glyph"); } } return PrepareBitmap(m_font_face->glyph); }
int createText(char c,Char* cha){ FT_UInt glyph_index; glyph_index = FT_Get_Char_Index(face, c); error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); if ( error ) { printf("e %d",error); return error; } error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); if ( error ) { printf("e1 %d",error); return error; } FT_Bitmap* bitmap = &slot->bitmap; int i,j; FT_Int x0 = slot->bitmap_left, y0 = slot->bitmap_top , w = bitmap->width , h = bitmap->rows ; //printf("x0=%d;y0=%d;w=%d;h=%d\n",x0,y0,w,h ); cha->w=w; cha->h=h; cha->a = slot->advance.x >> 6; cha->bx=x0; cha->by=y0; cha->data = malloc(w*h*sizeof(unsigned char)); for ( i=0; i<w*h; i++ ) cha->data[i] = bitmap->buffer[i]; // { // if(bitmap->buffer[i]==0) // { // printf("-"); // } // else // { // printf("0"); // } // if ( (i+1)%w==0 ) printf("\n"); // } return 0; }
JNIEXPORT jboolean JNICALL Java_com_badlogic_gdx_graphics_g2d_freetype_FreeType_renderGlyph(JNIEnv* env, jclass clazz, jlong slot, jint renderMode) { //@line:648 return !FT_Render_Glyph((FT_GlyphSlot)slot, (FT_Render_Mode)renderMode); }
bool TrueTypeFont::renderGlyph(uint32 unicode, Glyph &glyph) { uint32 index = FT_Get_Char_Index(_sjisFont, unicode); if (!index) return false; FT_Error err = FT_Load_Glyph(_sjisFont, index, FT_LOAD_MONOCHROME | FT_LOAD_NO_HINTING); if (err) return false; err = FT_Render_Glyph(_sjisFont->glyph, FT_RENDER_MODE_MONO); if (err) return false; FT_Glyph_Metrics &metrics = _sjisFont->glyph->metrics; glyph.xOffset = ftFloor26_6(metrics.horiBearingX); glyph.yOffset = _ascent - ftFloor26_6(metrics.horiBearingY); // In case we got a negative xMin we adjust that, this might make some // characters give a odd layout though. if (glyph.xOffset < 0) glyph.xOffset = 0; const FT_Bitmap &bitmap = _sjisFont->glyph->bitmap; glyph.height = bitmap.rows; glyph.width = bitmap.width; glyph.pitch = bitmap.pitch; glyph.plainData = 0; // We only accept monochrome characters. if (bitmap.pixel_mode != FT_PIXEL_MODE_MONO) return false; if (glyph.height) { glyph.plainData = new uint8[glyph.height * abs(glyph.pitch)]; if (!glyph.plainData) return false; const uint8 *src = bitmap.buffer; uint8 *dst = glyph.plainData; if (glyph.pitch < 0) dst += (glyph.height - 1) * (-glyph.pitch); for (int i = 0; i < bitmap.rows; ++i) { memcpy(dst, src, abs(glyph.pitch)); src += bitmap.pitch; dst += glyph.pitch; } } glyph.pitch = abs(glyph.pitch); return true; }
void loadGlyph(char letter) { int glyph_index = FT_Get_Char_Index( face, letter); FT_Load_Glyph(face,glyph_index,FT_LOAD_RENDER); FT_Render_Glyph(face->glyph,FT_RENDER_MODE_NORMAL); FT_Get_Glyph(face->glyph,(FT_Glyph *) &glyphs[letter -32]); }
const xd::detail::font::glyph& xd::font::load_glyph(utf8::uint32_t char_index, int size) { // check if glyph is already loaded glyph_map_t::iterator i = m_glyph_map.find(char_index); if (i != m_glyph_map.end()) return *i->second; FT_UInt glyph_index = FT_Get_Char_Index(m_face->handle, char_index); int error = FT_Load_Glyph(m_face->handle, glyph_index, FT_LOAD_DEFAULT); if (error) throw glyph_load_failed(m_filename, char_index); error = FT_Render_Glyph(m_face->handle->glyph, FT_RENDER_MODE_NORMAL); if (error) throw glyph_load_failed(m_filename, char_index); // create glyph m_glyph_map[char_index] = std::unique_ptr<detail::font::glyph>(new detail::font::glyph); detail::font::glyph& glyph = *m_glyph_map[char_index]; glyph.glyph_index = glyph_index; glyph.advance.x = static_cast<float>(m_face->handle->glyph->advance.x >> 6); glyph.advance.y = static_cast<float>(m_face->handle->glyph->advance.y >> 6); // get the handle to the bitmap FT_Bitmap bitmap = m_face->handle->glyph->bitmap; glGenTextures(1, &glyph.texture_id); glBindTexture(GL_TEXTURE_2D, glyph.texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap.width, bitmap.rows, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, bitmap.buffer); // create quad for it detail::font::vertex data[4]; data[0].pos = glm::vec2(0, 0); data[1].pos = glm::vec2(0, bitmap.rows); data[2].pos = glm::vec2(bitmap.width, bitmap.rows); data[3].pos = glm::vec2(bitmap.width, 0); data[0].tex = glm::vec2(0, 1); data[1].tex = glm::vec2(0, 0); data[2].tex = glm::vec2(1, 0); data[3].tex = glm::vec2(1, 1); // create a batch glyph.quad_ptr = detail::font::vertex_batch_ptr_t(new detail::font::vertex_batch_t(GL_QUADS)); glyph.quad_ptr->load(data, 4); glyph.offset.x = static_cast<float>(m_face->handle->glyph->bitmap_left); glyph.offset.y = static_cast<float>(m_face->handle->glyph->bitmap_top - bitmap.rows); return glyph; }
void LLFontFreetype::renderGlyph(const U32 glyph_index) const { if (mFTFace == NULL) return; llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT)); llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) ); mRenderGlyphCount++; }