0023457: Slow text rendering
authorkgv <kgv@opencascade.com>
Fri, 8 Feb 2013 11:05:16 +0000 (15:05 +0400)
committerkgv <kgv@opencascade.com>
Fri, 8 Feb 2013 11:05:16 +0000 (15:05 +0400)
Added class Font_FTFont wrapper over FreeType face

Unify collections methods NCollection_Array1, NCollection_Sequence, NCollection_Vector:
declare Upper, Lower, First, Last, ChangeFirst, ChangeLast methods for all these collections.

Added method NCollection_DataMap::Find() with check key is bound + retrieve value within single call interface.

OpenGl_Context::ReleaseResource() method now supports lazy release of shared resources.

Added class OpenGl_Font which implements textured fonts support.
Added class OpenGl_TextFormatter for text formatting using OpenGl_Font.

OpenGl_Text was redesigned to use OpenGl_FontFormatter.

OpenGl_FontMgr class was removed.
All methods related to text rendered removed from OpenGl_Display class.

OpenGl_Trihedron and OpenGl_GraduatedTrihedron classes were redesigned
to use OpenGl_Text.

OpenGl_PrinterContext instance was moved to OpenGl_GraphicDriver fields
(eliminated usage of global instance).

Added test cases into 3rdparty/fonts grid to check different font styles
and perform FPS tests (no automated results - requires manual analysis
or snapshots comparisons).

Removed unused CSF_FTGL dependency.
OpenGl_Text::setupMatrix - do not apply floor for myWinZ

72 files changed:
src/Font/FILES
src/Font/Font.cdl
src/Font/Font_FTFont.cxx [new file with mode: 0644]
src/Font/Font_FTFont.hxx [new file with mode: 0644]
src/Font/Font_FTLibrary.cxx [moved from src/OpenGl/OpenGl_GraphicDriver_print.cxx with 50% similarity, mode: 0644]
src/Font/Font_FTLibrary.hxx [new file with mode: 0644]
src/Font/Font_SystemFont.cxx
src/NCollection/FILES
src/NCollection/NCollection_Array1.hxx
src/NCollection/NCollection_DataMap.hxx
src/NCollection/NCollection_Sequence.hxx
src/NCollection/NCollection_String.hxx [moved from src/OpenGl/Handle_OpenGl_Trihedron.hxx with 70% similarity]
src/NCollection/NCollection_UtfIterator.hxx [new file with mode: 0644]
src/NCollection/NCollection_UtfIterator.lxx [new file with mode: 0644]
src/NCollection/NCollection_UtfString.hxx [new file with mode: 0644]
src/NCollection/NCollection_UtfString.lxx [new file with mode: 0644]
src/NCollection/NCollection_Vector.hxx
src/NIS/NIS_TriangulatedDrawer.cxx
src/OpenGl/EXTERNLIB
src/OpenGl/FILES
src/OpenGl/OpenGl_AspectText.cxx
src/OpenGl/OpenGl_AspectText.hxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_Display.cxx
src/OpenGl/OpenGl_Display.hxx
src/OpenGl/OpenGl_Display_1.cxx [deleted file]
src/OpenGl/OpenGl_Element.cxx [copied from src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx with 61% similarity]
src/OpenGl/OpenGl_Element.hxx
src/OpenGl/OpenGl_Font.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_Font.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_FontMgr.cxx [deleted file]
src/OpenGl/OpenGl_FontMgr.hxx [deleted file]
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_GraduatedTrihedron.cxx
src/OpenGl/OpenGl_GraduatedTrihedron.hxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_GraphicDriver_705.cxx [deleted file]
src/OpenGl/OpenGl_GraphicDriver_710.cxx [deleted file]
src/OpenGl/OpenGl_GraphicDriver_9.cxx [deleted file]
src/OpenGl/OpenGl_GraphicDriver_Layer.cxx
src/OpenGl/OpenGl_PrinterContext.cxx
src/OpenGl/OpenGl_PrinterContext.hxx
src/OpenGl/OpenGl_Text.cxx
src/OpenGl/OpenGl_Text.hxx
src/OpenGl/OpenGl_TextFormatter.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_TextFormatter.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Texture.cxx
src/OpenGl/OpenGl_Texture.hxx
src/OpenGl/OpenGl_Trihedron.cxx
src/OpenGl/OpenGl_Trihedron.hxx
src/OpenGl/OpenGl_Vec.hxx [moved from src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx with 67% similarity]
src/OpenGl/OpenGl_VertexBufferEditor.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_2.cxx
src/OpenGl/OpenGl_Workspace_4.cxx [deleted file]
src/OpenGl/OpenGl_Workspace_5.cxx
src/Standard/Standard.cdl
src/Standard/Standard_Integer.hxx
src/Standard/Standard_TypeDef.hxx
src/TKOpenGl/EXTERNLIB
src/ViewerTest/ViewerTest_OpenGlCommands.cxx
tests/3rdparty/fonts/A3 [new file with mode: 0644]
tests/3rdparty/fonts/A4 [new file with mode: 0644]
tests/3rdparty/fonts/A5 [new file with mode: 0644]
tests/3rdparty/fonts/A6 [new file with mode: 0644]
tests/3rdparty/fonts/A7 [new file with mode: 0644]

index 8943706..adcfa0e 100644 (file)
@@ -1,3 +1,7 @@
 EXTERNLIB
+Font_FTFont.hxx
+Font_FTFont.cxx
+Font_FTLibrary.hxx
+Font_FTLibrary.cxx
 Font_NListOfSystemFont.hxx
 Font_NameOfFont.hxx
index a96a7a6..5383816 100644 (file)
@@ -18,8 +18,8 @@
 
 package Font
 
-uses Standard ,  
-     Quantity ,  
+uses Standard,
+     Quantity,
      TCollection,
      OSD,
      TColStd
@@ -31,7 +31,9 @@ is
   class SystemFont;
   
   imported NListOfSystemFont;
-  
+  imported FTFont;
+  imported FTLibrary;
+
   class FontMgr;
 
-end Font;   
+end Font;
diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx
new file mode 100644 (file)
index 0000000..03e5110
--- /dev/null
@@ -0,0 +1,243 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <Font_FTFont.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (Font_FTFont, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont, Standard_Transient)
+
+// =======================================================================
+// function : Font_FTFont
+// purpose  :
+// =======================================================================
+Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
+: myFTLib (theFTLib),
+  myFTFace (NULL),
+  myPointSize (0),
+  myUChar (0)
+{
+  if (myFTLib.IsNull())
+  {
+    myFTLib = new Font_FTLibrary();
+  }
+}
+
+// =======================================================================
+// function : Font_FTFont
+// purpose  :
+// =======================================================================
+Font_FTFont::~Font_FTFont()
+{
+  Release();
+}
+
+// =======================================================================
+// function : Font_FTFont
+// purpose  :
+// =======================================================================
+void Font_FTFont::Release()
+{
+  myGlyphImg.Clear();
+  myFontPath.Clear();
+  myUChar = 0;
+  if (myFTFace != NULL)
+  {
+    FT_Done_Face (myFTFace);
+    myFTFace = NULL;
+  }
+}
+
+// =======================================================================
+// function : Font_FTFont
+// purpose  :
+// =======================================================================
+bool Font_FTFont::Init (const NCollection_String& theFontPath,
+                        const unsigned int        thePointSize,
+                        const unsigned int        theResolution)
+{
+  Release();
+  myFontPath  = theFontPath;
+  myPointSize = thePointSize;
+  if (!myFTLib->IsValid())
+  {
+    std::cerr << "FreeType library is unavailable!\n";
+    Release();
+    return false;
+  }
+
+  if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
+  {
+    //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
+    Release();
+    return false;
+  }
+  else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
+  {
+    //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
+    Release();
+    return false;
+  }
+  else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
+  {
+    //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
+    Release();
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : loadGlyph
+// purpose  :
+// =======================================================================
+bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
+{
+  if (myUChar == theUChar)
+  {
+    return true;
+  }
+
+  myGlyphImg.Clear();
+  myUChar = 0;
+  if (theUChar == 0
+   || FT_Load_Char (myFTFace, theUChar, FT_LOAD_TARGET_NORMAL) != 0
+   || myFTFace->glyph == NULL)
+  {
+    return false;
+  }
+
+  myUChar = theUChar;
+  return true;
+}
+
+// =======================================================================
+// function : RenderGlyph
+// purpose  :
+// =======================================================================
+bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
+{
+  myGlyphImg.Clear();
+  myUChar = 0;
+  if (theUChar == 0
+   || FT_Load_Char (myFTFace, theUChar, FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL) != 0
+   || myFTFace->glyph == NULL
+   || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
+  {
+    return false;
+  }
+
+  FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
+  if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
+   || aBitmap.buffer == NULL || aBitmap.width <= 0 || aBitmap.rows <= 0)
+  {
+    return false;
+  }
+  if (!myGlyphImg.InitWrapper (Image_PixMap::ImgGray, aBitmap.buffer,
+                               aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
+  {
+    return false;
+  }
+  myGlyphImg.SetTopDown (aBitmap.pitch > 0);
+  myUChar = theUChar;
+  return true;
+}
+
+// =======================================================================
+// function : GlyphMaxSizeX
+// purpose  :
+// =======================================================================
+unsigned int Font_FTFont::GlyphMaxSizeX() const
+{
+  float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
+               ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
+               : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
+  return (unsigned int)(aWidth + 0.5f);
+}
+
+// =======================================================================
+// function : GlyphMaxSizeY
+// purpose  :
+// =======================================================================
+unsigned int Font_FTFont::GlyphMaxSizeY() const
+{
+  float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
+                ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
+                : fromFTPoints<float> (myFTFace->size->metrics.height);
+  return (unsigned int)(aHeight + 0.5f);
+}
+
+// =======================================================================
+// function : AdvanceX
+// purpose  :
+// =======================================================================
+float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
+                             const Standard_Utf32Char theUCharNext)
+{
+  loadGlyph (theUChar);
+  return AdvanceX (theUCharNext);
+}
+
+// =======================================================================
+// function : AdvanceY
+// purpose  :
+// =======================================================================
+float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
+                             const Standard_Utf32Char theUCharNext)
+{
+  loadGlyph (theUChar);
+  return AdvanceY (theUCharNext);
+}
+
+// =======================================================================
+// function : AdvanceX
+// purpose  :
+// =======================================================================
+float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
+{
+  if (myUChar == 0)
+  {
+    return 0.0f;
+  }
+
+  if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
+   || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
+  {
+    return fromFTPoints<float> (myFTFace->glyph->advance.x);
+  }
+  return fromFTPoints<float> (myKernAdvance.x + myFTFace->glyph->advance.x);
+}
+
+// =======================================================================
+// function : AdvanceY
+// purpose  :
+// =======================================================================
+float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
+{
+  if (myUChar == 0)
+  {
+    return 0.0f;
+  }
+
+  if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
+   || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
+  {
+    return fromFTPoints<float> (myFTFace->glyph->advance.y);
+  }
+  return fromFTPoints<float> (myKernAdvance.y + myFTFace->glyph->advance.y);
+}
diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx
new file mode 100644 (file)
index 0000000..dc03bd7
--- /dev/null
@@ -0,0 +1,213 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Font_FTFont_H__
+#define _Font_FTFont_H__
+
+#include <NCollection_Vec2.hxx>
+#include <NCollection_String.hxx>
+#include <Font_FTLibrary.hxx>
+#include <Image_PixMap.hxx>
+
+//! Wrapper over FreeType font.
+//! Notice that this class uses internal buffers for loaded glyphs
+//! and it is absolutely UNSAFE to load/read glyph from concurrent threads!
+class Font_FTFont : public Standard_Transient
+{
+
+public:
+
+  //! Auxiliary structure - rectangle definition
+  struct Rect
+  {
+    float Left;
+    float Right;
+    float Top;
+    float Bottom;
+
+    NCollection_Vec2<float>& TopLeft (NCollection_Vec2<float>& theVec) const
+    {
+      theVec.x() = Left;
+      theVec.y() = Top;
+      return theVec;
+    }
+
+    NCollection_Vec2<float>& TopRight (NCollection_Vec2<float>& theVec) const
+    {
+      theVec.x() = Right;
+      theVec.y() = Top;
+      return theVec;
+    }
+
+    NCollection_Vec2<float>& BottomLeft (NCollection_Vec2<float>& theVec) const
+    {
+      theVec.x() = Left;
+      theVec.y() = Bottom;
+      return theVec;
+    }
+
+    NCollection_Vec2<float>& BottomRight (NCollection_Vec2<float>& theVec) const
+    {
+      theVec.x() = Right;
+      theVec.y() = Bottom;
+      return theVec;
+    }
+
+  };
+
+public:
+
+  //! Create uninitialized instance.
+  Standard_EXPORT Font_FTFont (const Handle(Font_FTLibrary)& theFTLib = NULL);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Font_FTFont();
+
+  //! @return true if font is loaded
+  inline bool IsValid() const
+  {
+    return myFTFace != NULL;
+  }
+
+  //! @return image plane for currently rendered glyph
+  inline const Image_PixMap& GlyphImage() const
+  {
+    return myGlyphImg;
+  }
+
+  //! Initialize the font.
+  //! @param theFontPath   path to the font
+  //! @param thePointSize  the face size in points (1/72 inch)
+  //! @param theResolution the resolution of the target device in dpi
+  //! @return true on success
+  Standard_EXPORT bool Init (const NCollection_String& theFontPath,
+                             const unsigned int        thePointSize,
+                             const unsigned int        theResolution = 72);
+
+  //! Release currently loaded font.
+  Standard_EXPORT void Release();
+
+  //! Render specified glyph into internal buffer (bitmap).
+  Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar);
+
+  //! @return maximal glyph width in pixels (rendered to bitmap).
+  Standard_EXPORT unsigned int GlyphMaxSizeX() const;
+
+  //! @return maximal glyph height in pixels (rendered to bitmap).
+  Standard_EXPORT unsigned int GlyphMaxSizeY() const;
+
+  //! @return vertical distance from the horizontal baseline to the highest character coordinate.
+  inline float Ascender() const
+  {
+    return float(myFTFace->ascender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
+  }
+
+  //! @return vertical distance from the horizontal baseline to the lowest character coordinate.
+  inline float Descender() const
+  {
+    return float(myFTFace->descender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
+  }
+
+  //! @return default line spacing (the baseline-to-baseline distance).
+  inline float LineSpacing() const
+  {
+    return float(myFTFace->height) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
+  }
+
+  //! Configured point size
+  unsigned int PointSize() const
+  {
+    return myPointSize;
+  }
+
+  //! Compute advance to the next character with kerning applied when applicable.
+  //! Assuming text rendered horizontally.
+  Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext);
+
+  //! Compute advance to the next character with kerning applied when applicable.
+  //! Assuming text rendered horizontally.
+  Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUChar,
+                                  const Standard_Utf32Char theUCharNext);
+
+  //! Compute advance to the next character with kerning applied when applicable.
+  //! Assuming text rendered vertically.
+  Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUCharNext);
+
+  //! Compute advance to the next character with kerning applied when applicable.
+  //! Assuming text rendered vertically.
+  Standard_EXPORT float AdvanceY (const Standard_Utf32Char theUChar,
+                                  const Standard_Utf32Char theUCharNext);
+
+  //! @return glyphs number in this font.
+  inline Standard_Integer GlyphsNumber() const
+  {
+    return myFTFace->num_glyphs;
+  }
+
+  //! Retrieve glyph bitmap rectangle
+  inline void GlyphRect (Font_FTFont::Rect& theRect) const
+  {
+    FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
+    theRect.Left   = float(myFTFace->glyph->bitmap_left);
+    theRect.Top    = float(myFTFace->glyph->bitmap_top);
+    theRect.Right  = float(myFTFace->glyph->bitmap_left + aBitmap.width);
+    theRect.Bottom = float(myFTFace->glyph->bitmap_top  - aBitmap.rows);
+  }
+
+protected:
+
+  //! Convert value to 26.6 fixed-point format for FT library API.
+  template <typename theInput_t>
+  inline FT_F26Dot6 toFTPoints (const theInput_t thePointSize) const
+  {
+    return (FT_F26Dot6)thePointSize * 64; 
+  }
+
+  //! Convert value from 26.6 fixed-point format for FT library API.
+  template <typename theReturn_t, typename theFTUnits_t>
+  inline theReturn_t fromFTPoints (const theFTUnits_t theFTUnits) const
+  {
+    return (theReturn_t)theFTUnits / 64.0f;
+  }
+
+protected:
+
+  //! Load glyph without rendering it.
+  Standard_EXPORT bool loadGlyph (const Standard_Utf32Char theUChar);
+
+protected:
+
+  Handle(Font_FTLibrary) myFTLib;       //!< handle to the FT library object
+  FT_Face                myFTFace;      //!< FT face object
+  NCollection_String     myFontPath;    //!< font path
+  unsigned int           myPointSize;   //!< point size set by FT_Set_Char_Size
+
+  Image_PixMap           myGlyphImg;    //!< cached glyph plane
+  FT_Vector              myKernAdvance; //!< buffer variable
+  Standard_Utf32Char     myUChar;       //!< currently loaded unicode character
+
+public:
+
+  DEFINE_STANDARD_RTTI(Font_FTFont) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient)
+
+#endif // _Font_FTFont_H__
old mode 100755 (executable)
new mode 100644 (file)
similarity index 50%
rename from src/OpenGl/OpenGl_GraphicDriver_print.cxx
rename to src/Font/Font_FTLibrary.cxx
index 6e51580..010aa57
@@ -1,6 +1,6 @@
-// Created on: 2011-10-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <Font_FTLibrary.hxx>
 
-#include <OpenGl_GraphicDriver.hxx>
+IMPLEMENT_STANDARD_HANDLE (Font_FTLibrary, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Font_FTLibrary, Standard_Transient)
 
-#include <Standard_NotImplemented.hxx>
-#include <OpenGl_CView.hxx>
+// =======================================================================
+// function : Font_FTLibrary
+// purpose  :
+// =======================================================================
+Font_FTLibrary::Font_FTLibrary()
+: myFTLib (NULL)
+{
+  if (FT_Init_FreeType (&myFTLib) != 0)
+  {
+    myFTLib = NULL;
+  }
+}
 
-Standard_Boolean OpenGl_GraphicDriver::Print
-  (const Graphic3d_CView& ACView, 
-   const Aspect_CLayer2d& ACUnderLayer, 
-   const Aspect_CLayer2d& ACOverLayer,
-   const Aspect_Handle    hPrintDC,
-   const Standard_Boolean showBackground,
-   const Standard_CString filename,
-   const Aspect_PrintAlgo printAlgorithm,
-   const Standard_Real theScaleFactor) const
+// =======================================================================
+// function : ~Font_FTLibrary
+// purpose  :
+// =======================================================================
+Font_FTLibrary::~Font_FTLibrary()
 {
-#ifdef WNT
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-    return aCView->WS->Print(ACView,ACUnderLayer,ACOverLayer,hPrintDC,showBackground,filename,printAlgorithm,theScaleFactor);
-#else
-  Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
-#endif
-  return Standard_False;
+  if (IsValid())
+  {
+    FT_Done_FreeType (myFTLib);
+  }
 }
