0028441: Coding Rules - move out nested Image_PixMap::ImgFormat enumeration to dedica...
[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>
317d68c9 18#include <Font_TextFormatter.hxx>
19
b514beda 20#include <TCollection_AsciiString.hxx>
21#include <TCollection_HAsciiString.hxx>
a174a3c5 22
a174a3c5 23
92efcf78 24IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
25
a174a3c5 26// =======================================================================
27// function : Font_FTFont
28// purpose :
29// =======================================================================
30Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
cbff1e55 31: myFTLib (theFTLib),
32 myFTFace (NULL),
33 myPointSize (0U),
34 myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
35 myUChar (0U)
a174a3c5 36{
37 if (myFTLib.IsNull())
38 {
39 myFTLib = new Font_FTLibrary();
40 }
41}
42
43// =======================================================================
44// function : Font_FTFont
45// purpose :
46// =======================================================================
47Font_FTFont::~Font_FTFont()
48{
49 Release();
50}
51
52// =======================================================================
53// function : Font_FTFont
54// purpose :
55// =======================================================================
56void Font_FTFont::Release()
57{
58 myGlyphImg.Clear();
59 myFontPath.Clear();
60 myUChar = 0;
61 if (myFTFace != NULL)
62 {
63 FT_Done_Face (myFTFace);
64 myFTFace = NULL;
65 }
66}
67
68// =======================================================================
b514beda 69// function : Init
a174a3c5 70// purpose :
71// =======================================================================
72bool Font_FTFont::Init (const NCollection_String& theFontPath,
73 const unsigned int thePointSize,
74 const unsigned int theResolution)
75{
76 Release();
77 myFontPath = theFontPath;
78 myPointSize = thePointSize;
79 if (!myFTLib->IsValid())
80 {
63c629aa 81 //std::cerr << "FreeType library is unavailable!\n";
a174a3c5 82 Release();
83 return false;
84 }
85
86 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
87 {
88 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
89 Release();
90 return false;
91 }
92 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
93 {
94 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
95 Release();
96 return false;
97 }
98 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
99 {
100 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
101 Release();
102 return false;
103 }
104 return true;
105}
106
b514beda 107// =======================================================================
108// function : Init
109// purpose :
110// =======================================================================
111bool Font_FTFont::Init (const NCollection_String& theFontName,
112 const Font_FontAspect theFontAspect,
113 const unsigned int thePointSize,
114 const unsigned int theResolution)
115{
116 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
117 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
118 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
119 return !aRequestedFont.IsNull()
120 && Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
121}
122
a174a3c5 123// =======================================================================
124// function : loadGlyph
125// purpose :
126// =======================================================================
127bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
128{
129 if (myUChar == theUChar)
130 {
131 return true;
132 }
133
134 myGlyphImg.Clear();
135 myUChar = 0;
136 if (theUChar == 0
6788f423 137 || FT_Load_Char (myFTFace, theUChar, myLoadFlags) != 0
a174a3c5 138 || myFTFace->glyph == NULL)
139 {
140 return false;
141 }
142
143 myUChar = theUChar;
144 return true;
145}
146
147// =======================================================================
148// function : RenderGlyph
149// purpose :
150// =======================================================================
151bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
152{
153 myGlyphImg.Clear();
154 myUChar = 0;
155 if (theUChar == 0
6788f423 156 || FT_Load_Char (myFTFace, theUChar, myLoadFlags | FT_LOAD_RENDER) != 0
a174a3c5 157 || myFTFace->glyph == NULL
158 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
159 {
160 return false;
161 }
162
163 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
164 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
49297cb6 165 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
a174a3c5 166 {
167 return false;
168 }
dc858f4c 169 if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
a174a3c5 170 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
171 {
172 return false;
173 }
174 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
175 myUChar = theUChar;
176 return true;
177}
178
179// =======================================================================
180// function : GlyphMaxSizeX
181// purpose :
182// =======================================================================
183unsigned int Font_FTFont::GlyphMaxSizeX() const
184{
185 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
186 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
187 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
188 return (unsigned int)(aWidth + 0.5f);
189}
190
191// =======================================================================
192// function : GlyphMaxSizeY
193// purpose :
194// =======================================================================
195unsigned int Font_FTFont::GlyphMaxSizeY() const
196{
197 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
198 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
199 : fromFTPoints<float> (myFTFace->size->metrics.height);
200 return (unsigned int)(aHeight + 0.5f);
201}
202
203// =======================================================================
204// function : AdvanceX
205// purpose :
206// =======================================================================
207float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
208 const Standard_Utf32Char theUCharNext)
209{
210 loadGlyph (theUChar);
211 return AdvanceX (theUCharNext);
212}
213
214// =======================================================================
215// function : AdvanceY
216// purpose :
217// =======================================================================
218float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
219 const Standard_Utf32Char theUCharNext)
220{
221 loadGlyph (theUChar);
222 return AdvanceY (theUCharNext);
223}
224
225// =======================================================================
226// function : AdvanceX
227// purpose :
228// =======================================================================
229float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
230{
231 if (myUChar == 0)
232 {
233 return 0.0f;
234 }
235
236 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
237 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
238 {
239 return fromFTPoints<float> (myFTFace->glyph->advance.x);
240 }
241 return fromFTPoints<float> (myKernAdvance.x + myFTFace->glyph->advance.x);
242}
243
244// =======================================================================
245// function : AdvanceY
246// purpose :
247// =======================================================================
248float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
249{
250 if (myUChar == 0)
251 {
252 return 0.0f;
253 }
254
255 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
256 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
257 {
258 return fromFTPoints<float> (myFTFace->glyph->advance.y);
259 }
260 return fromFTPoints<float> (myKernAdvance.y + myFTFace->glyph->advance.y);
261}
317d68c9 262
263// =======================================================================
264// function : BoundingBox
265// purpose :
266// =======================================================================
d2eddacc 267Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theString,
268 const Graphic3d_HorizontalTextAlignment theAlignX,
269 const Graphic3d_VerticalTextAlignment theAlignY)
317d68c9 270{
271 Font_TextFormatter aFormatter;
272 aFormatter.SetupAlignment (theAlignX, theAlignY);
273 aFormatter.Reset();
274
275 aFormatter.Append (theString, *this);
276 aFormatter.Format();
277
d2eddacc 278 Font_Rect aBndBox;
317d68c9 279 aFormatter.BndBox (aBndBox);
317d68c9 280 return aBndBox;
281}