]> OCCT Git - occt.git/commitdiff
0032992: Visualization - Font_TextFormatter should wrap words when possible
authorngavrilo <ngavrilo@opencascade.com>
Thu, 14 Jul 2022 13:53:58 +0000 (16:53 +0300)
committersmoskvin <smoskvin@opencascade.com>
Tue, 2 Aug 2022 14:13:03 +0000 (17:13 +0300)
src/Font/Font_TextFormatter.cxx
src/Font/Font_TextFormatter.hxx
src/ViewerTest/ViewerTest_ObjectCommands.cxx
tests/opengl/data/text/text_wrapped

index eddc4bc83ef3b5a4469dab774026fb62aa2d282b..e8d2d6b2f44bfc2348c9c7ea66ff2b1b0cfaa652 100644 (file)
@@ -60,6 +60,7 @@ Font_TextFormatter::Font_TextFormatter()
   myAlignY (Graphic3d_VTA_TOP),
   myTabSize (8),
   myWrappingWidth (0.0f),
+  myIsWordWrapping (true),
   myLastSymbolWidth (0.0f),
   myMaxSymbolWidth (0.0f),
   //
@@ -249,6 +250,7 @@ void Font_TextFormatter::Format()
     }
   }
 
+  Standard_Utf32Char aCharPrev = 0;
   for (Font_TextFormatter::Iterator aFormatterIt(*this);
        aFormatterIt.More(); aFormatterIt.Next())
   {
@@ -269,12 +271,30 @@ void Font_TextFormatter::Format()
       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
+      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
         newLine (aLastRect, aMaxLineWidth);
       }
     }
+    aCharPrev = aCharThis;
   }
 
   myBndWidth = aMaxLineWidth;
index 1d917f22bb43a12842808118ce9879f92d3bb4e9..5ef5d0aeae198cb46f60f4e51fb732458da9504f 100755 (executable)
@@ -220,6 +220,12 @@ public:
   //! Returns text maximum width, zero means that the text is not bounded by width
   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.
   inline Standard_ShortReal ResultWidth() const
   {
@@ -274,6 +280,14 @@ public:
     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)
 
 protected: //! @name class auxiliary methods
@@ -288,6 +302,7 @@ protected: //! @name configuration
   Graphic3d_VerticalTextAlignment   myAlignY;  //!< vertical   alignment style
   Standard_Integer                  myTabSize; //!< horizontal tabulation width (number of space symbols)
   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                myMaxSymbolWidth; //!< maximum symbol width of the formatter string
 
index d2f9763539fb7f31f7f5b983c9cb7baa13f1e15a..98ae2e622af82669b08bce9649ab6a4ac8504be0 100644 (file)
@@ -2500,6 +2500,11 @@ static int VDrawText (Draw_Interpretor& theDI,
       }
       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"
           && anArgIt + 1 < theArgsNb)
     {
@@ -6925,6 +6930,7 @@ vdrawtext name text
           [-zoom {0|1}]=0
           [-height height]=16
           [-wrapping width]=40
+          [-wordwrapping {0|1}]=1
           [-aspect {regular|bold|italic|boldItalic}]=regular
           [-font font]=Times
           [-2d] [-perspos {X Y Z}]={0 0 0}
index 3063a2e1be442d3c18c066fb9a74a48a95ef07a9..9117431357b89c161ec7018c60359fdfadc4afa2 100644 (file)
@@ -4,21 +4,30 @@ puts ""
 puts "==========="
 
 pload MODELING VISUALIZATION
-vinit View1
+vinit View1 -width 500
 vclear
 vaxo
 
-box b1 10 0 360 10 180 40
+box b1 10 0 460 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
+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
-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
-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
 vfit