Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: core/fxge/ge/fx_ge_text.cpp

Issue 2263623002: Refactor fx_font part 3 (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Trying to fix bots Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <limits> 7 #include <limits>
8 #include <vector> 8 #include <vector>
9 9
10 #include "core/fxcodec/include/fx_codec.h" 10 #include "core/fxcodec/include/fx_codec.h"
11 #include "core/fxcrt/include/fx_safe_types.h" 11 #include "core/fxcrt/include/fx_safe_types.h"
12 #include "core/fxge/ge/fx_text_int.h" 12 #include "core/fxge/ge/fx_text_int.h"
13 #include "core/fxge/include/cfx_fontmgr.h"
14 #include "core/fxge/include/cfx_gemodule.h"
15 #include "core/fxge/include/cfx_pathdata.h" 13 #include "core/fxge/include/cfx_pathdata.h"
16 #include "core/fxge/include/fx_freetype.h" 14 #include "core/fxge/include/fx_freetype.h"
17 #include "core/fxge/include/ifx_renderdevicedriver.h" 15 #include "core/fxge/include/ifx_renderdevicedriver.h"
18 16
19 #ifdef _SKIA_SUPPORT_
20 #include "third_party/skia/include/core/SkStream.h"
21 #include "third_party/skia/include/core/SkTypeface.h"
22 #endif
23
24 namespace { 17 namespace {
25 18
26 void ResetTransform(FT_Face face) { 19 void ResetTransform(FT_Face face) {
27 FXFT_Matrix matrix; 20 FXFT_Matrix matrix;
28 matrix.xx = 0x10000L; 21 matrix.xx = 0x10000L;
29 matrix.xy = 0; 22 matrix.xy = 0;
30 matrix.yx = 0; 23 matrix.yx = 0;
31 matrix.yy = 0x10000L; 24 matrix.yy = 0x10000L;
32 FXFT_Set_Transform(face, &matrix, 0); 25 FXFT_Set_Transform(face, &matrix, 0);
33 } 26 }
34 27
35 // Sets the given transform on the font, and resets it to the identity when it 28 } // namespace
36 // goes out of scope.
37 class ScopedFontTransform {
38 public:
39 ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix) : m_Face(face) {
40 FXFT_Set_Transform(m_Face, matrix, 0);
41 }
42 29
43 ~ScopedFontTransform() { ResetTransform(m_Face); } 30 ScopedFontTransform::ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix)
31 : m_Face(face) {
32 FXFT_Set_Transform(m_Face, matrix, 0);
33 }
44 34
45 private: 35 ScopedFontTransform::~ScopedFontTransform() {
46 FT_Face m_Face; 36 ResetTransform(m_Face);
47 }; 37 }
48
49 } // namespace
50 38
51 FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, 39 FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs,
52 int anti_alias, 40 int anti_alias,
53 FX_FLOAT retinaScaleX, 41 FX_FLOAT retinaScaleX,
54 FX_FLOAT retinaScaleY) { 42 FX_FLOAT retinaScaleY) {
55 FX_RECT rect(0, 0, 0, 0); 43 FX_RECT rect(0, 0, 0, 0);
56 bool bStarted = false; 44 bool bStarted = false;
57 for (const FXTEXT_GLYPHPOS& glyph : glyphs) { 45 for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
58 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph; 46 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
59 if (!pGlyph) 47 if (!pGlyph)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 87
100 rect.left = char_left.ValueOrDie(); 88 rect.left = char_left.ValueOrDie();
101 rect.right = char_right.ValueOrDie(); 89 rect.right = char_right.ValueOrDie();
102 rect.top = char_top.ValueOrDie(); 90 rect.top = char_top.ValueOrDie();
103 rect.bottom = char_bottom.ValueOrDie(); 91 rect.bottom = char_bottom.ValueOrDie();
104 bStarted = true; 92 bStarted = true;
105 } 93 }
106 return rect; 94 return rect;
107 } 95 }
108 96
109 #ifdef _SKIA_SUPPORT_
110 CFX_TypeFace* CFX_FaceCache::GetDeviceCache(CFX_Font* pFont) {
111 if (!m_pTypeface) {
112 m_pTypeface =
113 SkTypeface::MakeFromStream(
114 new SkMemoryStream(pFont->GetFontData(), pFont->GetSize()))
115 .release();
116 }
117 return m_pTypeface;
118 }
119 #endif
120
121 CFX_FaceCache::CFX_FaceCache(FXFT_Face face)
122 : m_Face(face)
123 #ifdef _SKIA_SUPPORT_
124 ,
125 m_pTypeface(nullptr)
126 #endif
127 {
128 }
129
130 CFX_FaceCache::~CFX_FaceCache() {
131 for (const auto& pair : m_SizeMap) {
132 delete pair.second;
133 }
134 m_SizeMap.clear();
135 for (const auto& pair : m_PathMap) {
136 delete pair.second;
137 }
138 m_PathMap.clear();
139 #ifdef _SKIA_SUPPORT_
140 SkSafeUnref(m_pTypeface);
141 #endif
142 }
143
144 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
145 void CFX_FaceCache::InitPlatform() {}
146 #endif
147 CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(
148 CFX_Font* pFont,
149 const CFX_Matrix* pMatrix,
150 const CFX_ByteString& FaceGlyphsKey,
151 uint32_t glyph_index,
152 FX_BOOL bFontStyle,
153 int dest_width,
154 int anti_alias) {
155 CFX_SizeGlyphCache* pSizeCache;
156 auto it = m_SizeMap.find(FaceGlyphsKey);
157 if (it == m_SizeMap.end()) {
158 pSizeCache = new CFX_SizeGlyphCache;
159 m_SizeMap[FaceGlyphsKey] = pSizeCache;
160 } else {
161 pSizeCache = it->second;
162 }
163 auto it2 = pSizeCache->m_GlyphMap.find(glyph_index);
164 if (it2 != pSizeCache->m_GlyphMap.end())
165 return it2->second;
166
167 CFX_GlyphBitmap* pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle,
168 pMatrix, dest_width, anti_alias);
169 if (!pGlyphBitmap)
170 return nullptr;
171
172 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
173 return pGlyphBitmap;
174 }
175 const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont,
176 uint32_t glyph_index,
177 FX_BOOL bFontStyle,
178 const CFX_Matrix* pMatrix,
179 int dest_width,
180 int anti_alias,
181 int& text_flags) {
182 if (glyph_index == (uint32_t)-1) {
183 return nullptr;
184 }
185 _CFX_UniqueKeyGen keygen;
186 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
187 if (pFont->GetSubstFont())
188 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
189 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
190 dest_width, anti_alias, pFont->GetSubstFont()->m_Weight,
191 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
192 else
193 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
194 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
195 dest_width, anti_alias);
196 #else
197 if (text_flags & FXTEXT_NO_NATIVETEXT) {
198 if (pFont->GetSubstFont())
199 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
200 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
201 dest_width, anti_alias, pFont->GetSubstFont()->m_Weight,
202 pFont->GetSubstFont()->m_ItalicAngle,
203 pFont->IsVertical());
204 else
205 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
206 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
207 dest_width, anti_alias);
208 } else {
209 if (pFont->GetSubstFont())
210 keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
211 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
212 dest_width, anti_alias, pFont->GetSubstFont()->m_Weight,
213 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(),
214 3);
215 else
216 keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
217 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
218 dest_width, anti_alias, 3);
219 }
220 #endif
221 CFX_ByteString FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
222 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ || defined _SKIA_SUPPORT_
223 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index,
224 bFontStyle, dest_width, anti_alias);
225 #else
226 if (text_flags & FXTEXT_NO_NATIVETEXT) {
227 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index,
228 bFontStyle, dest_width, anti_alias);
229 }
230 CFX_GlyphBitmap* pGlyphBitmap;
231 auto it = m_SizeMap.find(FaceGlyphsKey);
232 if (it != m_SizeMap.end()) {
233 CFX_SizeGlyphCache* pSizeCache = it->second;
234 auto it2 = pSizeCache->m_GlyphMap.find(glyph_index);
235 if (it2 != pSizeCache->m_GlyphMap.end())
236 return it2->second;
237
238 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix,
239 dest_width, anti_alias);
240 if (pGlyphBitmap) {
241 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
242 return pGlyphBitmap;
243 }
244 } else {
245 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix,
246 dest_width, anti_alias);
247 if (pGlyphBitmap) {
248 CFX_SizeGlyphCache* pSizeCache = new CFX_SizeGlyphCache;
249 m_SizeMap[FaceGlyphsKey] = pSizeCache;
250 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
251 return pGlyphBitmap;
252 }
253 }
254 if (pFont->GetSubstFont())
255 keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
256 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
257 dest_width, anti_alias, pFont->GetSubstFont()->m_Weight,
258 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
259 else
260 keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
261 (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000),
262 dest_width, anti_alias);
263 CFX_ByteString FaceGlyphsKey2(keygen.m_Key, keygen.m_KeyLen);
264 text_flags |= FXTEXT_NO_NATIVETEXT;
265 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey2, glyph_index,
266 bFontStyle, dest_width, anti_alias);
267 #endif
268 }
269
270 CFX_SizeGlyphCache::CFX_SizeGlyphCache() {} 97 CFX_SizeGlyphCache::CFX_SizeGlyphCache() {}
271 98
272 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() { 99 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() {
273 for (const auto& pair : m_GlyphMap) { 100 for (const auto& pair : m_GlyphMap) {
274 delete pair.second; 101 delete pair.second;
275 } 102 }
276 m_GlyphMap.clear(); 103 m_GlyphMap.clear();
277 } 104 }
278 105
279 #define CONTRAST_RAMP_STEP 1 106 #define CONTRAST_RAMP_STEP 1
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 return; 140 return;
314 } 141 }
315 int param = min_param + 142 int param = min_param +
316 (max_param - min_param) * (dest_width - min_width) / 143 (max_param - min_param) * (dest_width - min_width) /
317 (max_width - min_width); 144 (max_width - min_width);
318 coords[1] = param; 145 coords[1] = param;
319 } 146 }
320 FXFT_Free(m_Face, pMasters); 147 FXFT_Free(m_Face, pMasters);
321 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); 148 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
322 } 149 }
323 static const size_t ANGLESKEW_ARRAY_SIZE = 30; 150 const char CFX_Font::s_AngleSkew[] = {
324 static const char g_AngleSkew[ANGLESKEW_ARRAY_SIZE] = {
325 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, 151 0, 2, 3, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25,
326 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55, 152 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
327 }; 153 };
328 static const size_t WEIGHTPOW_ARRAY_SIZE = 100; 154 const uint8_t CFX_Font::s_WeightPow[] = {
329 static const uint8_t g_WeightPow[WEIGHTPOW_ARRAY_SIZE] = {
330 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 155 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22,
331 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37, 156 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36, 37,
332 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 157 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42,
333 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 158 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47,
334 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 159 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50,
335 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 160 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
336 }; 161 };
337 static const uint8_t g_WeightPow_11[WEIGHTPOW_ARRAY_SIZE] = { 162 const uint8_t CFX_Font::s_WeightPow_11[] = {
338 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24, 163 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23, 24,
339 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41, 164 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40, 41,
340 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46, 165 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
341 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, 166 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52,
342 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 167 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55,
343 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 168 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
344 }; 169 };
345 static const uint8_t g_WeightPow_SHIFTJIS[WEIGHTPOW_ARRAY_SIZE] = { 170 const uint8_t CFX_Font::s_WeightPow_SHIFTJIS[] = {
346 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, 171 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21,
347 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, 172 22, 24, 26, 28, 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48,
348 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 173 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53,
349 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 174 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56,
350 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 175 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58,
351 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 176 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
352 }; 177 };
353 static void _GammaAdjust(uint8_t* pData,
354 int nWid,
355 int nHei,
356 int src_pitch,
357 const uint8_t* gammaTable) {
358 int count = nHei * src_pitch;
359 for (int i = 0; i < count; i++) {
360 pData[i] = gammaTable[pData[i]];
361 }
362 }
363 static void _ContrastAdjust(uint8_t* pDataIn,
364 uint8_t* pDataOut,
365 int nWid,
366 int nHei,
367 int nSrcRowBytes,
368 int nDstRowBytes) {
369 int col, row, temp;
370 int max = 0, min = 255;
371 FX_FLOAT rate;
372 for (row = 0; row < nHei; row++) {
373 uint8_t* pRow = pDataIn + row * nSrcRowBytes;
374 for (col = 0; col < nWid; col++) {
375 temp = *pRow++;
376 if (temp > max) {
377 max = temp;
378 }
379 if (temp < min) {
380 min = temp;
381 }
382 }
383 }
384 temp = max - min;
385 if (0 == temp || 255 == temp) {
386 int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes
387 ? nDstRowBytes
388 : FXSYS_abs(nSrcRowBytes);
389 for (row = 0; row < nHei; row++) {
390 FXSYS_memcpy(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes,
391 rowbytes);
392 }
393 return;
394 }
395 rate = 255.f / temp;
396 for (row = 0; row < nHei; row++) {
397 uint8_t* pSrcRow = pDataIn + row * nSrcRowBytes;
398 uint8_t* pDstRow = pDataOut + row * nDstRowBytes;
399 for (col = 0; col < nWid; col++) {
400 temp = (int)((*(pSrcRow++) - min) * rate + 0.5);
401 if (temp > 255) {
402 temp = 255;
403 } else if (temp < 0) {
404 temp = 0;
405 }
406 *pDstRow++ = (uint8_t)temp;
407 }
408 }
409 }
410 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont,
411 uint32_t glyph_index,
412 FX_BOOL bFontStyle,
413 const CFX_Matrix* pMatrix,
414 int dest_width,
415 int anti_alias) {
416 if (!m_Face) {
417 return nullptr;
418 }
419 FXFT_Matrix ft_matrix;
420 ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
421 ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
422 ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
423 ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
424 FX_BOOL bUseCJKSubFont = FALSE;
425 const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
426 if (pSubstFont) {
427 bUseCJKSubFont = pSubstFont->m_bSubstCJK && bFontStyle;
428 int skew = 0;
429 if (bUseCJKSubFont) {
430 skew = pSubstFont->m_bItalicCJK ? -15 : 0;
431 } else {
432 skew = pSubstFont->m_ItalicAngle;
433 }
434 if (skew) {
435 // |skew| is nonpositive so |-skew| is used as the index. We need to make
436 // sure |skew| != INT_MIN since -INT_MIN is undefined.
437 if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
438 static_cast<size_t>(-skew) < ANGLESKEW_ARRAY_SIZE) {
439 skew = -g_AngleSkew[-skew];
440 } else {
441 skew = -58;
442 }
443 if (pFont->IsVertical())
444 ft_matrix.yx += ft_matrix.yy * skew / 100;
445 else
446 ft_matrix.xy -= ft_matrix.xx * skew / 100;
447 }
448 if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
449 pFont->AdjustMMParams(glyph_index, dest_width,
450 pFont->GetSubstFont()->m_Weight);
451 }
452 }
453 ScopedFontTransform scoped_transform(m_Face, &ft_matrix);
454 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT)
455 ? FXFT_LOAD_NO_BITMAP
456 : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
457 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
458 if (error) {
459 // if an error is returned, try to reload glyphs without hinting.
460 if (load_flags & FT_LOAD_NO_HINTING || load_flags & FT_LOAD_NO_SCALE) {
461 return nullptr;
462 }
463
464 load_flags |= FT_LOAD_NO_HINTING;
465 error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
466
467 if (error) {
468 return nullptr;
469 }
470 }
471 int weight = 0;
472 if (bUseCJKSubFont) {
473 weight = pSubstFont->m_WeightCJK;
474 } else {
475 weight = pSubstFont ? pSubstFont->m_Weight : 0;
476 }
477 if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
478 weight > 400) {
479 uint32_t index = (weight - 400) / 10;
480 if (index >= WEIGHTPOW_ARRAY_SIZE)
481 return nullptr;
482 int level = 0;
483 if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
484 level =
485 g_WeightPow_SHIFTJIS[index] * 2 *
486 (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) /
487 36655;
488 } else {
489 level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) +
490 FXSYS_abs((int)(ft_matrix.xy))) /
491 36655;
492 }
493 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
494 }
495 FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
496 FT_LCD_FILTER_DEFAULT);
497 error = FXFT_Render_Glyph(m_Face, anti_alias);
498 if (error) {
499 return nullptr;
500 }
501 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face));
502 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face));
503 if (bmwidth > 2048 || bmheight > 2048) {
504 return nullptr;
505 }
506 int dib_width = bmwidth;
507 CFX_GlyphBitmap* pGlyphBitmap = new CFX_GlyphBitmap;
508 pGlyphBitmap->m_Bitmap.Create(
509 dib_width, bmheight,
510 anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask);
511 pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face);
512 pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face);
513 int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch();
514 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face));
515 uint8_t* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer();
516 uint8_t* pSrcBuf =
517 (uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face));
518 if (anti_alias != FXFT_RENDER_MODE_MONO &&
519 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
520 FXFT_PIXEL_MODE_MONO) {
521 int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1;
522 for (int i = 0; i < bmheight; i++)
523 for (int n = 0; n < bmwidth; n++) {
524 uint8_t data =
525 (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
526 for (int b = 0; b < bytes; b++) {
527 pDestBuf[i * dest_pitch + n * bytes + b] = data;
528 }
529 }
530 } else {
531 FXSYS_memset(pDestBuf, 0, dest_pitch * bmheight);
532 if (anti_alias == FXFT_RENDER_MODE_MONO &&
533 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
534 FXFT_PIXEL_MODE_MONO) {
535 int rowbytes =
536 FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch);
537 for (int row = 0; row < bmheight; row++) {
538 FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch,
539 rowbytes);
540 }
541 } else {
542 _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch,
543 dest_pitch);
544 _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch,
545 CFX_GEModule::Get()->GetTextGammaTable());
546 }
547 }
548 return pGlyphBitmap;
549 }
550 const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont,
551 uint32_t glyph_index,
552 int dest_width) {
553 if (!m_Face || glyph_index == (uint32_t)-1)
554 return nullptr;
555
556 uint32_t key = glyph_index;
557 if (pFont->GetSubstFont()) {
558 key += (((pFont->GetSubstFont()->m_Weight / 16) << 15) +
559 ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) +
560 ((dest_width / 16) << 25) + (pFont->IsVertical() << 31));
561 }
562 auto it = m_PathMap.find(key);
563 if (it != m_PathMap.end())
564 return it->second;
565
566 CFX_PathData* pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
567 m_PathMap[key] = pGlyphPath;
568 return pGlyphPath;
569 }
570 typedef struct { 178 typedef struct {
571 FX_BOOL m_bCount; 179 FX_BOOL m_bCount;
572 int m_PointCount; 180 int m_PointCount;
573 FX_PATHPOINT* m_pPoints; 181 FX_PATHPOINT* m_pPoints;
574 int m_CurX; 182 int m_CurX;
575 int m_CurY; 183 int m_CurY;
576 FX_FLOAT m_CoordUnit; 184 FX_FLOAT m_CoordUnit;
577 } OUTLINE_PARAMS; 185 } OUTLINE_PARAMS;
578 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { 186 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
579 if (param->m_PointCount >= 2 && 187 if (param->m_PointCount >= 2 &&
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 return nullptr; 306 return nullptr;
699 } 307 }
700 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 308 FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
701 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; 309 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536};
702 if (m_pSubstFont) { 310 if (m_pSubstFont) {
703 if (m_pSubstFont->m_ItalicAngle) { 311 if (m_pSubstFont->m_ItalicAngle) {
704 int skew = m_pSubstFont->m_ItalicAngle; 312 int skew = m_pSubstFont->m_ItalicAngle;
705 // |skew| is nonpositive so |-skew| is used as the index. We need to make 313 // |skew| is nonpositive so |-skew| is used as the index. We need to make
706 // sure |skew| != INT_MIN since -INT_MIN is undefined. 314 // sure |skew| != INT_MIN since -INT_MIN is undefined.
707 if (skew <= 0 && skew != std::numeric_limits<int>::min() && 315 if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
708 static_cast<size_t>(-skew) < ANGLESKEW_ARRAY_SIZE) { 316 static_cast<size_t>(-skew) < kAngleSkewArraySize) {
709 skew = -g_AngleSkew[-skew]; 317 skew = -s_AngleSkew[-skew];
710 } else { 318 } else {
711 skew = -58; 319 skew = -58;
712 } 320 }
713 if (m_bVertical) 321 if (m_bVertical)
714 ft_matrix.yx += ft_matrix.yy * skew / 100; 322 ft_matrix.yx += ft_matrix.yy * skew / 100;
715 else 323 else
716 ft_matrix.xy -= ft_matrix.xx * skew / 100; 324 ft_matrix.xy -= ft_matrix.xx * skew / 100;
717 } 325 }
718 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { 326 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
719 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); 327 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
720 } 328 }
721 } 329 }
722 ScopedFontTransform scoped_transform(m_Face, &ft_matrix); 330 ScopedFontTransform scoped_transform(m_Face, &ft_matrix);
723 int load_flags = FXFT_LOAD_NO_BITMAP; 331 int load_flags = FXFT_LOAD_NO_BITMAP;
724 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) { 332 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) {
725 load_flags |= FT_LOAD_NO_HINTING; 333 load_flags |= FT_LOAD_NO_HINTING;
726 } 334 }
727 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags)) 335 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags))
728 return nullptr; 336 return nullptr;
729 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && 337 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
730 m_pSubstFont->m_Weight > 400) { 338 m_pSubstFont->m_Weight > 400) {
731 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10; 339 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10;
732 if (index >= WEIGHTPOW_ARRAY_SIZE) 340 if (index >= kWeightPowArraySize)
Lei Zhang 2016/08/19 22:44:58 std::min(index, kWeightPowArraySize - 1)
733 index = WEIGHTPOW_ARRAY_SIZE - 1; 341 index = kWeightPowArraySize - 1;
734 int level = 0; 342 int level = 0;
735 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) 343 if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET)
736 level = g_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655; 344 level = s_WeightPow_SHIFTJIS[index] * 2 * 65536 / 36655;
737 else 345 else
738 level = g_WeightPow[index] * 2; 346 level = s_WeightPow[index] * 2;
739 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); 347 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
740 } 348 }
741 FXFT_Outline_Funcs funcs; 349 FXFT_Outline_Funcs funcs;
742 funcs.move_to = _Outline_MoveTo; 350 funcs.move_to = _Outline_MoveTo;
743 funcs.line_to = _Outline_LineTo; 351 funcs.line_to = _Outline_LineTo;
744 funcs.conic_to = _Outline_ConicTo; 352 funcs.conic_to = _Outline_ConicTo;
745 funcs.cubic_to = _Outline_CubicTo; 353 funcs.cubic_to = _Outline_CubicTo;
746 funcs.shift = 0; 354 funcs.shift = 0;
747 funcs.delta = 0; 355 funcs.delta = 0;
748 OUTLINE_PARAMS params; 356 OUTLINE_PARAMS params;
(...skipping 21 matching lines...) Expand all
770 void _CFX_UniqueKeyGen::Generate(int count, ...) { 378 void _CFX_UniqueKeyGen::Generate(int count, ...) {
771 va_list argList; 379 va_list argList;
772 va_start(argList, count); 380 va_start(argList, count);
773 for (int i = 0; i < count; i++) { 381 for (int i = 0; i < count; i++) {
774 int p = va_arg(argList, int); 382 int p = va_arg(argList, int);
775 ((uint32_t*)m_Key)[i] = p; 383 ((uint32_t*)m_Key)[i] = p;
776 } 384 }
777 va_end(argList); 385 va_end(argList);
778 m_KeyLen = count * sizeof(uint32_t); 386 m_KeyLen = count * sizeof(uint32_t);
779 } 387 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698