mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0030537: Visualization - wrapping text in font text formatter
Font_TextFormatter inherits Standard_Transient, now it is given as a handle in functions. Graphic3d_Text - extended with Font_TextFormatter to be able to have it filled out of text render. If it is not defined here, the default text formatter of context is used. OpenGl_Context - has default Font_TextFormatter for rendering OpenGl_Text. AIS_TextLabel extending with Font_TextFormatter to prepare test case for text wrapping. Prs3d_Text returns created graphic text to be able to manage it outside.
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include <Font_Rect.hxx>
|
#include <Font_Rect.hxx>
|
||||||
#include <Graphic3d_AspectText3d.hxx>
|
#include <Graphic3d_AspectText3d.hxx>
|
||||||
#include <Graphic3d_RenderingParams.hxx>
|
#include <Graphic3d_RenderingParams.hxx>
|
||||||
|
#include <Graphic3d_Text.hxx>
|
||||||
|
|
||||||
#include <Prs3d_Text.hxx>
|
#include <Prs3d_Text.hxx>
|
||||||
#include <Prs3d_TextAspect.hxx>
|
#include <Prs3d_TextAspect.hxx>
|
||||||
@@ -308,7 +309,9 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
|
|||||||
{
|
{
|
||||||
aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
|
aHasOwnAnchor = Standard_False; // always not using own anchor if flipping
|
||||||
}
|
}
|
||||||
Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, anOrientation, aHasOwnAnchor);
|
Handle(Graphic3d_Text) aText =
|
||||||
|
Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, anOrientation, aHasOwnAnchor);
|
||||||
|
aText->SetTextFormatter (myFormatter);
|
||||||
if (myHasFlipping && isInit)
|
if (myHasFlipping && isInit)
|
||||||
{
|
{
|
||||||
thePrs->CurrentGroup()->SetFlippingOptions (Standard_False, gp_Ax2());
|
thePrs->CurrentGroup()->SetFlippingOptions (Standard_False, gp_Ax2());
|
||||||
@@ -316,7 +319,9 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, aPosition);
|
Handle(Graphic3d_Text) aText =
|
||||||
|
Prs3d_Text::Draw (thePrs->CurrentGroup(), anAsp, myText, aPosition);
|
||||||
|
aText->SetTextFormatter (myFormatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInit)
|
if (isInit)
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
#include <Font_FontAspect.hxx>
|
#include <Font_FontAspect.hxx>
|
||||||
#include <TCollection_ExtendedString.hxx>
|
#include <TCollection_ExtendedString.hxx>
|
||||||
|
|
||||||
|
class Font_TextFormatter;
|
||||||
|
|
||||||
//! Presentation of the text.
|
//! Presentation of the text.
|
||||||
class AIS_TextLabel : public AIS_InteractiveObject
|
class AIS_TextLabel : public AIS_InteractiveObject
|
||||||
{
|
{
|
||||||
@@ -121,6 +123,12 @@ public:
|
|||||||
//! and the colour of backgroubd for the TODT_DEKALE TextDisplayType.
|
//! and the colour of backgroubd for the TODT_DEKALE TextDisplayType.
|
||||||
Standard_EXPORT void SetColorSubTitle (const Quantity_Color& theColor);
|
Standard_EXPORT void SetColorSubTitle (const Quantity_Color& theColor);
|
||||||
|
|
||||||
|
//! Returns text presentation formatter; NULL by default, which means standard text formatter will be used.
|
||||||
|
const Handle(Font_TextFormatter)& TextFormatter() const { return myFormatter; }
|
||||||
|
|
||||||
|
//! Setup text formatter for presentation. It's empty by default.
|
||||||
|
void SetTextFormatter (const Handle(Font_TextFormatter)& theFormatter) { myFormatter = theFormatter; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Compute
|
//! Compute
|
||||||
@@ -144,6 +152,8 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
Handle(Font_TextFormatter) myFormatter;
|
||||||
|
|
||||||
TCollection_ExtendedString myText;
|
TCollection_ExtendedString myText;
|
||||||
gp_Ax2 myOrientation3D;
|
gp_Ax2 myOrientation3D;
|
||||||
Standard_Boolean myHasOrientation3D;
|
Standard_Boolean myHasOrientation3D;
|
||||||
|
@@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
#include <Font_FTFont.hxx>
|
#include <Font_FTFont.hxx>
|
||||||
|
|
||||||
|
#include <Precision.hxx>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
typedef NCollection_Vec2<Standard_ShortReal> Vec2f;
|
typedef NCollection_Vec2<Standard_ShortReal> Vec2f;
|
||||||
@@ -55,16 +59,17 @@ Font_TextFormatter::Font_TextFormatter()
|
|||||||
: myAlignX (Graphic3d_HTA_LEFT),
|
: myAlignX (Graphic3d_HTA_LEFT),
|
||||||
myAlignY (Graphic3d_VTA_TOP),
|
myAlignY (Graphic3d_VTA_TOP),
|
||||||
myTabSize (8),
|
myTabSize (8),
|
||||||
|
myWrappingWidth (0.0f),
|
||||||
|
myLastSymbolWidth (0.0f),
|
||||||
|
myMaxSymbolWidth (0.0f),
|
||||||
//
|
//
|
||||||
myPen (0.0f, 0.0f),
|
myPen (0.0f, 0.0f),
|
||||||
myRectsNb (0),
|
|
||||||
myLineSpacing (0.0f),
|
myLineSpacing (0.0f),
|
||||||
myAscender (0.0f),
|
myAscender (0.0f),
|
||||||
myIsFormatted (false),
|
myIsFormatted (false),
|
||||||
//
|
//
|
||||||
myLinesNb (0),
|
myLinesNb (0),
|
||||||
myRectLineStart (0),
|
myRectLineStart (0),
|
||||||
myRectWordStart (0),
|
|
||||||
myNewLineNb(0),
|
myNewLineNb(0),
|
||||||
myPenCurrLine (0.0f),
|
myPenCurrLine (0.0f),
|
||||||
myBndTop (0.0f),
|
myBndTop (0.0f),
|
||||||
@@ -94,10 +99,12 @@ void Font_TextFormatter::Reset()
|
|||||||
myIsFormatted = false;
|
myIsFormatted = false;
|
||||||
myString.Clear();
|
myString.Clear();
|
||||||
myPen.x() = myPen.y() = 0.0f;
|
myPen.x() = myPen.y() = 0.0f;
|
||||||
myRectsNb = 0;
|
|
||||||
myLineSpacing = myAscender = 0.0f;
|
myLineSpacing = myAscender = 0.0f;
|
||||||
myCorners.Clear();
|
myCorners.Clear();
|
||||||
myNewLines.Clear();
|
myNewLines.Clear();
|
||||||
|
|
||||||
|
myLastSymbolWidth = 0.0f;
|
||||||
|
myMaxSymbolWidth = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -119,16 +126,13 @@ void Font_TextFormatter::Append (const NCollection_String& theString,
|
|||||||
int aSymbolsCounter = 0; // special counter to process tabulation symbols
|
int aSymbolsCounter = 0; // special counter to process tabulation symbols
|
||||||
|
|
||||||
// first pass - render all symbols using associated font on single ZERO baseline
|
// first pass - render all symbols using associated font on single ZERO baseline
|
||||||
for (NCollection_Utf8Iter anIter = theString.Iterator(); *anIter != 0;)
|
for (Font_TextFormatter::Iterator aFormatterIt (*this); aFormatterIt.More(); aFormatterIt.Next())
|
||||||
{
|
{
|
||||||
const Standard_Utf32Char aCharThis = *anIter;
|
const Standard_Utf32Char aCharThis = aFormatterIt.Symbol();
|
||||||
const Standard_Utf32Char aCharNext = *++anIter;
|
const Standard_Utf32Char aCharNext = aFormatterIt.SymbolNext();
|
||||||
|
|
||||||
if (aCharThis == '\x0D' // CR (carriage return)
|
Standard_ShortReal anAdvanceX = 0;
|
||||||
|| aCharThis == '\a' // BEL (alarm)
|
if (IsCommandSymbol (aCharThis))
|
||||||
|| aCharThis == '\f' // FF (form feed) NP (new page)
|
|
||||||
|| aCharThis == '\b' // BS (backspace)
|
|
||||||
|| aCharThis == '\v') // VT (vertical tab)
|
|
||||||
{
|
{
|
||||||
continue; // skip unsupported carriage control codes
|
continue; // skip unsupported carriage control codes
|
||||||
}
|
}
|
||||||
@@ -136,79 +140,69 @@ void Font_TextFormatter::Append (const NCollection_String& theString,
|
|||||||
{
|
{
|
||||||
aSymbolsCounter = 0;
|
aSymbolsCounter = 0;
|
||||||
myNewLines.Append (myPen.x());
|
myNewLines.Append (myPen.x());
|
||||||
continue; // will be processed on second pass
|
anAdvanceX = 0; // the symbol has null width
|
||||||
}
|
}
|
||||||
else if (aCharThis == ' ')
|
else if (aCharThis == ' ')
|
||||||
{
|
{
|
||||||
++aSymbolsCounter;
|
anAdvanceX = theFont.AdvanceX (' ', aCharNext);
|
||||||
myPen.x() += theFont.AdvanceX (' ', aCharNext);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else if (aCharThis == '\t')
|
else if (aCharThis == '\t')
|
||||||
{
|
{
|
||||||
const Standard_Integer aSpacesNum = (myTabSize - (aSymbolsCounter - 1) % myTabSize);
|
const Standard_Integer aSpacesNum = (myTabSize - (aSymbolsCounter - 1) % myTabSize);
|
||||||
myPen.x() += theFont.AdvanceX (' ', aCharNext) * Standard_ShortReal(aSpacesNum);
|
anAdvanceX = theFont.AdvanceX (' ', aCharNext) * Standard_ShortReal(aSpacesNum);
|
||||||
aSymbolsCounter += aSpacesNum;
|
aSymbolsCounter += aSpacesNum;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
anAdvanceX = theFont.AdvanceX (aCharThis, aCharNext);
|
||||||
|
}
|
||||||
++aSymbolsCounter;
|
++aSymbolsCounter;
|
||||||
|
|
||||||
myCorners.Append (myPen);
|
myCorners.Append (myPen);
|
||||||
|
myPen.x() += anAdvanceX;
|
||||||
myPen.x() += theFont.AdvanceX (aCharThis, aCharNext);
|
myMaxSymbolWidth = Max (myMaxSymbolWidth, anAdvanceX);
|
||||||
|
|
||||||
++myRectsNb;
|
|
||||||
}
|
}
|
||||||
|
myLastSymbolWidth = myPen.x() - myCorners.Last().x();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : newLine
|
// function : newLine
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Font_TextFormatter::newLine (const Standard_Integer theLastRect)
|
void Font_TextFormatter::newLine (const Standard_Integer theLastRect,
|
||||||
|
const Standard_ShortReal theMaxLineWidth)
|
||||||
{
|
{
|
||||||
if (myRectLineStart >= myRectsNb)
|
Standard_Integer aFirstCornerId = myRectLineStart;
|
||||||
|
Standard_Integer aLastCornerId = theLastRect;
|
||||||
|
|
||||||
|
if (aFirstCornerId >= myCorners.Length())
|
||||||
{
|
{
|
||||||
++myLinesNb;
|
++myLinesNb;
|
||||||
myPenCurrLine -= myLineSpacing;
|
myPenCurrLine -= myLineSpacing;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Standard_ShortReal aXMin = BottomLeft (aFirstCornerId).x();
|
||||||
|
Font_Rect aBndBox;
|
||||||
|
GlyphBoundingBox (aLastCornerId, aBndBox);
|
||||||
|
Standard_ShortReal aXMax = aBndBox.Right;
|
||||||
|
|
||||||
myMoveVec.y() = myPenCurrLine;
|
myMoveVec.y() = myPenCurrLine;
|
||||||
switch (myAlignX)
|
switch (myAlignX)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Graphic3d_HTA_LEFT:
|
case Graphic3d_HTA_LEFT: myMoveVec.x() = -aXMin;
|
||||||
{
|
|
||||||
myMoveVec.x() = (myNewLineNb > 0) ? -myNewLines.Value (myNewLineNb - 1) : 0.0f;
|
|
||||||
break;
|
break;
|
||||||
}
|
case Graphic3d_HTA_RIGHT: myMoveVec.x() = -aXMin + (theMaxLineWidth - (aXMax - aXMin)) - theMaxLineWidth;
|
||||||
case Graphic3d_HTA_RIGHT:
|
|
||||||
{
|
|
||||||
myMoveVec.x() = (myNewLineNb < myNewLines.Length())
|
|
||||||
? -myNewLines.Value (myNewLineNb)
|
|
||||||
: -myPen.x();
|
|
||||||
break;
|
break;
|
||||||
}
|
case Graphic3d_HTA_CENTER: myMoveVec.x() = -aXMin + 0.5f * (theMaxLineWidth - (aXMax - aXMin)) - 0.5f * theMaxLineWidth;
|
||||||
case Graphic3d_HTA_CENTER:
|
|
||||||
{
|
|
||||||
const Standard_ShortReal aFrom = (myNewLineNb > 0)
|
|
||||||
? myNewLines.Value (myNewLineNb - 1)
|
|
||||||
: 0.0f;
|
|
||||||
const Standard_ShortReal aTo = (myNewLineNb < myNewLines.Length())
|
|
||||||
? myNewLines.Value (myNewLineNb)
|
|
||||||
: myPen.x();
|
|
||||||
myMoveVec.x() = -0.5f * (aFrom + aTo);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
move (myCorners, myMoveVec, myRectLineStart, theLastRect);
|
move (myCorners, myMoveVec, myRectLineStart, theLastRect);
|
||||||
|
|
||||||
++myLinesNb;
|
++myLinesNb;
|
||||||
myPenCurrLine -= myLineSpacing;
|
myPenCurrLine -= myLineSpacing;
|
||||||
myRectLineStart = myRectWordStart = theLastRect + 1;
|
myRectLineStart = theLastRect + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
@@ -217,13 +211,13 @@ void Font_TextFormatter::newLine (const Standard_Integer theLastRect)
|
|||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Font_TextFormatter::Format()
|
void Font_TextFormatter::Format()
|
||||||
{
|
{
|
||||||
if (myRectsNb == 0 || myIsFormatted)
|
if (myCorners.Length() == 0 || myIsFormatted)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
myIsFormatted = true;
|
myIsFormatted = true;
|
||||||
myLinesNb = myRectLineStart = myRectWordStart = 0;
|
myLinesNb = myRectLineStart = 0;
|
||||||
myBndTop = 0.0f;
|
myBndTop = 0.0f;
|
||||||
myBndWidth = 0.0f;
|
myBndWidth = 0.0f;
|
||||||
myMoveVec.x() = myMoveVec.y() = 0.0f;
|
myMoveVec.x() = myMoveVec.y() = 0.0f;
|
||||||
@@ -232,59 +226,61 @@ void Font_TextFormatter::Format()
|
|||||||
myPenCurrLine = -myAscender;
|
myPenCurrLine = -myAscender;
|
||||||
Standard_Integer aRectIter = 0;
|
Standard_Integer aRectIter = 0;
|
||||||
myNewLineNb = 0;
|
myNewLineNb = 0;
|
||||||
Standard_ShortReal aMaxLineWidth = -1.0f;
|
|
||||||
for (NCollection_Utf8Iter anIter = myString.Iterator(); *anIter != 0; ++anIter)
|
|
||||||
{
|
|
||||||
const Standard_Utf32Char aCharThis = *anIter;
|
|
||||||
if (aCharThis == '\x0D' // CR (carriage return)
|
|
||||||
|| aCharThis == '\a' // BEL (alarm)
|
|
||||||
|| aCharThis == '\f' // FF (form feed) NP (new page)
|
|
||||||
|| aCharThis == '\b' // BS (backspace)
|
|
||||||
|| aCharThis == '\v') // VT (vertical tab)
|
|
||||||
{
|
|
||||||
continue; // skip unsupported carriage control codes
|
|
||||||
}
|
|
||||||
else if (aCharThis == '\x0A') // LF (line feed, new line)
|
|
||||||
{
|
|
||||||
// calculate max line width
|
|
||||||
if (myNewLineNb == 0)
|
|
||||||
{
|
|
||||||
aMaxLineWidth = myNewLines.Value(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aMaxLineWidth = Max (aMaxLineWidth, myNewLines.Value (myNewLineNb) - myNewLines.Value (myNewLineNb - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line
|
Standard_ShortReal aMaxLineWidth = Wrapping();
|
||||||
newLine (aLastRect);
|
if (HasWrapping())
|
||||||
|
{
|
||||||
|
// it is not possible to wrap less than symbol width
|
||||||
|
aMaxLineWidth = Max (aMaxLineWidth, MaximumSymbolWidth());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (myNewLines.IsEmpty()) // If only one line
|
||||||
|
{
|
||||||
|
aMaxLineWidth = myPen.x();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int aLineIt = 0; aLineIt < myNewLines.Size(); aLineIt++)
|
||||||
|
{
|
||||||
|
aMaxLineWidth = Max (aMaxLineWidth, LineWidth (aLineIt));
|
||||||
|
}
|
||||||
|
aMaxLineWidth = Max (aMaxLineWidth, LineWidth (myNewLines.Size())); // processing the last line also
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Font_TextFormatter::Iterator aFormatterIt(*this);
|
||||||
|
aFormatterIt.More(); aFormatterIt.Next())
|
||||||
|
{
|
||||||
|
const Standard_Utf32Char aCharThis = aFormatterIt.Symbol();
|
||||||
|
aRectIter = aFormatterIt.SymbolPosition();
|
||||||
|
|
||||||
|
if (aCharThis == '\x0A') // LF (line feed, new line)
|
||||||
|
{
|
||||||
|
const Standard_Integer aLastRect = aRectIter; // last rect on current line
|
||||||
|
newLine (aLastRect, aMaxLineWidth);
|
||||||
++myNewLineNb;
|
++myNewLineNb;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (aCharThis == ' '
|
else if (HasWrapping()) // wrap lines longer than maximum width
|
||||||
|| aCharThis == '\t')
|
|
||||||
{
|
{
|
||||||
myRectWordStart = aRectIter;
|
Standard_Integer aFirstCornerId = myRectLineStart;
|
||||||
continue;
|
|
||||||
|
Font_Rect aBndBox;
|
||||||
|
GlyphBoundingBox (aRectIter, aBndBox);
|
||||||
|
const Standard_ShortReal aNextXPos = aBndBox.Right - BottomLeft (aFirstCornerId).x();
|
||||||
|
if (aNextXPos > aMaxLineWidth) // wrap the line and do processing of the symbol
|
||||||
|
{
|
||||||
|
const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line
|
||||||
|
newLine (aLastRect, aMaxLineWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++aRectIter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If only one line
|
|
||||||
if (aMaxLineWidth < 0.0f)
|
|
||||||
{
|
|
||||||
aMaxLineWidth = myPen.x();
|
|
||||||
}
|
|
||||||
else // Consider last line
|
|
||||||
{
|
|
||||||
aMaxLineWidth = Max (aMaxLineWidth, myPen.x() - myNewLines.Value (myNewLineNb - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
myBndWidth = aMaxLineWidth;
|
myBndWidth = aMaxLineWidth;
|
||||||
|
|
||||||
// move last line
|
// move last line
|
||||||
newLine (myRectsNb - 1);
|
newLine (myCorners.Length() - 1, aMaxLineWidth);
|
||||||
|
|
||||||
// apply vertical alignment style
|
// apply vertical alignment style
|
||||||
if (myAlignY == Graphic3d_VTA_BOTTOM)
|
if (myAlignY == Graphic3d_VTA_BOTTOM)
|
||||||
@@ -302,6 +298,129 @@ void Font_TextFormatter::Format()
|
|||||||
|
|
||||||
if (myAlignY != Graphic3d_VTA_TOP)
|
if (myAlignY != Graphic3d_VTA_TOP)
|
||||||
{
|
{
|
||||||
moveY (myCorners, myBndTop, 0, myRectsNb - 1);
|
moveY (myCorners, myBndTop, 0, myCorners.Length() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : GlyphBoundingBox
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Font_TextFormatter::GlyphBoundingBox (const Standard_Integer theIndex,
|
||||||
|
Font_Rect& theBndBox) const
|
||||||
|
{
|
||||||
|
if (theIndex < 0 || theIndex >= Corners().Size())
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
const NCollection_Vec2<Standard_ShortReal>& aLeftCorner = BottomLeft (theIndex);
|
||||||
|
if (theIndex + 1 < myCorners.Length()) // not the last symbol
|
||||||
|
{
|
||||||
|
const NCollection_Vec2<Standard_ShortReal>& aNextLeftCorner = BottomLeft (theIndex + 1);
|
||||||
|
theBndBox.Left = aLeftCorner.x();
|
||||||
|
theBndBox.Bottom = aLeftCorner.y();
|
||||||
|
theBndBox.Top = theBndBox.Bottom + myLineSpacing;
|
||||||
|
if (Abs (aLeftCorner.y() - aNextLeftCorner.y()) < Precision::Confusion()) // in the same row
|
||||||
|
{
|
||||||
|
theBndBox.Right = aNextLeftCorner.x();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// the next symbol is on the next row either by '\n' or by wrapping
|
||||||
|
Standard_ShortReal aLineWidth = LineWidth (LineIndex (theIndex));
|
||||||
|
theBndBox.Left = aLeftCorner.x();
|
||||||
|
switch (myAlignX)
|
||||||
|
{
|
||||||
|
case Graphic3d_HTA_LEFT: theBndBox.Right = aLineWidth; break;
|
||||||
|
case Graphic3d_HTA_RIGHT: theBndBox.Right = myBndWidth; break;
|
||||||
|
case Graphic3d_HTA_CENTER: theBndBox.Right = 0.5f * (myBndWidth + aLineWidth); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // the last symbol
|
||||||
|
{
|
||||||
|
theBndBox.Left = aLeftCorner.x();
|
||||||
|
theBndBox.Right = aLeftCorner.x() + myLastSymbolWidth;
|
||||||
|
theBndBox.Bottom = aLeftCorner.y();
|
||||||
|
theBndBox.Top = theBndBox.Bottom + myLineSpacing;
|
||||||
|
}
|
||||||
|
return Standard_True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : IsLFSymbol
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Boolean Font_TextFormatter::IsLFSymbol (const Standard_Integer theIndex) const
|
||||||
|
{
|
||||||
|
Font_Rect aBndBox;
|
||||||
|
if (!GlyphBoundingBox (theIndex, aBndBox))
|
||||||
|
return Standard_False;
|
||||||
|
|
||||||
|
return Abs (aBndBox.Right - aBndBox.Left) < Precision::Confusion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : FirstPosition
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_ShortReal Font_TextFormatter::FirstPosition() const
|
||||||
|
{
|
||||||
|
switch (myAlignX)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case Graphic3d_HTA_LEFT: return 0;
|
||||||
|
case Graphic3d_HTA_RIGHT: return myBndWidth;
|
||||||
|
case Graphic3d_HTA_CENTER: return 0.5f * myBndWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : LinePositionIndex
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Integer Font_TextFormatter::LinePositionIndex (const Standard_Integer theIndex) const
|
||||||
|
{
|
||||||
|
Standard_Integer anIndex = 0;
|
||||||
|
|
||||||
|
Standard_ShortReal anIndexHeight = BottomLeft (theIndex).y();
|
||||||
|
for (Standard_Integer aPrevIndex = theIndex-1; aPrevIndex >= 0; aPrevIndex--)
|
||||||
|
{
|
||||||
|
if (BottomLeft (aPrevIndex).y() > anIndexHeight)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
anIndex++;
|
||||||
|
}
|
||||||
|
return anIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : LineIndex
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_Integer Font_TextFormatter::LineIndex (const Standard_Integer theIndex) const
|
||||||
|
{
|
||||||
|
if (myLineSpacing < 0.0f)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (Standard_Integer)Abs((BottomLeft (theIndex).y() + myAscender) / myLineSpacing);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =======================================================================
|
||||||
|
// function : LineWidth
|
||||||
|
// purpose :
|
||||||
|
// =======================================================================
|
||||||
|
Standard_ShortReal Font_TextFormatter::LineWidth (const Standard_Integer theIndex) const
|
||||||
|
{
|
||||||
|
if (theIndex < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (theIndex < myNewLines.Length())
|
||||||
|
return theIndex == 0 ? myNewLines[0] : myNewLines[theIndex] - myNewLines[theIndex -1];
|
||||||
|
|
||||||
|
if (theIndex == myNewLines.Length()) // the last line
|
||||||
|
return theIndex == 0 ? myPen.x() : myPen.x() - myNewLines[theIndex -1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -25,10 +25,120 @@
|
|||||||
|
|
||||||
class Font_FTFont;
|
class Font_FTFont;
|
||||||
|
|
||||||
//! This class intended to prepare formatted text.
|
DEFINE_STANDARD_HANDLE(Font_TextFormatter, Standard_Transient)
|
||||||
class Font_TextFormatter
|
|
||||||
|
//! This class is intended to prepare formatted text by using:<br>
|
||||||
|
//! - font to string combination,<br>
|
||||||
|
//! - alignment,<br>
|
||||||
|
//! - wrapping.<br>
|
||||||
|
//!
|
||||||
|
//! After text formatting, each symbol of formatted text is placed in some position.
|
||||||
|
//! Further work with the formatter is using an iterator.
|
||||||
|
//! The iterator gives an access to each symbol inside the initial row.
|
||||||
|
//! Also it's possible to get only significant/writable symbols of the text.<br>
|
||||||
|
//! Formatter gives an access to geometrical position of a symbol by the symbol index in the text.<br>
|
||||||
|
//! Example of correspondence of some text symbol to an index in "row_1\n\nrow_2\n":<br>
|
||||||
|
//! "row_1\n" - 0-5 indices;<br>
|
||||||
|
//! "\n" - 6 index;<br>
|
||||||
|
//! "\n" - 7 index;<br>
|
||||||
|
//! "row_2\n" - 8-13 indices.<br>
|
||||||
|
//! Pay attention that fonts should have the same LineSpacing value for correct formatting.<br>
|
||||||
|
//! Example of the formatter using:
|
||||||
|
//! @code
|
||||||
|
//! Handle(Font_TextFormatter) aFormatter = new Font_TextFormatter();
|
||||||
|
//! aFormatter->Append(text_1, aFont1);
|
||||||
|
//! aFormatter->Append(text_2, aFont2);
|
||||||
|
//! // setting of additional properties such as wrapping or alignment
|
||||||
|
//! aFormatter->Format();
|
||||||
|
//! @endcode
|
||||||
|
class Font_TextFormatter : public Standard_Transient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
//! Iteration filter flags. Command symbols are skipped with any filter.
|
||||||
|
enum IterationFilter
|
||||||
|
{
|
||||||
|
IterationFilter_None = 0x0000, //!< no filter
|
||||||
|
IterationFilter_ExcludeInvisible = 0x0002, //!< exclude ' ', '\t', '\n'
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Iterator through formatted symbols.
|
||||||
|
//! It's possible to filter returned symbols to have only significant ones.
|
||||||
|
class Iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor with initialization.
|
||||||
|
Iterator (const Font_TextFormatter& theFormatter,
|
||||||
|
IterationFilter theFilter = IterationFilter_None)
|
||||||
|
: myFilter (theFilter), myIter (theFormatter.myString.Iterator()), mySymbolChar (0), mySymbolCharNext (0)
|
||||||
|
{
|
||||||
|
mySymbolPosition = readNextSymbol (-1, mySymbolChar);
|
||||||
|
mySymbolNext = readNextSymbol (mySymbolPosition, mySymbolCharNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns TRUE if iterator points to a valid item.
|
||||||
|
Standard_Boolean More() const { return mySymbolPosition >= 0; }
|
||||||
|
|
||||||
|
//! Returns TRUE if next item exists
|
||||||
|
Standard_Boolean HasNext() const { return mySymbolNext >= 0; }
|
||||||
|
|
||||||
|
//! Returns current symbol.
|
||||||
|
Standard_Utf32Char Symbol() const { return mySymbolChar; }
|
||||||
|
|
||||||
|
//! Returns the next symbol if exists.
|
||||||
|
Standard_Utf32Char SymbolNext() const { return mySymbolCharNext; }
|
||||||
|
|
||||||
|
//! Returns current symbol position.
|
||||||
|
Standard_Integer SymbolPosition() const { return mySymbolPosition; }
|
||||||
|
|
||||||
|
//! Returns the next symbol position.
|
||||||
|
Standard_Integer SymbolPositionNext() const { return mySymbolNext; }
|
||||||
|
|
||||||
|
//! Moves to the next item.
|
||||||
|
void Next()
|
||||||
|
{
|
||||||
|
mySymbolPosition = mySymbolNext;
|
||||||
|
mySymbolChar = mySymbolCharNext;
|
||||||
|
mySymbolNext = readNextSymbol (mySymbolPosition, mySymbolCharNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//! Finds index of the next symbol
|
||||||
|
Standard_Integer readNextSymbol (const Standard_Integer theSymbolStartingFrom,
|
||||||
|
Standard_Utf32Char& theSymbolChar)
|
||||||
|
{
|
||||||
|
Standard_Integer aNextSymbol = theSymbolStartingFrom;
|
||||||
|
for (; *myIter != 0; ++myIter)
|
||||||
|
{
|
||||||
|
const Standard_Utf32Char aCharCurr = *myIter;
|
||||||
|
if (Font_TextFormatter::IsCommandSymbol (aCharCurr))
|
||||||
|
{
|
||||||
|
continue; // skip unsupported carriage control codes
|
||||||
|
}
|
||||||
|
aNextSymbol++;
|
||||||
|
if ((myFilter & IterationFilter_ExcludeInvisible) != 0)
|
||||||
|
{
|
||||||
|
if (aCharCurr == '\x0A'|| // LF (line feed, new line)
|
||||||
|
aCharCurr == ' ' ||
|
||||||
|
aCharCurr == '\t')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++myIter;
|
||||||
|
theSymbolChar = aCharCurr;
|
||||||
|
return aNextSymbol; // found the first next, not command and not filtered symbol
|
||||||
|
}
|
||||||
|
return -1; // the next symbol is not found
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IterationFilter myFilter; //!< possibility to filter not-necessary symbols
|
||||||
|
NCollection_Utf8Iter myIter; //!< the next symbol iterator value over the text formatter string
|
||||||
|
Standard_Integer mySymbolPosition; //!< the current position
|
||||||
|
Standard_Utf32Char mySymbolChar; //!< the current symbol
|
||||||
|
Standard_Integer mySymbolNext; //!< position of the next symbol in iterator, if zero, the iterator is finished
|
||||||
|
Standard_Utf32Char mySymbolCharNext; //!< the current symbol
|
||||||
|
};
|
||||||
|
|
||||||
//! Default constructor.
|
//! Default constructor.
|
||||||
Standard_EXPORT Font_TextFormatter();
|
Standard_EXPORT Font_TextFormatter();
|
||||||
@@ -48,24 +158,68 @@ public:
|
|||||||
//! Should not be called more than once after initialization!
|
//! Should not be called more than once after initialization!
|
||||||
Standard_EXPORT void Format();
|
Standard_EXPORT void Format();
|
||||||
|
|
||||||
//! Returns specific glyph rectangle.
|
Standard_DEPRECATED("BottomLeft should be used instead")
|
||||||
inline const NCollection_Vec2<Standard_ShortReal>& TopLeft (const Standard_Integer theIndex) const
|
const NCollection_Vec2<Standard_ShortReal>& TopLeft (const Standard_Integer theIndex) const
|
||||||
{
|
{
|
||||||
return myCorners.Value (theIndex);
|
return BottomLeft (theIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns specific glyph rectangle.
|
||||||
|
const NCollection_Vec2<Standard_ShortReal>& BottomLeft (const Standard_Integer theIndex) const
|
||||||
|
{ return myCorners.Value (theIndex); }
|
||||||
|
|
||||||
//! Returns current rendering string.
|
//! Returns current rendering string.
|
||||||
inline const NCollection_String& String() const
|
inline const NCollection_String& String() const
|
||||||
{
|
{
|
||||||
return myString;
|
return myString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns symbol bounding box
|
||||||
|
//! @param bounding box.
|
||||||
|
Standard_EXPORT Standard_Boolean GlyphBoundingBox (const Standard_Integer theIndex,
|
||||||
|
Font_Rect& theBndBox) const;
|
||||||
|
|
||||||
|
//! Returns the line height
|
||||||
|
//! @param theIndex a line index, obtained by LineIndex()
|
||||||
|
Standard_ShortReal LineHeight (const Standard_Integer theIndex) const
|
||||||
|
{ return theIndex == 0 ? myAscender : myLineSpacing; }
|
||||||
|
|
||||||
|
//! Returns width of a line
|
||||||
|
Standard_EXPORT Standard_ShortReal LineWidth (const Standard_Integer theIndex) const;
|
||||||
|
|
||||||
|
//! Returns true if the symbol by the index is '\n'. The width of the symbol is zero.
|
||||||
|
Standard_EXPORT Standard_Boolean IsLFSymbol (const Standard_Integer theIndex) const;
|
||||||
|
|
||||||
|
//! Returns position of the first symbol in a line using alignment
|
||||||
|
Standard_EXPORT Standard_ShortReal FirstPosition() const;
|
||||||
|
|
||||||
|
//! Returns column index of the corner index in the current line
|
||||||
|
Standard_EXPORT Standard_Integer LinePositionIndex (const Standard_Integer theIndex) const;
|
||||||
|
|
||||||
|
//! Returns row index of the corner index among text lines
|
||||||
|
Standard_EXPORT Standard_Integer LineIndex (const Standard_Integer theIndex) const;
|
||||||
|
|
||||||
//! Returns tab size.
|
//! Returns tab size.
|
||||||
inline Standard_Integer TabSize() const
|
inline Standard_Integer TabSize() const
|
||||||
{
|
{
|
||||||
return myTabSize;
|
return myTabSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns horizontal alignment style
|
||||||
|
Graphic3d_HorizontalTextAlignment HorizontalTextAlignment() const { return myAlignX; }
|
||||||
|
|
||||||
|
//! Returns vertical alignment style
|
||||||
|
Graphic3d_VerticalTextAlignment VerticalTextAlignment() const { return myAlignY; }
|
||||||
|
|
||||||
|
//! Sets text wrapping width, zero means that the text is not bounded by width
|
||||||
|
void SetWrapping (const Standard_ShortReal theWidth) { myWrappingWidth = theWidth; }
|
||||||
|
|
||||||
|
//! Returns text maximum width, zero means that the text is not bounded by width
|
||||||
|
Standard_Boolean HasWrapping() const { return myWrappingWidth > 0; }
|
||||||
|
|
||||||
|
//! Returns text maximum width, zero means that the text is not bounded by width
|
||||||
|
Standard_ShortReal Wrapping() const { return myWrappingWidth; }
|
||||||
|
|
||||||
//! @return width of formatted text.
|
//! @return width of formatted text.
|
||||||
inline Standard_ShortReal ResultWidth() const
|
inline Standard_ShortReal ResultWidth() const
|
||||||
{
|
{
|
||||||
@@ -78,6 +232,9 @@ public:
|
|||||||
return myLineSpacing * Standard_ShortReal(myLinesNb);
|
return myLineSpacing * Standard_ShortReal(myLinesNb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! @return maximum width of the text symbol
|
||||||
|
Standard_ShortReal MaximumSymbolWidth() const { return myMaxSymbolWidth; }
|
||||||
|
|
||||||
//! @param bounding box.
|
//! @param bounding box.
|
||||||
inline void BndBox (Font_Rect& theBndBox) const
|
inline void BndBox (Font_Rect& theBndBox) const
|
||||||
{
|
{
|
||||||
@@ -98,16 +255,41 @@ public:
|
|||||||
theBndBox.Bottom = theBndBox.Top - myLineSpacing * Standard_ShortReal(myLinesNb);
|
theBndBox.Bottom = theBndBox.Top - myLineSpacing * Standard_ShortReal(myLinesNb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns internal container of the top left corners of a formatted rectangles.
|
||||||
|
const NCollection_Vector < NCollection_Vec2<Standard_ShortReal> >& Corners() const { return myCorners; }
|
||||||
|
|
||||||
|
//! Returns container of each line position at LF in formatted text
|
||||||
|
const NCollection_Vector<Standard_ShortReal>& NewLines() const { return myNewLines; }
|
||||||
|
|
||||||
|
//! Returns true if the symbol is CR, BEL, FF, NP, BS or VT
|
||||||
|
static inline Standard_Boolean IsCommandSymbol (const Standard_Utf32Char& theSymbol)
|
||||||
|
{
|
||||||
|
if (theSymbol == '\x0D' // CR (carriage return)
|
||||||
|
|| theSymbol == '\a' // BEL (alarm)
|
||||||
|
|| theSymbol == '\f' // FF (form feed) NP (new page)
|
||||||
|
|| theSymbol == '\b' // BS (backspace)
|
||||||
|
|| theSymbol == '\v') // VT (vertical tab)
|
||||||
|
return Standard_True;
|
||||||
|
|
||||||
|
return Standard_False;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient)
|
||||||
|
|
||||||
protected: //! @name class auxiliary methods
|
protected: //! @name class auxiliary methods
|
||||||
|
|
||||||
//! Move glyphs on the current line to correct position.
|
//! Move glyphs on the current line to correct position.
|
||||||
Standard_EXPORT void newLine (const Standard_Integer theLastRect);
|
Standard_EXPORT void newLine (const Standard_Integer theLastRect,
|
||||||
|
const Standard_ShortReal theMaxLineWidth);
|
||||||
|
|
||||||
protected: //! @name configuration
|
protected: //! @name configuration
|
||||||
|
|
||||||
Graphic3d_HorizontalTextAlignment myAlignX; //!< horizontal alignment style
|
Graphic3d_HorizontalTextAlignment myAlignX; //!< horizontal alignment style
|
||||||
Graphic3d_VerticalTextAlignment myAlignY; //!< vertical alignment style
|
Graphic3d_VerticalTextAlignment myAlignY; //!< vertical alignment style
|
||||||
Standard_Integer myTabSize; //!< horizontal tabulation width (number of space symbols)
|
Standard_Integer myTabSize; //!< horizontal tabulation width (number of space symbols)
|
||||||
|
Standard_ShortReal myWrappingWidth; //!< text is wrapped by the width if defined (more 0)
|
||||||
|
Standard_ShortReal myLastSymbolWidth; //!< width of the last symbol
|
||||||
|
Standard_ShortReal myMaxSymbolWidth; //!< maximum symbol width of the formatter string
|
||||||
|
|
||||||
protected: //! @name input data
|
protected: //! @name input data
|
||||||
|
|
||||||
@@ -115,19 +297,17 @@ protected: //! @name input data
|
|||||||
NCollection_Vec2<Standard_ShortReal>
|
NCollection_Vec2<Standard_ShortReal>
|
||||||
myPen; //!< current pen position
|
myPen; //!< current pen position
|
||||||
NCollection_Vector < NCollection_Vec2<Standard_ShortReal> >
|
NCollection_Vector < NCollection_Vec2<Standard_ShortReal> >
|
||||||
myCorners; //!< The top left corners of a formatted rectangles.
|
myCorners; //!< The bottom left corners of a formatted rectangles.
|
||||||
Standard_Integer myRectsNb; //!< rectangles number
|
|
||||||
NCollection_Vector<Standard_ShortReal>
|
NCollection_Vector<Standard_ShortReal>
|
||||||
myNewLines; //!< position at LF
|
myNewLines; //!< position at LF
|
||||||
Standard_ShortReal myLineSpacing; //!< line spacing (computed as maximum of all fonts involved in text formatting)
|
Standard_ShortReal myLineSpacing; //!< line spacing (computed as maximum of all fonts involved in text formatting)
|
||||||
Standard_ShortReal myAscender; //!<
|
Standard_ShortReal myAscender; //!< line spacing for the first line
|
||||||
bool myIsFormatted; //!< formatting state
|
bool myIsFormatted; //!< formatting state
|
||||||
|
|
||||||
protected: //! @name temporary variables for formatting routines
|
protected: //! @name temporary variables for formatting routines
|
||||||
|
|
||||||
Standard_Integer myLinesNb; //!< overall (new)lines number (including splitting by width limit)
|
Standard_Integer myLinesNb; //!< overall (new)lines number (including splitting by width limit)
|
||||||
Standard_Integer myRectLineStart; //!< id of first rectangle on the current line
|
Standard_Integer myRectLineStart; //!< id of first rectangle on the current line
|
||||||
Standard_Integer myRectWordStart; //!< id of first rectangle in the current word
|
|
||||||
Standard_Integer myNewLineNb;
|
Standard_Integer myNewLineNb;
|
||||||
|
|
||||||
Standard_ShortReal myPenCurrLine; //!< current baseline position
|
Standard_ShortReal myPenCurrLine; //!< current baseline position
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <gp_Ax2.hxx>
|
#include <gp_Ax2.hxx>
|
||||||
|
|
||||||
#include <Graphic3d_Vertex.hxx>
|
#include <Graphic3d_Vertex.hxx>
|
||||||
|
#include <Font_TextFormatter.hxx>
|
||||||
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
#include <Graphic3d_HorizontalTextAlignment.hxx>
|
||||||
#include <Graphic3d_VerticalTextAlignment.hxx>
|
#include <Graphic3d_VerticalTextAlignment.hxx>
|
||||||
#include <NCollection_String.hxx>
|
#include <NCollection_String.hxx>
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
//! - text formatter. Formatter contains text, height and alignment parameter.
|
//! - text formatter. Formatter contains text, height and alignment parameter.
|
||||||
//!
|
//!
|
||||||
//! This class also has parameters of the text height and H/V alignments.
|
//! This class also has parameters of the text height and H/V alignments.
|
||||||
|
//! Custom formatting is available using Font_TextFormatter.
|
||||||
class Graphic3d_Text : public Standard_Transient
|
class Graphic3d_Text : public Standard_Transient
|
||||||
{
|
{
|
||||||
DEFINE_STANDARD_RTTIEXT(Graphic3d_Text, Standard_Transient)
|
DEFINE_STANDARD_RTTIEXT(Graphic3d_Text, Standard_Transient)
|
||||||
@@ -55,6 +57,12 @@ public:
|
|||||||
//! Sets text value.
|
//! Sets text value.
|
||||||
void SetText (Standard_CString theText) { myText = theText; }
|
void SetText (Standard_CString theText) { myText = theText; }
|
||||||
|
|
||||||
|
//! @return text formatter; NULL by default, which means standard text formatter will be used.
|
||||||
|
const Handle(Font_TextFormatter)& TextFormatter() const { return myFormatter; }
|
||||||
|
|
||||||
|
//! Setup text default formatter for text within this context.
|
||||||
|
void SetTextFormatter (const Handle(Font_TextFormatter)& theFormatter) { myFormatter = theFormatter; }
|
||||||
|
|
||||||
//! The 3D point of attachment is projected.
|
//! The 3D point of attachment is projected.
|
||||||
//! If the orientation is defined, the text is written in the plane of projection.
|
//! If the orientation is defined, the text is written in the plane of projection.
|
||||||
const gp_Pnt& Position() const { return myOrientation.Location(); }
|
const gp_Pnt& Position() const { return myOrientation.Location(); }
|
||||||
@@ -99,6 +107,8 @@ public:
|
|||||||
void SetVerticalAlignment (const Graphic3d_VerticalTextAlignment theJustification) { myVAlign = theJustification; }
|
void SetVerticalAlignment (const Graphic3d_VerticalTextAlignment theJustification) { myVAlign = theJustification; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Handle(Font_TextFormatter) myFormatter; //!< text formatter
|
||||||
|
|
||||||
NCollection_String myText; //!< text value
|
NCollection_String myText; //!< text value
|
||||||
gp_Ax2 myOrientation; //!< Text orientation in 3D space.
|
gp_Ax2 myOrientation; //!< Text orientation in 3D space.
|
||||||
|
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <Font_FontMgr.hxx>
|
#include <Font_FontMgr.hxx>
|
||||||
#include <Font_FTFont.hxx>
|
#include <Font_FTFont.hxx>
|
||||||
|
#include <Font_TextFormatter.hxx>
|
||||||
#include <Graphic3d_TransformUtils.hxx>
|
#include <Graphic3d_TransformUtils.hxx>
|
||||||
#include <TCollection_HAsciiString.hxx>
|
#include <TCollection_HAsciiString.hxx>
|
||||||
|
|
||||||
@@ -659,7 +660,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
|
|||||||
const OpenGl_Vec4& theColorSubs,
|
const OpenGl_Vec4& theColorSubs,
|
||||||
unsigned int theResolution) const
|
unsigned int theResolution) const
|
||||||
{
|
{
|
||||||
if (myText->Text().IsEmpty())
|
if (myText->Text().IsEmpty() && myText->TextFormatter().IsNull())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -685,13 +686,16 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
|
|||||||
|
|
||||||
if (myTextures.IsEmpty())
|
if (myTextures.IsEmpty())
|
||||||
{
|
{
|
||||||
Font_TextFormatter aFormatter;
|
Handle(Font_TextFormatter) aFormatter = myText->TextFormatter();
|
||||||
|
if (aFormatter.IsNull())
|
||||||
|
{
|
||||||
|
aFormatter = new Font_TextFormatter();
|
||||||
|
}
|
||||||
|
aFormatter->SetupAlignment (myText->HorizontalAlignment(), myText->VerticalAlignment());
|
||||||
|
aFormatter->Reset();
|
||||||
|
|
||||||
aFormatter.SetupAlignment (myText->HorizontalAlignment(), myText->VerticalAlignment());
|
aFormatter->Append (myText->Text(), *myFont->FTFont());
|
||||||
aFormatter.Reset();
|
aFormatter->Format();
|
||||||
|
|
||||||
aFormatter.Append (myText->Text(), *myFont->FTFont());
|
|
||||||
aFormatter.Format();
|
|
||||||
|
|
||||||
OpenGl_TextBuilder aBuilder;
|
OpenGl_TextBuilder aBuilder;
|
||||||
aBuilder.Perform (aFormatter,
|
aBuilder.Perform (aFormatter,
|
||||||
@@ -701,7 +705,7 @@ void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
|
|||||||
myVertsVbo,
|
myVertsVbo,
|
||||||
myTCrdsVbo);
|
myTCrdsVbo);
|
||||||
|
|
||||||
aFormatter.BndBox (myBndBox);
|
aFormatter->BndBox (myBndBox);
|
||||||
if (!myBndVertsVbo.IsNull())
|
if (!myBndVertsVbo.IsNull())
|
||||||
{
|
{
|
||||||
myBndVertsVbo->Release (theCtx.get());
|
myBndVertsVbo->Release (theCtx.get());
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <OpenGl_VertexBufferCompat.hxx>
|
#include <OpenGl_VertexBufferCompat.hxx>
|
||||||
|
|
||||||
#include <Font_FTFont.hxx>
|
#include <Font_FTFont.hxx>
|
||||||
|
#include <Font_TextFormatter.hxx>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -44,7 +45,7 @@ OpenGl_TextBuilder::OpenGl_TextBuilder()
|
|||||||
// function : createGlyphs
|
// function : createGlyphs
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_TextBuilder::createGlyphs (const Font_TextFormatter& theFormatter,
|
void OpenGl_TextBuilder::createGlyphs (const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const Handle(OpenGl_Context)& theCtx,
|
const Handle(OpenGl_Context)& theCtx,
|
||||||
OpenGl_Font& theFont,
|
OpenGl_Font& theFont,
|
||||||
NCollection_Vector<GLuint>& theTextures,
|
NCollection_Vector<GLuint>& theTextures,
|
||||||
@@ -58,51 +59,16 @@ void OpenGl_TextBuilder::createGlyphs (const Font_TextFormatter&
|
|||||||
theTCrdsPerTexture.Clear();
|
theTCrdsPerTexture.Clear();
|
||||||
|
|
||||||
OpenGl_Font::Tile aTile = {Font_Rect(), Font_Rect(), 0u};
|
OpenGl_Font::Tile aTile = {Font_Rect(), Font_Rect(), 0u};
|
||||||
OpenGl_Vec2 aPen (0.0f, 0.0f);
|
for (Font_TextFormatter::Iterator aFormatterIt (*theFormatter, Font_TextFormatter::IterationFilter_ExcludeInvisible);
|
||||||
Standard_Integer aRectsNb = 0;
|
aFormatterIt.More(); aFormatterIt.Next())
|
||||||
Standard_Integer aSymbolsCounter = 0;
|
|
||||||
|
|
||||||
for (NCollection_Utf8Iter anIter = theFormatter.String().Iterator(); *anIter != 0;)
|
|
||||||
{
|
{
|
||||||
const Standard_Utf32Char aCharThis = *anIter;
|
theFont.RenderGlyph (theCtx, aFormatterIt.Symbol(), aTile);
|
||||||
const Standard_Utf32Char aCharNext = *++anIter;
|
|
||||||
|
|
||||||
if (aCharThis == '\x0D' // CR (carriage return)
|
const OpenGl_Vec2& aBottomLeft = theFormatter->BottomLeft (aFormatterIt.SymbolPosition());
|
||||||
|| aCharThis == '\a' // BEL (alarm)
|
aTile.px.Right += aBottomLeft.x();
|
||||||
|| aCharThis == '\f' // FF (form feed) NP (new page)
|
aTile.px.Left += aBottomLeft.x();
|
||||||
|| aCharThis == '\b' // BS (backspace)
|
aTile.px.Bottom += aBottomLeft.y();
|
||||||
|| aCharThis == '\v') // VT (vertical tab)
|
aTile.px.Top += aBottomLeft.y();
|
||||||
{
|
|
||||||
continue; // skip unsupported carriage control codes
|
|
||||||
}
|
|
||||||
else if (aCharThis == '\x0A') // LF (line feed, new line)
|
|
||||||
{
|
|
||||||
aSymbolsCounter = 0;
|
|
||||||
continue; // will be processed on second pass
|
|
||||||
}
|
|
||||||
else if (aCharThis == ' ')
|
|
||||||
{
|
|
||||||
++aSymbolsCounter;
|
|
||||||
aPen.x() += theFont.FTFont()->AdvanceX (' ', aCharNext);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (aCharThis == '\t')
|
|
||||||
{
|
|
||||||
const Standard_Integer aSpacesNum = (theFormatter.TabSize() - (aSymbolsCounter - 1) % theFormatter.TabSize());
|
|
||||||
aPen.x() += theFont.FTFont()->AdvanceX (' ', aCharNext) * Standard_ShortReal(aSpacesNum);
|
|
||||||
aSymbolsCounter += aSpacesNum;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
++aSymbolsCounter;
|
|
||||||
|
|
||||||
theFont.RenderGlyph (theCtx, aCharThis, aTile);
|
|
||||||
|
|
||||||
const OpenGl_Vec2& aTopLeft = theFormatter.TopLeft (aRectsNb);
|
|
||||||
aTile.px.Right += aTopLeft.x();
|
|
||||||
aTile.px.Left += aTopLeft.x();
|
|
||||||
aTile.px.Bottom += aTopLeft.y();
|
|
||||||
aTile.px.Top += aTopLeft.y();
|
|
||||||
const Font_Rect& aRectUV = aTile.uv;
|
const Font_Rect& aRectUV = aTile.uv;
|
||||||
const GLuint aTexture = aTile.texture;
|
const GLuint aTexture = aTile.texture;
|
||||||
|
|
||||||
@@ -139,8 +105,6 @@ void OpenGl_TextBuilder::createGlyphs (const Font_TextFormatter&
|
|||||||
aTCrds.Append (aRectUV.BottomRight (aVec));
|
aTCrds.Append (aRectUV.BottomRight (aVec));
|
||||||
aTCrds.Append (aRectUV.TopRight (aVec));
|
aTCrds.Append (aRectUV.TopRight (aVec));
|
||||||
aTCrds.Append (aRectUV.BottomLeft (aVec));
|
aTCrds.Append (aRectUV.BottomLeft (aVec));
|
||||||
|
|
||||||
++aRectsNb;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +112,7 @@ void OpenGl_TextBuilder::createGlyphs (const Font_TextFormatter&
|
|||||||
// function : CreateTextures
|
// function : CreateTextures
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void OpenGl_TextBuilder::Perform (const Font_TextFormatter& theFormatter,
|
void OpenGl_TextBuilder::Perform (const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const Handle(OpenGl_Context)& theCtx,
|
const Handle(OpenGl_Context)& theCtx,
|
||||||
OpenGl_Font& theFont,
|
OpenGl_Font& theFont,
|
||||||
NCollection_Vector<GLuint>& theTextures,
|
NCollection_Vector<GLuint>& theTextures,
|
||||||
|
@@ -16,8 +16,6 @@
|
|||||||
#ifndef OpenGl_TextBuilder_Header
|
#ifndef OpenGl_TextBuilder_Header
|
||||||
#define OpenGl_TextBuilder_Header
|
#define OpenGl_TextBuilder_Header
|
||||||
|
|
||||||
#include <Font_TextFormatter.hxx>
|
|
||||||
|
|
||||||
#include <OpenGl_Context.hxx>
|
#include <OpenGl_Context.hxx>
|
||||||
#include <OpenGl_Font.hxx>
|
#include <OpenGl_Font.hxx>
|
||||||
#include <OpenGl_VertexBuffer.hxx>
|
#include <OpenGl_VertexBuffer.hxx>
|
||||||
@@ -27,6 +25,7 @@
|
|||||||
#include <NCollection_Vector.hxx>
|
#include <NCollection_Vector.hxx>
|
||||||
#include <NCollection_Handle.hxx>
|
#include <NCollection_Handle.hxx>
|
||||||
|
|
||||||
|
class Font_TextFormatter;
|
||||||
|
|
||||||
//! This class generates primitive array required for rendering textured text using OpenGl_Font instance.
|
//! This class generates primitive array required for rendering textured text using OpenGl_Font instance.
|
||||||
class OpenGl_TextBuilder
|
class OpenGl_TextBuilder
|
||||||
@@ -37,7 +36,7 @@ public:
|
|||||||
Standard_EXPORT OpenGl_TextBuilder();
|
Standard_EXPORT OpenGl_TextBuilder();
|
||||||
|
|
||||||
//! Creates texture quads for the given text.
|
//! Creates texture quads for the given text.
|
||||||
Standard_EXPORT void Perform (const Font_TextFormatter& theFormatter,
|
Standard_EXPORT void Perform (const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const Handle(OpenGl_Context)& theContext,
|
const Handle(OpenGl_Context)& theContext,
|
||||||
OpenGl_Font& theFont,
|
OpenGl_Font& theFont,
|
||||||
NCollection_Vector<GLuint>& theTextures,
|
NCollection_Vector<GLuint>& theTextures,
|
||||||
@@ -46,7 +45,7 @@ public:
|
|||||||
|
|
||||||
protected: //! @name class auxillary methods
|
protected: //! @name class auxillary methods
|
||||||
|
|
||||||
Standard_EXPORT void createGlyphs (const Font_TextFormatter& theFormatter,
|
Standard_EXPORT void createGlyphs (const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const Handle(OpenGl_Context)& theCtx,
|
const Handle(OpenGl_Context)& theCtx,
|
||||||
OpenGl_Font& theFont,
|
OpenGl_Font& theFont,
|
||||||
NCollection_Vector<GLuint>& theTextures,
|
NCollection_Vector<GLuint>& theTextures,
|
||||||
|
@@ -29,10 +29,10 @@
|
|||||||
// function : Draw
|
// function : Draw
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
Handle(Graphic3d_Text) Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
||||||
const Handle(Prs3d_TextAspect)& theAspect,
|
const Handle(Prs3d_TextAspect)& theAspect,
|
||||||
const TCollection_ExtendedString& theText,
|
const TCollection_ExtendedString& theText,
|
||||||
const gp_Pnt& theAttachmentPoint)
|
const gp_Pnt& theAttachmentPoint)
|
||||||
{
|
{
|
||||||
theGroup->SetPrimitivesAspect (theAspect->Aspect());
|
theGroup->SetPrimitivesAspect (theAspect->Aspect());
|
||||||
|
|
||||||
@@ -42,17 +42,18 @@ void Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
|||||||
aText->SetHorizontalAlignment (theAspect->HorizontalJustification());
|
aText->SetHorizontalAlignment (theAspect->HorizontalJustification());
|
||||||
aText->SetVerticalAlignment (theAspect->VerticalJustification());
|
aText->SetVerticalAlignment (theAspect->VerticalJustification());
|
||||||
theGroup->AddText (aText);
|
theGroup->AddText (aText);
|
||||||
|
return aText;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// function : Draw
|
// function : Draw
|
||||||
// purpose :
|
// purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
void Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
Handle(Graphic3d_Text) Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
||||||
const Handle(Prs3d_TextAspect)& theAspect,
|
const Handle(Prs3d_TextAspect)& theAspect,
|
||||||
const TCollection_ExtendedString& theText,
|
const TCollection_ExtendedString& theText,
|
||||||
const gp_Ax2& theOrientation,
|
const gp_Ax2& theOrientation,
|
||||||
const Standard_Boolean theHasOwnAnchor)
|
const Standard_Boolean theHasOwnAnchor)
|
||||||
{
|
{
|
||||||
theGroup->SetPrimitivesAspect (theAspect->Aspect());
|
theGroup->SetPrimitivesAspect (theAspect->Aspect());
|
||||||
|
|
||||||
@@ -63,4 +64,5 @@ void Prs3d_Text::Draw (const Handle(Graphic3d_Group)& theGroup,
|
|||||||
aText->SetHorizontalAlignment (theAspect->HorizontalJustification());
|
aText->SetHorizontalAlignment (theAspect->HorizontalJustification());
|
||||||
aText->SetVerticalAlignment (theAspect->VerticalJustification());
|
aText->SetVerticalAlignment (theAspect->VerticalJustification());
|
||||||
theGroup->AddText (aText);
|
theGroup->AddText (aText);
|
||||||
|
return aText;
|
||||||
}
|
}
|
||||||
|
@@ -37,10 +37,11 @@ public:
|
|||||||
//! @param theAspect presentation attributes
|
//! @param theAspect presentation attributes
|
||||||
//! @param theText text to draw
|
//! @param theText text to draw
|
||||||
//! @param theAttachmentPoint attachment point
|
//! @param theAttachmentPoint attachment point
|
||||||
Standard_EXPORT static void Draw (const Handle(Graphic3d_Group)& theGroup,
|
//! @return text to draw
|
||||||
const Handle(Prs3d_TextAspect)& theAspect,
|
Standard_EXPORT static Handle(Graphic3d_Text) Draw (const Handle(Graphic3d_Group)& theGroup,
|
||||||
const TCollection_ExtendedString& theText,
|
const Handle(Prs3d_TextAspect)& theAspect,
|
||||||
const gp_Pnt& theAttachmentPoint);
|
const TCollection_ExtendedString& theText,
|
||||||
|
const gp_Pnt& theAttachmentPoint);
|
||||||
|
|
||||||
//! Draws the text label.
|
//! Draws the text label.
|
||||||
//! @param theGroup group to add primitives
|
//! @param theGroup group to add primitives
|
||||||
@@ -48,11 +49,12 @@ public:
|
|||||||
//! @param theText text to draw
|
//! @param theText text to draw
|
||||||
//! @param theOrientation location and orientation specified in the model 3D space
|
//! @param theOrientation location and orientation specified in the model 3D space
|
||||||
//! @param theHasOwnAnchor
|
//! @param theHasOwnAnchor
|
||||||
Standard_EXPORT static void Draw (const Handle(Graphic3d_Group)& theGroup,
|
//! @return text to draw
|
||||||
const Handle(Prs3d_TextAspect)& theAspect,
|
Standard_EXPORT static Handle(Graphic3d_Text) Draw (const Handle(Graphic3d_Group)& theGroup,
|
||||||
const TCollection_ExtendedString& theText,
|
const Handle(Prs3d_TextAspect)& theAspect,
|
||||||
const gp_Ax2& theOrientation,
|
const TCollection_ExtendedString& theText,
|
||||||
const Standard_Boolean theHasOwnAnchor = Standard_True);
|
const gp_Ax2& theOrientation,
|
||||||
|
const Standard_Boolean theHasOwnAnchor = Standard_True);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@@ -15,12 +15,14 @@
|
|||||||
|
|
||||||
#include <StdPrs_BRepTextBuilder.hxx>
|
#include <StdPrs_BRepTextBuilder.hxx>
|
||||||
|
|
||||||
|
#include <Font_TextFormatter.hxx>
|
||||||
|
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
// Function : Perfrom
|
// Function : Perfrom
|
||||||
// Purpose :
|
// Purpose :
|
||||||
// =======================================================================
|
// =======================================================================
|
||||||
TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& theFont,
|
TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& theFont,
|
||||||
const Font_TextFormatter& theFormatter,
|
const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const gp_Ax3& thePenLoc)
|
const gp_Ax3& thePenLoc)
|
||||||
{
|
{
|
||||||
gp_Trsf aTrsf;
|
gp_Trsf aTrsf;
|
||||||
@@ -31,34 +33,20 @@ TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont& theFont,
|
|||||||
|
|
||||||
myBuilder.MakeCompound (aResult);
|
myBuilder.MakeCompound (aResult);
|
||||||
|
|
||||||
Standard_Integer aSymbolCounter = 0;
|
Standard_Real aScaleUnits = theFont.Scale();
|
||||||
Standard_Real aScaleUnits = theFont.Scale();
|
for (Font_TextFormatter::Iterator aFormatterIt (*theFormatter, Font_TextFormatter::IterationFilter_ExcludeInvisible);
|
||||||
for (NCollection_Utf8Iter anIter = theFormatter.String().Iterator(); *anIter != 0; ++anIter)
|
aFormatterIt.More(); aFormatterIt.Next())
|
||||||
{
|
{
|
||||||
const Standard_Utf32Char aCharCurr = *anIter;
|
const NCollection_Vec2<Standard_ShortReal>& aCorner = theFormatter->BottomLeft (aFormatterIt.SymbolPosition());
|
||||||
if (aCharCurr == '\x0D' // CR (carriage return)
|
|
||||||
|| aCharCurr == '\a' // BEL (alarm)
|
|
||||||
|| aCharCurr == '\f' // FF (form feed) NP (new page)
|
|
||||||
|| aCharCurr == '\b' // BS (backspace)
|
|
||||||
|| aCharCurr == '\v' // VT (vertical tab)
|
|
||||||
|| aCharCurr == ' '
|
|
||||||
|| aCharCurr == '\t'
|
|
||||||
|| aCharCurr == '\n')
|
|
||||||
{
|
|
||||||
continue; // skip unsupported carriage control codes
|
|
||||||
}
|
|
||||||
|
|
||||||
const NCollection_Vec2<Standard_ShortReal>& aCorner = theFormatter.TopLeft (aSymbolCounter);
|
|
||||||
aPen.SetCoord (aCorner.x() * aScaleUnits, aCorner.y() * aScaleUnits, 0.0);
|
aPen.SetCoord (aCorner.x() * aScaleUnits, aCorner.y() * aScaleUnits, 0.0);
|
||||||
aGlyphShape = theFont.RenderGlyph (aCharCurr);
|
aGlyphShape = theFont.RenderGlyph (aFormatterIt.Symbol());
|
||||||
if (!aGlyphShape.IsNull())
|
if (!aGlyphShape.IsNull())
|
||||||
{
|
{
|
||||||
aTrsf.SetTranslation (gp_Vec (aPen));
|
aTrsf.SetTranslation (gp_Vec (aPen));
|
||||||
aGlyphShape.Move (aTrsf);
|
aGlyphShape.Move (aTrsf);
|
||||||
myBuilder.Add (aResult, aGlyphShape);
|
myBuilder.Add (aResult, aGlyphShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
++aSymbolCounter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aTrsf.SetTransformation (thePenLoc, gp_Ax3 (gp::XOY()));
|
aTrsf.SetTransformation (thePenLoc, gp_Ax3 (gp::XOY()));
|
||||||
@@ -77,13 +65,13 @@ TopoDS_Shape StdPrs_BRepTextBuilder::Perform (StdPrs_BRepFont&
|
|||||||
const Graphic3d_HorizontalTextAlignment theHAlign,
|
const Graphic3d_HorizontalTextAlignment theHAlign,
|
||||||
const Graphic3d_VerticalTextAlignment theVAlign)
|
const Graphic3d_VerticalTextAlignment theVAlign)
|
||||||
{
|
{
|
||||||
Font_TextFormatter aFormatter;
|
Handle(Font_TextFormatter) aFormatter = new Font_TextFormatter();
|
||||||
|
|
||||||
aFormatter.Reset();
|
aFormatter->Reset();
|
||||||
aFormatter.SetupAlignment (theHAlign, theVAlign);
|
aFormatter->SetupAlignment (theHAlign, theVAlign);
|
||||||
|
|
||||||
aFormatter.Append (theString, *(reinterpret_cast<Font_FTFont*> (&theFont)));
|
aFormatter->Append (theString, *(reinterpret_cast<Font_FTFont*> (&theFont)));
|
||||||
aFormatter.Format();
|
aFormatter->Format();
|
||||||
|
|
||||||
return Perform (theFont, aFormatter, thePenLoc);
|
return Perform (theFont, aFormatter, thePenLoc);
|
||||||
}
|
}
|
||||||
|
@@ -25,13 +25,12 @@ class StdPrs_BRepTextBuilder
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Render text as BRep shape.
|
//! Render text as BRep shape.
|
||||||
//! @param theString text in UTF-8 encoding
|
//! @param theFormatter formatter which defines aligned text
|
||||||
//! @param thePenLoc start position and orientation on the baseline
|
//! @param thePenLoc start position and orientation on the baseline
|
||||||
//! @param theFormatter formatter which defines alignment for the text
|
|
||||||
//! @return result shape with pen transformation applied as shape location
|
//! @return result shape with pen transformation applied as shape location
|
||||||
Standard_EXPORT TopoDS_Shape Perform (StdPrs_BRepFont& theFont,
|
Standard_EXPORT TopoDS_Shape Perform (StdPrs_BRepFont& theFont,
|
||||||
const Font_TextFormatter& theFormatter,
|
const Handle(Font_TextFormatter)& theFormatter,
|
||||||
const gp_Ax3& thePenLoc = gp_Ax3());
|
const gp_Ax3& thePenLoc = gp_Ax3());
|
||||||
//! Render text as BRep shape.
|
//! Render text as BRep shape.
|
||||||
//! @param theString text in UTF-8 encoding
|
//! @param theString text in UTF-8 encoding
|
||||||
//! @param thePenLoc start position and orientation on the baseline
|
//! @param thePenLoc start position and orientation on the baseline
|
||||||
|
@@ -2390,6 +2390,8 @@ static int VDrawText (Draw_Interpretor& theDI,
|
|||||||
gp_Dir aDirection;
|
gp_Dir aDirection;
|
||||||
gp_Pnt aPos;
|
gp_Pnt aPos;
|
||||||
|
|
||||||
|
|
||||||
|
Handle(Font_TextFormatter) aTextFormatter;
|
||||||
for (; anArgIt < theArgsNb; ++anArgIt)
|
for (; anArgIt < theArgsNb; ++anArgIt)
|
||||||
{
|
{
|
||||||
TCollection_AsciiString aParam (theArgVec[anArgIt]);
|
TCollection_AsciiString aParam (theArgVec[anArgIt]);
|
||||||
@@ -2517,6 +2519,20 @@ static int VDrawText (Draw_Interpretor& theDI,
|
|||||||
|
|
||||||
aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
|
aTextPrs->SetHeight (Draw::Atof(theArgVec[anArgIt]));
|
||||||
}
|
}
|
||||||
|
else if (aParam == "-wrapping")
|
||||||
|
{
|
||||||
|
if (++anArgIt >= theArgsNb)
|
||||||
|
{
|
||||||
|
Message::SendFail() << "Syntax error: wrong number of values for parameter '" << aParam << "'";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aTextFormatter.IsNull())
|
||||||
|
{
|
||||||
|
aTextFormatter = new Font_TextFormatter();
|
||||||
|
}
|
||||||
|
aTextFormatter->SetWrapping ((Standard_ShortReal)Draw::Atof(theArgVec[anArgIt]));
|
||||||
|
}
|
||||||
else if (aParam == "-aspect")
|
else if (aParam == "-aspect")
|
||||||
{
|
{
|
||||||
if (++anArgIt >= theArgsNb)
|
if (++anArgIt >= theArgsNb)
|
||||||
@@ -2662,6 +2678,8 @@ static int VDrawText (Draw_Interpretor& theDI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aTextPrs->SetTextFormatter (aTextFormatter);
|
||||||
|
|
||||||
if (aHasPlane)
|
if (aHasPlane)
|
||||||
{
|
{
|
||||||
aTextPrs->SetOrientation3D (gp_Ax2 (aPos, aNormal, aDirection));
|
aTextPrs->SetOrientation3D (gp_Ax2 (aPos, aNormal, aDirection));
|
||||||
@@ -6628,6 +6646,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
|
|||||||
"\n\t\t: [-angle angle=0]"
|
"\n\t\t: [-angle angle=0]"
|
||||||
"\n\t\t: [-zoom {0|1}=0]"
|
"\n\t\t: [-zoom {0|1}=0]"
|
||||||
"\n\t\t: [-height height=16]"
|
"\n\t\t: [-height height=16]"
|
||||||
|
"\n\t\t: [-wrapping width=40]"
|
||||||
"\n\t\t: [-aspect {regular|bold|italic|boldItalic}=regular]"
|
"\n\t\t: [-aspect {regular|bold|italic|boldItalic}=regular]"
|
||||||
"\n\t\t: [-font font=Times]"
|
"\n\t\t: [-font font=Times]"
|
||||||
"\n\t\t: [-2d]"
|
"\n\t\t: [-2d]"
|
||||||
|
27
tests/3rdparty/text3d/text_wrapped
vendored
Normal file
27
tests/3rdparty/text3d/text_wrapped
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
puts "==========="
|
||||||
|
puts "0030537: Visualization - wrapping text in font text formatter"
|
||||||
|
puts ""
|
||||||
|
puts "==========="
|
||||||
|
|
||||||
|
pload MODELING VISUALIZATION
|
||||||
|
vinit View1
|
||||||
|
vclear
|
||||||
|
vaxo
|
||||||
|
|
||||||
|
box b1 10 0 360 10 180 40
|
||||||
|
vdisplay b1
|
||||||
|
vdrawtext t1 "Top text on plane yOz\n(not wrapped)" -pos 10 5 400 -color green -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1
|
||||||
|
|
||||||
|
box b2 10 0 240 10 130 60
|
||||||
|
vdisplay b2
|
||||||
|
vdrawtext t2 "Top text on plane yOz\n(wrapping=120)" -pos 10 5 300 -color green -wrapping 120 -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1
|
||||||
|
|
||||||
|
box b3 10 0 60 10 60 150
|
||||||
|
vdisplay b3
|
||||||
|
vdrawtext t3 "Top text on plane yOz\n(wrapping=50)" -pos 10 5 200 -color green -wrapping 50 -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1
|
||||||
|
|
||||||
|
vright
|
||||||
|
vfit
|
||||||
|
vzoom 0.9
|
||||||
|
|
||||||
|
vdump $imagedir/${casename}.png
|
Reference in New Issue
Block a user