diff --git a/src/Font/Font_FTLibrary.hxx b/src/Font/Font_FTLibrary.hxx
new file mode 100644 (file)
index 0000000..ba2a196
--- /dev/null
@@ -0,0 +1,73 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _Font_FTLibrary_H__
+#define _Font_FTLibrary_H__
+
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Transient.hxx>
+#include <Handle_Standard_Transient.hxx>
+
+// inclusion template for FreeType
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+//! Wrapper over FT_Library. Provides access to FreeType library.
+class Font_FTLibrary : public Standard_Transient
+{
+
+public:
+
+  //! Initialize new FT_Library instance.
+  Standard_EXPORT Font_FTLibrary();
+
+  //! Release FT_Library instance.
+  Standard_EXPORT ~Font_FTLibrary();
+
+  //! This method should always return true.
+  //! @return true if FT_Library instance is valid.
+  bool IsValid() const
+  {
+    return myFTLib != NULL;
+  }
+
+  //! Access FT_Library instance.
+  FT_Library Instance() const
+  {
+    return myFTLib;
+  }
+
+private:
+
+  FT_Library myFTLib;
+
+private:
+
+  Font_FTLibrary            (const Font_FTLibrary& );
+  Font_FTLibrary& operator= (const Font_FTLibrary& );
+
+public:
+
+  DEFINE_STANDARD_RTTI(Font_FTLibrary) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(Font_FTLibrary, Standard_Transient)
+
+#endif // _Font_FTLibrary_H__
index bc3804b..e1eaece 100644 (file)
@@ -38,8 +38,8 @@ Font_SystemFont::Font_SystemFont( const Handle(TCollection_HAsciiString)& FontNa
                                 const Handle(TCollection_HAsciiString)& FilePath ):
 MyFontName(FontName),
 MyFontAspect(FontAspect),
-MyFilePath(FilePath),
 MyFaceSize(-1),
+MyFilePath(FilePath),
 MyVerification(Standard_True)
 {
 
@@ -47,8 +47,9 @@ MyVerification(Standard_True)
 
 Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD,
                                   const Handle(TCollection_HAsciiString)& theFilePath) :
-MyFilePath(theFilePath),
-MyFontAspect(Font_FA_Regular)
+MyFontAspect(Font_FA_Regular),
+MyFaceSize(-1),
+MyFilePath(theFilePath)
 {
   MyVerification = Standard_True;
   if (theXLFD.IsNull())
@@ -73,7 +74,7 @@ MyFontAspect(Font_FA_Regular)
       MyFaceSize = aXLFD.Token ("-", 7).IntegerValue();
 
     // Detect font aspect
-    if (aXLFD.Token ("-", 3).IsEqual ("bold") && 
+    if (aXLFD.Token ("-", 3).IsEqual ("bold") &&
        (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o")))
     {
       MyFontAspect = Font_FA_BoldItalic;
@@ -99,7 +100,7 @@ Standard_Boolean Font_SystemFont::IsValid() const{
   if ( MyFontName->IsEmpty() || !MyFontName->IsAscii() )
     return Standard_False;
 
-  OSD_Path path;  
+  OSD_Path path;
   return path.IsValid( MyFilePath->String() );
 }
 
index b5da38b..d7e9af7 100755 (executable)
@@ -68,6 +68,12 @@ NCollection_EBTree.hxx
 NCollection_UBTree.hxx
 NCollection_UBTreeFiller.hxx
 
+NCollection_UtfIterator.hxx
+NCollection_UtfIterator.lxx
+NCollection_UtfString.hxx
+NCollection_UtfString.lxx
+NCollection_String.hxx
+
 NCollection_SparseArray.hxx
 NCollection_SparseArrayBase.hxx
 NCollection_SparseArrayBase.cxx
index 02f7dd5..f593c4e 100755 (executable)
@@ -221,6 +221,30 @@ template <class TheItemType> class NCollection_Array1
     return *this; 
   }
 
+  //! @return first element
+  const TheItemType& First() const
+  {
+    return myData[myLowerBound];
+  }
+
+  //! @return first element
+  TheItemType& ChangeFirst()
+  {
+    return myData[myLowerBound];
+  }
+
+  //! @return last element
+  const TheItemType& Last() const
+  {
+    return myData[myUpperBound];
+  }
+
+  //! @return last element
+  TheItemType& ChangeLast()
+  {
+    return myData[myUpperBound];
+  }
+
   //! Constant value access
   const TheItemType& Value (const Standard_Integer theIndex) const
   {
index aeab1b0..6271039 100755 (executable)
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef NCollection_DataMap_HeaderFile
 #define NCollection_DataMap_HeaderFile
 
@@ -290,6 +289,29 @@ template < class TheKeyType,
     return p->Value(); // This for compiler
   }
 
+  //! Find value for key with copying.
+  //! @return true if key was found
+  Standard_Boolean Find (const TheKeyType& theKey,
+                         TheItemType&      theValue) const
+  {
+    if (IsEmpty())
+    {
+      return Standard_False;
+    }
+
+    for (DataMapNode* aNodeIter = (DataMapNode* )myData1[Hasher::HashCode (theKey, NbBuckets())];
+         aNodeIter != NULL;
+         aNodeIter = (DataMapNode* )aNodeIter->Next())
+    {
+      if (Hasher::IsEqual (aNodeIter->Key(), theKey))
+      {
+        theValue = aNodeIter->Value();
+        return Standard_True;
+      }
+    }
+    return Standard_False;
+  }
+
   //! operator ()
   const TheItemType& operator() (const TheKeyType& theKey) const
   { return Find(theKey); }
index 3b0866a..6a3487e 100755 (executable)
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef NCollection_Sequence_HeaderFile
 #define NCollection_Sequence_HeaderFile
 
@@ -114,6 +113,20 @@ template <class TheItemType> class NCollection_Sequence
   Standard_Integer Length (void) const
   { return mySize; }
 
+  //! Method for consistency with other collections.
+  //! @return Lower bound (inclusive) for iteration.
+  Standard_Integer Lower() const
+  {
+    return 1;
+  }
+
+  //! Method for consistency with other collections.
+  //! @return Upper bound (inclusive) for iteration.
+  Standard_Integer Upper() const
+  {
+    return mySize;
+  }
+
   //! Empty query
   Standard_Boolean IsEmpty (void) const
   { return (mySize==0); }
@@ -253,6 +266,16 @@ template <class TheItemType> class NCollection_Sequence
     return ((const Node *) myFirstItem) -> Value();
   }
 
+  //! First item access
+  TheItemType& ChangeFirst()
+  {
+#if !defined No_Exception && !defined No_Standard_NoSuchObject
+    if (mySize == 0)
+      Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeFirst");
+#endif
+    return ((Node* )myFirstItem)->ChangeValue();
+  }
+
   //! Last item access
   const TheItemType& Last () const
   {
@@ -263,6 +286,16 @@ template <class TheItemType> class NCollection_Sequence
     return ((const Node *) myLastItem) -> Value();
   }
 
+  //! Last item access
+  TheItemType& ChangeLast()
+  {
+#if !defined No_Exception && !defined No_Standard_NoSuchObject
+    if (mySize == 0)
+      Standard_NoSuchObject::Raise ("NCollection_Sequence::ChangeLast");
+#endif
+    return ((Node* )myLastItem)->ChangeValue();
+  }
+
   //! Constant item access by theIndex
   const TheItemType& Value (const Standard_Integer theIndex) const
   {
similarity index 70%
rename from src/OpenGl/Handle_OpenGl_Trihedron.hxx
rename to src/NCollection/NCollection_String.hxx
index d8c92d1..c521600 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2011-09-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _NCollection_String_H__
+#define _NCollection_String_H__
 
-#ifndef _Handle_OpenGl_Trihedron_Header
-#define _Handle_OpenGl_Trihedron_Header
+#include "NCollection_UtfString.hxx"
 
-#include <Standard_DefineHandle.hxx>
-#include <Handle_MMgt_TShared.hxx>
+typedef NCollection_Utf8String NCollection_String;
 
-class OpenGl_Trihedron;
-
-// Handle definition
-//
-DEFINE_STANDARD_HANDLE(OpenGl_Trihedron,MMgt_TShared)
-
-
-#endif //_Handle_OpenGl_Trihedron_Header
+#endif // _NCollection_String_H__
diff --git a/src/NCollection/NCollection_UtfIterator.hxx b/src/NCollection/NCollection_UtfIterator.hxx
new file mode 100644 (file)
index 0000000..19a4506
--- /dev/null
@@ -0,0 +1,209 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _NCollection_UtfIterator_H__
+#define _NCollection_UtfIterator_H__
+
+#include <Standard_TypeDef.hxx>
+
+//! Template class for Unicode strings support.
+//! It defines an iterator and provide correct way to read multi-byte text (UTF-8 and UTF-16)
+//! and convert it from one to another.
+//! The current value of iterator returned as UTF-32 Unicode code.
+template<typename Type>
+class NCollection_UtfIterator
+{
+
+public:
+
+  //! Constructor.
+  //! @param theString buffer to iterate
+  NCollection_UtfIterator (const Type* theString)
+  : myPosition(theString),
+    myPosNext(theString),
+    myCharIndex(0),
+    myCharUtf32(0)
+  {
+    if (theString != NULL)
+    {
+      ++(*this);
+      myCharIndex = 0;
+    }
+  }
+
+  //! Initialize iterator within specified NULL-terminated string.
+  void Init (const Type* theString)
+  {
+    myPosition  = theString;
+    myPosNext   = theString;
+    myCharUtf32 = 0;
+    if (theString != NULL)
+    {
+      ++(*this);
+    }
+    myCharIndex = 0;
+  }
+
+  //! Pre-increment operator. Reads the next unicode character.
+  //! Notice - no protection against overrun!
+  NCollection_UtfIterator& operator++()
+  {
+    myPosition = myPosNext;
+    ++myCharIndex;
+    switch (sizeof(Type))
+    {
+      case 1: readUTF8();  break;
+      case 2: readUTF16(); break;
+      case 4: // UTF-32
+      default:
+        myCharUtf32 = *myPosNext++;
+    }
+    return *this;
+  }
+
+  //! Post-increment operator.
+  //! Notice - no protection against overrun!
+  NCollection_UtfIterator operator++ (int )
+  {
+    NCollection_UtfIterator aCopy = *this;
+    ++*this;
+    return aCopy;
+  }
+
+  //! Equality operator.
+  bool operator== (const NCollection_UtfIterator& theRight) const
+  {
+    return myPosition == theRight.myPosition;
+  }
+
+  //! Dereference operator.
+  //! @return the UTF-32 codepoint of the character currently pointed by iterator.
+  Standard_Utf32Char operator*() const
+  {
+    return myCharUtf32;
+  }
+
+  //! Buffer-fetching getter.
+  const Type* BufferHere() const { return myPosition; }
+
+  //! Buffer-fetching getter. Dangerous! Iterator should be reinitialized on buffer change.
+  Type* ChangeBufferHere() { return (Type* )myPosition; }
+
+  //! Buffer-fetching getter.
+  const Type* BufferNext() const { return myPosNext; }
+
+  //! @return the index displacement from iterator intialization
+  Standard_Integer Index() const
+  {
+    return myCharIndex;
+  }
+
+  //! @return the advance in bytes to store current symbol in UTF-8.
+  //! 0 means an invalid symbol;
+  //! 1-4 bytes are valid range.
+  Standard_Integer AdvanceBytesUtf8() const;
+
+  //! @return the advance in bytes to store current symbol in UTF-16.
+  //! 0 means an invalid symbol;
+  //! 2 bytes is a general case;
+  //! 4 bytes for surrogate pair.
+  Standard_Integer AdvanceBytesUtf16() const;
+
+  //! @return the advance in bytes to store current symbol in UTF-32.
+  //! Always 4 bytes (method for consistency).
+  Standard_Integer AdvanceBytesUtf32() const
+  {
+    return Standard_Integer(sizeof(Standard_Utf32Char));
+  }
+
+  //! Fill the UTF-8 buffer within current Unicode symbol.
+  //! Use method AdvanceUtf8() to allocate buffer with enough size.
+  //! @param theBuffer buffer to fill
+  //! @return new buffer position (for next char)
+  Standard_Utf8Char*  GetUtf8 (Standard_Utf8Char*  theBuffer) const;
+  Standard_Utf8UChar* GetUtf8 (Standard_Utf8UChar* theBuffer) const;
+
+  //! Fill the UTF-16 buffer within current Unicode symbol.
+  //! Use method AdvanceUtf16() to allocate buffer with enough size.
+  //! @param theBuffer buffer to fill
+  //! @return new buffer position (for next char)
+  Standard_Utf16Char* GetUtf16 (Standard_Utf16Char* theBuffer) const;
+
+  //! Fill the UTF-32 buffer within current Unicode symbol.
+  //! Use method AdvanceUtf32() to allocate buffer with enough size.
+  //! @param theBuffer buffer to fill
+  //! @return new buffer position (for next char)
+  Standard_Utf32Char* GetUtf32 (Standard_Utf32Char* theBuffer) const;
+
+  //! @return the advance in TypeWrite chars needed to store current symbol
+  template<typename TypeWrite>
+  Standard_Integer AdvanceBytesUtf() const;
+
+  //! Fill the UTF-** buffer within current Unicode symbol.
+  //! Use method AdvanceUtf**() to allocate buffer with enough size.
+  //! @param theBuffer buffer to fill
+  //! @return new buffer position (for next char)
+  template<typename TypeWrite>
+  TypeWrite* GetUtf (TypeWrite* theBuffer) const;
+
+private:
+
+  //! Helper function for reading a single UTF8 character from the string.
+  //! Updates internal state appropriately.
+  void readUTF8();
+
+  //! Helper function for reading a single UTF16 character from the string.
+  //! Updates internal state appropriately.
+  void readUTF16();
+
+private: //! @name unicode magic numbers
+
+  static const unsigned char UTF8_BYTES_MINUS_ONE[256];
+  static const unsigned long offsetsFromUTF8[6];
+  static const unsigned char UTF8_FIRST_BYTE_MARK[7];
+  static const unsigned long UTF8_BYTE_MASK;
+  static const unsigned long UTF8_BYTE_MARK;
+  static const unsigned long UTF16_SURROGATE_HIGH_START;
+  static const unsigned long UTF16_SURROGATE_HIGH_END;
+  static const unsigned long UTF16_SURROGATE_LOW_START;
+  static const unsigned long UTF16_SURROGATE_LOW_END;
+  static const unsigned long UTF16_SURROGATE_HIGH_SHIFT;
+  static const unsigned long UTF16_SURROGATE_LOW_BASE;
+  static const unsigned long UTF16_SURROGATE_LOW_MASK;
+  static const unsigned long UTF32_MAX_BMP;
+  static const unsigned long UTF32_MAX_LEGAL;
+
+private: //! @name private fields
+
+  const Type*        myPosition;  //!< buffer position of the first element in the current character
+  const Type*        myPosNext;   //!< buffer position of the first element in the next character
+  Standard_Integer   myCharIndex; //!< index displacement from iterator intialization
+  Standard_Utf32Char myCharUtf32; //!< character stored at the current buffer position
+
+};
+
+typedef NCollection_UtfIterator<Standard_Utf8Char>  NCollection_Utf8Iter;
+typedef NCollection_UtfIterator<Standard_Utf16Char> NCollection_Utf16Iter;
+typedef NCollection_UtfIterator<Standard_Utf32Char> NCollection_Utf32Iter;
+typedef NCollection_UtfIterator<Standard_WideChar>  NCollection_UtfWideIter;
+
+// template implementation
+#include "NCollection_UtfIterator.lxx"
+
+#endif // _NCollection_UtfIterator_H__
diff --git a/src/NCollection/NCollection_UtfIterator.lxx b/src/NCollection/NCollection_UtfIterator.lxx
new file mode 100644 (file)
index 0000000..ead44e8
--- /dev/null
@@ -0,0 +1,340 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+// Portions of code are copyrighted by Unicode, Inc.
+//
+// Copyright © 2001-2004 Unicode, Inc.
+//
+// Disclaimer
+//
+// This source code is provided as is by Unicode, Inc. No claims are
+// made as to fitness for any particular purpose. No warranties of any
+// kind are expressed or implied. The recipient agrees to determine
+// applicability of information provided. If this file has been
+// purchased on magnetic or optical media from Unicode, Inc., the
+// sole remedy for any claim will be exchange of defective media
+// within 90 days of receipt.
+//
+// Limitations on Rights to Redistribute This Code
+//
+// Unicode, Inc. hereby grants the right to freely use the information
+// supplied in this file in the creation of products supporting the
+// Unicode Standard, and to make copies of this file in any form
+// for internal or external distribution as long as this notice
+// remains attached.
+
+//! The first character in a UTF-8 sequence indicates how many bytes
+//! to read (among other things).
+template<typename Type>
+const unsigned char NCollection_UtfIterator<Type>::UTF8_BYTES_MINUS_ONE[256] =
+{
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+//! Magic values subtracted from a buffer value during UTF-8 conversion.
+//! This table contains as many values as there might be trailing bytes
+//! in a UTF-8 sequence.
+template<typename Type>
+const unsigned long NCollection_UtfIterator<Type>::offsetsFromUTF8[6] =
+{
+  0x00000000UL, 0x00003080UL, 0x000E2080UL,
+  0x03C82080UL, 0xFA082080UL, 0x82082080UL
+};
+
+//! The first character in a UTF-8 sequence indicates how many bytes to read.
+template<typename Type>
+const unsigned char NCollection_UtfIterator<Type>::UTF8_FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+// =======================================================================
+// function : readUTF8
+// purpose  : Get a UTF-8 character; leave the tracking pointer at the start of the next character.
+//            Not protected against invalid UTF-8.
+// =======================================================================
+template<typename Type>
+inline void NCollection_UtfIterator<Type>::readUTF8()
+{
+  // unsigned arithmetic used
+  Standard_Utf8UChar* aPos = (Standard_Utf8UChar* )myPosNext;
+  const unsigned char aBytesToRead = UTF8_BYTES_MINUS_ONE[*aPos];
+  myCharUtf32 = 0;
+  switch (aBytesToRead)
+  {
+    case 5: myCharUtf32 += *aPos++; myCharUtf32 <<= 6; // remember, illegal UTF-8
+    case 4: myCharUtf32 += *aPos++; myCharUtf32 <<= 6; // remember, illegal UTF-8
+    case 3: myCharUtf32 += *aPos++; myCharUtf32 <<= 6;
+    case 2: myCharUtf32 += *aPos++; myCharUtf32 <<= 6;
+    case 1: myCharUtf32 += *aPos++; myCharUtf32 <<= 6;
+    case 0: myCharUtf32 += *aPos++;
+  }
+  myCharUtf32 -= offsetsFromUTF8[aBytesToRead];
+  myPosNext = (Type* )aPos;
+}
+
+// magic numbers
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF8_BYTE_MASK = 0xBF;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF8_BYTE_MARK = 0x80;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_HIGH_START = 0xD800;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_HIGH_END   = 0xDBFF;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_LOW_START  = 0xDC00;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_LOW_END    = 0xDFFF;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_HIGH_SHIFT = 10;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_LOW_BASE   = 0x0010000UL;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF16_SURROGATE_LOW_MASK   = 0x3FFUL;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF32_MAX_BMP   = 0x0000FFFFUL;
+template<typename Type> const unsigned long NCollection_UtfIterator<Type>::UTF32_MAX_LEGAL = 0x0010FFFFUL;
+
+// =======================================================================
+// function : readUTF16
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+void NCollection_UtfIterator<Type>::readUTF16()
+{
+  Standard_Utf32Char aChar = *myPosNext++;
+  // if we have the first half of the surrogate pair
+  if (aChar >= UTF16_SURROGATE_HIGH_START
+   && aChar <= UTF16_SURROGATE_HIGH_END)
+  {
+    Standard_Utf32Char aChar2 = *myPosition;
+    // complete the surrogate pair
+    if (aChar2 >= UTF16_SURROGATE_LOW_START
+     && aChar2 <= UTF16_SURROGATE_LOW_END)
+    {
+      aChar = ((aChar - UTF16_SURROGATE_HIGH_START) << UTF16_SURROGATE_HIGH_SHIFT)
+            + (aChar2 - UTF16_SURROGATE_LOW_START)   + UTF16_SURROGATE_LOW_BASE;
+      ++myPosNext;
+    }
+  }
+  myCharUtf32 = aChar;
+}
+
+// =======================================================================
+// function : AdvanceBytesUtf8
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf8() const
+{
+  if (myCharUtf32 >= UTF16_SURROGATE_HIGH_START
+   && myCharUtf32 <= UTF16_SURROGATE_LOW_END)
+   {
+    // UTF-16 surrogate values are illegal in UTF-32
+    return 0;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x80))
+  {
+    return 1;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x800))
+  {
+    return 2;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x10000))
+  {
+    return 3;
+  }
+  else if (myCharUtf32 <= UTF32_MAX_LEGAL)
+  {
+    return 4;
+  }
+  else
+  {
+    // illegal
+    return 0;
+  }
+}
+
+// =======================================================================
+// function : GetUtf8
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Utf8Char* NCollection_UtfIterator<Type>::GetUtf8 (Standard_Utf8Char* theBuffer) const
+{
+  // unsigned arithmetic used
+  return (Standard_Utf8Char* )GetUtf8 ((Standard_Utf8UChar* )theBuffer);
+}
+
+// =======================================================================
+// function : GetUtf8
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Utf8UChar* NCollection_UtfIterator<Type>::GetUtf8 (Standard_Utf8UChar* theBuffer) const
+{
+  Standard_Utf32Char aChar = myCharUtf32;
+  if (myCharUtf32 >= UTF16_SURROGATE_HIGH_START
+   && myCharUtf32 <= UTF16_SURROGATE_LOW_END)
+  {
+    // UTF-16 surrogate values are illegal in UTF-32
+    return theBuffer;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x80))
+  {
+    *theBuffer++ = Standard_Utf8UChar (aChar | UTF8_FIRST_BYTE_MARK[1]);
+    return theBuffer;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x800))
+  {
+    *++theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar (aChar | UTF8_FIRST_BYTE_MARK[2]);
+    return theBuffer + 2;
+  }
+  else if (myCharUtf32 < Standard_Utf32Char(0x10000))
+  {
+    theBuffer += 3;
+    *--theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar (aChar | UTF8_FIRST_BYTE_MARK[3]);
+    return theBuffer + 3;
+  }
+  else if (myCharUtf32 <= UTF32_MAX_LEGAL)
+  {
+    theBuffer += 4;
+    *--theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar((aChar | UTF8_BYTE_MARK) & UTF8_BYTE_MASK); aChar >>= 6;
+    *--theBuffer = Standard_Utf8UChar (aChar | UTF8_FIRST_BYTE_MARK[4]);
+    return theBuffer + 4;
+  }
+  else
+  {
+    // illegal
+    return theBuffer;
+  }
+}
+
+// =======================================================================
+// function : AdvanceBytesUtf16
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf16() const
+{
+  if (myCharUtf32 <= UTF32_MAX_BMP) // target is a character <= 0xFFFF
+  {
+    // UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values
+    if (myCharUtf32 >= UTF16_SURROGATE_HIGH_START
+     && myCharUtf32 <= UTF16_SURROGATE_LOW_END)
+    {
+      return 0;
+    }
+    else
+    {
+      return Standard_Integer(sizeof(Standard_Utf16Char));
+    }
+  }
+  else if (myCharUtf32 > UTF32_MAX_LEGAL)
+  {
+    // illegal
+    return 0;
+  }
+  else
+  {
+    // target is a character in range 0xFFFF - 0x10FFFF
+    // surrogate pair
+    return Standard_Integer(sizeof(Standard_Utf16Char) * 2);
+  }
+}
+
+// =======================================================================
+// function : GetUtf16
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Utf16Char* NCollection_UtfIterator<Type>::GetUtf16 (Standard_Utf16Char* theBuffer) const
+{
+  if (myCharUtf32 <= UTF32_MAX_BMP) // target is a character <= 0xFFFF
+  {
+    // UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values
+    if (myCharUtf32 >= UTF16_SURROGATE_HIGH_START
+     && myCharUtf32 <= UTF16_SURROGATE_LOW_END)
+    {
+      return theBuffer;
+    }
+    else
+    {
+      *theBuffer++ = Standard_Utf16Char(myCharUtf32);
+      return theBuffer;
+    }
+  }
+  else if (myCharUtf32 > UTF32_MAX_LEGAL)
+  {
+    // illegal
+    return theBuffer;
+  }
+  else
+  {
+    // surrogate pair
+    Standard_Utf32Char aChar = myCharUtf32 - UTF16_SURROGATE_LOW_BASE;
+    *theBuffer++ = Standard_Utf16Char((aChar >> UTF16_SURROGATE_HIGH_SHIFT) + UTF16_SURROGATE_HIGH_START);
+    *theBuffer++ = Standard_Utf16Char((aChar &  UTF16_SURROGATE_LOW_MASK)   + UTF16_SURROGATE_LOW_START);
+    return theBuffer;
+  }
+}
+
+// =======================================================================
+// function : GetUtf32
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Utf32Char* NCollection_UtfIterator<Type>::GetUtf32 (Standard_Utf32Char* theBuffer) const
+{
+  *theBuffer++ = myCharUtf32;
+  return theBuffer;
+}
+
+// =======================================================================
+// function : AdvanceBytesUtf
+// purpose  :
+// =======================================================================
+template<typename Type> template<typename TypeWrite> inline
+Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf() const
+{
+  switch (sizeof(TypeWrite))
+  {
+    case sizeof(Standard_Utf8Char):  return AdvanceBytesUtf8();
+    case sizeof(Standard_Utf16Char): return AdvanceBytesUtf16();
+    case sizeof(Standard_Utf32Char): return AdvanceBytesUtf32();
+    default:                         return 0; // invalid case
+  }
+}
+
+// =======================================================================
+// function : GetUtf
+// purpose  :
+// =======================================================================
+template<typename Type> template<typename TypeWrite> inline
+TypeWrite* NCollection_UtfIterator<Type>::GetUtf (TypeWrite* theBuffer) const
+{
+  switch (sizeof(TypeWrite))
+  {
+    case sizeof(Standard_Utf8Char):  return (TypeWrite* )GetUtf8 ((Standard_Utf8UChar* )theBuffer);
+    case sizeof(Standard_Utf16Char): return (TypeWrite* )GetUtf16((Standard_Utf16Char* )theBuffer);
+    case sizeof(Standard_Utf32Char): return (TypeWrite* )GetUtf32((Standard_Utf32Char* )theBuffer);
+    default:                         return NULL; // invalid case
+  }
+}
diff --git a/src/NCollection/NCollection_UtfString.hxx b/src/NCollection/NCollection_UtfString.hxx
new file mode 100644 (file)
index 0000000..c644669
--- /dev/null
@@ -0,0 +1,278 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _NCollection_UtfString_H__
+#define _NCollection_UtfString_H__
+
+#include "NCollection_UtfIterator.hxx"
+
+#include <Standard.hxx>
+
+#include <string>
+#include <cstdlib>
+
+//! This template class represent constant UTF-* string.
+//! String stored in memory continuously, always NULL-terminated
+//! and can be used as standard C-string using ToCString() method.
+//!
+//! Notice that changing the string is not allowed
+//! and any modifications should produce new string.
+template<typename Type>
+class NCollection_UtfString
+{
+
+public:
+
+  NCollection_UtfIterator<Type> Iterator() const
+  {
+    return NCollection_UtfIterator<Type> (myString);
+  }
+
+  //! @return the size of the buffer, excluding NULL-termination symbol
+  Standard_Integer Size() const
+  {
+    return mySize;
+  }
+
+  //! @return the length of the string in Unicode symbols
+  Standard_Integer Length() const
+  {
+    return myLength;
+  }
+
+  //! Retrieve Unicode symbol at specified position.
+  //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
+  //! @param theCharIndex the index of the symbol, should be lesser than Length()
+  //! @return the Unicode symbol value
+  Standard_Utf32Char GetChar (const Standard_Integer theCharIndex) const;
+
+  //! Retrieve string buffer at specified position.
+  //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
+  //! @param theCharIndex the index of the symbol, should be lesser than Length()
+  //! @return the pointer to the symbol
+  const Type* GetCharBuffer (const Standard_Integer theCharIndex) const;
+
+  //! Retrieve Unicode symbol at specified position.
+  //! Warning! This is a slow access. Iterator should be used for consecutive parsing.
+  Standard_Utf32Char operator[] (const Standard_Integer theCharIndex) const
+  {
+    return GetChar (theCharIndex);
+  }
+
+  //! Initialize empty string.
+  NCollection_UtfString();
+
+  //! Copy constructor.
+  //! @param theCopy string to copy.
+  NCollection_UtfString (const NCollection_UtfString& theCopy);
+
+  //! Copy constructor from NULL-terminated UTF-8 string.
+  //! @param theCopyUtf8 NULL-terminated UTF-8 string to copy
+  //! @param theLength   the length limit in Unicode symbols (NOT bytes!)
+  NCollection_UtfString (const char*            theCopyUtf8,
+                         const Standard_Integer theLength = -1);
+
+  //! Copy constructor from NULL-terminated UTF-16 string.
+  //! @param theCopyUtf16 NULL-terminated UTF-16 string to copy
+  //! @param theLength    the length limit in Unicode symbols (NOT bytes!)
+  NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
+                         const Standard_Integer    theLength = -1);
+
+  //! Copy constructor from NULL-terminated UTF-32 string.
+  //! @param theCopyUtf32 NULL-terminated UTF-32 string to copy
+  //! @param theLength    the length limit in Unicode symbols (NOT bytes!)
+  NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
+                         const Standard_Integer    theLength = -1);
+
+  //! Copy constructor from NULL-terminated wide UTF string.
+  //! @param theCopyUtfWide NULL-terminated wide UTF string to copy
+  //! @param theLength      the length limit in Unicode symbols (NOT bytes!)
+  NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
+                         const Standard_Integer   theLength = -1);
+
+  //! Copy from NULL-terminated Unicode string.
+  //! @param theStringUtf NULL-terminated Unicode string
+  //! @param theLength    the length limit in Unicode symbols
+  template <typename TypeFrom>
+  void FromUnicode (const TypeFrom*        theStringUtf,
+                    const Standard_Integer theLength = -1);
+
+  //! Copy from NULL-terminated multibyte string in system locale.
+  //! You should avoid this function unless extreme necessity.
+  //! @param theString NULL-terminated multibyte string
+  //! @param theLength the length limit in Unicode symbols
+  void FromLocale (const char*            theString,
+                   const Standard_Integer theLength = -1);
+
+  //! Destructor.
+  ~NCollection_UtfString();
+
+  //! Compares this string with another one.
+  bool IsEqual (const NCollection_UtfString& theCompare) const;
+
+  //! Returns the substring.
+  //! @param theStart start index (inclusive) of subString
+  //! @param theEnd   end index   (exclusive) of subString
+  //! @return the substring
+  NCollection_UtfString SubString (const Standard_Integer theStart,
+                                   const Standard_Integer theEnd) const;
+
+  //! Returns NULL-terminated Unicode string.
+  //! Should not be modifed or deleted!
+  //! @return (const Type* ) pointer to string
+  const Type* ToCString() const
+  {
+    return myString;
+  }
+
+  //! @return copy in UTF-8 format
+  const NCollection_UtfString<Standard_Utf8Char> ToUtf8() const;
+
+  //! @return copy in UTF-16 format
+  const NCollection_UtfString<Standard_Utf16Char> ToUtf16() const;
+
+  //! @return copy in UTF-32 format
+  const NCollection_UtfString<Standard_Utf32Char> ToUtf32() const;
+
+  //! @return copy in wide format (UTF-16 on Windows and UTF-32 on Linux)
+  const NCollection_UtfString<Standard_WideChar> ToUtfWide() const;
+
+  //! Converts the string into multibyte string.
+  //! You should avoid this function unless extreme necessity.
+  //! @param theBuffer    output buffer
+  //! @param theSizeBytes buffer size in bytes
+  //! @return true on success
+  bool ToLocale (char*                  theBuffer,
+                 const Standard_Integer theSizeBytes) const;
+
+  //! @return true if string is empty
+  bool IsEmpty() const
+  {
+    return myString[0] == Type(0);
+  }
+
+  //! Zero string.
+  void Clear();
+
+public: //! @name assign operators
+
+  //! Copy from another string.
+  const NCollection_UtfString& operator= (const NCollection_UtfString& theOther);
+
+  //! Copy from UTF-8 NULL-terminated string.
+  const NCollection_UtfString& operator= (const char* theStringUtf8);
+
+  //! Copy from wchar_t UTF NULL-terminated string.
+  const NCollection_UtfString& operator= (const Standard_WideChar* theStringUtfWide);
+
+  //! Join strings.
+  NCollection_UtfString& operator+= (const NCollection_UtfString& theAppend);
+
+  //! Join two strings.
+  friend NCollection_UtfString operator+ (const NCollection_UtfString& theLeft,
+                                          const NCollection_UtfString& theRight)
+  {
+    NCollection_UtfString aSumm;
+    strFree (aSumm.myString);
+    aSumm.mySize   = theLeft.mySize   + theRight.mySize;
+    aSumm.myLength = theLeft.myLength + theRight.myLength;
+    aSumm.myString = strAlloc (aSumm.mySize);
+
+    // copy bytes
+    strCopy ((Standard_Byte* )aSumm.myString,                  (const Standard_Byte* )theLeft.myString,  theLeft.mySize);
+    strCopy ((Standard_Byte* )aSumm.myString + theLeft.mySize, (const Standard_Byte* )theRight.myString, theRight.mySize);
+    return aSumm;
+  }
+
+public: //! @name compare operators
+
+  bool operator== (const NCollection_UtfString& theCompare) const
+  {
+    return IsEqual (theCompare);
+  }
+  bool operator!= (const NCollection_UtfString& theCompare) const;
+
+private: //! @name low-level methods
+
+  //! Compute advance for specified string.
+  //! @param theStringUtf pointer to the NULL-terminated Unicode string
+  //! @param theLengthMax length limit (to cut the string), set to -1 to compute up to NULL-termination symbol
+  //! @param theSizeBytes advance in bytes (out)
+  //! @param theLength    string length (out)
+  template<typename TypeFrom>
+  static void strGetAdvance (const TypeFrom*        theStringUtf,
+                             const Standard_Integer theLengthMax,
+                             Standard_Integer&      theSizeBytes,
+                             Standard_Integer&      theLength);
+
+  //! Allocate NULL-terminated string buffer.
+  static Type* strAlloc (const Standard_Size theSizeBytes)
+  {
+    Type* aPtr = (Type* )Standard::Allocate (theSizeBytes + sizeof(Type));
+    if (aPtr != NULL)
+    {
+      // always NULL-terminate the string
+      aPtr[theSizeBytes / sizeof(Type)] = Type(0);
+    }
+    return aPtr;
+  }
+
+  //! Release string buffer and nullify the pointer.
+  static void strFree (Type*& thePtr)
+  {
+    void* aPtr = thePtr;
+    Standard::Free (aPtr);
+    thePtr = NULL;
+  }
+
+  //! Provides bytes interface to avoid incorrect pointer arithmetics.
+  static void strCopy (Standard_Byte*         theStrDst,
+                       const Standard_Byte*   theStrSrc,
+                       const Standard_Integer theSizeBytes)
+  {
+    ::memcpy (theStrDst, theStrSrc, (Standard_Size )theSizeBytes);
+  }
+
+  //! Compare two Unicode strings per-byte.
+  static bool strAreEqual (const Type*            theString1,
+                           const Standard_Integer theSizeBytes1,
+                           const Type*            theString2,
+                           const Standard_Integer theSizeBytes2)
+  {
+    return (theSizeBytes1 == theSizeBytes2)
+        && (::memcmp (theString1, theString2, (Standard_Size )theSizeBytes1) == 0);
+  }
+
+private: //! @name private fields
+
+  Type*            myString; //!< string buffer
+  Standard_Integer mySize;   //!< buffer size in bytes, excluding NULL-termination symbol
+  Standard_Integer myLength; //!< length of the string in Unicode symbols (cached value, excluding NULL-termination symbol)
+
+};
+
+typedef NCollection_UtfString<Standard_Utf8Char>  NCollection_Utf8String;
+typedef NCollection_UtfString<Standard_Utf16Char> NCollection_Utf16String;
+typedef NCollection_UtfString<Standard_Utf32Char> NCollection_Utf32String;
+typedef NCollection_UtfString<Standard_WideChar>  NCollection_UtfWideString;
+
+// template implementation (inline methods)
+#include "NCollection_UtfString.lxx"
+
+#endif // _NCollection_UtfString_H__
diff --git a/src/NCollection/NCollection_UtfString.lxx b/src/NCollection/NCollection_UtfString.lxx
new file mode 100644 (file)
index 0000000..4217826
--- /dev/null
@@ -0,0 +1,475 @@
+// Created on: 2013-01-28
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+// =======================================================================
+// function : strGetAdvance
+// purpose  : Compute advance for specified string.
+// =======================================================================
+template<typename TypeTo> template<typename TypeFrom> inline
+void NCollection_UtfString<TypeTo>::strGetAdvance (const TypeFrom*        theStringUtf,
+                                                   const Standard_Integer theLengthMax,
+                                                   Standard_Integer&      theSizeBytes,
+                                                   Standard_Integer&      theLength)
+{
+  theSizeBytes = 0;
+  theLength    = 0;
+  NCollection_UtfIterator<TypeFrom> anIter (theStringUtf);
+  const Standard_Integer aLengthMax = (theLengthMax > 0) ? theLengthMax : IntegerLast();
+  switch (sizeof(TypeTo))
+  {
+    case sizeof(Standard_Utf8Char):
+    {
+      for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
+      {
+        theSizeBytes += anIter.AdvanceBytesUtf8();
+      }
+      theLength = anIter.Index();
+      return;
+    }
+    case sizeof(Standard_Utf16Char):
+    {
+      for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
+      {
+        theSizeBytes += anIter.AdvanceBytesUtf16();
+      }
+      theLength = anIter.Index();
+      return;
+    }
+    case sizeof(Standard_Utf32Char):
+    {
+      for (; *anIter != 0 && anIter.Index() < aLengthMax; ++anIter)
+      {
+        theSizeBytes += anIter.AdvanceBytesUtf32();
+      }
+      theLength = anIter.Index();
+      return;
+    }
+    default: return;
+  }
+}
+
+// =======================================================================
+// function : GetChar
+// purpose  :
+// =======================================================================
+template<typename Type>
+Standard_Utf32Char NCollection_UtfString<Type>::GetChar (const Standard_Integer theCharIndex) const
+{
+  //Standard_ASSERT_SKIP (theCharIndex < myLength, "Out of range");
+  NCollection_UtfIterator<Type> anIter (myString);
+  for (; *anIter != 0; ++anIter)
+  {
+    if (anIter.Index() == theCharIndex)
+    {
+      return *anIter;
+    }
+  }
+  return 0;
+}
+
+// =======================================================================
+// function : GetCharBuffer
+// purpose  :
+// =======================================================================
+template<typename Type>
+const Type* NCollection_UtfString<Type>::GetCharBuffer (const Standard_Integer theCharIndex) const
+{
+  //Standard_ASSERT_SKIP(theCharIndex < myLength);
+  NCollection_UtfIterator<Type> anIter (myString);
+  for (; *anIter != 0; ++anIter)
+  {
+    if (anIter.Index() == theCharIndex)
+    {
+      return anIter.BufferHere();
+    }
+  }
+  return NULL;
+}
+
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+void NCollection_UtfString<Type>::Clear()
+{
+  strFree (myString);
+  mySize   = 0;
+  myLength = 0;
+  myString = strAlloc (mySize);
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString()
+: myString (strAlloc(0)),
+  mySize   (0),
+  myLength (0)
+{
+  //
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString (const NCollection_UtfString& theCopy)
+: myString (strAlloc (theCopy.mySize)),
+  mySize   (theCopy.mySize),
+  myLength (theCopy.myLength)
+{
+  strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theCopy.myString, mySize);
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString (const char*            theCopyUtf8,
+                                                    const Standard_Integer theLength)
+: myString (NULL),
+  mySize   (0),
+  myLength (0)
+{
+  FromUnicode (theCopyUtf8, theLength);
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16,
+                                                    const Standard_Integer    theLength)
+: myString (NULL),
+  mySize   (0),
+  myLength (0)
+{
+  FromUnicode (theCopyUtf16, theLength);
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
+                                                    const Standard_Integer     theLength)
+: myString (NULL),
+  mySize   (0),
+  myLength (0)
+{
+  FromUnicode (theCopyUtf32, theLength);
+}
+
+// =======================================================================
+// function : NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
+                                                    const Standard_Integer   theLength)
+: myString (NULL),
+  mySize   (0),
+  myLength (0)
+{
+  FromUnicode (theCopyUtfWide, theLength);
+}
+
+// =======================================================================
+// function : ~NCollection_UtfString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>::~NCollection_UtfString()
+{
+  strFree (myString);
+}
+
+// =======================================================================
+// function : operator=
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const NCollection_UtfString<Type>& theOther)
+{
+  if (this == &theOther)
+  {
+    return (*this);
+  }
+
+  strFree (myString);
+  mySize   = theOther.mySize;
+  myLength = theOther.myLength;
+  myString = strAlloc (mySize);
+  strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theOther.myString, mySize);
+  return (*this);
+}
+
+// =======================================================================
+// function : FromUnicode
+// purpose  :
+// =======================================================================
+template<typename Type> template<typename TypeFrom>
+void NCollection_UtfString<Type>::FromUnicode (const TypeFrom*        theStringUtf,
+                                               const Standard_Integer theLength)
+{
+  Type* anOldBuffer = myString; // necessary in case of self-copying
+  NCollection_UtfIterator<TypeFrom> anIterRead (theStringUtf);
+  if (*anIterRead == 0)
+  {
+    // special case
+    Clear();
+    return;
+  }
+
+  switch (sizeof(TypeFrom)) // use switch() rather than if() to shut up msvc compiler
+  {
+    case sizeof(Type):
+    {
+      if (theLength > 0)
+      {
+        // optimized copy
+        for(; *anIterRead != 0 && anIterRead.Index() < theLength; ++anIterRead) {}
+
+        mySize   = Standard_Integer((Standard_Byte* )anIterRead.BufferHere() - (Standard_Byte* )theStringUtf);
+        myLength = anIterRead.Index();
+        myString = strAlloc (mySize);
+        strCopy ((Standard_Byte* )myString, (const Standard_Byte* )theStringUtf, mySize);
+        strFree (anOldBuffer);
+        return;
+      }
+    }
+    default: break;
+  }
+
+  strGetAdvance (theStringUtf, theLength, mySize, myLength);
+  myString = strAlloc (mySize);
+  // reset iterator
+  anIterRead.Init (theStringUtf);
+  Type* anIterWrite = myString;
+  for (; *anIterRead != 0 && anIterRead.Index() < myLength; ++anIterRead)
+  {
+    anIterWrite = anIterRead.GetUtf (anIterWrite);
+  }
+  strFree (anOldBuffer);
+}
+
+// =======================================================================
+// function : FromLocale
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+void NCollection_UtfString<Type>::FromLocale (const char*            theString,
+                                              const Standard_Integer theLength)
+{
+#if(defined(_WIN32) || defined(__WIN32__))
+  // use WinAPI
+  int aWideSize = MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, theString, -1, NULL, 0);
+  if (aWideSize <= 0)
+  {
+    Clear();
+    return;
+  }
+  wchar_t* aWideBuffer = new wchar_t[aWideSize + 1];
+  MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, theString, -1, aWideBuffer, aWideSize);
+  aWideBuffer[aWideSize] = L'\0';
+  FromUnicode (aWideBuffer, theLength);
+  delete[] aWideBuffer;
+#else
+  // this is size in bytes but should probably be enough to store string in wide chars
+  // notice that these functions are sensitive to locale set by application!
+  int aMbLen = mblen (theString, MB_CUR_MAX);
+  if (aMbLen <= 0)
+  {
+    Clear();
+    return;
+  }
+  wchar_t* aWideBuffer = new wchar_t[aMbLen + 1];
+  mbstowcs (aWideBuffer, theString, aMbLen);
+  aWideBuffer[aMbLen] = L'\0';
+  FromUnicode (aWideBuffer, theLength);
+  delete[] aWideBuffer;
+#endif
+}
+
+// =======================================================================
+// function : ToLocale
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+bool NCollection_UtfString<Type>::ToLocale (char*                  theBuffer,
+                                            const Standard_Integer theSizeBytes) const
+{
+  NCollection_UtfString<wchar_t> aWideCopy (myString, myLength);
+#if(defined(_WIN32) || defined(__WIN32__))
+  int aMbBytes = WideCharToMultiByte (CP_ACP, 0, aWideCopy.ToCString(), -1, theBuffer, theSizeBytes, NULL, NULL);
+#else
+  std::size_t aMbBytes = std::wcstombs (theBuffer, aWideCopy.ToCString(), theSizeBytes);
+#endif
+  if (aMbBytes <= 0)
+  {
+    *theBuffer = '\0';
+    return false;
+  }
+  return true;
+}
+
+// =======================================================================
+// function : operator=
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const char* theStringUtf8)
+{
+  FromUnicode (theStringUtf8);
+  return (*this);
+}
+
+// =======================================================================
+// function : operator=
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator= (const Standard_WideChar* theStringUtfWide)
+{
+  FromUnicode (theStringUtfWide);
+  return (*this);
+}
+
+// =======================================================================
+// function : IsEqual
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+bool NCollection_UtfString<Type>::IsEqual (const NCollection_UtfString& theCompare) const
+{
+  return this == &theCompare
+      || strAreEqual (myString, mySize, theCompare.myString, theCompare.mySize);
+}
+
+// =======================================================================
+// function : operator!=
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+bool NCollection_UtfString<Type>::operator!= (const NCollection_UtfString& theCompare) const
+{
+  return (!NCollection_UtfString::operator== (theCompare));
+}
+
+// =======================================================================
+// function : operator+=
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type>& NCollection_UtfString<Type>::operator+= (const NCollection_UtfString<Type>& theAppend)
+{
+  if (theAppend.IsEmpty())
+  {
+    return (*this);
+  }
+
+  // create new string
+  Standard_Integer aSize = mySize + theAppend.mySize;
+  Type* aString = strAlloc (aSize);
+  strCopy ((Standard_Byte* )aString,          (const Standard_Byte* )myString,           mySize);
+  strCopy ((Standard_Byte* )aString + mySize, (const Standard_Byte* )theAppend.myString, theAppend.mySize);
+
+  strFree (myString);
+  mySize   = aSize;
+  myString = aString;
+  myLength += theAppend.myLength;
+  return (*this);
+}
+
+// =======================================================================
+// function : SubString
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+NCollection_UtfString<Type> NCollection_UtfString<Type>::SubString (const Standard_Integer theStart,
+                                                                    const Standard_Integer theEnd) const
+{
+  if (theStart >= theEnd)
+  {
+    return NCollection_UtfString<Type>();
+  }
+  for (NCollection_UtfIterator<Type> anIter(myString); *anIter != 0; ++anIter)
+  {
+    if (anIter.Index() >= theStart)
+    {
+      return NCollection_UtfString<Type> (anIter.BufferHere(), theEnd - theStart);
+    }
+  }
+  return NCollection_UtfString<Type>();
+}
+
+// =======================================================================
+// function : ToUtf8
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Standard_Utf8Char> NCollection_UtfString<Type>::ToUtf8() const
+{
+  NCollection_UtfString<Standard_Utf8Char> aCopy;
+  aCopy.FromUnicode (myString);
+  return aCopy;
+}
+
+// =======================================================================
+// function : ToUtf16
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Standard_Utf16Char> NCollection_UtfString<Type>::ToUtf16() const
+{
+  NCollection_UtfString<Standard_Utf16Char> aCopy;
+  aCopy.FromUnicode (myString);
+  return aCopy;
+}
+
+// =======================================================================
+// function : ToUtf32
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Standard_Utf32Char> NCollection_UtfString<Type>::ToUtf32() const
+{
+  NCollection_UtfString<Standard_Utf32Char> aCopy;
+  aCopy.FromUnicode (myString);
+  return aCopy;
+}
+
+// =======================================================================
+// function : ToUtfWide
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+const NCollection_UtfString<Standard_WideChar> NCollection_UtfString<Type>::ToUtfWide() const
+{
+  NCollection_UtfString<Standard_WideChar> aCopy;
+  aCopy.FromUnicode (myString);
+  return aCopy;
+}
index eb1c7b8..5e94b22 100755 (executable)
@@ -17,8 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
-
 #ifndef NCollection_Vector_HeaderFile
 #define NCollection_Vector_HeaderFile
 
@@ -200,6 +198,26 @@ template <class TheItemType> class NCollection_Vector
   //! Total number of items in the vector
   virtual Standard_Integer Size () const        { return Length(); }
 
+  //! Method for consistency with other collections.
+  //! @return Lower bound (inclusive) for iteration.
+  Standard_Integer Lower() const
+  {
+    return 0;
+  }
+
+  //! Method for consistency with other collections.
+  //! @return Upper bound (inclusive) for iteration.
+  Standard_Integer Upper() const
+  {
+    return Length() - 1;
+  }
+
+  //! Empty query
+  Standard_Boolean IsEmpty() const
+  {
+    return (Length() == 0);
+  }
+
   //! Virtual assignment (any collection to this array)
   virtual void Assign (const NCollection_BaseCollection<TheItemType>& theOther)
   {
@@ -242,6 +260,30 @@ template <class TheItemType> class NCollection_Vector
     return * (const TheItemType *) Find (theIndex);
   }
 
+  //! @return first element
+  const TheItemType& First() const
+  {
+    return *(const TheItemType* )Find (Lower());
+  }
+
+  //! @return first element
+  TheItemType& ChangeFirst()
+  {
+    return *(TheItemType* )Find (Lower());
+  }
+
+  //! @return last element
+  const TheItemType& Last() const
+  {
+    return *(const TheItemType* )Find (Upper());
+  }
+
+  //! @return last element
+  TheItemType& ChangeLast()
+  {
+    return *(TheItemType* )Find (Upper());
+  }
+
   //! Operator () - query the value
   TheItemType& operator () (const Standard_Integer theIndex)
                                         { return ChangeValue (theIndex); }
index 77eb97d..26f5c2b 100755 (executable)
@@ -49,10 +49,10 @@ NIS_TriangulatedDrawer::NIS_TriangulatedDrawer
                                 (const Quantity_Color theNormal,
                                  const Quantity_Color theHilight,
                                  const Quantity_Color theDynHilight)
-  : myLineWidth      (1.f),
+  : myPolygonAsLineLoop (Standard_False),
+    myLineWidth      (1.f),
     myIsDrawPolygons (Standard_False),
