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>
17 #include <Font_FontMgr.hxx>
18 #include <Font_TextFormatter.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TCollection_HAsciiString.hxx>
24 IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient)
26 // =======================================================================
27 // function : Font_FTFont
29 // =======================================================================
30 Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib)
34 myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL),
39 myFTLib = new Font_FTLibrary();
43 // =======================================================================
44 // function : Font_FTFont
46 // =======================================================================
47 Font_FTFont::~Font_FTFont()
52 // =======================================================================
53 // function : Font_FTFont
55 // =======================================================================
56 void Font_FTFont::Release()
63 FT_Done_Face (myFTFace);
68 // =======================================================================
71 // =======================================================================
72 bool Font_FTFont::Init (const NCollection_String& theFontPath,
73 const unsigned int thePointSize,
74 const unsigned int theResolution)
77 myFontPath = theFontPath;
78 myPointSize = thePointSize;
79 if (!myFTLib->IsValid())
81 //std::cerr << "FreeType library is unavailable!\n";
86 if (FT_New_Face (myFTLib->Instance(), myFontPath.ToCString(), 0, &myFTFace) != 0)
88 //std::cerr << "Font '" << myFontPath << "' fail to load!\n";
92 else if (FT_Select_Charmap (myFTFace, ft_encoding_unicode) != 0)
94 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
98 else if (FT_Set_Char_Size (myFTFace, 0L, toFTPoints (thePointSize), theResolution, theResolution) != 0)
100 //std::cerr << "Font '" << myFontPath << "' doesn't contains Unicode charmap!\n";
107 // =======================================================================
110 // =======================================================================
111 bool Font_FTFont::Init (const NCollection_String& theFontName,
112 const Font_FontAspect theFontAspect,
113 const unsigned int thePointSize,
114 const unsigned int theResolution)
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);
123 // =======================================================================
124 // function : loadGlyph
126 // =======================================================================
127 bool Font_FTFont::loadGlyph (const Standard_Utf32Char theUChar)
129 if (myUChar == theUChar)
137 || FT_Load_Char (myFTFace, theUChar, myLoadFlags) != 0
138 || myFTFace->glyph == NULL)
147 // =======================================================================
148 // function : RenderGlyph
150 // =======================================================================
151 bool Font_FTFont::RenderGlyph (const Standard_Utf32Char theUChar)
156 || FT_Load_Char (myFTFace, theUChar, myLoadFlags | FT_LOAD_RENDER) != 0
157 || myFTFace->glyph == NULL
158 || myFTFace->glyph->format != FT_GLYPH_FORMAT_BITMAP)
163 FT_Bitmap aBitmap = myFTFace->glyph->bitmap;
164 if (aBitmap.pixel_mode != FT_PIXEL_MODE_GRAY
165 || aBitmap.buffer == NULL || aBitmap.width == 0 || aBitmap.rows == 0)
169 if (!myGlyphImg.InitWrapper (Image_PixMap::ImgAlpha, aBitmap.buffer,
170 aBitmap.width, aBitmap.rows, Abs (aBitmap.pitch)))
174 myGlyphImg.SetTopDown (aBitmap.pitch > 0);
179 // =======================================================================
180 // function : GlyphMaxSizeX
182 // =======================================================================
183 unsigned int Font_FTFont::GlyphMaxSizeX() const
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);
191 // =======================================================================
192 // function : GlyphMaxSizeY
194 // =======================================================================
195 unsigned int Font_FTFont::GlyphMaxSizeY() const
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);
203 // =======================================================================
204 // function : AdvanceX
206 // =======================================================================
207 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUChar,
208 const Standard_Utf32Char theUCharNext)
210 loadGlyph (theUChar);
211 return AdvanceX (theUCharNext);
214 // =======================================================================
215 // function : AdvanceY
217 // =======================================================================
218 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUChar,
219 const Standard_Utf32Char theUCharNext)
221 loadGlyph (theUChar);
222 return AdvanceY (theUCharNext);
225 // =======================================================================
226 // function : AdvanceX
228 // =======================================================================
229 float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext)
236 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
237 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
239 return fromFTPoints<float> (myFTFace->glyph->advance.x);
241 return fromFTPoints<float> (myKernAdvance.x + myFTFace->glyph->advance.x);
244 // =======================================================================
245 // function : AdvanceY
247 // =======================================================================
248 float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext)
255 if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0
256 || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, &myKernAdvance) != 0)
258 return fromFTPoints<float> (myFTFace->glyph->advance.y);
260 return fromFTPoints<float> (myKernAdvance.y + myFTFace->glyph->advance.y);
263 // =======================================================================
264 // function : BoundingBox
266 // =======================================================================
267 Font_Rect Font_FTFont::BoundingBox (const NCollection_String& theString,
268 const Graphic3d_HorizontalTextAlignment theAlignX,
269 const Graphic3d_VerticalTextAlignment theAlignY)
271 Font_TextFormatter aFormatter;
272 aFormatter.SetupAlignment (theAlignX, theAlignY);
275 aFormatter.Append (theString, *this);
279 aFormatter.BndBox (aBndBox);