Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
2 | // | |
3 | // The content of this file is subject to the Open CASCADE Technology Public | |
4 | // License Version 6.5 (the "License"). You may not use the content of this file | |
5 | // except in compliance with the License. Please obtain a copy of the License | |
6 | // at http://www.opencascade.org and read it completely before using this file. | |
7 | // | |
8 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
9 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
10 | // | |
11 | // The Original Code and all software distributed under the License is | |
12 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
13 | // Initial Developer hereby disclaims all such warranties, including without | |
14 | // limitation, any warranties of merchantability, fitness for a particular | |
15 | // purpose or non-infringement. Please see the License for the specific terms | |
16 | // and conditions governing the rights and limitations under the License. | |
17 | ||
7fd59977 | 18 | #include <OpenGl_FontMgr.hxx> |
567148d8 | 19 | #include <OpenGl_GlCore11.hxx> |
7fd59977 | 20 | |
7fd59977 | 21 | #include <Standard_Stream.hxx> |
aff395a3 | 22 | #include <TColStd_SequenceOfHAsciiString.hxx> |
567148d8 | 23 | |
24 | #ifdef _MSC_VER | |
25 | #pragma comment( lib, "ftgl.lib" ) | |
567148d8 | 26 | #endif |
27 | ||
7fd59977 | 28 | #undef TRACE |
29 | ||
30 | #define DEFAULT_FONT_HEIGHT 16 | |
31 | ||
32 | float h_scale = 0; | |
33 | ||
34 | void dump_texture( int id); | |
35 | ||
36 | class Font_DataMap: | |
37 | public NCollection_DataMap< Handle(TCollection_HAsciiString), | |
38 | Handle(TCollection_HAsciiString)> | |
39 | { | |
40 | public: | |
41 | inline Font_DataMap | |
42 | (const Standard_Integer NbBuckets = 1, | |
43 | const Handle(NCollection_BaseAllocator)& theAllocator = 0L) | |
44 | : NCollection_DataMap<Handle(TCollection_HAsciiString), | |
45 | Handle(TCollection_HAsciiString)> (NbBuckets, theAllocator) | |
46 | {} | |
47 | ||
48 | inline Font_DataMap (const Font_DataMap& theOther) | |
49 | : NCollection_DataMap<Handle(TCollection_HAsciiString), | |
50 | Handle(TCollection_HAsciiString)> (theOther) | |
51 | {} | |
52 | friend Standard_Boolean IsEqual( const Handle(TCollection_HAsciiString)& h1, | |
53 | const Handle(TCollection_HAsciiString)& h2 ); | |
54 | }; | |
55 | inline Standard_Boolean | |
56 | IsEqual( const Handle(TCollection_HAsciiString)& h1, | |
57 | const Handle(TCollection_HAsciiString)& h2 ) | |
58 | { | |
59 | return (!h1->IsLess(h2) && !h1->IsGreater(h2)); | |
60 | } | |
61 | ||
62 | OpenGl_FontMgr::OpenGl_FontMgr() | |
aff395a3 | 63 | : myCurrentFontId(-1), |
64 | myXCurrentScale(1.f), | |
65 | myYCurrentScale(1.f) | |
7fd59977 | 66 | { |
67 | } | |
68 | ||
69 | OpenGl_FontMgr* OpenGl_FontMgr::instance() | |
70 | { | |
71 | static OpenGl_FontMgr* _mgr = NULL; | |
72 | if ( _mgr == NULL ) | |
73 | { | |
74 | _mgr = new OpenGl_FontMgr(); | |
7fd59977 | 75 | } |
76 | return _mgr; | |
77 | } | |
78 | ||
7fd59977 | 79 | // Empty fontName means that ANY family name can be used. |
eeaaaefb | 80 | // fontAspect == Font_FA_Undefined means ANY font aspect is acceptable. |
7fd59977 | 81 | // fontheight == -1 means ANY font height is acceptable. |
aff395a3 | 82 | int OpenGl_FontMgr::request_font (const Handle(TCollection_HAsciiString)& theFontName, |
83 | const Font_FontAspect theFontAspect, | |
84 | const Standard_Integer& theFontHeight) | |
7fd59977 | 85 | { |
aff395a3 | 86 | Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance(); |
87 | Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (theFontName, theFontAspect, theFontHeight); | |
88 | ||
89 | if (aRequestedFont.IsNull()) | |
7fd59977 | 90 | { |
7fd59977 | 91 | return -1; |
aff395a3 | 92 | } |
7fd59977 | 93 | |
aff395a3 | 94 | // Setting font height |
95 | Standard_Integer aFontHeight = theFontHeight; | |
96 | if (theFontHeight < 2 && aRequestedFont->FontHeight() == -1) | |
97 | { | |
98 | // Font height is not specified -> use DEFAULT_FONT_HEIGHT for variable-height fonts | |
99 | aFontHeight = DEFAULT_FONT_HEIGHT; | |
100 | } | |
101 | else if (theFontHeight < 2) | |
102 | { | |
103 | // Font height is not specified -> use font height for fixed size fonts | |
104 | aFontHeight = aRequestedFont->FontHeight(); | |
105 | } | |
7fd59977 | 106 | |
aff395a3 | 107 | GLCONTEXT aContext = GET_GL_CONTEXT(); |
7fd59977 | 108 | |
aff395a3 | 109 | // Check in already generated fonts. |
110 | if (myGeneratedFontDB.IsBound (aRequestedFont)) | |
111 | { | |
112 | const IDList& anIDList = myGeneratedFontDB.Find (aRequestedFont); | |
113 | for (IDList::Iterator anIDListIterator (anIDList); anIDListIterator.More(); | |
114 | anIDListIterator.Next()) | |
115 | { | |
116 | OGLFont_Cache aFontCache = myGeneratedFontCache (anIDListIterator.Value()); | |
117 | if (aFontCache.FontHeight == aFontHeight && aFontCache.GlContext == aContext) | |
7fd59977 | 118 | { |
aff395a3 | 119 | // Requested font is already generated, returning it cache ID. |
120 | myCurrentFontId = anIDListIterator.Value(); | |
121 | return myCurrentFontId; | |
7fd59977 | 122 | } |
aff395a3 | 123 | } |
124 | } | |
7fd59977 | 125 | |
aff395a3 | 126 | // Cache for requested font is not found. Generating new FTGL font. |
127 | FTGLTextureFont* aFTGLFont = new FTGLTextureFont(aRequestedFont->FontPath()->ToCString()); | |
128 | if ( !aFTGLFont || aFTGLFont->Error() != FT_Err_Ok) | |
129 | { | |
130 | return -1; // Error during creation FTGL font object! | |
131 | } | |
7fd59977 | 132 | |
aff395a3 | 133 | if ( !aFTGLFont->FaceSize (aFontHeight) || aFTGLFont->Error() != FT_Err_Ok ) |
134 | { | |
135 | return -1; // Error during setup FTGL font height! | |
136 | } | |
7fd59977 | 137 | |
aff395a3 | 138 | aFTGLFont->UseDisplayList (false); |
7fd59977 | 139 | |
aff395a3 | 140 | // Adding font to cache. |
141 | OGLFont_Cache aCache; | |
142 | aCache.Font = aFTGLFont; | |
143 | aCache.FontHeight = aFontHeight; | |
144 | aCache.GlContext = aContext; | |
7fd59977 | 145 | |
aff395a3 | 146 | myCurrentFontId = myGeneratedFontCache.Size() + 1; |
147 | myGeneratedFontCache.Bind ( myCurrentFontId, aCache); | |
7fd59977 | 148 | |
aff395a3 | 149 | if (myGeneratedFontDB.IsBound (aRequestedFont)) |
150 | { | |
151 | myGeneratedFontDB.ChangeFind (aRequestedFont).Append (myCurrentFontId); | |
7fd59977 | 152 | } |
aff395a3 | 153 | else |
154 | { | |
155 | IDList anIDList; | |
156 | anIDList.Append (myCurrentFontId); | |
157 | myGeneratedFontDB.Bind (aRequestedFont, anIDList); | |
158 | } | |
159 | ||
160 | return myCurrentFontId; | |
7fd59977 | 161 | } |
162 | ||
13a22457 S |
163 | void OpenGl_FontMgr::render_text( const Standard_Integer id, const wchar_t* text, |
164 | const Standard_Boolean is2d ) | |
7fd59977 | 165 | { |
166 | #ifdef TRACE | |
167 | cout << "TKOpenGl::render_text\n" | |
168 | << "\tfont id = " << id << endl | |
169 | << "\ttext = " << text << endl; | |
170 | #endif | |
aff395a3 | 171 | if ( text && myGeneratedFontCache.IsBound( id ) ) { |
7fd59977 | 172 | glMatrixMode( GL_MODELVIEW ); |
173 | glPushMatrix(); | |
174 | ||
aff395a3 | 175 | glScalef( myXCurrentScale, myYCurrentScale, 1 ); |
7fd59977 | 176 | glPushAttrib( GL_ENABLE_BIT ); |
177 | ||
178 | GLboolean enableTexture = glIsEnabled(GL_TEXTURE_2D); | |
179 | GLboolean enableDepthTest = glIsEnabled(GL_DEPTH_TEST); | |
180 | ||
181 | if( !enableTexture ) | |
182 | glEnable(GL_TEXTURE_2D); | |
256d4320 A |
183 | if ( !is2d ) { |
184 | if ( !enableDepthTest ) | |
185 | glEnable(GL_DEPTH_TEST); | |
13a22457 | 186 | } |
256d4320 A |
187 | else if ( enableDepthTest ) { |
188 | glDisable(GL_DEPTH_TEST); | |
189 | } | |
7fd59977 | 190 | |
c320e557 A |
191 | GLint param; |
192 | glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, ¶m); | |
7fd59977 | 193 | |
194 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
195 | glAlphaFunc(GL_GEQUAL, 0.285f); | |
196 | glEnable(GL_ALPHA_TEST); | |
aff395a3 | 197 | OGLFont_Cache cache = myGeneratedFontCache.Find( id ); |
7fd59977 | 198 | cache.Font->Render( text ); |
199 | ||
c320e557 | 200 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param); |
7fd59977 | 201 | |
202 | if( !enableTexture ) | |
203 | glDisable(GL_TEXTURE_2D); | |
204 | if( !enableDepthTest ) | |
205 | glDisable(GL_DEPTH_TEST); | |
206 | ||
7fd59977 | 207 | glPopAttrib(); |
208 | glMatrixMode( GL_MODELVIEW ); | |
209 | glPopMatrix(); | |
210 | } | |
211 | ||
212 | } | |
213 | ||
13a22457 S |
214 | void OpenGl_FontMgr::render_text ( const wchar_t* text, const Standard_Boolean is2d ) |
215 | { | |
aff395a3 | 216 | render_text( myCurrentFontId, text, is2d ); |
7fd59977 | 217 | } |
218 | ||
13a22457 S |
219 | const FTFont* OpenGl_FontMgr::fontById (const Standard_Integer id) |
220 | { | |
aff395a3 | 221 | return myGeneratedFontCache.IsBound( id ) ? myGeneratedFontCache.Find( id ).Font: NULL; |
7fd59977 | 222 | } |
223 | ||
13a22457 S |
224 | Standard_ShortReal OpenGl_FontMgr::computeWidth( const Standard_Integer id, const wchar_t* text ) |
225 | { | |
aff395a3 | 226 | if( !myGeneratedFontCache.IsBound( id ) ) |
7fd59977 | 227 | return 0.f; |
228 | ||
aff395a3 | 229 | OGLFont_Cache cache = myGeneratedFontCache.Find( id ); |
7fd59977 | 230 | |
13a22457 | 231 | Standard_ShortReal w = cache.Font->Advance( text ); |
7fd59977 | 232 | |
233 | return w; | |
234 | } | |
235 | ||
13a22457 S |
236 | void OpenGl_FontMgr::setCurrentScale (const Standard_ShortReal xScale, |
237 | const Standard_ShortReal yScale) | |
7fd59977 | 238 | { |
aff395a3 | 239 | myXCurrentScale = xScale; |
240 | myYCurrentScale = yScale; | |
7fd59977 | 241 | } |
242 | ||
243 | #include <AlienImage_BMPAlienData.hxx> | |
244 | #include <OSD_File.hxx> | |
245 | #include <OSD_Protection.hxx> | |
246 | #include <Aspect_GenericColorMap.hxx> | |
247 | #include <Image_ColorImage.hxx> | |
248 | #include <Quantity_Color.hxx> | |
249 | ||
13a22457 S |
250 | void dump_texture( int id) |
251 | { | |
7fd59977 | 252 | Handle(AlienImage_BMPAlienData) image = new AlienImage_BMPAlienData(); |
253 | ||
254 | if (!glIsTexture(id)) | |
255 | return; | |
256 | ||
257 | unsigned char* pixels = new unsigned char[8192*1024]; | |
258 | memset( pixels, 0, 8192*1024 ); | |
259 | static int index = 0; | |
260 | index++; | |
261 | ||
262 | glBindTexture(GL_TEXTURE_2D, id ); | |
263 | glGetTexImage( GL_TEXTURE_2D , | |
264 | 0, | |
265 | GL_ALPHA, | |
266 | GL_UNSIGNED_BYTE, | |
267 | pixels ); | |
268 | ||
269 | Handle(Image_ColorImage) anImage = new Image_ColorImage( 0, 0, 1024, 8192 ); | |
270 | ||
271 | Aspect_ColorPixel mark( Quantity_Color (0.,0.5,1., Quantity_TOC_RGB ) ), | |
272 | space( Quantity_Color (1.,1.,1., Quantity_TOC_RGB ) ); | |
273 | ||
274 | for( int i = 0; i < 1024; i++ ) { | |
275 | for (int j = 0; j < 8192; j++ ) | |
276 | if (pixels[i*8192+j]>0) { | |
277 | anImage->SetPixel( anImage->LowerX()+i, | |
278 | anImage->LowerY()+j, | |
279 | mark ); | |
280 | } | |
281 | else { | |
282 | anImage->SetPixel( anImage->LowerX()+i, | |
283 | anImage->LowerY()+j, | |
284 | space ); | |
285 | } | |
286 | } | |
287 | ||
288 | image->FromImage( anImage ); | |
289 | TCollection_AsciiString name( index ); | |
290 | name.Prepend( "D:\\Temp_image" ); | |
291 | name += ".bmp"; | |
292 | OSD_File file ( name ); | |
293 | file.Build( OSD_WriteOnly, OSD_Protection()); | |
294 | image->Write(file); | |
295 | file.Close(); | |
296 | delete []pixels; | |
297 | } |