-    myPolygonType    (NIS_Triangulated::Polygon_Default),
-    myPolygonAsLineLoop (Standard_False)
+    myPolygonType    (NIS_Triangulated::Polygon_Default)
 {
   myColor[Draw_Normal]       = theNormal;
   myColor[Draw_Top]          = theNormal;
@@ -285,6 +285,7 @@ void NIS_TriangulatedDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
   else {
     Standard_Boolean isLoop;
     if (pObject->IsLine(isLoop))
+    {
       if (isLoop) {
 //         glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
         glDrawElements (GL_LINE_LOOP, pObject->NLineNodes(),
@@ -294,6 +295,7 @@ void NIS_TriangulatedDrawer::Draw (const Handle_NIS_InteractiveObject& theObj,
         glDrawElements (GL_LINE_STRIP, pObject->NLineNodes(),
                         aType, pObject->mypLines);
       }
+    }
   }
 
 }
index 8779a60..21580fc 100755 (executable)
@@ -8,5 +8,4 @@ CSF_IOKit
 CSF_OpenGlLibs
 CSF_AviLibs
 CSF_FREETYPE
-CSF_FTGL
 CSF_GL2PS
index a5f77cb..e6e91ca 100755 (executable)
@@ -8,13 +8,9 @@ OpenGl_GraphicDriver_2.cxx
 OpenGl_GraphicDriver_3.cxx
 OpenGl_GraphicDriver_4.cxx
 OpenGl_GraphicDriver_7.cxx
-OpenGl_GraphicDriver_9.cxx
 OpenGl_GraphicDriver_703.cxx
-OpenGl_GraphicDriver_705.cxx
-OpenGl_GraphicDriver_710.cxx
 OpenGl_GraphicDriver_713.cxx
 OpenGl_GraphicDriver_Layer.cxx
-OpenGl_GraphicDriver_print.cxx
 OpenGl_GraphicDriver_Export.cxx
 OpenGl_AspectLine.hxx
 OpenGl_AspectLine.cxx
@@ -29,8 +25,11 @@ OpenGl_Group.cxx
 OpenGl_Structure.hxx
 OpenGl_Structure.cxx
 OpenGl_Element.hxx
+OpenGl_Element.cxx
 OpenGl_Text.hxx
 OpenGl_Text.cxx
+OpenGl_TextFormatter.hxx
+OpenGl_TextFormatter.cxx
 OpenGl_Polyline.hxx
 OpenGl_Polyline.cxx
 OpenGl_Marker.hxx
@@ -47,7 +46,6 @@ OpenGl_Workspace.cxx
 OpenGl_Workspace_1.cxx
 OpenGl_Workspace_2.cxx
 OpenGl_Workspace_3.cxx
-OpenGl_Workspace_4.cxx
 OpenGl_Workspace_5.cxx
 Handle_OpenGl_View.hxx
 OpenGl_View.hxx
@@ -55,10 +53,8 @@ OpenGl_View.cxx
 OpenGl_View_1.cxx
 OpenGl_View_2.cxx
 OpenGl_Light.hxx
-Handle_OpenGl_Trihedron.hxx
 OpenGl_Trihedron.hxx
 OpenGl_Trihedron.cxx
-Handle_OpenGl_GraduatedTrihedron.hxx
 OpenGl_GraduatedTrihedron.hxx
 OpenGl_GraduatedTrihedron.cxx
 OpenGl_Matrix.hxx
@@ -71,7 +67,6 @@ OpenGl_PrinterContext.cxx
 Handle_OpenGl_Display.hxx
 OpenGl_Display.hxx
 OpenGl_Display.cxx
-OpenGl_Display_1.cxx
 OpenGl_Display_2.cxx
 Handle_OpenGl_Window.hxx
 OpenGl_Window.hxx
@@ -94,8 +89,8 @@ OpenGl_Resource.cxx
 OpenGl_telem_util.hxx
 OpenGl_telem_util.cxx
 OpenGl_transform_persistence.hxx
-OpenGl_FontMgr.hxx
-OpenGl_FontMgr.cxx
+OpenGl_Font.hxx
+OpenGl_Font.cxx
 OpenGl_tgl_funcs.hxx
 Handle_OpenGl_Context.hxx
 OpenGl_Context.hxx
@@ -119,6 +114,7 @@ OpenGl_IndexBuffer.hxx
 OpenGl_IndexBuffer.cxx
 OpenGl_TextureBufferArb.hxx
 OpenGl_TextureBufferArb.cxx
+OpenGl_Vec.hxx
 OpenGl_VertexBuffer.hxx
 OpenGl_VertexBuffer.cxx
 OpenGl_VertexBufferEditor.hxx
index c889b2d..57def3b 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-07-13
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 #include <OpenGl_AspectText.hxx>
 #include <OpenGl_Workspace.hxx>
 
-static const TEL_COLOUR myDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
-
-/*----------------------------------------------------------------------*/
+namespace
+{
+  static const TEL_COLOUR TheDefaultColor = {{ 1.0F, 1.0F, 1.0F, 1.0F }};
+};
 
-OpenGl_AspectText::OpenGl_AspectText ()
- : myZoomable(0),
-   myAngle(0.0F),
-   myFontAspect(Font_FA_Regular),
-   myFont(NULL),
-   //mySpace(0.3F),
-   //myExpan(1.0F),
-   myColor(myDefaultColor),
-   myStyleType(Aspect_TOST_NORMAL),
-   myDisplayType(Aspect_TODT_NORMAL),
-   mySubtitleColor(myDefaultColor)
+// =======================================================================
+// function : OpenGl_AspectText
+// purpose  :
+// =======================================================================
+OpenGl_AspectText::OpenGl_AspectText()
+: myFont ("Courier") ,
+  myColor (TheDefaultColor),
+  mySubtitleColor (TheDefaultColor),
+  myAngle (0.0f),
+  myStyleType   (Aspect_TOST_NORMAL),
+  myDisplayType (Aspect_TODT_NORMAL),
+  myFontAspect  (Font_FA_Regular),
+  myZoomable (false)
 {
-  SetFontName( (const char *) "Courier" );
+  //
 }
 
-/*----------------------------------------------------------------------*/
-
-OpenGl_AspectText::~OpenGl_AspectText ()
+// =======================================================================
+// function : ~OpenGl_AspectText
+// purpose  :
+// =======================================================================
+OpenGl_AspectText::~OpenGl_AspectText()
 {
-  if (myFont)
-    delete[] myFont;
+  //
 }
 
-/*----------------------------------------------------------------------*/
-
-void OpenGl_AspectText::SetContext (const CALL_DEF_CONTEXTTEXT &AContext)
+// =======================================================================
+// function : SetContext
+// purpose  :
+// =======================================================================
+void OpenGl_AspectText::SetContext (const CALL_DEF_CONTEXTTEXT& theContext)
 {
-  myZoomable = (int) AContext.TextZoomable;
-  myAngle = (float) AContext.TextAngle;
-  myFontAspect = (Font_FontAspect) AContext.TextFontAspect;
-  //mySpace = (float) AContext.Space;
-  //myExpan = (float) AContext.Expan;
-  myColor.rgb[0] = (float) AContext.Color.r;
-  myColor.rgb[1] = (float) AContext.Color.g;
-  myColor.rgb[2] = (float) AContext.Color.b;
+  myFont = theContext.Font;
+  myColor.rgb[0] = (float )theContext.Color.r;
+  myColor.rgb[1] = (float )theContext.Color.g;
+  myColor.rgb[2] = (float )theContext.Color.b;
   myColor.rgb[3] = 1.0f;
-  myStyleType = (Aspect_TypeOfStyleText) AContext.Style;
-  myDisplayType = (Aspect_TypeOfDisplayText) AContext.DisplayType;
-  mySubtitleColor.rgb[0] = (float) AContext.ColorSubTitle.r;
-  mySubtitleColor.rgb[1] = (float) AContext.ColorSubTitle.g;
-  mySubtitleColor.rgb[2] = (float) AContext.ColorSubTitle.b;
+  mySubtitleColor.rgb[0] = (float )theContext.ColorSubTitle.r;
+  mySubtitleColor.rgb[1] = (float )theContext.ColorSubTitle.g;
+  mySubtitleColor.rgb[2] = (float )theContext.ColorSubTitle.b;
   mySubtitleColor.rgb[3] = 1.0f;
-
-  SetFontName( (const char *) AContext.Font );
+  myAngle = (float )theContext.TextAngle;
+  myStyleType   = (Aspect_TypeOfStyleText   )theContext.Style;
+  myDisplayType = (Aspect_TypeOfDisplayText )theContext.DisplayType;
+  myFontAspect  = (Font_FontAspect )theContext.TextFontAspect;
+  myZoomable    = (theContext.TextZoomable != 0);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_AspectText::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   theWorkspace->SetAspectText (this);
 }
 
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
 void OpenGl_AspectText::Release (const Handle(OpenGl_Context)& theContext)
 {
   //
 }
-
-/*----------------------------------------------------------------------*/
-
-void OpenGl_AspectText::SetFontName (const char *AFont)
-{
-  if (myFont)
-    delete[] myFont;
-  char *fontname = new char[ strlen( AFont ) + 1 ];
-  strcpy( fontname, AFont );
-  myFont = fontname;
-}
-
-/*----------------------------------------------------------------------*/
index d7fd9ac..1970806 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-07-13
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 #include <Aspect_TypeOfStyleText.hxx>
 #include <Aspect_TypeOfDisplayText.hxx>
 
+#include <TCollection_AsciiString.hxx>
+
 #include <OpenGl_Element.hxx>
 
+//! Text representation parameters
 class OpenGl_AspectText : public OpenGl_Element
 {
 
@@ -35,36 +38,99 @@ public:
   OpenGl_AspectText();
   virtual ~OpenGl_AspectText();
 
-  void SetContext (const CALL_DEF_CONTEXTTEXT &AContext);
-
-  int                      IsZoomable() const { return myZoomable; }
-  float                    Angle() const { return myAngle; }
-  Font_FontAspect          FontAspect() const { return myFontAspect; }
-  const char *             Font() const { return myFont; }
-  const TEL_COLOUR &       Color() const { return myColor; }
-  Aspect_TypeOfStyleText   StyleType() const { return myStyleType; }
-  Aspect_TypeOfDisplayText DisplayType() const { return myDisplayType; }
-  const TEL_COLOUR &       SubtitleColor() const { return mySubtitleColor; }
+  //! Copy parameters
+  void SetContext (const CALL_DEF_CONTEXTTEXT& theContext);
+
+  //! @return font family name
+  const TCollection_AsciiString& FontName() const
+  {
+    return myFont;
+  }
+
+  //! @return font family name
+  TCollection_AsciiString& ChangeFontName()
+  {
+    return myFont;
+  }
+
+  //! @return is zoomable flag
+  bool IsZoomable() const
+  {
+    return myZoomable;
+  }
+
+  //! @return rotation angle
+  float Angle() const
+  {
+    return myAngle;
+  }
+
+  //! @return font aspect (regular/bold/italic)
+  Font_FontAspect FontAspect() const
+  {
+    return myFontAspect;
+  }
+
+  //! @param theValue font aspect (regular/bold/italic)
+  void SetFontAspect (const Font_FontAspect theValue)
+  {
+    myFontAspect = theValue;
+  }
+
+  //! @return text color
+  const TEL_COLOUR& Color() const
+  {
+    return myColor;
+  }
+
+  //! @return text color
+  TEL_COLOUR& ChangeColor()
+  {
+    return myColor;
+  }
+
+  //! @return annotation style
+  Aspect_TypeOfStyleText StyleType() const
+  {
+    return myStyleType;
+  }
+
+  //! @return subtitle style (none/blend/decale/subtitle)
+  Aspect_TypeOfDisplayText DisplayType() const
+  {
+    return myDisplayType;
+  }
+
+  void SetDisplayType (const Aspect_TypeOfDisplayText theType)
+  {
+    myDisplayType = theType;
+  }
+
+  //! @return subtitle color
+  const TEL_COLOUR& SubtitleColor() const
+  {
+    return mySubtitleColor;
+  }
+
+  //! @return subtitle color
+  TEL_COLOUR& ChangeSubtitleColor()
+  {
+    return mySubtitleColor;
+  }
 
   virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
   virtual void Release (const Handle(OpenGl_Context)&   theContext);
 
 protected:
 
-  void SetFontName (const char *AFont);
-
-protected:
-
-  int                      myZoomable;
-  float                    myAngle;
-  Font_FontAspect          myFontAspect;
-  const char              *myFont;
-  //float                  mySpace;
-  //float                  myExpan;
+  TCollection_AsciiString  myFont;
   TEL_COLOUR               myColor;
+  TEL_COLOUR               mySubtitleColor;
+  float                    myAngle;
   Aspect_TypeOfStyleText   myStyleType;
   Aspect_TypeOfDisplayText myDisplayType;
-  TEL_COLOUR               mySubtitleColor;
+  Font_FontAspect          myFontAspect;
+  bool                     myZoomable;
 
 public:
 
@@ -72,4 +138,4 @@ public:
 
 };
 
-#endif //OpenGl_AspectText_Header
+#endif // OpenGl_AspectText_Header
index c26001a..0262971 100644 (file)
@@ -30,6 +30,8 @@
 #include <OpenGl_ExtGS.hxx>
 #include <OpenGl_GlCore20.hxx>
 
+#include <NCollection_Vector.hxx>
+
 #include <Standard_ProgramError.hxx>
 
 #if (defined(_WIN32) || defined(__WIN32__))
@@ -84,7 +86,8 @@ OpenGl_Context::OpenGl_Context()
   atiMem (Standard_False),
   nvxMem (Standard_False),
   mySharedResources (new OpenGl_ResourcesMap()),
-  myReleaseQueue (new OpenGl_ResourcesQueue()),
+  myDelayed         (new OpenGl_DelayReleaseMap()),
+  myReleaseQueue    (new OpenGl_ResourcesQueue()),
   myGlLibHandle (NULL),
   myGlCore20 (NULL),
   myMaxTexDim  (1024),
@@ -127,6 +130,7 @@ OpenGl_Context::~OpenGl_Context()
     }
   }
   mySharedResources.Nullify();
+  myDelayed.Nullify();
 
   delete myGlCore20;
   delete arbVBO;
@@ -161,6 +165,7 @@ void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
   if (!theShareCtx.IsNull())
   {
     mySharedResources = theShareCtx->mySharedResources;
+    myDelayed         = theShareCtx->myDelayed;
     myReleaseQueue    = theShareCtx->myReleaseQueue;
   }
 }
@@ -955,7 +960,8 @@ Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& t
 // function : ReleaseResource
 // purpose  :
 // =======================================================================
-void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
+void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
+                                      const Standard_Boolean         theToDelay)
 {
   if (!mySharedResources->IsBound (theKey))
   {
@@ -967,8 +973,15 @@ void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
     return;
   }
 
-  aRes->Release (this);
-  mySharedResources->UnBind (theKey);
+  if (theToDelay)
+  {
+    myDelayed->Bind (theKey, 1);
+  }
+  else
+  {
+    aRes->Release (this);
+    mySharedResources->UnBind (theKey);
+  }
 }
 
 // =======================================================================
@@ -987,9 +1000,48 @@ void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
 // =======================================================================
 void OpenGl_Context::ReleaseDelayed()
 {
+  // release queued elements
   while (!myReleaseQueue->IsEmpty())
   {
     myReleaseQueue->Front()->Release (this);
     myReleaseQueue->Pop();
   }
+
+  // release delayed shared resoruces
+  NCollection_Vector<TCollection_AsciiString> aDeadList;
+  for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
+       anIter.More(); anIter.Next())
+  {
+    if (++anIter.ChangeValue() <= 2)
+    {
+      continue; // postpone release one more frame to ensure noone use it periodically
+    }
+
+    const TCollection_AsciiString& aKey = anIter.Key();
+    if (!mySharedResources->IsBound (aKey))
+    {
+      // mixed unshared strategy delayed/undelayed was used!
+      aDeadList.Append (aKey);
+      continue;
+    }
+
+    Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
+    if (aRes->GetRefCount() > 1)
+    {
+      // should be only 1 instance in mySharedResources
+      // if not - resource was reused again
+      aDeadList.Append (aKey);
+      continue;
+    }
+
+    // release resource if no one requiested it more than 2 redraw calls
+    aRes->Release (this);
+    mySharedResources->UnBind (aKey);
+    aDeadList.Append (aKey);
+  }
+
+  for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
+  {
+    myDelayed->UnBind (aDeadList.Value (anIter));
+  }
 }
index a125ad4..a35b36e 100644 (file)
@@ -82,6 +82,25 @@ class OpenGl_Context : public Standard_Transient
 {
 public:
 
+  //! Function for getting power of to number larger or equal to input number.
+  //! @param theNumber    number to 'power of two'
+  //! @param theThreshold upper threshold
+  //! @return power of two number
+  inline static Standard_Integer GetPowerOfTwo (const Standard_Integer theNumber,
+                                                const Standard_Integer theThreshold)
+  {
+    for (Standard_Integer p2 = 2; p2 <= theThreshold; p2 <<= 1)
+    {
+      if (theNumber <= p2)
+      {
+        return p2;
+      }
+    }
+    return theThreshold;
+  }
+
+public:
+
   //! Empty constructor. You should call Init() to perform initialization with bound GL context.
   Standard_EXPORT OpenGl_Context();
 
@@ -201,8 +220,10 @@ public:
   //! This means that current object itself should nullify handle before this call.
   //! Notice that this is unrecommended operation at all and should be used
   //! only in case of fat resources to release memory for other needs.
-  //! @param  theKey - unique identifier.
-  Standard_EXPORT void ReleaseResource (const TCollection_AsciiString& theKey);
+  //! @param theKey     unique identifier
+  //! @param theToDelay postpone release until next redraw call
+  Standard_EXPORT void ReleaseResource (const TCollection_AsciiString& theKey,
+                                        const Standard_Boolean         theToDelay = Standard_False);
 
   //! Append resource to queue for delayed clean up.
   //! Resources in this queue will be released at next redraw call.
@@ -265,13 +286,16 @@ private: // system-dependent fields
 
 private: // context info
 
+  typedef NCollection_DataMap<TCollection_AsciiString, Standard_Integer> OpenGl_DelayReleaseMap;
+  typedef NCollection_Handle<OpenGl_DelayReleaseMap> Handle(OpenGl_DelayReleaseMap);
   typedef NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)> OpenGl_ResourcesMap;
   typedef NCollection_Handle<OpenGl_ResourcesMap> Handle(OpenGl_ResourcesMap);
   typedef NCollection_Queue<Handle(OpenGl_Resource)> OpenGl_ResourcesQueue;
   typedef NCollection_Handle<OpenGl_ResourcesQueue> Handle(OpenGl_ResourcesQueue);
 
-  Handle(OpenGl_ResourcesMap)   mySharedResources; //!< shared resourced with unique identification key
-  Handle(OpenGl_ResourcesQueue) myReleaseQueue;    //!< queue of resources for delayed clean up
+  Handle(OpenGl_ResourcesMap)    mySharedResources; //!< shared resources with unique identification key
+  Handle(OpenGl_DelayReleaseMap) myDelayed;         //!< shared resources for delayed release
+  Handle(OpenGl_ResourcesQueue)  myReleaseQueue;    //!< queue of resources for delayed clean up
 
   void*            myGlLibHandle;   //!< optional handle to GL library
   OpenGl_GlCore20* myGlCore20;      //!< common structure for GL core functions upto 2.0
index 12b44a8..5b6e558 100644 (file)
@@ -61,9 +61,7 @@ OpenGl_Display::OpenGl_Display (const Standard_CString theDisplay)
   myAntiAliasingMode(3),
   myLinestyleBase(0),
   myPatternBase(0),
-  myMarkerBase(0),
-  myFont(-1),
-  myFontSize(-1)
+  myMarkerBase(0)
 {
 #if (defined(_WIN32) || defined(__WIN32__)) || (defined(__APPLE__) && !defined(MACOSX_USE_GLX))
   myDisplay = TheDummyDisplay;
@@ -99,9 +97,7 @@ OpenGl_Display::OpenGl_Display (const Aspect_Display theDisplay)
   myAntiAliasingMode(3),
   myLinestyleBase(0),
   myPatternBase(0),
-  myMarkerBase(0),
-  myFont(-1),
-  myFontSize(-1)
+  myMarkerBase(0)
 {
 #if (defined(_WIN32) || defined(__WIN32__))
   myDisplay = TheDummyDisplay;
index 95b8a9a..ccc1c3b 100644 (file)
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef _OpenGl_Display_Header
 #define _OpenGl_Display_Header
 
@@ -113,14 +112,6 @@ class OpenGl_Display : public MMgt_TShared
 
   Standard_Integer GetUserMarkerListIndex (const Standard_Integer AIndex) const;
 
-  // Fonts
-
-  Standard_Integer FindFont (Standard_CString theFontName, const Font_FontAspect theFontAspect, const Standard_Integer theBestSize = -1, const Standard_ShortReal theXScale = 1.F, const Standard_ShortReal theYScale = 1.F);
-
-  void StringSize (const wchar_t *text, int &width, int &ascent, int &descent);
-
-  void RenderText (const wchar_t *text, const int is2d, const float x, const float y, const float z, const OpenGl_AspectText *aspect, const OpenGl_TextParam *param);
-
   friend class OpenGl_Window;
 
   // Type definition
@@ -161,9 +152,6 @@ class OpenGl_Display : public MMgt_TShared
 
   OpenGl_MapOfUserMarker myMapOfUM;
 
-  Standard_Integer myFont;
-  Standard_Integer myFontSize;
-
  public:
   DEFINE_STANDARD_ALLOC
 };
diff --git a/src/OpenGl/OpenGl_Display_1.cxx b/src/OpenGl/OpenGl_Display_1.cxx
deleted file mode 100644 (file)
index e7f06e9..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-// Created on: 2011-10-25
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-#include <OpenGl_GlCore11.hxx>
-
-#include <InterfaceGraphic.hxx>
-#include <OpenGl_Display.hxx>
-
-#include <TCollection_AsciiString.hxx>
-#include <TCollection_HAsciiString.hxx>
-
-#include <OpenGl_FontMgr.hxx>
-#include <OpenGl_PrinterContext.hxx>
-#include <OpenGl_AspectText.hxx>
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifdef HAVE_GL2PS
-#include <gl2ps.h>
-#endif
-
-/*-----------------------------------------------------------------------------*/
-/*
-* Prototypes variables statiques
-*/
-
-struct FontMapNode
-{
-  const char *    EnumName;
-  const char *    FontName;
-  Font_FontAspect FontAspect;
-};
-
-static const FontMapNode myFontMap[] =
-{
-
-#ifdef WNT
-
-  { "Courier"                  , "Courier New"    , Font_FA_Regular },
-  { "Times-Roman"              , "Times New Roman", Font_FA_Regular  },
-  { "Times-Bold"               , "Times New Roman", Font_FA_Bold },
-  { "Times-Italic"             , "Times New Roman", Font_FA_Italic  },
-  { "Times-BoldItalic"         , "Times New Roman", Font_FA_BoldItalic  },
-  { "ZapfChancery-MediumItalic", "Script"         , Font_FA_Regular  },
-  { "Symbol"                   , "Symbol"         , Font_FA_Regular  },
-  { "ZapfDingbats"             , "WingDings"      , Font_FA_Regular  },
-  { "Rock"                     , "Arial"          , Font_FA_Regular  },
-  { "Iris"                     , "Lucida Console" , Font_FA_Regular  }
-
-#else   //X11
-
-  { "Courier"                  , "Courier"      , Font_FA_Regular },
-  { "Times-Roman"              , "Times"        , Font_FA_Regular  },
-  { "Times-Bold"               , "Times"        , Font_FA_Bold },
-  { "Times-Italic"             , "Times"        , Font_FA_Italic  },
-  { "Times-BoldItalic"         , "Times"        , Font_FA_BoldItalic  },
-  { "Arial"                    , "Helvetica"    , Font_FA_Regular  },
-  { "ZapfChancery-MediumItalic", "-adobe-itc zapf chancery-medium-i-normal--*-*-*-*-*-*-iso8859-1"              , Font_FA_Regular  },
-  { "Symbol"                   , "-adobe-symbol-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"                , Font_FA_Regular  },
-  { "ZapfDingbats"             , "-adobe-itc zapf dingbats-medium-r-normal--*-*-*-*-*-*-adobe-fontspecific"     , Font_FA_Regular  },
-  { "Rock"                     , "-sgi-rock-medium-r-normal--*-*-*-*-p-*-iso8859-1"                             , Font_FA_Regular  },
-  { "Iris"                     , "--iris-medium-r-normal--*-*-*-*-m-*-iso8859-1"                                , Font_FA_Regular  }
-#endif
-
-};
-
-#define NUM_FONT_ENTRIES (sizeof(myFontMap)/sizeof(FontMapNode))
-
-/*-----------------------------------------------------------------------------*/
-
-/*
-*  Constants
-*/
-
-#ifdef HAVE_GL2PS
-void OpenGl_Display::getGL2PSFontName (const char *src_font, char *ps_font)
-{
-  /*
-  Convert font name used for rendering to some "good" font names
-  that produce good vector text
-  */
-  static char const *family[] = {"Helvetica", "Courier", "Times"};
-  static char const *italic[] = {"Oblique", "Oblique", "Italic"};
-  static char const *base[] = {"", "", "-Roman"};
-
-  int font = 0;
-  int isBold = 0;
-  int isItalic = 0;
-
-  if( strstr( src_font, "Symbol" ) ){
-    sprintf( ps_font, "%s", "Symbol" );
-    return;
-  }
-
-  if( strstr( src_font, "ZapfDingbats" ) ){
-    sprintf( ps_font, "%s", "WingDings" );
-    return;
-  }
-
-  if ( strstr( src_font, "Courier" ) ){
-    font = 1;
-  }
-  else if ( strstr( src_font, "Times" ) ){
-    font = 2;
-  }
-
-  if ( strstr( src_font, "Bold" ) ){
-    isBold = 1;
-  }
-
-  if ( strstr( src_font, "Italic" ) || strstr( src_font, "Oblique" ) ){
-    isItalic = 1;
-  }
-
-  if ( isBold ){
-    sprintf( ps_font, "%s-%s", family[font], "Bold");
-    if ( isItalic ){
-      sprintf(ps_font, "%s%s", ps_font, italic[font]);
-    }
-  }
-  else if ( isItalic )
-  {
-    sprintf( ps_font, "%s-%s", family[font], italic[font] );
-  }
-  else
-  {
-    sprintf( ps_font, "%s%s", family[font], base[font] );
-  }
-}
-#endif
-
-/*-----------------------------------------------------------------------------*/
-
-/*
-* Fonctions publiques
-*/
-
-/*-----------------------------------------------------------------------------*/
-
-int OpenGl_Display::FindFont (const char* AFontName, const Font_FontAspect AFontAspect,
-                             const int ABestSize, const float AXScale, const float AYScale)
-{
-  if (!AFontName)
-    return -1;
-
-  if (ABestSize != -1)
-    myFontSize = ABestSize;
-
-  OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
-
-  Handle(TCollection_HAsciiString) family_name = new TCollection_HAsciiString(AFontName);
-  myFont = mgr->request_font( family_name, AFontAspect, myFontSize );
-
-  if( myFont == -1 )
-  {
-    //try to use font names mapping
-    FontMapNode newTempFont = myFontMap[0];
-    for ( int i = 0; i < NUM_FONT_ENTRIES; ++i )
-    {
-      if ( TCollection_AsciiString(myFontMap[i].EnumName).IsEqual( family_name->ToCString() ) )
-      {
-        newTempFont = myFontMap[i];
-        break;
-      }
-    }
-    family_name = new TCollection_HAsciiString(newTempFont.FontName);
-    myFont = mgr->request_font( family_name, newTempFont.FontAspect, myFontSize );
-  }
-
-  // Requested family name not found -> serach for any font family with given aspect and height
-  if ( myFont == -1 )
-  {
-    family_name = new TCollection_HAsciiString( "" );
-    myFont = mgr->request_font( family_name, AFontAspect, myFontSize );
-  }
-
-  // The last resort: trying to use ANY font available in the system
-  if ( myFont == -1 )
-  {
-    myFont = mgr->request_font( family_name, Font_FA_Undefined, -1 );
-  }
-
-  if ( myFont != -1 )
-    mgr->setCurrentScale( AXScale, AYScale );
-
-  return myFont;
-}
-
-/*-----------------------------------------------------------------------------*/
-
-void OpenGl_Display::StringSize (const wchar_t *str, int &width, int &ascent, int &descent)
-{
-  ascent = 0;
-  descent = 0;
-  width = 0;
-  if (myFont != -1) {
-    OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
-    const FTFont* font = mgr->fontById( myFont );
-    if ( font ) {
-      width = int( mgr->computeWidth( myFont, str ) );
-      ascent = int( font->Ascender() );
-      descent = int( font->Descender() );
-    }
-  }
-}
-
-/*
-  Class       : MultilineTextRenderer
-  Description : Class for constructing text and multi-line text
-*/
-
-class MultilineTextRenderer
-{
-  private:
-
-  Standard_Integer        myLFNum;        // Number of '\n' (Line Feed) '\x00\x0A'
-  Standard_Integer        myCurrPos;      // Position of the current substring
-  Standard_Integer        myNewStrLen;    // Length of the new string
-  Standard_Integer        mySubstrNum;    // Number of substrings
-  wchar_t                 *myNewStr;      // New string
-  const wchar_t           *myStrPtr;      // Pointer to the original string
-
-  public:
-
-  // ----------------------------------------------
-  // Function: MultilineTextRenderer
-  // Purpose:  Constructor with initialization
-  // ----------------------------------------------
-  MultilineTextRenderer ( const wchar_t           *theStr,
-                          GLdouble                &theXdis,
-                          GLdouble                &theYdis,
-                          const OpenGl_TextParam  *theParam,
-                          const FTFont            *theFnt,
-                          GLint                   theWidthFont,
-                          GLint                   theAscentFont,
-                          GLint                   theDescentFont ) :
-
-      myLFNum         (0),
-      myCurrPos       (0),
-      myNewStrLen     (0),
-      mySubstrNum     (0),
-      myNewStr        (0),
-      myStrPtr        (&theStr[0])
-  {
-    const Standard_Integer  aStrLen       = (Standard_Integer) wcslen(theStr); // Length of the original string
-    Standard_Integer        aNextCRChar   = 0;  // Character after '\r' (Carriage Return)        '\x00\x0D'
-    Standard_Integer        aHTNum        = 0;  // Number of       '\t' (Horizontal Tabulation)  '\x00\x09'
-    Standard_Integer        aDumpNum      = 0;  // Number of '\a', '\b', '\v' and '\f'
-    Standard_Integer        anAllSpaces   = 0;  // Number of spaces instead of all '\t' characters
-    Standard_Integer        aMaxSubstrLen = 0;  // Length of the largest substring in the new string
-
-    Standard_Integer        aTimeVar      = 0;
-
-    // Calculation index after last '\r' character
-    for ( Standard_Integer anIndex = 0; anIndex < aStrLen; ++anIndex )
-    {
-      if ( theStr[anIndex] == '\r' )  aNextCRChar = anIndex+1;
-    }
-
-    // Calculation numbers of the some control characters
-    for (Standard_Integer anIndex = aNextCRChar; anIndex < aStrLen; anIndex++)
-    {
-      ++aTimeVar;
-      switch ( theStr[anIndex] )
-      {
-      case '\n':
-        ++myLFNum;
-        aTimeVar = 0;
-        break;
-      case '\b':
-      case '\v':
-      case '\f':
-      case '\a':
-        ++aDumpNum;
-        --aTimeVar;
-        break;
-      case '\t':
-        ++aHTNum;
-        anAllSpaces += ( 8 - ( aTimeVar - 1 )%8 );
-        aTimeVar = 0;
-        break;
-      }
-    }
-
-    // Calculation length of the new string
-    myStrPtr += aNextCRChar;
-    myNewStrLen = aStrLen - aNextCRChar + anAllSpaces - aHTNum - aDumpNum;
-
-    myNewStr = new wchar_t[myNewStrLen + 1];
-    myNewStr[myNewStrLen]='\0';
-
-    CalcString (aStrLen, aMaxSubstrLen);
-    CalcHAlign (theXdis, theParam, theWidthFont, aStrLen, aMaxSubstrLen);
-    CalcVAlign (theYdis, theParam, theFnt, theAscentFont, theDescentFont);
-  }
-
-  // ----------------------------------------------
-  // Function: ~MultilineTextRenderer
-  // Purpose:  Default destructor
-  // ----------------------------------------------
-  ~MultilineTextRenderer ()
-  {
-    delete[] myNewStr;
-  }
-
-  // ----------------------------------------------
-  // Function: Next
-  // Purpose:  Calculate position of the next substring
-  // ----------------------------------------------
-  void Next ()
-  {
-    for ( Standard_Integer anIndex = 0; anIndex <= myNewStrLen; ++anIndex )
-    {
-      if ( myNewStr[myCurrPos + anIndex] == '\0' )
-      {
-        ++mySubstrNum;
-        myCurrPos += anIndex + 1;
-        break;
-      }
-    }
-  }
-
-  // ----------------------------------------------
-  // Function: More
-  // Purpose:  Calculate position of the next substring
-  // ----------------------------------------------
-  Standard_Boolean More ()
-  {
-    if ( mySubstrNum <= myLFNum )  return Standard_True;
-    else                           return Standard_False;
-  }
-
-  // ----------------------------------------------
-  // Function: GetValue
-  // Purpose:  Returns current substring
-  // ----------------------------------------------
-  wchar_t* GetValue ()
-  {
-    return ( myNewStr + myCurrPos );
-  }
-
-  private:
-
-  // ----------------------------------------------
-  // Function: CalcString
-  // Purpose:  Calculate new string separated by '\0' without '\n', '\t', '\b', '\v', '\f', '\a'
-  // ----------------------------------------------
-  void CalcString ( const Standard_Integer theStrLen, Standard_Integer &theMaxSubstrLen )
-  {
-    Standard_Integer
-        aHelpIndex  = 0,
-        aTimeVar    = 0,
-        aSpacesNum  = 0;
-
-    for ( Standard_Integer anIndex1 = 0, anIndex2 = 0;
-          (anIndex1 < theStrLen)&&(anIndex2 < myNewStrLen);
-          ++anIndex1, ++anIndex2 )
-    {
-      ++aTimeVar;
-
-      if ( *(myStrPtr + anIndex1) == '\n' ) aTimeVar = 0;
-
-      while ( (*(myStrPtr + anIndex1)=='\b')||(*(myStrPtr + anIndex1)=='\f')
-            ||(*(myStrPtr + anIndex1)=='\v')||(*(myStrPtr + anIndex1)=='\a') )
-      {
-        ++anIndex1;
-      }
-
-      if ( *(myStrPtr + anIndex1) == '\t' )
-      {
-        aSpacesNum = ( 8 - ( aTimeVar - 1 )%8 );
-
-        for ( aHelpIndex = 0; aHelpIndex < aSpacesNum; aHelpIndex++ )
-        {
-          myNewStr[anIndex2 + aHelpIndex] = ' ';
-        }
-        anIndex2 += aHelpIndex - 1;
-        aTimeVar = 0;
-      }
-      else
-      {
-        myNewStr[anIndex2] = *(myStrPtr + anIndex1);
-      }
-    }
-
-    // After this part of code we will have a string separated by '\0' characters
-    Standard_Integer aHelpLength = 0;
-
-    if( myNewStr )
-    {
-      for( Standard_Integer anIndex = 0; anIndex <= myNewStrLen; ++anIndex )
-      {
-        if ( myNewStr[anIndex] == '\n' )
-        {
-          myNewStr[anIndex] = '\0';
-        }
-
-        // Calculating length of the largest substring of the new string.
-        // It's needed for horizontal alignment
-        if ( myNewStr[anIndex] != '\0' )
-        {
-          ++aHelpLength;
-        }
-        else
-        {
-          if ( aHelpLength > theMaxSubstrLen ) theMaxSubstrLen = aHelpLength;
-
-          aHelpLength = 0;
-        }
-      }
-    }
-  }
-
-  // ----------------------------------------------
-  // Function: CalcVAlign
-  // Purpose:  Calculate vertical alignment for text
-  // ----------------------------------------------
-  void CalcVAlign ( GLdouble                &theYdis,
-                    const OpenGl_TextParam  *theParam,
-                    const FTFont            *theFnt,
-                    GLint                   theAscentFont,
-                    GLint                   theDescentFont )
-  {
-    switch (theParam->VAlign)
-    {
-    case Graphic3d_VTA_BOTTOM:
-      theYdis = (GLdouble)(myLFNum * theFnt->FaceSize());
-      break;
-    case Graphic3d_VTA_CENTER:
-      if ( (myLFNum%2) == 0 )   // An odd number of strings
-      {
-        theYdis = (GLdouble)((myLFNum/2.0) * theFnt->FaceSize()) + theDescentFont;
-      }
-      else                      // An even number of strings
-      {
-        theYdis = (GLdouble)((myLFNum - 1)/2.0 * theFnt->FaceSize()) - theDescentFont/2.0;
-      }
-      break;
-    case Graphic3d_VTA_TOP:
-      theYdis = -(GLdouble)theAscentFont - theDescentFont;
-      break;
-    default:
-      theYdis = (GLdouble)(myLFNum * theFnt->FaceSize());
-      break;
-    }
-  }
-
-  // ----------------------------------------------
-  // Function: CalcHAlign
-  // Purpose:  Calculate horizontal alignment for text
-  // ----------------------------------------------
-  void CalcHAlign ( GLdouble                &theXdis,
-                    const OpenGl_TextParam  *theParam,
-                    GLint                   theWidthFont,
-                    const Standard_Integer  theStrLen,
-                    Standard_Integer        theMaxSubstrLen)
-  {
-    GLdouble aWidth = (GLdouble)(theMaxSubstrLen * theWidthFont)/theStrLen;
-
-    switch (theParam->HAlign)
-    {
-    case Graphic3d_HTA_LEFT:
-      theXdis = 0.;
-      break;
-    case Graphic3d_HTA_CENTER:
-      theXdis = -0.5 * (GLdouble)aWidth;
-      break;
-    case Graphic3d_HTA_RIGHT:
-      theXdis = -(GLdouble)aWidth;
-      break;
-    default:
-      theXdis = 0.;
-      break;
-    }
-  }
-};
-
-/*-----------------------------------------------------------------------------*/
-
-void OpenGl_Display::RenderText (const wchar_t* str, const int is2d, const float x, const float y, const float z,
-                                const OpenGl_AspectText *aspect, const OpenGl_TextParam *param)
-{
-  OpenGl_FontMgr* mgr = OpenGl_FontMgr::instance();
-  const FTFont* fnt = mgr->fontById( myFont );
-  if ( !fnt )
-    return;
-
-  // FTFont changes texture state when it renders and computes size for the text
-  glPushAttrib(GL_TEXTURE_BIT);
-
-  int widthFont, ascentFont, descentFont;
-  StringSize( str, widthFont, ascentFont, descentFont );
-
-  GLdouble xdis = 0., ydis = 0.;
-
-  float export_h = 1.;
-
-  MultilineTextRenderer aRenderer( str,
-                                   xdis,
-                                   ydis,
-                                   param,
-                                   fnt,
-                                   widthFont,
-                                   ascentFont,
-                                   descentFont );
-
-  glMatrixMode(GL_MODELVIEW);
-  glPushMatrix();
-  if (is2d)
-  {
-    glLoadIdentity();
-    glTranslatef(x, y, 0.f);
-    glRotatef( 180, 1, 0, 0 );
-  }
-  else
-  {
-    const GLdouble identityMatrix[4][4] =
-    {
-      {1.,0.,0.,0.},
-      {0.,1.,0.,0.},
-      {0.,0.,1.,0.},
-      {0.,0.,0.,1.}
-    };
-
-    GLdouble projMatrix[4][4], modelMatrix[4][4];
-    GLint viewport[4];
-
-    GLdouble wx, wy, wz;
-    GLdouble x1, y1, z1;
-    GLdouble x2, y2, z2;
-
-    glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble*)modelMatrix );
-    glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble*)projMatrix );
-    glGetIntegerv( GL_VIEWPORT, (GLint*)viewport );
-
-    gluProject( x, y, z,
-      (GLdouble*)modelMatrix,
-      (GLdouble*)projMatrix,
-      (GLint*)viewport,
-      &wx, &wy, &wz );
-
-    gluUnProject( wx, wy, wz,
-      (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
-      &x1, &y1 , &z1 );
-
-    GLdouble h = (GLdouble)fnt->FaceSize();
-
-    gluUnProject( wx, wy + h - 1., wz,
-      (GLdouble*)identityMatrix, (GLdouble*)projMatrix, (GLint*)viewport,
-      &x2, &y2, &z2 );
-
-    h = (y2-y1)/h;
-
-    glLoadIdentity();
-    glTranslated (x1, y1 , z1);
-    glRotated (aspect->Angle(), 0, 0, 1);
-
-    if( !aspect->IsZoomable() )
-    {
-#ifdef WNT
-      // if the context has assigned printer context, use it's parameters
-      OpenGl_PrinterContext* aPrinterContext =
-        OpenGl_PrinterContext::GetPrinterContext( GET_GL_CONTEXT() );
-      if( aPrinterContext )
-      {
-        // get printing scaling in x and y dimensions
-        GLfloat aTextScalex = 1, aTextScaley = 1;
-        aPrinterContext->GetScale( aTextScalex, aTextScaley );
-
-        // text should be scaled in all directions with same
-        // factor to save its proportions, so use height (y) scaling
-        // as it is better for keeping text/3d graphics proportions
-        glScalef( aTextScaley, aTextScaley, aTextScaley );
-      }
-#endif
-      glScaled( h, h, h );
-    }
-    else
-    {
-      export_h = (float)h;
-    }
-
-    glTranslated (xdis, ydis, 0);
-  }
-
-  GLint renderMode;
-  glGetIntegerv(GL_RENDER_MODE, &renderMode);
-  if ( renderMode == GL_FEEDBACK )
-  {
-#ifdef HAVE_GL2PS
-    export_h = (float)fnt->FaceSize() / export_h;
-    for ( ; aRenderer.More(); aRenderer.Next() )
-    {
-      // x, y, z coordinates are used here as zero values, because position of the text
-      // and alignment is calculated in the code above using glTranslated methods
-      ExportText( aRenderer.GetValue(), is2d, 0, 0, 0, aspect, param, (short)export_h );
-      glTranslated(0, -(GLdouble)fnt->FaceSize(), 0);
-    }
-#endif
-  }
-  else
-  {
-    for ( ; aRenderer.More(); aRenderer.Next() )
-    {
-      mgr->render_text( myFont, aRenderer.GetValue(), is2d );
-      glTranslated(0, -(GLdouble)fnt->FaceSize(), 0);
-    }
-  }
-  glPopMatrix();
-  glPopAttrib();
-}
-
-/*-----------------------------------------------------------------------------*/
-
-void OpenGl_Display::ExportText (const wchar_t* text, const int is2d, const float x, const float y, const float z,
-                                const OpenGl_AspectText *aspect, const OpenGl_TextParam *param, const short height)
-{
-#ifdef HAVE_GL2PS
-
-  const char* fontname = aspect->Font();
-  float angle = aspect->Angle();
-
-  GLubyte zero = 0;
-  char ps_font[64];
-
-  getGL2PSFontName(fontname, ps_font);
-
-  if( is2d )
-    glRasterPos2f( x, y );
-  else
-    glRasterPos3f( x, y, z );
-
-  glBitmap( 1, 1, 0, 0, 0, 0, &zero );
-
-  //szv: workaround for gl2ps!
-  const int len = 4 * (wcslen(text) + 1); //szv: should be more than enough
-  char *astr = new char[len];
-  wcstombs(astr,text,len);
-
-  // Standard GL2PS's alignment isn't used, because it doesn't work correctly
-  // for all formats, therefore alignment is calculated manually relative
-  // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
-  gl2psTextOpt(astr, ps_font, height, GL2PS_TEXT_BL, angle);
-  delete[] astr;
-
-#endif
-}
similarity index 61%
copy from src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx
copy to src/OpenGl/OpenGl_Element.cxx
index c5b9086..9b83eb3 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2011-09-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2013-02-01
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <OpenGl_Element.hxx>
 
