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)
35 myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
36 myKernAdvance(new FT_Vector()),
41 myFTLib = new Font_FTLibrary();
45 // =======================================================================
46 // function : Font_FTFont
48 // =======================================================================
49 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 Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
121 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize);
122 return !aRequestedFont.IsNull()
123 && Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
126 // =======================================================================
127 // function : loadGlyph
129 // =======================================================================
130 bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
132 if (myUChar == theUChar)
140 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
141 || myFTFace->glyph == NULL)
150 // =======================================================================
151 // function : RenderGlyph
153 // =======================================================================
154 bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
159 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
160 || myFTFace->glyph == NULL
161 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
166 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
167 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
168 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
172 if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
173 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
177 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
182 // =======================================================================
183 // function : GlyphMaxSizeX
185 // =======================================================================
186 unsigned int Font_FTFont::GlyphMaxSizeX() const
188 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
189 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
190 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
191 return (unsigned int)(aWidth + 0.5f);
194 // =======================================================================
195 // function : GlyphMaxSizeY
197 // =======================================================================
198 unsigned int Font_FTFont::GlyphMaxSizeY() const
200 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
201 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
202 : fromFTPoints<float> (myFTFace->size->metrics.height);
203 return (unsigned int)(aHeight + 0.5f);
206 // =======================================================================
207 // function : Ascender
209 // =======================================================================
210 float Font_FTFont::Ascender() const
212 return float(myFTFace->ascender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
215 // =======================================================================
216 // function : Descender
218 // =======================================================================
219 float Font_FTFont::Descender() const
221 return float(myFTFace->descender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
224 // =======================================================================
225 // function : LineSpacing
227 // =======================================================================
228 float Font_FTFont::LineSpacing() const
230 return float(myFTFace->height) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
233 // =======================================================================
234 // function : AdvanceX
236 // =======================================================================
237 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
238 const Standard_Utf32Char theUCharNext)
240 loadGlyph (theUChar);
241 return AdvanceX (theUCharNext);
244 // =======================================================================
245 // function : AdvanceY
247 // =======================================================================
248 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
249 const Standard_Utf32Char theUCharNext)
251 loadGlyph (theUChar);
252 return AdvanceY (theUCharNext);
255 // =======================================================================
256 // function : AdvanceX
258 // =======================================================================
259 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
266 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
267 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
269 return fromFTPoints<float> (myFTFace->glyph->advance.x);
271 return fromFTPoints<float> (myKernAdvance->x + myFTFace->glyph->advance.x);
274 // =======================================================================
275 // function : AdvanceY
277 // =======================================================================
278 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
285 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
286 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
288 return fromFTPoints<float> (myFTFace->glyph->advance.y);
290 return fromFTPoints<float> (myKernAdvance->y + myFTFace->glyph->advance.y);
293 // =======================================================================
294 // function : GlyphsNumber
296 // =======================================================================
297 Standard_Integer Font_FTFont::GlyphsNumber() const
299 return myFTFace->num_glyphs;
302 // =======================================================================
303 // function : theRect
305 // =======================================================================
306 void Font_FTFont::GlyphRect (Font_Rect& theRect) const
308 const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
309 theRect.Left = float(myFTFace->glyph->bitmap_left);
310 theRect.Top = float(myFTFace->glyph->bitmap_top);
311 theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
312 theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
315 // =======================================================================
316 // function : BoundingBox
318 // =======================================================================
319 Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theString,
320 const Graphic3d_HorizontalTextAlignment theAlignX,
321 const Graphic3d_VerticalTextAlignment theAlignY)
323 Font_TextFormatter aFormatter;
324 aFormatter.SetupAlignment (theAlignX, theAlignY);
327 aFormatter.Append (theString, *this);
331 aFormatter.BndBox (aBndBox);