41 #include FT_FREETYPE_H 48 #define FT_ERRORDEF( e, v, s ) { e, s }, 49 #define FT_ERROR_START_LIST { 50 #define FT_ERROR_END_LIST { 0, 0 } }; 61 const char* get_ft_error_message(
int error)
85 VL_DEBUG_SET_OBJECT_NAME()
90 mFreeTypeLoadForceAutoHint =
true;
96 VL_DEBUG_SET_OBJECT_NAME()
101 mFreeTypeLoadForceAutoHint =
true;
108 releaseFreeTypeData();
115 if (!mFontManager->freeTypeLibrary())
117 vl::Log::error(
"Font::releaseFreeTypeData(): mFontManager->freeTypeLibrary() is NULL!\n");
122 FT_Done_Face(mFT_Face);
140 if(path == mFilePath)
150 FT_Done_Face(mFT_Face);
159 Log::error(
Say(
"Font::loadFont('%s'): font file not found.\n") << filePath() );
161 if ( font_file && font_file->
load(mMemoryFile) )
163 if ( (
int)mMemoryFile.size() == font_file->
size() )
165 error = FT_New_Memory_Face( (FT_Library)mFontManager->freeTypeLibrary(),
166 (FT_Byte*)&mMemoryFile[0],
167 (
int)mMemoryFile.size(),
172 Log::error(
Say(
"Font::loadFont('%s'): could not read file.\n") << filePath() );
177 Log::error(
Say(
"FT_New_Face error (%s): %s\n") << filePath() << get_ft_error_message(error) );
196 error = FT_Set_Char_Size(
206 if ( (mFT_Face->face_flags & FT_FACE_FLAG_SCALABLE) == 0 && mFT_Face->num_fixed_sizes)
210 int best_match_index = -1;
211 int best_match_size = 0;
212 for(
int i=0; i < mFT_Face->num_fixed_sizes; ++i )
214 int size = mFT_Face->available_sizes[i].y_ppem/64;
218 if (best_match_index == -1 || (mSize - size) < (mSize - best_match_size) )
220 best_match_index = i;
221 best_match_size = size;
226 if (best_match_index == -1)
227 best_match_index = 0;
229 error = FT_Select_Size(mFT_Face, best_match_index);
231 Log::error(
Say(
"FT_Select_Size error (%s): %s\n") << filePath() << get_ft_error_message(error) );
236 Log::error(
Say(
"FT_Set_Char_Size error (%s): %s\n") << filePath() << get_ft_error_message(error) );
242 mHeight = mFT_Face->size->metrics.height / 64.0f;
267 error = FT_Load_Char( mFT_Face, character, freeTypeLoadForceAutoHint() ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_DEFAULT );
271 Log::error(
Say(
"FT_Load_Char error (%s): %s\n") << filePath() << get_ft_error_message(error) );
277 glyph->
setGlyphIndex( FT_Get_Char_Index( mFT_Face, character ) );
279 error = FT_Render_Glyph(
281 FT_RENDER_MODE_NORMAL );
290 error = FT_Load_Glyph(
296 error = FT_Render_Glyph(
298 FT_RENDER_MODE_NORMAL );
303 Log::error(
Say(
"FT_Render_Glyph error (%s): %s\n") << filePath() << get_ft_error_message(error) );
309 bool ok_format = mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY || mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO;
310 ok_format &= mFT_Face->glyph->bitmap.palette_mode == 0;
311 ok_format &= mFT_Face->glyph->bitmap.pitch > 0 || mFT_Face->glyph->bitmap.buffer ==
NULL;
315 Log::error(
Say(
"Font::glyph() error (%s): glyph format not supported. Visualization Library currently supports only FT_PIXEL_MODE_GRAY and FT_PIXEL_MODE_MONO.\n") << filePath() );
320 if ( mFT_Face->glyph->bitmap.buffer )
323 mHeight = (float)mFT_Face->glyph->bitmap.rows;
325 glyph->
setWidth ( mFT_Face->glyph->bitmap.width);
326 glyph->
setHeight( mFT_Face->glyph->bitmap.rows);
327 glyph->
setLeft ( mFT_Face->glyph->bitmap_left);
328 glyph->
setTop ( mFT_Face->glyph->bitmap_top);
330 VL_CHECK( mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY || mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO )
331 VL_CHECK( mFT_Face->glyph->bitmap.palette_mode == 0 )
332 VL_CHECK( mFT_Face->glyph->bitmap.pitch > 0 )
335 glGenTextures( 1, &texhdl );
337 VL_glActiveTexture(GL_TEXTURE0);
340 int texsize[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
341 int max_tex_size = 0;
342 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
344 int w=0, h=0, margin = 1;
346 for(
int i=0; texsize[i]; ++i)
348 if ( (texsize[i] >= glyph->
width() + margin*2 && texsize[i] >= glyph->
height() + margin*2) || texsize[i+1] > max_tex_size )
362 glyph->
setS1((margin*2 + glyph->
width() ) /(
float)(w-1) );
363 glyph->
setT1( 1 -(margin*2 + glyph->
height() ) /(
float)(h-1) );
371 glyph->
setS0((
float)margin /(
float)w);
372 glyph->
setT0( 1 -(
float)margin /(
float)h);
373 glyph->
setS1(((
float)margin + glyph->
width() ) /(
float)w);
374 glyph->
setT1( 1 -((
float)margin + glyph->
height() ) /(
float)h);
391 for(
int y=0; y<glyph->
height(); y++)
393 for(
int x=0; x<glyph->
width(); x++)
395 int offset_1 = (x+margin) * 4 + (w-1-y-margin) * img->
pitch();
397 if (mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
398 offset_2 = x / 8 + y *
::abs(mFT_Face->glyph->bitmap.pitch);
400 offset_2 = x + y * mFT_Face->glyph->bitmap.pitch;
403 if (mFT_Face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
404 img->
pixels()[ offset_1+3 ] = (mFT_Face->glyph->bitmap.buffer[ offset_2 ] >> (7-x%8)) & 0x1 ? 0xFF : 0x0;
406 img->
pixels()[ offset_1+3 ] = mFT_Face->glyph->bitmap.buffer[ offset_2 ];
409 img->
pixels()[ offset_1+0 ] = face->glyph->bitmap.buffer[ offset_2 ];
410 img->
pixels()[ offset_1+1 ] = face->glyph->bitmap.buffer[ offset_2 ];
411 img->
pixels()[ offset_1+2 ] = face->glyph->bitmap.buffer[ offset_2 ];
412 img->
pixels()[ offset_1+3 ] = 0xFF;
421 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
422 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
423 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
424 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
428 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
429 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
430 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
431 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
435 if (Has_GL_EXT_texture_filter_anisotropic)
437 float max_anisotropy;
438 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
439 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
443 glBindTexture( GL_TEXTURE_2D, 0 );
446 glyph->
setAdvance(
fvec2( (
float)mFT_Face->glyph->advance.x / 64.0f, (
float)mFT_Face->glyph->advance.y / 64.0f ) );
455 std::map<int, ref<Glyph> >::iterator it = mGlyphMap.begin();
456 for(; it != mGlyphMap.end(); ++it )
465 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
466 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
467 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
468 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
472 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
473 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
474 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
475 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
478 glBindTexture( GL_TEXTURE_2D, 0 );
The FontManager class keeps a map associating a font path, size and smoothing flag to a Font object...
VLCORE_EXPORT FileSystem * defFileSystem()
Returns the default FileSystem used by VisualizationLibrary.
void setGlyphIndex(unsigned int glyph_index)
A simple String formatting class.
const unsigned char * pixels() const
Raw pointer to pixels.
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
void loadFont(const String &path)
Loads a font using fileSystem()locateFile().
Glyph * glyph(int character)
Returns (and eventually creates) the Glyph* associated to the given character.
The Glyph associated to a character of a given Font.
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
unsigned int textureHandle() const
void releaseFreeTypeData()
Releases the FreeType's FT_Face used by a Font.
virtual ref< VirtualFile > locateFile(const String &full_path, const String &alternate_path=String()) const
Looks for a VirtualFile on the disk and in the currently active FileSystem.
void setSize(int size)
The size of the font.
int requiredMemory() const
Returns the number of bytes requested to store the image.
Visualization Library main namespace.
Vector2< float > fvec2
A 2 components vector with float precision.
void setTextureHandle(unsigned int handle)
void setHeight(int height)
void setSmooth(bool smooth)
Whether the font rendering should use linear filtering or not.
unsigned int mTextureHandle
virtual long long size() const =0
Returns the size of the file in bytes.
void setAdvance(const fvec2 &advance)
Implements a generic 1d, 2d, 3d and cubemap image that can have mipmaps.
The ref<> class is used to reference-count an Object.
void allocate2D(int x, int y, int bytealign, EImageFormat format, EImageType type)
long long load(std::vector< char > &data)
Loads the entire file in the specified vector.
String & clear()
Clears the string.
EImageFormat format() const