-#ifndef _Handle_OpenGl_GraduatedTrihedron_Header
-#define _Handle_OpenGl_GraduatedTrihedron_Header
+// =======================================================================
+// function : OpenGl_Element
+// purpose  :
+// =======================================================================
+OpenGl_Element::OpenGl_Element()
+{
+  //
+}
 
-#include <Standard_DefineHandle.hxx>
-#include <Handle_MMgt_TShared.hxx>
-
-class OpenGl_GraduatedTrihedron;
-
-// Handle definition
-//
-DEFINE_STANDARD_HANDLE(OpenGl_GraduatedTrihedron,MMgt_TShared)
-
-
-#endif //_Handle_OpenGl_GraduatedTrihedron_Header
+// =======================================================================
+// function : ~OpenGl_Element
+// purpose  :
+// =======================================================================
+OpenGl_Element::~OpenGl_Element()
+{
+  //
+}
index ba81189..b900f28 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef OpenGl_Element_Header
 #define OpenGl_Element_Header
 
 #include <Handle_OpenGl_Context.hxx>
 #include <Handle_OpenGl_Workspace.hxx>
 
+//! Base interface for drawable elements.
 class OpenGl_Element
 {
 public:
 
-  OpenGl_Element() {}
+  Standard_EXPORT OpenGl_Element();
 
   virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const = 0;
 
@@ -52,7 +52,7 @@ public:
 
 protected:
 
-  virtual ~OpenGl_Element() {}
+  Standard_EXPORT virtual ~OpenGl_Element();
 
 public:
 
@@ -60,4 +60,4 @@ public:
 
 };
 
-#endif //OpenGl_Element_Header
+#endif // OpenGl_Element_Header
diff --git a/src/OpenGl/OpenGl_Font.cxx b/src/OpenGl/OpenGl_Font.cxx
new file mode 100644 (file)
index 0000000..3f1736c
--- /dev/null
@@ -0,0 +1,227 @@
+// Created on: 2013-01-29
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OpenGl_Font.hxx>
+
+#include <OpenGl_Context.hxx>
+#include <Standard_Assert.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_Font, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Font, OpenGl_Resource)
+
+// =======================================================================
+// function : OpenGl_Font
+// purpose  :
+// =======================================================================
+OpenGl_Font::OpenGl_Font (const Handle(Font_FTFont)&     theFont,
+                          const TCollection_AsciiString& theKey)
+: myKey  (theKey),
+  myFont (theFont),
+  myAscender (0.0f),
+  myDescender (0.0f),
+  myLineSpacing (0.0f),
+  myTileSizeX (0),
+  myTileSizeY (0),
+  myLastTileId (-1),
+  myTextureFormat (GL_ALPHA8)
+{
+  memset (&myLastTilePx, 0, sizeof(myLastTilePx));
+}
+
+// =======================================================================
+// function : ~OpenGl_Font
+// purpose  :
+// =======================================================================
+OpenGl_Font::~OpenGl_Font()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_Font::Release (const OpenGl_Context* theCtx)
+{
+  if (myTextures.IsEmpty())
+  {
+    return;
+  }
+
+  // application can not handle this case by exception - this is bug in code
+  Standard_ASSERT_RETURN (theCtx != NULL,
+    "OpenGl_Font destroyed without GL context! Possible GPU memory leakage...",);
+
+  for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
+  {
+    Handle(OpenGl_Texture)& aTexture = myTextures.ChangeValue (anIter);
+    aTexture->Release (theCtx);
+    aTexture.Nullify();
+  }
+  myTextures.Clear();
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+bool OpenGl_Font::Init (const Handle(OpenGl_Context)& theCtx)
+{
+  Release (theCtx.operator->());
+  if (myFont.IsNull() || !myFont->IsValid())
+  {
+    return false;
+  }
+
+  myAscender    = myFont->Ascender();
+  myDescender   = myFont->Descender();
+  myLineSpacing = myFont->LineSpacing();
+  myTileSizeX   = myFont->GlyphMaxSizeX();
+  myTileSizeY   = myFont->GlyphMaxSizeY();
+
+  myLastTileId = -1;
+  return createTexture (theCtx);
+}
+
+// =======================================================================
+// function : createTexture
+// purpose  :
+// =======================================================================
+bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
+{
+  const Standard_Integer aMaxSize = theCtx->MaxTextureSize();
+
+  Standard_Integer aGlyphsNb = myFont->GlyphsNumber() - myLastTileId + 1;
+
+  const Standard_Integer aTextureSizeX = OpenGl_Context::GetPowerOfTwo (aGlyphsNb * myTileSizeX, aMaxSize);
+  const Standard_Integer aTilesPerRow  = aTextureSizeX / myTileSizeX;
+  const Standard_Integer aTextureSizeY = OpenGl_Context::GetPowerOfTwo (GLint((aGlyphsNb / aTilesPerRow) + 1) * myTileSizeY, aMaxSize);
+
+  memset (&myLastTilePx, 0, sizeof(myLastTilePx));
+  myLastTilePx.Bottom = myTileSizeY;
+
+  myTextures.Append (new OpenGl_Texture());
+  Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
+
+  Image_PixMap aBlackImg;
+  if (!aBlackImg.InitZero (Image_PixMap::ImgGray, Standard_Size(aTextureSizeX), Standard_Size(aTextureSizeY))
+   || !aTexture->Init (theCtx, aBlackImg, Graphic3d_TOT_2D)) // myTextureFormat
+  {
+    return false;
+  }
+
+  aTexture->Bind (theCtx);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+  glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+  aTexture->Unbind (theCtx);
+  return true;
+}
+
+// =======================================================================
+// function : renderGlyph
+// purpose  :
+// =======================================================================
+bool OpenGl_Font::renderGlyph (const Handle(OpenGl_Context)& theCtx,
+                               const Standard_Utf32Char      theChar)
+{
+  if (!myFont->RenderGlyph (theChar))
+  {
+    return false;
+  }
+
+  Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
+
+  const Image_PixMap& anImg = myFont->GlyphImage();
+  const Standard_Integer aTileId = myLastTileId + 1;
+  myLastTilePx.Left  = myLastTilePx.Right + 3;
+  myLastTilePx.Right = myLastTilePx.Left + (Standard_Integer )anImg.SizeX();
+  if (myLastTilePx.Right >= aTexture->SizeX())
+  {
+    myLastTilePx.Left    = 0;
+    myLastTilePx.Right   = (Standard_Integer )anImg.SizeX();
+    myLastTilePx.Top    += myTileSizeY;
+    myLastTilePx.Bottom += myTileSizeY;
+
+    if (myLastTilePx.Bottom >= aTexture->SizeY())
+    {
+      if (!createTexture (theCtx))
+      {
+        return false;
+      }
+      return renderGlyph (theCtx, theChar);
+    }
+  }
+
+  aTexture->Bind (theCtx);
+  glPixelStorei (GL_UNPACK_LSB_FIRST,  GL_FALSE);
+  glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+  glPixelStorei (GL_UNPACK_ALIGNMENT,  1);
+
+  glTexSubImage2D (GL_TEXTURE_2D, 0,
+                   myLastTilePx.Left, myLastTilePx.Top, (GLsizei )anImg.SizeX(), (GLsizei )anImg.SizeY(),
+                   GL_ALPHA, GL_UNSIGNED_BYTE, anImg.Data());
+
+  OpenGl_Font::Tile aTile;
+  aTile.uv.Left   = GLfloat(myLastTilePx.Left)                / GLfloat(aTexture->SizeX());
+  aTile.uv.Right  = GLfloat(myLastTilePx.Right)               / GLfloat(aTexture->SizeX());
+  aTile.uv.Top    = GLfloat(myLastTilePx.Top)                 / GLfloat(aTexture->SizeY());
+  aTile.uv.Bottom = GLfloat(myLastTilePx.Top + anImg.SizeY()) / GLfloat(aTexture->SizeY());
+  aTile.texture   = aTexture->TextureId();
+  myFont->GlyphRect (aTile.px);
+
+  myLastTileId = aTileId;
+  myTiles.Append (aTile);
+  return true;
+}
+
+// =======================================================================
+// function : RenderGlyph
+// purpose  :
+// =======================================================================
+void OpenGl_Font::RenderGlyph (const Handle(OpenGl_Context)& theCtx,
+                               const Standard_Utf32Char      theUChar,
+                               const Standard_Utf32Char      theUCharNext,
+                               OpenGl_Font::Tile&            theGlyph,
+                               OpenGl_Vec2&                  thePen)
+{
+  Standard_Integer aTileId = 0;
+  if (!myGlyphMap.Find (theUChar, aTileId))
+  {
+    if (renderGlyph (theCtx, theUChar))
+    {
+      aTileId = myLastTileId;
+    }
+    else
+    {
+      thePen.x() += myFont->AdvanceX (theUChar, theUCharNext);
+      return;
+    }
+    myGlyphMap.Bind (theUChar, aTileId);
+  }
+
+  const OpenGl_Font::Tile& aTile = myTiles.Value (aTileId);
+  theGlyph.px.Top    = thePen.y() + aTile.px.Top;
+  theGlyph.px.Bottom = thePen.y() + aTile.px.Bottom;
+  theGlyph.px.Left   = thePen.x() + aTile.px.Left;
+  theGlyph.px.Right  = thePen.x() + aTile.px.Right;
+  theGlyph.uv        = aTile.uv;
+  theGlyph.texture   = aTile.texture;
+
+  thePen.x() += myFont->AdvanceX (theUChar, theUCharNext);
+}
diff --git a/src/OpenGl/OpenGl_Font.hxx b/src/OpenGl/OpenGl_Font.hxx
new file mode 100644 (file)
index 0000000..779806c
--- /dev/null
@@ -0,0 +1,170 @@
+// Created on: 2013-01-29
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_Font_H__
+#define _OpenGl_Font_H__
+
+#include <OpenGl_Texture.hxx>
+#include <OpenGl_Vec.hxx>
+
+#include <Font_FTFont.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Vector.hxx>
+#include <TCollection_AsciiString.hxx>
+
+//! Texture font.
+class OpenGl_Font : public OpenGl_Resource
+{
+
+public:
+
+  //! Simple structure stores tile rectangle.
+  struct Tile
+  {
+    Font_FTFont::Rect uv;      //!< UV coordinates in texture
+    Font_FTFont::Rect px;      //!< pixel displacement coordinates
+    GLuint            texture; //!< GL texture ID
+  };
+
+  struct RectI
+  {
+    Standard_Integer Left;
+    Standard_Integer Right;
+    Standard_Integer Top;
+    Standard_Integer Bottom;
+  };
+
+public:
+
+  //! Main constructor.
+  Standard_EXPORT OpenGl_Font (const Handle(Font_FTFont)&     theFont,
+                               const TCollection_AsciiString& theKey = "");
+
+  //! Destroy object.
+  Standard_EXPORT virtual ~OpenGl_Font();
+
+  //! Destroy object - will release GPU memory if any
+  Standard_EXPORT virtual void Release (const OpenGl_Context* theCtx);
+
+  //! @return key of shared resource
+  inline const TCollection_AsciiString& ResourceKey() const
+  {
+    return myKey;
+  }
+
+  //! @return FreeType font instance specified on construction.
+  inline const Handle(Font_FTFont)& FTFont() const
+  {
+    return myFont;
+  }
+
+  //! @return true if font was loaded successfully.
+  inline bool IsValid() const
+  {
+    return !myTextures.IsEmpty() && myTextures.First()->IsValid();
+  }
+
+  //! Notice that this method doesn't return initialization success state.
+  //! Use IsValid() instead.
+  //! @return true if initialization was already called.
+  inline bool WasInitialized() const
+  {
+    return !myTextures.IsEmpty();
+  }
+
+  //! Initialize GL resources.
+  //! FreeType font instance should be already initialized!
+  Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theCtx);
+
+  //! Compute advance to the next character with kerning applied when applicable.
+  //! Assuming text rendered horizontally.
+  inline float AdvanceX (const Standard_Utf32Char theUChar,
+                         const Standard_Utf32Char theUCharNext)
+  {
+    return myFont->AdvanceX (theUChar, theUCharNext);
+  }
+
+  //! @return vertical distance from the horizontal baseline to the highest character coordinate
+  inline float Ascender() const
+  {
+    return myAscender;
+  }
+
+  //! @return vertical distance from the horizontal baseline to the lowest character coordinate
+  inline float Descender() const
+  {
+    return myDescender;
+  }
+
+  //! @return default line spacing (the baseline-to-baseline distance)
+  inline float LineSpacing() const
+  {
+    return myLineSpacing;
+  }
+
+  //! Compute glyph rectangle at specified pen position (on baseline)
+  //! and render it to texture if not already.
+  //! @param theCtx       active context
+  //! @param theUChar     unicode symbol to render
+  //! @param theUCharNext next symbol to compute advance with kerning when available
+  //! @param theGlyph     computed glyph position rectangle, texture ID and UV coordinates
+  //! @param thePen       pen position on baseline to place new glyph
+  Standard_EXPORT void RenderGlyph (const Handle(OpenGl_Context)& theCtx,
+                                    const Standard_Utf32Char      theUChar,
+                                    const Standard_Utf32Char      theUCharNext,
+                                    Tile&                         theGlyph,
+                                    OpenGl_Vec2&                  thePen);
+
+protected:
+
+  //! Render new glyph to the texture.
+  bool renderGlyph (const Handle(OpenGl_Context)& theCtx,
+                    const Standard_Utf32Char      theChar);
+
+  //! Allocate new texture.
+  bool createTexture (const Handle(OpenGl_Context)& theCtx);
+
+protected:
+
+  TCollection_AsciiString myKey;           //!< key of shared resource
+  Handle(Font_FTFont)     myFont;          //!< FreeType font instance
+  Standard_ShortReal      myAscender;      //!< ascender     provided my FT font
+  Standard_ShortReal      myDescender;     //!< descender    provided my FT font
+  Standard_ShortReal      myLineSpacing;   //!< line spacing provided my FT font
+  Standard_Integer        myTileSizeX;     //!< tile width
+  Standard_Integer        myTileSizeY;     //!< tile height
+  Standard_Integer        myLastTileId;    //!< id of last tile
+  RectI                   myLastTilePx;
+  Standard_Integer        myTextureFormat; //!< texture format
+
+  NCollection_Vector<Handle(OpenGl_Texture)> myTextures; //!< array of textures
+  NCollection_Vector<Tile>                   myTiles;    //!< array of loaded tiles
+
+  NCollection_DataMap<Standard_Utf32Char, Standard_Integer> myGlyphMap;
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_Font) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(OpenGl_Font, OpenGl_Resource)
+
+#endif // _OpenGl_Font_H__
diff --git a/src/OpenGl/OpenGl_FontMgr.cxx b/src/OpenGl/OpenGl_FontMgr.cxx
deleted file mode 100755 (executable)
index 596355a..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-#include <OpenGl_FontMgr.hxx>
-#include <OpenGl_GlCore11.hxx>
-
-#include <Standard_Stream.hxx>
-#include <TColStd_SequenceOfHAsciiString.hxx>
-
-#ifdef _MSC_VER
-#pragma comment( lib, "ftgl.lib" )
-#endif
-
-#undef TRACE
-
-#define DEFAULT_FONT_HEIGHT 16
-
-float h_scale = 0;
-
-void dump_texture( int id);
-
-OpenGl_FontMgr::OpenGl_FontMgr()
-: myCurrentFontId(-1),
-myXCurrentScale(1.f),
-myYCurrentScale(1.f) 
-{
-}
-
-OpenGl_FontMgr* OpenGl_FontMgr::instance() 
-{
-  static OpenGl_FontMgr* _mgr = NULL;
-  if ( _mgr == NULL )
-  {
-    _mgr = new OpenGl_FontMgr();
-  }
-  return _mgr;
-}
-
-// Empty fontName means that ANY family name can be used.
-// fontAspect == Font_FA_Undefined means ANY font aspect is acceptable.
-// fontheight == -1 means ANY font height is acceptable.
-int OpenGl_FontMgr::request_font (const Handle(TCollection_HAsciiString)& theFontName,
-                                  const Font_FontAspect                   theFontAspect,
-                                  const Standard_Integer&                 theFontHeight)
-{
-  Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
-  Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName, theFontAspect, theFontHeight);
-
-  if (aRequestedFont.IsNull())
-  {
-    return -1;
-  }
-
-  // Setting font height
-  Standard_Integer aFontHeight = theFontHeight;
-  if (theFontHeight < 2 && aRequestedFont->FontHeight() == -1)
-  {
-    // Font height is not specified -> use DEFAULT_FONT_HEIGHT for variable-height fonts
-    aFontHeight = DEFAULT_FONT_HEIGHT;
-  }
-  else if (theFontHeight < 2)
-  {
-    // Font height is not specified -> use font height for fixed size fonts
-    aFontHeight = aRequestedFont->FontHeight();
-  }
-
-  GLCONTEXT aContext = GET_GL_CONTEXT();
-
-  // Check in already generated fonts.
-  if (myGeneratedFontDB.IsBound (aRequestedFont))
-  {
-    const IDList& anIDList = myGeneratedFontDB.Find (aRequestedFont);
-    for (IDList::Iterator anIDListIterator (anIDList); anIDListIterator.More();
-         anIDListIterator.Next())
-    {
-      OGLFont_Cache aFontCache = myGeneratedFontCache (anIDListIterator.Value());
-      if (aFontCache.FontHeight == aFontHeight && aFontCache.GlContext == aContext)
-      {
-        // Requested font is already generated, returning it cache ID.
-        myCurrentFontId = anIDListIterator.Value();
-        return myCurrentFontId;
-      }
-    }
-  }
-
-  // Cache for requested font is not found. Generating new FTGL font.
-  FTGLTextureFont* aFTGLFont = new FTGLTextureFont(aRequestedFont->FontPath()->ToCString());
-  if ( !aFTGLFont || aFTGLFont->Error() != FT_Err_Ok)
-  {
-    return -1; // Error during creation FTGL font object!
-  }
-
-  if ( !aFTGLFont->FaceSize (aFontHeight) || aFTGLFont->Error() != FT_Err_Ok )
-  {
-    return -1; // Error during setup FTGL font height!
-  }
-
-  aFTGLFont->UseDisplayList (false);
-
-  // Adding font to cache.
-  OGLFont_Cache aCache;
-  aCache.Font = aFTGLFont;
-  aCache.FontHeight = aFontHeight;
-  aCache.GlContext = aContext;
-
-  myCurrentFontId = myGeneratedFontCache.Size() + 1;
-  myGeneratedFontCache.Bind ( myCurrentFontId, aCache);
-
-  if (myGeneratedFontDB.IsBound (aRequestedFont))
-  {
-    myGeneratedFontDB.ChangeFind (aRequestedFont).Append (myCurrentFontId);
-  }
-  else
-  {
-    IDList anIDList;
-    anIDList.Append (myCurrentFontId);
-    myGeneratedFontDB.Bind (aRequestedFont, anIDList);
-  }
-
-  return myCurrentFontId;
-}
-
-void OpenGl_FontMgr::render_text( const Standard_Integer id, const wchar_t* text,
-                                  const Standard_Boolean is2d )
-{
-#ifdef TRACE
-  cout << "TKOpenGl::render_text\n"
-    << "\tfont id = " << id << endl
-    << "\ttext = " << text << endl;
-#endif
-  if ( text && myGeneratedFontCache.IsBound( id ) ) {
-    glMatrixMode( GL_MODELVIEW );
-    glPushMatrix();
-
-    glScalef( myXCurrentScale, myYCurrentScale, 1 );
-    glPushAttrib( GL_ENABLE_BIT );
-
-    GLboolean enableTexture = glIsEnabled(GL_TEXTURE_2D);
-    GLboolean enableDepthTest = glIsEnabled(GL_DEPTH_TEST);
-
-    if( !enableTexture )
-      glEnable(GL_TEXTURE_2D);
-    if ( !is2d ) {
-      if ( !enableDepthTest )
-        glEnable(GL_DEPTH_TEST);
-    }
-    else if ( enableDepthTest ) {
-        glDisable(GL_DEPTH_TEST);
-    }
-
-    GLint param;
-    glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &param);
-
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
-    glAlphaFunc(GL_GEQUAL, 0.285f);    
-    glEnable(GL_ALPHA_TEST);   
-    OGLFont_Cache cache = myGeneratedFontCache.Find( id );
-    cache.Font->Render( text );
-
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param);
-
-    if( !enableTexture )
-      glDisable(GL_TEXTURE_2D);
-    if( !enableDepthTest )
-      glDisable(GL_DEPTH_TEST);
-
-    glPopAttrib();
-    glMatrixMode( GL_MODELVIEW );
-    glPopMatrix();
-  }
-
-}
-
-void OpenGl_FontMgr::render_text ( const wchar_t* text, const Standard_Boolean is2d )
-{
-  render_text( myCurrentFontId, text, is2d );
-}
-
-const FTFont* OpenGl_FontMgr::fontById (const Standard_Integer id)
-{
-  return myGeneratedFontCache.IsBound( id ) ? myGeneratedFontCache.Find( id ).Font: NULL;
-}
-
-Standard_ShortReal OpenGl_FontMgr::computeWidth( const Standard_Integer id, const wchar_t* text )
-{
-  if( !myGeneratedFontCache.IsBound( id ) )
-    return 0.f;
-
-  OGLFont_Cache cache = myGeneratedFontCache.Find( id );
-
-  Standard_ShortReal w = cache.Font->Advance( text );
-
-  return w;
-}
-
-void OpenGl_FontMgr::setCurrentScale (const Standard_ShortReal xScale,
-                                      const Standard_ShortReal yScale)
-{
-  myXCurrentScale = xScale;
-  myYCurrentScale = yScale;
-}
-
-#include <AlienImage_BMPAlienData.hxx>
-#include <OSD_File.hxx>
-#include <OSD_Protection.hxx>
-#include <Aspect_GenericColorMap.hxx>
-#include <Image_ColorImage.hxx>
-#include <Quantity_Color.hxx>
-
-void dump_texture( int id)
-{
-  Handle(AlienImage_BMPAlienData) image = new AlienImage_BMPAlienData();
-
-  if (!glIsTexture(id))
-    return;
-
-  unsigned char* pixels = new unsigned char[8192*1024];
-  memset( pixels, 0, 8192*1024 );
-  static int index = 0;
-  index++;
-
-  glBindTexture(GL_TEXTURE_2D, id );
-  glGetTexImage( GL_TEXTURE_2D , 
-    0,
-    GL_ALPHA,
-    GL_UNSIGNED_BYTE,
-    pixels );
-
-  Handle(Image_ColorImage) anImage = new Image_ColorImage( 0, 0, 1024, 8192 );
-
-  Aspect_ColorPixel mark( Quantity_Color (0.,0.5,1., Quantity_TOC_RGB ) ),
-    space( Quantity_Color (1.,1.,1., Quantity_TOC_RGB ) );
-
-  for( int i = 0; i < 1024; i++ ) {
-    for (int j = 0; j < 8192; j++ )
-      if (pixels[i*8192+j]>0) {
-        anImage->SetPixel( anImage->LowerX()+i, 
-          anImage->LowerY()+j,
-          mark );
-      }
-      else {
-        anImage->SetPixel( anImage->LowerX()+i, 
-          anImage->LowerY()+j,
-          space );
-      }
-  }
-
-  image->FromImage( anImage );
-  TCollection_AsciiString name( index );
-  name.Prepend( "D:\\Temp_image" );
-  name += ".bmp";
-  OSD_File file ( name );
-  file.Build( OSD_WriteOnly, OSD_Protection());
-  image->Write(file);
-  file.Close();
-  delete []pixels;
-}
diff --git a/src/OpenGl/OpenGl_FontMgr.hxx b/src/OpenGl/OpenGl_FontMgr.hxx
deleted file mode 100755 (executable)
index de20a17..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-#ifndef OPENGL_FONT_MGR_H
-#define OPENGL_FONT_MGR_H
-
-#ifdef WNT
-# include <windows.h>
-# include <stdlib.h>
-#endif
-
-#ifdef HAVE_FTGL_UPPERCASE
-#include <FTGLTextureFont.h>
-#else
-#include <FTGL/ftgl.h>
-#endif
-
-#include <InterfaceGraphic.hxx>
-#include <TCollection_HAsciiString.hxx>
-#include <NCollection_List.hxx>
-#include <NCollection_DataMap.hxx>
-#include <Graphic3d_NListOfHAsciiString.hxx>
-#include <Font_FontMgr.hxx>
-
-void dump_texture();
-
-class OpenGl_FontMgr
-{
- public:
-  static OpenGl_FontMgr*  instance();
-
-  int request_font (const Handle(TCollection_HAsciiString)& theFontName,
-                    const Font_FontAspect                   theFontAspect,
-                    const Standard_Integer&                 theFontHeight);
-
-  void render_text( const Standard_Integer id,
-    const wchar_t* text,
-    const Standard_Boolean is2d = Standard_False );
-
-  //render text by last requested font
-  void render_text( const wchar_t* text,
-    const Standard_Boolean is2d = Standard_False );
-
-  //returns direct access to FTGL font
-  //Warning: don't change font pointer.
-  const FTFont*   fontById( const Standard_Integer id );
-
-  //returns width of string
-  Standard_ShortReal computeWidth( const Standard_Integer id, const wchar_t *str );
-
-  void setCurrentScale( const Standard_ShortReal xScale = 1.f,
-                        const Standard_ShortReal yScale = 1.f);
-
-private:
-  OpenGl_FontMgr();
-  OpenGl_FontMgr( const OpenGl_FontMgr& ){};
-  OpenGl_FontMgr& operator = ( const OpenGl_FontMgr&){ return *this;};
-  ~OpenGl_FontMgr(){};
-
-  void                          _initializeFontDB();
-
-  typedef NCollection_List<Standard_Integer> IDList;
-
-  struct OGLFont_Cache {
-    FTFont*            Font;
-    Standard_Integer   FontHeight;
-    GLCONTEXT          GlContext;
-  };
-
-  typedef NCollection_DataMap<Handle(Font_SystemFont), IDList> FontDataBase;
-  typedef FontDataBase::Iterator                               FontDBIterator;
-  typedef NCollection_DataMap<Standard_Integer, OGLFont_Cache> FontCache;
-  typedef FontCache::Iterator                                  FontCacheIterator;
-
-  FontDataBase            myGeneratedFontDB;
-  FontCache               myGeneratedFontCache;
-
-  Standard_Integer        myCurrentFontId;
-
-  Standard_ShortReal      myXCurrentScale,
-                          myYCurrentScale;
-};
-
-#endif //OPENGL_FONT_MGR_H
index e199386..1dd334d 100644 (file)
@@ -39,19 +39,6 @@ static inline bool isPowerOfTwo (const GLsizei theNumber)
        return !(theNumber & (theNumber - 1));
 }
 
-static inline GLsizei getPowerOfTwo (const GLsizei theNumber,
-                                     const GLsizei theThreshold)
-{
-  for (GLsizei p2 = 2; p2 <= theThreshold; p2 <<= 1)
-  {
-    if (theNumber <= p2)
-    {
-      return p2;
-    }
-  }
-  return theThreshold;
-}
-
 OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
 : mySizeX (0),
   mySizeY (0),
