From 56121a167cacf1131182616b6d9a41ce825f9402 Mon Sep 17 00:00:00 2001 From: Johnson Lin Date: Fri, 18 Jul 2014 00:25:54 +0800 Subject: [PATCH] getDimension no longer calculate character height every time anymore. 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. --- source/Irrlicht/CGUITTFont.cpp | 48 ++++++++++++++++++++-------------- source/Irrlicht/CGUITTFont.h | 1 + 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/source/Irrlicht/CGUITTFont.cpp b/source/Irrlicht/CGUITTFont.cpp index ca3ac1ef..76fa6906 100644 --- a/source/Irrlicht/CGUITTFont.cpp +++ b/source/Irrlicht/CGUITTFont.cpp @@ -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"); @@ -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; } @@ -491,7 +509,7 @@ void CGUITTFont::draw(const core::stringw& text, const core::rect& position if (lineBreak) { previousChar = 0; - offset.Y += font_metrics.ascender / 64; + offset.Y += supposed_line_height_; offset.X = position.UpperLeftCorner.X; if (hcenter) @@ -550,20 +568,8 @@ core::dimension2d CGUITTFont::getDimension(const wchar_t* text) const core::dimension2d 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 text_dimension(0, max_font_height); - core::dimension2d line(0, max_font_height); + core::dimension2d text_dimension(0, supposed_line_height_); + core::dimension2d line(0, supposed_line_height_); uchar32_t previousChar = 0; core::ustring::const_iterator iter = text.begin(); @@ -598,7 +604,7 @@ core::dimension2d 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); @@ -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)) @@ -800,6 +807,7 @@ core::vector2di CGUITTFont::getKerning(const uchar32_t thisLetter, const uchar32 ret.X += v.x; ret.Y += v.y; } + return ret; } @@ -973,7 +981,7 @@ core::array 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; diff --git a/source/Irrlicht/CGUITTFont.h b/source/Irrlicht/CGUITTFont.h index 01071234..a978dc38 100644 --- a/source/Irrlicht/CGUITTFont.h +++ b/source/Irrlicht/CGUITTFont.h @@ -368,6 +368,7 @@ class CGUITTFont : public IGUITTFont s32 GlobalKerningWidth; s32 GlobalKerningHeight; + s32 supposed_line_height_; core::ustring Invisible; };