typeface.cpp   typeface.cpp 
skipping to change at line 39 skipping to change at line 39
// - (20080221) Code formatting to meet Stellarium coding guidelines // - (20080221) Code formatting to meet Stellarium coding guidelines
// - (20080221) Additional comments for Doxygen // - (20080221) Additional comments for Doxygen
// - (20080221) Improve comments // - (20080221) Improve comments
// ________________________________________________________________________ __________________________ // ________________________________________________________________________ __________________________
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
#include <map> #include <map>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <cassert>
#include <algorithm> #include <algorithm>
#include <QtGlobal>
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include FT_GLYPH_H #include FT_GLYPH_H
#include "GLee.h" #include "GLee.h"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "typeface.h" #include "typeface.h"
// Data would be hidden inside an anonymous namespace, but msvc 6 can't han dle it // Data would be hidden inside an anonymous namespace, but msvc 6 can't han dle it
static FT_Library ftlibrary_; static FT_Library ftlibrary_;
static bool FTinitialized=false; static bool FTinitialized=false;
//! Information on a cached glyph //! Information on a cached glyph
struct CacheEntry struct CacheEntry
{ {
// CacheEntry() : topLeftUV_(0.f,0.f), bottomRightUV_(0.f,0.f), rend erSize_(0,0), advance_(0.f,0.f), bitmapPosition_(0.f,0.f) {}
size_t textureIndex_; //!< Index into the TypeFace's texture a rray size_t textureIndex_; //!< Index into the TypeFace's texture a rray
Vec2f topLeftUV_; //!< Texcoords for the top left corner o f the glyph Vec2f topLeftUV_; //!< Texcoords for the top left corner o f the glyph
Vec2f bottomRightUV_; //!< Texcoords for the bottom right corn er of the glyph Vec2f bottomRightUV_; //!< Texcoords for the bottom right corn er of the glyph
Vec2size_t renderSize_; //!< The size of the glyph in pixels on the render target Vec2size_t renderSize_; //!< The size of the glyph in pixels on the render target
Vec2f advance_; //!< The character advance for the cache d glyph Vec2f advance_; //!< The character advance for the cache d glyph
Vec2f bitmapPosition_; //!< The offset from the pen to the top left corner of the bitmap Vec2f bitmapPosition_; //!< The offset from the pen to the top left corner of the bitmap
}; };
//! Information on a cache texture //! Information on a cache texture
struct TextureInfo struct TextureInfo
{ {
TextureInfo() : size_(0,0) {}
typedef GLuint Handle; //!< typedef for a texture handle for an OpenGL texture typedef GLuint Handle; //!< typedef for a texture handle for an OpenGL texture
Handle handle_; //!< The OpenGL texture handle Handle handle_; //!< The OpenGL texture handle
Vec2size_t size_; //!< The size of the texture in texels Vec2size_t size_; //!< The size of the texture in texels
}; };
typedef std::vector<TextureInfo> Textures; //!< An array of text ures typedef std::vector<TextureInfo> Textures; //!< An array of text ures
typedef std::map<FT_UInt, CacheEntry> CharacterCache; //!< The cache maps g lyphs to cache entries typedef std::map<FT_UInt, CacheEntry> CharacterCache; //!< The cache maps g lyphs to cache entries
//! Implementation data for the TypeFace class //! Implementation data for the TypeFace class
struct Data struct Data
{ {
//! Constructor //! Constructor
Data(size_t aPointSize, size_t aResolution) : Data(size_t aPointSize, size_t aResolution) :
pointSize_(aPointSize), resolution_(aResolution) {} pointSize_(aPointSize), resolution_(aResolution), of fset_(0, 0) {}
size_t pointSize_; //!< The size of the type face in po ints size_t pointSize_; //!< The size of the type face in po ints
size_t resolution_; //!< The resolution of the type face in dpi size_t resolution_; //!< The resolution of the type face in dpi
FT_Face face_; //!< A handle to the FreeType face o bject FT_Face face_; //!< A handle to the FreeType face o bject
CharacterCache characterCache_; //!< The glyph cache CharacterCache characterCache_; //!< The glyph cache
Vec2i offset_; //!< The top left corner of the next glyph to be cached Vec2i offset_; //!< The top left corner of the next glyph to be cached
Textures textures_; //!< The texture sizes and handles o btained from OpenGL Textures textures_; //!< The texture sizes and handles o btained from OpenGL
bool hasKerning_; //!< Set to true if the type face su pports kerning bool hasKerning_; //!< Set to true if the type face su pports kerning
}; };
skipping to change at line 255 skipping to change at line 257
: data_(new Data(aPointSize, aResolution)) : data_(new Data(aPointSize, aResolution))
{ {
if (!StelFileMgr::exists(aFaceName)) if (!StelFileMgr::exists(aFaceName))
{ {
qWarning() << "Error: cannot find TTF font file " << aFaceNa me; qWarning() << "Error: cannot find TTF font file " << aFaceNa me;
} }
if (FTinitialized==false) if (FTinitialized==false)
{ {
int res = FT_Init_FreeType(&ftlibrary_); int res = FT_Init_FreeType(&ftlibrary_);
assert(res==0); Q_ASSERT(res==0);
res = 0; res = 0;
FTinitialized = true; FTinitialized = true;
} }
int res = FT_New_Face(ftlibrary_, aFaceName.toLocal8Bit(), 0, &data_ ->face_); int res = FT_New_Face(ftlibrary_, aFaceName.toLocal8Bit(), 0, &data_ ->face_);
assert(res == 0); Q_ASSERT(res == 0);
res = FT_IS_SCALABLE(data_->face_); res = FT_IS_SCALABLE(data_->face_);
assert(res!=0); Q_ASSERT(res!=0);
res = FT_IS_SFNT(data_->face_); res = FT_IS_SFNT(data_->face_);
assert(res!=0); Q_ASSERT(res!=0);
if(!data_->face_->charmap) if(!data_->face_->charmap)
FT_Set_Charmap(data_->face_, data_->face_->charmaps[0]); FT_Set_Charmap(data_->face_, data_->face_->charmaps[0]);
res = FT_Set_Char_Size(data_->face_, res = FT_Set_Char_Size(data_->face_,
0L, 0L,
static_cast<FT_F26Dot6>(aPointSize << 6), static_cast<FT_F26Dot6>(aPointSize << 6),
aResolution, aResolution,
aResolution); aResolution);
assert(res == 0); Q_ASSERT(res == 0);
data_->hasKerning_ = (FT_HAS_KERNING(data_->face_) != 0); data_->hasKerning_ = (FT_HAS_KERNING(data_->face_) != 0);
} }
TypeFace::~TypeFace() TypeFace::~TypeFace()
{ {
flushCache(); flushCache();
FT_Done_Face(data_->face_); FT_Done_Face(data_->face_);
delete data_; delete data_;
} }
skipping to change at line 301 skipping to change at line 303
return data_->pointSize_; return data_->pointSize_;
} }
void TypeFace::setPointSize(size_t aPointSize) void TypeFace::setPointSize(size_t aPointSize)
{ {
if(data_->pointSize_ != aPointSize) if(data_->pointSize_ != aPointSize)
{ {
data_->pointSize_ = aPointSize; data_->pointSize_ = aPointSize;
const FT_F26Dot6 sz = static_cast<FT_F26Dot6>(aPointSize << 6); const FT_F26Dot6 sz = static_cast<FT_F26Dot6>(aPointSize << 6);
int res = FT_Set_Char_Size(data_->face_, sz, sz, data_->reso lution_, data_->resolution_); int res = FT_Set_Char_Size(data_->face_, sz, sz, data_->reso lution_, data_->resolution_);
assert(res == 0); Q_ASSERT(res == 0);
res = 0; res = 0;
FT_Set_Char_Size(data_->face_, sz, sz, data_->resolution_, d ata_->resolution_); FT_Set_Char_Size(data_->face_, sz, sz, data_->resolution_, d ata_->resolution_);
flushCache(); flushCache();
} }
} }
size_t TypeFace::resolution() const size_t TypeFace::resolution() const
{ {
return data_->resolution_; return data_->resolution_;
} }
skipping to change at line 376 skipping to change at line 378
renderGlyphs(aString); renderGlyphs(aString);
glPopMatrix(); glPopMatrix();
glPopAttrib(); glPopAttrib();
} }
float TypeFace::width(const QString& aString) float TypeFace::width(const QString& aString)
{ {
float ret = 0; float ret = 0;
size_t leftChar = 0; size_t leftChar = 0;
for(int pos=0; pos<aString.size(); pos++) for (int pos=0; pos<aString.size(); ++pos)
{ {
size_t rightChar = FT_Get_Char_Index(data_->face_, aString.a t(pos).unicode()); size_t rightChar = FT_Get_Char_Index(data_->face_, aString.a t(pos).unicode());
ret += kerning(leftChar, rightChar)[0]; ret += kerning(leftChar, rightChar)[0];
ret += cachedGlyph(rightChar).advance_[0]; ret += cachedGlyph(rightChar).advance_[0];
leftChar = rightChar; leftChar = rightChar;
} }
return ret; return ret;
} }
int TypeFace::hitCharacterIndex(const QString& aString, float anOffset) int TypeFace::hitCharacterIndex(const QString& aString, float anOffset)
skipping to change at line 413 skipping to change at line 415
found = true; found = true;
break; break;
} }
leftChar = rightChar; leftChar = rightChar;
oldOffset = newOffset; oldOffset = newOffset;
++characterIndex; ++characterIndex;
} }
} }
if(!found) if (!found)
characterIndex = -1; return -1;
return characterIndex; return characterIndex;
} }
void TypeFace::addCacheEntry(FT_GlyphRec_* aGlyph, void TypeFace::addCacheEntry(FT_GlyphRec_* aGlyph,
FT_BitmapGlyphRec_* aBitmapGlyph, FT_BitmapGlyphRec_* aBitmapGlyph,
size_t aGlyphIndex, size_t aGlyphIndex,
const Vec2size_t& aGlyphSize) const Vec2size_t& aGlyphSize)
{ {
const TextureInfo& textureInfo = *(data_->textures_.rbegin()); const TextureInfo& textureInfo = *(data_->textures_.rbegin());
skipping to change at line 493 skipping to change at line 495
} }
void TypeFace::cacheGlyph(size_t aGlyphIndex) void TypeFace::cacheGlyph(size_t aGlyphIndex)
{ {
ensureTextureIsAvailable(); ensureTextureIsAvailable();
// 20060728 Modified to not load bitmap glyps - Stellarium patch 151 9491 // 20060728 Modified to not load bitmap glyps - Stellarium patch 151 9491
const FT_Error loadError = FT_Load_Glyph(data_->face_, const FT_Error loadError = FT_Load_Glyph(data_->face_,
aGlyphIndex, aGlyphIndex,
FT_LOAD_NO_HINTING | FT_LOA D_NO_BITMAP); FT_LOAD_NO_HINTING | FT_LOA D_NO_BITMAP);
assert(loadError == 0); Q_ASSERT(loadError == 0);
if(loadError == 0) if(loadError == 0)
{ {
FT_Glyph glyph; FT_Glyph glyph;
const FT_Error getError = FT_Get_Glyph( data_->face_->glyph, &glyph); const FT_Error getError = FT_Get_Glyph( data_->face_->glyph, &glyph);
if(getError == 0) if(getError == 0)
{ {
const FT_Error bitmapError = FT_Glyph_To_Bitmap(&gly ph, const FT_Error bitmapError = FT_Glyph_To_Bitmap(&gly ph,
FT_R ENDER_MODE_NORMAL, FT_R ENDER_MODE_NORMAL,
0, 1 ); 0, 1 );
skipping to change at line 532 skipping to change at line 534
} }
} }
CacheEntry& TypeFace::cachedGlyph(size_t aGlyphIndex) CacheEntry& TypeFace::cachedGlyph(size_t aGlyphIndex)
{ {
CharacterCache::iterator cacheIterator = data_->characterCache_.find (aGlyphIndex); CharacterCache::iterator cacheIterator = data_->characterCache_.find (aGlyphIndex);
if(cacheIterator == data_->characterCache_.end()) if(cacheIterator == data_->characterCache_.end())
{ {
cacheGlyph(aGlyphIndex); cacheGlyph(aGlyphIndex);
cacheIterator = data_->characterCache_.find(aGlyphIndex); cacheIterator = data_->characterCache_.find(aGlyphIndex);
assert(cacheIterator != data_->characterCache_.end()); Q_ASSERT(cacheIterator != data_->characterCache_.end());
} }
return cacheIterator->second; return cacheIterator->second;
} }
Vec2f TypeFace::renderGlyph(size_t aGlyphIndex, const Vec2f& aPosition) Vec2f TypeFace::renderGlyph(size_t aGlyphIndex, const Vec2f& aPosition)
{ {
CacheEntry& entry = cachedGlyph(aGlyphIndex); CacheEntry& entry = cachedGlyph(aGlyphIndex);
bindTexture(entry); bindTexture(entry);
skipping to change at line 571 skipping to change at line 573
glTexCoord2f( topLeftUV[0], bottomRightUV[1] ); glTexCoord2f( topLeftUV[0], bottomRightUV[1] );
glVertex2f( position[0], position[1] + glyphHeight ); glVertex2f( position[0], position[1] + glyphHeight );
} }
glEnd(); glEnd();
return entry.advance_; return entry.advance_;
} }
Vec2f TypeFace::kerning(size_t leftGlyphIndex, size_t rightGlyphIndex) cons t Vec2f TypeFace::kerning(size_t leftGlyphIndex, size_t rightGlyphIndex) cons t
{ {
Vec2f ret; Vec2f ret(0.f, 0.f);
if(data_->hasKerning_ && (leftGlyphIndex > 0) && (rightGlyphIndex > if (data_->hasKerning_ && (leftGlyphIndex > 0) && (rightGlyphIndex >
0)) 0))
{ {
FT_Vector kerningVector; FT_Vector kerningVector;
FT_Error ftError = FT_Get_Kerning(data_->face_, leftGlyphInd ex, FT_Error ftError = FT_Get_Kerning(data_->face_, leftGlyphInd ex,
rightGlyphIndex, FT_KERNIN G_DEFAULT, rightGlyphIndex, FT_KERNIN G_DEFAULT,
&kerningVector); &kerningVector);
if(!ftError) if (!ftError)
{ {
ret = Vec2f(static_cast<float>(kerningVector.x), ret.set(static_cast<float>(kerningVector.x)* OneOver
static_cast<float>(kerningVector.y)) * O 64, static_cast<float>(kerningVector.y)* OneOver64);
neOver64;
} }
} }
return ret; return ret;
} }
void TypeFace::bindTexture(const CacheEntry& aCacheEntry) const void TypeFace::bindTexture(const CacheEntry& aCacheEntry) const
{ {
assert(aCacheEntry.textureIndex_ < data_->textures_.size()); Q_ASSERT(aCacheEntry.textureIndex_ < data_->textures_.size());
const TextureInfo& info = data_->textures_[aCacheEntry.textureIndex_ ]; const TextureInfo& info = data_->textures_[aCacheEntry.textureIndex_ ];
GLint currentTextureID = -1; GLint currentTextureID = -1;
glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &currentTextureID); glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &currentTextureID);
if(static_cast<GLuint>(currentTextureID) != info.handle_) if(static_cast<GLuint>(currentTextureID) != info.handle_)
{ {
glBindTexture(GL_TEXTURE_2D, info.handle_); glBindTexture(GL_TEXTURE_2D, info.handle_);
} }
} }
void TypeFace::renderGlyphs(const QString& aString, bool useColorSwitch) void TypeFace::renderGlyphs(const QString& aString)
{ {
Vec2f vPos(0.0f, 0.0f); Vec2f vPos(0.0f, 0.0f);
size_t leftChar = 0; size_t leftChar = 0;
for(int pos=0; pos<aString.size(); pos++) for (int pos=0; pos<aString.size(); ++pos)
{ {
if (useColorSwitch)
{
// Manage color highlight here
if(aString.at(pos)==L'\21')
{
glColor3f(0.5,1,0.5); // normal
++pos;
continue;
}
if(aString.at(pos)==L'\22')
{
glColor3f(1,1,1); // hilight
++pos;
continue;
}
}
size_t rightChar = FT_Get_Char_Index(data_->face_, aString.a t(pos).unicode()); size_t rightChar = FT_Get_Char_Index(data_->face_, aString.a t(pos).unicode());
vPos += kerning(leftChar, rightChar); vPos += kerning(leftChar, rightChar);
vPos += renderGlyph(rightChar, vPos); vPos += renderGlyph(rightChar, vPos);
leftChar = rightChar; leftChar = rightChar;
} }
} }
 End of changes. 22 change blocks. 
39 lines changed or deleted 24 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/