Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:30

0001 // Created on: 2013-01-29
0002 // Created by: Kirill GAVRILOV
0003 // Copyright (c) 2013-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef Font_TextFormatter_Header
0017 #define Font_TextFormatter_Header
0018 
0019 #include <Font_Rect.hxx>
0020 #include <Graphic3d_HorizontalTextAlignment.hxx>
0021 #include <Graphic3d_VerticalTextAlignment.hxx>
0022 #include <NCollection_DataMap.hxx>
0023 #include <NCollection_Vector.hxx>
0024 #include <NCollection_String.hxx>
0025 
0026 class Font_FTFont;
0027 
0028 DEFINE_STANDARD_HANDLE(Font_TextFormatter, Standard_Transient)
0029 
0030 //! This class is intended to prepare formatted text by using:<br>
0031 //! - font to string combination,<br>
0032 //! - alignment,<br>
0033 //! - wrapping.<br>
0034 //!
0035 //! After text formatting, each symbol of formatted text is placed in some position.
0036 //! Further work with the formatter is using an iterator.
0037 //! The iterator gives an access to each symbol inside the initial row.
0038 //! Also it's possible to get only significant/writable symbols of the text.<br>
0039 //! Formatter gives an access to geometrical position of a symbol by the symbol index in the text.<br>
0040 //! Example of correspondence of some text symbol to an index in "row_1\n\nrow_2\n":<br>
0041 //! "row_1\n"  - 0-5 indices;<br>
0042 //! "\n"       - 6 index;<br>
0043 //! "\n"       - 7 index;<br>
0044 //! "row_2\n"  - 8-13 indices.<br>
0045 //! Pay attention that fonts should have the same LineSpacing value for correct formatting.<br>
0046 //! Example of the formatter using:
0047 //! @code
0048 //!   Handle(Font_TextFormatter) aFormatter = new Font_TextFormatter();
0049 //!   aFormatter->Append(text_1, aFont1);
0050 //!   aFormatter->Append(text_2, aFont2);
0051 //!   // setting of additional properties such as wrapping or alignment
0052 //!   aFormatter->Format();
0053 //! @endcode
0054 class Font_TextFormatter : public Standard_Transient
0055 {
0056 public:
0057   //! Iteration filter flags. Command symbols are skipped with any filter.
0058   enum IterationFilter
0059   {
0060     IterationFilter_None             = 0x0000, //!< no filter
0061     IterationFilter_ExcludeInvisible = 0x0002, //!< exclude ' ', '\t', '\n'
0062   };
0063 
0064   //! Iterator through formatted symbols.
0065   //! It's possible to filter returned symbols to have only significant ones.
0066   class Iterator
0067   {
0068   public:
0069     //! Constructor with initialization.
0070     Iterator (const Font_TextFormatter& theFormatter,
0071               IterationFilter theFilter = IterationFilter_None)
0072     : myFilter (theFilter), myIter (theFormatter.myString.Iterator()), mySymbolChar (0), mySymbolCharNext (0)
0073     {
0074       mySymbolPosition = readNextSymbol (-1, mySymbolChar);
0075       mySymbolNext = readNextSymbol (mySymbolPosition, mySymbolCharNext);
0076     }
0077 
0078     //! Returns TRUE if iterator points to a valid item.
0079     Standard_Boolean More() const { return mySymbolPosition >= 0; }
0080 
0081     //! Returns TRUE if next item exists
0082     Standard_Boolean HasNext() const { return mySymbolNext >= 0; }
0083 
0084     //! Returns current symbol.
0085     Standard_Utf32Char Symbol() const { return mySymbolChar; }
0086 
0087     //! Returns the next symbol if exists.
0088     Standard_Utf32Char SymbolNext() const { return mySymbolCharNext; }
0089 
0090     //! Returns current symbol position.
0091     Standard_Integer SymbolPosition() const { return mySymbolPosition; }
0092 
0093     //! Returns the next symbol position.
0094     Standard_Integer SymbolPositionNext() const { return mySymbolNext; }
0095 
0096     //! Moves to the next item.
0097     void Next()
0098     {
0099       mySymbolPosition = mySymbolNext;
0100       mySymbolChar = mySymbolCharNext;
0101       mySymbolNext = readNextSymbol (mySymbolPosition, mySymbolCharNext);
0102     }
0103 
0104   protected:
0105     //! Finds index of the next symbol
0106     Standard_Integer readNextSymbol (const Standard_Integer theSymbolStartingFrom,
0107                                      Standard_Utf32Char& theSymbolChar)
0108     {
0109       Standard_Integer aNextSymbol = theSymbolStartingFrom;
0110       for (; *myIter != 0; ++myIter)
0111       {
0112         const Standard_Utf32Char aCharCurr = *myIter;
0113         if (Font_TextFormatter::IsCommandSymbol (aCharCurr))
0114         {
0115           continue; // skip unsupported carriage control codes
0116         }
0117         aNextSymbol++;
0118         if ((myFilter & IterationFilter_ExcludeInvisible) != 0)
0119         {
0120           if (aCharCurr == '\x0A'|| // LF (line feed, new line)
0121               aCharCurr == ' ' ||
0122               aCharCurr == '\t')
0123           {
0124             continue;
0125           }
0126         }
0127         ++myIter;
0128         theSymbolChar = aCharCurr;
0129         return aNextSymbol; // found the first next, not command and not filtered symbol
0130       }
0131       return -1; // the next symbol is not found
0132     }
0133 
0134   protected:
0135     IterationFilter      myFilter; //!< possibility to filter not-necessary symbols
0136     NCollection_Utf8Iter myIter; //!< the next symbol iterator value over the text formatter string
0137     Standard_Integer     mySymbolPosition; //!< the current position
0138     Standard_Utf32Char   mySymbolChar; //!< the current symbol
0139     Standard_Integer     mySymbolNext; //!< position of the next symbol in iterator, if zero, the iterator is finished
0140     Standard_Utf32Char   mySymbolCharNext; //!< the current symbol
0141   };
0142 
0143   //! Default constructor.
0144   Standard_EXPORT Font_TextFormatter();
0145 
0146   //! Setup alignment style.
0147   Standard_EXPORT void SetupAlignment (const Graphic3d_HorizontalTextAlignment theAlignX,
0148                                        const Graphic3d_VerticalTextAlignment   theAlignY);
0149 
0150   //! Reset current progress.
0151   Standard_EXPORT void Reset();
0152 
0153   //! Render specified text to inner buffer.
0154   Standard_EXPORT void Append (const NCollection_String& theString,
0155                                Font_FTFont&              theFont);
0156 
0157   //! Perform formatting on the buffered text.
0158   //! Should not be called more than once after initialization!
0159   Standard_EXPORT void Format();
0160 
0161   Standard_DEPRECATED("BottomLeft should be used instead")
0162   const NCollection_Vec2<Standard_ShortReal>& TopLeft (const Standard_Integer theIndex) const
0163   {
0164     return BottomLeft (theIndex);
0165   }
0166 
0167   //! Returns specific glyph rectangle.
0168   const NCollection_Vec2<Standard_ShortReal>& BottomLeft (const Standard_Integer theIndex) const
0169   { return myCorners.Value (theIndex); }
0170 
0171   //! Returns current rendering string.
0172   inline const NCollection_String& String() const
0173   {
0174     return myString;
0175   }
0176 
0177   //! Returns symbol bounding box
0178   //! @param bounding box.
0179   Standard_EXPORT Standard_Boolean GlyphBoundingBox (const Standard_Integer theIndex,
0180                                                      Font_Rect& theBndBox) const;
0181 
0182   //! Returns the line height
0183   //! @param theIndex a line index, obtained by LineIndex()
0184   Standard_ShortReal LineHeight (const Standard_Integer theIndex) const
0185   { return theIndex == 0 ? myAscender : myLineSpacing; }
0186 
0187   //! Returns width of a line
0188   Standard_EXPORT Standard_ShortReal LineWidth (const Standard_Integer theIndex) const;
0189 
0190   //! Returns true if the symbol by the index is '\n'. The width of the symbol is zero.
0191   Standard_EXPORT Standard_Boolean IsLFSymbol (const Standard_Integer theIndex) const;
0192 
0193   //! Returns position of the first symbol in a line using alignment
0194   Standard_EXPORT Standard_ShortReal FirstPosition() const;
0195 
0196   //! Returns column index of the corner index in the current line
0197   Standard_EXPORT Standard_Integer LinePositionIndex (const Standard_Integer theIndex) const;
0198 
0199   //! Returns row index of the corner index among text lines
0200   Standard_EXPORT Standard_Integer LineIndex (const Standard_Integer theIndex) const;
0201 
0202   //! Returns tab size.
0203   inline Standard_Integer TabSize() const
0204   {
0205     return myTabSize;
0206   }
0207 
0208   //! Returns horizontal alignment style
0209   Graphic3d_HorizontalTextAlignment HorizontalTextAlignment() const { return myAlignX; }
0210 
0211   //! Returns vertical   alignment style
0212   Graphic3d_VerticalTextAlignment VerticalTextAlignment() const { return myAlignY; }
0213 
0214   //! Sets text wrapping width, zero means that the text is not bounded by width
0215   void SetWrapping (const Standard_ShortReal theWidth) { myWrappingWidth = theWidth; }
0216 
0217   //! Returns text maximum width, zero means that the text is not bounded by width
0218   Standard_Boolean HasWrapping() const { return myWrappingWidth > 0; }
0219 
0220   //! Returns text maximum width, zero means that the text is not bounded by width
0221   Standard_ShortReal Wrapping() const { return myWrappingWidth; }
0222 
0223   //! returns TRUE when trying not to break words when wrapping text
0224   Standard_Boolean WordWrapping () const { return myIsWordWrapping; }
0225 
0226   //! returns TRUE when trying not to break words when wrapping text
0227   void SetWordWrapping (const Standard_Boolean theIsWordWrapping)  { myIsWordWrapping = theIsWordWrapping; }
0228 
0229   //! @return width of formatted text.
0230   inline Standard_ShortReal ResultWidth() const
0231   {
0232     return myBndWidth;
0233   }
0234 
0235   //! @return height of formatted text.
0236   inline Standard_ShortReal ResultHeight() const
0237   {
0238     return myLineSpacing * Standard_ShortReal(myLinesNb);
0239   }
0240 
0241   //! @return maximum width of the text symbol
0242   Standard_ShortReal MaximumSymbolWidth() const { return myMaxSymbolWidth; }
0243 
0244   //! @param bounding box.
0245   inline void BndBox (Font_Rect& theBndBox) const
0246   {
0247     theBndBox.Left = 0.0f;
0248     switch (myAlignX)
0249     {
0250       default:
0251       case Graphic3d_HTA_LEFT:  theBndBox.Right  =  myBndWidth; break;
0252       case Graphic3d_HTA_RIGHT: theBndBox.Right  = -myBndWidth; break;
0253       case Graphic3d_HTA_CENTER:
0254       {
0255         theBndBox.Left  = -0.5f * myBndWidth;
0256         theBndBox.Right =  0.5f * myBndWidth;
0257         break;
0258       }
0259     }
0260     theBndBox.Top    = myBndTop;
0261     theBndBox.Bottom = theBndBox.Top - myLineSpacing * Standard_ShortReal(myLinesNb);
0262   }
0263 
0264   //! Returns internal container of the top left corners of a formatted rectangles.
0265   const NCollection_Vector < NCollection_Vec2<Standard_ShortReal> >& Corners() const { return myCorners; }
0266 
0267   //! Returns container of each line position at LF in formatted text
0268   const NCollection_Vector<Standard_ShortReal>& NewLines() const { return myNewLines; }
0269 
0270   //! Returns true if the symbol is CR, BEL, FF, NP, BS or VT
0271   static inline Standard_Boolean IsCommandSymbol (const Standard_Utf32Char& theSymbol)
0272   {
0273     if (theSymbol == '\x0D' // CR  (carriage return)
0274      || theSymbol == '\a'   // BEL (alarm)
0275      || theSymbol == '\f'   // FF  (form feed) NP (new page)
0276      || theSymbol == '\b'   // BS  (backspace)
0277      || theSymbol == '\v')  // VT  (vertical tab)
0278       return Standard_True;
0279 
0280     return Standard_False;
0281   }
0282 
0283   //! Returns true if the symbol separates words when wrapping is enabled
0284   static Standard_Boolean IsSeparatorSymbol (const Standard_Utf32Char& theSymbol)
0285   {
0286     return theSymbol == '\x0A'    // new line
0287         || theSymbol == ' '       // space
0288         || theSymbol == '\x09';   // tab
0289   }
0290 
0291   DEFINE_STANDARD_RTTIEXT (Font_TextFormatter, Standard_Transient)
0292 
0293 protected: //! @name class auxiliary methods
0294 
0295   //! Move glyphs on the current line to correct position.
0296   Standard_EXPORT void newLine (const Standard_Integer theLastRect,
0297                                 const Standard_ShortReal theMaxLineWidth);
0298 
0299 protected: //! @name configuration
0300 
0301   Graphic3d_HorizontalTextAlignment myAlignX;  //!< horizontal alignment style
0302   Graphic3d_VerticalTextAlignment   myAlignY;  //!< vertical   alignment style
0303   Standard_Integer                  myTabSize; //!< horizontal tabulation width (number of space symbols)
0304   Standard_ShortReal                myWrappingWidth; //!< text is wrapped by the width if defined (more 0)
0305   Standard_Boolean                  myIsWordWrapping;  //!< if TRUE try not to break words when wrapping text (true by default)
0306   Standard_ShortReal                myLastSymbolWidth; //!< width of the last symbol
0307   Standard_ShortReal                myMaxSymbolWidth; //!< maximum symbol width of the formatter string
0308 
0309 protected: //! @name input data
0310 
0311   NCollection_String myString;        //!< currently rendered text
0312   NCollection_Vec2<Standard_ShortReal>
0313                      myPen;           //!< current pen position
0314   NCollection_Vector < NCollection_Vec2<Standard_ShortReal> >
0315                      myCorners;       //!< The bottom left corners of a formatted rectangles.
0316   NCollection_Vector<Standard_ShortReal>
0317                      myNewLines;      //!< position at LF
0318   Standard_ShortReal myLineSpacing;   //!< line spacing (computed as maximum of all fonts involved in text formatting)
0319   Standard_ShortReal myAscender;      //!< line spacing for the first line
0320   bool               myIsFormatted;   //!< formatting state
0321 
0322 protected: //! @name temporary variables for formatting routines
0323 
0324   Standard_Integer   myLinesNb;       //!< overall (new)lines number (including splitting by width limit)
0325   Standard_Integer   myRectLineStart; //!< id of first rectangle on the current line
0326   Standard_Integer   myNewLineNb;
0327 
0328   Standard_ShortReal myPenCurrLine;   //!< current baseline position
0329   Standard_ShortReal myBndTop;
0330   Standard_ShortReal myBndWidth;
0331   NCollection_Vec2<Standard_ShortReal>
0332                      myMoveVec;       //!< local variable
0333 };
0334 
0335 #endif // Font_TextFormatter_Header