@@ -84,10 +71,8 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
   // upscale width/height if numbers are odd
   if (toForcePowerOfTwo)
   {
-    GLint aMaxTexDim = 2048;
-    glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aMaxTexDim);
-    mySizeX = getPowerOfTwo (theViewportSizeX, aMaxTexDim);
-    mySizeY = getPowerOfTwo (theViewportSizeY, aMaxTexDim);
+    mySizeX = OpenGl_Context::GetPowerOfTwo (theViewportSizeX, theGlContext->MaxTextureSize());
+    mySizeY = OpenGl_Context::GetPowerOfTwo (theViewportSizeY, theGlContext->MaxTextureSize());
   }
   else
   {
index 200f5f3..de72c8c 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-09-20
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #include <OpenGl_GlCore11.hxx>
 
 #include <stddef.h>
 #include <InterfaceGraphic_Visual3d.hxx>
 
 #ifdef HAVE_CONFIG_H
-#include <config.h>
+  #include <config.h>
 #endif
 #ifdef HAVE_STRING_H
-#include <string.h>
+  #include <string.h>
 #endif
 
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_GraduatedTrihedron.hxx>
 #include <OpenGl_AspectLine.hxx>
 
-IMPLEMENT_STANDARD_HANDLE(OpenGl_GraduatedTrihedron,MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraduatedTrihedron,MMgt_TShared)
-
 const OpenGl_AspectLine myDefaultAspectLine;
 
+static const OpenGl_TextParam THE_LABEL_PARAMS =
+{
+  16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
+};
+
 /* Bounding box */
 float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f, xmax = 100.0f, ymax = 100.0f, zmax = 100.0f;
 
@@ -133,28 +134,6 @@ static char getFarestCorner(float d000, float d100, float d010, float d001,
     return 8; /* d111 */
 }
 
-static void drawText(const Handle(OpenGl_Workspace) &AWorkspace, const wchar_t* text, const char* font, Font_FontAspect style, int size, float x, float y, float z)
-{
-  AWorkspace->FindFont(font, style, size);
-  AWorkspace->RenderText(text, 0, x, y, z);
-
-/* 4 OCC 6.3.1 and older:
-    GLuint fontBase;
-
-#ifndef WNT
-     fontBase = tXfmsetfont (1.0F, 1.0F);
-#else
-     fontBase = WNTSetFont (1.0F, 1.0F);
-#endif
-
-#ifndef WNT
-     tXfmprstr(text, fontBase, x, y, z);
-#else
-     WNTPuts(text, fontBase, 0, x, y, z);
-#endif
-*/
-}
-
 static void drawArrow(float x1, float y1, float z1,
                       float x2, float y2, float z2,
                       float xn, float yn, float zn)
@@ -210,121 +189,103 @@ static void drawArrow(float x1, float y1, float z1,
     glEnd();
 }
 
-OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron (const Graphic3d_CGraduatedTrihedron &AData)
-: myXName(NULL), myYName(NULL), myZName(NULL),
-  myDrawXName(AData.xdrawname), myDrawYName(AData.ydrawname), myDrawZName(AData.zdrawname),
-  myDrawXValues(AData.xdrawvalues), myDrawYValues(AData.ydrawvalues), myDrawZValues(AData.zdrawvalues),
-  myDrawGrid(AData.drawgrid), myDrawAxes(AData.drawaxes),
-  myNbX(AData.nbx), myNbY(AData.nby), myNbZ(AData.nbz),
-  myXOffset(AData.xoffset), myYOffset(AData.yoffset), myZOffset(AData.zoffset),
-  myXAxisOffset(AData.xaxisoffset), myYAxisOffset(AData.yaxisoffset), myZAxisOffset(AData.zaxisoffset),
-  myDrawXTickmarks(AData.xdrawtickmarks), myDrawYTickmarks(AData.ydrawtickmarks), myDrawZTickmarks(AData.zdrawtickmarks),
-  myXTickmarkLength(AData.xtickmarklength), myYTickmarkLength(AData.ytickmarklength), myZTickmarkLength(AData.ztickmarklength),
-  myFontOfNames(NULL),
-  myStyleOfNames(AData.styleOfNames),
-  mySizeOfNames(AData.sizeOfNames),
-  myFontOfValues(NULL),
-  myStyleOfValues(AData.styleOfValues),
-  mySizeOfValues(AData.sizeOfValues),
-  myCbCubicAxes(AData.cbCubicAxes),
-  myPtrVisual3dView(AData.ptrVisual3dView)
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_GraduatedTrihedron::Release (const Handle(OpenGl_Context)& theCtx)
 {
-  /* Names of axes */
-  /* X-name */
-  int len = AData.xname.Length();
-  if (len)
-  {
-    Standard_ExtString iname = AData.xname.ToExtString();
-    wchar_t *xname = new wchar_t[len+1];
-    len = 0; while (xname[len] = (wchar_t)(iname[len])) len++;
-    myXName = xname;
-  }
-  /* Y-name */
-  len = AData.yname.Length();
-  if (len)
-  {
-    Standard_ExtString iname = AData.yname.ToExtString();
-    wchar_t *yname = new wchar_t[len+1];
-    len = 0; while (yname[len] = (wchar_t)(iname[len])) len++;
-    myYName = yname;
-  }
-  /* Z-name */
-  len = AData.zname.Length();
-  if (len)
-  {
-    Standard_ExtString iname = AData.zname.ToExtString();
-    wchar_t *zname = new wchar_t[len+1];
-    len = 0; while (zname[len] = (wchar_t)(iname[len])) len++;
-    myZName = zname;
-  }
-  /* Grid color */
-  myGridColor[0] = (float) AData.gridcolor.Red();
-  myGridColor[1] = (float) AData.gridcolor.Green();
-  myGridColor[2] = (float) AData.gridcolor.Blue();
-  /* X name color */
-  myXNameColor[0] = (float) AData.xnamecolor.Red();
-  myXNameColor[1] = (float) AData.xnamecolor.Green();
-  myXNameColor[2] = (float) AData.xnamecolor.Blue();
-  /* Y name color */
-  myYNameColor[0] = (float) AData.ynamecolor.Red();
-  myYNameColor[1] = (float) AData.ynamecolor.Green();
-  myYNameColor[2] = (float) AData.ynamecolor.Blue();
-  /* Z name color */
-  myZNameColor[0] = (float) AData.znamecolor.Red();
-  myZNameColor[1] = (float) AData.znamecolor.Green();
-  myZNameColor[2] = (float) AData.znamecolor.Blue();
-  /* X color of axis and values */
-  myXColor[0] = (float) AData.xcolor.Red();
-  myXColor[1] = (float) AData.xcolor.Green();
-  myXColor[2] = (float) AData.xcolor.Blue();
-  /* Y color of axis and values */
-  myYColor[0] = (float) AData.ycolor.Red();
-  myYColor[1] = (float) AData.ycolor.Green();
-  myYColor[2] = (float) AData.ycolor.Blue();
-  /* Z color of axis and values */
-  myZColor[0] = (float) AData.zcolor.Red();
-  myZColor[1] = (float) AData.zcolor.Green();
-  myZColor[2] = (float) AData.zcolor.Blue();
-  /* Font name of names of axes: Courier, Arial, ... */
-  len = AData.fontOfNames.Length();
-  char *fontOfNames = new char[len+1];
-  if (len)
-    strcpy(fontOfNames, AData.fontOfNames.ToCString());
-  else
-    fontOfNames[0] = '\0';
-  myFontOfNames = fontOfNames;
-  /* Font name of values: Courier, Arial, ... */
-  len = AData.fontOfValues.Length();
-  char *fontOfValues = new char[len+1];
-  if (len)
-    strcpy(fontOfValues, AData.fontOfValues.ToCString());
-  else
-    fontOfValues[0] = '\0';
-  myFontOfValues = fontOfValues;
+  myLabelX.Release (theCtx);
+  myLabelY.Release (theCtx);
+  myLabelZ.Release (theCtx);
+  myLabelValues.Release (theCtx);
 }
 
-OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron ()
+OpenGl_GraduatedTrihedron::OpenGl_GraduatedTrihedron (const Graphic3d_CGraduatedTrihedron& theData)
+: myLabelX (theData.xname, OpenGl_Vec3(1.0f, 0.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelY (theData.yname, OpenGl_Vec3(0.0f, 1.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelZ (theData.zname, OpenGl_Vec3(0.0f, 0.0f, 1.0f), THE_LABEL_PARAMS),
+  myToDrawXName (theData.xdrawname == Standard_True),
+  myToDrawYName (theData.ydrawname == Standard_True),
+  myToDrawZName (theData.zdrawname == Standard_True),
+  myToDrawXValues (theData.xdrawvalues == Standard_True),
+  myToDrawYValues (theData.ydrawvalues == Standard_True),
+  myToDrawZValues (theData.zdrawvalues == Standard_True),
+  myToDrawGrid (theData.drawgrid == Standard_True),
+  myToDrawAxes (theData.drawaxes == Standard_True),
+  myNbX (theData.nbx),
+  myNbY (theData.nby),
+  myNbZ (theData.nbz),
+  myXOffset (theData.xoffset),
+  myYOffset (theData.yoffset),
+  myZOffset (theData.zoffset),
+  myXAxisOffset (theData.xaxisoffset),
+  myYAxisOffset (theData.yaxisoffset),
+  myZAxisOffset (theData.zaxisoffset),
+  myDrawXTickmarks (theData.xdrawtickmarks),
+  myDrawYTickmarks (theData.ydrawtickmarks),
+  myDrawZTickmarks (theData.zdrawtickmarks),
+  myXTickmarkLength (theData.xtickmarklength),
+  myYTickmarkLength (theData.ytickmarklength),
+  myZTickmarkLength (theData.ztickmarklength),
+  myCbCubicAxes (theData.cbCubicAxes),
+  myPtrVisual3dView (theData.ptrVisual3dView)
 {
-  // Names of axes
-  if (myXName)
-    delete[] myXName;
-  if (myYName)
-    delete[] myYName;
-  if (myZName)
-    delete[] myZName;
-
-  // Fonts
-  if (myFontOfNames)
-    delete[] myFontOfNames;
-  if (myFontOfValues)
-    delete[] myFontOfValues;
+  myAspectLabels.ChangeFontName() = theData.fontOfNames;
+  myAspectValues.ChangeFontName() = theData.fontOfValues;
+  myAspectLabels.SetFontAspect (theData.styleOfNames);
+  myAspectValues.SetFontAspect (theData.styleOfValues);
+  myLabelX.SetFontSize (NULL, theData.sizeOfNames);
+  myLabelY.SetFontSize (NULL, theData.sizeOfNames);
+  myLabelZ.SetFontSize (NULL, theData.sizeOfNames);
+  myLabelValues.SetFontSize (NULL, theData.sizeOfValues);
+
+  // Grid color
+  myGridColor[0] = (float) theData.gridcolor.Red();
+  myGridColor[1] = (float) theData.gridcolor.Green();
+  myGridColor[2] = (float) theData.gridcolor.Blue();
+  // X name color
+  myXNameColor.rgb[0] = (float )theData.xnamecolor.Red();
+  myXNameColor.rgb[1] = (float )theData.xnamecolor.Green();
+  myXNameColor.rgb[2] = (float )theData.xnamecolor.Blue();
+  myXNameColor.rgb[3] = 1.0f;
+  // Y name color
+  myYNameColor.rgb[0] = (float )theData.ynamecolor.Red();
+  myYNameColor.rgb[1] = (float )theData.ynamecolor.Green();
+  myYNameColor.rgb[2] = (float )theData.ynamecolor.Blue();
+  myYNameColor.rgb[3] = 1.0f;
+  // Z name color
+  myZNameColor.rgb[0] = (float )theData.znamecolor.Red();
+  myZNameColor.rgb[1] = (float )theData.znamecolor.Green();
+  myZNameColor.rgb[2] = (float )theData.znamecolor.Blue();
+  myZNameColor.rgb[3] = 1.0f;
+  // X color of axis and values
+  myXColor.rgb[0] = (float )theData.xcolor.Red();
+  myXColor.rgb[1] = (float )theData.xcolor.Green();
+  myXColor.rgb[2] = (float )theData.xcolor.Blue();
+  myXColor.rgb[3] = 1.0f;
+  // Y color of axis and values
+  myYColor.rgb[0] = (float )theData.ycolor.Red();
+  myYColor.rgb[1] = (float )theData.ycolor.Green();
+  myYColor.rgb[2] = (float )theData.ycolor.Blue();
+  myYColor.rgb[3] = 1.0f;
+  // Z color of axis and values
+  myZColor.rgb[0] = (float )theData.zcolor.Red();
+  myZColor.rgb[1] = (float )theData.zcolor.Green();
+  myZColor.rgb[2] = (float )theData.zcolor.Blue();
+  myZColor.rgb[3] = 1.0f;
+}
+
+OpenGl_GraduatedTrihedron::~OpenGl_GraduatedTrihedron()
+{
+  //
 }
 
 //call_graduatedtrihedron_redraw
-void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const OpenGl_AspectLine *oldAspectLine = AWorkspace->SetAspectLine(&myDefaultAspectLine);
-  AWorkspace->AspectLine(Standard_True);
+  const OpenGl_AspectLine *oldAspectLine = theWorkspace->SetAspectLine(&myDefaultAspectLine);
+  theWorkspace->AspectLine(Standard_True);
 
   /* Update boundary box */
   if (myCbCubicAxes)
@@ -650,17 +611,17 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     }
   }
 
-  /* Draw the graduated trihedron */
-  unsigned int i, j, offset;
+  // Draw the graduated trihedron
+  unsigned int i, offset;
   float m1[3], m2[3];
   float step, dx, dy, dz;
 
-  /* Grid */
-  if (myDrawGrid)
+  // Grid
+  if (myToDrawGrid)
   {
     glColor3fv(myGridColor);
     glBegin(GL_LINES);
-    /* Boundary grid-lines */
+    // Boundary grid-lines
     if (LX1draw == 1)
     {
       glVertex3fv(&(LX1[0]));
@@ -712,7 +673,7 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     /* X-Grid lines */
     if (myNbX > 0)
     {
-      i = myDrawAxes ? 1 : 0;
+      i = myToDrawAxes ? 1 : 0;
       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
       while (i < myNbX)
       {
@@ -727,7 +688,7 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     /* Y-Grid lines */
     if (myNbY > 0)
     {
-      i = myDrawAxes ? 1 : 0;
+      i = myToDrawAxes ? 1 : 0;
       step = fabsf(LY1[4] - LY1[1]) / (float) myNbY;
       while (i < myNbY)
       {
@@ -742,8 +703,9 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     /* Z-Grid lines */
     if (myNbZ > 0)
     {
-      i = myDrawAxes ? 1 : 0;
+      i = myToDrawAxes ? 1 : 0;
       step = fabsf(LZ1[5] - LZ1[2]) / (float) myNbZ;
+
       while (i < myNbZ)
       {
         glBegin(GL_LINE_STRIP);
@@ -756,39 +718,38 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     }
   }
 
-  /* Axes (arrows) */
-  if (myDrawAxes)
+  // Axes (arrows)
+  if (myToDrawAxes)
   {
-    /* X-axis */
-    glColor3fv(myXColor);
+    // X-axis
+    glColor3fv(myXColor.rgb);
     drawArrow(xmin, ymin, zmin, xmax, ymin, zmin, normal[0], normal[1], normal[2]);
 
-    /* Y-axis */
-    glColor3fv(myYColor);
+    // Y-axis
+    glColor3fv(myYColor.rgb);
     drawArrow(xmin, ymin, zmin, xmin, ymax, zmin, normal[0], normal[1], normal[2]);
 
-    /* Z-axis */
-    glColor3fv(myZColor);
+    // Z-axis
+    glColor3fv(myZColor.rgb);
     drawArrow(xmin, ymin, zmin, xmin, ymin, zmax, normal[0], normal[1], normal[2]);
   }
 
-  /* Names of axes & values */
+  // Names of axes & values
   char textValue[128];
-  wchar_t wtextValue[128];
 
-  if (myDrawXName || myDrawXValues)
+  if (myToDrawXName || myToDrawXValues)
   {
-    /* Middle point of the first X-axis */
+    // Middle point of the first X-axis
     m1[0] = 0.5f * (LX1[0] + LX1[3]);
     m1[1] = 0.5f * (LX1[1] + LX1[4]);
     m1[2] = 0.5f * (LX1[2] + LX1[5]);
 
-    /* Middle point of the second X-axis */
+    // Middle point of the second X-axis
     m2[0] = 0.5f * (LX2[0] + LX2[3]);
     m2[1] = 0.5f * (LX2[1] + LX2[4]);
     m2[2] = 0.5f * (LX2[2] + LX2[5]);
 
-    /* Apply offset to m1 */
+    // Apply offset to m1
     dy = m1[1] - m2[1];
     if (fabsf(dy) > 1.e-7f)
     {
@@ -802,64 +763,66 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     m2[1] = dpix * dy;
     m2[2] = dpix * dz;
 
-    /* Name of X-axis */
-    if (myDrawXName)
+    // Name of X-axis
+    if (myToDrawXName)
     {
-      glColor3fv(myXNameColor);
       offset = myXAxisOffset + myXTickmarkLength;
-      drawText(AWorkspace, myXName, myFontOfNames, myStyleOfNames, mySizeOfNames,
-               m1[0], m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
+
+      // draw axes labels
+      myAspectLabels.ChangeColor() = myXNameColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectLabels);
+      myLabelX.SetPosition (OpenGl_Vec3(m1[0], m1[1] + offset * m2[1], m1[2] + offset * m2[2]));
+      myLabelX.Render (theWorkspace);
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* X-values */
-    if (myDrawXValues && myNbX > 0)
+    // X-values
+    if (myToDrawXValues && myNbX > 0)
     {
-      glColor3fv(myXColor);
+      myAspectValues.ChangeColor() = myXColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectValues);
 
-      i = 0;
       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
       offset = myXOffset + myXTickmarkLength;
-      while (i <= myNbX)
+      for (unsigned int anIter = 0; anIter <= myNbX; ++anIter)
       {
-        sprintf(textValue, "%g", LX1[0] + i * step);
-        j = 0; while (wtextValue[j] = textValue[j]) j++;
-        drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues,
-                 LX1[0] + i * step, m1[1] + offset * m2[1], m1[2] + offset * m2[2]);
-        i++;
+        sprintf (textValue, "%g", LX1[0] + anIter * step);
+        myLabelValues.Init (theWorkspace->GetGlContext(), textValue,
+                            OpenGl_Vec3(LX1[0] + anIter * step, m1[1] + offset * m2[1], m1[2] + offset * m2[2]));
+        myLabelValues.Render (theWorkspace);
       }
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* X-tickmark */
+    // X-tickmark
     if (myDrawXTickmarks && myNbX > 0)
     {
       glColor3fv(myGridColor);
 
-      i = 0;
       step = fabsf(LX1[3] - LX1[0]) / (float) myNbX;
-      while (i <= myNbX)
+      for (unsigned int anIter = 0; anIter <= myNbX; ++anIter)
       {
         glBegin(GL_LINES);
-        glVertex3f(LX1[0] + i * step, m1[1],                             m1[2]);
-        glVertex3f(LX1[0] + i * step, m1[1] + myXTickmarkLength * m2[1], m1[2] + myXTickmarkLength * m2[2]);
+        glVertex3f(LX1[0] + anIter * step, m1[1],                             m1[2]);
+        glVertex3f(LX1[0] + anIter * step, m1[1] + myXTickmarkLength * m2[1], m1[2] + myXTickmarkLength * m2[2]);
         glEnd();
-        i++;
       }
     }
   }
 
-  if (myDrawYName || myDrawYValues)
+  if (myToDrawYName || myToDrawYValues)
   {
-    /* Middle point of the first Y-axis */
+    // Middle point of the first Y-axis
     m1[0] = 0.5f * (LY1[0] + LY1[3]);
     m1[1] = 0.5f * (LY1[1] + LY1[4]);
     m1[2] = 0.5f * (LY1[2] + LY1[5]);
 
-    /* Middle point of the second Y-axis */
+    // Middle point of the second Y-axis
     m2[0] = 0.5f * (LY2[0] + LY2[3]);
     m2[1] = 0.5f * (LY2[1] + LY2[4]);
     m2[2] = 0.5f * (LY2[2] + LY2[5]);
 
-    /* Apply offset to m1 */
+    // Apply offset to m1
     dx = m1[0] - m2[0];
     if (fabsf(dx) > 1.e-7f)
     {
@@ -874,34 +837,37 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     m2[0] = dpix * dx;
     m2[2] = dpix * dz;
 
-    /* Name of Y-axis */
-    if (myDrawYName)
+    // Name of Y-axis
+    if (myToDrawYName)
     {
-      glColor3fv(myYNameColor);
       offset = myYAxisOffset + myYTickmarkLength;
-      drawText(AWorkspace, myYName, myFontOfNames, myStyleOfNames, mySizeOfNames,
-               m1[0] + offset * m2[0], m1[1], m1[2] + offset * m2[2]);
+
+      myAspectLabels.ChangeColor() = myYNameColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectLabels);
+      myLabelY.SetPosition (OpenGl_Vec3(m1[0] + offset * m2[0], m1[1], m1[2] + offset * m2[2]));
+      myLabelY.Render (theWorkspace);
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* Y-values */
-    if (myDrawYValues && myNbY > 0)
+    // Y-values
+    if (myToDrawYValues && myNbY > 0)
     {
-      glColor3fv(myYColor);
+      myAspectValues.ChangeColor() = myYColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectValues);
 
-      i = 0;
       step = fabsf(LY1[4] - LY1[1]) / (float) myNbY;
       offset = myYOffset + myYTickmarkLength;
-      while (i <= myNbY)
+      for (unsigned int anIter = 0; anIter <= myNbY; ++anIter)
       {
-        sprintf(textValue, "%g", LY1[1] + i * step);
-        j = 0; while (wtextValue[j] = textValue[j]) j++;
-        drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues,
-                 m1[0] + offset * m2[0], LY1[1] + i * step, m1[2] + offset * m2[2]);
-        i++;
+        sprintf (textValue, "%g", LY1[1] + anIter * step);
+        myLabelValues.Init (theWorkspace->GetGlContext(), textValue,
+                            OpenGl_Vec3(m1[0] + offset * m2[0], LY1[1] + anIter * step, m1[2] + offset * m2[2]));
+        myLabelValues.Render (theWorkspace);
       }
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* Y-tickmark */
+    // Y-tickmark
     if (myDrawYTickmarks && myNbY > 0)
     {
       glColor3fv(myGridColor);
@@ -919,19 +885,19 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     }
   }
 
-  if (myDrawZName || myDrawZValues)
+  if (myToDrawZName || myToDrawZValues)
   {
-    /* Middle point of the first Z-axis */
+    // Middle point of the first Z-axis
     m1[0] = 0.5f * (LZ1[0] + LZ1[3]);
     m1[1] = 0.5f * (LZ1[1] + LZ1[4]);
     m1[2] = 0.5f * (LZ1[2] + LZ1[5]);
 
-    /* Middle point of the second Z-axis */
+    // Middle point of the second Z-axis
     m2[0] = 0.5f * (LZ2[0] + LZ2[3]);
     m2[1] = 0.5f * (LZ2[1] + LZ2[4]);
     m2[2] = 0.5f * (LZ2[2] + LZ2[5]);
 
-    /* Apply offset to m1 */
+    // Apply offset to m1
     dx = m1[0] - m2[0];
     if (fabsf(dx) > 1.e-7f)
     {
@@ -946,34 +912,37 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     m2[0] = dpix * dx;
     m2[1] = dpix * dy;
 
-    /* Name of Z-axis */
-    if (myDrawZName)
+    // Name of Z-axis
+    if (myToDrawZName)
     {
-      glColor3fv(myZNameColor);
       offset = myZAxisOffset + myZTickmarkLength;
-      drawText(AWorkspace, myZName, myFontOfNames, myStyleOfNames, mySizeOfNames,
-               m1[0] + offset * m2[0], m1[1] + offset * m2[1], m1[2]);
+
+      myAspectLabels.ChangeColor() = myZNameColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectLabels);
+      myLabelZ.SetPosition (OpenGl_Vec3(m1[0] + offset * m2[0], m1[1] + offset * m2[1], m1[2]));
+      myLabelZ.Render (theWorkspace);
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* Z-values */
-    if (myDrawZValues && myNbZ > 0)
+    // Z-values
+    if (myToDrawZValues && myNbZ > 0)
     {
-      glColor3fv(myZColor);
+      myAspectValues.ChangeColor() = myZColor;
+      const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectValues);
 
-      i = 0;
       step = fabsf(LZ1[5] - LZ1[2]) / (float) myNbZ;
       offset = myZOffset + myZTickmarkLength;
-      while (i <= myNbZ)
+      for (unsigned int anIter = 0; anIter <= myNbZ; ++anIter)
       {
-        sprintf(textValue, "%g", LZ1[2] + i * step);
-        j = 0; while (wtextValue[j] = textValue[j]) j++;
-        drawText(AWorkspace, wtextValue, myFontOfValues, myStyleOfValues, mySizeOfValues,
-                 m1[0] + offset * m2[0], m1[1] + offset * m2[1], LZ1[2] + i * step);
-        i++;
+        sprintf (textValue, "%g", LZ1[2] + anIter * step);
+        myLabelValues.Init (theWorkspace->GetGlContext(), textValue,
+                            OpenGl_Vec3(m1[0] + offset * m2[0], m1[1] + offset * m2[1], LZ1[2] + anIter * step));
+        myLabelValues.Render (theWorkspace);
       }
+      theWorkspace->SetAspectText (aPrevAspectText);
     }
 
-    /* Z-tickmark */
+    // Z-tickmark
     if (myDrawZTickmarks && myNbZ > 0)
     {
       glColor3fv(myGridColor);
@@ -991,11 +960,11 @@ void OpenGl_GraduatedTrihedron::Render (const Handle(OpenGl_Workspace) &AWorkspa
     }
   }
 
-  /* Activate the lighting if it was turned off by this method call */
+  // Activate the lighting if it was turned off by this method call
   if (light)
     glEnable(GL_LIGHTING);
 
-  AWorkspace->SetAspectLine(oldAspectLine);
+  theWorkspace->SetAspectLine(oldAspectLine);
 }
 
 //call_graduatedtrihedron_minmaxvalues
index 529620b..3b128bf 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-09-20
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef _OpenGl_GraduatedTrihedron_Header
 #define _OpenGl_GraduatedTrihedron_Header
 
-#include <Handle_OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_Element.hxx>
 
+#include <OpenGl_Text.hxx>
 #include <Graphic3d_CGraduatedTrihedron.hxx>
 
 class OpenGl_View;
 
-class OpenGl_GraduatedTrihedron : public MMgt_TShared
+class OpenGl_GraduatedTrihedron : public OpenGl_Element
 {
- public:
-  OpenGl_GraduatedTrihedron (const Graphic3d_CGraduatedTrihedron &AData);
-  virtual ~OpenGl_GraduatedTrihedron ();
+
+public:
 
   static void SetMinMax (const Standard_ShortReal xMin, const Standard_ShortReal yMin, const Standard_ShortReal zMin,
                          const Standard_ShortReal xMax, const Standard_ShortReal yMax, const Standard_ShortReal zMax);
 
-  void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+public:
+
+  OpenGl_GraduatedTrihedron (const Graphic3d_CGraduatedTrihedron& theData);
+
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theCtx);
 
-  // Type definition
-  //
-  DEFINE_STANDARD_RTTI(OpenGl_GraduatedTrihedron)
+protected:
 
- protected:
+  virtual ~OpenGl_GraduatedTrihedron();
 
-  const wchar_t *myXName;
-  const wchar_t *myYName;
-  const wchar_t *myZName;
-  unsigned char myDrawXName, myDrawYName, myDrawZName;
-  unsigned char myDrawXValues, myDrawYValues, myDrawZValues;
-  unsigned char myDrawGrid;
-  unsigned char myDrawAxes;
+protected:
+
+  mutable OpenGl_Text       myLabelX;
+  mutable OpenGl_Text       myLabelY;
+  mutable OpenGl_Text       myLabelZ;
+  mutable OpenGl_Text       myLabelValues;
+  mutable OpenGl_AspectText myAspectLabels;
+  mutable OpenGl_AspectText myAspectValues;
+  TEL_COLOUR myXNameColor;
+  TEL_COLOUR myYNameColor;
+  TEL_COLOUR myZNameColor;
+
+  bool myToDrawXName;
+  bool myToDrawYName;
+  bool myToDrawZName;
+  bool myToDrawXValues;
+  bool myToDrawYValues;
+  bool myToDrawZValues;
+  bool myToDrawGrid;
+  bool myToDrawAxes;
   unsigned int myNbX, myNbY, myNbZ;
   int myXOffset, myYOffset, myZOffset;
   int myXAxisOffset, myYAxisOffset, myZAxisOffset;
   unsigned char myDrawXTickmarks, myDrawYTickmarks, myDrawZTickmarks;
   unsigned int myXTickmarkLength, myYTickmarkLength, myZTickmarkLength;
   float myGridColor[3];
-  float myXNameColor[3];
-  float myYNameColor[3];
-  float myZNameColor[3];
-  float myXColor[3];
-  float myYColor[3];
-  float myZColor[3];
-  const char *myFontOfNames;
-  Font_FontAspect myStyleOfNames;
-  int mySizeOfNames;
-  const char* myFontOfValues;
-  Font_FontAspect myStyleOfValues;
-  int mySizeOfValues;
+  TEL_COLOUR myXColor;
+  TEL_COLOUR myYColor;
+  TEL_COLOUR myZColor;
   minMaxValuesCallback myCbCubicAxes;
   void* myPtrVisual3dView;
 
- public:
+public:
+
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //_OpenGl_GraduatedTrihedron_Header
index 1f9487b..f626dd2 100755 (executable)
 #include <OpenGl_GraphicDriver.hxx>
 
 #include <OpenGl_Context.hxx>
+#include <OpenGl_GraduatedTrihedron.hxx>
+#include <OpenGl_Group.hxx>
 #include <OpenGl_CView.hxx>
 #include <OpenGl_View.hxx>
+#include <OpenGl_Text.hxx>
+#include <OpenGl_Trihedron.hxx>
 #include <OpenGl_Workspace.hxx>
 
+#include <Standard_NotImplemented.hxx>
+
 IMPLEMENT_STANDARD_HANDLE(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
 
@@ -64,7 +70,8 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Standard_CString theShrName)
   myMapOfView      (1, NCollection_BaseAllocator::CommonBaseAllocator()),
   myMapOfWS        (1, NCollection_BaseAllocator::CommonBaseAllocator()),
   myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator()),
-  myUserDrawCallback (NULL)
+  myUserDrawCallback (NULL),
+  myTempText (new OpenGl_Text())
 {
   //
 }
@@ -274,3 +281,271 @@ void OpenGl_GraphicDriver::EndImmediatMode (const Standard_Integer )
     myImmediateWS.Nullify();
   }
 }
+
+// =======================================================================
+// function : Print
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_GraphicDriver::Print (const Graphic3d_CView& theCView,
+                                              const Aspect_CLayer2d& theCUnderLayer,
+                                              const Aspect_CLayer2d& theCOverLayer,
+                                              const Aspect_Handle    thePrintDC,
+                                              const Standard_Boolean theToShowBackground,
+                                              const Standard_CString theFilename,
+                                              const Aspect_PrintAlgo thePrintAlgorithm,
+                                              const Standard_Real    theScaleFactor) const
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView == NULL
+   || !myPrintContext.IsNull())
+  {
+    return Standard_False;
+  }
+
+  Standard_Boolean isPrinted = Standard_False;
+  myPrintContext = new OpenGl_PrinterContext();
+#ifdef _WIN32
+  isPrinted = aCView->WS->Print (myPrintContext,
+                                 theCView,
+                                 theCUnderLayer,
+                                 theCOverLayer,
+                                 thePrintDC,
+                                 theToShowBackground,
+                                 theFilename,
+                                 thePrintAlgorithm,
+                                 theScaleFactor);
+#else
+  Standard_NotImplemented::Raise ("OpenGl_GraphicDriver::Print is implemented only on Windows");
+#endif
+  myPrintContext.Nullify();
+  return isPrinted;
+}
+
+// =======================================================================
+// function : Text
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&                 theCGroup,
+                                 const TCollection_ExtendedString&       theText,
+                                 const Graphic3d_Vertex&                 thePoint,
+                                 const Standard_Real                     theHeight,
+                                 const Quantity_PlaneAngle               /*theAngle*/,
+                                 const Graphic3d_TextPath                /*theTp*/,
+                                 const Graphic3d_HorizontalTextAlignment theHta,
+                                 const Graphic3d_VerticalTextAlignment   theVta,
+                                 const Standard_Boolean                  /*theToEvalMinMax*/)
+{
+  if (theCGroup.ptrGroup == NULL)
+  {
+    return;
+  }
+
+  OpenGl_TextParam aParams;
+  aParams.Height = int ((theHeight < 2.0) ? DefaultTextHeight() : theHeight);
+  aParams.HAlign = theHta;
+  aParams.VAlign = theVta;
+  const OpenGl_Vec3 aPoint (thePoint.X(), thePoint.Y(), thePoint.Z());
+  OpenGl_Text* aText = new OpenGl_Text (theText, aPoint, aParams);
+  ((OpenGl_Group* )theCGroup.ptrGroup)->AddElement (TelText, aText);
+}
+
+// =======================================================================
+// function : Text
+// purpose  : Wrapper CString -> TCollection_ExtendedString
+// =======================================================================
+void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&                 theCGroup,
+                                 const Standard_CString                  theText,
+                                 const Graphic3d_Vertex&                 thePoint,
+                                 const Standard_Real                     theHeight,
+                                 const Quantity_PlaneAngle               theAngle,
+                                 const Graphic3d_TextPath                theTp,
+                                 const Graphic3d_HorizontalTextAlignment theHta,
+                                 const Graphic3d_VerticalTextAlignment   theVta,
+                                 const Standard_Boolean                  theToEvalMinMax)
+{
+  OpenGl_GraphicDriver::Text (theCGroup, TCollection_ExtendedString (theText),
+                              thePoint, theHeight, theAngle, theTp, theHta, theVta, theToEvalMinMax);
+}
+
+// =======================================================================
+// function : Text
+// purpose  : Wrapper CString -> TCollection_ExtendedString
+// =======================================================================
+void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup& theCGroup,
+                                 const Standard_CString  theText,
+                                 const Graphic3d_Vertex& thePoint,
+                                 const Standard_Real     theHeight,
+                                 const Standard_Boolean  theToEvalMinMax)
+{
+  OpenGl_GraphicDriver::Text (theCGroup, TCollection_ExtendedString (theText), thePoint, theHeight, theToEvalMinMax);
+}
+
+// =======================================================================
+// function : Text
+// purpose  : Wrapper with default values
+// =======================================================================
+void OpenGl_GraphicDriver::Text (const Graphic3d_CGroup&           theCGroup,
+                                 const TCollection_ExtendedString& theText,
+                                 const Graphic3d_Vertex&           thePoint,
+                                 const Standard_Real               theHeight,
+                                 const Standard_Boolean            theToEvalMinMax)
+{
+  OpenGl_GraphicDriver::Text (theCGroup,
+                              theText, thePoint, theHeight, 0.0,
+                              Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM,
+                              theToEvalMinMax);
+}
+
+// =======================================================================
+// function : ZBufferTriedronSetup
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::ZBufferTriedronSetup (const Quantity_NameOfColor theXColor,
+                                                 const Quantity_NameOfColor theYColor,
+                                                 const Quantity_NameOfColor theZColor,
+                                                 const Standard_Real        theSizeRatio,
+                                                 const Standard_Real        theAxisDiametr,
+                                                 const Standard_Integer     theNbFacettes)
+{
+  OpenGl_Trihedron::Setup (theXColor, theYColor, theZColor, theSizeRatio, theAxisDiametr, theNbFacettes);
+}
+
+// =======================================================================
+// function : TriedronDisplay
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::TriedronDisplay (const Graphic3d_CView&              theCView,
+                                            const Aspect_TypeOfTriedronPosition thePosition,
+                                            const Quantity_NameOfColor          theColor,
+                                            const Standard_Real                 theScale,
+                                            const Standard_Boolean              theAsWireframe)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->TriedronDisplay (aCView->WS->GetGlContext(), thePosition, theColor, theScale, theAsWireframe);
+  }
+}
+
+// =======================================================================
+// function : TriedronErase
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& theCView)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->TriedronErase (aCView->WS->GetGlContext());
+  }
+}
+
+// =======================================================================
+// function : TriedronEcho
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ,
+                                         const Aspect_TypeOfTriedronEcho )
+{
+  // do nothing
+}
+
+// =======================================================================
+// function : Environment
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::Environment (const Graphic3d_CView& theCView)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView == NULL)
+  {
+    return;
+  }
+
+  aCView->View->SetTextureEnv    (aCView->WS->GetGlContext(), theCView.Context.TextureEnv);
+  aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
+}
+
+// =======================================================================
+// function : BackgroundImage
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::BackgroundImage (const Standard_CString  theFileName,
+                                            const Graphic3d_CView&  theCView,
+                                            const Aspect_FillMethod theFillStyle)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->CreateBackgroundTexture (theFileName, theFillStyle);
+  }
+}
+
+// =======================================================================
+// function : SetBgImageStyle
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::SetBgImageStyle (const Graphic3d_CView&  theCView,
+                                            const Aspect_FillMethod theFillStyle)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->SetBackgroundTextureStyle (theFillStyle);
+  }
+}
+
+// =======================================================================
+// function : SetBgGradientStyle
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::SetBgGradientStyle (const Graphic3d_CView&          theCView,
+                                               const Aspect_GradientFillMethod theFillType)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->SetBackgroundGradientType (theFillType);
+  }
+}
+
+// =======================================================================
+// function : GraduatedTrihedronDisplay
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::GraduatedTrihedronDisplay (const Graphic3d_CView&               theCView,
+                                                      const Graphic3d_CGraduatedTrihedron& theCubic)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->GraduatedTrihedronDisplay (aCView->WS->GetGlContext(), theCubic);
+  }
+}
+
+// =======================================================================
+// function : GraduatedTrihedronErase
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::GraduatedTrihedronErase (const Graphic3d_CView& theCView)
+{
+  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
+  if (aCView != NULL)
+  {
+    aCView->View->GraduatedTrihedronErase (aCView->WS->GetGlContext());
+  }
+}
+
+// =======================================================================
+// function : GraduatedTrihedronMinMaxValues
+// purpose  :
+// =======================================================================
+void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues (const Standard_ShortReal theMinX,
+                                                           const Standard_ShortReal theMinY,
+                                                           const Standard_ShortReal theMinZ,
+                                                           const Standard_ShortReal theMaxX,
+                                                           const Standard_ShortReal theMaxY,
+                                                           const Standard_ShortReal theMaxZ)
+{
+  OpenGl_GraduatedTrihedron::SetMinMax (theMinX, theMinY, theMinZ, theMaxX, theMaxY, theMaxZ);
+}
index fbc2ca0..e61b897 100644 (file)
@@ -23,6 +23,7 @@
 #include <Graphic3d_GraphicDriver.hxx>
 #include <Handle_OpenGl_GraphicDriver.hxx>
 #include <OpenGl_Context.hxx>
+#include <OpenGl_PrinterContext.hxx>
 
 #include <Standard_CString.hxx>
 
@@ -78,6 +79,7 @@ class TColStd_HArray1OfReal;
 class Handle(OpenGl_Workspace);
 class OpenGl_Element;
 class OpenGl_Structure;
+class OpenGl_Text;
 
 //! This class defines an OpenGl graphic driver <br>
 class OpenGl_GraphicDriver : public Graphic3d_GraphicDriver
@@ -337,7 +339,9 @@ private:
   NCollection_DataMap<Standard_Integer, Handle(OpenGl_Workspace)> myMapOfWS;
   NCollection_DataMap<Standard_Integer, OpenGl_Structure*>        myMapOfStructure;
   Handle(OpenGl_Workspace)                                        myImmediateWS;
+  mutable Handle(OpenGl_PrinterContext)                           myPrintContext;
   OpenGl_UserDrawCallback_t                                       myUserDrawCallback;
+  OpenGl_Text*                                                    myTempText;         //!< variable for compatibility (drawing text in layers)
 
 };
 
diff --git a/src/OpenGl/OpenGl_GraphicDriver_705.cxx b/src/OpenGl/OpenGl_GraphicDriver_705.cxx
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/src/OpenGl/OpenGl_GraphicDriver_710.cxx b/src/OpenGl/OpenGl_GraphicDriver_710.cxx
deleted file mode 100755 (executable)
index 83d0c80..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-// Created on: 2011-10-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-
-#include <OpenGl_GraphicDriver.hxx>
-
-#include <TCollection_AsciiString.hxx>
-#include <OpenGl_Group.hxx>
-#include <OpenGl_Text.hxx>
-
-void OpenGl_GraphicDriver::Text 
-(
- const Graphic3d_CGroup& ACGroup,
- const Standard_CString AText,
- const Graphic3d_Vertex& APoint,
- const Standard_Real AHeight,
- const Quantity_PlaneAngle AAngle,
- const Graphic3d_TextPath ATp,
- const Graphic3d_HorizontalTextAlignment AHta,
- const Graphic3d_VerticalTextAlignment AVta,
- const Standard_Boolean EvalMinMax
- ) 
-{
-  TCollection_ExtendedString TheText(AText);
-  OpenGl_GraphicDriver::Text(ACGroup,TheText,APoint,AHeight,AAngle,ATp,AHta,AVta,EvalMinMax);
-}
-
-void OpenGl_GraphicDriver::Text 
-(
- const Graphic3d_CGroup& ACGroup,
- const Standard_CString AText, 
- const Graphic3d_Vertex& APoint, 
- const Standard_Real AHeight, 
- const Standard_Boolean EvalMinMax
- ) 
-{
-  TCollection_ExtendedString TheText(AText);
-  OpenGl_GraphicDriver::Text(ACGroup,TheText,APoint,AHeight,EvalMinMax);
-}
-
-void OpenGl_GraphicDriver::Text 
-(
- const Graphic3d_CGroup& ACGroup,
- const TCollection_ExtendedString& AText, 
- const Graphic3d_Vertex& APoint, 
- const Standard_Real AHeight, 
- const Quantity_PlaneAngle AAngle, 
- const Graphic3d_TextPath ATp, 
- const Graphic3d_HorizontalTextAlignment AHta, 
- const Graphic3d_VerticalTextAlignment AVta, 
- const Standard_Boolean 
- ) 
-{
-  if (ACGroup.ptrGroup)
-  {
-    Standard_Real theHeight = AHeight;
-    if (theHeight < 0.)
-      theHeight = DefaultTextHeight();
-
-    OpenGl_Text *atext = new OpenGl_Text( AText, APoint, theHeight, AHta, AVta );
-    ((OpenGl_Group *)ACGroup.ptrGroup)->AddElement( TelText, atext );
-  }
-}
-
-void OpenGl_GraphicDriver::Text 
-(
- const Graphic3d_CGroup& ACGroup,
- const TCollection_ExtendedString& AText, 
- const Graphic3d_Vertex& APoint, 
- const Standard_Real AHeight, 
- const Standard_Boolean 
- )
-{
-  if (ACGroup.ptrGroup)
-  {
-    Standard_Real theHeight = AHeight;
-    if (theHeight < 0.)
-      theHeight = DefaultTextHeight();
-
-    OpenGl_Text *atext = new OpenGl_Text( AText, APoint, theHeight, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM );
-    ((OpenGl_Group *)ACGroup.ptrGroup)->AddElement( TelText, atext );
-  }
-}
diff --git a/src/OpenGl/OpenGl_GraphicDriver_9.cxx b/src/OpenGl/OpenGl_GraphicDriver_9.cxx
deleted file mode 100755 (executable)
index ef4cc2f..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-// Created on: 2011-10-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-#include <OpenGl_GraphicDriver.hxx>
-#include <OpenGl_CView.hxx>
-#include <OpenGl_Trihedron.hxx>
-#include <OpenGl_GraduatedTrihedron.hxx>
-#include <OpenGl_tgl_funcs.hxx>
-
-void OpenGl_GraphicDriver::Environment(const Graphic3d_CView& theCView)
-{
-  const OpenGl_CView* aCView = (const OpenGl_CView* )theCView.ptrView;
-  if (aCView == NULL)
-  {
-    return;
-  }
-
-  aCView->View->SetTextureEnv    (GetSharedContext(), theCView.Context.TextureEnv);
-  aCView->View->SetSurfaceDetail ((Visual3d_TypeOfSurfaceDetail)theCView.Context.SurfaceDetail);
-}
-
-//
-// Triedron methods : the Triedron is a non-zoomable object.
-//
-
-void OpenGl_GraphicDriver::ZBufferTriedronSetup (
-  const Quantity_NameOfColor XColor,
-  const Quantity_NameOfColor YColor,
-  const Quantity_NameOfColor ZColor,
-  const Standard_Real        SizeRatio,
-  const Standard_Real        AxisDiametr,
-  const Standard_Integer     NbFacettes)
-{
-  OpenGl_Trihedron::Setup(XColor,YColor,ZColor,SizeRatio,AxisDiametr,NbFacettes);
-}
-
-void OpenGl_GraphicDriver::TriedronDisplay (
-  const Graphic3d_CView& ACView,
-  const Aspect_TypeOfTriedronPosition APosition,
-  const Quantity_NameOfColor AColor,
-  const Standard_Real AScale,
-  const Standard_Boolean AsWireframe )
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->TriedronDisplay(APosition, AColor, AScale, AsWireframe);
-  }
-}
-
-void OpenGl_GraphicDriver::TriedronErase (const Graphic3d_CView& ACView)
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->TriedronErase();
-  }
-}
-
-void OpenGl_GraphicDriver::TriedronEcho (const Graphic3d_CView& ACView,const Aspect_TypeOfTriedronEcho AType )
-{
-  // Do nothing
-}
-
-void OpenGl_GraphicDriver::BackgroundImage( const Standard_CString FileName,
-                                           const Graphic3d_CView& ACView,
-                                           const Aspect_FillMethod FillStyle )
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->CreateBackgroundTexture( FileName, FillStyle );
-  }
-}
-
-void OpenGl_GraphicDriver::SetBgImageStyle( const Graphic3d_CView& ACView,
-                                           const Aspect_FillMethod FillStyle )
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->SetBackgroundTextureStyle( FillStyle );
-  }
-}
-
-void OpenGl_GraphicDriver::SetBgGradientStyle(const Graphic3d_CView& ACView,const Aspect_GradientFillMethod FillType)
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->SetBackgroundGradientType(FillType);
-  }
-}
-
-void OpenGl_GraphicDriver::GraduatedTrihedronDisplay(const Graphic3d_CView& ACView, const Graphic3d_CGraduatedTrihedron& cubic)
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->GraduatedTrihedronDisplay(cubic);
-  }
-}
-
-void OpenGl_GraphicDriver::GraduatedTrihedronErase(const Graphic3d_CView& ACView)
-{
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
-  if (aCView)
-  {
-    aCView->View->GraduatedTrihedronErase();
-  }
-}
-
-void OpenGl_GraphicDriver::GraduatedTrihedronMinMaxValues(const Standard_ShortReal xmin,
-                                                         const Standard_ShortReal ymin,
-                                                         const Standard_ShortReal zmin,
-                                                         const Standard_ShortReal xmax,
-                                                         const Standard_ShortReal ymax,
-                                                         const Standard_ShortReal zmax)
-{
-  OpenGl_GraduatedTrihedron::SetMinMax(xmin, ymin, zmin, xmax, ymax, zmax);
-}
index d1bc4ce..c8f2446 100755 (executable)
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #include <OpenGl_GlCore11.hxx>
 
 #include <OpenGl_GraphicDriver.hxx>
