From a174a3c54f4657c3b4cd9fd1b6fda4f5f717ac1e Mon Sep 17 00:00:00 2001 From: kgv Date: Fri, 8 Feb 2013 15:05:16 +0400 Subject: [PATCH] 0023457: Slow text rendering 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 --- src/Font/FILES | 4 + src/Font/Font.cdl | 10 +- src/Font/Font_FTFont.cxx | 243 +++++ src/Font/Font_FTFont.hxx | 213 +++++ .../Font_FTLibrary.cxx} | 50 +- src/Font/Font_FTLibrary.hxx | 73 ++ src/Font/Font_SystemFont.cxx | 11 +- src/NCollection/FILES | 6 + src/NCollection/NCollection_Array1.hxx | 24 + src/NCollection/NCollection_DataMap.hxx | 24 +- src/NCollection/NCollection_Sequence.hxx | 35 +- .../NCollection_String.hxx} | 23 +- src/NCollection/NCollection_UtfIterator.hxx | 209 +++++ src/NCollection/NCollection_UtfIterator.lxx | 340 +++++++ src/NCollection/NCollection_UtfString.hxx | 278 ++++++ src/NCollection/NCollection_UtfString.lxx | 475 ++++++++++ src/NCollection/NCollection_Vector.hxx | 46 +- src/NIS/NIS_TriangulatedDrawer.cxx | 8 +- src/OpenGl/EXTERNLIB | 1 - src/OpenGl/FILES | 16 +- src/OpenGl/OpenGl_AspectText.cxx | 104 ++- src/OpenGl/OpenGl_AspectText.hxx | 112 ++- src/OpenGl/OpenGl_Context.cxx | 60 +- src/OpenGl/OpenGl_Context.hxx | 32 +- src/OpenGl/OpenGl_Display.cxx | 8 +- src/OpenGl/OpenGl_Display.hxx | 12 - src/OpenGl/OpenGl_Display_1.cxx | 665 -------------- src/OpenGl/OpenGl_Element.cxx | 38 + src/OpenGl/OpenGl_Element.hxx | 8 +- src/OpenGl/OpenGl_Font.cxx | 227 +++++ src/OpenGl/OpenGl_Font.hxx | 170 ++++ src/OpenGl/OpenGl_FontMgr.cxx | 271 ------ src/OpenGl/OpenGl_FontMgr.hxx | 98 -- src/OpenGl/OpenGl_FrameBuffer.cxx | 19 +- src/OpenGl/OpenGl_GraduatedTrihedron.cxx | 411 ++++----- src/OpenGl/OpenGl_GraduatedTrihedron.hxx | 72 +- src/OpenGl/OpenGl_GraphicDriver.cxx | 277 +++++- src/OpenGl/OpenGl_GraphicDriver.hxx | 4 + src/OpenGl/OpenGl_GraphicDriver_705.cxx | 0 src/OpenGl/OpenGl_GraphicDriver_710.cxx | 99 -- src/OpenGl/OpenGl_GraphicDriver_9.cxx | 137 --- src/OpenGl/OpenGl_GraphicDriver_Layer.cxx | 242 +---- src/OpenGl/OpenGl_PrinterContext.cxx | 136 ++- src/OpenGl/OpenGl_PrinterContext.hxx | 120 +-- src/OpenGl/OpenGl_Text.cxx | 847 +++++++++++++++--- src/OpenGl/OpenGl_Text.hxx | 131 ++- src/OpenGl/OpenGl_TextFormatter.cxx | 490 ++++++++++ src/OpenGl/OpenGl_TextFormatter.hxx | 158 ++++ src/OpenGl/OpenGl_Texture.cxx | 51 +- src/OpenGl/OpenGl_Texture.hxx | 18 + src/OpenGl/OpenGl_Trihedron.cxx | 91 +- src/OpenGl/OpenGl_Trihedron.hxx | 56 +- ..._GraduatedTrihedron.hxx => OpenGl_Vec.hxx} | 25 +- src/OpenGl/OpenGl_VertexBufferEditor.hxx | 39 +- src/OpenGl/OpenGl_View.cxx | 26 +- src/OpenGl/OpenGl_View.hxx | 42 +- src/OpenGl/OpenGl_View_2.cxx | 54 +- src/OpenGl/OpenGl_Workspace.cxx | 89 +- src/OpenGl/OpenGl_Workspace.hxx | 37 +- src/OpenGl/OpenGl_Workspace_2.cxx | 37 +- src/OpenGl/OpenGl_Workspace_4.cxx | 93 -- src/OpenGl/OpenGl_Workspace_5.cxx | 31 +- src/Standard/Standard.cdl | 5 + src/Standard/Standard_Integer.hxx | 39 +- src/Standard/Standard_TypeDef.hxx | 21 +- src/TKOpenGl/EXTERNLIB | 1 - src/ViewerTest/ViewerTest_OpenGlCommands.cxx | 2 +- tests/3rdparty/fonts/A3 | 20 + tests/3rdparty/fonts/A4 | 31 + tests/3rdparty/fonts/A5 | 38 + tests/3rdparty/fonts/A6 | 38 + tests/3rdparty/fonts/A7 | 28 + 72 files changed, 5370 insertions(+), 2579 deletions(-) create mode 100644 src/Font/Font_FTFont.cxx create mode 100644 src/Font/Font_FTFont.hxx rename src/{OpenGl/OpenGl_GraphicDriver_print.cxx => Font/Font_FTLibrary.cxx} (50%) mode change 100755 => 100644 create mode 100644 src/Font/Font_FTLibrary.hxx rename src/{OpenGl/Handle_OpenGl_Trihedron.hxx => NCollection/NCollection_String.hxx} (70%) create mode 100644 src/NCollection/NCollection_UtfIterator.hxx create mode 100644 src/NCollection/NCollection_UtfIterator.lxx create mode 100644 src/NCollection/NCollection_UtfString.hxx create mode 100644 src/NCollection/NCollection_UtfString.lxx delete mode 100644 src/OpenGl/OpenGl_Display_1.cxx create mode 100644 src/OpenGl/OpenGl_Element.cxx create mode 100644 src/OpenGl/OpenGl_Font.cxx create mode 100644 src/OpenGl/OpenGl_Font.hxx delete mode 100755 src/OpenGl/OpenGl_FontMgr.cxx delete mode 100755 src/OpenGl/OpenGl_FontMgr.hxx delete mode 100755 src/OpenGl/OpenGl_GraphicDriver_705.cxx delete mode 100755 src/OpenGl/OpenGl_GraphicDriver_710.cxx delete mode 100755 src/OpenGl/OpenGl_GraphicDriver_9.cxx create mode 100644 src/OpenGl/OpenGl_TextFormatter.cxx create mode 100644 src/OpenGl/OpenGl_TextFormatter.hxx rename src/OpenGl/{Handle_OpenGl_GraduatedTrihedron.hxx => OpenGl_Vec.hxx} (67%) delete mode 100644 src/OpenGl/OpenGl_Workspace_4.cxx create mode 100644 tests/3rdparty/fonts/A3 create mode 100644 tests/3rdparty/fonts/A4 create mode 100644 tests/3rdparty/fonts/A5 create mode 100644 tests/3rdparty/fonts/A6 create mode 100644 tests/3rdparty/fonts/A7 diff --git a/src/Font/FILES b/src/Font/FILES index 89437064bc..adcfa0e40d 100644 --- a/src/Font/FILES +++ b/src/Font/FILES @@ -1,3 +1,7 @@ EXTERNLIB +Font_FTFont.hxx +Font_FTFont.cxx +Font_FTLibrary.hxx +Font_FTLibrary.cxx Font_NListOfSystemFont.hxx Font_NameOfFont.hxx diff --git a/src/Font/Font.cdl b/src/Font/Font.cdl index a96a7a6f9d..538381614b 100644 --- a/src/Font/Font.cdl +++ b/src/Font/Font.cdl @@ -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 index 0000000000..03e5110a69 --- /dev/null +++ b/src/Font/Font_FTFont.cxx @@ -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 + +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 (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 (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 (myFTFace->glyph->advance.x); + } + return fromFTPoints (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 (myFTFace->glyph->advance.y); + } + return fromFTPoints (myKernAdvance.y + myFTFace->glyph->advance.y); +} diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx new file mode 100644 index 0000000000..dc03bd737b --- /dev/null +++ b/src/Font/Font_FTFont.hxx @@ -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 +#include +#include +#include + +//! 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& TopLeft (NCollection_Vec2& theVec) const + { + theVec.x() = Left; + theVec.y() = Top; + return theVec; + } + + NCollection_Vec2& TopRight (NCollection_Vec2& theVec) const + { + theVec.x() = Right; + theVec.y() = Top; + return theVec; + } + + NCollection_Vec2& BottomLeft (NCollection_Vec2& theVec) const + { + theVec.x() = Left; + theVec.y() = Bottom; + return theVec; + } + + NCollection_Vec2& BottomRight (NCollection_Vec2& 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 + 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 + 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__ diff --git a/src/OpenGl/OpenGl_GraphicDriver_print.cxx b/src/Font/Font_FTLibrary.cxx old mode 100755 new mode 100644 similarity index 50% rename from src/OpenGl/OpenGl_GraphicDriver_print.cxx rename to src/Font/Font_FTLibrary.cxx index 6e515802c7..010aa57694 --- a/src/OpenGl/OpenGl_GraphicDriver_print.cxx +++ b/src/Font/Font_FTLibrary.cxx @@ -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 @@ -17,28 +17,32 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. +#include -#include +IMPLEMENT_STANDARD_HANDLE (Font_FTLibrary, Standard_Transient) +IMPLEMENT_STANDARD_RTTIEXT(Font_FTLibrary, Standard_Transient) -#include -#include +// ======================================================================= +// 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 index 0000000000..ba2a196ff5 --- /dev/null +++ b/src/Font/Font_FTLibrary.hxx @@ -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 +#include +#include + +// inclusion template for FreeType +#include +#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__ diff --git a/src/Font/Font_SystemFont.cxx b/src/Font/Font_SystemFont.cxx index bc3804b775..e1eaece194 100644 --- a/src/Font/Font_SystemFont.cxx +++ b/src/Font/Font_SystemFont.cxx @@ -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() ); } diff --git a/src/NCollection/FILES b/src/NCollection/FILES index b5da38be75..d7e9af7fff 100755 --- a/src/NCollection/FILES +++ b/src/NCollection/FILES @@ -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 diff --git a/src/NCollection/NCollection_Array1.hxx b/src/NCollection/NCollection_Array1.hxx index 02f7dd59f5..f593c4e15d 100755 --- a/src/NCollection/NCollection_Array1.hxx +++ b/src/NCollection/NCollection_Array1.hxx @@ -221,6 +221,30 @@ template 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 { diff --git a/src/NCollection/NCollection_DataMap.hxx b/src/NCollection/NCollection_DataMap.hxx index aeab1b0a0b..6271039d82 100755 --- a/src/NCollection/NCollection_DataMap.hxx +++ b/src/NCollection/NCollection_DataMap.hxx @@ -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); } diff --git a/src/NCollection/NCollection_Sequence.hxx b/src/NCollection/NCollection_Sequence.hxx index 3b0866a8d8..6a3487e1f0 100755 --- a/src/NCollection/NCollection_Sequence.hxx +++ b/src/NCollection/NCollection_Sequence.hxx @@ -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 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 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 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 { diff --git a/src/OpenGl/Handle_OpenGl_Trihedron.hxx b/src/NCollection/NCollection_String.hxx similarity index 70% rename from src/OpenGl/Handle_OpenGl_Trihedron.hxx rename to src/NCollection/NCollection_String.hxx index d8c92d19f8..c521600f45 100644 --- a/src/OpenGl/Handle_OpenGl_Trihedron.hxx +++ b/src/NCollection/NCollection_String.hxx @@ -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 @@ -17,18 +17,11 @@ // 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 -#include +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 index 0000000000..19a450634b --- /dev/null +++ b/src/NCollection/NCollection_UtfIterator.hxx @@ -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 + +//! 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 +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 + 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 + 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 NCollection_Utf8Iter; +typedef NCollection_UtfIterator NCollection_Utf16Iter; +typedef NCollection_UtfIterator NCollection_Utf32Iter; +typedef NCollection_UtfIterator 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 index 0000000000..ead44e8d7b --- /dev/null +++ b/src/NCollection/NCollection_UtfIterator.lxx @@ -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 +const unsigned char NCollection_UtfIterator::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 +const unsigned long NCollection_UtfIterator::offsetsFromUTF8[6] = +{ + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL +}; + +//! The first character in a UTF-8 sequence indicates how many bytes to read. +template +const unsigned char NCollection_UtfIterator::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 +inline void NCollection_UtfIterator::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 const unsigned long NCollection_UtfIterator::UTF8_BYTE_MASK = 0xBF; +template const unsigned long NCollection_UtfIterator::UTF8_BYTE_MARK = 0x80; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_HIGH_START = 0xD800; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_HIGH_END = 0xDBFF; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_LOW_START = 0xDC00; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_LOW_END = 0xDFFF; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_HIGH_SHIFT = 10; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_LOW_BASE = 0x0010000UL; +template const unsigned long NCollection_UtfIterator::UTF16_SURROGATE_LOW_MASK = 0x3FFUL; +template const unsigned long NCollection_UtfIterator::UTF32_MAX_BMP = 0x0000FFFFUL; +template const unsigned long NCollection_UtfIterator::UTF32_MAX_LEGAL = 0x0010FFFFUL; + +// ======================================================================= +// function : readUTF16 +// purpose : +// ======================================================================= +template inline +void NCollection_UtfIterator::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 inline +Standard_Integer NCollection_UtfIterator::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 inline +Standard_Utf8Char* NCollection_UtfIterator::GetUtf8 (Standard_Utf8Char* theBuffer) const +{ + // unsigned arithmetic used + return (Standard_Utf8Char* )GetUtf8 ((Standard_Utf8UChar* )theBuffer); +} + +// ======================================================================= +// function : GetUtf8 +// purpose : +// ======================================================================= +template inline +Standard_Utf8UChar* NCollection_UtfIterator::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 inline +Standard_Integer NCollection_UtfIterator::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 inline +Standard_Utf16Char* NCollection_UtfIterator::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 inline +Standard_Utf32Char* NCollection_UtfIterator::GetUtf32 (Standard_Utf32Char* theBuffer) const +{ + *theBuffer++ = myCharUtf32; + return theBuffer; +} + +// ======================================================================= +// function : AdvanceBytesUtf +// purpose : +// ======================================================================= +template template inline +Standard_Integer NCollection_UtfIterator::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 template inline +TypeWrite* NCollection_UtfIterator::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 index 0000000000..c644669678 --- /dev/null +++ b/src/NCollection/NCollection_UtfString.hxx @@ -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 + +#include +#include + +//! 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 +class NCollection_UtfString +{ + +public: + + NCollection_UtfIterator Iterator() const + { + return NCollection_UtfIterator (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 + 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 ToUtf8() const; + + //! @return copy in UTF-16 format + const NCollection_UtfString ToUtf16() const; + + //! @return copy in UTF-32 format + const NCollection_UtfString ToUtf32() const; + + //! @return copy in wide format (UTF-16 on Windows and UTF-32 on Linux) + const NCollection_UtfString 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 + 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 NCollection_Utf8String; +typedef NCollection_UtfString NCollection_Utf16String; +typedef NCollection_UtfString NCollection_Utf32String; +typedef NCollection_UtfString 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 index 0000000000..421782611a --- /dev/null +++ b/src/NCollection/NCollection_UtfString.lxx @@ -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 template inline +void NCollection_UtfString::strGetAdvance (const TypeFrom* theStringUtf, + const Standard_Integer theLengthMax, + Standard_Integer& theSizeBytes, + Standard_Integer& theLength) +{ + theSizeBytes = 0; + theLength = 0; + NCollection_UtfIterator 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 +Standard_Utf32Char NCollection_UtfString::GetChar (const Standard_Integer theCharIndex) const +{ + //Standard_ASSERT_SKIP (theCharIndex < myLength, "Out of range"); + NCollection_UtfIterator anIter (myString); + for (; *anIter != 0; ++anIter) + { + if (anIter.Index() == theCharIndex) + { + return *anIter; + } + } + return 0; +} + +// ======================================================================= +// function : GetCharBuffer +// purpose : +// ======================================================================= +template +const Type* NCollection_UtfString::GetCharBuffer (const Standard_Integer theCharIndex) const +{ + //Standard_ASSERT_SKIP(theCharIndex < myLength); + NCollection_UtfIterator anIter (myString); + for (; *anIter != 0; ++anIter) + { + if (anIter.Index() == theCharIndex) + { + return anIter.BufferHere(); + } + } + return NULL; +} + +// ======================================================================= +// function : Clear +// purpose : +// ======================================================================= +template inline +void NCollection_UtfString::Clear() +{ + strFree (myString); + mySize = 0; + myLength = 0; + myString = strAlloc (mySize); +} + +// ======================================================================= +// function : NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::NCollection_UtfString() +: myString (strAlloc(0)), + mySize (0), + myLength (0) +{ + // +} + +// ======================================================================= +// function : NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::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 inline +NCollection_UtfString::NCollection_UtfString (const char* theCopyUtf8, + const Standard_Integer theLength) +: myString (NULL), + mySize (0), + myLength (0) +{ + FromUnicode (theCopyUtf8, theLength); +} + +// ======================================================================= +// function : NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::NCollection_UtfString (const Standard_Utf16Char* theCopyUtf16, + const Standard_Integer theLength) +: myString (NULL), + mySize (0), + myLength (0) +{ + FromUnicode (theCopyUtf16, theLength); +} + +// ======================================================================= +// function : NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32, + const Standard_Integer theLength) +: myString (NULL), + mySize (0), + myLength (0) +{ + FromUnicode (theCopyUtf32, theLength); +} + +// ======================================================================= +// function : NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::NCollection_UtfString (const Standard_WideChar* theCopyUtfWide, + const Standard_Integer theLength) +: myString (NULL), + mySize (0), + myLength (0) +{ + FromUnicode (theCopyUtfWide, theLength); +} + +// ======================================================================= +// function : ~NCollection_UtfString +// purpose : +// ======================================================================= +template inline +NCollection_UtfString::~NCollection_UtfString() +{ + strFree (myString); +} + +// ======================================================================= +// function : operator= +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString& NCollection_UtfString::operator= (const NCollection_UtfString& 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 template +void NCollection_UtfString::FromUnicode (const TypeFrom* theStringUtf, + const Standard_Integer theLength) +{ + Type* anOldBuffer = myString; // necessary in case of self-copying + NCollection_UtfIterator 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 inline +void NCollection_UtfString::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 inline +bool NCollection_UtfString::ToLocale (char* theBuffer, + const Standard_Integer theSizeBytes) const +{ + NCollection_UtfString 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 inline +const NCollection_UtfString& NCollection_UtfString::operator= (const char* theStringUtf8) +{ + FromUnicode (theStringUtf8); + return (*this); +} + +// ======================================================================= +// function : operator= +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString& NCollection_UtfString::operator= (const Standard_WideChar* theStringUtfWide) +{ + FromUnicode (theStringUtfWide); + return (*this); +} + +// ======================================================================= +// function : IsEqual +// purpose : +// ======================================================================= +template inline +bool NCollection_UtfString::IsEqual (const NCollection_UtfString& theCompare) const +{ + return this == &theCompare + || strAreEqual (myString, mySize, theCompare.myString, theCompare.mySize); +} + +// ======================================================================= +// function : operator!= +// purpose : +// ======================================================================= +template inline +bool NCollection_UtfString::operator!= (const NCollection_UtfString& theCompare) const +{ + return (!NCollection_UtfString::operator== (theCompare)); +} + +// ======================================================================= +// function : operator+= +// purpose : +// ======================================================================= +template inline +NCollection_UtfString& NCollection_UtfString::operator+= (const NCollection_UtfString& 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 inline +NCollection_UtfString NCollection_UtfString::SubString (const Standard_Integer theStart, + const Standard_Integer theEnd) const +{ + if (theStart >= theEnd) + { + return NCollection_UtfString(); + } + for (NCollection_UtfIterator anIter(myString); *anIter != 0; ++anIter) + { + if (anIter.Index() >= theStart) + { + return NCollection_UtfString (anIter.BufferHere(), theEnd - theStart); + } + } + return NCollection_UtfString(); +} + +// ======================================================================= +// function : ToUtf8 +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString NCollection_UtfString::ToUtf8() const +{ + NCollection_UtfString aCopy; + aCopy.FromUnicode (myString); + return aCopy; +} + +// ======================================================================= +// function : ToUtf16 +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString NCollection_UtfString::ToUtf16() const +{ + NCollection_UtfString aCopy; + aCopy.FromUnicode (myString); + return aCopy; +} + +// ======================================================================= +// function : ToUtf32 +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString NCollection_UtfString::ToUtf32() const +{ + NCollection_UtfString aCopy; + aCopy.FromUnicode (myString); + return aCopy; +} + +// ======================================================================= +// function : ToUtfWide +// purpose : +// ======================================================================= +template inline +const NCollection_UtfString NCollection_UtfString::ToUtfWide() const +{ + NCollection_UtfString aCopy; + aCopy.FromUnicode (myString); + return aCopy; +} diff --git a/src/NCollection/NCollection_Vector.hxx b/src/NCollection/NCollection_Vector.hxx index eb1c7b86a2..5e94b221b9 100755 --- a/src/NCollection/NCollection_Vector.hxx +++ b/src/NCollection/NCollection_Vector.hxx @@ -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 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& theOther) { @@ -242,6 +260,30 @@ template 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); } diff --git a/src/NIS/NIS_TriangulatedDrawer.cxx b/src/NIS/NIS_TriangulatedDrawer.cxx index 77eb97d811..26f5c2b810 100755 --- a/src/NIS/NIS_TriangulatedDrawer.cxx +++ b/src/NIS/NIS_TriangulatedDrawer.cxx @@ -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); } + } } } diff --git a/src/OpenGl/EXTERNLIB b/src/OpenGl/EXTERNLIB index 8779a608df..21580fc276 100755 --- a/src/OpenGl/EXTERNLIB +++ b/src/OpenGl/EXTERNLIB @@ -8,5 +8,4 @@ CSF_IOKit CSF_OpenGlLibs CSF_AviLibs CSF_FREETYPE -CSF_FTGL CSF_GL2PS diff --git a/src/OpenGl/FILES b/src/OpenGl/FILES index a5f77cb278..e6e91ca46d 100755 --- a/src/OpenGl/FILES +++ b/src/OpenGl/FILES @@ -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 diff --git a/src/OpenGl/OpenGl_AspectText.cxx b/src/OpenGl/OpenGl_AspectText.cxx index c889b2dc9b..57def3b099 100644 --- a/src/OpenGl/OpenGl_AspectText.cxx +++ b/src/OpenGl/OpenGl_AspectText.cxx @@ -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 @@ -20,77 +20,73 @@ #include #include -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; -} - -/*----------------------------------------------------------------------*/ diff --git a/src/OpenGl/OpenGl_AspectText.hxx b/src/OpenGl/OpenGl_AspectText.hxx index d7fd9aceae..19708068bd 100644 --- a/src/OpenGl/OpenGl_AspectText.hxx +++ b/src/OpenGl/OpenGl_AspectText.hxx @@ -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 @@ -25,8 +25,11 @@ #include #include +#include + #include +//! 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 diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index c26001a62f..0262971c48 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -30,6 +30,8 @@ #include #include +#include + #include #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 aDeadList; + for (NCollection_DataMap::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)); + } } diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index a125ad487c..a35b36ee86 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -80,6 +80,25 @@ struct OpenGl_ExtGS; //! for each GL context individually. 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. @@ -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 OpenGl_DelayReleaseMap; + typedef NCollection_Handle Handle(OpenGl_DelayReleaseMap); typedef NCollection_DataMap OpenGl_ResourcesMap; typedef NCollection_Handle Handle(OpenGl_ResourcesMap); typedef NCollection_Queue OpenGl_ResourcesQueue; typedef NCollection_Handle 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 diff --git a/src/OpenGl/OpenGl_Display.cxx b/src/OpenGl/OpenGl_Display.cxx index 12b44a87ba..5b6e55861f 100644 --- a/src/OpenGl/OpenGl_Display.cxx +++ b/src/OpenGl/OpenGl_Display.cxx @@ -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; diff --git a/src/OpenGl/OpenGl_Display.hxx b/src/OpenGl/OpenGl_Display.hxx index 95b8a9abf5..ccc1c3b9c7 100644 --- a/src/OpenGl/OpenGl_Display.hxx +++ b/src/OpenGl/OpenGl_Display.hxx @@ -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 index e7f06e9188..0000000000 --- a/src/OpenGl/OpenGl_Display_1.cxx +++ /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 - -#include -#include - -#include -#include - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_GL2PS -#include -#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 -} diff --git a/src/OpenGl/OpenGl_Element.cxx b/src/OpenGl/OpenGl_Element.cxx new file mode 100644 index 0000000000..9b83eb3f14 --- /dev/null +++ b/src/OpenGl/OpenGl_Element.cxx @@ -0,0 +1,38 @@ +// 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 +// 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 + +// ======================================================================= +// function : OpenGl_Element +// purpose : +// ======================================================================= +OpenGl_Element::OpenGl_Element() +{ + // +} + +// ======================================================================= +// function : ~OpenGl_Element +// purpose : +// ======================================================================= +OpenGl_Element::~OpenGl_Element() +{ + // +} diff --git a/src/OpenGl/OpenGl_Element.hxx b/src/OpenGl/OpenGl_Element.hxx index ba811898ec..b900f28132 100644 --- a/src/OpenGl/OpenGl_Element.hxx +++ b/src/OpenGl/OpenGl_Element.hxx @@ -17,18 +17,18 @@ // 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 #include +//! 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 index 0000000000..3f1736c9a9 --- /dev/null +++ b/src/OpenGl/OpenGl_Font.cxx @@ -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 + +#include +#include + +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 index 0000000000..779806c57d --- /dev/null +++ b/src/OpenGl/OpenGl_Font.hxx @@ -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 +#include + +#include + +#include +#include +#include + +//! 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 myTextures; //!< array of textures + NCollection_Vector myTiles; //!< array of loaded tiles + + NCollection_DataMap 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 index 596355a183..0000000000 --- a/src/OpenGl/OpenGl_FontMgr.cxx +++ /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 -#include - -#include -#include - -#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, ¶m); - - 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 -#include -#include -#include -#include -#include - -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 index de20a172e2..0000000000 --- a/src/OpenGl/OpenGl_FontMgr.hxx +++ /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 -# include -#endif - -#ifdef HAVE_FTGL_UPPERCASE -#include -#else -#include -#endif - -#include -#include -#include -#include -#include -#include - -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 IDList; - - struct OGLFont_Cache { - FTFont* Font; - Standard_Integer FontHeight; - GLCONTEXT GlContext; - }; - - typedef NCollection_DataMap FontDataBase; - typedef FontDataBase::Iterator FontDBIterator; - typedef NCollection_DataMap FontCache; - typedef FontCache::Iterator FontCacheIterator; - - FontDataBase myGeneratedFontDB; - FontCache myGeneratedFontCache; - - Standard_Integer myCurrentFontId; - - Standard_ShortReal myXCurrentScale, - myYCurrentScale; -}; - -#endif //OPENGL_FONT_MGR_H diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index e199386149..1dd334d911 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -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 { diff --git a/src/OpenGl/OpenGl_GraduatedTrihedron.cxx b/src/OpenGl/OpenGl_GraduatedTrihedron.cxx index 200f5f34a9..de72c8c74e 100644 --- a/src/OpenGl/OpenGl_GraduatedTrihedron.cxx +++ b/src/OpenGl/OpenGl_GraduatedTrihedron.cxx @@ -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 #include @@ -30,10 +29,10 @@ #include #ifdef HAVE_CONFIG_H -#include + #include #endif #ifdef HAVE_STRING_H -#include + #include #endif #include @@ -41,11 +40,13 @@ #include #include -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 diff --git a/src/OpenGl/OpenGl_GraduatedTrihedron.hxx b/src/OpenGl/OpenGl_GraduatedTrihedron.hxx index 529620b390..3b128bf7ad 100644 --- a/src/OpenGl/OpenGl_GraduatedTrihedron.hxx +++ b/src/OpenGl/OpenGl_GraduatedTrihedron.hxx @@ -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,63 +17,71 @@ // 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 +#include +#include #include 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 diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 1f9487b152..f626dd2762 100755 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -20,10 +20,16 @@ #include #include +#include +#include #include #include +#include +#include #include +#include + 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); +} diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index fbc2ca03d5..e61b897804 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -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
class OpenGl_GraphicDriver : public Graphic3d_GraphicDriver @@ -337,7 +339,9 @@ private: NCollection_DataMap myMapOfWS; NCollection_DataMap 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 index e69de29bb2..0000000000 diff --git a/src/OpenGl/OpenGl_GraphicDriver_710.cxx b/src/OpenGl/OpenGl_GraphicDriver_710.cxx deleted file mode 100755 index 83d0c802f6..0000000000 --- a/src/OpenGl/OpenGl_GraphicDriver_710.cxx +++ /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 - -#include -#include -#include - -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 index ef4cc2fc52..0000000000 --- a/src/OpenGl/OpenGl_GraphicDriver_9.cxx +++ /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 -#include -#include -#include -#include - -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); -} diff --git a/src/OpenGl/OpenGl_GraphicDriver_Layer.cxx b/src/OpenGl/OpenGl_GraphicDriver_Layer.cxx index d1bc4ce19e..c8f244645c 100755 --- a/src/OpenGl/OpenGl_GraphicDriver_Layer.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver_Layer.cxx @@ -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 #include @@ -26,6 +25,7 @@ #include #include +#include #include /*----------------------------------------------------------------------*/ @@ -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); } diff --git a/src/OpenGl/OpenGl_PrinterContext.cxx b/src/OpenGl/OpenGl_PrinterContext.cxx index 3359844001..8c2d2be383 100644 --- a/src/OpenGl/OpenGl_PrinterContext.cxx +++ b/src/OpenGl/OpenGl_PrinterContext.cxx @@ -17,110 +17,92 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. - +#include #include -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; } diff --git a/src/OpenGl/OpenGl_PrinterContext.hxx b/src/OpenGl/OpenGl_PrinterContext.hxx index 1c6e5063d9..819670abbb 100644 --- a/src/OpenGl/OpenGl_PrinterContext.hxx +++ b/src/OpenGl/OpenGl_PrinterContext.hxx @@ -17,127 +17,79 @@ // 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 - -#include -#include #include -#include -#include -#include -#include #include - -#include - -class Standard_Transient; -class Handle(Standard_Type); -class Handle(MMgt_TShared); -class OpenGl_PrinterContext; - -DEFINE_STANDARD_HANDLE(OpenGl_PrinterContext,MMgt_TShared) +#include //! 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 diff --git a/src/OpenGl/OpenGl_Text.cxx b/src/OpenGl/OpenGl_Text.cxx index 797f4596a9..27b1871e3b 100644 --- a/src/OpenGl/OpenGl_Text.cxx +++ b/src/OpenGl/OpenGl_Text.cxx @@ -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 @@ -19,198 +19,755 @@ #include #include + #include -#include +#include #include -/*----------------------------------------------------------------------*/ +#include +#include + +#ifdef HAVE_CONFIG_H + #include +#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 +#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 (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 } diff --git a/src/OpenGl/OpenGl_Text.hxx b/src/OpenGl/OpenGl_Text.hxx index 3251b43899..b35048870d 100644 --- a/src/OpenGl/OpenGl_Text.hxx +++ b/src/OpenGl/OpenGl_Text.hxx @@ -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 @@ -17,42 +17,147 @@ // 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 +#include #include +#include #include #include #include #include +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 myTextures; //!< textures' IDs + mutable NCollection_Vector myVertsVbo; //!< VBOs of vertices + mutable NCollection_Vector myTCrdsVbo; //!< VBOs of texture coordinates + mutable NCollection_Vector myVertsArray; //!< arrays of vertices (for compatibility mode) + mutable NCollection_Vector 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 index 0000000000..9fcb2b8038 --- /dev/null +++ b/src/OpenGl/OpenGl_TextFormatter.cxx @@ -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 + +#include + +#include + +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& 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& 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& 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& theTextures, + NCollection_Vector< NCollection_Handle > >& theVertsPerTexture, + NCollection_Vector< NCollection_Handle > >& 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()); + theTCrdsPerTexture.Append (new NCollection_Vector()); + } + + NCollection_Vector& aVerts = *theVertsPerTexture.ChangeValue (aListId); + NCollection_Vector& 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& theTextures, + NCollection_Vector& theVertsPerTexture, + NCollection_Vector& theTCrdsPerTexture) const +{ + NCollection_Vector< NCollection_Handle > > aVertsPerTexture; + NCollection_Vector< NCollection_Handle > > 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& 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& 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& theTextures, + NCollection_Vector& theVertsPerTexture, + NCollection_Vector& theTCrdsPerTexture) const +{ + NCollection_Vector< NCollection_Handle > > aVertsPerTexture; + NCollection_Vector< NCollection_Handle > > aTCrdsPerTexture; + Result (theTextures, aVertsPerTexture, aTCrdsPerTexture); + + theVertsPerTexture.Clear(); + theTCrdsPerTexture.Clear(); + + for (Standard_Integer aTextureIter = 0; aTextureIter < theTextures.Length(); ++aTextureIter) + { + const NCollection_Vector& aVerts = *aVertsPerTexture.Value (aTextureIter); + const NCollection_Vector& 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 index 0000000000..efd5935120 --- /dev/null +++ b/src/OpenGl/OpenGl_TextFormatter.hxx @@ -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 +#include + +#include +#include + +#include + +typedef NCollection_Array1 OpenGl_Vec2Array; +typedef NCollection_Handle 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& theTextures, + NCollection_Vector< NCollection_Handle > >& theVertsPerTexture, + NCollection_Vector< NCollection_Handle > >& theTCrdsPerTexture) const; + + //! Retrieve formatting results. + Standard_EXPORT void Result (const Handle(OpenGl_Context)& theCtx, + NCollection_Vector& theTextures, + NCollection_Vector& theVertsPerTexture, + NCollection_Vector& theTCrdsPerTexture) const; + + //! Retrieve formatting results. + Standard_EXPORT void Result (const Handle(OpenGl_Context)& theCtx, + NCollection_Vector& theTextures, + NCollection_Vector& theVertsPerTexture, + NCollection_Vector& 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 + myRects; //!< glyphs rectangles + Standard_Integer myRectsNb; //!< rectangles number + NCollection_Vector + 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 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__ diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 08e7e101be..b7c9c32fd5 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -27,23 +27,6 @@ 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; } diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index 6e9c5e0f83..64f45aa38a 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -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); diff --git a/src/OpenGl/OpenGl_Trihedron.cxx b/src/OpenGl/OpenGl_Trihedron.cxx index 30e245085f..e367c7d599 100644 --- a/src/OpenGl/OpenGl_Trihedron.cxx +++ b/src/OpenGl/OpenGl_Trihedron.cxx @@ -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 #include @@ -34,8 +33,10 @@ #include #include -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 diff --git a/src/OpenGl/OpenGl_Trihedron.hxx b/src/OpenGl/OpenGl_Trihedron.hxx index b28224623b..547536b158 100644 --- a/src/OpenGl/OpenGl_Trihedron.hxx +++ b/src/OpenGl/OpenGl_Trihedron.hxx @@ -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,37 +17,46 @@ // 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 +#include -#include #include - #include #include +#include +#include -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 diff --git a/src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx b/src/OpenGl/OpenGl_Vec.hxx similarity index 67% rename from src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx rename to src/OpenGl/OpenGl_Vec.hxx index c5b90862c3..d659fe34f7 100644 --- a/src/OpenGl/Handle_OpenGl_GraduatedTrihedron.hxx +++ b/src/OpenGl/OpenGl_Vec.hxx @@ -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 @@ -17,18 +17,13 @@ // 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 -#include -#include +typedef NCollection_Vec2 OpenGl_Vec2; +typedef NCollection_Vec3 OpenGl_Vec3; +typedef NCollection_Vec4 OpenGl_Vec4; -class OpenGl_GraduatedTrihedron; - -// Handle definition -// -DEFINE_STANDARD_HANDLE(OpenGl_GraduatedTrihedron,MMgt_TShared) - - -#endif //_Handle_OpenGl_GraduatedTrihedron_Header +#endif // _OpenGl_Vec_H__ diff --git a/src/OpenGl/OpenGl_VertexBufferEditor.hxx b/src/OpenGl/OpenGl_VertexBufferEditor.hxx index b150cb8b93..eacf1417ad 100644 --- a/src/OpenGl/OpenGl_VertexBufferEditor.hxx +++ b/src/OpenGl/OpenGl_VertexBufferEditor.hxx @@ -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: diff --git a/src/OpenGl/OpenGl_View.cxx b/src/OpenGl/OpenGl_View.cxx index 355108a77d..9eae330784 100644 --- a/src/OpenGl/OpenGl_View.cxx +++ b/src/OpenGl/OpenGl_View.cxx @@ -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); } /*----------------------------------------------------------------------*/ diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 49ab5bc9a2..a70b81bf64 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -44,8 +44,6 @@ #include #include -#include -#include #include #include #include @@ -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; diff --git a/src/OpenGl/OpenGl_View_2.cxx b/src/OpenGl/OpenGl_View_2.cxx index 1ecb590aed..d37385f4e9 100644 --- a/src/OpenGl/OpenGl_View_2.cxx +++ b/src/OpenGl/OpenGl_View_2.cxx @@ -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); } diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 29a65c3cc8..cee0ed4c95 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -21,18 +21,21 @@ #include -#include - #include #include #include #include #include - +#include #include +#include #include +#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE) + #include +#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); +} diff --git a/src/OpenGl/OpenGl_Workspace.hxx b/src/OpenGl/OpenGl_Workspace.hxx index d556ceb0b6..57b1bd2d64 100644 --- a/src/OpenGl/OpenGl_Workspace.hxx +++ b/src/OpenGl/OpenGl_Workspace.hxx @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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; diff --git a/src/OpenGl/OpenGl_Workspace_2.cxx b/src/OpenGl/OpenGl_Workspace_2.cxx index bcfa10418c..d5a23e2bab 100644 --- a/src/OpenGl/OpenGl_Workspace_2.cxx +++ b/src/OpenGl/OpenGl_Workspace_2.cxx @@ -297,7 +297,8 @@ static bool imageStretchDC(HDC theDstDC, FipHandle theImage, int theOffsetX, //call_togl_print Standard_Boolean OpenGl_Workspace::Print - (const Graphic3d_CView& ACView, + (const Handle(OpenGl_PrinterContext)& thePrintContext, + const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer, const Aspect_Handle hPrintDC,// const Aspect_Drawable hPrintDC, @@ -306,6 +307,11 @@ Standard_Boolean OpenGl_Workspace::Print const Aspect_PrintAlgo printAlgorithm, const Standard_Real theScaleFactor) { + if (thePrintContext.IsNull()) + { + return Standard_False; + } + #ifdef WNT if (!Activate()) @@ -531,12 +537,11 @@ Standard_Boolean OpenGl_Workspace::Print } // setup printing context and viewport + myPrintContext = thePrintContext; GLint aViewPortBack[4]; GLint anAlignBack = 1; - - OpenGl_PrinterContext aPrinterContext (GetGContext()); - aPrinterContext.SetLayerViewport ((GLsizei)aFrameWidth, - (GLsizei)aFrameHeight); + myPrintContext->SetLayerViewport ((GLsizei )aFrameWidth, + (GLsizei )aFrameHeight); glGetIntegerv (GL_VIEWPORT, aViewPortBack); glGetIntegerv (GL_PACK_ALIGNMENT, &anAlignBack); glPixelStorei (GL_PACK_ALIGNMENT, 4); @@ -565,6 +570,7 @@ Standard_Boolean OpenGl_Workspace::Print DeleteDC (hMemDC); #endif + myPrintContext.Nullify(); return Standard_False; } } @@ -585,8 +591,8 @@ Standard_Boolean OpenGl_Workspace::Print if (!IsTiling) { - aPrinterContext.SetScale ((GLfloat)aFrameWidth /viewWidth, - (GLfloat)aFrameHeight/viewHeight); + myPrintContext->SetScale ((GLfloat )aFrameWidth /viewWidth, + (GLfloat )aFrameHeight/viewHeight); aFrameBuffer->SetupViewport (); Redraw1(ACView, ACUnderLayer, ACOverLayer, 0); if (!myTransientDrawToFront) @@ -647,8 +653,8 @@ Standard_Boolean OpenGl_Workspace::Print // calculate and set the text scaling factor for printing context GLfloat aScaleRatex = (GLfloat)aFrameWidth /viewWidth; GLfloat aScaleRatey = (GLfloat)aFrameHeight/viewHeight; - aPrinterContext.SetScale (aScaleRatex*(GLfloat)aScalex, - aScaleRatey*(GLfloat)aScaley); + myPrintContext->SetScale (aScaleRatex * (GLfloat )aScalex, + aScaleRatey * (GLfloat )aScaley); // initialize projection matrix for printer context TColStd_Array2OfReal aProj (0, 3, 0, 3); @@ -690,7 +696,7 @@ Standard_Boolean OpenGl_Workspace::Print // set projection matrix aProj(0,0) = aScalex; aProj(1,1) = aScaley; - aPrinterContext.SetProjTransformation (aProj); + myPrintContext->SetProjTransformation (aProj); // calculate cropped frame rect aTop = (j == 0) ? aPxCropy : 0; @@ -750,7 +756,6 @@ Standard_Boolean OpenGl_Workspace::Print } // return OpenGl to the previous state - aPrinterContext.Deactivate (); glPixelStorei (GL_PACK_ALIGNMENT, anAlignBack); aFrameBuffer->UnbindBuffer (GetGlContext()); glViewport (aViewPortBack[0], aViewPortBack[1], @@ -778,9 +783,11 @@ Standard_Boolean OpenGl_Workspace::Print // Reset status after printing NamedStatus &= ~OPENGL_NS_WHITEBACK; + myPrintContext.Nullify(); return (Standard_Boolean) isDone; #else // not WNT + myPrintContext.Nullify(); return Standard_False; #endif } @@ -789,9 +796,9 @@ Standard_Boolean OpenGl_Workspace::Print //redrawView void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView, - const Aspect_CLayer2d& ACUnderLayer, - const Aspect_CLayer2d& ACOverLayer, - const int aswap) + const Aspect_CLayer2d& ACUnderLayer, + const Aspect_CLayer2d& ACOverLayer, + const int aswap) { if (myDisplay.IsNull() || myView.IsNull()) return; @@ -840,7 +847,7 @@ void OpenGl_Workspace::Redraw1 (const Graphic3d_CView& ACView, glClear (toClear); Handle(OpenGl_Workspace) aWS(this); - myView->Render(aWS,ACView,ACUnderLayer,ACOverLayer); + myView->Render (myPrintContext, aWS, ACView, ACUnderLayer, ACOverLayer); // Swap the buffers if ( aswap ) diff --git a/src/OpenGl/OpenGl_Workspace_4.cxx b/src/OpenGl/OpenGl_Workspace_4.cxx deleted file mode 100644 index 0dbec40aeb..0000000000 --- a/src/OpenGl/OpenGl_Workspace_4.cxx +++ /dev/null @@ -1,93 +0,0 @@ -// Created on: 2011-09-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 - -#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE) - #include -#endif - -#include -#include -#include - -#include - -//call_togl_redraw -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); -} diff --git a/src/OpenGl/OpenGl_Workspace_5.cxx b/src/OpenGl/OpenGl_Workspace_5.cxx index 0e8510bf14..ef13b7664d 100644 --- a/src/OpenGl/OpenGl_Workspace_5.cxx +++ b/src/OpenGl/OpenGl_Workspace_5.cxx @@ -625,34 +625,13 @@ const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolea /*----------------------------------------------------------------------*/ -const OpenGl_AspectText * OpenGl_Workspace::AspectText(const Standard_Boolean WithApply) +const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply) { - if ( WithApply ) + if (theWithApply) { - Standard_Boolean toApply = Standard_False; - if ( AspectText_set != AspectText_applied ) - { - if ( !AspectText_applied ) - toApply = Standard_True; - else if ( strcmp( AspectText_set->Font(), AspectText_applied->Font() ) || - ( AspectText_set->FontAspect() != AspectText_applied->FontAspect() ) ) - toApply = Standard_True; - - AspectText_applied = AspectText_set; - } - if ( TextParam_set != TextParam_applied ) - { - if ( !TextParam_applied ) - toApply = Standard_True; - else if ( TextParam_set->Height != TextParam_applied->Height ) - toApply = Standard_True; - - TextParam_applied = TextParam_set; - } - if ( toApply ) - { - FindFont(AspectText_applied->Font(), AspectText_applied->FontAspect(), TextParam_applied->Height); - } + AspectText_applied = AspectText_set; + TextParam_applied = TextParam_set; } + return AspectText_set; } diff --git a/src/Standard/Standard.cdl b/src/Standard/Standard.cdl index ac188ddaa7..6ac326174a 100755 --- a/src/Standard/Standard.cdl +++ b/src/Standard/Standard.cdl @@ -67,6 +67,11 @@ is primitive PCharacter; primitive PExtCharacter; + primitive Utf8Char; + primitive Utf16Char; + primitive Utf32Char; + primitive WideChar; + deferred class ErrorHandlerCallback; class ErrorHandler; diff --git a/src/Standard/Standard_Integer.hxx b/src/Standard/Standard_Integer.hxx index 30fcd2814b..5c4fec225e 100755 --- a/src/Standard/Standard_Integer.hxx +++ b/src/Standard/Standard_Integer.hxx @@ -1,5 +1,5 @@ // Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2012 OPEN CASCADE SAS +// Copyright (c) 1999-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 @@ -47,7 +47,6 @@ __Standard_API long NextPrime (const long me); __Standard_API Standard_Integer CharToInt (const Standard_Character me); __Standard_API Standard_Integer CharToInt (const Standard_CString me); __Standard_API Standard_Integer ShallowCopy (const Standard_Integer me); -//__Standard_API Standard_Integer HashCode (const Standard_Integer, const Standard_Integer); // =============== // Inline methods @@ -64,19 +63,41 @@ inline Standard_Integer Abs (const Standard_Integer Value) // ------------------------------------------------------------------ // Hascode : Computes a hascoding value for a given Integer // ------------------------------------------------------------------ -inline Standard_Integer HashCode(const Standard_Integer me, - const Standard_Integer Upper) +inline Standard_Integer HashCode (const Standard_Integer theMe, + const Standard_Integer theUpper) { -// return (Abs(me) % Upper) + 1; - return ( ( me & 0x7fffffff ) % Upper) + 1; + //return (Abs (theMe) % theUpper) + 1; + return ((theMe & 0x7fffffff ) % theUpper) + 1; } // ------------------------------------------------------------------ // IsEqual : Returns Standard_True if two integers are equal // ------------------------------------------------------------------ -inline Standard_Boolean IsEqual(const Standard_Integer One - ,const Standard_Integer Two) -{ return One == Two; } +inline Standard_Boolean IsEqual (const Standard_Integer theOne, + const Standard_Integer theTwo) +{ + return theOne == theTwo; +} + +#if (defined(_LP64) || defined(__LP64__) || defined(_WIN64)) +// ------------------------------------------------------------------ +// Hascode : Computes a hascoding value for a given unsigned integer +// ------------------------------------------------------------------ +inline Standard_Integer HashCode (const Standard_Utf32Char theMe, + const Standard_Integer theUpper) +{ + return ((theMe & 0x7fffffff ) % theUpper) + 1; +} + +// ------------------------------------------------------------------ +// IsEqual : Returns Standard_True if two integers are equal +// ------------------------------------------------------------------ +inline Standard_Boolean IsEqual (const Standard_Utf32Char theOne, + const Standard_Utf32Char theTwo) +{ + return theOne == theTwo; +} +#endif // ------------------------------------------------------------------ // IsSimilar : Returns Standard_True if two integers are equal diff --git a/src/Standard/Standard_TypeDef.hxx b/src/Standard/Standard_TypeDef.hxx index 44bad4cf9d..6744201488 100755 --- a/src/Standard/Standard_TypeDef.hxx +++ b/src/Standard/Standard_TypeDef.hxx @@ -1,5 +1,5 @@ // Copyright (c) 1998-1999 Matra Datavision -// Copyright (c) 1999-2012 OPEN CASCADE SAS +// Copyright (c) 1999-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 @@ -16,13 +16,20 @@ // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. - #ifndef _Standard_TypeDef_HeaderFile #define _Standard_TypeDef_HeaderFile -#include +#include #include +#if(defined(_MSC_VER) && (_MSC_VER < 1600)) + // old MSVC - hasn't stdint header + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#else + #include +#endif + #define Standard_False (Standard_Boolean)0 #define Standard_True (Standard_Boolean)1 @@ -39,10 +46,18 @@ typedef short Standard_ExtCharacter; typedef unsigned char Standard_Byte; typedef void* Standard_Address; typedef size_t Standard_Size; + // typedef const char* Standard_CString; typedef const short* Standard_ExtString; +// Unicode primitives, char16_t, char32_t +typedef char Standard_Utf8Char; //!< signed UTF-8 char +typedef unsigned char Standard_Utf8UChar; //!< unsigned UTF-8 char +typedef uint16_t Standard_Utf16Char; //!< UTF-16 char (always unsigned) +typedef uint32_t Standard_Utf32Char; //!< UTF-32 char (always unsigned) +typedef wchar_t Standard_WideChar; //!< wide char (unsigned UTF-16 on Windows platform and signed UTF-32 on Linux) + typedef std::time_t Standard_Time; #endif diff --git a/src/TKOpenGl/EXTERNLIB b/src/TKOpenGl/EXTERNLIB index e510118c08..0ead3dee1d 100755 --- a/src/TKOpenGl/EXTERNLIB +++ b/src/TKOpenGl/EXTERNLIB @@ -6,7 +6,6 @@ CSF_objc CSF_Appkit CSF_IOKit CSF_FREETYPE -CSF_FTGL CSF_GL2PS CSF_user32 CSF_gdi32 diff --git a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx index 7921522189..c968220c7b 100644 --- a/src/ViewerTest/ViewerTest_OpenGlCommands.cxx +++ b/src/ViewerTest/ViewerTest_OpenGlCommands.cxx @@ -175,7 +175,7 @@ void VUserDrawObj::Render(const Handle(OpenGl_Workspace)& theWorkspace) const const OpenGl_AspectMarker* aMA = theWorkspace->AspectMarker(0); aMA->Type(); const OpenGl_AspectText* aTA = theWorkspace->AspectText(0); - aTA->Font(); + aTA->FontName(); TEL_COLOUR aColor = theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ? *(theWorkspace->HighlightColor) : aLA->Color(); diff --git a/tests/3rdparty/fonts/A3 b/tests/3rdparty/fonts/A3 new file mode 100644 index 0000000000..e438cffa51 --- /dev/null +++ b/tests/3rdparty/fonts/A3 @@ -0,0 +1,20 @@ +puts "============" +puts "OCC23457 Text rendering performance" +puts "Test case performs rendering of single huge text label" +puts "============" +puts "" + +vtrihedron trihedr + +set aFileHandle [open "$::env(CASROOT)/data/step/screw.step" r] +set aText [read $aFileHandle] +close $aFileHandle + +vpoint p0 0 0 -400 +vpoint p1 0 10000 -400 +vpoint p2 1000 0 -400 +vfit + +vdrawtext "$aText" 100 100 -400 000 255 255 0 0 000 1 50 1 Times-Roman + +vfps diff --git a/tests/3rdparty/fonts/A4 b/tests/3rdparty/fonts/A4 new file mode 100644 index 0000000000..c0cda4d1de --- /dev/null +++ b/tests/3rdparty/fonts/A4 @@ -0,0 +1,31 @@ +puts "============" +puts "OCC23457 Text rendering performance" +puts "Test case performs rendering of big number of small text labels" +puts "============" +puts "" + +vtrihedron trihedr + +set aFileHandle [open "$::env(CASROOT)/data/step/screw.step" r] +set aFileData [read $aFileHandle] +close $aFileHandle + +vpoint p0 0 0 -400 +vpoint p1 0 10000 -400 +vpoint p2 1000 0 -400 + +set data [split $aFileData "\n"] +set aLineId 0 +foreach aLine $data { + set aLineY [expr $aLineId * 400] + vdrawtext "$aLine" 100 $aLineY -400 000 255 255 0 0 000 0 20 1 Times-Roman + set aLineId [expr $aLineId + 1] +} + +puts "Number of labels: $aLineId" + +vfit +vzfit +vzoom 20 + +vfps diff --git a/tests/3rdparty/fonts/A5 b/tests/3rdparty/fonts/A5 new file mode 100644 index 0000000000..c399f0666e --- /dev/null +++ b/tests/3rdparty/fonts/A5 @@ -0,0 +1,38 @@ +puts "============" +puts "OCC23457 Text rendering performance" +puts "Test case prints 3D labels with different text alignment styles" +puts "============" +puts "" + +vtrihedron trihedr + +vpoint pTL -700 100 600 +vdrawtext "Top-Left\nFirst line\nLion The Second\n3rd" -700 100 600 000 255 255 0 2 000 1 50 1 Times-Roman + +vpoint pTC 0 100 600 +vdrawtext "Top-Center\nFirst line\nLion The Second\n3rd" 0 100 600 000 255 255 1 2 000 1 50 1 Times-Roman + +vpoint pTR 700 100 600 +vdrawtext "Top-Right\nFirst line\nLion The Second\n3rd" 700 100 600 000 255 255 2 2 000 1 50 1 Times-Roman + +vpoint pCL -700 100 -100 +vdrawtext "Center-Left\nFirst line\nLion The Second\n3rd" -700 100 -100 255 255 255 0 1 000 1 50 1 Times-Roman + +vpoint pCC 0 100 -100 +vdrawtext "Center-Center\nFirst line\nLion The Second\n3rd" 0 100 -100 255 255 255 1 1 000 1 50 1 Times-Roman + +vpoint pCR 700 100 -100 +vdrawtext "Center-Right\nFirst line\nLion The Second\n3rd" 700 100 -100 255 255 255 2 1 000 1 50 1 Times-Roman + +vpoint pBL -700 100 -700 +vdrawtext "Bottom-Left\nFirst line\nLion The Second\n3rd" -700 100 -700 255 255 0 0 0 000 1 50 1 Times-Roman + +vpoint pBC 0 100 -700 +vdrawtext "Bottom-Center\nFirst line\nLion The Second\n3rd" 0 100 -700 255 255 0 1 0 000 1 50 1 Times-Roman + +vpoint pBR 700 100 -700 +vdrawtext "Bottom-Right\nFirst line\nLion The Second\n3rd" 700 100 -700 255 255 0 2 0 000 1 50 1 Times-Roman + +vfit + +vfps diff --git a/tests/3rdparty/fonts/A6 b/tests/3rdparty/fonts/A6 new file mode 100644 index 0000000000..1e46142dac --- /dev/null +++ b/tests/3rdparty/fonts/A6 @@ -0,0 +1,38 @@ +puts "============" +puts "OCC23457 Text rendering performance" +puts "Test case prints 3D labels with different text alignment styles and extra spaces in it" +puts "============" +puts "" + +vtrihedron trihedr + +vpoint pTL -700 100 600 +vdrawtext " Top-Left\nFirst line \nLion The Second\n 3rd " -700 100 600 000 255 255 0 2 000 0 14 2 Arial + +vpoint pTC 0 100 600 +vdrawtext " Top-Center\nFirst line \nLion The Second\n 3rd " 0 100 600 000 255 255 1 2 000 0 14 2 Arial + +vpoint pTR 700 100 600 +vdrawtext " Top-Right\nFirst line \nLion The Second\n 3rd " 700 100 600 000 255 255 2 2 000 0 14 2 Arial + +vpoint pCL -700 100 -100 +vdrawtext " Center-Left\nFirst line \nLion The Second\n 3rd " -700 100 -100 255 255 255 0 1 000 0 14 2 Arial + +vpoint pCC 0 100 -100 +vdrawtext " Center-Center\nFirst line \nLion The Second\n 3rd " 0 100 -100 255 255 255 1 1 000 0 14 2 Arial + +vpoint pCR 700 100 -100 +vdrawtext " Center-Right\nFirst line \nLion The Second\n 3rd " 700 100 -100 255 255 255 2 1 000 0 14 2 Arial + +vpoint pBL -700 100 -700 +vdrawtext " Bottom-Left\nFirst line \nLion The Second\n 3rd " -700 100 -700 255 255 0 0 0 000 0 14 2 Arial + +vpoint pBC 0 100 -700 +vdrawtext " Bottom-Center\nFirst line \nLion The Second\n 3rd " 0 100 -700 255 255 0 1 0 000 0 14 2 Arial + +vpoint pBR 700 100 -700 +vdrawtext " Bottom-Right\nFirst line \nLion The Second\n 3rd " 700 100 -700 255 255 0 2 0 000 0 14 2 Arial + +vfit + +vfps diff --git a/tests/3rdparty/fonts/A7 b/tests/3rdparty/fonts/A7 new file mode 100644 index 0000000000..c0240c1017 --- /dev/null +++ b/tests/3rdparty/fonts/A7 @@ -0,0 +1,28 @@ +puts "============" +puts "OCC23457 Text rendering performance" +puts "Test case prints overlay labels with different subtitle styles" +puts "============" +puts "" + +voverlaytext "Overlay Test Blend" 100 50 16 Times-Roman 255 255 0 blend 0 0 255 + +voverlaytext "Overlay Test Decal" 100 100 16 Times-Roman 255 255 0 decal 0 0 255 + +voverlaytext "Overlay Test Subtitle" 100 150 16 Times-Roman 255 255 0 subtitle 0 0 255 + +voverlaytext "Overlay Test Normal" 100 200 16 Times-Roman 0 255 255 normal 0 0 255 + +voverlaytext " Overlay Test Normal \n Second line" 100 250 16 Times-Roman 0 255 255 normal 0 0 255 + +voverlaytext " Overlay Test Subtitle\n Second line" 100 300 16 Times-Roman 255 255 0 subtitle 0 0 255 + +voverlaytext " Overlay Test Decal \n Second line" 100 350 16 Times-Roman 255 255 0 decal 0 0 255 + +voverlaytext " Overlay Test Blend \n Second line" 100 400 16 Times-Roman 255 255 0 blend 0 0 255 + +box b 1 2 3 +vsetdispmode 1 +vdisplay b +vfit + +vfps -- 2.20.1