From 82be4141b6a23a51b29a1d2ade545e0062e2058c Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 13 Oct 2017 15:52:51 +0300 Subject: [PATCH] 0029225: Visualization - Font_FTFont::AdvanceX() retrieves kerning value for incorrect characters pair Fixed FT_Get_Kerning misuse within Font_FTFont::AdvanceX()/Font_FTFont::AdvanceY(). Font_FTFont::loadGlyph() has been corrected to not return TRUE in case if method called with 0 argument second+ time. --- src/Font/Font_FTFont.cxx | 56 +++++++++++++++++++++++++--------------- src/Font/Font_FTFont.hxx | 32 +++++++++++++++-------- tests/3rdparty/fonts/B3 | 14 +++++----- 3 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx index 5542baa50f..6d97511532 100755 --- a/src/Font/Font_FTFont.cxx +++ b/src/Font/Font_FTFont.cxx @@ -35,7 +35,6 @@ Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib) myWidthScaling(1.0), myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL), myIsSingleLine(false), - myKernAdvance (new FT_Vector()), myUChar (0U) { if (myFTLib.IsNull()) @@ -51,7 +50,6 @@ Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib) Font_FTFont::~Font_FTFont() { Release(); - delete myKernAdvance; } // ======================================================================= @@ -136,7 +134,7 @@ bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar) { if (myUChar == theUChar) { - return true; + return myUChar != 0; } myGlyphImg.Clear(); @@ -239,8 +237,8 @@ float Font_FTFont::LineSpacing() const // function : AdvanceX // purpose : // ======================================================================= -float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar, - const Standard_Utf32Char theUCharNext) +float Font_FTFont::AdvanceX (Standard_Utf32Char theUChar, + Standard_Utf32Char theUCharNext) { loadGlyph (theUChar); return AdvanceX (theUCharNext); @@ -250,49 +248,65 @@ float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar, // function : AdvanceY // purpose : // ======================================================================= -float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar, - const Standard_Utf32Char theUCharNext) +float Font_FTFont::AdvanceY (Standard_Utf32Char theUChar, + Standard_Utf32Char theUCharNext) { loadGlyph (theUChar); return AdvanceY (theUCharNext); } +bool Font_FTFont::getKerning (FT_Vector& theKern, + Standard_Utf32Char theUCharCurr, + Standard_Utf32Char theUCharNext) const +{ + theKern.x = 0; + theKern.y = 0; + if (theUCharNext != 0 && FT_HAS_KERNING(myFTFace) != 0) + { + const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, theUCharCurr); + const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext); + if (aCharCurr == 0 || aCharNext == 0 + || FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0) + { + theKern.x = 0; + theKern.y = 0; + return false; + } + return true; + } + return false; +} + // ======================================================================= // function : AdvanceX // purpose : // ======================================================================= -float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext) +float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const { if (myUChar == 0) { return 0.0f; } - if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0 - || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0) - { - return myWidthScaling * fromFTPoints (myFTFace->glyph->advance.x); - } - return myWidthScaling * fromFTPoints (myKernAdvance->x + myFTFace->glyph->advance.x); + FT_Vector aKern; + getKerning (aKern, myUChar, theUCharNext); + return myWidthScaling * fromFTPoints (myFTFace->glyph->advance.x + aKern.x); } // ======================================================================= // function : AdvanceY // purpose : // ======================================================================= -float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext) +float Font_FTFont::AdvanceY (Standard_Utf32Char theUCharNext) const { if (myUChar == 0) { return 0.0f; } - if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0 - || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0) - { - return fromFTPoints (myFTFace->glyph->advance.y); - } - return fromFTPoints (myKernAdvance->y + myFTFace->glyph->advance.y); + FT_Vector aKern; + getKerning (aKern, myUChar, theUCharNext); + return fromFTPoints (myFTFace->glyph->advance.y + aKern.y); } // ======================================================================= diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx index 8409aad6fa..9ab1ece514 100755 --- a/src/Font/Font_FTFont.hxx +++ b/src/Font/Font_FTFont.hxx @@ -114,23 +114,29 @@ public: myWidthScaling = theScaleFactor; } - //! Compute advance to the next character with kerning applied when applicable. + //! Compute horizontal advance to the next character with kerning applied when applicable. //! Assuming text rendered horizontally. - Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext); + //! @param theUCharNext the next character to compute advance from current one + Standard_EXPORT float AdvanceX (Standard_Utf32Char theUCharNext) const; - //! Compute advance to the next character with kerning applied when applicable. + //! Compute horizontal advance to the next character with kerning applied when applicable. //! Assuming text rendered horizontally. - Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUChar, - const Standard_Utf32Char theUCharNext); + //! @param theUChar the character to be loaded as current one + //! @param theUCharNext the next character to compute advance from current one + Standard_EXPORT float AdvanceX (Standard_Utf32Char theUChar, + Standard_Utf32Char theUCharNext); - //! Compute advance to the next character with kerning applied when applicable. + //! Compute vertical advance to the next character with kerning applied when applicable. //! Assuming text rendered vertically. - Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUCharNext); + //! @param theUCharNext the next character to compute advance from current one + Standard_EXPORT float AdvanceY (Standard_Utf32Char theUCharNext) const; - //! Compute advance to the next character with kerning applied when applicable. + //! Compute vertical advance to the next character with kerning applied when applicable. //! Assuming text rendered vertically. - Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUChar, - const Standard_Utf32Char theUCharNext); + //! @param theUChar the character to be loaded as current one + //! @param theUCharNext the next character to compute advance from current one + Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar, + Standard_Utf32Char theUCharNext); //! @return glyphs number in this font. Standard_EXPORT Standard_Integer GlyphsNumber() const; @@ -166,6 +172,11 @@ protected: //! Load glyph without rendering it. Standard_EXPORT bool loadGlyph (const Standard_Utf32Char theUChar); + //! Wrapper for FT_Get_Kerning - retrieve kerning values. + Standard_EXPORT bool getKerning (FT_Vector& theKern, + Standard_Utf32Char theUCharCurr, + Standard_Utf32Char theUCharNext) const; + protected: Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object @@ -177,7 +188,6 @@ protected: bool myIsSingleLine; //!< single stroke font flag, FALSE by default Image_PixMap myGlyphImg; //!< cached glyph plane - FT_Vector* myKernAdvance; //!< buffer variable Standard_Utf32Char myUChar; //!< currently loaded unicode character public: diff --git a/tests/3rdparty/fonts/B3 b/tests/3rdparty/fonts/B3 index 6c3b9f999a..aa49521cd0 100644 --- a/tests/3rdparty/fonts/B3 +++ b/tests/3rdparty/fonts/B3 @@ -2,8 +2,7 @@ puts "============" puts "OCC24181 Render text as BRep (check alphabet)" puts "============" puts "" -pload MODELING -pload VISUALIZATION +pload MODELING VISUALIZATION vfont add [locate_data_file DejaVuSans.ttf] SansFont @@ -18,6 +17,7 @@ asdfghjkl;' ASDFGHJKL:" zxcvbnm,./ ZXCVBNM<>?§ +AVATAR Y. } text2brep aBTextN $THE_TEXT -font $THE_FONT_NAME -height $THE_FONT_SIZE -aspect regular -composite off @@ -26,12 +26,12 @@ checkshape aBTextN checkshape aBTextC ttranslate aBTextC 220 0 0 -vsetdispmode 1 -vtop -vdisplay aBTextN -vdisplay aBTextC +vclear +vinit View1 +vtop +vdisplay -dispMode 1 aBTextN aBTextC vfit vglinfo -checkview -screenshot -3d -path ${imagedir}/${test_image}.png +vdump ${imagedir}/${casename}.png