@@ -26,6 +25,7 @@
 
 #include <OpenGl_Display.hxx>
 #include <OpenGl_AspectText.hxx>
+#include <OpenGl_Text.hxx>
 #include <OpenGl_TextParam.hxx>
 
 /*----------------------------------------------------------------------*/
@@ -38,9 +38,6 @@ struct OpenGl_LAYER_PROP
   int        NbPoints;
   int        LineType;
   float      LineWidth;
-  int        FontCurrent;
-
-  Standard_Boolean FontChanged;
 
   OpenGl_AspectText AspectText;
   OpenGl_TextParam TextParam;
@@ -80,13 +77,9 @@ void InitLayerProp (const int AListId)
     TheLayerProp.NbPoints = 0;
     TheLayerProp.LineType = -1;
     TheLayerProp.LineWidth = -1.F;
-    TheLayerProp.FontCurrent = 0;
-
-    TheLayerProp.FontChanged = Standard_False;
 
     TheLayerProp.AspectText.SetContext(myDefaultContextText);
 
-    TheLayerProp.TextParam.Height = -1;
     TheLayerProp.TextParam.HAlign = Graphic3d_HTA_LEFT;
     TheLayerProp.TextParam.VAlign = Graphic3d_VTA_BOTTOM;
   }
@@ -251,214 +244,61 @@ void OpenGl_GraphicDriver::SetLineAttributes (const Standard_Integer Type, const
   }
 }
 
-void OpenGl_GraphicDriver::SetTextAttributes (const Standard_CString Font, const Standard_Integer AType, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
+void OpenGl_GraphicDriver::SetTextAttributes (const Standard_CString   theFont,
+                                              const Standard_Integer   theType,
+                                              const Standard_ShortReal theR,
+                                              const Standard_ShortReal theG,
+                                              const Standard_ShortReal theB)
 {
-  if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
-
-  // get current subtitle text color
-  const TEL_COLOUR &aSubColor = TheLayerProp.AspectText.SubtitleColor ();
-
-  // update if there are any modifications
-  if (strcmp (TheLayerProp.AspectText.Font(), Font) != 0   ||
-      (int)TheLayerProp.AspectText.DisplayType() != AType  ||
-      aSubColor.rgb[0] != (float)R ||
-      aSubColor.rgb[1] != (float)G ||
-      aSubColor.rgb[2] != (float)B)
+  if (!TheLayerProp.ListId)
   {
-    CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
-
-    aContextText.Font = Font;
-    aContextText.DisplayType = AType;
-    aContextText.ColorSubTitle.r = R;
-    aContextText.ColorSubTitle.g = G;
-    aContextText.ColorSubTitle.b = B;
-    TheLayerProp.AspectText.SetContext(aContextText);
-    TheLayerProp.FontChanged = Standard_True;
+    return;
   }
+
+  TheLayerProp.AspectText.ChangeFontName() = theFont;
+  TheLayerProp.AspectText.SetDisplayType ((Aspect_TypeOfDisplayText )theType);
+  TEL_COLOUR& aSubColor = TheLayerProp.AspectText.ChangeSubtitleColor();
+  aSubColor.rgb[0] = (float )theR;
+  aSubColor.rgb[1] = (float )theG;
+  aSubColor.rgb[2] = (float )theB;
 }
 
-void OpenGl_GraphicDriver::Text (const Standard_CString AText, const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal AHeight)
+void OpenGl_GraphicDriver::Text (const Standard_CString   theText,
+                                 const Standard_ShortReal theX,
+                                 const Standard_ShortReal theY,
+                                 const Standard_ShortReal theHeight)
 {
-  if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
-
-  const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
-
-  if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
-  {
-    TheLayerProp.TextParam.Height = (int )height;
-    TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
-    TheLayerProp.FontChanged = Standard_False;
-  }
-
-  TCollection_ExtendedString aExtStr(AText);
-  const Techar *aTChStr = (const Techar *)aExtStr.ToExtString();
-
-  //szv: conversion of Techar to wchar_t
-  wchar_t *aWChStr = (wchar_t*)aTChStr;
-  if (sizeof(Techar) != sizeof(wchar_t))
+  const Handle(OpenGl_Context)& aCtx = GetSharedContext();
+  if (!TheLayerProp.ListId || aCtx.IsNull())
   {
-    Tint i = 0; while (aTChStr[i++]);
-    aWChStr = new wchar_t[i];
-    i = 0; while (aWChStr[i++] = (wchar_t)(*aTChStr++));
+    return;
   }
 
-  const Aspect_TypeOfDisplayText aDispType =
-    TheLayerProp.AspectText.DisplayType();
+  const Standard_ShortReal aHeight = (theHeight < 2.0f) ? DefaultTextHeight() : theHeight;
+  TheLayerProp.TextParam.Height = (int )aHeight;
+  TheLayerProp.AspectText.ChangeColor() = TheLayerProp.Color;
 
-  // display type of text
-  if (aDispType != Aspect_TODT_NORMAL)
-  {
-    switch (aDispType)
-    {
-      // blend type
-      case Aspect_TODT_BLEND:
-      {
-        glEnable(GL_COLOR_LOGIC_OP);
-        glLogicOp(GL_XOR);
-      }
-      break;
-
-      // subtitle type
-      case Aspect_TODT_SUBTITLE:
-      {
-        GLint aViewport[4];
-        GLdouble aModelMatrix[16], aProjMatrix[16];
-        glGetIntegerv (GL_VIEWPORT, aViewport);
-        glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
-        glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
-
-        int aWidth, anAscent, aDescent;
-        openglDisplay->StringSize(aWChStr, aWidth, anAscent, aDescent);
-
-        GLdouble aWinX, aWinY, aWinZ;
-        gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
-          aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
-
-        // project coordinates
-        GLdouble aCoordX[4];
-        GLdouble aCoordY[4];
-        GLdouble aCoordZ[4];
-
-        // left bottom corner
-        gluUnProject (aWinX,  aWinY + aDescent, aWinZ, aModelMatrix,
-          aProjMatrix, aViewport, &aCoordX[0], &aCoordY[0], &aCoordZ[0]);
-
-        // right bottom corner
-        gluUnProject (aWinX + aWidth, aWinY + aDescent, aWinZ, aModelMatrix,
-          aProjMatrix, aViewport, &aCoordX[1], &aCoordY[1], &aCoordZ[1]);
-
-        // right top corner
-        gluUnProject (aWinX + aWidth, aWinY + anAscent, aWinZ, aModelMatrix,
-          aProjMatrix, aViewport, &aCoordX[2], &aCoordY[2], &aCoordZ[2]);
-
-        // left top corner
-        gluUnProject (aWinX, aWinY + anAscent, aWinZ, aModelMatrix,
-          aProjMatrix, aViewport, &aCoordX[3], &aCoordY[3], &aCoordZ[3]);
-
-        // draw colored plane and reset the color
-        glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
-        glBegin(GL_POLYGON);
-        glVertex3d(aCoordX[0], aCoordY[0], aCoordZ[0]);
-        glVertex3d(aCoordX[1], aCoordY[1], aCoordZ[1]);
-        glVertex3d(aCoordX[2], aCoordY[2], aCoordZ[2]);
-        glVertex3d(aCoordX[3], aCoordY[3], aCoordZ[3]);
-        glEnd();
-        glColor3fv (TheLayerProp.Color.rgb);
-      }
-      break;
-
-      case Aspect_TODT_DEKALE:
-      {
-        GLint aViewport[4];
-        GLdouble aModelMatrix[16], aProjMatrix[16];
-        glGetIntegerv (GL_VIEWPORT, aViewport);
-        glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
-        glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
-
-        GLdouble aWinX, aWinY, aWinZ;
-        gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
-          aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
-
-        GLdouble aProjX, aProjY, aProjZ;
-
-        gluUnProject (aWinX + 1, aWinY + 1, aWinZ, aModelMatrix,
-          aProjMatrix, aViewport, &aProjX, &aProjY, &aProjZ);
-
-        // draw a decal
-        glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
-        openglDisplay->RenderText (aWChStr, 1, (float)aProjX, (float)aProjY,
-          (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
-
-        gluUnProject (aWinX, aWinY, aWinZ, aModelMatrix, aProjMatrix,
-          aViewport, &aProjX, &aProjY, &aProjZ);
-
-        gluUnProject (aWinX - 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
-          aViewport, &aProjX, &aProjY, &aProjZ);
-
-        openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
-          (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
-
-        gluUnProject (aWinX - 1, aWinY + 1, aWinZ, aModelMatrix, aProjMatrix,
-          aViewport, &aProjX, &aProjY, &aProjZ);
-
-        openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
-          (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
-
-        gluUnProject (aWinX + 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
-          aViewport, &aProjX, &aProjY, &aProjZ);
-
-        openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
-          (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
-        glColor3fv (TheLayerProp.Color.rgb);
-      }
-      break;
-    }
-  }
-
-  openglDisplay->RenderText(aWChStr, 1, (float)X, (float)Y, 0.F,
-    &TheLayerProp.AspectText, &TheLayerProp.TextParam);
-
-  if (aDispType == Aspect_TODT_BLEND)
-    glDisable(GL_COLOR_LOGIC_OP);
-
-  //szv: delete temporary wide string
-  if (sizeof(Techar) != sizeof(wchar_t))
-    delete[] aWChStr;
+  myTempText->Init (aCtx, TCollection_ExtendedString (theText), OpenGl_Vec2 (theX, theY), TheLayerProp.TextParam);
+  myTempText->Render (myPrintContext, aCtx, TheLayerProp.AspectText);
+  //myTempText->Release (aCtx);
 }
 
-void OpenGl_GraphicDriver::TextSize (const Standard_CString AText, const Standard_ShortReal AHeight, Standard_ShortReal& AWidth, Standard_ShortReal& AnAscent, Standard_ShortReal& ADescent) const
+void OpenGl_GraphicDriver::TextSize (const Standard_CString   theText,
+                                     const Standard_ShortReal theHeight,
+                                     Standard_ShortReal&      theWidth,
+                                     Standard_ShortReal&      theAscent,
+                                     Standard_ShortReal&      theDescent) const
 {
-  if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
-
-  const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
-
-  if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
-  {
-    TheLayerProp.TextParam.Height = (int )height;
-    TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
-    TheLayerProp.FontChanged = Standard_False;
-  }
-
-  TCollection_ExtendedString estr(AText);
-  const Techar *s = (const Techar *)estr.ToExtString();
-
-  //szv: conversion of Techar to wchar_t
-  wchar_t *s1 = (wchar_t*)s;
-  if (sizeof(Techar) != sizeof(wchar_t))
+  const Handle(OpenGl_Context)& aCtx = GetSharedContext();
+  if (!TheLayerProp.ListId || aCtx.IsNull())
   {
-    Tint i = 0; while (s[i++]);
-    s1 = new wchar_t[i];
-    i = 0; while (s1[i++] = (wchar_t)(*s++));
+    return;
   }
 
-  int aWidth = 0, anAscent = 0, aDescent = 0;
-  openglDisplay->StringSize(s1, aWidth, anAscent, aDescent);
-
-  //szv: delete temporary wide string
-  if (sizeof(Techar) != sizeof(wchar_t))
-    delete[] s1;
+  const Standard_ShortReal aHeight = (theHeight < 2.0f) ? DefaultTextHeight() : theHeight;
+  TheLayerProp.TextParam.Height = (int )aHeight;
 
-  AWidth = (Standard_ShortReal) aWidth;
-  AnAscent = (Standard_ShortReal) anAscent;
-  ADescent = (Standard_ShortReal) aDescent;
+  TCollection_ExtendedString anExtText = theText;
+  NCollection_String aText = (Standard_Utf16Char* )anExtText.ToExtString();
+  OpenGl_Text::StringSize (aCtx, aText, TheLayerProp.AspectText, TheLayerProp.TextParam, theWidth, theAscent, theDescent);
 }
index 3359844..8c2d2be 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
+#include <OpenGl_GlCore11.hxx>
 #include <OpenGl_PrinterContext.hxx>
 
-OpenGl_PrinterContext* OpenGl_PrinterContext::g_PrinterContext = NULL;
-GLCONTEXT             OpenGl_PrinterContext::g_ContextId      = NULL;
+IMPLEMENT_STANDARD_HANDLE (OpenGl_PrinterContext, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_PrinterContext, Standard_Transient)
 
 //=======================================================================
 //function : OpenGl_PrinterContext
-//purpose  : Constructor
+//purpose  :
 //=======================================================================
-
-OpenGl_PrinterContext::OpenGl_PrinterContext (GLCONTEXT theCtx) :
-  myCtx (theCtx), myProjTransform (0, 3, 0, 3), myLayerViewportX (0),
-  myLayerViewportY (0), myScaleX (1.0f), myScaleY (1.0f)
+OpenGl_PrinterContext::OpenGl_PrinterContext()
+: myProjTransform  (0, 3, 0, 3),
+  myLayerViewportX (0),
+  myLayerViewportY (0),
+  myScaleX (1.0f),
+  myScaleY (1.0f)
 {
-  // assign global instance to the current object
-  if (myCtx != NULL)
-  {
-    g_PrinterContext = this;
-    g_ContextId      = myCtx;
-  }
-
-  // init projection matrix
+  // identity projection matrix
   Standard_Real anInitValue = 0.0;
   myProjTransform.Init (anInitValue);
-  myProjTransform (0,0)  = 1.0f;
-  myProjTransform (1,1)  = 1.0f;
-  myProjTransform (2,2)  = 1.0f;
-  myProjTransform (3,3)  = 1.0f;
+  myProjTransform (0, 0)  = 1.0;
+  myProjTransform (1, 1)  = 1.0;
+  myProjTransform (2, 2)  = 1.0;
+  myProjTransform (3, 3)  = 1.0;
+  SetProjTransformation (myProjTransform);
 }
 
-//=======================================================================
-//function : ~OpenGl_PrinterContext
-//purpose  : Destructor
-//=======================================================================
-
-OpenGl_PrinterContext::~OpenGl_PrinterContext () 
+// =======================================================================
+// function : ~OpenGl_PrinterContext
+// purpose  :
+// =======================================================================
+OpenGl_PrinterContext::~OpenGl_PrinterContext()
 {
-  // unassign global instance
-  if (g_PrinterContext == this)
-  {
-    g_ContextId      = NULL;
-    g_PrinterContext = NULL;
-  }
+  //
 }
 
-//=======================================================================
-//function : GetProjTransformation
-//purpose  : Get view projection transformation matrix.
-//=======================================================================
-
-void OpenGl_PrinterContext::GetProjTransformation (GLfloat theMatrix[16])
+// =======================================================================
+// function : LoadProjTransformation
+// purpose  :
+// =======================================================================
+void OpenGl_PrinterContext::LoadProjTransformation()
 {
-  for (int i = 0, k = 0; i < 4; i++)
-    for (int j = 0; j < 4; j++, k++)
-      theMatrix[k] = (GLfloat)myProjTransform (i,j);
+  glLoadMatrixf ((GLfloat* )myProjMatrixGl);
 }
 
-//=======================================================================
-//function : SetProjTransformation
-//purpose  : Set view projection transformation matrix for printing purposes.
-//           theProjTransform parameter should be an 4x4 array.
-//=======================================================================
-
-bool OpenGl_PrinterContext::SetProjTransformation (TColStd_Array2OfReal& thePrj)
+// =======================================================================
+// function : SetProjTransformation
+// purpose  : Set view projection transformation matrix for printing purposes.
+//            theProjTransform parameter should be an 4x4 array.
+// =======================================================================
+bool OpenGl_PrinterContext::SetProjTransformation (const TColStd_Array2OfReal& thePrj)
 {
   if (thePrj.RowLength () != 4 || thePrj.ColLength () != 4)
+  {
     return false;
+  }
 
   myProjTransform = thePrj;
-
+  for (int i = 0, k = 0; i < 4; i++)
+  {
+    for (int j = 0; j < 4; j++, k++)
+    {
+      myProjMatrixGl[k] = (Standard_ShortReal )myProjTransform (i, j);
+    }
+  }
   return true;
 }
 
-//=======================================================================
-//function : Deactivate
-//purpose  : Deactivate PrinterContext object.
-//           Useful when you need to redraw in usual mode the same
-//           OpenGl context that you used for printing right after printing,
-//           before the OpenGl_PrinterContext instance destroyed
-//=======================================================================
-
-void OpenGl_PrinterContext::Deactivate ()
+// =======================================================================
+// function : SetScale
+// purpose  :
+// =======================================================================
+void OpenGl_PrinterContext::SetScale (const Standard_ShortReal theScaleX,
+                                      const Standard_ShortReal theScaleY)
 {
-  // unassign global instance
-  if (g_PrinterContext == this)
-  {
-    g_ContextId      = NULL;
-    g_PrinterContext = NULL;
-  }
+  myScaleX = theScaleX;
+  myScaleY = theScaleY;
 }
 
-
-//=======================================================================
-//function : GetInstance
-//purpose  : Get the PrinterContext instance assigned for OpenGl context.
-//           Return NULL, if there is no current printing operation and
-//           there is no assigned instance for "theCtx" OpenGl context.
-//=======================================================================
-
-OpenGl_PrinterContext* OpenGl_PrinterContext::GetPrinterContext (GLCONTEXT theCtx)
+// =======================================================================
+// function : SetLayerViewport
+// purpose  :
+// =======================================================================
+void OpenGl_PrinterContext::SetLayerViewport (const Standard_Integer theViewportX,
+                                              const Standard_Integer theViewportY)
 {
-  if (g_ContextId == theCtx)
-    return g_PrinterContext;
-  else
-    return NULL;
+  myLayerViewportX = theViewportX;
+  myLayerViewportY = theViewportY;
 }
index 1c6e506..819670a 100644 (file)
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef _OPENGL_PRINTERCONTEXT_H
 #define _OPENGL_PRINTERCONTEXT_H
 
-#include <OpenGl_GlCore11.hxx>
-
-#include <MMgt_TShared.hxx>
-#include <Standard.hxx>
 #include <Standard_DefineHandle.hxx>
-#include <Handle_MMgt_TShared.hxx>
-#include <NCollection_DataMap.hxx>
-#include <InterfaceGraphic_Graphic3d.hxx>
-#include <InterfaceGraphic_Visual3d.hxx>
 #include <TColStd_Array2OfReal.hxx>
-
-#include <OpenGl_Workspace.hxx>
-
-class Standard_Transient;
-class Handle(Standard_Type);
-class Handle(MMgt_TShared);
-class OpenGl_PrinterContext;
-
-DEFINE_STANDARD_HANDLE(OpenGl_PrinterContext,MMgt_TShared)
+#include <Handle_Standard_Transient.hxx>
 
 //! Class provides specific information for redrawing view to offscreen buffer
 //! on printing. The information is: projection matrixes for tiling,
 //! scaling factors for text/markers and layer viewport dimensions.
-//! The OpenGl_PrinterContext class allows to have only one global instance
-//! that can be accessed by GetPrinterContext() during printing operation. 
-//! The class instance can be created only by call_togl_print().
-class OpenGl_PrinterContext : public MMgt_TShared
+class OpenGl_PrinterContext : public Standard_Transient
 {
 
 public:
 
-  //! Get the PrinterContext instance assigned for OpenGl context.
-  //! Return NULL, if there is no current printing operation and
-  //! there is no assigned instance for "theCtx" OpenGl context.
-  static OpenGl_PrinterContext* GetPrinterContext(GLCONTEXT theCtx);
+  //! Constructor
+  OpenGl_PrinterContext();
+
+  //! Destructor
+  virtual ~OpenGl_PrinterContext();
 
   //! Get view projection transformation matrix.
-  const TColStd_Array2OfReal& GetProjTransformation () 
+  inline const TColStd_Array2OfReal& GetProjTransformation() const
   {
     return myProjTransform; 
   }
 
-  //! Get view projection transformation matrix.
-  void GetProjTransformation (GLfloat theMatrix[16]); 
+  //! Set view projection transformation matrix for printing/tiling purposes
+  //! theProjTransform parameter should be an 4x4 array.
+  bool SetProjTransformation (const TColStd_Array2OfReal& theProjTransform);
+
+  //! Setup view projection transformation matrix (glLoadMatrixf).
+  void LoadProjTransformation();
 
   //! Get text/markers scale factor
-  void GetScale (GLfloat& theScaleX, GLfloat& theScaleY)
+  inline void GetScale (Standard_ShortReal& theScaleX,
+                        Standard_ShortReal& theScaleY) const
   {
     theScaleX = myScaleX;
     theScaleY = myScaleY;
   }
 
+  //! Set text scale factor
+  void SetScale (const Standard_ShortReal theScaleX,
+                 const Standard_ShortReal theScaleY);
+
   //! Get layer viewport dimensions
-  void GetLayerViewport (GLsizei& theViewportX,
-                         GLsizei& theViewportY)
+  inline void GetLayerViewport (Standard_Integer& theViewportX,
+                                Standard_Integer& theViewportY) const
   {
     theViewportX = myLayerViewportX;
     theViewportY = myLayerViewportY;
   }
 
-private:
-
-  //! Constructor
-  OpenGl_PrinterContext (GLCONTEXT theCtx);
-
-  //! Destructor
-  virtual ~OpenGl_PrinterContext ();
-
-  //! Deactivate current printing context.
-  //! Useful when you need to redraw in usual mode the same OpenGl context
-  //! that you used for printing right after printing, before the 
-  //! OpenGl_PrinterContext instance destroyed.
-  void Deactivate ();
-
-  //! Set view projection transformation matrix for printing/tiling purposes
-  //! theProjTransform parameter should be an 4x4 array.
-  bool SetProjTransformation (TColStd_Array2OfReal& theProjTransform);
-
-  //! Set text scale factor
-  void SetScale (GLfloat theScaleX, GLfloat theScaleY)
-  {
-    myScaleX = theScaleX;
-    myScaleY = theScaleY;
-  }
-
   //! Set layer viewport dimensions
-  void SetLayerViewport (GLsizei theViewportX,
-                         GLsizei theViewportY) 
-  {
-    myLayerViewportX = theViewportX; 
-    myLayerViewportY = theViewportY;
-  }
+  void SetLayerViewport (const Standard_Integer theViewportX,
+                         const Standard_Integer theViewportY);
 
 private:
 
-  static OpenGl_PrinterContext* g_PrinterContext;
-  static GLCONTEXT g_ContextId;
   TColStd_Array2OfReal myProjTransform;
-  GLfloat              myScaleX;
-  GLfloat              myScaleY;
-  GLsizei              myLayerViewportX;
-  GLsizei              myLayerViewportY;
-  GLCONTEXT            myCtx;
-
-  // the printer context could be created only in method call_togl_print
-  /*friend Standard_Boolean call_togl_print (CALL_DEF_VIEW *, CALL_DEF_LAYER *,
-                                           CALL_DEF_LAYER *, 
-                                           const Aspect_Drawable, const int,
-                                           const char*, const int, const float);*/
-  friend Standard_Boolean OpenGl_Workspace::Print (const Graphic3d_CView& ACView,
-                                                  const Aspect_CLayer2d& ACUnderLayer, 
-                                                  const Aspect_CLayer2d& ACOverLayer,
-                                                  const Aspect_Handle    hPrintDC,
-                                                  const Standard_Boolean showBackground,
-                                                  const Standard_CString filename,
-                                                  const Aspect_PrintAlgo printAlgorithm,
-                                                  const Standard_Real theScaleFactor);
+  Standard_ShortReal   myProjMatrixGl[16];
+  Standard_ShortReal   myScaleX;
+  Standard_ShortReal   myScaleY;
+  Standard_Integer     myLayerViewportX;
+  Standard_Integer     myLayerViewportY;
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_PrinterContext) // Type definition
+
 };
 
+DEFINE_STANDARD_HANDLE(OpenGl_PrinterContext, Standard_Transient)
+
 #endif
index 797f459..27b1871 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-07-13
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_Text.hxx>
+
 #include <OpenGl_AspectText.hxx>
-#include <OpenGl_Structure.hxx>
+#include <OpenGl_GraphicDriver.hxx>
 #include <OpenGl_Workspace.hxx>
 
-/*----------------------------------------------------------------------*/
+#include <Font_FontMgr.hxx>
+#include <TCollection_HAsciiString.hxx>
+
+#ifdef HAVE_CONFIG_H
+  #include <config.h>
+#endif
 
-OpenGl_Text::OpenGl_Text (const TCollection_ExtendedString& AText,
-                        const Graphic3d_Vertex& APoint,
-                        const Standard_Real AHeight,
-                        const Graphic3d_HorizontalTextAlignment AHta,
-                        const Graphic3d_VerticalTextAlignment AVta)
-: myString(NULL)
+#ifdef HAVE_GL2PS
+  #include <gl2ps.h>
+#endif
+
+namespace
 {
-  const Techar *str = (const Techar *) AText.ToExtString();
+  static const GLdouble THE_IDENTITY_MATRIX[4][4] =
+  {
+    {1.,0.,0.,0.},
+    {0.,1.,0.,0.},
+    {0.,0.,1.,0.},
+    {0.,0.,0.,1.}
+  };
+
+#ifdef HAVE_GL2PS
+  static char const* TheFamily[] = {"Helvetica", "Courier", "Times"};
+  static char const* TheItalic[] = {"Oblique",   "Oblique", "Italic"};
+  static char const* TheBase[]   = {"", "", "-Roman"};
+
+  //! Convert font name used for rendering to some "good" font names
+  //! that produce good vector text.
+  static void getGL2PSFontName (const char* theSrcFont,
+                                char*       thePsFont)
+  {
+    if (strstr (theSrcFont, "Symbol"))
+    {
+      sprintf (thePsFont, "%s", "Symbol");
+      return;
+    }
+    else if (strstr (theSrcFont, "ZapfDingbats"))
+    {
+      sprintf (thePsFont, "%s", "WingDings");
+      return;
+    }
 
-  //szv: instead of strlen + 1
-  int i = 0; while (str[i++]);
+    int  aFontId  = 0;
+    bool isBold   = false;
+    bool isItalic = false;
+    if (strstr (theSrcFont, "Courier"))
+    {
+      aFontId = 1;
+    }
+    else if (strstr (theSrcFont, "Times"))
+    {
+      aFontId = 2;
+    }
 
-  wchar_t *wstr = new wchar_t[i];
+    if (strstr (theSrcFont, "Bold"))
+    {
+      isBold = true;
+    }
+    if (strstr (theSrcFont, "Italic")
+     || strstr (theSrcFont, "Oblique"))
+    {
+      isItalic = true;
+    }
 
-  //szv: instead of memcpy
-  i = 0; while (wstr[i++] = (wchar_t)(*str++));
-  if (myString) delete[] myString;
-  myString = wstr;
+    if (isBold)
+    {
+      sprintf (thePsFont, "%s-%s", TheFamily[aFontId], "Bold");
+      if (isItalic)
+      {
+        sprintf (thePsFont, "%s%s", thePsFont, TheItalic[aFontId]);
+      }
+    }
+    else if (isItalic)
+    {
+      sprintf (thePsFont, "%s-%s", TheFamily[aFontId], TheItalic[aFontId]);
+    }
+    else
+    {
+      sprintf (thePsFont, "%s%s", TheFamily[aFontId], TheBase[aFontId]);
+    }
+  }
 
-  myAttachPnt.xyz[0] = APoint.X();
-  myAttachPnt.xyz[1] = APoint.Y();
-  myAttachPnt.xyz[2] = APoint.Z();
+  static void exportText (const NCollection_String& theText,
+                          const Standard_Boolean    theIs2d,
+                          const OpenGl_AspectText&  theAspect,
+                          const Standard_Integer    theHeight)
+  {
 
-  myParam.Height = int (AHeight);
+    char aPsFont[64];
+    getGL2PSFontName (theAspect.FontName().ToCString(), aPsFont);
 
-  myParam.HAlign = AHta;
-  myParam.VAlign = AVta;
+    if (theIs2d)
+    {
+      glRasterPos2f (0.0f, 0.0f);
+    }
+    else
+    {
+      glRasterPos3f (0.0f, 0.0f, 0.0f);
+    }
+
+    GLubyte aZero = 0;
+    glBitmap (1, 1, 0, 0, 0, 0, &aZero);
+
+    // Standard GL2PS's alignment isn't used, because it doesn't work correctly
+    // for all formats, therefore alignment is calculated manually relative
+    // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
+    gl2psTextOpt (theText.ToCString(), aPsFont, theHeight, GL2PS_TEXT_BL, theAspect.Angle());
+  }
+#endif
+
+};
+
+// =======================================================================
+// function : OpenGl_Text
+// purpose  :
+// =======================================================================
+OpenGl_Text::OpenGl_Text()
+: myWinX (0.0f),
+  myWinY (0.0f),
+  myWinZ (0.0f),
+  myScaleHeight (1.0f),
+  myPoint  (0.0f, 0.0f, 0.0f),
+  myIs2d   (false)
+{
+  myParams.Height = 10;
+  myParams.HAlign = Graphic3d_HTA_LEFT;
+  myParams.VAlign = Graphic3d_VTA_BOTTOM;
 }
 
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : OpenGl_Text
+// purpose  :
+// =======================================================================
+OpenGl_Text::OpenGl_Text (const TCollection_ExtendedString& theText,
+                          const OpenGl_Vec3&                thePoint,
+                          const OpenGl_TextParam&           theParams)
+: myWinX (0.0f),
+  myWinY (0.0f),
+  myWinZ (0.0f),
+  myScaleHeight  (1.0f),
+  myExportHeight (1.0f),
+  myParams (theParams),
+  myString ((Standard_Utf16Char* )theText.ToExtString()),
+  myPoint  (thePoint),
+  myIs2d   (false)
+{
+  //
+}
 
-OpenGl_Text::~OpenGl_Text ()
+// =======================================================================
+// function : SetPosition
+// purpose  :
+// =======================================================================
+void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
 {
-  if (myString)
-    delete[] myString;
+  myPoint = thePoint;
 }
 
-/*----------------------------------------------------------------------*/
+// =======================================================================
+// function : SetFontSize
+// purpose  :
+// =======================================================================
+void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
+                               const Standard_Integer        theFontSize)
+{
+  if (myParams.Height != theFontSize)
+  {
+    Release (theCtx);
+  }
+  myParams.Height = theFontSize;
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
+                        const Standard_Utf8Char*      theText,
+                        const OpenGl_Vec3&            thePoint)
+{
+  releaseVbos (theCtx);
+  myIs2d   = false;
+  myPoint  = thePoint;
+  myString.FromUnicode (theText);
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
+                        const Standard_Utf8Char*      theText,
+                        const OpenGl_Vec3&            thePoint,
+                        const OpenGl_TextParam&       theParams)
+{
+  if (myParams.Height != theParams.Height)
+  {
+    Release (theCtx);
+  }
+  else
+  {
+    releaseVbos (theCtx);
+  }
+  myIs2d   = false;
+  myParams = theParams;
+  myPoint  = thePoint;
+  myString.FromUnicode (theText);
+}
 
-void OpenGl_Text::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Init (const Handle(OpenGl_Context)&     theCtx,
+                        const TCollection_ExtendedString& theText,
+                        const OpenGl_Vec2&                thePoint,
+                        const OpenGl_TextParam&           theParams)
 {
-  if ( AWorkspace->DegenerateModel > 0 && AWorkspace->SkipRatio >= 1.f )
+  if (myParams.Height != theParams.Height)
+  {
+    Release (theCtx);
+  }
+  else
+  {
+    releaseVbos (theCtx);
+  }
+  myIs2d       = true;
+  myParams     = theParams;
+  myPoint.xy() = thePoint;
+  myPoint.z()  = 0.0f;
+  myString.FromUnicode ((Standard_Utf16Char* )theText.ToExtString());
+}
+
+// =======================================================================
+// function : ~OpenGl_Text
+// purpose  :
+// =======================================================================
+OpenGl_Text::~OpenGl_Text()
+{
+  //
+}
+
+// =======================================================================
+// function : releaseVbos
+// purpose  :
+// =======================================================================
+void OpenGl_Text::releaseVbos (const Handle(OpenGl_Context)& theCtx)
+{
+  for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
+  {
+    Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
+    Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
+
+    if (!theCtx.IsNull())
+    {
+      theCtx->DelayedRelease (aVerts);
+      theCtx->DelayedRelease (aTCrds);
+    }
+    aVerts.Nullify();
+    aTCrds.Nullify();
+  }
+  myTextures.Clear();
+  myVertsVbo.Clear();
+  myTCrdsVbo.Clear();
+  myVertsArray.Clear();
+  myTCrdsArray.Clear();
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Release (const Handle(OpenGl_Context)& theCtx)
+{
+  releaseVbos (theCtx);
+  if (!myFont.IsNull())
+  {
+    Handle(OpenGl_Context) aCtx = theCtx;
+    const TCollection_AsciiString aKey = myFont->ResourceKey();
+    myFont.Nullify();
+    aCtx->ReleaseResource (aKey, Standard_True);
+  }
+}
+
+// =======================================================================
+// function : StringSize
+// purpose  :
+// =======================================================================
+void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
+                              const NCollection_String&     theText,
+                              const OpenGl_AspectText&      theTextAspect,
+                              const OpenGl_TextParam&       theParams,
+                              Standard_ShortReal&           theWidth,
+                              Standard_ShortReal&           theAscent,
+                              Standard_ShortReal&           theDescent)
+{
+  theWidth   = 0.0f;
+  theAscent  = 0.0f;
+  theDescent = 0.0f;
+  const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height);
+  Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, aFontKey);
+  if (aFont.IsNull() || !aFont->IsValid())
+  {
     return;
+  }
+
+  theAscent  = aFont->Ascender();
+  theDescent = aFont->Descender();
+
+  GLfloat aWidth = 0.0f;
+  for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
+  {
+    const Standard_Utf32Char aCharThis =   *anIter;
+    const Standard_Utf32Char aCharNext = *++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)
+    {
+      theWidth = Max (theWidth, aWidth);
+      aWidth   = 0.0f;
+      continue;
+    }
+    else if (aCharThis == ' ')
+    {
+      aWidth += aFont->AdvanceX (aCharThis, aCharNext);
+      continue;
+    }
+    else if (aCharThis == '\t')
+    {
+      aWidth += aFont->AdvanceX (' ', aCharNext) * 8.0f;
+      continue;
+    }
+
+    aWidth += aFont->AdvanceX (aCharThis, aCharNext);
+  }
+  theWidth = Max (theWidth, aWidth);
+
+  Handle(OpenGl_Context) aCtx = theCtx;
+  aFont.Nullify();
+  aCtx->ReleaseResource (aFontKey, Standard_True);
+}
+
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
+{
+  if (theWorkspace->DegenerateModel > 0 && theWorkspace->SkipRatio >= 1.0f)
+  {
+    return;
+  }
+
+  const OpenGl_AspectText* aTextAspect = theWorkspace->AspectText (Standard_True);
+  const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
+
+  // use highlight color or colors from aspect
+  if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
+  {
+    render (theWorkspace->PrinterContext(),
+            theWorkspace->GetGlContext(),
+            *aTextAspect,
+            *theWorkspace->HighlightColor,
+            *theWorkspace->HighlightColor);
+  }
+  else
+  {
+    render (theWorkspace->PrinterContext(),
+            theWorkspace->GetGlContext(),
+            *aTextAspect,
+            aTextAspect->Color(),
+            aTextAspect->SubtitleColor());
+  }
 
-  const OpenGl_AspectText *aspect_text = AWorkspace->AspectText( Standard_True );
+  // restore aspects
+  if (!aPrevTexture.IsNull())
+  {
+    theWorkspace->EnableTexture (aPrevTexture);
+  }
+}
 
-  const TEL_COLOUR *tcolor, *scolor;
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
+void OpenGl_Text::Render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                          const Handle(OpenGl_Context)&        theCtx,
+                          const OpenGl_AspectText&             theTextAspect) const
+{
+  render (thePrintCtx, theCtx, theTextAspect, theTextAspect.Color(), theTextAspect.SubtitleColor());
+}
 
