From: kgv Date: Thu, 23 Jul 2020 19:39:27 +0000 (+0300) Subject: 0031678: Visualization - add option enabling hinting for textured fonts X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=bf96ef6b06ff6b75a21a4233bcf2dfa0049269ce;p=occt-copy.git 0031678: Visualization - add option enabling hinting for textured fonts Added new rendering parameter Graphic3d_RenderingParams::ToEnableFontHinting allowing to enable/disable hinting (default is no hinting preserving old behavior). Command vrenderparams has been extended with arguments -fontHinting. (cherry picked from commit 16b905d142dfc4b3a801348b6cdf98f5d812a486) --- diff --git a/src/AIS/AIS_TextLabel.cxx b/src/AIS/AIS_TextLabel.cxx index 8344e85da0..5e4cc873a3 100644 --- a/src/AIS/AIS_TextLabel.cxx +++ b/src/AIS/AIS_TextLabel.cxx @@ -404,9 +404,11 @@ Standard_Boolean AIS_TextLabel::calculateLabelParams (const gp_Pnt& thePosition, { // Get width and height of text Handle(Prs3d_TextAspect) anAsp = myDrawer->TextAspect(); + const Graphic3d_RenderingParams& aRendParams = GetContext()->CurrentViewer()->DefaultRenderingParams(); Font_FTFontParams aFontParams; aFontParams.PointSize = (unsigned int) anAsp->Height(); - aFontParams.Resolution = GetContext()->CurrentViewer()->DefaultRenderingParams().Resolution; + aFontParams.Resolution = aRendParams.Resolution; + aFontParams.ToEnableFontHinting = aRendParams.ToEnableFontHinting; Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (anAsp->Aspect()->Font(), anAsp->Aspect()->GetTextFontAspect(), diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx index 7e4ecbe95a..7cafbe06bb 100755 --- a/src/Font/Font_FTFont.cxx +++ b/src/Font/Font_FTFont.cxx @@ -88,6 +88,15 @@ bool Font_FTFont::Init (const Handle(NCollection_Buffer)& theData, myBuffer = theData; myFontPath = theFileName; myFontParams = theParams; + if (theParams.ToEnableFontHinting) + { + myLoadFlags &= ~FT_LOAD_NO_HINTING; + } + else + { + myLoadFlags |= FT_LOAD_NO_HINTING; + } + if (!myFTLib->IsValid()) { Message::SendTrace ("FreeType library is unavailable"); diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx index c3fad616c7..575de31ae4 100755 --- a/src/Font/Font_FTFont.hxx +++ b/src/Font/Font_FTFont.hxx @@ -37,16 +37,26 @@ struct Font_FTFontParams { unsigned int PointSize; //!< face size in points (1/72 inch) unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size() + bool ToEnableFontHinting; //!< request hinting (exclude FT_LOAD_NO_HINTING flag), FALSE by default; + //! hinting improves readability of thin text on low-resolution screen, + //! but adds distortions to original font depending on font family and font library version bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default //! Empty constructor. - Font_FTFontParams() : PointSize (0), Resolution (72u), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {} + Font_FTFontParams() + : PointSize (0), Resolution (72u), + ToEnableFontHinting(false), + ToSynthesizeItalic (false), + IsSingleStrokeFont (false) {} //! Constructor. Font_FTFontParams (unsigned int thePointSize, unsigned int theResolution) - : PointSize (thePointSize), Resolution (theResolution), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {} + : PointSize (thePointSize), Resolution (theResolution), + ToEnableFontHinting(false), + ToSynthesizeItalic (false), + IsSingleStrokeFont (false) {} }; DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient) diff --git a/src/Graphic3d/Graphic3d_RenderingParams.hxx b/src/Graphic3d/Graphic3d_RenderingParams.hxx index 472311ff16..16e5c330fc 100644 --- a/src/Graphic3d/Graphic3d_RenderingParams.hxx +++ b/src/Graphic3d/Graphic3d_RenderingParams.hxx @@ -106,6 +106,7 @@ public: OitDepthFactor (0.0f), NbMsaaSamples (0), RenderResolutionScale (1.0f), + ToEnableFontHinting (Standard_False), ToEnableDepthPrepass (Standard_False), ToEnableAlphaToCoverage (Standard_True), // ray tracing parameters @@ -199,6 +200,9 @@ public: Standard_Integer NbMsaaSamples; //!< number of MSAA samples (should be within 0..GL_MAX_SAMPLES, power-of-two number), 0 by default Standard_ShortReal RenderResolutionScale; //!< rendering resolution scale factor, 1 by default; //! incompatible with MSAA (e.g. NbMsaaSamples should be set to 0) + Standard_Boolean ToEnableFontHinting; //!< enables/disables text hinting within textured fonts, False by default; + //! hinting improves readability of thin text on low-resolution screen, + //! but adds distortions to original font depending on font family and font library version Standard_Boolean ToEnableDepthPrepass; //!< enables/disables depth pre-pass, False by default Standard_Boolean ToEnableAlphaToCoverage; //!< enables/disables alpha to coverage, True by default diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 71b7796344..14125980d8 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -527,7 +527,9 @@ void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView, OpenGl_Aspects aTextAspect; TCollection_ExtendedString anExtText = theText; NCollection_String aText (anExtText.ToExtString()); - OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aHeight, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent); + OpenGl_Text::StringSize (aCtx, aText, aTextAspect, aHeight, + theView->RenderingParams().Resolution, theView->RenderingParams().ToEnableFontHinting, + theWidth, theAscent, theDescent); } //======================================================================= diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index 09c63975d1..abeb57df47 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -262,6 +262,7 @@ void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theTextAspect, const Standard_ShortReal theHeight, const unsigned int theResolution, + const bool theToEnableFontHinting, Standard_ShortReal& theWidth, Standard_ShortReal& theAscent, Standard_ShortReal& theDescent) @@ -269,8 +270,8 @@ void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx, theWidth = 0.0f; theAscent = 0.0f; theDescent = 0.0f; - const TCollection_AsciiString aFontKey = FontKey (theTextAspect, (Standard_Integer)theHeight, theResolution); - Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, (Standard_Integer)theHeight, theResolution, aFontKey); + const TCollection_AsciiString aFontKey = FontKey (theTextAspect, (Standard_Integer)theHeight, theResolution, theToEnableFontHinting); + Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, (Standard_Integer)theHeight, theResolution, theToEnableFontHinting, aFontKey); if (aFont.IsNull() || !aFont->IsValid()) { return; @@ -348,7 +349,8 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const *aTextAspect, theWorkspace->TextColor(), theWorkspace->TextSubtitleColor(), - aCtx->Resolution()); + aCtx->Resolution(), + theWorkspace->View()->RenderingParams().ToEnableFontHinting); // restore aspects if (!aPrevTexture.IsNull()) @@ -369,7 +371,8 @@ void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const // ======================================================================= void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theTextAspect, - unsigned int theResolution) const + unsigned int theResolution, + bool theToEnableFontHinting) const { #if !defined(GL_ES_VERSION_2_0) const Standard_Integer aPrevPolygonMode = theCtx->SetPolygonMode (GL_FILL); @@ -379,7 +382,8 @@ void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx, render (theCtx, theTextAspect, theTextAspect.Aspect()->ColorRGBA(), theTextAspect.Aspect()->ColorSubTitleRGBA(), - theResolution); + theResolution, + theToEnableFontHinting); #if !defined(GL_ES_VERSION_2_0) theCtx->SetPolygonMode (aPrevPolygonMode); @@ -535,7 +539,8 @@ void OpenGl_Text::drawText (const Handle(OpenGl_Context)& theCtx, // ======================================================================= TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_Aspects& theAspect, Standard_Integer theHeight, - unsigned int theResolution) + unsigned int theResolution, + bool theToEnableFontHinting) { const Font_FontAspect anAspect = theAspect.Aspect()->TextFontAspect() != Font_FA_Undefined ? theAspect.Aspect()->TextFontAspect() @@ -544,7 +549,8 @@ TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_Aspects& theAspect, return aFont + TCollection_AsciiString(":") + Standard_Integer(anAspect) + TCollection_AsciiString(":") + Standard_Integer(theResolution) - + TCollection_AsciiString(":") + theHeight; + + TCollection_AsciiString(":") + theHeight + + (theToEnableFontHinting ? ":h" : ""); } // ======================================================================= @@ -555,6 +561,7 @@ Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theAspect, Standard_Integer theHeight, unsigned int theResolution, + bool theToEnableFontHinting, const TCollection_AsciiString& theKey) { Handle(OpenGl_Font) aFont; @@ -575,6 +582,7 @@ Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx, Font_FTFontParams aParams; aParams.PointSize = theHeight; aParams.Resolution = theResolution; + aParams.ToEnableFontHinting = theToEnableFontHinting; if (Handle(Font_FTFont) aFontFt = Font_FTFont::FindAndCreate (aFontName, anAspect, aParams, Font_StrictLevel_Any)) { aFont = new OpenGl_Font (aFontFt, theKey); @@ -658,7 +666,8 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theTextAspect, const OpenGl_Vec4& theColorText, const OpenGl_Vec4& theColorSubs, - unsigned int theResolution) const + unsigned int theResolution, + bool theToEnableFontHinting) const { if (myText->Text().IsEmpty() && myText->TextFormatter().IsNull()) { @@ -667,7 +676,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, // Note that using difference resolution in different Views in same Viewer // will lead to performance regression (for example, text will be recreated every time). - const TCollection_AsciiString aFontKey = FontKey (theTextAspect, (Standard_Integer)myText->Height(), theResolution); + const TCollection_AsciiString aFontKey = FontKey (theTextAspect, (Standard_Integer)myText->Height(), theResolution, theToEnableFontHinting); if (!myFont.IsNull() && !myFont->ResourceKey().IsEqual (aFontKey)) { @@ -677,7 +686,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx, if (myFont.IsNull()) { - myFont = FindFont (theCtx, theTextAspect, (Standard_Integer)myText->Height(), theResolution, aFontKey); + myFont = FindFont (theCtx, theTextAspect, (Standard_Integer)myText->Height(), theResolution, theToEnableFontHinting, aFontKey); } if (!myFont->WasInitialized()) { diff --git a/src/OpenGl/OpenGl_Text.hxx b/src/OpenGl/OpenGl_Text.hxx index 5d8ac6f7d5..4ba7377d77 100755 --- a/src/OpenGl/OpenGl_Text.hxx +++ b/src/OpenGl/OpenGl_Text.hxx @@ -83,13 +83,15 @@ public: //! @name methods for compatibility with layers //! Create key for shared resource Standard_EXPORT static TCollection_AsciiString FontKey (const OpenGl_Aspects& theAspect, Standard_Integer theHeight, - unsigned int theResolution); + unsigned int theResolution, + bool theToEnableFontHinting); //! Find shared resource for specified font or initialize new one Standard_EXPORT static Handle(OpenGl_Font) FindFont (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theAspect, Standard_Integer theHeight, unsigned int theResolution, + bool theToEnableFontHinting, const TCollection_AsciiString& theKey); //! Compute text width @@ -98,6 +100,7 @@ public: //! @name methods for compatibility with layers const OpenGl_Aspects& theTextAspect, const Standard_ShortReal theHeight, const unsigned int theResolution, + const bool theToEnableFontHinting, Standard_ShortReal& theWidth, Standard_ShortReal& theAscent, Standard_ShortReal& theDescent); @@ -105,7 +108,8 @@ public: //! @name methods for compatibility with layers //! Perform rendering Standard_EXPORT void Render (const Handle(OpenGl_Context)& theCtx, const OpenGl_Aspects& theTextAspect, - unsigned int theResolution = Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION) const; + unsigned int theResolution = Graphic3d_RenderingParams::THE_DEFAULT_RESOLUTION, + bool theToEnableFontHinting = false) const; //! Dumps the content of me into the stream Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE; @@ -152,7 +156,8 @@ private: const OpenGl_Aspects& theTextAspect, const OpenGl_Vec4& theColorText, const OpenGl_Vec4& theColorSubs, - unsigned int theResolution) const; + unsigned int theResolution, + bool theToEnableFontHinting) const; protected: diff --git a/src/PrsDim/PrsDim_Dimension.cxx b/src/PrsDim/PrsDim_Dimension.cxx index 9ccb1395d5..1824ed34a1 100644 --- a/src/PrsDim/PrsDim_Dimension.cxx +++ b/src/PrsDim/PrsDim_Dimension.cxx @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +84,6 @@ namespace // default text margin and resolution static const Standard_Real THE_3D_TEXT_MARGIN = 0.1; - static const unsigned int THE_2D_TEXT_RESOLUTION = 72; // default selection priorities static const Standard_Integer THE_NEUTRAL_SEL_PRIORITY = 5; @@ -329,9 +330,14 @@ TCollection_ExtendedString PrsDim_Dimension::GetValueString (Standard_Real& theW { // Text width for 1:1 scale 2D case Font_FTFontParams aFontParams; + const Graphic3d_RenderingParams& aRendParams = GetContext()->CurrentViewer()->DefaultRenderingParams(); aFontParams.PointSize = (unsigned int )aTextAspect->Height(); - aFontParams.Resolution = THE_2D_TEXT_RESOLUTION; - if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (aTextAspect->Aspect()->Font(), aTextAspect->Aspect()->GetTextFontAspect(), aFontParams, Font_StrictLevel_Any)) + aFontParams.Resolution = aRendParams.Resolution; + aFontParams.ToEnableFontHinting = aRendParams.ToEnableFontHinting; + if (Handle(Font_FTFont) aFont = Font_FTFont::FindAndCreate (aTextAspect->Aspect()->Font(), + aTextAspect->Aspect()->GetTextFontAspect(), + aFontParams, + Font_StrictLevel_Any)) { for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; ) { diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index bfb5356615..7617c536f7 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -12016,6 +12016,21 @@ static Standard_Integer VRenderParams (Draw_Interpretor& theDI, return 1; } } + else if (aFlag == "-fonthinting" + || aFlag == "-fonthint") + { + if (toPrint) + { + theDI << (aParams.ToEnableFontHinting ? "on " : "off "); + continue; + } + aParams.ToEnableFontHinting = true; + if (anArgIter + 1 < theArgNb + && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], aParams.ToEnableFontHinting)) + { + ++anArgIter; + } + } else if (aFlag == "-depthprepass") { if (toPrint) @@ -15085,7 +15100,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n\t\t: Common parameters:" "\n\t\t: vrenderparams [-raster] [-shadingModel {unlit|facet|gouraud|phong|pbr|pbr_facet}=gouraud]" "\n\t\t: [-msaa 0..8=0] [-rendScale scale=1] [-resolution value=72]" - "\n\t\t: [-oit {off|0.0-1.0}=off]" + "\n\t\t: [-oit {off|0.0-1.0}=off] [-fontHinting {on|off}=off]" "\n\t\t: [-depthPrePass {on|off}=off] [-alphaToCoverage {on|off}=on]" "\n\t\t: [-frustumCulling {on|off|noupdate}=on] [-lineFeather width=1.0]" "\n\t\t: [-sync {default|views}] [-reset]" @@ -15099,6 +15114,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) "\n\t\t: -oit Enables/disables order-independent transparency (OIT) rendering;" "\n\t\t: weight OIT fixes transparency artifacts at the cost of blurry result," "\n\t\t: it is managed by depth weight factor (0.0 value also enables weight OIT)." + "\n\t\t: -fontHinting Enables/disables font hinting for better readability on low-resolution screens." "\n\t\t: -depthPrePass Enables/disables depth pre-pass." "\n\t\t: -frustumCulling Enables/disables objects frustum clipping or" "\n\t\t: sets state to check structures culled previously." diff --git a/tests/3rdparty/fonts/A2 b/tests/3rdparty/fonts/A2 index 3081622fa2..cd16863400 100755 --- a/tests/3rdparty/fonts/A2 +++ b/tests/3rdparty/fonts/A2 @@ -1,6 +1,5 @@ puts "============" -puts "OCC21091" -puts "OCC21450" +puts "0024387: Draw the text with different fonts" puts "============" puts "" @@ -61,12 +60,22 @@ vdrawtext OC16 OpenCascade -pos -100 -300 -100 -color GREEN -halign left -valign vdrawtext OC17 OpenCascade -pos -200 -200 100 -color MAGENTA -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font sans-serif vdrawtext OC18 OpenCascade -pos -200 -200 150 -color CYAN -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font serif -vdrawtext OC19 OpenCascade -pos -200 -200 200 -color YELLOW -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font serif -vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 00FF05 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font monospace -vdrawtext OC21 OpenCascade -pos -200 -200 300 -color FF0005 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font monospace +vdrawtext OC19 OpenCascade -pos -200 -200 200 -color YELLOW -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect italic -font serif +vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 00FF05 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect bolditalic -font monospace +vdrawtext OC21 OpenCascade -pos -200 -200 300 -color FF0005 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font monospace vglinfo -checkview -screenshot -3d -path ${imagedir}/${test_image}.png +vrenderparams -fontHinting 1 +vbackground -color WHITE +vdump ${imagedir}/${test_image}_white_hinted.png +vbackground -color BLACK +vdump ${imagedir}/${test_image}_hinted.png + +vrenderparams -fontHinting 0 +vbackground -color WHITE +vdump ${imagedir}/${test_image}_white.png +vbackground -color BLACK +vdump ${imagedir}/${test_image}.png vsensdis -checkview -screenshot -3d -path ${imagedir}/${test_image}_sensitive.png \ No newline at end of file +vdump ${imagedir}/${test_image}_sensitive.png diff --git a/tests/3rdparty/fonts/A8 b/tests/3rdparty/fonts/A8 index f28d7fb125..c8645f173f 100644 --- a/tests/3rdparty/fonts/A8 +++ b/tests/3rdparty/fonts/A8 @@ -1,10 +1,7 @@ puts "============" -puts "OCC24387" +puts "0021091: Draw the text with different fonts" puts "============" puts "" -################################################# -# Draw the text with different fonts. -################################################# dtracelevel trace vfont -verbose 1 @@ -64,4 +61,14 @@ vdrawtext OC20 OpenCascade -pos -200 -200 250 -color 00FF05 -halign left -valig vdrawtext OC21 OpenCascade -pos -200 -200 300 -color FF0005 -halign left -valign bottom -angle 010 -zoom 0 -height 15 -aspect regular -font Arial vglinfo -checkview -screenshot -3d -path ${imagedir}/${test_image}.png +vrenderparams -fontHinting 1 +vbackground -color WHITE +vdump ${imagedir}/${test_image}_white_hinted.png +vbackground -color BLACK +vdump ${imagedir}/${test_image}_hinted.png + +vrenderparams -fontHinting 0 +vbackground -color WHITE +vdump ${imagedir}/${test_image}_white.png +vbackground -color BLACK +vdump ${imagedir}/${test_image}.png