OLD | NEW |
---|---|
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fxge/include/fx_font.h" | 7 #include "core/fxge/include/fx_font.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" | 9 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" |
10 #include "core/fxge/ge/fx_text_int.h" | 10 #include "core/fxge/ge/fx_text_int.h" |
11 #include "core/fxge/include/cfx_fontmgr.h" | 11 #include "core/fxge/include/cfx_fontmgr.h" |
12 #include "core/fxge/include/cfx_gemodule.h" | 12 #include "core/fxge/include/cfx_gemodule.h" |
13 #include "core/fxge/include/cfx_pathdata.h" | |
13 #include "core/fxge/include/cfx_substfont.h" | 14 #include "core/fxge/include/cfx_substfont.h" |
14 #include "core/fxge/include/fx_freetype.h" | 15 #include "core/fxge/include/fx_freetype.h" |
15 | 16 |
16 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) | 17 #define EM_ADJUST(em, a) (em == 0 ? (a) : (a)*1000 / em) |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
21 typedef struct { | |
22 FX_BOOL m_bCount; | |
23 int m_PointCount; | |
24 FX_PATHPOINT* m_pPoints; | |
25 int m_CurX; | |
26 int m_CurY; | |
27 FX_FLOAT m_CoordUnit; | |
28 } OUTLINE_PARAMS; | |
29 | |
20 #ifdef PDF_ENABLE_XFA | 30 #ifdef PDF_ENABLE_XFA |
21 | 31 |
22 unsigned long FTStreamRead(FXFT_Stream stream, | 32 unsigned long FTStreamRead(FXFT_Stream stream, |
23 unsigned long offset, | 33 unsigned long offset, |
24 unsigned char* buffer, | 34 unsigned char* buffer, |
25 unsigned long count) { | 35 unsigned long count) { |
26 if (count == 0) | 36 if (count == 0) |
27 return 0; | 37 return 0; |
28 | 38 |
29 IFX_FileRead* pFile = static_cast<IFX_FileRead*>(stream->descriptor.pointer); | 39 IFX_FileRead* pFile = static_cast<IFX_FileRead*>(stream->descriptor.pointer); |
(...skipping 22 matching lines...) Expand all Loading... | |
52 if (stream) | 62 if (stream) |
53 *stream = std::move(stream1); | 63 *stream = std::move(stream1); |
54 return TRUE; | 64 return TRUE; |
55 } | 65 } |
56 #endif // PDF_ENABLE_XFA | 66 #endif // PDF_ENABLE_XFA |
57 | 67 |
58 FXFT_Face FT_LoadFont(const uint8_t* pData, int size) { | 68 FXFT_Face FT_LoadFont(const uint8_t* pData, int size) { |
59 return CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(pData, size, 0); | 69 return CFX_GEModule::Get()->GetFontMgr()->GetFixedFace(pData, size, 0); |
60 } | 70 } |
61 | 71 |
72 void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { | |
73 if (param->m_PointCount >= 2 && | |
74 param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO && | |
75 param->m_pPoints[param->m_PointCount - 2].m_PointX == | |
76 param->m_pPoints[param->m_PointCount - 1].m_PointX && | |
77 param->m_pPoints[param->m_PointCount - 2].m_PointY == | |
78 param->m_pPoints[param->m_PointCount - 1].m_PointY) { | |
79 param->m_PointCount -= 2; | |
80 } | |
81 if (param->m_PointCount >= 4 && | |
82 param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO && | |
83 param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && | |
84 param->m_pPoints[param->m_PointCount - 3].m_PointX == | |
85 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
86 param->m_pPoints[param->m_PointCount - 3].m_PointY == | |
87 param->m_pPoints[param->m_PointCount - 4].m_PointY && | |
88 param->m_pPoints[param->m_PointCount - 2].m_PointX == | |
89 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
90 param->m_pPoints[param->m_PointCount - 2].m_PointY == | |
91 param->m_pPoints[param->m_PointCount - 4].m_PointY && | |
92 param->m_pPoints[param->m_PointCount - 1].m_PointX == | |
93 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
94 param->m_pPoints[param->m_PointCount - 1].m_PointY == | |
95 param->m_pPoints[param->m_PointCount - 4].m_PointY) { | |
96 param->m_PointCount -= 4; | |
97 } | |
98 } | |
99 | |
100 int Outline_MoveTo(const FXFT_Vector* to, void* user) { | |
101 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
102 if (!param->m_bCount) { | |
103 Outline_CheckEmptyContour(param); | |
104 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; | |
105 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; | |
106 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; | |
107 param->m_CurX = to->x; | |
108 param->m_CurY = to->y; | |
109 if (param->m_PointCount) | |
110 param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; | |
111 } | |
112 param->m_PointCount++; | |
113 return 0; | |
114 } | |
115 | |
116 int Outline_LineTo(const FXFT_Vector* to, void* user) { | |
117 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
118 if (!param->m_bCount) { | |
119 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; | |
120 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; | |
121 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; | |
122 param->m_CurX = to->x; | |
123 param->m_CurY = to->y; | |
124 } | |
125 param->m_PointCount++; | |
126 return 0; | |
127 } | |
128 | |
129 int Outline_ConicTo(const FXFT_Vector* control, | |
130 const FXFT_Vector* to, | |
131 void* user) { | |
132 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
133 if (!param->m_bCount) { | |
134 param->m_pPoints[param->m_PointCount].m_PointX = | |
135 (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / | |
136 param->m_CoordUnit; | |
137 param->m_pPoints[param->m_PointCount].m_PointY = | |
138 (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / | |
139 param->m_CoordUnit; | |
140 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; | |
141 param->m_pPoints[param->m_PointCount + 1].m_PointX = | |
142 (control->x + (to->x - control->x) / 3) / param->m_CoordUnit; | |
143 param->m_pPoints[param->m_PointCount + 1].m_PointY = | |
144 (control->y + (to->y - control->y) / 3) / param->m_CoordUnit; | |
145 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; | |
146 param->m_pPoints[param->m_PointCount + 2].m_PointX = | |
147 to->x / param->m_CoordUnit; | |
148 param->m_pPoints[param->m_PointCount + 2].m_PointY = | |
149 to->y / param->m_CoordUnit; | |
150 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; | |
151 param->m_CurX = to->x; | |
152 param->m_CurY = to->y; | |
153 } | |
154 param->m_PointCount += 3; | |
155 return 0; | |
156 } | |
157 | |
158 int Outline_CubicTo(const FXFT_Vector* control1, | |
159 const FXFT_Vector* control2, | |
160 const FXFT_Vector* to, | |
161 void* user) { | |
162 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
163 if (!param->m_bCount) { | |
164 param->m_pPoints[param->m_PointCount].m_PointX = | |
165 control1->x / param->m_CoordUnit; | |
166 param->m_pPoints[param->m_PointCount].m_PointY = | |
167 control1->y / param->m_CoordUnit; | |
168 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; | |
169 param->m_pPoints[param->m_PointCount + 1].m_PointX = | |
170 control2->x / param->m_CoordUnit; | |
171 param->m_pPoints[param->m_PointCount + 1].m_PointY = | |
172 control2->y / param->m_CoordUnit; | |
173 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; | |
174 param->m_pPoints[param->m_PointCount + 2].m_PointX = | |
175 to->x / param->m_CoordUnit; | |
176 param->m_pPoints[param->m_PointCount + 2].m_PointY = | |
177 to->y / param->m_CoordUnit; | |
178 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; | |
179 param->m_CurX = to->x; | |
180 param->m_CurY = to->y; | |
181 } | |
182 param->m_PointCount += 3; | |
183 return 0; | |
184 } | |
185 | |
62 } // namespace | 186 } // namespace |
63 | 187 |
188 const char CFX_Font::s_AngleSkew[] = { | |
dsinclair
2016/09/06 12:57:03
Are these referenced externally? If not, can they
npm
2016/09/06 14:21:52
They are referenced by CFX_FaceCache
| |
189 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, | |
190 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55, | |
191 }; | |
192 | |
193 const uint8_t CFX_Font::s_WeightPow[] = { | |
194 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, | |
195 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37, | |
196 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, | |
197 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, | |
198 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, | |
199 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, | |
200 }; | |
201 | |
202 const uint8_t CFX_Font::s_WeightPow_11[] = { | |
203 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, | |
204 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41, | |
205 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, | |
206 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, | |
207 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, | |
208 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, | |
209 }; | |
210 | |
211 const uint8_t CFX_Font::s_WeightPow_SHIFTJIS[] = { | |
212 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, | |
213 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, | |
214 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, | |
215 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, | |
216 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, | |
217 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, | |
218 }; | |
219 | |
64 CFX_Font::CFX_Font() | 220 CFX_Font::CFX_Font() |
221 : | |
65 #ifdef PDF_ENABLE_XFA | 222 #ifdef PDF_ENABLE_XFA |
66 : m_bLogic(FALSE), | 223 m_bLogic(FALSE), |
67 m_pOwnedStream(nullptr), | 224 m_pOwnedStream(nullptr), |
225 #endif // PDF_ENABLE_XFA | |
68 m_Face(nullptr), | 226 m_Face(nullptr), |
69 #else | |
70 : m_Face(nullptr), | |
71 #endif // PDF_ENABLE_XFA | |
72 m_pFontData(nullptr), | 227 m_pFontData(nullptr), |
73 m_pGsubData(nullptr), | 228 m_pGsubData(nullptr), |
74 m_dwSize(0), | 229 m_dwSize(0), |
75 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | 230 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
76 m_pPlatformFont(nullptr), | 231 m_pPlatformFont(nullptr), |
77 #endif | 232 #endif |
78 m_bEmbedded(FALSE), | 233 m_bEmbedded(FALSE), |
79 m_bVertical(FALSE) { | 234 m_bVertical(FALSE) { |
80 } | 235 } |
81 | 236 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 m_OtfFontData.DetachBuffer(); | 272 m_OtfFontData.DetachBuffer(); |
118 return; | 273 return; |
119 } | 274 } |
120 #endif // PDF_ENABLE_XFA | 275 #endif // PDF_ENABLE_XFA |
121 if (m_Face) { | 276 if (m_Face) { |
122 #ifndef PDF_ENABLE_XFA | 277 #ifndef PDF_ENABLE_XFA |
123 if (FXFT_Get_Face_External_Stream(m_Face)) { | 278 if (FXFT_Get_Face_External_Stream(m_Face)) { |
124 FXFT_Clear_Face_External_Stream(m_Face); | 279 FXFT_Clear_Face_External_Stream(m_Face); |
125 } | 280 } |
126 #endif // PDF_ENABLE_XFA | 281 #endif // PDF_ENABLE_XFA |
127 if (m_bEmbedded) { | 282 if (m_bEmbedded) |
128 DeleteFace(); | 283 DeleteFace(); |
129 } else { | 284 else |
130 CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face); | 285 CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face); |
131 } | |
132 } | 286 } |
133 #ifdef PDF_ENABLE_XFA | 287 #ifdef PDF_ENABLE_XFA |
134 FX_Free(m_pOwnedStream); | 288 FX_Free(m_pOwnedStream); |
135 #endif // PDF_ENABLE_XFA | 289 #endif // PDF_ENABLE_XFA |
136 FX_Free(m_pGsubData); | 290 FX_Free(m_pGsubData); |
137 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && !defined _SKIA_SUPPORT_ | 291 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && !defined _SKIA_SUPPORT_ |
138 ReleasePlatformResource(); | 292 ReleasePlatformResource(); |
139 #endif | 293 #endif |
140 } | 294 } |
141 | 295 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 | 333 |
180 if (pFaceCount) | 334 if (pFaceCount) |
181 *pFaceCount = (int)m_Face->num_faces; | 335 *pFaceCount = (int)m_Face->num_faces; |
182 m_pOwnedStream = stream.release(); | 336 m_pOwnedStream = stream.release(); |
183 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); | 337 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); |
184 return TRUE; | 338 return TRUE; |
185 } | 339 } |
186 #endif // PDF_ENABLE_XFA | 340 #endif // PDF_ENABLE_XFA |
187 | 341 |
188 int CFX_Font::GetGlyphWidth(uint32_t glyph_index) { | 342 int CFX_Font::GetGlyphWidth(uint32_t glyph_index) { |
189 if (!m_Face) { | 343 if (!m_Face) |
190 return 0; | 344 return 0; |
191 } | 345 if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) |
192 if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) { | |
193 AdjustMMParams(glyph_index, 0, 0); | 346 AdjustMMParams(glyph_index, 0, 0); |
194 } | |
195 int err = FXFT_Load_Glyph( | 347 int err = FXFT_Load_Glyph( |
196 m_Face, glyph_index, | 348 m_Face, glyph_index, |
197 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | 349 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); |
198 if (err) { | 350 if (err) |
199 return 0; | 351 return 0; |
200 } | |
201 int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | 352 int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), |
202 FXFT_Get_Glyph_HoriAdvance(m_Face)); | 353 FXFT_Get_Glyph_HoriAdvance(m_Face)); |
203 return width; | 354 return width; |
204 } | 355 } |
205 | 356 |
206 FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, uint32_t size) { | 357 FX_BOOL CFX_Font::LoadEmbedded(const uint8_t* data, uint32_t size) { |
207 std::vector<uint8_t> temp(data, data + size); | 358 std::vector<uint8_t> temp(data, data + size); |
208 m_pFontDataAllocation.swap(temp); | 359 m_pFontDataAllocation.swap(temp); |
209 m_Face = FT_LoadFont(m_pFontDataAllocation.data(), size); | 360 m_Face = FT_LoadFont(m_pFontDataAllocation.data(), size); |
210 m_pFontData = m_pFontDataAllocation.data(); | 361 m_pFontData = m_pFontDataAllocation.data(); |
(...skipping 21 matching lines...) Expand all Loading... | |
232 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | 383 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), |
233 FXFT_Get_Face_Descender(m_Face)); | 384 FXFT_Get_Face_Descender(m_Face)); |
234 } | 385 } |
235 | 386 |
236 FX_BOOL CFX_Font::GetGlyphBBox(uint32_t glyph_index, FX_RECT& bbox) { | 387 FX_BOOL CFX_Font::GetGlyphBBox(uint32_t glyph_index, FX_RECT& bbox) { |
237 if (!m_Face) | 388 if (!m_Face) |
238 return FALSE; | 389 return FALSE; |
239 | 390 |
240 if (FXFT_Is_Face_Tricky(m_Face)) { | 391 if (FXFT_Is_Face_Tricky(m_Face)) { |
241 int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); | 392 int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72); |
242 if (error) { | 393 if (error) |
243 return FALSE; | 394 return FALSE; |
244 } | |
245 error = FXFT_Load_Glyph(m_Face, glyph_index, | 395 error = FXFT_Load_Glyph(m_Face, glyph_index, |
246 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | 396 FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); |
247 if (error) { | 397 if (error) |
248 return FALSE; | 398 return FALSE; |
249 } | |
250 FXFT_BBox cbox; | 399 FXFT_BBox cbox; |
251 FT_Glyph glyph; | 400 FT_Glyph glyph; |
252 error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); | 401 error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph); |
253 if (error) { | 402 if (error) |
254 return FALSE; | 403 return FALSE; |
255 } | |
256 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); | 404 FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox); |
257 int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, | 405 int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem, |
258 pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; | 406 pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem; |
259 if (pixel_size_x == 0 || pixel_size_y == 0) { | 407 if (pixel_size_x == 0 || pixel_size_y == 0) { |
260 bbox.left = cbox.xMin; | 408 bbox.left = cbox.xMin; |
261 bbox.right = cbox.xMax; | 409 bbox.right = cbox.xMax; |
262 bbox.top = cbox.yMax; | 410 bbox.top = cbox.yMax; |
263 bbox.bottom = cbox.yMin; | 411 bbox.bottom = cbox.yMin; |
264 } else { | 412 } else { |
265 bbox.left = cbox.xMin * 1000 / pixel_size_x; | 413 bbox.left = cbox.xMin * 1000 / pixel_size_x; |
266 bbox.right = cbox.xMax * 1000 / pixel_size_x; | 414 bbox.right = cbox.xMax * 1000 / pixel_size_x; |
267 bbox.top = cbox.yMax * 1000 / pixel_size_y; | 415 bbox.top = cbox.yMax * 1000 / pixel_size_y; |
268 bbox.bottom = cbox.yMin * 1000 / pixel_size_y; | 416 bbox.bottom = cbox.yMin * 1000 / pixel_size_y; |
269 } | 417 } |
270 if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) { | 418 if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) |
271 bbox.top = FXFT_Get_Face_Ascender(m_Face); | 419 bbox.top = FXFT_Get_Face_Ascender(m_Face); |
272 } | 420 if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) |
273 if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) { | |
274 bbox.bottom = FXFT_Get_Face_Descender(m_Face); | 421 bbox.bottom = FXFT_Get_Face_Descender(m_Face); |
275 } | |
276 FT_Done_Glyph(glyph); | 422 FT_Done_Glyph(glyph); |
277 return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; | 423 return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0; |
278 } | 424 } |
279 if (FXFT_Load_Glyph( | 425 if (FXFT_Load_Glyph( |
280 m_Face, glyph_index, | 426 m_Face, glyph_index, |
281 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { | 427 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) { |
282 return FALSE; | 428 return FALSE; |
283 } | 429 } |
284 int em = FXFT_Get_Face_UnitsPerEM(m_Face); | 430 int em = FXFT_Get_Face_UnitsPerEM(m_Face); |
285 if (em == 0) { | 431 if (em == 0) { |
(...skipping 15 matching lines...) Expand all Loading... | |
301 } | 447 } |
302 | 448 |
303 FX_BOOL CFX_Font::IsItalic() const { | 449 FX_BOOL CFX_Font::IsItalic() const { |
304 if (!m_Face) | 450 if (!m_Face) |
305 return FALSE; | 451 return FALSE; |
306 | 452 |
307 FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC; | 453 FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC; |
308 if (!ret) { | 454 if (!ret) { |
309 CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face)); | 455 CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face)); |
310 str.MakeLower(); | 456 str.MakeLower(); |
311 if (str.Find("italic") != -1) { | 457 if (str.Find("italic") != -1) |
312 ret = TRUE; | 458 ret = TRUE; |
313 } | |
314 } | 459 } |
315 return ret; | 460 return ret; |
316 } | 461 } |
317 | 462 |
318 FX_BOOL CFX_Font::IsBold() const { | 463 FX_BOOL CFX_Font::IsBold() const { |
319 if (!m_Face) | 464 if (!m_Face) |
320 return FALSE; | 465 return FALSE; |
321 return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD; | 466 return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD; |
322 } | 467 } |
323 | 468 |
324 FX_BOOL CFX_Font::IsFixedWidth() const { | 469 FX_BOOL CFX_Font::IsFixedWidth() const { |
325 if (!m_Face) | 470 if (!m_Face) |
326 return FALSE; | 471 return FALSE; |
327 return FXFT_Is_Face_fixedwidth(m_Face); | 472 return FXFT_Is_Face_fixedwidth(m_Face); |
328 } | 473 } |
329 | 474 |
330 CFX_ByteString CFX_Font::GetPsName() const { | 475 CFX_ByteString CFX_Font::GetPsName() const { |
331 if (!m_Face) | 476 if (!m_Face) |
332 return CFX_ByteString(); | 477 return CFX_ByteString(); |
333 | 478 |
334 CFX_ByteString psName = FXFT_Get_Postscript_Name(m_Face); | 479 CFX_ByteString psName = FXFT_Get_Postscript_Name(m_Face); |
335 if (psName.IsEmpty()) | 480 if (psName.IsEmpty()) |
336 psName = "Untitled"; | 481 psName = "Untitled"; |
337 return psName; | 482 return psName; |
338 } | 483 } |
339 | 484 |
340 CFX_ByteString CFX_Font::GetFamilyName() const { | 485 CFX_ByteString CFX_Font::GetFamilyName() const { |
341 if (!m_Face && !m_pSubstFont) { | 486 if (!m_Face && !m_pSubstFont) |
342 return CFX_ByteString(); | 487 return CFX_ByteString(); |
343 } | 488 if (m_Face) |
344 if (m_Face) { | |
345 return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); | 489 return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face)); |
346 } | |
347 return m_pSubstFont->m_Family; | 490 return m_pSubstFont->m_Family; |
348 } | 491 } |
492 | |
349 CFX_ByteString CFX_Font::GetFaceName() const { | 493 CFX_ByteString CFX_Font::GetFaceName() const { |
350 if (!m_Face && !m_pSubstFont) { | 494 if (!m_Face && !m_pSubstFont) |
351 return CFX_ByteString(); | 495 return CFX_ByteString(); |
352 } | |
353 if (m_Face) { | 496 if (m_Face) { |
354 CFX_ByteString facename; | 497 CFX_ByteString facename; |
355 CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face)); | 498 CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face)); |
356 facename = GetFamilyName(); | 499 facename = GetFamilyName(); |
357 if (facename.IsEmpty()) { | 500 if (facename.IsEmpty()) |
358 facename = "Untitled"; | 501 facename = "Untitled"; |
359 } | 502 if (!style.IsEmpty() && style != "Regular") |
360 if (!style.IsEmpty() && style != "Regular") { | |
361 facename += " " + style; | 503 facename += " " + style; |
362 } | |
363 return facename; | 504 return facename; |
364 } | 505 } |
365 return m_pSubstFont->m_Family; | 506 return m_pSubstFont->m_Family; |
366 } | 507 } |
508 | |
367 FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) { | 509 FX_BOOL CFX_Font::GetBBox(FX_RECT& bbox) { |
368 if (!m_Face) { | 510 if (!m_Face) |
369 return FALSE; | 511 return FALSE; |
370 } | |
371 int em = FXFT_Get_Face_UnitsPerEM(m_Face); | 512 int em = FXFT_Get_Face_UnitsPerEM(m_Face); |
372 if (em == 0) { | 513 if (em == 0) { |
373 bbox.left = FXFT_Get_Face_xMin(m_Face); | 514 bbox.left = FXFT_Get_Face_xMin(m_Face); |
374 bbox.bottom = FXFT_Get_Face_yMax(m_Face); | 515 bbox.bottom = FXFT_Get_Face_yMax(m_Face); |
375 bbox.top = FXFT_Get_Face_yMin(m_Face); | 516 bbox.top = FXFT_Get_Face_yMin(m_Face); |
376 bbox.right = FXFT_Get_Face_xMax(m_Face); | 517 bbox.right = FXFT_Get_Face_xMax(m_Face); |
377 } else { | 518 } else { |
378 bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em; | 519 bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em; |
379 bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em; | 520 bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em; |
380 bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em; | 521 bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em; |
(...skipping 26 matching lines...) Expand all Loading... | |
407 FXFT_Get_Face_UnderLinePosition(m_Face)); | 548 FXFT_Get_Face_UnderLinePosition(m_Face)); |
408 } | 549 } |
409 | 550 |
410 int CFX_Font::GetULthickness() const { | 551 int CFX_Font::GetULthickness() const { |
411 if (!m_Face) | 552 if (!m_Face) |
412 return 0; | 553 return 0; |
413 | 554 |
414 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), | 555 return EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), |
415 FXFT_Get_Face_UnderLineThickness(m_Face)); | 556 FXFT_Get_Face_UnderLineThickness(m_Face)); |
416 } | 557 } |
558 | |
559 void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight) { | |
560 FXFT_MM_Var pMasters = nullptr; | |
561 FXFT_Get_MM_Var(m_Face, &pMasters); | |
562 if (!pMasters) | |
563 return; | |
564 long coords[2]; | |
565 if (weight == 0) | |
566 coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536; | |
567 else | |
568 coords[0] = weight; | |
569 if (dest_width == 0) { | |
570 coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
571 } else { | |
572 int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
573 int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
574 coords[1] = min_param; | |
575 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
576 FXFT_Load_Glyph(m_Face, glyph_index, | |
577 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | |
578 int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / | |
579 FXFT_Get_Face_UnitsPerEM(m_Face); | |
580 coords[1] = max_param; | |
581 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
582 FXFT_Load_Glyph(m_Face, glyph_index, | |
583 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | |
584 int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / | |
585 FXFT_Get_Face_UnitsPerEM(m_Face); | |
586 if (max_width == min_width) { | |
587 FXFT_Free(m_Face, pMasters); | |
588 return; | |
589 } | |
590 int param = min_param + | |
591 (max_param - min_param) * (dest_width - min_width) / | |
592 (max_width - min_width); | |
593 coords[1] = param; | |
594 } | |
595 FXFT_Free(m_Face, pMasters); | |
596 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
597 } | |
598 | |
599 CFX_PathData* CFX_Font::LoadGlyphPath(uint32_t glyph_index, int dest_width) { | |
600 if (!m_Face) | |
601 return nullptr; | |
602 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); | |
603 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; | |
604 if (m_pSubstFont) { | |
605 if (m_pSubstFont->m_ItalicAngle) { | |
606 int skew = m_pSubstFont->m_ItalicAngle; | |
607 // |skew| is nonpositive so |-skew| is used as the index. We need to make | |
608 // sure |skew| != INT_MIN since -INT_MIN is undefined. | |
609 if (skew <= 0 && skew != std::numeric_limits<int>::min() && | |
610 static_cast<size_t>(-skew) < kAngleSkewArraySize) { | |
611 skew = -s_AngleSkew[-skew]; | |
612 } else { | |
613 skew = -58; | |
614 } | |
615 if (m_bVertical) | |
616 ft_matrix.yx += ft_matrix.yy * skew / 100; | |
617 else | |
618 ft_matrix.xy -= ft_matrix.xx * skew / 100; | |
619 } | |
620 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { | |
621 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); | |
622 } | |
623 } | |
624 ScopedFontTransform scoped_transform(m_Face, &ft_matrix); | |
625 int load_flags = FXFT_LOAD_NO_BITMAP; | |
626 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) | |
627 load_flags |= FT_LOAD_NO_HINTING; | |
628 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags)) | |
629 return nullptr; | |
630 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && | |
631 m_pSubstFont->m_Weight > 400) { | |
632 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10; | |
633 index = std::min(index, static_cast<uint32_t>(kWeightPowArraySize - 1)); | |
634 int level = 0; | |
635 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) | |
636 level = s_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655; | |
637 else | |
638 level = s_WeightPow[index] * 2; | |
639 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); | |
640 } | |
641 FXFT_Outline_Funcs funcs; | |
642 funcs.move_to = Outline_MoveTo; | |
643 funcs.line_to = Outline_LineTo; | |
644 funcs.conic_to = Outline_ConicTo; | |
645 funcs.cubic_to = Outline_CubicTo; | |
646 funcs.shift = 0; | |
647 funcs.delta = 0; | |
648 OUTLINE_PARAMS params; | |
649 params.m_bCount = TRUE; | |
650 params.m_PointCount = 0; | |
651 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); | |
652 if (params.m_PointCount == 0) | |
653 return nullptr; | |
654 CFX_PathData* pPath = new CFX_PathData; | |
655 pPath->SetPointCount(params.m_PointCount); | |
656 params.m_bCount = FALSE; | |
657 params.m_PointCount = 0; | |
658 params.m_pPoints = pPath->GetPoints(); | |
659 params.m_CurX = params.m_CurY = 0; | |
660 params.m_CoordUnit = 64 * 64.0; | |
661 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); | |
662 Outline_CheckEmptyContour(¶ms); | |
663 pPath->TrimPoints(params.m_PointCount); | |
664 if (params.m_PointCount) | |
665 pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; | |
666 return pPath; | |
667 } | |
OLD | NEW |