-  // Use highlight colours
-  if( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
+// =======================================================================
+// function : setupMatrix
+// purpose  :
+// =======================================================================
+void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                               const Handle(OpenGl_Context)&        theCtx,
+                               const OpenGl_AspectText&             theTextAspect,
+                               const OpenGl_Vec3                    theDVec) const
+{
+  // setup matrix
+  if (myIs2d)
   {
-    tcolor = scolor = AWorkspace->HighlightColor;
+    glLoadIdentity();
+    glTranslatef (myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.0f);
+    glRotatef (180.0f, 1.0f, 0.0f, 0.0f);
   }
   else
   {
-    tcolor = &aspect_text->Color();
-    scolor = &aspect_text->SubtitleColor();
+    // align coordinates to the nearest integer
+    // to avoid extra interpolation issues
+    GLdouble anObjX, anObjY, anObjZ;
+    gluUnProject (std::floor (myWinX + (GLdouble )theDVec.x()),
+                  std::floor (myWinY + (GLdouble )theDVec.y()),
+                  myWinZ + (GLdouble )theDVec.z(),
+                  (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
+                  &anObjX, &anObjY, &anObjZ);
+
+    glLoadIdentity();
+    glTranslated (anObjX, anObjY, anObjZ);
+    glRotated (theTextAspect.Angle(), 0.0, 0.0, 1.0);
+    if (!theTextAspect.IsZoomable())
+    {
+    #ifdef _WIN32
+      // if the context has assigned printer context, use it's parameters
+      if (!thePrintCtx.IsNull())
+      {
+        // get printing scaling in x and y dimensions
+        GLfloat aTextScalex = 1.0f, aTextScaley = 1.0f;
+        thePrintCtx->GetScale (aTextScalex, aTextScaley);
+
+        // text should be scaled in all directions with same
+        // factor to save its proportions, so use height (y) scaling
+        // as it is better for keeping text/3d graphics proportions
+        glScalef (aTextScaley, aTextScaley, aTextScaley);
+      }
+    #endif
+      glScaled (myScaleHeight, myScaleHeight, myScaleHeight);
+    }
+  }
+}
+
+// =======================================================================
+// function : drawText
+// purpose  :
+// =======================================================================
+void OpenGl_Text::drawText (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                            const Handle(OpenGl_Context)&        theCtx,
+                            const OpenGl_AspectText&             theTextAspect) const
+{
+#ifdef HAVE_GL2PS
+  if (theCtx->IsFeedback())
+  {
+    // position of the text and alignment is calculated by transformation matrix
+    exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
+    return;
   }
+#endif
 
-  // Handle annotation style
-  GLboolean flag_zbuffer = GL_FALSE;
-  if (aspect_text->StyleType() == Aspect_TOST_ANNOTATION)
+  if (myVertsVbo.Length() == myTextures.Length())
   {
-    flag_zbuffer = glIsEnabled(GL_DEPTH_TEST);
-    if (flag_zbuffer) glDisable(GL_DEPTH_TEST);
+    for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
+    {
+      const GLuint aTexId = myTextures.Value (anIter);
+      const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
+      const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
+      aVerts->BindFixed (theCtx, GL_VERTEX_ARRAY);
+      aTCrds->BindFixed (theCtx, GL_TEXTURE_COORD_ARRAY);
+      glBindTexture (GL_TEXTURE_2D, aTexId);
+
+      glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
+
+      glBindTexture (GL_TEXTURE_2D, 0);
+      aTCrds->UnbindFixed (theCtx, GL_VERTEX_ARRAY);
+      aVerts->UnbindFixed (theCtx, GL_VERTEX_ARRAY);
+    }
   }
+  else if (myVertsArray.Length() == myTextures.Length())
+  {
+    glEnableClientState (GL_VERTEX_ARRAY);
+    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+    for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
+    {
+      const GLuint aTexId = myTextures.Value (anIter);
+      const Handle(OpenGl_Vec2Array)& aVerts = myVertsArray.Value (anIter);
+      const Handle(OpenGl_Vec2Array)& aTCrds = myTCrdsArray.Value (anIter);
+
+      glVertexPointer   (2, GL_FLOAT, 0, (GLfloat* )&aVerts->First());
+      glTexCoordPointer (2, GL_FLOAT, 0, (GLfloat* )&aTCrds->First());
+      glBindTexture (GL_TEXTURE_2D, aTexId);
 
-  AWorkspace->SetTextParam(&myParam);
+      glDrawArrays (GL_TRIANGLES, 0, aVerts->Length());
 
-  GLdouble        modelMatrix[16], projMatrix[16];
-  GLint           viewport[4];
-  GLdouble        objrefX, objrefY, objrefZ;
-  GLdouble        objX, objY, objZ;
-  GLdouble        obj1X, obj1Y, obj1Z;
-  GLdouble        obj2X, obj2Y, obj2Z;
-  GLdouble        obj3X, obj3Y, obj3Z;
-  GLdouble        winx1, winy1, winz1;
-  GLdouble        winx, winy, winz;
-  GLint           status;
+      glBindTexture (GL_TEXTURE_2D, 0);
+    }
+    glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+    glDisableClientState (GL_VERTEX_ARRAY);
+  }
+}
 
-  /* display type of text */
-  if (aspect_text->DisplayType() != Aspect_TODT_NORMAL)
+// =======================================================================
+// function : FontKey
+// purpose  :
+// =======================================================================
+TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
+                                              const Standard_Integer   theHeight)
+{
+  const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
+  return theAspect.FontName()
+       + TCollection_AsciiString(":") + Standard_Integer(anAspect)
+       + TCollection_AsciiString(":") + theHeight;
+}
+
+// =======================================================================
+// function : FindFont
+// purpose  :
+// =======================================================================
+Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
+                                           const OpenGl_AspectText&      theAspect,
+                                           const Standard_Integer        theHeight,
+                                           const TCollection_AsciiString theKey)
+{
+  Handle(OpenGl_Font) aFont;
+  if (theHeight < 2)
   {
-    /* Optimisation: il faudrait ne faire le Get qu'une fois par Redraw */
-    glGetIntegerv (GL_VIEWPORT, viewport);
-    glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
-    glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
+    return aFont; // invalid parameters
+  }
 
-    switch (aspect_text->DisplayType())
+  if (!theCtx->GetResource (theKey, aFont))
+  {
+    Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
+    const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.FontName());
+    const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
+    Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
+    if (aRequestedFont.IsNull())
     {
+      return aFont;
+    }
+
+    Handle(Font_FTFont) aFontFt = new Font_FTFont (NULL);
+    if (!aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight))
+    {
+      return aFont;
+    }
+
+    Handle(OpenGl_Context) aCtx = theCtx;
+    glPushAttrib (GL_TEXTURE_BIT);
+    aFont = new OpenGl_Font (aFontFt, theKey);
+    if (!aFont->Init (aCtx))
+    {
+      //glPopAttrib();
+      //return aFont; // out of resources?
+    }
+    glPopAttrib(); // texture bit
+
+    aCtx->ShareResource (theKey, aFont);
+  }
+  return aFont;
+}
+
+// =======================================================================
+// function : render
+// purpose  :
+// =======================================================================
+void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                          const Handle(OpenGl_Context)&        theCtx,
+                          const OpenGl_AspectText&             theTextAspect,
+                          const TEL_COLOUR&                    theColorText,
+                          const TEL_COLOUR&                    theColorSubs) const
+{
+  if (myString.IsEmpty())
+  {
+    return;
+  }
+
+  const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height);
+  if (!myFont.IsNull()
+   && !myFont->ResourceKey().IsEqual (aFontKey))
+  {
+    // font changed
+    const_cast<OpenGl_Text* > (this)->Release (theCtx);
+  }
+
+  if (myFont.IsNull())
+  {
+    myFont = FindFont (theCtx, theTextAspect, myParams.Height, aFontKey);
+    if (myFont.IsNull())
+    {
+      return;
+    }
+  }
+
+  if (myTextures.IsEmpty())
+  {
+    OpenGl_TextFormatter aFormatter;
+    aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
+    aFormatter.Reset();
+    aFormatter.Append (theCtx, myString, *myFont.operator->());
+    aFormatter.Format();
+
+    if (OpenGl_GraphicDriver::ToUseVBO() && theCtx->core15 != NULL)
+    {
+      aFormatter.Result (theCtx, myTextures, myVertsVbo, myTCrdsVbo);
+    }
+    else
+    {
+      aFormatter.Result (theCtx, myTextures, myVertsArray, myTCrdsArray);
+    }
+    aFormatter.BndBox (myBndBox);
+  }
+
+  if (myTextures.IsEmpty())
+  {
+    return;
+  }
+
+  myExportHeight = 1.0f;
+  myScaleHeight  = 1.0f;
+
+  glMatrixMode (GL_MODELVIEW);
+  glPushMatrix();
+  if (!myIs2d)
+  {
+    // retrieve active matrices for project/unproject calls
+    glGetDoublev  (GL_MODELVIEW_MATRIX,  myModelMatrix);
+    glGetDoublev  (GL_PROJECTION_MATRIX, myProjMatrix);
+    glGetIntegerv (GL_VIEWPORT,          myViewport);
+    gluProject (myPoint.x(), myPoint.y(), myPoint.z(),
+                myModelMatrix, myProjMatrix, myViewport,
+                &myWinX, &myWinY, &myWinZ);
+
+    // compute scale factor for constant text height
+    GLdouble x1, y1, z1;
+    gluUnProject (myWinX, myWinY, myWinZ,
+                  (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
+                  &x1, &y1, &z1);
+
+    GLdouble x2, y2, z2;
+    const GLdouble h = (GLdouble )myFont->FTFont()->PointSize();
+    gluUnProject (myWinX, myWinY + h - 1.0, myWinZ,
+                  (GLdouble* )THE_IDENTITY_MATRIX, myProjMatrix, myViewport,
+                  &x2, &y2, &z2);
+
+    myScaleHeight = (y2 - y1) / h;
+    if (theTextAspect.IsZoomable())
+    {
+      myExportHeight = (float )h;
+    }
+  }
+  myExportHeight = (float )myFont->FTFont()->PointSize() / myExportHeight;
+
+  // push enabled flags to the stack
+  glPushAttrib (GL_ENABLE_BIT);
+
+  // setup depth test
+  if (!myIs2d
+   && theTextAspect.StyleType() != Aspect_TOST_ANNOTATION)
+  {
+    glEnable (GL_DEPTH_TEST);
+  }
+  else
+  {
+    glDisable (GL_DEPTH_TEST);
+  }
+
+  // setup alpha test
+  GLint aTexEnvParam = GL_REPLACE;
+  glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
+  if (aTexEnvParam != GL_REPLACE)
+  {
+    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+  }
+  glAlphaFunc (GL_GEQUAL, 0.285f);
+  glEnable (GL_ALPHA_TEST);
+
+  // setup blending
+  glEnable (GL_BLEND);
+  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // GL_ONE
+
+  // activate texture unit
+  glDisable (GL_TEXTURE_1D);
+  glEnable  (GL_TEXTURE_2D);
+  if (theCtx->core13 != NULL)
+  {
+    theCtx->core13->glActiveTexture (GL_TEXTURE0);
+  }
+
+  // extra drawings
+  switch (theTextAspect.DisplayType())
+  {
     case Aspect_TODT_BLEND:
-      glEnable(GL_COLOR_LOGIC_OP);
-      glLogicOp(GL_XOR);
+    {
+      glEnable  (GL_COLOR_LOGIC_OP);
+      glLogicOp (GL_XOR);
       break;
+    }
     case Aspect_TODT_SUBTITLE:
     {
-      int sWidth, sAscent, sDescent;
-      AWorkspace->StringSize(myString, sWidth, sAscent, sDescent);
-
-      objrefX = (float)myAttachPnt.xyz[0];
-      objrefY = (float)myAttachPnt.xyz[1];
-      objrefZ = (float)myAttachPnt.xyz[2];
-      status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
-        &winx1, &winy1, &winz1);
-
-      winx = winx1;
-      winy = winy1-sDescent;
-      winz = winz1+0.00001;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &objX, &objY, &objZ);
-
-      winx = winx1 + sWidth;
-      winy = winy1-sDescent;
-      winz = winz1+0.00001; /* il vaut mieux F+B / 1000000 ? */
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &obj1X, &obj1Y, &obj1Z);
-
-      winx = winx1 + sWidth;
-      winy = winy1 + sAscent;
-      winz = winz1+0.00001;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &obj2X, &obj2Y, &obj2Z);
-
-      winx = winx1;
-      winy = winy1+ sAscent;
-      winz = winz1+0.00001;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &obj3X, &obj3Y, &obj3Z);
-
-      glColor3fv( scolor->rgb );
-      glBegin(GL_POLYGON);
-      glVertex3d(objX, objY, objZ);
-      glVertex3d(obj1X, obj1Y, obj1Z);
-      glVertex3d(obj2X, obj2Y, obj2Z);
-      glVertex3d(obj3X, obj3Y, obj3Z);
+      glColor3fv  (theColorSubs.rgb);
+      setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
+
+      glBindTexture (GL_TEXTURE_2D, 0);
+      glBegin (GL_QUADS);
+      glVertex2f (myBndBox.Left,  myBndBox.Top);
+      glVertex2f (myBndBox.Right, myBndBox.Top);
+      glVertex2f (myBndBox.Right, myBndBox.Bottom);
+      glVertex2f (myBndBox.Left,  myBndBox.Bottom);
       glEnd();
       break;
     }
-
     case Aspect_TODT_DEKALE:
-      objrefX = (float)myAttachPnt.xyz[0];
-      objrefY = (float)myAttachPnt.xyz[1];
-      objrefZ = (float)myAttachPnt.xyz[2];
-      status = gluProject (objrefX, objrefY, objrefZ, modelMatrix, projMatrix, viewport,
-        &winx1, &winy1, &winz1);
-
-      winx = winx1+1;
-      winy = winy1+1;
-      winz = winz1+0.00001;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &objX, &objY, &objZ);
-
-      glColor3fv( scolor->rgb );
-      AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
-      winx = winx1-1;
-      winy = winy1-1;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &objX, &objY, &objZ);
-
-      AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
-      winx = winx1-1;
-      winy = winy1+1;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &objX, &objY, &objZ);
-
-      AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
-      winx = winx1+1;
-      winy = winy1-1;
-      status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
-        &objX, &objY, &objZ);
-      AWorkspace->RenderText( myString, 0, (float)objX, (float)objY,(float)objZ );
+    {
+      glColor3fv  (theColorSubs.rgb);
+      setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
+      drawText    (thePrintCtx, theCtx, theTextAspect);
+      setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
+      drawText    (thePrintCtx, theCtx, theTextAspect);
+      setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
+      drawText    (thePrintCtx, theCtx, theTextAspect);
+      setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
+      drawText    (thePrintCtx, theCtx, theTextAspect);
+      break;
+    }
+    case Aspect_TODT_NORMAL:
+    {
       break;
     }
   }
 
-  glColor3fv( tcolor->rgb );
-  AWorkspace->RenderText( myString, 0, (float)myAttachPnt.xyz[0], (float)myAttachPnt.xyz[1],(float)myAttachPnt.xyz[2] );
-  /* maj attributs */
-  if (flag_zbuffer) glEnable(GL_DEPTH_TEST);
-  if (aspect_text->DisplayType() == Aspect_TODT_BLEND)
-  {
-    glDisable(GL_COLOR_LOGIC_OP);
-  }
-}
+  // main draw call
+  glColor3fv  (theColorText.rgb);
+  setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
+  drawText    (thePrintCtx, theCtx, theTextAspect);
 
-void OpenGl_Text::Release (const Handle(OpenGl_Context)& theContext)
-{
-  //
+  // revert OpenGL state
+  glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
+  glPopAttrib(); // enable bit
+  glPopMatrix(); // model view matrix was modified
 }
index 3251b43..b350488 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-07-13
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef OpenGl_Text_Header
 #define OpenGl_Text_Header
 
 #include <OpenGl_Element.hxx>
 
+#include <OpenGl_AspectText.hxx>
 #include <OpenGl_TextParam.hxx>
+#include <OpenGl_TextFormatter.hxx>
 
 #include <TCollection_ExtendedString.hxx>
 #include <Graphic3d_Vertex.hxx>
 #include <Graphic3d_HorizontalTextAlignment.hxx>
 #include <Graphic3d_VerticalTextAlignment.hxx>
 
+class Handle(OpenGl_PrinterContext);
+
+//! Text rendering
 class OpenGl_Text : public OpenGl_Element
 {
 
 public:
 
-  OpenGl_Text (const TCollection_ExtendedString& AText,
-              const Graphic3d_Vertex& APoint,
-              const Standard_Real AHeight,
-              const Graphic3d_HorizontalTextAlignment AHta,
-              const Graphic3d_VerticalTextAlignment AVta);
+  //! Main constructor
+  Standard_EXPORT OpenGl_Text (const TCollection_ExtendedString& theText,
+                               const OpenGl_Vec3&                thePoint,
+                               const OpenGl_TextParam&           theParams);
+
+  //! Setup new string and position
+  Standard_EXPORT void Init (const Handle(OpenGl_Context)& theCtx,
+                             const Standard_Utf8Char*      theText,
+                             const OpenGl_Vec3&            thePoint);
+
+  //! Setup new string and parameters
+  Standard_EXPORT void Init (const Handle(OpenGl_Context)& theCtx,
+                             const Standard_Utf8Char*      theText,
+                             const OpenGl_Vec3&            thePoint,
+                             const OpenGl_TextParam&       theParams);
+
+  //! Setup new position
+  Standard_EXPORT void SetPosition (const OpenGl_Vec3& thePoint);
+
+  //! Setup new font size
+  Standard_EXPORT void SetFontSize (const Handle(OpenGl_Context)& theContext,
+                                    const Standard_Integer        theFontSize);
+
+  Standard_EXPORT virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  Standard_EXPORT virtual void Release (const Handle(OpenGl_Context)&   theContext);
+
+public: //! @name methods for compatibility with layers
+
+  //! Empty constructor
+  OpenGl_Text();
+
+  //! Create key for shared resource
+  static TCollection_AsciiString FontKey (const OpenGl_AspectText& theAspect,
+                                          const Standard_Integer   theHeight);
+
+  //! Find shared resource for specified font or initialize new one
+  static Handle(OpenGl_Font) FindFont (const Handle(OpenGl_Context)& theCtx,
+                                       const OpenGl_AspectText&      theAspect,
+                                       const Standard_Integer        theHeight,
+                                       const TCollection_AsciiString theKey);
+
+  //! Compute text width
+  static void StringSize (const Handle(OpenGl_Context)& theCtx,
+                          const NCollection_String&     theText,
+                          const OpenGl_AspectText&      theTextAspect,
+                          const OpenGl_TextParam&       theParams,
+                          Standard_ShortReal&           theWidth,
+                          Standard_ShortReal&           theAscent,
+                          Standard_ShortReal&           theDescent);
+
+  //! Setup new string and parameters
+  void Init (const Handle(OpenGl_Context)&     theCtx,
+             const TCollection_ExtendedString& theText,
+             const OpenGl_Vec2&                thePoint,
+             const OpenGl_TextParam&           theParams);
+
+  //! Perform rendering
+  void Render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+               const Handle(OpenGl_Context)&        theCtx,
+               const OpenGl_AspectText&             theTextAspect) const;
+
+protected:
+
+  //! Destructor
+  Standard_EXPORT virtual ~OpenGl_Text();
+
+  friend class OpenGl_Trihedron;
+  friend class OpenGl_GraduatedTrihedron;
+
+private:
+
+  //! Release cached VBO resources
+  void releaseVbos (const Handle(OpenGl_Context)& theCtx);
+
+  //! Setup matrix.
+  void setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                    const Handle(OpenGl_Context)&        theCtx,
+                    const OpenGl_AspectText&             theTextAspect,
+                    const OpenGl_Vec3                    theDVec) const;
+
+  //! Draw arrays of vertices.
+  void drawText (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+                 const Handle(OpenGl_Context)&        theCtx,
+                 const OpenGl_AspectText&             theTextAspect) const;
+
+  //! Main rendering code
+  void render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
+               const Handle(OpenGl_Context)&        theCtx,
+               const OpenGl_AspectText&             theTextAspect,
+               const TEL_COLOUR&                    theColorText,
+               const TEL_COLOUR&                    theColorSubs) const;
+
+protected:
 
-  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
-  virtual void Release (const Handle(OpenGl_Context)&   theContext);
+  mutable Handle(OpenGl_Font)                             myFont;
+  mutable NCollection_Vector<GLuint>                      myTextures;   //!< textures' IDs
+  mutable NCollection_Vector<Handle(OpenGl_VertexBuffer)> myVertsVbo;   //!< VBOs of vertices
+  mutable NCollection_Vector<Handle(OpenGl_VertexBuffer)> myTCrdsVbo;   //!< VBOs of texture coordinates
+  mutable NCollection_Vector<Handle(OpenGl_Vec2Array)>    myVertsArray; //!< arrays of vertices (for compatibility mode)
+  mutable NCollection_Vector<Handle(OpenGl_Vec2Array)>    myTCrdsArray; //!< arrays of vertices (for compatibility mode)
+  mutable Font_FTFont::Rect                               myBndBox;
 
 protected:
 
-  virtual ~OpenGl_Text();
+  mutable GLdouble myProjMatrix[16];
+  mutable GLdouble myModelMatrix[16];
+  mutable GLint    myViewport[4];
+  mutable GLdouble myWinX;
+  mutable GLdouble myWinY;
+  mutable GLdouble myWinZ;
+  mutable GLdouble myScaleHeight;
+  mutable GLdouble myExportHeight;
 
 protected:
 
-  OpenGl_TextParam myParam;
-  TEL_POINT       myAttachPnt;
-  const wchar_t  *myString;
+  OpenGl_TextParam   myParams;
+  NCollection_String myString;
+  OpenGl_Vec3        myPoint;
+  bool               myIs2d;
 
 public:
 
diff --git a/src/OpenGl/OpenGl_TextFormatter.cxx b/src/OpenGl/OpenGl_TextFormatter.cxx
new file mode 100644 (file)
index 0000000..9fcb2b8
--- /dev/null
@@ -0,0 +1,490 @@
+// Created on: 2013-01-29
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OpenGl_TextFormatter.hxx>
+
+#include <OpenGl_VertexBuffer.hxx>
+
+#include <cmath>
+
+namespace
+{
+
+  //! Auxiliary function to translate rectangle by the vector.
+  inline void move (Font_FTFont::Rect& theRect,
+                    const OpenGl_Vec2& theVec)
+  {
+    theRect.Left   += theVec.x();
+    theRect.Right  += theVec.x();
+    theRect.Top    += theVec.y();
+    theRect.Bottom += theVec.y();
+  }
+
+  //! Auxiliary function to translate rectangles by the vector.
+  inline void move (NCollection_Vector<OpenGl_Font::Tile>& theRects,
+                    const OpenGl_Vec2&                     theMoveVec,
+                    Standard_Integer                       theCharLower,
+                    const Standard_Integer                 theCharUpper)
+  {
+    for(; theCharLower <= theCharUpper; ++theCharLower)
+    {
+      Font_FTFont::Rect& aRect = theRects.ChangeValue (theCharLower).px;
+      move (aRect, theMoveVec);
+    }
+  }
+
+  //! Auxiliary function to translate rectangles in horizontal direction.
+  inline void moveX (NCollection_Vector<OpenGl_Font::Tile>& theRects,
+                     const Standard_ShortReal               theMoveVec,
+                     Standard_Integer                       theCharLower,
+                     const Standard_Integer                 theCharUpper)
+  {
+    for (; theCharLower <= theCharUpper; ++theCharLower)
+    {
+      Font_FTFont::Rect& aRect = theRects.ChangeValue (theCharLower).px;
+      aRect.Left  += theMoveVec;
+      aRect.Right += theMoveVec;
+    }
+  }
+
+  //! Auxiliary function to translate rectangles in vertical direction.
+  inline void moveY (NCollection_Vector<OpenGl_Font::Tile>& theRects,
+                     const Standard_ShortReal               theMoveVec,
+                     Standard_Integer                       theCharLower,
+                     const Standard_Integer                 theCharUpper)
+  {
+    for(; theCharLower <= theCharUpper; ++theCharLower)
+    {
+      Font_FTFont::Rect& aRect = theRects.ChangeValue (theCharLower).px;
+      aRect.Top    += theMoveVec;
+      aRect.Bottom += theMoveVec;
+    }
+  }
+
+  //! Apply floor to vector components.
+  //! @param  theVec - vector to change (by reference!)
+  //! @return modified vector
+  inline OpenGl_Vec2& floor (OpenGl_Vec2& theVec)
+  {
+    theVec.x() = std::floor (theVec.x());
+    theVec.y() = std::floor (theVec.y());
+    return theVec;
+  }
+
+};
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_TextFormatter, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_TextFormatter, Standard_Transient)
+
+// =======================================================================
+// function : OpenGl_TextFormatter
+// purpose  :
+// =======================================================================
+OpenGl_TextFormatter::OpenGl_TextFormatter()
+: myAlignX (Graphic3d_HTA_LEFT),
+  myAlignY (Graphic3d_VTA_TOP),
+  myTabSize (8),
+  //
+  myPen (0.0f, 0.0f),
+  myRectsNb (0),
+  myLineSpacing (0.0f),
+  myAscender (0.0f),
+  myIsFormatted (false),
+  //
+  myLinesNb (0),
+  myRectLineStart (0),
+  myRectWordStart (0),
+  myPenCurrLine (0.0f),
+  myLineLeft (0.0f),
+  myLineTail (0.0f),
+  myBndTop   (0.0f),
+  myBndWidth (0.0f),
+  myMoveVec (0.0f, 0.0f)
+{
+  //
+}
+
+// =======================================================================
+// function : SetupAlignment
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::SetupAlignment (const Graphic3d_HorizontalTextAlignment theAlignX,
+                                           const Graphic3d_VerticalTextAlignment   theAlignY)
+{
+  myAlignX = theAlignX;
+  myAlignY = theAlignY;
+}
+
+// =======================================================================
+// function : Reset
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Reset()
+{
+  myIsFormatted = false;
+  myString.Clear();
+  myPen.x() = myPen.y() = 0.0f;
+  myRectsNb = 0;
+  myLineSpacing = myAscender = 0.0f;
+  myRects.Clear();
+  myNewLines.Clear();
+}
+
+// =======================================================================
+// function : Result
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Result (NCollection_Vector<GLuint>& theTextures,
+                                   NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > >& theVertsPerTexture,
+                                   NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > >& theTCrdsPerTexture) const
+{
+  OpenGl_Vec2 aVec (0.0f, 0.0f);
+  theTextures.Clear();
+  theVertsPerTexture.Clear();
+  theTCrdsPerTexture.Clear();
+  for (Standard_Integer aRectIter = 0; aRectIter < myRectsNb; ++aRectIter)
+  {
+    const Font_FTFont::Rect& aRect    = myRects.Value (aRectIter).px;
+    const Font_FTFont::Rect& aRectUV  = myRects.Value (aRectIter).uv;
+    const GLuint             aTexture = myRects.Value (aRectIter).texture;
+
+    Standard_Integer aListId = 0;
+    for (aListId = 0; aListId < theTextures.Length(); ++aListId)
+    {
+      if (theTextures.Value (aListId) == aTexture)
+      {
+        break;
+      }
+    }
+    if (aListId >= theTextures.Length())
+    {
+      theTextures.Append (aTexture);
+      theVertsPerTexture.Append (new NCollection_Vector<OpenGl_Vec2>());
+      theTCrdsPerTexture.Append (new NCollection_Vector<OpenGl_Vec2>());
+    }
+
+    NCollection_Vector<OpenGl_Vec2>& aVerts = *theVertsPerTexture.ChangeValue (aListId);
+    NCollection_Vector<OpenGl_Vec2>& aTCrds = *theTCrdsPerTexture.ChangeValue (aListId);
+
+    // apply floor on position to avoid blurring issues
+    // due to cross-pixel coordinates
+    aVerts.Append (floor(aRect.BottomLeft (aVec)));
+    aVerts.Append (floor(aRect.TopLeft    (aVec)));
+    aVerts.Append (floor(aRect.TopRight   (aVec)));
+    aTCrds.Append (aRectUV.BottomLeft (aVec));
+    aTCrds.Append (aRectUV.TopLeft    (aVec));
+    aTCrds.Append (aRectUV.TopRight   (aVec));
+
+    aVerts.Append (floor(aRect.BottomLeft  (aVec)));
+    aVerts.Append (floor(aRect.TopRight    (aVec)));
+    aVerts.Append (floor(aRect.BottomRight (aVec)));
+    aTCrds.Append (aRectUV.BottomLeft  (aVec));
+    aTCrds.Append (aRectUV.TopRight    (aVec));
+    aTCrds.Append (aRectUV.BottomRight (aVec));
+  }
+}
+
+// =======================================================================
+// function : Result
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Result (const Handle(OpenGl_Context)&                    theCtx,
+                                   NCollection_Vector<GLuint>&                      theTextures,
+                                   NCollection_Vector<Handle(OpenGl_VertexBuffer)>& theVertsPerTexture,
+                                   NCollection_Vector<Handle(OpenGl_VertexBuffer)>& theTCrdsPerTexture) const
+{
+  NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > > aVertsPerTexture;
+  NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > > aTCrdsPerTexture;
+  Result (theTextures, aVertsPerTexture, aTCrdsPerTexture);
+
+  if (theVertsPerTexture.Length() != theTextures.Length())
+  {
+    for (Standard_Integer aTextureIter = 0; aTextureIter < theVertsPerTexture.Length(); ++aTextureIter)
+    {
+      theVertsPerTexture.Value (aTextureIter)->Release (theCtx.operator->());
+      theTCrdsPerTexture.Value (aTextureIter)->Release (theCtx.operator->());
+    }
+    theVertsPerTexture.Clear();
+    theTCrdsPerTexture.Clear();
+
+    while (theVertsPerTexture.Length() < theTextures.Length())
+    {
+      Handle(OpenGl_VertexBuffer) aVertsVbo = new OpenGl_VertexBuffer();
+      Handle(OpenGl_VertexBuffer) aTcrdsVbo = new OpenGl_VertexBuffer();
+      theVertsPerTexture.Append (aVertsVbo);
+      theTCrdsPerTexture.Append (aTcrdsVbo);
+      aVertsVbo->Create (theCtx);
+      aTcrdsVbo->Create (theCtx);
+    }
+  }
+
+  for (Standard_Integer aTextureIter = 0; aTextureIter < theTextures.Length(); ++aTextureIter)
+  {
+    const NCollection_Vector<OpenGl_Vec2>& aVerts = *aVertsPerTexture.Value (aTextureIter);
+    Handle(OpenGl_VertexBuffer)& aVertsVbo = theVertsPerTexture.ChangeValue (aTextureIter);
+    if (!aVertsVbo->Init (theCtx, 2, aVerts.Length(), (GLfloat* )NULL)
+     || !myVboEditor.Init (theCtx, aVertsVbo))
+    {
+      continue;
+    }
+    for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter, myVboEditor.Next())
+    {
+      myVboEditor.Value() = aVerts.Value (aVertIter);
+    }
+    myVboEditor.Flush();
+
+    const NCollection_Vector<OpenGl_Vec2>& aTCrds = *aTCrdsPerTexture.Value (aTextureIter);
+    Handle(OpenGl_VertexBuffer)& aTCrdsVbo = theTCrdsPerTexture.ChangeValue (aTextureIter);
+    if (!aTCrdsVbo->Init (theCtx, 2, aVerts.Length(), (GLfloat* )NULL)
+     || !myVboEditor.Init (theCtx, aTCrdsVbo))
+    {
+      continue;
+    }
+    for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter, myVboEditor.Next())
+    {
+      myVboEditor.Value() = aTCrds.Value (aVertIter);
+    }
+    myVboEditor.Flush();
+  }
+  myVboEditor.Init (NULL, NULL);
+}
+
+// =======================================================================
+// function : Result
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Result (const Handle(OpenGl_Context)&                 theCtx,
+                                   NCollection_Vector<GLuint>&                   theTextures,
+                                   NCollection_Vector<Handle(OpenGl_Vec2Array)>& theVertsPerTexture,
+                                   NCollection_Vector<Handle(OpenGl_Vec2Array)>& theTCrdsPerTexture) const
+{
+  NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > > aVertsPerTexture;
+  NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > > aTCrdsPerTexture;
+  Result (theTextures, aVertsPerTexture, aTCrdsPerTexture);
+
+  theVertsPerTexture.Clear();
+  theTCrdsPerTexture.Clear();
+
+  for (Standard_Integer aTextureIter = 0; aTextureIter < theTextures.Length(); ++aTextureIter)
+  {
+    const NCollection_Vector<OpenGl_Vec2>& aVerts = *aVertsPerTexture.Value (aTextureIter);
+    const NCollection_Vector<OpenGl_Vec2>& aTCrds = *aTCrdsPerTexture.Value (aTextureIter);
+    Handle(OpenGl_Vec2Array) aVertsArray = new OpenGl_Vec2Array (1, aVerts.Length());
+    Handle(OpenGl_Vec2Array) aTCrdsArray = new OpenGl_Vec2Array (1, aVerts.Length());
+    theVertsPerTexture.Append (aVertsArray);
+    theTCrdsPerTexture.Append (aTCrdsArray);
+
+    for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter)
+    {
+      aVertsArray->ChangeValue (aVertIter + 1) = aVerts.Value (aVertIter);
+    }
+    for (Standard_Integer aVertIter = 0; aVertIter < aVerts.Length(); ++aVertIter)
+    {
+      aTCrdsArray->ChangeValue (aVertIter + 1) = aTCrds.Value (aVertIter);
+    }
+  }
+}
+
+// =======================================================================
+// function : Append
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Append (const Handle(OpenGl_Context)& theCtx,
+                                   const NCollection_String&     theString,
+                                   OpenGl_Font&                  theFont)
+{
+  if (theString.IsEmpty())
+  {
+    return;
+  }
+
+  myAscender    = Max (myAscender,    theFont.Ascender());
+  myLineSpacing = Max (myLineSpacing, theFont.LineSpacing());
+  myString     += theString;
+
+  int aSymbolsCounter = 0; // special counter to process tabulation symbols
+
+  // first pass - render all symbols using associated font on single ZERO baseline
+  OpenGl_Font::Tile aTile;
+  memset (&aTile, 0, sizeof(aTile));
+  for (NCollection_Utf8Iter anIter = theString.Iterator(); *anIter != 0;)
+  {
+    const Standard_Utf32Char aCharThis =   *anIter;
+    const Standard_Utf32Char aCharNext = *++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)
+    {
+      aSymbolsCounter = 0;
+      myNewLines.Append (myPen.x());
+      continue; // will be processed on second pass
+    }
+    else if (aCharThis == ' ')
+    {
+      ++aSymbolsCounter;
+      myPen.x() += theFont.AdvanceX (' ', aCharNext);
+      continue;
+    }
+    else if (aCharThis == '\t')
+    {
+      const Standard_Integer aSpacesNum = (myTabSize - (aSymbolsCounter - 1) % myTabSize);
+      myPen.x() += theFont.AdvanceX (' ', aCharNext) * Standard_ShortReal(aSpacesNum);
+      aSymbolsCounter += aSpacesNum;
+      continue;
+    }
+
+    ++aSymbolsCounter;
+    theFont.RenderGlyph (theCtx,
+                         aCharThis, aCharNext,
+                         aTile, myPen);
+    myRects.Append (aTile);
+
+    ++myRectsNb;
+  }
+}
+
+// =======================================================================
+// function : newLine
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::newLine (const Standard_Integer theLastRect)
+{
+  if (myRectLineStart >= myRectsNb)
+  {
+    ++myLinesNb;
+    myPenCurrLine -= myLineSpacing;
+    return;
+  }
+
+  myMoveVec.y() = myPenCurrLine;
+  switch (myAlignX)
+  {
+    default:
+    case Graphic3d_HTA_LEFT:
+    {
+      myMoveVec.x() = (myNewLineNb > 0) ? -myNewLines.Value (myNewLineNb - 1) : 0.0f;
+      break;
+    }
+    case Graphic3d_HTA_RIGHT:
+    {
+      myMoveVec.x() = (myNewLineNb < myNewLines.Length())
+                    ? -myNewLines.Value (myNewLineNb)
+                    : -myPen.x();
+      break;
+    }
+    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;
+    }
+  }
+
+  move (myRects, myMoveVec, myRectLineStart, theLastRect);
+
+  ++myLinesNb;
+  myPenCurrLine -= myLineSpacing;
+  myRectLineStart = myRectWordStart = theLastRect + 1;
+  if (myRectLineStart < myRectsNb)
+  {
+    myLineLeft = myRects.Value (myRectLineStart).px.Left;
+  }
+}
+
+// =======================================================================
+// function : Format
+// purpose  :
+// =======================================================================
+void OpenGl_TextFormatter::Format()
+{
+  if (myRectsNb == 0 || myIsFormatted)
+  {
+    return;
+  }
+
+  myIsFormatted = true;
+  myLinesNb = myRectLineStart = myRectWordStart = 0;
+  myLineLeft   = 0.0f;
+  myLineTail   = 0.0f;
+  myBndTop     = 0.0f;
+  myBndWidth   = 0.0f;
+  myMoveVec.x() = myMoveVec.y() = 0.0f;
+
+  // split text into lines and apply horizontal alignment
+  myPenCurrLine = -myAscender;
+  Standard_Integer aRectIter = 0;
+  myNewLineNb = 0;
+  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)
+    {
+      const Standard_Integer aLastRect = aRectIter - 1; // last rect on current line
+      newLine (aLastRect);
+      ++myNewLineNb;
+      continue;
+    }
+    else if (aCharThis == ' '
+          || aCharThis == '\t')
+    {
+      myRectWordStart = aRectIter;
+      continue;
+    }
+
+    Standard_ShortReal aWidth = myRects.Value (aRectIter).px.Right - myLineLeft;
+    myBndWidth = Max (myBndWidth, aWidth);
+
+    ++aRectIter;
+  }
+
+  // move last line
+  newLine (myRectsNb - 1);
+
+  // apply vertical alignment style
+  if (myAlignY == Graphic3d_VTA_BOTTOM)
+  {
+    myBndTop = -myLineSpacing - myPenCurrLine;
+    moveY (myRects, myBndTop, 0, myRectsNb - 1);
+  }
+  else if (myAlignY == Graphic3d_VTA_CENTER)
+  {
+    myBndTop = 0.5f * (myLineSpacing * Standard_ShortReal(myLinesNb));
+    moveY (myRects, myBndTop, 0, myRectsNb - 1);
+  }
+}
diff --git a/src/OpenGl/OpenGl_TextFormatter.hxx b/src/OpenGl/OpenGl_TextFormatter.hxx
new file mode 100644 (file)
index 0000000..efd5935
--- /dev/null
@@ -0,0 +1,158 @@
+// Created on: 2013-01-29
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_TextFormatter_H__
+#define _OpenGl_TextFormatter_H__
+
+#include <OpenGl_Font.hxx>
+#include <OpenGl_VertexBufferEditor.hxx>
+
+#include <Graphic3d_HorizontalTextAlignment.hxx>
+#include <Graphic3d_VerticalTextAlignment.hxx>
+
+#include <NCollection_String.hxx>
+
+typedef NCollection_Array1<OpenGl_Vec2> OpenGl_Vec2Array;
+typedef NCollection_Handle<OpenGl_Vec2Array> Handle(OpenGl_Vec2Array);
+
+//! This class intended to prepare formatted text.
+class OpenGl_TextFormatter : public Standard_Transient
+{
+
+public:
+
+  //! Default constructor.
+  Standard_EXPORT OpenGl_TextFormatter();
+
+  //! Setup alignment style.
+  Standard_EXPORT void SetupAlignment (const Graphic3d_HorizontalTextAlignment theAlignX,
+                                       const Graphic3d_VerticalTextAlignment   theAlignY);
+
+  //! Reset current progress.
+  Standard_EXPORT void Reset();
+
+  //! Render specified text to inner buffer.
+  Standard_EXPORT void Append (const Handle(OpenGl_Context)& theCtx,
+                               const NCollection_String&     theString,
+                               OpenGl_Font&                  theFont);
+
+  //! Perform formatting on the buffered text.
+  //! Should not be called more than once after initialization!
+  Standard_EXPORT void Format();
+
+  //! Retrieve formatting results.
+  Standard_EXPORT void Result (NCollection_Vector<GLuint>& theTextures,
+                               NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > >& theVertsPerTexture,
+                               NCollection_Vector< NCollection_Handle <NCollection_Vector <OpenGl_Vec2> > >& theTCrdsPerTexture) const;
+
+  //! Retrieve formatting results.
+  Standard_EXPORT void Result (const Handle(OpenGl_Context)&                    theCtx,
+                               NCollection_Vector<GLuint>&                      theTextures,
+                               NCollection_Vector<Handle(OpenGl_VertexBuffer)>& theVertsPerTexture,
+                               NCollection_Vector<Handle(OpenGl_VertexBuffer)>& theTCrdsPerTexture) const;
+
+  //! Retrieve formatting results.
+  Standard_EXPORT void Result (const Handle(OpenGl_Context)&                 theCtx,
+                               NCollection_Vector<GLuint>&                   theTextures,
+                               NCollection_Vector<Handle(OpenGl_Vec2Array)>& theVertsPerTexture,
+                               NCollection_Vector<Handle(OpenGl_Vec2Array)>& theTCrdsPerTexture) const;
+
+  //! @return width of formatted text.
+  inline Standard_ShortReal ResultWidth() const
+  {
+    return myBndWidth;
+  }
+
+  //! @return height of formatted text.
+  inline Standard_ShortReal ResultHeight() const
+  {
+    return myLineSpacing * Standard_ShortReal(myLinesNb);
+  }
+
+  //! @param bounding box.
+  inline void BndBox (Font_FTFont::Rect& theBndBox) const
+  {
+    theBndBox.Left = 0.0f;
+    switch (myAlignX)
+    {
+      default:
+      case Graphic3d_HTA_LEFT:  theBndBox.Right  =  myBndWidth; break;
+      case Graphic3d_HTA_RIGHT: theBndBox.Right  = -myBndWidth; break;
+      case Graphic3d_HTA_CENTER:
+      {
+        theBndBox.Left  = -0.5f * myBndWidth;
+        theBndBox.Right =  0.5f * myBndWidth;
+        break;
+      }
+    }
+    theBndBox.Top    = myBndTop;
+    theBndBox.Bottom = theBndBox.Top - myLineSpacing * Standard_ShortReal(myLinesNb);
+  }
+
+protected: //! @name class auxiliary methods
+
+  //! Move glyphs on the current line to correct position.
+  Standard_EXPORT void newLine (const Standard_Integer theLastRect);
+
+protected: //! @name configuration
+
+  Graphic3d_HorizontalTextAlignment myAlignX;  //!< horizontal alignment style
+  Graphic3d_VerticalTextAlignment   myAlignY;  //!< vertical   alignment style
+  Standard_Integer                  myTabSize; //!< horizontal tabulation width (number of space symbols)
+
+protected: //! @name input data
+
+  NCollection_String myString;        //!< currently rendered text
+  OpenGl_Vec2        myPen;           //!< current pen position
+  NCollection_Vector<OpenGl_Font::Tile>
+                     myRects;         //!< glyphs rectangles
+  Standard_Integer   myRectsNb;       //!< rectangles number
+  NCollection_Vector<Standard_ShortReal>
+                     myNewLines;      //!< position at LF
+  Standard_ShortReal myLineSpacing;   //!< line spacing (computed as maximum of all fonts involved in text formatting)
+  Standard_ShortReal myAscender;      //!<
+  bool               myIsFormatted;   //!< formatting state
+
+protected:
+
+  mutable OpenGl_VertexBufferEditor<OpenGl_Vec2> myVboEditor;
+
+protected: //! @name temporary variables for formatting routines
+
+  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   myRectWordStart; //!< id of first rectangle in the current word
+  Standard_Integer   myNewLineNb;
+
+  Standard_ShortReal myPenCurrLine;   //!< current baseline position
+  Standard_ShortReal myLineLeft;      //!< left x position of first glyph on line before formatting applied
+  Standard_ShortReal myLineTail;
+  Standard_ShortReal myBndTop;
+  Standard_ShortReal myBndWidth;
+  OpenGl_Vec2        myMoveVec;       //!< local variable
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_TextFormatter) // Type definition
+
+};
+
+DEFINE_STANDARD_HANDLE(OpenGl_TextFormatter, Standard_Transient)
+
+#endif // _OpenGl_TextFormatter_H__
index 08e7e10..b7c9c32 100644 (file)
 IMPLEMENT_STANDARD_HANDLE (OpenGl_Texture, OpenGl_Resource)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_Resource)
 
