Corrected integration for issue 26393
[occt.git] / src / Font / Font_FTFont.cxx
CommitLineData
a174a3c5 1// Created on: 2013-01-28
2// Created by: Kirill GAVRILOV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
a174a3c5 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
a174a3c5 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
a174a3c5 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
a174a3c5 15
16#include <Font_FTFont.hxx>
b514beda 17#include <Font_FontMgr.hxx>
18#include <TCollection_AsciiString.hxx>
19#include <TCollection_HAsciiString.hxx>
a174a3c5 20
a174a3c5 21
22// =======================================================================
23// function : Font_FTFont
24// purpose :
25// =======================================================================
26Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
cbff1e55 27: myFTLib (theFTLib),
28 myFTFace (NULL),
29 myPointSize (0U),
30 myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
31 myUChar (0U)
a174a3c5 32{
33 if (myFTLib.IsNull())
34 {
35 myFTLib = new Font_FTLibrary();
36 }
37}
38
39// =======================================================================
40// function : Font_FTFont
41// purpose :
42// =======================================================================
43Font_FTFont::~Font_FTFont()
44{
45 Release();
46}
47
48// =======================================================================
49// function : Font_FTFont
50// purpose :
51// =======================================================================
52void Font_FTFont::Release()
53{
54 myGlyphImg.Clear();
55 myFontPath.Clear();
56 myUChar = 0;
57 if (myFTFace != NULL)
58 {
59 FT_Done_Face (myFTFace);
60 myFTFace = NULL;
61 }
62}
63
64// =======================================================================
b514beda 65// function : Init
a174a3c5 66// purpose :
67// =======================================================================
68bool Font_FTFont::Init (const NCollection_String& theFontPath,
69 const unsigned int thePointSize,
70 const unsigned int theResolution)
71{
72 Release();
73 myFontPath = theFontPath;
74 myPointSize = thePointSize;
75 if (!myFTLib->IsValid())
76 {
63c629aa 77 //std::cerr << "FreeType library is unavailable!\n";
a174a3c5 78 Release();
79 return false;
80 }
81
82 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
83 {
84 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
85 Release();
86 return false;
87 }
88 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
89 {
90 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
91 Release();
92 return false;
93 }
94 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
95 {
96 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
97 Release();
98 return false;
99 }
100 return true;
101}
102
b514beda 103// =======================================================================
104// function : Init
105// purpose :
106// =======================================================================
107bool Font_FTFont::Init (const NCollection_String& theFontName,
108 const Font_FontAspect theFontAspect,
109 const unsigned int thePointSize,
110 const unsigned int theResolution)
111{
112 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
113 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
114 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
115 return !aRequestedFont.IsNull()
116 && Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
117}
118
a174a3c5 119// =======================================================================
120// function : loadGlyph
121// purpose :
122// =======================================================================
123bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
124{
125 if (myUChar == theUChar)
126 {
127 return true;
128 }
129
130 myGlyphImg.Clear();
131 myUChar = 0;
132 if (theUChar == 0
6788f423 133 || FT_Load_Char (myFTFace, theUChar, myLoadFlags) != 0
a174a3c5 134 || myFTFace->glyph == NULL)
135 {
136 return false;
137 }
138
139 myUChar = theUChar;
140 return true;
141}
142
143// =======================================================================
144// function : RenderGlyph
145// purpose :
146// =======================================================================
147bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
148{
149 myGlyphImg.Clear();
150 myUChar = 0;
151 if (theUChar == 0
6788f423 152 || FT_Load_Char (myFTFace, theUChar, myLoadFlags | FT_LOAD_RENDER) != 0
a174a3c5 153 || myFTFace->glyph == NULL
154 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
155 {
156 return false;
157 }
158
159 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
160 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
49297cb6 161 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
a174a3c5 162 {
163 return false;
164 }
076ca35c 165 if (!myGlyphImg.InitWrapper (Image_PixMap::ImgAlpha, aBitmap.buffer,
a174a3c5 166 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
167 {
168 return false;
169 }
170 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
171 myUChar = theUChar;
172 return true;
173}
174
175// =======================================================================
176// function : GlyphMaxSizeX
177// purpose :
178// =======================================================================
179unsigned int Font_FTFont::GlyphMaxSizeX() const
180{
181 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
182 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
183 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
184 return (unsigned int)(aWidth + 0.5f);
185}
186
187// =======================================================================
188// function : GlyphMaxSizeY
189// purpose :
190// =======================================================================
191unsigned int Font_FTFont::GlyphMaxSizeY() const
192{
193 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
194 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
195 : fromFTPoints<float> (myFTFace->size->metrics.height);
196 return (unsigned int)(aHeight + 0.5f);
197}
198
199// =======================================================================
200// function : AdvanceX
201// purpose :
202// =======================================================================
203float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
204 const Standard_Utf32Char theUCharNext)
205{
206 loadGlyph (theUChar);
207 return AdvanceX (theUCharNext);
208}
209
210// =======================================================================
211// function : AdvanceY
212// purpose :
213// =======================================================================
214float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
215 const Standard_Utf32Char theUCharNext)
216{
217 loadGlyph (theUChar);
218 return AdvanceY (theUCharNext);
219}
220
221// =======================================================================
222// function : AdvanceX
223// purpose :
224// =======================================================================
225float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
226{
227 if (myUChar == 0)
228 {
229 return 0.0f;
230 }
231
232 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
233 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
234 {
235 return fromFTPoints<float> (myFTFace->glyph->advance.x);
236 }
237 return fromFTPoints<float> (myKernAdvance.x + myFTFace->glyph->advance.x);
238}
239
240// =======================================================================
241// function : AdvanceY
242// purpose :
243// =======================================================================
244float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
245{
246 if (myUChar == 0)
247 {
248 return 0.0f;
249 }
250
251 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
252 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
253 {
254 return fromFTPoints<float> (myFTFace->glyph->advance.y);
255 }
256 return fromFTPoints<float> (myKernAdvance.y + myFTFace->glyph->advance.y);
257}