1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0032992: Visualization - Font_TextFormatter should wrap words when possible

This commit is contained in:
ngavrilo 2022-07-14 16:53:58 +03:00 committed by smoskvin
parent e1b097eb67
commit 6072d3093c
4 changed files with 58 additions and 8 deletions

View File

@ -60,6 +60,7 @@ Font_TextFormatter::Font_TextFormatter()
myAlignY (Graphic3d_VTA_TOP), myAlignY (Graphic3d_VTA_TOP),
myTabSize (8), myTabSize (8),
myWrappingWidth (0.0f), myWrappingWidth (0.0f),
myIsWordWrapping (true),
myLastSymbolWidth (0.0f), myLastSymbolWidth (0.0f),
myMaxSymbolWidth (0.0f), myMaxSymbolWidth (0.0f),
// //
@ -249,6 +250,7 @@ void Font_TextFormatter::Format()
} }
} }
Standard_Utf32Char aCharPrev = 0;
for (Font_TextFormatter::Iterator aFormatterIt(*this); for (Font_TextFormatter::Iterator aFormatterIt(*this);
aFormatterIt.More(); aFormatterIt.Next()) aFormatterIt.More(); aFormatterIt.Next())
{ {
@ -269,12 +271,30 @@ void Font_TextFormatter::Format()
Font_Rect aBndBox; Font_Rect aBndBox;
GlyphBoundingBox (aRectIter, aBndBox); GlyphBoundingBox (aRectIter, aBndBox);
const Standard_ShortReal aNextXPos = aBndBox.Right - BottomLeft (aFirstCornerId).x(); const Standard_ShortReal aNextXPos = aBndBox.Right - BottomLeft (aFirstCornerId).x();
if (aNextXPos > aMaxLineWidth) // wrap the line and do processing of the symbol Standard_Boolean isCurWordFits = true;
if(myIsWordWrapping && IsSeparatorSymbol(aCharPrev))
{
for (Font_TextFormatter::Iterator aWordIt = aFormatterIt; aWordIt.More(); aWordIt.Next())
{
if (IsSeparatorSymbol(aWordIt.Symbol()))
{
break;
}
float aWordWidthPx = myCorners[aWordIt.SymbolPosition()].x() - myCorners[aRectIter].x();
if (aNextXPos + aWordWidthPx > aMaxLineWidth)
{
isCurWordFits = false;
break;
}
}
}
if (aNextXPos > aMaxLineWidth || !isCurWordFits) // wrap the line and do processing of the symbol
{ {
const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line
newLine (aLastRect, aMaxLineWidth); newLine (aLastRect, aMaxLineWidth);
} }
} }
aCharPrev = aCharThis;
} }
myBndWidth = aMaxLineWidth; myBndWidth = aMaxLineWidth;

View File

@ -220,6 +220,12 @@ public:
//! Returns text maximum width, zero means that the text is not bounded by width //! Returns text maximum width, zero means that the text is not bounded by width
Standard_ShortReal Wrapping() const { return myWrappingWidth; } Standard_ShortReal Wrapping() const { return myWrappingWidth; }
//! returns TRUE when trying not to break words when wrapping text
Standard_Boolean WordWrapping () const { return myIsWordWrapping; }
//! returns TRUE when trying not to break words when wrapping text
void SetWordWrapping (const Standard_Boolean theIsWordWrapping) { myIsWordWrapping = theIsWordWrapping; }
//! @return width of formatted text. //! @return width of formatted text.
inline Standard_ShortReal ResultWidth() const inline Standard_ShortReal ResultWidth() const
{ {
@ -274,6 +280,14 @@ public:
return Standard_False; return Standard_False;
} }
//! Returns true if the symbol separates words when wrapping is enabled
static Standard_Boolean IsSeparatorSymbol (const Standard_Utf32Char& theSymbol)
{
return theSymbol == '\x0A' // new line
|| theSymbol == ' ' // space
|| theSymbol == '\x09'; // tab
}
DEFINE_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient) DEFINE_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient)
protected: //! @name class auxiliary methods protected: //! @name class auxiliary methods
@ -288,6 +302,7 @@ protected: //! @name configuration
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 myWrappingWidth; //!< text is wrapped by the width if defined (more 0)
Standard_Boolean myIsWordWrapping; //!< if TRUE try not to break words when wrapping text (true by default)
Standard_ShortReal myLastSymbolWidth; //!< width of the last symbol Standard_ShortReal myLastSymbolWidth; //!< width of the last symbol
Standard_ShortReal myMaxSymbolWidth; //!< maximum symbol width of the formatter string Standard_ShortReal myMaxSymbolWidth; //!< maximum symbol width of the formatter string

View File

@ -2500,6 +2500,11 @@ static int VDrawText (Draw_Interpretor& theDI,
} }
aTextFormatter->SetWrapping ((Standard_ShortReal)Draw::Atof(theArgVec[++anArgIt])); aTextFormatter->SetWrapping ((Standard_ShortReal)Draw::Atof(theArgVec[++anArgIt]));
} }
else if (aParam == "-wordwrapping")
{
const bool isWordWrapping = Draw::ParseOnOffNoIterator(theArgsNb, theArgVec, anArgIt);
aTextFormatter->SetWordWrapping(isWordWrapping);
}
else if (aParam == "-aspect" else if (aParam == "-aspect"
&& anArgIt + 1 < theArgsNb) && anArgIt + 1 < theArgsNb)
{ {
@ -6925,6 +6930,7 @@ vdrawtext name text
[-zoom {0|1}]=0 [-zoom {0|1}]=0
[-height height]=16 [-height height]=16
[-wrapping width]=40 [-wrapping width]=40
[-wordwrapping {0|1}]=1
[-aspect {regular|bold|italic|boldItalic}]=regular [-aspect {regular|bold|italic|boldItalic}]=regular
[-font font]=Times [-font font]=Times
[-2d] [-perspos {X Y Z}]={0 0 0} [-2d] [-perspos {X Y Z}]={0 0 0}

View File

@ -4,21 +4,30 @@ puts ""
puts "===========" puts "==========="
pload MODELING VISUALIZATION pload MODELING VISUALIZATION
vinit View1 vinit View1 -width 500
vclear vclear
vaxo vaxo
box b1 10 0 360 10 180 40 box b1 10 0 460 10 180 40
vdisplay b1 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 vdrawtext t1 "Top text on plane yOz\n(not wrapped)" -pos 10 5 500 -color green -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1
box b2 10 0 240 10 130 60 box b2 10 0 340 10 130 60
vdisplay b2 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 vdrawtext t2 "Top text on plane yOz\n(wrapping=120)" -pos 10 5 400 -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 box b3 10 0 160 10 60 150
vdisplay b3 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 vdrawtext t3 "Top text on plane yOz\n(wrapping=50)" -pos 10 5 300 -color green -wrapping 50 -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1
box b4 10 200 400 10 130 100
vdisplay b4
vdrawtext t4 "Top text on plane yOz\n(wrapping=120, word wrapping disabled)" -pos 10 205 500 -color green -wrapping 120 -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1 -wordwrapping 0
box b5 10 200 160 10 60 200
vdisplay b5
vdrawtext t5 "Top text on plane yOz\n(wrapping=50, word wrapping disabled)" -pos 10 205 350 -color green -wrapping 50 -plane 1 0 0 0 1 0 -valign top -font SansFont -zoom 1 -wordwrapping 0
vright vright
vfit vfit