Skip to content

Commit

Permalink
getDimension no longer calculate character height every time anymore.…
Browse files Browse the repository at this point in the history
… Instead for a certain font of a certain size, the line height (at least the default line height) should be predetermined at the point of initializing/loading stage of the font. Also originally the calculation involved was using ascender info plus the most descended glyph as the total line height, but that value was actually not honored when drawing and outputing the whole text with newlines. It used only ascender data, and of course that will cause clutter at some point.
  • Loading branch information
arch-jslin committed Jul 17, 2014
1 parent 0b226e6 commit 56121a1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
48 changes: 28 additions & 20 deletions source/Irrlicht/CGUITTFont.cpp
Expand Up @@ -189,7 +189,7 @@ CGUITTFont* CGUITTFont::create(IGUIEnvironment *env, const io::path& filename, c
//! constructor
CGUITTFont::CGUITTFont(IGUIEnvironment *env)
: use_monochrome(false), use_transparency(true), use_hinting(true), use_auto_hinting(true),
batch_load_size(1), Environment(env), Driver(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
batch_load_size(1), Environment(env), Driver(0), GlobalKerningWidth(0), GlobalKerningHeight(0), supposed_line_height_(0)
{
#ifdef _DEBUG
setDebugName("CGUITTFont");
Expand Down Expand Up @@ -291,6 +291,24 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool& anti
getGlyphIndexByChar((uchar32_t)0);
batch_load_size = old_size;

// Calculate the supposed line height of this font (of this size) --
// Not using FT_SizeMetric::ascender or height, but actually by testing some of the glyphs,
// to see what should give a reasonable not cluttered line height.
// The ascender or height info may as well just be arbitrary ones.

// Get the maximum font height. Unfortunately, we have to do this hack as
// Irrlicht will draw things wrong. In FreeType, the font size is the
// maximum size for a single glyph, but that glyph may hang "under" the
// draw line, increasing the total font height to beyond the set size.
// Irrlicht does not understand this concept when drawing fonts. Also, I
// add +1 to give it a 1 pixel blank border. This makes things like
// tooltips look nicer.
s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1;
s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1;
s32 test3 = getHeightFromCharacter((uchar32_t)0x570B) + 1; // a chinese character here.

supposed_line_height_ = core::max_(test1, core::max_(test2, test3));

return true;
}

Expand Down Expand Up @@ -491,7 +509,7 @@ void CGUITTFont::draw(const core::stringw& text, const core::rect<s32>& position
if (lineBreak)
{
previousChar = 0;
offset.Y += font_metrics.ascender / 64;
offset.Y += supposed_line_height_;
offset.X = position.UpperLeftCorner.X;

if (hcenter)
Expand Down Expand Up @@ -550,20 +568,8 @@ core::dimension2d<u32> CGUITTFont::getDimension(const wchar_t* text) const

core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
{
// Get the maximum font height. Unfortunately, we have to do this hack as
// Irrlicht will draw things wrong. In FreeType, the font size is the
// maximum size for a single glyph, but that glyph may hang "under" the
// draw line, increasing the total font height to beyond the set size.
// Irrlicht does not understand this concept when drawing fonts. Also, I
// add +1 to give it a 1 pixel blank border. This makes things like
// tooltips look nicer.
s32 test1 = getHeightFromCharacter((uchar32_t)'g') + 1;
s32 test2 = getHeightFromCharacter((uchar32_t)'j') + 1;
s32 test3 = getHeightFromCharacter((uchar32_t)'_') + 1;
s32 max_font_height = core::max_(test1, core::max_(test2, test3));

core::dimension2d<u32> text_dimension(0, max_font_height);
core::dimension2d<u32> line(0, max_font_height);
core::dimension2d<u32> text_dimension(0, supposed_line_height_);
core::dimension2d<u32> line(0, supposed_line_height_);

uchar32_t previousChar = 0;
core::ustring::const_iterator iter = text.begin();
Expand Down Expand Up @@ -598,7 +604,7 @@ core::dimension2d<u32> CGUITTFont::getDimension(const core::ustring& text) const
if (text_dimension.Width < line.Width)
text_dimension.Width = line.Width;
line.Width = 0;
line.Height = max_font_height;
line.Height = supposed_line_height_;
continue;
}
line.Width += getWidthFromCharacter(p);
Expand Down Expand Up @@ -780,12 +786,13 @@ core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32
core::vector2di ret(GlobalKerningWidth, GlobalKerningHeight);

// If we don't have kerning, no point in continuing.
if (!FT_HAS_KERNING(tt_face))
if (!FT_HAS_KERNING(tt_face)) {
return ret;
}

// Get the kerning information.
FT_Vector v;
FT_Get_Kerning(tt_face, getGlyphIndexByChar(previousLetter), getGlyphIndexByChar(thisLetter), FT_KERNING_DEFAULT, &v);
FT_Get_Kerning(tt_face, getGlyphIndexByChar(previousLetter), getGlyphIndexByChar(thisLetter), FT_KERNING_UNFITTED, &v);

// If we have a scalable font, the return value will be in font points.
if (FT_IS_SCALABLE(tt_face))
Expand All @@ -800,6 +807,7 @@ core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32
ret.X += v.x;
ret.Y += v.y;
}

return ret;
}

Expand Down Expand Up @@ -973,7 +981,7 @@ core::array<scene::ISceneNode*> CGUITTFont::addTextSceneNode

if (line_break) {
previous_char = 0;
offset.Y -= tt_face->size->metrics.ascender / 64;
offset.Y -= supposed_line_height_;
offset.X = start_point.X;
if (center) {
offset.X += ( text_size.Width - getDimensionUntilEndOfLine(iter+1).Width ) >> 1;
Expand Down
1 change: 1 addition & 0 deletions source/Irrlicht/CGUITTFont.h
Expand Up @@ -368,6 +368,7 @@ class CGUITTFont : public IGUITTFont

s32 GlobalKerningWidth;
s32 GlobalKerningHeight;
s32 supposed_line_height_;
core::ustring Invisible;
};

Expand Down

0 comments on commit 56121a1

Please sign in to comment.