| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 | 97 |
| 98 CFX_SizeGlyphCache::CFX_SizeGlyphCache() {} | 98 CFX_SizeGlyphCache::CFX_SizeGlyphCache() {} |
| 99 | 99 |
| 100 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() { | 100 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() { |
| 101 for (const auto& pair : m_GlyphMap) { | 101 for (const auto& pair : m_GlyphMap) { |
| 102 delete pair.second; | 102 delete pair.second; |
| 103 } | 103 } |
| 104 m_GlyphMap.clear(); | 104 m_GlyphMap.clear(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 #define CONTRAST_RAMP_STEP 1 | |
| 108 void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight) { | |
| 109 FXFT_MM_Var pMasters = nullptr; | |
| 110 FXFT_Get_MM_Var(m_Face, &pMasters); | |
| 111 if (!pMasters) { | |
| 112 return; | |
| 113 } | |
| 114 long coords[2]; | |
| 115 if (weight == 0) { | |
| 116 coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536; | |
| 117 } else { | |
| 118 coords[0] = weight; | |
| 119 } | |
| 120 if (dest_width == 0) { | |
| 121 coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
| 122 } else { | |
| 123 int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
| 124 int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536; | |
| 125 coords[1] = min_param; | |
| 126 (void)FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
| 127 (void)FXFT_Load_Glyph( | |
| 128 m_Face, glyph_index, | |
| 129 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | |
| 130 int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / | |
| 131 FXFT_Get_Face_UnitsPerEM(m_Face); | |
| 132 coords[1] = max_param; | |
| 133 (void)FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
| 134 (void)FXFT_Load_Glyph( | |
| 135 m_Face, glyph_index, | |
| 136 FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH); | |
| 137 int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / | |
| 138 FXFT_Get_Face_UnitsPerEM(m_Face); | |
| 139 if (max_width == min_width) { | |
| 140 FXFT_Free(m_Face, pMasters); | |
| 141 return; | |
| 142 } | |
| 143 int param = min_param + | |
| 144 (max_param - min_param) * (dest_width - min_width) / | |
| 145 (max_width - min_width); | |
| 146 coords[1] = param; | |
| 147 } | |
| 148 FXFT_Free(m_Face, pMasters); | |
| 149 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); | |
| 150 } | |
| 151 const char CFX_Font::s_AngleSkew[] = { | |
| 152 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, | |
| 153 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55, | |
| 154 }; | |
| 155 const uint8_t CFX_Font::s_WeightPow[] = { | |
| 156 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, | |
| 157 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37, | |
| 158 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, | |
| 159 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, | |
| 160 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, | |
| 161 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, | |
| 162 }; | |
| 163 const uint8_t CFX_Font::s_WeightPow_11[] = { | |
| 164 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, | |
| 165 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41, | |
| 166 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, | |
| 167 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, | |
| 168 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, | |
| 169 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, | |
| 170 }; | |
| 171 const uint8_t CFX_Font::s_WeightPow_SHIFTJIS[] = { | |
| 172 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, | |
| 173 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, | |
| 174 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, | |
| 175 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, | |
| 176 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, | |
| 177 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, | |
| 178 }; | |
| 179 typedef struct { | |
| 180 FX_BOOL m_bCount; | |
| 181 int m_PointCount; | |
| 182 FX_PATHPOINT* m_pPoints; | |
| 183 int m_CurX; | |
| 184 int m_CurY; | |
| 185 FX_FLOAT m_CoordUnit; | |
| 186 } OUTLINE_PARAMS; | |
| 187 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { | |
| 188 if (param->m_PointCount >= 2 && | |
| 189 param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO && | |
| 190 param->m_pPoints[param->m_PointCount - 2].m_PointX == | |
| 191 param->m_pPoints[param->m_PointCount - 1].m_PointX && | |
| 192 param->m_pPoints[param->m_PointCount - 2].m_PointY == | |
| 193 param->m_pPoints[param->m_PointCount - 1].m_PointY) { | |
| 194 param->m_PointCount -= 2; | |
| 195 } | |
| 196 if (param->m_PointCount >= 4 && | |
| 197 param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO && | |
| 198 param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && | |
| 199 param->m_pPoints[param->m_PointCount - 3].m_PointX == | |
| 200 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
| 201 param->m_pPoints[param->m_PointCount - 3].m_PointY == | |
| 202 param->m_pPoints[param->m_PointCount - 4].m_PointY && | |
| 203 param->m_pPoints[param->m_PointCount - 2].m_PointX == | |
| 204 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
| 205 param->m_pPoints[param->m_PointCount - 2].m_PointY == | |
| 206 param->m_pPoints[param->m_PointCount - 4].m_PointY && | |
| 207 param->m_pPoints[param->m_PointCount - 1].m_PointX == | |
| 208 param->m_pPoints[param->m_PointCount - 4].m_PointX && | |
| 209 param->m_pPoints[param->m_PointCount - 1].m_PointY == | |
| 210 param->m_pPoints[param->m_PointCount - 4].m_PointY) { | |
| 211 param->m_PointCount -= 4; | |
| 212 } | |
| 213 } | |
| 214 extern "C" { | |
| 215 static int _Outline_MoveTo(const FXFT_Vector* to, void* user) { | |
| 216 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
| 217 if (!param->m_bCount) { | |
| 218 _Outline_CheckEmptyContour(param); | |
| 219 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; | |
| 220 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; | |
| 221 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; | |
| 222 param->m_CurX = to->x; | |
| 223 param->m_CurY = to->y; | |
| 224 if (param->m_PointCount) { | |
| 225 param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; | |
| 226 } | |
| 227 } | |
| 228 param->m_PointCount++; | |
| 229 return 0; | |
| 230 } | |
| 231 }; | |
| 232 extern "C" { | |
| 233 static int _Outline_LineTo(const FXFT_Vector* to, void* user) { | |
| 234 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
| 235 if (!param->m_bCount) { | |
| 236 param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; | |
| 237 param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; | |
| 238 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; | |
| 239 param->m_CurX = to->x; | |
| 240 param->m_CurY = to->y; | |
| 241 } | |
| 242 param->m_PointCount++; | |
| 243 return 0; | |
| 244 } | |
| 245 }; | |
| 246 extern "C" { | |
| 247 static int _Outline_ConicTo(const FXFT_Vector* control, | |
| 248 const FXFT_Vector* to, | |
| 249 void* user) { | |
| 250 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
| 251 if (!param->m_bCount) { | |
| 252 param->m_pPoints[param->m_PointCount].m_PointX = | |
| 253 (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / | |
| 254 param->m_CoordUnit; | |
| 255 param->m_pPoints[param->m_PointCount].m_PointY = | |
| 256 (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / | |
| 257 param->m_CoordUnit; | |
| 258 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; | |
| 259 param->m_pPoints[param->m_PointCount + 1].m_PointX = | |
| 260 (control->x + (to->x - control->x) / 3) / param->m_CoordUnit; | |
| 261 param->m_pPoints[param->m_PointCount + 1].m_PointY = | |
| 262 (control->y + (to->y - control->y) / 3) / param->m_CoordUnit; | |
| 263 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; | |
| 264 param->m_pPoints[param->m_PointCount + 2].m_PointX = | |
| 265 to->x / param->m_CoordUnit; | |
| 266 param->m_pPoints[param->m_PointCount + 2].m_PointY = | |
| 267 to->y / param->m_CoordUnit; | |
| 268 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; | |
| 269 param->m_CurX = to->x; | |
| 270 param->m_CurY = to->y; | |
| 271 } | |
| 272 param->m_PointCount += 3; | |
| 273 return 0; | |
| 274 } | |
| 275 }; | |
| 276 extern "C" { | |
| 277 static int _Outline_CubicTo(const FXFT_Vector* control1, | |
| 278 const FXFT_Vector* control2, | |
| 279 const FXFT_Vector* to, | |
| 280 void* user) { | |
| 281 OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; | |
| 282 if (!param->m_bCount) { | |
| 283 param->m_pPoints[param->m_PointCount].m_PointX = | |
| 284 control1->x / param->m_CoordUnit; | |
| 285 param->m_pPoints[param->m_PointCount].m_PointY = | |
| 286 control1->y / param->m_CoordUnit; | |
| 287 param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; | |
| 288 param->m_pPoints[param->m_PointCount + 1].m_PointX = | |
| 289 control2->x / param->m_CoordUnit; | |
| 290 param->m_pPoints[param->m_PointCount + 1].m_PointY = | |
| 291 control2->y / param->m_CoordUnit; | |
| 292 param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; | |
| 293 param->m_pPoints[param->m_PointCount + 2].m_PointX = | |
| 294 to->x / param->m_CoordUnit; | |
| 295 param->m_pPoints[param->m_PointCount + 2].m_PointY = | |
| 296 to->y / param->m_CoordUnit; | |
| 297 param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; | |
| 298 param->m_CurX = to->x; | |
| 299 param->m_CurY = to->y; | |
| 300 } | |
| 301 param->m_PointCount += 3; | |
| 302 return 0; | |
| 303 } | |
| 304 }; | |
| 305 CFX_PathData* CFX_Font::LoadGlyphPath(uint32_t glyph_index, int dest_width) { | |
| 306 if (!m_Face) { | |
| 307 return nullptr; | |
| 308 } | |
| 309 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); | |
| 310 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; | |
| 311 if (m_pSubstFont) { | |
| 312 if (m_pSubstFont->m_ItalicAngle) { | |
| 313 int skew = m_pSubstFont->m_ItalicAngle; | |
| 314 // |skew| is nonpositive so |-skew| is used as the index. We need to make | |
| 315 // sure |skew| != INT_MIN since -INT_MIN is undefined. | |
| 316 if (skew <= 0 && skew != std::numeric_limits<int>::min() && | |
| 317 static_cast<size_t>(-skew) < kAngleSkewArraySize) { | |
| 318 skew = -s_AngleSkew[-skew]; | |
| 319 } else { | |
| 320 skew = -58; | |
| 321 } | |
| 322 if (m_bVertical) | |
| 323 ft_matrix.yx += ft_matrix.yy * skew / 100; | |
| 324 else | |
| 325 ft_matrix.xy -= ft_matrix.xx * skew / 100; | |
| 326 } | |
| 327 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { | |
| 328 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); | |
| 329 } | |
| 330 } | |
| 331 ScopedFontTransform scoped_transform(m_Face, &ft_matrix); | |
| 332 int load_flags = FXFT_LOAD_NO_BITMAP; | |
| 333 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) { | |
| 334 load_flags |= FT_LOAD_NO_HINTING; | |
| 335 } | |
| 336 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags)) | |
| 337 return nullptr; | |
| 338 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && | |
| 339 m_pSubstFont->m_Weight > 400) { | |
| 340 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10; | |
| 341 index = std::min(index, static_cast<uint32_t>(kWeightPowArraySize - 1)); | |
| 342 int level = 0; | |
| 343 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) | |
| 344 level = s_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655; | |
| 345 else | |
| 346 level = s_WeightPow[index] * 2; | |
| 347 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); | |
| 348 } | |
| 349 FXFT_Outline_Funcs funcs; | |
| 350 funcs.move_to = _Outline_MoveTo; | |
| 351 funcs.line_to = _Outline_LineTo; | |
| 352 funcs.conic_to = _Outline_ConicTo; | |
| 353 funcs.cubic_to = _Outline_CubicTo; | |
| 354 funcs.shift = 0; | |
| 355 funcs.delta = 0; | |
| 356 OUTLINE_PARAMS params; | |
| 357 params.m_bCount = TRUE; | |
| 358 params.m_PointCount = 0; | |
| 359 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); | |
| 360 if (params.m_PointCount == 0) { | |
| 361 return nullptr; | |
| 362 } | |
| 363 CFX_PathData* pPath = new CFX_PathData; | |
| 364 pPath->SetPointCount(params.m_PointCount); | |
| 365 params.m_bCount = FALSE; | |
| 366 params.m_PointCount = 0; | |
| 367 params.m_pPoints = pPath->GetPoints(); | |
| 368 params.m_CurX = params.m_CurY = 0; | |
| 369 params.m_CoordUnit = 64 * 64.0; | |
| 370 FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); | |
| 371 _Outline_CheckEmptyContour(¶ms); | |
| 372 pPath->TrimPoints(params.m_PointCount); | |
| 373 if (params.m_PointCount) { | |
| 374 pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; | |
| 375 } | |
| 376 return pPath; | |
| 377 } | |
| 378 void _CFX_UniqueKeyGen::Generate(int count, ...) { | 107 void _CFX_UniqueKeyGen::Generate(int count, ...) { |
| 379 va_list argList; | 108 va_list argList; |
| 380 va_start(argList, count); | 109 va_start(argList, count); |
| 381 for (int i = 0; i < count; i++) { | 110 for (int i = 0; i < count; i++) { |
| 382 int p = va_arg(argList, int); | 111 int p = va_arg(argList, int); |
| 383 ((uint32_t*)m_Key)[i] = p; | 112 ((uint32_t*)m_Key)[i] = p; |
| 384 } | 113 } |
| 385 va_end(argList); | 114 va_end(argList); |
| 386 m_KeyLen = count * sizeof(uint32_t); | 115 m_KeyLen = count * sizeof(uint32_t); |
| 387 } | 116 } |
| OLD | NEW |