0024211: Definition of Basic Runtime Check parameter causes regression in debug mode
[occt.git] / src / Font / Font_FTFont.cxx
CommitLineData
a174a3c5 1// Created on: 2013-01-28
2// Created by: Kirill GAVRILOV
3// Copyright (c) 2013 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
20#include <Font_FTFont.hxx>
21
22IMPLEMENT_STANDARD_HANDLE (Font_FTFont, Standard_Transient)
23IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont, Standard_Transient)
24
25// =======================================================================
26// function : Font_FTFont
27// purpose :
28// =======================================================================
29Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
30: myFTLib (theFTLib),
31 myFTFace (NULL),
32 myPointSize (0),
33 myUChar (0)
34{
35 if (myFTLib.IsNull())
36 {
37 myFTLib = new Font_FTLibrary();
38 }
39}
40
41// =======================================================================
42// function : Font_FTFont
43// purpose :
44// =======================================================================
45Font_FTFont::~Font_FTFont()
46{
47 Release();
48}
49
50// =======================================================================
51// function : Font_FTFont
52// purpose :
53// =======================================================================
54void Font_FTFont::Release()
55{
56 myGlyphImg.Clear();
57 myFontPath.Clear();
58 myUChar = 0;
59 if (myFTFace != NULL)
60 {
61 FT_Done_Face (myFTFace);
62 myFTFace = NULL;
63 }
64}
65
66// =======================================================================
67// function : Font_FTFont
68// purpose :
69// =======================================================================
70bool Font_FTFont::Init (const NCollection_String& theFontPath,
71 const unsigned int thePointSize,
72 const unsigned int theResolution)
73{
74 Release();
75 myFontPath = theFontPath;
76 myPointSize = thePointSize;
77 if (!myFTLib->IsValid())
78 {
79 std::cerr << "FreeType library is unavailable!\n";
80 Release();
81 return false;
82 }
83
84 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
85 {
86 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
87 Release();
88 return false;
89 }
90 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
91 {
92 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
93 Release();
94 return false;
95 }
96 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
97 {
98 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
99 Release();
100 return false;
101 }
102 return true;
103}
104
105// =======================================================================
106// function : loadGlyph
107// purpose :
108// =======================================================================
109bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
110{
111 if (myUChar == theUChar)
112 {
113 return true;
114 }
115
116 myGlyphImg.Clear();
117 myUChar = 0;
118 if (theUChar == 0
119 || FT_Load_Char (myFTFace, theUChar, FT_LOAD_TARGET_NORMAL) != 0
120 || myFTFace->glyph == NULL)
121 {
122 return false;
123 }
124
125 myUChar = theUChar;
126 return true;
127}
128
129// =======================================================================
130// function : RenderGlyph
131// purpose :
132// =======================================================================
133bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
134{
135 myGlyphImg.Clear();
136 myUChar = 0;
137 if (theUChar == 0
138 || FT_Load_Char (myFTFace, theUChar, FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL) != 0
139 || myFTFace->glyph == NULL
140 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
141 {
142 return false;
143 }
144
145 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
146 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
147 || aBitmap.buffer == NULL || aBitmap.width <= 0 || aBitmap.rows <= 0)
148 {
149 return false;
150 }
151 if (!myGlyphImg.InitWrapper (Image_PixMap::ImgGray, aBitmap.buffer,
152 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
153 {
154 return false;
155 }
156 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
157 myUChar = theUChar;
158 return true;
159}
160
161// =======================================================================
162// function : GlyphMaxSizeX
163// purpose :
164// =======================================================================
165unsigned int Font_FTFont::GlyphMaxSizeX() const
166{
167 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
168 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
169 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
170 return (unsigned int)(aWidth + 0.5f);
171}
172
173// =======================================================================
174// function : GlyphMaxSizeY
175// purpose :
176// =======================================================================
177unsigned int Font_FTFont::GlyphMaxSizeY() const
178{
179 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
180 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
181 : fromFTPoints<float> (myFTFace->size->metrics.height);
182 return (unsigned int)(aHeight + 0.5f);
183}
184
185// =======================================================================
186// function : AdvanceX
187// purpose :
188// =======================================================================
189float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
190 const Standard_Utf32Char theUCharNext)
191{
192 loadGlyph (theUChar);
193 return AdvanceX (theUCharNext);
194}
195
196// =======================================================================
197// function : AdvanceY
198// purpose :
199// =======================================================================
200float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
201 const Standard_Utf32Char theUCharNext)
202{
203 loadGlyph (theUChar);
204 return AdvanceY (theUCharNext);
205}
206
207// =======================================================================
208// function : AdvanceX
209// purpose :
210// =======================================================================
211float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
212{
213 if (myUChar == 0)
214 {
215 return 0.0f;
216 }
217
218 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
219 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
220 {
221 return fromFTPoints<float> (myFTFace->glyph->advance.x);
222 }
223 return fromFTPoints<float> (myKernAdvance.x + myFTFace->glyph->advance.x);
224}
225
226// =======================================================================
227// function : AdvanceY
228// purpose :
229// =======================================================================
230float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
231{
232 if (myUChar == 0)
233 {
234 return 0.0f;
235 }
236
237 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
238 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
239 {
240 return fromFTPoints<float> (myFTFace->glyph->advance.y);
241 }
242 return fromFTPoints<float> (myKernAdvance.y + myFTFace->glyph->advance.y);
243}