Chromium Code Reviews| 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 |