From ac5b3cbc0a167bcbbf2ba7f7b6500fdd7046d981 Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 25 Sep 2020 15:00:43 +0300 Subject: [PATCH] 0030911: Visualization - Font_BRepFont using as a usual Standard_Transient - StdPrs_BRepFont inherits Standard_Transient; - StdPrs_BRepFont contains Font_FTFont in internal field; - StdPrs_BRepFont implements FindAndCreate; --- src/Font/Font_FTFont.cxx | 14 ++++++ src/Font/Font_FTFont.hxx | 15 ++++++ src/StdPrs/StdPrs_BRepFont.cxx | 68 ++++++++++++++++++--------- src/StdPrs/StdPrs_BRepFont.hxx | 44 ++++++++++------- src/StdPrs/StdPrs_BRepTextBuilder.cxx | 2 +- 5 files changed, 103 insertions(+), 40 deletions(-) diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx index 9bce764bde..5464195e2a 100755 --- a/src/Font/Font_FTFont.cxx +++ b/src/Font/Font_FTFont.cxx @@ -607,3 +607,17 @@ Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theS aFormatter.BndBox (aBndBox); return aBndBox; } + +// ======================================================================= +// function : renderGlyphOutline +// purpose : +// ======================================================================= +const FT_Outline* Font_FTFont::renderGlyphOutline (const Standard_Utf32Char theChar) +{ + if (!loadGlyph (theChar) + || myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) + { + return 0; + } + return &myActiveFTFace->glyph->outline; +} diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx index b5755a3325..c3fad616c7 100755 --- a/src/Font/Font_FTFont.hxx +++ b/src/Font/Font_FTFont.hxx @@ -29,6 +29,7 @@ // forward declarations to avoid including of FreeType headers typedef struct FT_FaceRec_* FT_Face; typedef struct FT_Vector_ FT_Vector; +typedef struct FT_Outline_ FT_Outline; class Font_FTLibrary; //! Font initialization parameters. @@ -231,6 +232,12 @@ public: return myFontParams.PointSize; } + //! Return glyph scaling along X-axis. + float WidthScaling() const + { + return myWidthScaling; + } + //! Setup glyph scaling along X-axis. //! By default glyphs are not scaled (scaling factor = 1.0) void SetWidthScaling (const float theScaleFactor) @@ -279,6 +286,14 @@ public: const Graphic3d_HorizontalTextAlignment theAlignX, const Graphic3d_VerticalTextAlignment theAlignY); +public: + + //! Computes outline contour for the symbol. + //! @param theUChar [in] the character to be loaded as current one + //! @param theOutline [out] outline contour + //! @return true on success + Standard_EXPORT const FT_Outline* renderGlyphOutline(const Standard_Utf32Char theChar); + public: //! Initialize the font. diff --git a/src/StdPrs/StdPrs_BRepFont.cxx b/src/StdPrs/StdPrs_BRepFont.cxx index 203a0c1a47..bc752ac4e5 100644 --- a/src/StdPrs/StdPrs_BRepFont.cxx +++ b/src/StdPrs/StdPrs_BRepFont.cxx @@ -51,7 +51,7 @@ #include FT_FREETYPE_H #include FT_OUTLINE_H -IMPLEMENT_STANDARD_RTTIEXT(StdPrs_BRepFont, Font_FTFont) +IMPLEMENT_STANDARD_RTTIEXT(StdPrs_BRepFont, Standard_Transient) namespace { @@ -127,6 +127,7 @@ StdPrs_BRepFont::StdPrs_BRepFont () my3Poles (1, 3), my4Poles (1, 4) { + myFTFont = new Font_FTFont(); init(); } @@ -162,7 +163,8 @@ StdPrs_BRepFont::StdPrs_BRepFont (const NCollection_String& theFontPath, } myScaleUnits = getScale (theSize); - Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId); + myFTFont = new Font_FTFont(); + myFTFont->Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId); } // ======================================================================= @@ -186,7 +188,8 @@ StdPrs_BRepFont::StdPrs_BRepFont (const NCollection_String& theFontName, } myScaleUnits = getScale (theSize); - Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel); + myFTFont = new Font_FTFont(); + myFTFont->FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel); } // ======================================================================= @@ -196,7 +199,24 @@ StdPrs_BRepFont::StdPrs_BRepFont (const NCollection_String& theFontName, void StdPrs_BRepFont::Release() { myCache.Clear(); - Font_FTFont::Release(); + myFTFont->Release(); +} + +// ======================================================================= +// function : FindAndCreate +// purpose : +// ======================================================================= +Handle(StdPrs_BRepFont) StdPrs_BRepFont::FindAndCreate (const TCollection_AsciiString& theFontName, + const Font_FontAspect theFontAspect, + const Standard_Real theSize, + const Font_StrictLevel theStrictLevel) +{ + Handle(StdPrs_BRepFont) aFont = new StdPrs_BRepFont(); + + if (aFont->FindAndInit (theFontName, theFontAspect, theSize, theStrictLevel)) + return aFont; + + return Handle(StdPrs_BRepFont)(); } // ======================================================================= @@ -226,7 +246,8 @@ bool StdPrs_BRepFont::Init (const NCollection_String& theFontPath, } myScaleUnits = getScale (theSize); - return Font_FTFont::Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId); + myCache.Clear(); + return myFTFont->Init (theFontPath.ToCString(), THE_FONT_PARAMS, theFaceId); } // ======================================================================= @@ -244,7 +265,8 @@ bool StdPrs_BRepFont::FindAndInit (const TCollection_AsciiString& theFontName, } myScaleUnits = getScale (theSize); - return Font_FTFont::FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel); + myCache.Clear(); + return myFTFont->FindAndInit (theFontName.ToCString(), theFontAspect, THE_FONT_PARAMS, theStrictLevel); } // ======================================================================= @@ -407,8 +429,9 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, TopoDS_Shape& theShape) { theShape.Nullify(); - if (!loadGlyph (theChar) - || myActiveFTFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) + + const FT_Outline* anOutline = myFTFont->renderGlyphOutline (theChar); + if (!anOutline) { return Standard_False; } @@ -417,8 +440,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, return !theShape.IsNull(); } - const FT_Outline& anOutline = myActiveFTFace->glyph->outline; - if (!anOutline.n_contours) + if (!anOutline->n_contours) return Standard_False; TopLoc_Location aLoc; @@ -428,14 +450,14 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, // Get orientation is useless since it doesn't retrieve any in-font information and just computes orientation. // Because it fails in some cases - leave this to ShapeFix. //const FT_Orientation anOrient = FT_Outline_Get_Orientation (&anOutline); - for (short aContour = 0, aStartIndex = 0; aContour < anOutline.n_contours; ++aContour) + for (short aContour = 0, aStartIndex = 0; aContour < anOutline->n_contours; ++aContour) { - const FT_Vector* aPntList = &anOutline.points[aStartIndex]; - const char* aTags = &anOutline.tags[aStartIndex]; - const short anEndIndex = anOutline.contours[aContour]; + const FT_Vector* aPntList = &anOutline->points[aStartIndex]; + const char* aTags = &anOutline->tags[aStartIndex]; + const short anEndIndex = anOutline->contours[aContour]; const short aPntsNb = (anEndIndex - aStartIndex) + 1; aStartIndex = anEndIndex + 1; - if (aPntsNb < 3 && !myFontParams.IsSingleStrokeFont) + if (aPntsNb < 3 && !myFTFont->IsSingleStrokeFont()) { // closed contour can not be constructed from < 3 points continue; @@ -444,10 +466,10 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, BRepBuilderAPI_MakeWire aWireMaker; gp_XY aPntPrev; - gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling); - gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling); + gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myFTFont->WidthScaling()); + gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myFTFont->WidthScaling()); - bool isLineSeg = !myFontParams.IsSingleStrokeFont + bool isLineSeg = !myFTFont->IsSingleStrokeFont() && FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On; gp_XY aPntLine1 = aPntCurr; @@ -457,7 +479,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, { aPntPrev = aPntCurr; aPntCurr = aPntNext; - aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling); + aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myFTFont->WidthScaling()); // process tags if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On) @@ -541,7 +563,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, my4Poles.SetValue (1, aPntPrev); my4Poles.SetValue (2, aPntCurr); my4Poles.SetValue (3, aPntNext); - my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling))); + my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myFTFont->WidthScaling()))); Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles); if (myIsCompositeCurve) { @@ -570,7 +592,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint(); const gp_Pnt2d aLastPnt = aDraft2d->EndPoint(); - if (!myFontParams.IsSingleStrokeFont + if (!myFTFont->IsSingleStrokeFont() && !aFirstPnt.IsEqual (aLastPnt, myPrecision)) { Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt); @@ -598,7 +620,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV); gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV); gp_Pnt aLastPoint = BRep_Tool::Pnt (aLastV); - if (!myFontParams.IsSingleStrokeFont + if (!myFTFont->IsSingleStrokeFont() && !aFirstPoint.IsEqual (aLastPoint, myPrecision)) { aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV)); @@ -611,7 +633,7 @@ Standard_Boolean StdPrs_BRepFont::renderGlyph (const Standard_Utf32Char theChar, } TopoDS_Wire aWireDraft = aWireMaker.Wire(); - if (!myFontParams.IsSingleStrokeFont) + if (!myFTFont->IsSingleStrokeFont()) { // collect all wires and set CCW orientation TopoDS_Face aFace; diff --git a/src/StdPrs/StdPrs_BRepFont.hxx b/src/StdPrs/StdPrs_BRepFont.hxx index 4ed96b4717..e59a21ed96 100644 --- a/src/StdPrs/StdPrs_BRepFont.hxx +++ b/src/StdPrs/StdPrs_BRepFont.hxx @@ -32,7 +32,7 @@ #include #include -DEFINE_STANDARD_HANDLE(StdPrs_BRepFont, Font_FTFont) +DEFINE_STANDARD_HANDLE(StdPrs_BRepFont, Standard_Transient) //! This tool provides basic services for rendering of vectorized text glyphs as BRep shapes. //! Single instance initialize single font for sequential glyphs rendering with implicit caching of already rendered glyphs. @@ -41,11 +41,22 @@ DEFINE_STANDARD_HANDLE(StdPrs_BRepFont, Font_FTFont) //! Please notice that this implementation uses mutex for thread-safety access, //! thus may lead to performance penalties in case of concurrent access. //! Although caching should eliminate this issue after rendering of sufficient number of glyphs. -class StdPrs_BRepFont : protected Font_FTFont +class StdPrs_BRepFont : public Standard_Transient { - DEFINE_STANDARD_RTTIEXT(StdPrs_BRepFont, Font_FTFont) + DEFINE_STANDARD_RTTIEXT(StdPrs_BRepFont, Standard_Transient) public: + //! Find the font Initialize the font. + //! @param theFontName the font name + //! @param theFontAspect the font style + //! @param theSize the face size in model units + //! @param theStrictLevel search strict level for using aliases and fallback + //! @return true on success + Standard_EXPORT static Handle(StdPrs_BRepFont) FindAndCreate (const TCollection_AsciiString& theFontName, + const Font_FontAspect theFontAspect, + const Standard_Real theSize, + const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any); + //! Empty constructor Standard_EXPORT StdPrs_BRepFont(); @@ -68,7 +79,7 @@ public: const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any); //! Release currently loaded font. - Standard_EXPORT virtual void Release() Standard_OVERRIDE; + Standard_EXPORT virtual void Release(); //! Initialize the font. //! @param theFontPath FULL path to the font @@ -94,6 +105,9 @@ public: const Standard_Real theSize, const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any); + //! Return wrapper over FreeType font. + const Handle(Font_FTFont)& FTFont() const { return myFTFont; } + //! Render single glyph as TopoDS_Shape. //! @param theChar glyph identifier //! @return rendered glyph within cache, might be NULL shape @@ -111,7 +125,7 @@ public: //! By default glyphs are not scaled (scaling factor = 1.0) void SetWidthScaling (const float theScaleFactor) { - myWidthScaling = theScaleFactor; + myFTFont->SetWidthScaling (theScaleFactor); } public: @@ -119,32 +133,32 @@ public: //! @return vertical distance from the horizontal baseline to the highest character coordinate. Standard_Real Ascender() const { - return myScaleUnits * Standard_Real(Font_FTFont::Ascender()); + return myScaleUnits * Standard_Real(myFTFont->Ascender()); } //! @return vertical distance from the horizontal baseline to the lowest character coordinate. Standard_Real Descender() const { - return myScaleUnits * Standard_Real(Font_FTFont::Descender()); + return myScaleUnits * Standard_Real(myFTFont->Descender()); } //! @return default line spacing (the baseline-to-baseline distance). Standard_Real LineSpacing() const { - return myScaleUnits * Standard_Real(Font_FTFont::LineSpacing()); + return myScaleUnits * Standard_Real(myFTFont->LineSpacing()); } //! Configured point size Standard_Real PointSize() const { - return myScaleUnits * Standard_Real(Font_FTFont::PointSize()); + return myScaleUnits * Standard_Real(myFTFont->PointSize()); } //! Compute advance to the next character with kerning applied when applicable. //! Assuming text rendered horizontally. Standard_Real AdvanceX (const Standard_Utf32Char theUCharNext) { - return myScaleUnits * Standard_Real(Font_FTFont::AdvanceX (theUCharNext)); + return myScaleUnits * Standard_Real(myFTFont->AdvanceX (theUCharNext)); } //! Compute advance to the next character with kerning applied when applicable. @@ -152,14 +166,14 @@ public: Standard_Real AdvanceX (const Standard_Utf32Char theUChar, const Standard_Utf32Char theUCharNext) { - return myScaleUnits * Standard_Real(Font_FTFont::AdvanceX (theUChar, theUCharNext)); + return myScaleUnits * Standard_Real(myFTFont->AdvanceX (theUChar, theUCharNext)); } //! Compute advance to the next character with kerning applied when applicable. //! Assuming text rendered vertically. Standard_Real AdvanceY (const Standard_Utf32Char theUCharNext) { - return myScaleUnits * Standard_Real(Font_FTFont::AdvanceY (theUCharNext)); + return myScaleUnits * Standard_Real(myFTFont->AdvanceY (theUCharNext)); } //! Compute advance to the next character with kerning applied when applicable. @@ -167,7 +181,7 @@ public: Standard_Real AdvanceY (const Standard_Utf32Char theUChar, const Standard_Utf32Char theUCharNext) { - return myScaleUnits * Standard_Real(Font_FTFont::AdvanceY (theUChar, theUCharNext)); + return myScaleUnits * Standard_Real(myFTFont->AdvanceY (theUChar, theUCharNext)); } //! Returns scaling factor for current font size. @@ -217,11 +231,9 @@ private: Standard_Boolean buildFaces (const NCollection_Sequence& theWires, TopoDS_Shape& theRes); - //! Hide visibility. - using Font_FTFont::FindAndCreate; - protected: //! @name Protected fields + Handle(Font_FTFont) myFTFont; //!< wrapper over FreeType font NCollection_DataMap myCache; //!< glyphs cache Standard_Mutex myMutex; //!< lock for thread-safety diff --git a/src/StdPrs/StdPrs_BRepTextBuilder.cxx b/src/StdPrs/StdPrs_BRepTextBuilder.cxx index 2554414a62..9facb1d7f6 100644 --- a/src/StdPrs/StdPrs_BRepTextBuilder.cxx +++ b/src/StdPrs/StdPrs_BRepTextBuilder.cxx @@ -70,7 +70,7 @@ TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& aFormatter->Reset(); aFormatter->SetupAlignment (theHAlign, theVAlign); - aFormatter->Append (theString, *(reinterpret_cast (&theFont))); + aFormatter->Append (theString, *theFont.FTFont()); aFormatter->Format(); return Perform (theFont, aFormatter, thePenLoc);