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

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: Comments 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
« no previous file with comments | « core/fxge/ge/cfx_renderdevice.cpp ('k') | core/fxge/include/cfx_facecache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <algorithm>
7 #include <limits> 8 #include <limits>
8 #include <vector> 9 #include <vector>
9 10
10 #include "core/fxcodec/include/fx_codec.h" 11 #include "core/fxcodec/include/fx_codec.h"
11 #include "core/fxcrt/include/fx_safe_types.h" 12 #include "core/fxcrt/include/fx_safe_types.h"
12 #include "core/fxge/ge/fx_text_int.h" 13 #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" 14 #include "core/fxge/include/cfx_pathdata.h"
16 #include "core/fxge/include/fx_freetype.h" 15 #include "core/fxge/include/fx_freetype.h"
17 #include "core/fxge/include/ifx_renderdevicedriver.h" 16 #include "core/fxge/include/ifx_renderdevicedriver.h"
18 17
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 { 18 namespace {
25 19
26 void ResetTransform(FT_Face face) { 20 void ResetTransform(FT_Face face) {
27 FXFT_Matrix matrix; 21 FXFT_Matrix matrix;
28 matrix.xx = 0x10000L; 22 matrix.xx = 0x10000L;
29 matrix.xy = 0; 23 matrix.xy = 0;
30 matrix.yx = 0; 24 matrix.yx = 0;
31 matrix.yy = 0x10000L; 25 matrix.yy = 0x10000L;
32 FXFT_Set_Transform(face, &matrix, 0); 26 FXFT_Set_Transform(face, &matrix, 0);
33 } 27 }
34 28
35 // Sets the given transform on the font, and resets it to the identity when it 29 } // 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 30
43 ~ScopedFontTransform() { ResetTransform(m_Face); } 31 ScopedFontTransform::ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix)
32 : m_Face(face) {
33 FXFT_Set_Transform(m_Face, matrix, 0);
34 }
44 35
45 private: 36 ScopedFontTransform::~ScopedFontTransform() {
46 FT_Face m_Face; 37 ResetTransform(m_Face);
47 }; 38 }
48
49 } // namespace
50 39
51 FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, 40 FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs,
52 int anti_alias, 41 int anti_alias,
53 FX_FLOAT retinaScaleX, 42 FX_FLOAT retinaScaleX,
54 FX_FLOAT retinaScaleY) { 43 FX_FLOAT retinaScaleY) {
55 FX_RECT rect(0, 0, 0, 0); 44 FX_RECT rect(0, 0, 0, 0);
56 bool bStarted = false; 45 bool bStarted = false;
57 for (const FXTEXT_GLYPHPOS& glyph : glyphs) { 46 for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
58 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph; 47 const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
59 if (!pGlyph) 48 if (!pGlyph)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 88
100 rect.left = char_left.ValueOrDie(); 89 rect.left = char_left.ValueOrDie();
101 rect.right = char_right.ValueOrDie(); 90 rect.right = char_right.ValueOrDie();
102 rect.top = char_top.ValueOrDie(); 91 rect.top = char_top.ValueOrDie();
103 rect.bottom = char_bottom.ValueOrDie(); 92 rect.bottom = char_bottom.ValueOrDie();
104 bStarted = true; 93 bStarted = true;
105 } 94 }
106 return rect; 95 return rect;
107 } 96 }
108 97
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() {} 98 CFX_SizeGlyphCache::CFX_SizeGlyphCache() {}
271 99
272 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() { 100 CFX_SizeGlyphCache::~CFX_SizeGlyphCache() {
273 for (const auto& pair : m_GlyphMap) { 101 for (const auto& pair : m_GlyphMap) {
274 delete pair.second; 102 delete pair.second;
275 } 103 }
276 m_GlyphMap.clear(); 104 m_GlyphMap.clear();
277 } 105 }
278 106
279 #define CONTRAST_RAMP_STEP 1 107 #define CONTRAST_RAMP_STEP 1
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 return; 141 return;
314 } 142 }
315 int param = min_param + 143 int param = min_param +
316 (max_param - min_param) * (dest_width - min_width) / 144 (max_param - min_param) * (dest_width - min_width) /
317 (max_width - min_width); 145 (max_width - min_width);
318 coords[1] = param; 146 coords[1] = param;
319 } 147 }
320 FXFT_Free(m_Face, pMasters); 148 FXFT_Free(m_Face, pMasters);
321 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords); 149 FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
322 } 150 }
323 static const size_t ANGLESKEW_ARRAY_SIZE = 30; 151 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, 152 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, 153 27, 29, 31, 32, 34, 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
327 }; 154 };
328 static const size_t WEIGHTPOW_ARRAY_SIZE = 100; 155 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, 156 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, 157 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, 158 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, 159 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, 160 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, 161 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
336 }; 162 };
337 static const uint8_t g_WeightPow_11[WEIGHTPOW_ARRAY_SIZE] = { 163 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, 164 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, 165 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, 166 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, 167 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, 168 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, 169 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
344 }; 170 };
345 static const uint8_t g_WeightPow_SHIFTJIS[WEIGHTPOW_ARRAY_SIZE] = { 171 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, 172 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, 173 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, 174 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, 175 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, 176 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, 177 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
352 }; 178 };
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 { 179 typedef struct {
571 FX_BOOL m_bCount; 180 FX_BOOL m_bCount;
572 int m_PointCount; 181 int m_PointCount;
573 FX_PATHPOINT* m_pPoints; 182 FX_PATHPOINT* m_pPoints;
574 int m_CurX; 183 int m_CurX;
575 int m_CurY; 184 int m_CurY;
576 FX_FLOAT m_CoordUnit; 185 FX_FLOAT m_CoordUnit;
577 } OUTLINE_PARAMS; 186 } OUTLINE_PARAMS;
578 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { 187 void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param) {
579 if (param->m_PointCount >= 2 && 188 if (param->m_PointCount >= 2 &&
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 return nullptr; 307 return nullptr;
699 } 308 }
700 FXFT_Set_Pixel_Sizes(m_Face, 0, 64); 309 FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
701 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536}; 310 FXFT_Matrix ft_matrix = {65536, 0, 0, 65536};
702 if (m_pSubstFont) { 311 if (m_pSubstFont) {
703 if (m_pSubstFont->m_ItalicAngle) { 312 if (m_pSubstFont->m_ItalicAngle) {
704 int skew = m_pSubstFont->m_ItalicAngle; 313 int skew = m_pSubstFont->m_ItalicAngle;
705 // |skew| is nonpositive so |-skew| is used as the index. We need to make 314 // |skew| is nonpositive so |-skew| is used as the index. We need to make
706 // sure |skew| != INT_MIN since -INT_MIN is undefined. 315 // sure |skew| != INT_MIN since -INT_MIN is undefined.
707 if (skew <= 0 && skew != std::numeric_limits<int>::min() && 316 if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
708 static_cast<size_t>(-skew) < ANGLESKEW_ARRAY_SIZE) { 317 static_cast<size_t>(-skew) < kAngleSkewArraySize) {
709 skew = -g_AngleSkew[-skew]; 318 skew = -s_AngleSkew[-skew];
710 } else { 319 } else {
711 skew = -58; 320 skew = -58;
712 } 321 }
713 if (m_bVertical) 322 if (m_bVertical)
714 ft_matrix.yx += ft_matrix.yy * skew / 100; 323 ft_matrix.yx += ft_matrix.yy * skew / 100;
715 else 324 else
716 ft_matrix.xy -= ft_matrix.xx * skew / 100; 325 ft_matrix.xy -= ft_matrix.xx * skew / 100;
717 } 326 }
718 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) { 327 if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
719 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight); 328 AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
720 } 329 }
721 } 330 }
722 ScopedFontTransform scoped_transform(m_Face, &ft_matrix); 331 ScopedFontTransform scoped_transform(m_Face, &ft_matrix);
723 int load_flags = FXFT_LOAD_NO_BITMAP; 332 int load_flags = FXFT_LOAD_NO_BITMAP;
724 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) { 333 if (!(m_Face->face_flags & FT_FACE_FLAG_SFNT) || !FT_IS_TRICKY(m_Face)) {
725 load_flags |= FT_LOAD_NO_HINTING; 334 load_flags |= FT_LOAD_NO_HINTING;
726 } 335 }
727 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags)) 336 if (FXFT_Load_Glyph(m_Face, glyph_index, load_flags))
728 return nullptr; 337 return nullptr;
729 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && 338 if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
730 m_pSubstFont->m_Weight > 400) { 339 m_pSubstFont->m_Weight > 400) {
731 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10; 340 uint32_t index = (m_pSubstFont->m_Weight - 400) / 10;
732 if (index >= WEIGHTPOW_ARRAY_SIZE) 341 index = std::min(index, static_cast<uint32_t>(kWeightPowArraySize - 1));
733 index = WEIGHTPOW_ARRAY_SIZE - 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
« no previous file with comments | « core/fxge/ge/cfx_renderdevice.cpp ('k') | core/fxge/include/cfx_facecache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698