-//! Function for getting power of to number larger or equal to input number.
-//! @param theNumber    number to 'power of two'
-//! @param theThreshold upper threshold
-//! @return power of two number
-inline GLsizei getPowerOfTwo (const GLsizei theNumber,
-                              const GLsizei theThreshold)
-{
-  for (GLsizei p2 = 2; p2 <= theThreshold; p2 <<= 1)
-  {
-    if (theNumber <= p2)
-    {
-      return p2;
-    }
-  }
-  return theThreshold;
-}
-
 // =======================================================================
 // function : OpenGl_Texture
 // purpose  :
@@ -295,8 +278,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
   // Trying to create NPOT rextures on such hardware will not fail
   // but driver will fall back into software rendering,
   const bool    toForceP2  = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
-  const GLsizei aWidthOut  = toForceP2 ? getPowerOfTwo (aWidth,  aMaxSize) : Min (aWidth,  aMaxSize);
-  const GLsizei aHeightOut = toForceP2 ? getPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
+  const GLsizei aWidthOut  = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth,  aMaxSize) : Min (aWidth,  aMaxSize);
+  const GLsizei aHeightOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
 
   GLint aTestWidth  = 0;
   GLint aTestHeight = 0;
@@ -342,6 +325,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       glTexImage1D (GL_TEXTURE_1D, 0, aTextureFormat,
                     aWidthOut, 0,
                     aPixelFormat, aDataType, aDataPtr);
+      if (glGetError() != GL_NO_ERROR)
+      {
+        Unbind (theCtx);
+        return false;
+      }
+
+      mySizeX = aWidthOut;
+      mySizeY = 1;
 
       Unbind (theCtx);
       return true;
@@ -386,6 +377,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
       glTexImage2D (GL_TEXTURE_2D, 0, aTextureFormat,
                     aWidthOut, aHeightOut, 0,
                     aPixelFormat, aDataType, aDataPtr);
+      if (glGetError() != GL_NO_ERROR)
+      {
+        Unbind (theCtx);
+        return false;
+      }
+
+      mySizeX = aWidthOut;
+      mySizeY = aHeightOut;
 
       Unbind (theCtx);
       return true;
@@ -418,6 +417,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
         glTexImage2D (GL_TEXTURE_2D, 0, aTextureFormat,
                       aWidthOut, aHeightOut, 0,
                       aPixelFormat, aDataType, theImage.Data());
+        if (glGetError() != GL_NO_ERROR)
+        {
+          Unbind (theCtx);
+          return false;
+        }
+
+        mySizeX = aWidthOut;
+        mySizeY = aHeightOut;
 
         // generate mipmaps
         //glHint (GL_GENERATE_MIPMAP_HINT, GL_NICEST);
@@ -431,6 +438,12 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
         bool isCreated = gluBuild2DMipmaps (GL_TEXTURE_2D, aTextureFormat,
                                             aWidth, aHeight,
                                             aPixelFormat, aDataType, theImage.Data()) == 0;
+        if (isCreated)
+        {
+          glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,  &mySizeX);
+          glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &mySizeY);
+        }
+
         Unbind (theCtx);
         return isCreated;
       }
index 6e9c5e0..64f45aa 100644 (file)
@@ -58,6 +58,24 @@ public:
     return myTarget;
   }
 
+  //! @return texture width (0 LOD)
+  inline GLsizei SizeX() const
+  {
+    return mySizeX;
+  }
+
+  //! @return texture height (0 LOD)
+  inline GLsizei SizeY() const
+  {
+    return mySizeY;
+  }
+
+  //! @return texture ID
+  inline GLuint TextureId() const
+  {
+    return myTextureId;
+  }
+
   //! Creates Texture id if not yet generated.
   //! Data should be initialized by another method.
   Standard_EXPORT bool Create (const Handle(OpenGl_Context)& theCtx);
index 30e2450..e367c7d 100644 (file)
@@ -17,7 +17,6 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #include <OpenGl_GlCore11.hxx>
 
 #include <stddef.h>
 #include <OpenGl_View.hxx>
 #include <OpenGl_Trihedron.hxx>
 
-IMPLEMENT_STANDARD_HANDLE(OpenGl_Trihedron,MMgt_TShared)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Trihedron,MMgt_TShared)
+static const OpenGl_TextParam THE_LABEL_PARAMS =
+{
+  16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
+};
 
 static const CALL_DEF_CONTEXTLINE myDefaultContextLine =
 {
@@ -89,10 +90,10 @@ static int   theNbFacettes = 12;
 */
 
 //call_triedron_redraw
-void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const Standard_Real U = AWorkspace->ActiveView()->Height();
-  const Standard_Real V = AWorkspace->ActiveView()->Width();
+  const Standard_Real U = theWorkspace->ActiveView()->Height();
+  const Standard_Real V = theWorkspace->ActiveView()->Width();
 
   /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
   /* de la dimension la plus petite de la window.                    */
@@ -157,7 +158,7 @@ void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
   /*
   * Creation du triedre
   */
-  const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
+  const OpenGl_AspectLine *AspectLine = theWorkspace->AspectLine( Standard_True );
 
   /* Fotis Sioutis 2007-11-14 15:06
   I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode
@@ -258,15 +259,13 @@ void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
   }
   glEnd();
 
-  /*
-  * Noms des axes et de l'origine
-  */
-  const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
-  glColor3fv (AspectText->Color().rgb);
-
-  AWorkspace->RenderText (L"X", 0, float(L + rayon),    0.0f,                   float(-rayon));
-  AWorkspace->RenderText (L"Y", 0, float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon));
-  AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon));
+  // draw axes labels
+  myLabelX.SetPosition (OpenGl_Vec3(float(L + rayon),    0.0f,                   float(-rayon)));
+  myLabelY.SetPosition (OpenGl_Vec3(float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon)));
+  myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon)));
+  myLabelX.Render (theWorkspace);
+  myLabelY.Render (theWorkspace);
+  myLabelZ.Render (theWorkspace);
 
   /*
   * restauration du contexte des matrices
@@ -282,10 +281,10 @@ void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
 *  Draws ZBUFFER trihedron mode
 *******************************************************/
 //call_zbuffer_triedron_redraw
-void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace) const
+void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const Standard_Real U = AWorkspace->ActiveView()->Height();
-  const Standard_Real V = AWorkspace->ActiveView()->Width();
+  const Standard_Real U = theWorkspace->ActiveView()->Height();
+  const Standard_Real V = theWorkspace->ActiveView()->Width();
 
   GLdouble modelMatrix[4][4];
   glGetDoublev( GL_MODELVIEW_MATRIX,  (GLdouble *) modelMatrix );
@@ -351,7 +350,7 @@ void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace
     L *= myRatio;
   }
 
-  const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
+  const OpenGl_AspectLine *AspectLine = theWorkspace->AspectLine( Standard_True );
   const TEL_COLOUR &aLineColor = AspectLine->Color();
 
   /*
@@ -529,15 +528,13 @@ void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace
 
   glDisable(GL_LIGHTING);
 
-  /*
-  * origine names
-  */
-  const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
-  glColor3fv (AspectText->Color().rgb);
-
-  AWorkspace->RenderText (L"X", 0, float(L + rayon),    0.0f,                   float(-rayon));
-  AWorkspace->RenderText (L"Y", 0, float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon));
-  AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon));
+  // draw axes labels
+  myLabelX.SetPosition (OpenGl_Vec3(float(L + rayon),    0.0f,                   float(-rayon)));
+  myLabelY.SetPosition (OpenGl_Vec3(float(rayon),        float(L + 3.0 * rayon), float(2.0 * rayon)));
+  myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon), float(0.5 * rayon),     float(L + 3.0 * rayon)));
+  myLabelX.Render (theWorkspace);
+  myLabelY.Render (theWorkspace);
+  myLabelZ.Render (theWorkspace);
 
   /*PCD 17/06/07    */
   glDepthFunc(df);
@@ -565,15 +562,20 @@ void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace
 */
 
 //call_triedron_init
-OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
-                                  const Standard_Real AScale, const Standard_Boolean AsWireframe)
-: myPos(APosition),
-  myScale(AScale),
-  myIsWireframe(AsWireframe)
+OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition thePosition,
+                                    const Quantity_NameOfColor          theColor,
+                                    const Standard_Real                 theScale,
+                                    const Standard_Boolean              theAsWireframe)
+: myPos (thePosition),
+  myScale (theScale),
+  myIsWireframe (theAsWireframe),
+  myLabelX (TCollection_ExtendedString ("X"), OpenGl_Vec3(1.0f, 0.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelY (TCollection_ExtendedString ("Y"), OpenGl_Vec3(0.0f, 1.0f, 0.0f), THE_LABEL_PARAMS),
+  myLabelZ (TCollection_ExtendedString ("Z"), OpenGl_Vec3(0.0f, 0.0f, 1.0f), THE_LABEL_PARAMS)
 {
   Standard_Real R,G,B;
-  Quantity_Color Color(AColor);
-  Color.Values(R,G,B,Quantity_TOC_RGB);
+  Quantity_Color aColor (theColor);
+  aColor.Values (R, G, B, Quantity_TOC_RGB);
 
   CALL_DEF_CONTEXTLINE aContextLine = myDefaultContextLine;
   aContextLine.Color.r = (float)R;
@@ -603,8 +605,19 @@ OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APositio
 */
 
 //call_triedron_erase
-OpenGl_Trihedron::~OpenGl_Trihedron ()
+OpenGl_Trihedron::~OpenGl_Trihedron()
+{
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_Trihedron::Release (const Handle(OpenGl_Context)& theCtx)
 {
+  myLabelX.Release (theCtx);
+  myLabelY.Release (theCtx);
+  myLabelZ.Release (theCtx);
 }
 
 /*----------------------------------------------------------------------*/
@@ -640,11 +653,11 @@ void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) con
 
   if (myIsWireframe)
   {
-    Redraw (theWorkspace);
+    redraw (theWorkspace);
   }
   else
   {
-    RedrawZBuffer (theWorkspace);
+    redrawZBuffer (theWorkspace);
   }
 
   // restore aspects
index b282246..547536b 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2011-09-20
 // Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Copyright (c) 2011-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
 #ifndef _OpenGl_Trihedron_Header
 #define _OpenGl_Trihedron_Header
 
-#include <Handle_OpenGl_Trihedron.hxx>
+#include <OpenGl_Element.hxx>
 
-#include <Quantity_NameOfColor.hxx>
 #include <Aspect_TypeOfTriedronPosition.hxx>
-
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_AspectText.hxx>
+#include <OpenGl_Text.hxx>
+#include <Quantity_NameOfColor.hxx>
 
-class OpenGl_Trihedron : public MMgt_TShared
+class OpenGl_Trihedron : public OpenGl_Element
 {
- public:
-  OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor, const Standard_Real AScale, const Standard_Boolean AsWireframe);
-  virtual ~OpenGl_Trihedron ();
+public:
+
+  static void Setup (const Quantity_NameOfColor theXColor,
+                     const Quantity_NameOfColor theYColor,
+                     const Quantity_NameOfColor theZColor,
+                     const Standard_Real        theSizeRatio,
+                     const Standard_Real        theAxisDiametr,
+                     const Standard_Integer     theNbFacettes);
 
-  static void Setup (const Quantity_NameOfColor XColor, const Quantity_NameOfColor YColor, const Quantity_NameOfColor ZColor,
-                     const Standard_Real SizeRatio, const Standard_Real AxisDiametr, const Standard_Integer NbFacettes);
+public:
 
-  void Render (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition thePosition,
+                    const Quantity_NameOfColor          theColor,
+                    const Standard_Real                 theScale,
+                    const Standard_Boolean              theAsWireframe);
 
-  // Type definition
-  //
-  DEFINE_STANDARD_RTTI(OpenGl_Trihedron)
+  virtual void Render  (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  virtual void Release (const Handle(OpenGl_Context)&   theCtx);
 
- protected:
+protected:
 
-  void Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const;
-  void RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace) const;
+  virtual ~OpenGl_Trihedron();
+
+  void redraw        (const Handle(OpenGl_Workspace)& theWorkspace) const;
+  void redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
+protected:
 
   Aspect_TypeOfTriedronPosition myPos;
   Standard_Real myScale;
@@ -60,11 +69,16 @@ class OpenGl_Trihedron : public MMgt_TShared
   float myDiameter;
   int   myNbFacettes;
 
-  OpenGl_AspectLine myAspectLine;
-  OpenGl_AspectText myAspectText;
+  OpenGl_AspectLine   myAspectLine;
+  OpenGl_AspectText   myAspectText;
+  mutable OpenGl_Text myLabelX;
+  mutable OpenGl_Text myLabelY;
+  mutable OpenGl_Text myLabelZ;
+
+public:
 
- public:
   DEFINE_STANDARD_ALLOC
+
 };
 
 #endif //_OpenGl_Trihedron_Header
similarity index 67%
rename from src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx
rename to src/OpenGl/OpenGl_Vec.hxx
index c5b9086..d659fe3 100644 (file)
@@ -1,6 +1,6 @@
-// Created on: 2011-09-20
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2012 OPEN CASCADE SAS
+// Created on: 2013-01-29
+// Created by: Kirill GAVRILOV
+// Copyright (c) 2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#ifndef _OpenGl_Vec_H__
+#define _OpenGl_Vec_H__
 
-#ifndef _Handle_OpenGl_GraduatedTrihedron_Header
-#define _Handle_OpenGl_GraduatedTrihedron_Header
+#include <NCollection_Vec4.hxx>
 
-#include <Standard_DefineHandle.hxx>
-#include <Handle_MMgt_TShared.hxx>
+typedef NCollection_Vec2<float> OpenGl_Vec2;
+typedef NCollection_Vec3<float> OpenGl_Vec3;
+typedef NCollection_Vec4<float> OpenGl_Vec4;
 
-class OpenGl_GraduatedTrihedron;
-
-// Handle definition
-//
-DEFINE_STANDARD_HANDLE(OpenGl_GraduatedTrihedron,MMgt_TShared)
-
-
-#endif //_Handle_OpenGl_GraduatedTrihedron_Header
+#endif // _OpenGl_Vec_H__
index b150cb8..eacf141 100644 (file)
@@ -78,36 +78,37 @@ public:
   //! Modify current element in VBO.
   theVec_t& Value()
   {
-      return myTmpBuffer.ChangeValue (myElemsNb);
+    return myTmpBuffer.ChangeValue (myElemsNb);
   }
 
   //! Move to the next position in VBO.
   Standard_Boolean Next()
   {
-      if (++myElemsNb > myTmpBuffer.Upper())
-      {
-          return Flush();
-      }
-      return Standard_True;
+    if (++myElemsNb > myTmpBuffer.Upper())
+    {
+      return Flush();
+    }
+    return Standard_True;
   }
 
   //! Push current data from local buffer to VBO.
   Standard_Boolean Flush()
   {
-      if (myElemsNb <= 0)
-      {
-          return Standard_True;
-      }
-
-      if (!myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
-      {
-          // should never happens
-          return Standard_False;
-      }
-      myElemFrom += myElemsNb;
-      myElemsNb = 0;
-
+    if (myElemsNb <= 0)
+    {
       return Standard_True;
+    }
+
+    if (myVbo.IsNull()
+     || !myVbo->SubData (myGlCtx, myElemFrom, myElemsNb, &myTmpBuffer.Value (0)[0]))
+    {
+      // should never happens
+      return Standard_False;
+    }
+    myElemFrom += myElemsNb;
+    myElemsNb = 0;
+
+    return Standard_True;
   }
 
 private:
index 355108a..9eae330 100644 (file)
@@ -132,6 +132,8 @@ OpenGl_View::~OpenGl_View ()
 
 void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
 {
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
   if (!myTextureEnv.IsNull())
   {
     theCtx->DelayedRelease (myTextureEnv);
@@ -487,31 +489,37 @@ void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
-                                  const Standard_Real AScale, const Standard_Boolean AsWireframe)
+void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)&       theCtx,
+                                   const Aspect_TypeOfTriedronPosition thePosition,
+                                   const Quantity_NameOfColor          theColor,
+                                   const Standard_Real                 theScale,
+                                   const Standard_Boolean              theAsWireframe)
 {
-  myTrihedron = new OpenGl_Trihedron (APosition, AColor, AScale, AsWireframe);
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
+  myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::TriedronErase ()
+void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  myTrihedron.Nullify();
+  OpenGl_Element::Destroy (theCtx, myTrihedron);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &data)
+void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&        theCtx,
+                                             const Graphic3d_CGraduatedTrihedron& theData)
 {
-  myGraduatedTrihedron = new OpenGl_GraduatedTrihedron(data);
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
+  myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
 }
 
 /*----------------------------------------------------------------------*/
 
-void OpenGl_View::GraduatedTrihedronErase ()
+void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
 {
-  myGraduatedTrihedron.Nullify();
+  OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
 }
 
 /*----------------------------------------------------------------------*/
index 49ab5bc..a70b81b 100644 (file)
@@ -44,8 +44,6 @@
 #include <OpenGl_Light.hxx>
 
 #include <Handle_OpenGl_Context.hxx>
-#include <Handle_OpenGl_Trihedron.hxx>
-#include <Handle_OpenGl_GraduatedTrihedron.hxx>
 #include <Handle_OpenGl_Workspace.hxx>
 #include <Handle_OpenGl_View.hxx>
 #include <Handle_OpenGl_Texture.hxx>
@@ -100,7 +98,10 @@ struct OPENGL_FOG
   TEL_COLOUR         Color;
 };
 
+class OpenGl_GraduatedTrihedron;
 class OpenGl_Structure;
+class OpenGl_Trihedron;
+class Handle(OpenGl_PrinterContext);
 
 class OpenGl_View : public MMgt_TShared
 {
@@ -125,11 +126,16 @@ class OpenGl_View : public MMgt_TShared
 
   void SetFog (const Graphic3d_CView& theCView, const Standard_Boolean theFlag);
 
-  void TriedronDisplay (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor, const Standard_Real AScale, const Standard_Boolean AsWireframe);
-  void TriedronErase ();
+  void TriedronDisplay (const Handle(OpenGl_Context)&       theCtx,
+                        const Aspect_TypeOfTriedronPosition thePosition,
+                        const Quantity_NameOfColor          theColor,
+                        const Standard_Real                 theScale,
+                        const Standard_Boolean              theAsWireframe);
+  void TriedronErase (const Handle(OpenGl_Context)& theCtx);
 
-  void GraduatedTrihedronDisplay (const Graphic3d_CGraduatedTrihedron &ACubic);
-  void GraduatedTrihedronErase ();
+  void GraduatedTrihedronDisplay (const Handle(OpenGl_Context)&        theCtx,
+                                  const Graphic3d_CGraduatedTrihedron& theCubic);
+  void GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx);
 
   Standard_Boolean ProjectObjectToRaster (const Standard_Integer w, const Standard_Integer h,
                                           const Standard_ShortReal x, const Standard_ShortReal y, const Standard_ShortReal z,
@@ -180,19 +186,23 @@ class OpenGl_View : public MMgt_TShared
   void SetBackgroundGradient (const Quantity_Color& AColor1, const Quantity_Color& AColor2, const Aspect_GradientFillMethod AType);
   void SetBackgroundGradientType (const Aspect_GradientFillMethod AType);
 
-  void Render (const Handle(OpenGl_Workspace) &AWorkspace,
-               const Graphic3d_CView& ACView,
-               const Aspect_CLayer2d& ACUnderLayer,
-               const Aspect_CLayer2d& ACOverLayer);
+  void Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
+               const Handle(OpenGl_Workspace)&      theWorkspace,
+               const Graphic3d_CView&               theCView,
+               const Aspect_CLayer2d&               theCUnderLayer,
+               const Aspect_CLayer2d&               theCOverLayer);
 
-  // Type definition
-  //
-  DEFINE_STANDARD_RTTI(OpenGl_View)
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_View) // Type definition
 
  protected:
 
   void RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace);
-  void RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer);
+  void RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
+                      const Handle(OpenGl_Workspace)&      theWorkspace,
+                      const Graphic3d_CView&               theCView,
+                      const Aspect_CLayer2d&               theCLayer);
 
   Handle(OpenGl_Texture) myTextureEnv;
   Visual3d_TypeOfSurfaceDetail mySurfaceDetail; //WSSurfaceDetail
@@ -218,8 +228,8 @@ class OpenGl_View : public MMgt_TShared
   //}
 
   OPENGL_FOG myFog;
-  Handle(OpenGl_Trihedron) myTrihedron;
-  Handle(OpenGl_GraduatedTrihedron) myGraduatedTrihedron;
+  OpenGl_Trihedron*          myTrihedron;
+  OpenGl_GraduatedTrihedron* myGraduatedTrihedron;
 
   //View_LABViewContext
   int myVisualization;
index 1ecb590..d37385f 100644 (file)
@@ -631,10 +631,11 @@ call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
 /*----------------------------------------------------------------------*/
 
 //call_func_redraw_all_structs_proc
-void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
-                         const Graphic3d_CView& ACView,
-                         const Aspect_CLayer2d& ACUnderLayer,
-                         const Aspect_CLayer2d& ACOverLayer)
+void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
+                          const Handle(OpenGl_Workspace) &AWorkspace,
+                          const Graphic3d_CView& ACView,
+                          const Aspect_CLayer2d& ACUnderLayer,
+                          const Aspect_CLayer2d& ACOverLayer)
 {
   // Reset FLIST status after modification of myBackfacing
   if (myResetFLIST)
@@ -862,7 +863,7 @@ void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
 
   /////////////////////////////////////////////////////////////////////////////
   // Step 2: Draw underlayer
-  RedrawLayer2d(AWorkspace, ACView, ACUnderLayer);
+  RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACUnderLayer);
 
   /////////////////////////////////////////////////////////////////////////////
   // Step 3: Redraw main plane
@@ -896,15 +897,11 @@ void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
 
   glMatrixMode( GL_PROJECTION );
 
-#ifdef WNT
+#ifdef _WIN32
   // add printing scale/tiling transformation
-  OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext(AWorkspace->GetGContext());
-
-  if (aPrinterContext)
+  if (!thePrintContext.IsNull())
   {
-    GLfloat aProjMatrix[16];
-    aPrinterContext->GetProjTransformation(aProjMatrix);
-    glLoadMatrixf((GLfloat*) aProjMatrix);
+    thePrintContext->LoadProjTransformation();
   }
   else
 #endif
@@ -1186,11 +1183,15 @@ D = -[Px,Py,Pz] dot |Nx|
   for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
     glDisable( planeid );
 
-  /* affichage de Triedre Non Zoomable de la vue s'il existe */
-  if (!myTrihedron.IsNull())
-    myTrihedron->Render(AWorkspace);
-  if (!myGraduatedTrihedron.IsNull())
-    myGraduatedTrihedron->Render(AWorkspace);
+  // display global trihedron
+  if (myTrihedron != NULL)
+  {
+    myTrihedron->Render (AWorkspace);
+  }
+  if (myGraduatedTrihedron != NULL)
+  {
+    myGraduatedTrihedron->Render (AWorkspace);
+  }
 
   // Restore face culling
   if ( myBackfacing )
@@ -1209,7 +1210,7 @@ D = -[Px,Py,Pz] dot |Nx|
   const int aMode = 0;
   AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
 
-  RedrawLayer2d(AWorkspace, ACView, ACOverLayer);
+  RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACOverLayer);
 
   AWorkspace->DisplayCallback (ACView, aMode);
 
@@ -1277,7 +1278,10 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
 /*----------------------------------------------------------------------*/
 
 //call_togl_redraw_layer2d
-void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer)
+void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
+                                 const Handle(OpenGl_Workspace)&      AWorkspace,
+                                 const Graphic3d_CView&               ACView,
+                                 const Aspect_CLayer2d&               ACLayer)
 {
   if (&ACLayer == NULL
    || ACLayer.ptrLayer == NULL
@@ -1346,11 +1350,9 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, con
     }
   }
 
-#ifdef WNT
+#ifdef _WIN32
   // Check printer context that exists only for print operation
-  OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext (AWorkspace->GetGContext());
-
-  if (aPrinterContext)
+  if (!thePrintContext.IsNull())
   {
     // additional transformation matrix could be applied to
     // render only those parts of viewport that will be
@@ -1358,16 +1360,14 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, con
     // tiling; scaling of graphics by matrix helps render a
     // part of a view (frame) in same viewport, but with higher
     // resolution
-    GLfloat aProjMatrix[16];
-    aPrinterContext->GetProjTransformation (aProjMatrix);
-    glLoadMatrixf ((GLfloat*) aProjMatrix);
+    thePrintContext->LoadProjTransformation();
 
     // printing operation also assumes other viewport dimension
     // to comply with transformation matrix or graphics scaling
     // factors for tiling for layer redraw
     GLsizei anViewportX = 0;
     GLsizei anViewportY = 0;
-    aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
+    thePrintContext->GetLayerViewport (anViewportX, anViewportY);
     if (anViewportX != 0 && anViewportY != 0)
       glViewport (0, 0, anViewportX, anViewportY);
   }
index 29a65c3..cee0ed4 100644 (file)
 
 #include <InterfaceGraphic.hxx>
 
-#include <OpenGl_Workspace.hxx>
-
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_AspectFace.hxx>
 #include <OpenGl_AspectMarker.hxx>
 #include <OpenGl_AspectText.hxx>
 #include <OpenGl_Context.hxx>
-
+#include <OpenGl_FrameBuffer.hxx>
 #include <OpenGl_Texture.hxx>
+#include <OpenGl_Workspace.hxx>
 
 #include <Graphic3d_TextureParams.hxx>
 
+#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
+  #include <OpenGl_AVIWriter.hxx>
+#endif
+
 IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window)
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window)
 
@@ -69,20 +72,20 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay,
                                     Aspect_RenderingContext       theGContext,
                                     const Handle(OpenGl_Context)& theShareCtx)
 : OpenGl_Window (theDisplay, theCWindow, theGContext, theShareCtx),
-  myTransientList (0),
+  NamedStatus (0),
+  DegenerateModel (0),
+  SkipRatio (0.F),
+  HighlightColor (&myDefaultHighlightColor),
+  //
   myIsTransientOpen (Standard_False),
-  myTransientDrawToFront (Standard_True),
   myRetainMode (Standard_False),
+  myTransientDrawToFront (Standard_True),
   myUseTransparency (Standard_False),
   myUseZBuffer (Standard_False),
   myUseDepthTest (Standard_True),
   myUseGLLight (Standard_True),
   myBackBufferRestored (Standard_False),
   //
-  NamedStatus (0),
-  DegenerateModel (0),
-  SkipRatio (0.F),
-  HighlightColor (&myDefaultHighlightColor),
   AspectLine_set (&myDefaultAspectLine),
   AspectLine_applied (NULL),
   AspectFace_set (&myDefaultAspectFace),
@@ -434,3 +437,71 @@ Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Text
 
   return aPrevTexture;
 }
+
+// =======================================================================
+// function : Redraw
+// purpose  :
+// =======================================================================
+void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
+                               const Aspect_CLayer2d& theCUnderLayer,
+                               const Aspect_CLayer2d& theCOverLayer)
+{
+  if (!Activate())
+  {
+    return;
+  }
+
+  // release pending GL resources
+  Handle(OpenGl_Context) aGlCtx = GetGlContext();
+  aGlCtx->ReleaseDelayed();
+
+  // cache render mode state
+  GLint aRendMode = GL_RENDER;
+  glGetIntegerv (GL_RENDER_MODE,  &aRendMode);
+  aGlCtx->SetFeedback (aRendMode == GL_FEEDBACK);
+
+  Tint toSwap = (aRendMode == GL_RENDER); // swap buffers
+  GLint aViewPortBack[4];
+  OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
+  if (aFrameBuffer != NULL)
+  {
+    glGetIntegerv (GL_VIEWPORT, aViewPortBack);
+    aFrameBuffer->SetupViewport();
+    aFrameBuffer->BindBuffer (aGlCtx);
+    toSwap = 0; // no need to swap buffers
+  }
+
+  Redraw1 (theCView, theCUnderLayer, theCOverLayer, toSwap);
+  if (aFrameBuffer == NULL || !myTransientDrawToFront)
+  {
+    RedrawImmediatMode();
+  }
+
+  if (aFrameBuffer != NULL)
+  {
+    aFrameBuffer->UnbindBuffer (aGlCtx);
+    // move back original viewport
+    glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]);
+  }
+
+#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE)
+  if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow))
+  {
+    GLint params[4];
+    glGetIntegerv (GL_VIEWPORT, params);
+    int nWidth  = params[2] & ~0x7;
+    int nHeight = params[3] & ~0x7;
+
+    const int nBitsPerPixel = 24;
+    GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
+
+    glPixelStorei (GL_PACK_ALIGNMENT, 1);
+    glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
+    OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
+    delete[] aDumpData;
+  }
+#endif
+
+  // reset render mode state
+  aGlCtx->SetFeedback (Standard_False);
+}
index d556ceb..57b1bd2 100644 (file)
@@ -47,6 +47,7 @@
 #include <OpenGl_Display.hxx>
 #include <OpenGl_Matrix.hxx>
 #include <OpenGl_NamedStatus.hxx>
+#include <OpenGl_PrinterContext.hxx>
 #include <OpenGl_TextParam.hxx>
 
 #include <Handle_OpenGl_View.hxx>
@@ -92,7 +93,8 @@ public:
 
   //! Special method to perform printing.
   //! System-specific and currently only Win platform implemented.
-  Standard_Boolean Print (const Graphic3d_CView& theCView,
+  Standard_Boolean Print (const Handle(OpenGl_PrinterContext)& thePrintContext,
+                          const Graphic3d_CView& theCView,
                           const Aspect_CLayer2d& theCUnderLayer,
                           const Aspect_CLayer2d& theCOverLayer,
                           const Aspect_Handle    theHPrintDC,
@@ -101,6 +103,11 @@ public:
                           const Aspect_PrintAlgo thePrintAlgorithm,
                           const Standard_Real    theScaleFactor);
 
+  const Handle(OpenGl_PrinterContext)& PrinterContext() const
+  {
+    return myPrintContext;
+  }
+
   void DisplayCallback (const Graphic3d_CView& theCView, int theReason);
 
   // szvgl: defined in OpenGl_Workspace_1.cxx
@@ -156,6 +163,10 @@ public:
   Standard_EXPORT const OpenGl_AspectFace*   AspectFace   (const Standard_Boolean theWithApply);
   Standard_EXPORT const OpenGl_AspectMarker* AspectMarker (const Standard_Boolean theWithApply);
   Standard_EXPORT const OpenGl_AspectText*   AspectText   (const Standard_Boolean theWithApply);
+  inline const OpenGl_TextParam* AspectTextParams() const
+  {
+    return TextParam_applied;
+  }
 
   //! Clear the applied aspect state.
   void ResetAppliedAspect();
@@ -164,29 +175,6 @@ public:
   Standard_EXPORT Handle(OpenGl_Texture) EnableTexture (const Handle(OpenGl_Texture)&          theTexture,
                                                         const Handle(Graphic3d_TextureParams)& theParams = NULL);
 
-  //// RELATED TO FONTS ////
-
-  int FindFont (const char*           theFontName,
-                const Font_FontAspect theFontAspect,
-                const int             theBestSize = -1,
-                const float           theXScale = 1.0f,
-                const float           theYScale = 1.0f)
-  {
-    return myDisplay->FindFont (theFontName, theFontAspect, theBestSize, theXScale, theYScale);
-  }
-
-  void StringSize (const wchar_t* theText, int& theWidth, int& theAscent, int& theDescent)
-  {
-    myDisplay->StringSize (theText, theWidth, theAscent, theDescent);
-  }
-
-  void RenderText (const wchar_t* theText, const int theIs2d,
-                   const float theX, const float theY, const float theZ)
-  {
-    const OpenGl_AspectText* anAspect = AspectText (Standard_True);
-    myDisplay->RenderText (theText, theIs2d, theX, theY, theZ, anAspect, TextParam_applied);
-  }
-
 protected:
 
   void CopyBuffers (const Standard_Boolean theFrontToBack);
@@ -206,6 +194,7 @@ protected:
 
 protected: //! @name protected fields
 
+  Handle(OpenGl_PrinterContext) myPrintContext;
   Handle(OpenGl_View)    myView;            // WSViews - now just one view is supported
   Standard_Boolean       myIsTransientOpen; // transientOpen
   Standard_Boolean       myRetainMode;