1 // Created on: 2013-01-28
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <Font_FTFont.hxx>
18 #include <Font_FTLibrary.hxx>
19 #include <Font_FontMgr.hxx>
20 #include <Font_TextFormatter.hxx>
23 #include FT_FREETYPE_H
25 IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
27 // =======================================================================
28 // function : Font_FTFont
30 // =======================================================================
31 Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
36 myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
37 myIsSingleLine(false),
42 myFTLib = new Font_FTLibrary();
46 // =======================================================================
47 // function : Font_FTFont
49 // =======================================================================
50 Font_FTFont::~Font_FTFont()
55 // =======================================================================
58 // =======================================================================
59 void Font_FTFont::Release()
66 FT_Done_Face (myFTFace);
71 // =======================================================================
74 // =======================================================================
75 bool Font_FTFont::Init (const NCollection_String& theFontPath,
76 const unsigned int thePointSize,
77 const unsigned int theResolution)
80 myFontPath = theFontPath;
81 myPointSize = thePointSize;
82 if (!myFTLib->IsValid())
84 //std::cerr << "FreeType library is unavailable!\n";
89 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
91 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
95 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
97 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
101 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
103 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
110 // =======================================================================
113 // =======================================================================
114 bool Font_FTFont::Init (const NCollection_String& theFontName,
115 const Font_FontAspect theFontAspect,
116 const unsigned int thePointSize,
117 const unsigned int theResolution)
119 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
120 const TCollection_AsciiString aFontName (theFontName.ToCString());
121 Font_FontAspect aFontAspect = theFontAspect;
122 if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, aFontAspect))
124 myIsSingleLine = aRequestedFont->IsSingleStrokeFont();
125 return Font_FTFont::Init (aRequestedFont->FontPathAny (aFontAspect).ToCString(), thePointSize, theResolution);
130 // =======================================================================
131 // function : loadGlyph
133 // =======================================================================
134 bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
136 if (myUChar == theUChar)
144 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
145 || myFTFace->glyph == NULL)
154 // =======================================================================
155 // function : RenderGlyph
157 // =======================================================================
158 bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
163 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
164 || myFTFace->glyph == NULL
165 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
170 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
171 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
172 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
176 if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
177 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
181 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
186 // =======================================================================
187 // function : GlyphMaxSizeX
189 // =======================================================================
190 unsigned int Font_FTFont::GlyphMaxSizeX() const
192 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
193 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
194 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
195 return (unsigned int)(aWidth + 0.5f);
198 // =======================================================================
199 // function : GlyphMaxSizeY
201 // =======================================================================
202 unsigned int Font_FTFont::GlyphMaxSizeY() const
204 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
205 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
206 : fromFTPoints<float> (myFTFace->size->metrics.height);
207 return (unsigned int)(aHeight + 0.5f);
210 // =======================================================================
211 // function : Ascender
213 // =======================================================================
214 float Font_FTFont::Ascender() const
216 return float(myFTFace->ascender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
219 // =======================================================================
220 // function : Descender
222 // =======================================================================
223 float Font_FTFont::Descender() const
225 return float(myFTFace->descender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
228 // =======================================================================
229 // function : LineSpacing
231 // =======================================================================
232 float Font_FTFont::LineSpacing() const
234 return float(myFTFace->height) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
237 // =======================================================================
238 // function : AdvanceX
240 // =======================================================================
241 float Font_FTFont::AdvanceX (Standard_Utf32Char theUChar,
242 Standard_Utf32Char theUCharNext)
244 loadGlyph (theUChar);
245 return AdvanceX (theUCharNext);
248 // =======================================================================
249 // function : AdvanceY
251 // =======================================================================
252 float Font_FTFont::AdvanceY (Standard_Utf32Char theUChar,
253 Standard_Utf32Char theUCharNext)
255 loadGlyph (theUChar);
256 return AdvanceY (theUCharNext);
259 bool Font_FTFont::getKerning (FT_Vector& theKern,
260 Standard_Utf32Char theUCharCurr,
261 Standard_Utf32Char theUCharNext) const
265 if (theUCharNext != 0 && FT_HAS_KERNING(myFTFace) != 0)
267 const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, theUCharCurr);
268 const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext);
269 if (aCharCurr == 0 || aCharNext == 0
270 || FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, &theKern) != 0)
281 // =======================================================================
282 // function : AdvanceX
284 // =======================================================================
285 float Font_FTFont::AdvanceX (Standard_Utf32Char theUCharNext) const
293 getKerning (aKern, myUChar, theUCharNext);
294 return myWidthScaling * fromFTPoints<float> (myFTFace->glyph->advance.x + aKern.x);
297 // =======================================================================
298 // function : AdvanceY
300 // =======================================================================
301 float Font_FTFont::AdvanceY (Standard_Utf32Char theUCharNext) const
309 getKerning (aKern, myUChar, theUCharNext);
310 return fromFTPoints<float> (myFTFace->glyph->advance.y + aKern.y);
313 // =======================================================================
314 // function : GlyphsNumber
316 // =======================================================================
317 Standard_Integer Font_FTFont::GlyphsNumber() const
319 return myFTFace->num_glyphs;
322 // =======================================================================
323 // function : theRect
325 // =======================================================================
326 void Font_FTFont::GlyphRect (Font_Rect& theRect) const
328 const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
329 theRect.Left = float(myFTFace->glyph->bitmap_left);
330 theRect.Top = float(myFTFace->glyph->bitmap_top);
331 theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
332 theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
335 // =======================================================================
336 // function : BoundingBox
338 // =======================================================================
339 Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theString,
340 const Graphic3d_HorizontalTextAlignment theAlignX,
341 const Graphic3d_VerticalTextAlignment theAlignY)
343 Font_TextFormatter aFormatter;
344 aFormatter.SetupAlignment (theAlignX, theAlignY);
347 aFormatter.Append (theString, *this);
351 aFormatter.BndBox (aBndBox);