0023415: OSD_FontMgr can't idenify aspect for fonts with names dependant on system...
[occt.git] / src / OpenGl / OpenGl_FontMgr.cxx
CommitLineData
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
32float h_scale = 0;
33
34void dump_texture( int id);
35
36class Font_DataMap:
37 public NCollection_DataMap< Handle(TCollection_HAsciiString),
38 Handle(TCollection_HAsciiString)>
39{
40public:
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};
55inline Standard_Boolean
56IsEqual( const Handle(TCollection_HAsciiString)& h1,
57 const Handle(TCollection_HAsciiString)& h2 )
58{
59 return (!h1->IsLess(h2) && !h1->IsGreater(h2));
60}
61
62OpenGl_FontMgr::OpenGl_FontMgr()
aff395a3 63: myCurrentFontId(-1),
64myXCurrentScale(1.f),
65myYCurrentScale(1.f)
7fd59977 66{
67}
68
69OpenGl_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 82int 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
163void 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, &param);
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
214void 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
219const 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
224Standard_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
236void 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
250void 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}