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),
38 myKernAdvance (new FT_Vector()),
43 myFTLib = new Font_FTLibrary();
47 // =======================================================================
48 // function : Font_FTFont
50 // =======================================================================
51 Font_FTFont::~Font_FTFont()
57 // =======================================================================
60 // =======================================================================
61 void Font_FTFont::Release()
68 FT_Done_Face (myFTFace);
73 // =======================================================================
76 // =======================================================================
77 bool Font_FTFont::Init (const NCollection_String& theFontPath,
78 const unsigned int thePointSize,
79 const unsigned int theResolution)
82 myFontPath = theFontPath;
83 myPointSize = thePointSize;
84 if (!myFTLib->IsValid())
86 //std::cerr << "FreeType library is unavailable!\n";
91 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
93 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
97 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
99 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
103 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
105 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
112 // =======================================================================
115 // =======================================================================
116 bool Font_FTFont::Init (const NCollection_String& theFontName,
117 const Font_FontAspect theFontAspect,
118 const unsigned int thePointSize,
119 const unsigned int theResolution)
121 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
122 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString());
123 if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize))
125 myIsSingleLine = aRequestedFont->IsSingleStrokeFont();
126 return Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution);
131 // =======================================================================
132 // function : loadGlyph
134 // =======================================================================
135 bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
137 if (myUChar == theUChar)
145 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags)) != 0
146 || myFTFace->glyph == NULL)
155 // =======================================================================
156 // function : RenderGlyph
158 // =======================================================================
159 bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
164 || FT_Load_Char (myFTFace, theUChar, FT_Int32(myLoadFlags | FT_LOAD_RENDER)) != 0
165 || myFTFace->glyph == NULL
166 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
171 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
172 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
173 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
177 if (!myGlyphImg.InitWrapper (Image_Format_Alpha, aBitmap.buffer,
178 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
182 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
187 // =======================================================================
188 // function : GlyphMaxSizeX
190 // =======================================================================
191 unsigned int Font_FTFont::GlyphMaxSizeX() const
193 float aWidth = (FT_IS_SCALABLE(myFTFace) != 0)
194 ? float(myFTFace->bbox.xMax - myFTFace->bbox.xMin) * (float(myFTFace->size->metrics.x_ppem) / float(myFTFace->units_per_EM))
195 : fromFTPoints<float> (myFTFace->size->metrics.max_advance);
196 return (unsigned int)(aWidth + 0.5f);
199 // =======================================================================
200 // function : GlyphMaxSizeY
202 // =======================================================================
203 unsigned int Font_FTFont::GlyphMaxSizeY() const
205 float aHeight = (FT_IS_SCALABLE(myFTFace) != 0)
206 ? float(myFTFace->bbox.yMax - myFTFace->bbox.yMin) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM))
207 : fromFTPoints<float> (myFTFace->size->metrics.height);
208 return (unsigned int)(aHeight + 0.5f);
211 // =======================================================================
212 // function : Ascender
214 // =======================================================================
215 float Font_FTFont::Ascender() const
217 return float(myFTFace->ascender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
220 // =======================================================================
221 // function : Descender
223 // =======================================================================
224 float Font_FTFont::Descender() const
226 return float(myFTFace->descender) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
229 // =======================================================================
230 // function : LineSpacing
232 // =======================================================================
233 float Font_FTFont::LineSpacing() const
235 return float(myFTFace->height) * (float(myFTFace->size->metrics.y_ppem) / float(myFTFace->units_per_EM));
238 // =======================================================================
239 // function : AdvanceX
241 // =======================================================================
242 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
243 const Standard_Utf32Char theUCharNext)
245 loadGlyph (theUChar);
246 return AdvanceX (theUCharNext);
249 // =======================================================================
250 // function : AdvanceY
252 // =======================================================================
253 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
254 const Standard_Utf32Char theUCharNext)
256 loadGlyph (theUChar);
257 return AdvanceY (theUCharNext);
260 // =======================================================================
261 // function : AdvanceX
263 // =======================================================================
264 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
271 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
272 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
274 return myWidthScaling * fromFTPoints<float> (myFTFace->glyph->advance.x);
276 return myWidthScaling * fromFTPoints<float> (myKernAdvance->x + myFTFace->glyph->advance.x);
279 // =======================================================================
280 // function : AdvanceY
282 // =======================================================================
283 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
290 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
291 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0)
293 return fromFTPoints<float> (myFTFace->glyph->advance.y);
295 return fromFTPoints<float> (myKernAdvance->y + myFTFace->glyph->advance.y);
298 // =======================================================================
299 // function : GlyphsNumber
301 // =======================================================================
302 Standard_Integer Font_FTFont::GlyphsNumber() const
304 return myFTFace->num_glyphs;
307 // =======================================================================
308 // function : theRect
310 // =======================================================================
311 void Font_FTFont::GlyphRect (Font_Rect& theRect) const
313 const FT_Bitmap& aBitmap = myFTFace->glyph->bitmap;
314 theRect.Left = float(myFTFace->glyph->bitmap_left);
315 theRect.Top = float(myFTFace->glyph->bitmap_top);
316 theRect.Right = float(myFTFace->glyph->bitmap_left + (int )aBitmap.width);
317 theRect.Bottom = float(myFTFace->glyph->bitmap_top - (int )aBitmap.rows);
320 // =======================================================================
321 // function : BoundingBox
323 // =======================================================================
324 Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theString,
325 const Graphic3d_HorizontalTextAlignment theAlignX,
326 const Graphic3d_VerticalTextAlignment theAlignY)
328 Font_TextFormatter aFormatter;
329 aFormatter.SetupAlignment (theAlignX, theAlignY);
332 aFormatter.Append (theString, *this);
336 aFormatter.BndBox (aBndBox);