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 | #ifndef _Font_FTFont_H__ |
17 | #define _Font_FTFont_H__ |
18 | |
317d68c9 |
19 | #include <Font_FontAspect.hxx> |
d2eddacc |
20 | #include <Font_Rect.hxx> |
1bbd7c79 |
21 | #include <Font_StrictLevel.hxx> |
912761ea |
22 | #include <Font_UnicodeSubset.hxx> |
317d68c9 |
23 | #include <Graphic3d_HorizontalTextAlignment.hxx> |
24 | #include <Graphic3d_VerticalTextAlignment.hxx> |
a174a3c5 |
25 | #include <Image_PixMap.hxx> |
317d68c9 |
26 | #include <NCollection_String.hxx> |
1bbd7c79 |
27 | #include <TCollection_AsciiString.hxx> |
a174a3c5 |
28 | |
f9801cf9 |
29 | // forward declarations to avoid including of FreeType headers |
30 | typedef struct FT_FaceRec_* FT_Face; |
31 | typedef struct FT_Vector_ FT_Vector; |
32 | class Font_FTLibrary; |
33 | |
1bbd7c79 |
34 | //! Font initialization parameters. |
35 | struct Font_FTFontParams |
36 | { |
912761ea |
37 | unsigned int PointSize; //!< face size in points (1/72 inch) |
38 | unsigned int Resolution; //!< resolution of the target device in dpi for FT_Set_Char_Size() |
39 | bool ToSynthesizeItalic; //!< generate italic style (e.g. for font family having no italic style); FALSE by default |
40 | bool IsSingleStrokeFont; //!< single-stroke (one-line) font, FALSE by default |
1bbd7c79 |
41 | |
42 | //! Empty constructor. |
43 | Font_FTFontParams() : PointSize (0), Resolution (72u), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {} |
44 | |
45 | //! Constructor. |
46 | Font_FTFontParams (unsigned int thePointSize, |
47 | unsigned int theResolution) |
48 | : PointSize (thePointSize), Resolution (theResolution), ToSynthesizeItalic (false), IsSingleStrokeFont (false) {} |
49 | }; |
50 | |
51 | DEFINE_STANDARD_HANDLE(Font_FTFont, Standard_Transient) |
52 | |
a174a3c5 |
53 | //! Wrapper over FreeType font. |
54 | //! Notice that this class uses internal buffers for loaded glyphs |
55 | //! and it is absolutely UNSAFE to load/read glyph from concurrent threads! |
56 | class Font_FTFont : public Standard_Transient |
57 | { |
1bbd7c79 |
58 | DEFINE_STANDARD_RTTIEXT(Font_FTFont, Standard_Transient) |
59 | public: |
60 | |
61 | //! Find the font Initialize the font. |
62 | //! @param theFontName the font name |
63 | //! @param theFontAspect the font style |
64 | //! @param theParams initialization parameters |
65 | //! @param theStrictLevel search strict level for using aliases and fallback |
66 | //! @return true on success |
67 | Standard_EXPORT static Handle(Font_FTFont) FindAndCreate (const TCollection_AsciiString& theFontName, |
68 | const Font_FontAspect theFontAspect, |
69 | const Font_FTFontParams& theParams, |
70 | const Font_StrictLevel theStrictLevel = Font_StrictLevel_Any); |
71 | |
912761ea |
72 | //! Return TRUE if specified character is within subset of modern CJK characters. |
73 | static bool IsCharFromCJK (Standard_Utf32Char theUChar) |
74 | { |
75 | return (theUChar >= 0x03400 && theUChar <= 0x04DFF) |
76 | || (theUChar >= 0x04E00 && theUChar <= 0x09FFF) |
77 | || (theUChar >= 0x0F900 && theUChar <= 0x0FAFF) |
78 | || (theUChar >= 0x20000 && theUChar <= 0x2A6DF) |
79 | || (theUChar >= 0x2F800 && theUChar <= 0x2FA1F) |
80 | // Hiragana and Katakana (Japanese) are NOT part of CJK, but CJK fonts usually include these symbols |
81 | || IsCharFromHiragana (theUChar) |
82 | || IsCharFromKatakana (theUChar); |
83 | } |
84 | |
85 | //! Return TRUE if specified character is within subset of Hiragana (Japanese). |
86 | static bool IsCharFromHiragana (Standard_Utf32Char theUChar) |
87 | { |
88 | return (theUChar >= 0x03040 && theUChar <= 0x0309F); |
89 | } |
90 | |
91 | //! Return TRUE if specified character is within subset of Katakana (Japanese). |
92 | static bool IsCharFromKatakana (Standard_Utf32Char theUChar) |
93 | { |
94 | return (theUChar >= 0x030A0 && theUChar <= 0x030FF); |
95 | } |
96 | |
97 | //! Return TRUE if specified character is within subset of modern Korean characters (Hangul). |
98 | static bool IsCharFromKorean (Standard_Utf32Char theUChar) |
99 | { |
100 | return (theUChar >= 0x01100 && theUChar <= 0x011FF) |
101 | || (theUChar >= 0x03130 && theUChar <= 0x0318F) |
102 | || (theUChar >= 0x0AC00 && theUChar <= 0x0D7A3); |
103 | } |
104 | |
105 | //! Return TRUE if specified character is within subset of Arabic characters. |
106 | static bool IsCharFromArabic (Standard_Utf32Char theUChar) |
107 | { |
108 | return (theUChar >= 0x00600 && theUChar <= 0x006FF); |
109 | } |
110 | |
111 | //! Return TRUE if specified character should be displayed in Right-to-Left order. |
112 | static bool IsCharRightToLeft (Standard_Utf32Char theUChar) |
113 | { |
114 | return IsCharFromArabic(theUChar); |
115 | } |
116 | |
117 | //! Determine Unicode subset for specified character |
118 | static Font_UnicodeSubset CharSubset (Standard_Utf32Char theUChar) |
119 | { |
120 | if (IsCharFromCJK (theUChar)) |
121 | { |
122 | return Font_UnicodeSubset_CJK; |
123 | } |
124 | else if (IsCharFromKorean (theUChar)) |
125 | { |
126 | return Font_UnicodeSubset_Korean; |
127 | } |
128 | else if (IsCharFromArabic (theUChar)) |
129 | { |
130 | return Font_UnicodeSubset_Arabic; |
131 | } |
132 | return Font_UnicodeSubset_Western; |
133 | } |
134 | |
a174a3c5 |
135 | public: |
136 | |
137 | //! Create uninitialized instance. |
f9801cf9 |
138 | Standard_EXPORT Font_FTFont (const Handle(Font_FTLibrary)& theFTLib = Handle(Font_FTLibrary)()); |
a174a3c5 |
139 | |
140 | //! Destructor. |
141 | Standard_EXPORT virtual ~Font_FTFont(); |
142 | |
143 | //! @return true if font is loaded |
144 | inline bool IsValid() const |
145 | { |
146 | return myFTFace != NULL; |
147 | } |
148 | |
149 | //! @return image plane for currently rendered glyph |
150 | inline const Image_PixMap& GlyphImage() const |
151 | { |
152 | return myGlyphImg; |
153 | } |
154 | |
1bbd7c79 |
155 | //! Initialize the font from the given file path. |
156 | //! @param theFontPath path to the font |
157 | //! @param theParams initialization parameters |
9a90a452 |
158 | //! @param theFaceId face id within the file (0 by default) |
a174a3c5 |
159 | //! @return true on success |
1bbd7c79 |
160 | bool Init (const TCollection_AsciiString& theFontPath, |
9a90a452 |
161 | const Font_FTFontParams& theParams, |
162 | const Standard_Integer theFaceId = 0) |
1bbd7c79 |
163 | { |
9a90a452 |
164 | return Init (Handle(NCollection_Buffer)(), theFontPath, theParams, theFaceId); |
1bbd7c79 |
165 | } |
a174a3c5 |
166 | |
1bbd7c79 |
167 | //! Initialize the font from the given file path or memory buffer. |
168 | //! @param theData memory to read from, should NOT be freed after initialization! |
169 | //! when NULL, function will attempt to open theFileName file |
170 | //! @param theFileName optional path to the font |
171 | //! @param theParams initialization parameters |
9a90a452 |
172 | //! @param theFaceId face id within the file (0 by default) |
1bbd7c79 |
173 | //! @return true on success |
174 | Standard_EXPORT bool Init (const Handle(NCollection_Buffer)& theData, |
175 | const TCollection_AsciiString& theFileName, |
9a90a452 |
176 | const Font_FTFontParams& theParams, |
177 | const Standard_Integer theFaceId = 0); |
1bbd7c79 |
178 | |
179 | //! Find (using Font_FontMgr) and initialize the font from the given name. |
180 | //! @param theFontName the font name |
181 | //! @param theFontAspect the font style |
182 | //! @param theParams initialization parameters |
183 | //! @param theStrictLevel search strict level for using aliases and fallback |
b514beda |
184 | //! @return true on success |
1bbd7c79 |
185 | Standard_EXPORT bool FindAndInit (const TCollection_AsciiString& theFontName, |
186 | Font_FontAspect theFontAspect, |
187 | const Font_FTFontParams& theParams, |
188 | Font_StrictLevel theStrictLevel = Font_StrictLevel_Any); |
b514beda |
189 | |
912761ea |
190 | //! Return flag to use fallback fonts in case if used font does not include symbols from specific Unicode subset; TRUE by default. |
191 | //! @sa Font_FontMgr::ToUseUnicodeSubsetFallback() |
192 | Standard_Boolean ToUseUnicodeSubsetFallback() const { return myToUseUnicodeSubsetFallback; } |
193 | |
194 | //! Set if fallback fonts should be used in case if used font does not include symbols from specific Unicode subset. |
195 | void SetUseUnicodeSubsetFallback (Standard_Boolean theToFallback) { myToUseUnicodeSubsetFallback = theToFallback; } |
196 | |
e4f0cc46 |
197 | //! Return TRUE if this is single-stroke (one-line) font, FALSE by default. |
198 | //! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software. |
1bbd7c79 |
199 | bool IsSingleStrokeFont() const { return myFontParams.IsSingleStrokeFont; } |
e4f0cc46 |
200 | |
201 | //! Set if this font should be rendered as single-stroke (one-line). |
1bbd7c79 |
202 | void SetSingleStrokeFont (bool theIsSingleLine) { myFontParams.IsSingleStrokeFont = theIsSingleLine; } |
203 | |
204 | //! Return TRUE if italic style should be synthesized; FALSE by default. |
205 | bool ToSynthesizeItalic() const { return myFontParams.ToSynthesizeItalic; } |
e4f0cc46 |
206 | |
a174a3c5 |
207 | //! Release currently loaded font. |
b514beda |
208 | Standard_EXPORT virtual void Release(); |
a174a3c5 |
209 | |
210 | //! Render specified glyph into internal buffer (bitmap). |
211 | Standard_EXPORT bool RenderGlyph (const Standard_Utf32Char theChar); |
212 | |
213 | //! @return maximal glyph width in pixels (rendered to bitmap). |
912761ea |
214 | Standard_EXPORT unsigned int GlyphMaxSizeX (bool theToIncludeFallback = false) const; |
a174a3c5 |
215 | |
216 | //! @return maximal glyph height in pixels (rendered to bitmap). |
912761ea |
217 | Standard_EXPORT unsigned int GlyphMaxSizeY (bool theToIncludeFallback = false) const; |
a174a3c5 |
218 | |
219 | //! @return vertical distance from the horizontal baseline to the highest character coordinate. |
f9801cf9 |
220 | Standard_EXPORT float Ascender() const; |
a174a3c5 |
221 | |
222 | //! @return vertical distance from the horizontal baseline to the lowest character coordinate. |
f9801cf9 |
223 | Standard_EXPORT float Descender() const; |
a174a3c5 |
224 | |
225 | //! @return default line spacing (the baseline-to-baseline distance). |
f9801cf9 |
226 | Standard_EXPORT float LineSpacing() const; |
a174a3c5 |
227 | |
228 | //! Configured point size |
229 | unsigned int PointSize() const |
230 | { |
1bbd7c79 |
231 | return myFontParams.PointSize; |
a174a3c5 |
232 | } |
233 | |
151da08b |
234 | //! Setup glyph scaling along X-axis. |
235 | //! By default glyphs are not scaled (scaling factor = 1.0) |
236 | void SetWidthScaling (const float theScaleFactor) |
237 | { |
238 | myWidthScaling = theScaleFactor; |
239 | } |
240 | |
912761ea |
241 | //! Return TRUE if font contains specified symbol (excluding fallback list). |
242 | Standard_EXPORT bool HasSymbol (Standard_Utf32Char theUChar) const; |
243 | |
82be4141 |
244 | //! Compute horizontal advance to the next character with kerning applied when applicable. |
a174a3c5 |
245 | //! Assuming text rendered horizontally. |
82be4141 |
246 | //! @param theUCharNext the next character to compute advance from current one |
247 | Standard_EXPORT float AdvanceX (Standard_Utf32Char theUCharNext) const; |
a174a3c5 |
248 | |
82be4141 |
249 | //! Compute horizontal advance to the next character with kerning applied when applicable. |
a174a3c5 |
250 | //! Assuming text rendered horizontally. |
82be4141 |
251 | //! @param theUChar the character to be loaded as current one |
252 | //! @param theUCharNext the next character to compute advance from current one |
253 | Standard_EXPORT float AdvanceX (Standard_Utf32Char theUChar, |
254 | Standard_Utf32Char theUCharNext); |
a174a3c5 |
255 | |
82be4141 |
256 | //! Compute vertical advance to the next character with kerning applied when applicable. |
a174a3c5 |
257 | //! Assuming text rendered vertically. |
82be4141 |
258 | //! @param theUCharNext the next character to compute advance from current one |
259 | Standard_EXPORT float AdvanceY (Standard_Utf32Char theUCharNext) const; |
a174a3c5 |
260 | |
82be4141 |
261 | //! Compute vertical advance to the next character with kerning applied when applicable. |
a174a3c5 |
262 | //! Assuming text rendered vertically. |
82be4141 |
263 | //! @param theUChar the character to be loaded as current one |
264 | //! @param theUCharNext the next character to compute advance from current one |
265 | Standard_EXPORT float AdvanceY (Standard_Utf32Char theUChar, |
266 | Standard_Utf32Char theUCharNext); |
a174a3c5 |
267 | |
912761ea |
268 | //! Return glyphs number in this font. |
269 | //! @param theToIncludeFallback if TRUE then the number will include fallback list |
270 | Standard_EXPORT Standard_Integer GlyphsNumber (bool theToIncludeFallback = false) const; |
a174a3c5 |
271 | |
272 | //! Retrieve glyph bitmap rectangle |
f9801cf9 |
273 | Standard_EXPORT void GlyphRect (Font_Rect& theRect) const; |
a174a3c5 |
274 | |
317d68c9 |
275 | //! Computes bounding box of the given text using plain-text formatter (Font_TextFormatter). |
276 | //! Note that bounding box takes into account the text alignment options. |
277 | //! Its corners are relative to the text alignment anchor point, their coordinates can be negative. |
d2eddacc |
278 | Standard_EXPORT Font_Rect BoundingBox (const NCollection_String& theString, |
279 | const Graphic3d_HorizontalTextAlignment theAlignX, |
280 | const Graphic3d_VerticalTextAlignment theAlignY); |
317d68c9 |
281 | |
1bbd7c79 |
282 | public: |
283 | |
284 | //! Initialize the font. |
285 | //! @param theFontPath path to the font |
286 | //! @param thePointSize the face size in points (1/72 inch) |
287 | //! @param theResolution the resolution of the target device in dpi |
288 | //! @return true on success |
289 | Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters") |
290 | bool Init (const NCollection_String& theFontPath, |
291 | unsigned int thePointSize, |
292 | unsigned int theResolution) |
293 | { |
294 | Font_FTFontParams aParams; |
295 | aParams.PointSize = thePointSize; |
296 | aParams.Resolution = theResolution; |
9a90a452 |
297 | return Init (theFontPath.ToCString(), aParams, 0); |
1bbd7c79 |
298 | } |
299 | |
300 | //! Initialize the font. |
301 | //! @param theFontName the font name |
302 | //! @param theFontAspect the font style |
303 | //! @param thePointSize the face size in points (1/72 inch) |
304 | //! @param theResolution the resolution of the target device in dpi |
305 | //! @return true on success |
306 | Standard_DEPRECATED ("Deprecated method, Font_FTFontParams should be used for passing parameters") |
307 | bool Init (const NCollection_String& theFontName, |
308 | Font_FontAspect theFontAspect, |
309 | unsigned int thePointSize, |
310 | unsigned int theResolution) |
311 | { |
312 | Font_FTFontParams aParams; |
313 | aParams.PointSize = thePointSize; |
314 | aParams.Resolution = theResolution; |
315 | return FindAndInit (theFontName.ToCString(), theFontAspect, aParams); |
316 | } |
317 | |
a174a3c5 |
318 | protected: |
319 | |
320 | //! Convert value to 26.6 fixed-point format for FT library API. |
321 | template <typename theInput_t> |
f9801cf9 |
322 | int32_t toFTPoints (const theInput_t thePointSize) const |
a174a3c5 |
323 | { |
f9801cf9 |
324 | return (int32_t)thePointSize * 64; |
a174a3c5 |
325 | } |
326 | |
327 | //! Convert value from 26.6 fixed-point format for FT library API. |
328 | template <typename theReturn_t, typename theFTUnits_t> |
329 | inline theReturn_t fromFTPoints (const theFTUnits_t theFTUnits) const |
330 | { |
331 | return (theReturn_t)theFTUnits / 64.0f; |
332 | } |
333 | |
334 | protected: |
335 | |
336 | //! Load glyph without rendering it. |
337 | Standard_EXPORT bool loadGlyph (const Standard_Utf32Char theUChar); |
338 | |
82be4141 |
339 | //! Wrapper for FT_Get_Kerning - retrieve kerning values. |
340 | Standard_EXPORT bool getKerning (FT_Vector& theKern, |
341 | Standard_Utf32Char theUCharCurr, |
342 | Standard_Utf32Char theUCharNext) const; |
343 | |
912761ea |
344 | //! Initialize fallback font. |
345 | Standard_EXPORT bool findAndInitFallback (Font_UnicodeSubset theSubset); |
346 | |
a174a3c5 |
347 | protected: |
348 | |
1bbd7c79 |
349 | Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object |
350 | Handle(NCollection_Buffer) myBuffer; //!< memory buffer |
912761ea |
351 | Handle(Font_FTFont) myFallbackFaces[Font_UnicodeSubset_NB]; //!< fallback fonts |
1bbd7c79 |
352 | FT_Face myFTFace; //!< FT face object |
912761ea |
353 | FT_Face myActiveFTFace; //!< active FT face object (the main of fallback) |
1bbd7c79 |
354 | TCollection_AsciiString myFontPath; //!< font path |
355 | Font_FTFontParams myFontParams; //!< font initialization parameters |
912761ea |
356 | Font_FontAspect myFontAspect; //!< font initialization aspect |
1bbd7c79 |
357 | float myWidthScaling; //!< scale glyphs along X-axis |
358 | int32_t myLoadFlags; //!< default load flags |
151da08b |
359 | |
1bbd7c79 |
360 | Image_PixMap myGlyphImg; //!< cached glyph plane |
361 | Standard_Utf32Char myUChar; //!< currently loaded unicode character |
912761ea |
362 | Standard_Boolean myToUseUnicodeSubsetFallback; //!< use default fallback fonts for extended Unicode sub-sets (Korean, CJK, etc.) |
a174a3c5 |
363 | |
364 | }; |
365 | |
a174a3c5 |
366 | #endif // _Font_FTFont_H__ |