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

Side by Side Diff: core/fxge/ge/cfx_facecache.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
(Empty)
1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxge/include/cfx_facecache.h"
8
9 #include <algorithm>
10
11 #include "core/fxge/ge/fx_text_int.h"
12 #include "core/fxge/include/cfx_fontmgr.h"
13 #include "core/fxge/include/cfx_gemodule.h"
14 #include "core/fxge/include/cfx_pathdata.h"
15 #include "core/fxge/include/fx_freetype.h"
16
17 #ifdef _SKIA_SUPPORT_
18 #include "third_party/skia/include/core/SkStream.h"
19 #include "third_party/skia/include/core/SkTypeface.h"
20 #endif
21
22 namespace {
23
24 void GammaAdjust(uint8_t* pData,
25 int nHeight,
26 int src_pitch,
27 const uint8_t* gammaTable) {
28 int count = nHeight * src_pitch;
29 for (int i = 0; i < count; i++)
30 pData[i] = gammaTable[pData[i]];
31 }
32
33 void ContrastAdjust(uint8_t* pDataIn,
34 uint8_t* pDataOut,
35 int nWidth,
36 int nHeight,
37 int nSrcRowBytes,
38 int nDstRowBytes) {
39 int col, row, temp;
40 int max = 0, min = 255;
41 FX_FLOAT rate;
42 for (row = 0; row < nHeight; row++) {
43 uint8_t* pRow = pDataIn + row * nSrcRowBytes;
44 for (col = 0; col < nWidth; col++) {
45 temp = *pRow++;
46 max = std::max(temp, max);
47 min = std::min(temp, min);
48 }
49 }
50 temp = max - min;
51 if (temp == 0 || temp == 255) {
52 int rowbytes = std::min(FXSYS_abs(nSrcRowBytes), nDstRowBytes);
53 for (row = 0; row < nHeight; row++) {
54 FXSYS_memcpy(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes,
55 rowbytes);
56 }
57 return;
58 }
59 rate = 255.f / temp;
60 for (row = 0; row < nHeight; row++) {
61 uint8_t* pSrcRow = pDataIn + row * nSrcRowBytes;
62 uint8_t* pDstRow = pDataOut + row * nDstRowBytes;
63 for (col = 0; col < nWidth; col++) {
64 temp = static_cast<int>((*(pSrcRow++) - min) * rate + 0.5);
65 temp = std::min(temp, 255);
66 temp = std::max(temp, 0);
67 *pDstRow++ = (uint8_t)temp;
68 }
69 }
70 }
71 } // namespace
72
73 CFX_FaceCache::CFX_FaceCache(FXFT_Face face)
74 : m_Face(face)
75 #ifdef _SKIA_SUPPORT_
76 ,
77 m_pTypeface(nullptr)
78 #endif
79 {
80 }
81
82 CFX_FaceCache::~CFX_FaceCache() {
83 #ifdef _SKIA_SUPPORT_
84 SkSafeUnref(m_pTypeface);
85 #endif
86 }
87
88 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont,
89 uint32_t glyph_index,
90 FX_BOOL bFontStyle,
91 const CFX_Matrix* pMatrix,
92 int dest_width,
93 int anti_alias) {
94 if (!m_Face)
95 return nullptr;
96
97 FXFT_Matrix ft_matrix;
98 ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
99 ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
100 ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
101 ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
102 bool bUseCJKSubFont = FALSE;
Lei Zhang 2016/08/19 22:44:58 s/FALSE/false/
103 const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
104 if (pSubstFont) {
105 bUseCJKSubFont = pSubstFont->m_bSubstCJK && bFontStyle;
106 int skew = 0;
107 if (bUseCJKSubFont)
108 skew = pSubstFont->m_bItalicCJK ? -15 : 0;
109 else
110 skew = pSubstFont->m_ItalicAngle;
111 if (skew) {
112 // |skew| is nonpositive so |-skew| is used as the index. We need to make
113 // sure |skew| != INT_MIN since -INT_MIN is undefined.
114 if (skew <= 0 && skew != std::numeric_limits<int>::min() &&
115 static_cast<size_t>(-skew) < CFX_Font::kAngleSkewArraySize) {
116 skew = -CFX_Font::s_AngleSkew[-skew];
117 } else {
118 skew = -58;
119 }
120 if (pFont->IsVertical())
121 ft_matrix.yx += ft_matrix.yy * skew / 100;
122 else
123 ft_matrix.xy -= ft_matrix.xx * skew / 100;
124 }
125 if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
126 pFont->AdjustMMParams(glyph_index, dest_width,
127 pFont->GetSubstFont()->m_Weight);
128 }
129 }
130 ScopedFontTransform scoped_transform(m_Face, &ft_matrix);
131 int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT)
132 ? FXFT_LOAD_NO_BITMAP
133 : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
134 int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
135 if (error) {
136 // if an error is returned, try to reload glyphs without hinting.
137 if (load_flags & FT_LOAD_NO_HINTING || load_flags & FT_LOAD_NO_SCALE)
138 return nullptr;
139
140 load_flags |= FT_LOAD_NO_HINTING;
141 error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
142
143 if (error)
144 return nullptr;
145 }
146 int weight = 0;
147 if (bUseCJKSubFont)
148 weight = pSubstFont->m_WeightCJK;
149 else
150 weight = pSubstFont ? pSubstFont->m_Weight : 0;
151 if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) &&
152 weight > 400) {
153 uint32_t index = (weight - 400) / 10;
154 if (index >= CFX_Font::kWeightPowArraySize)
155 return nullptr;
156 int level = 0;
157 if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
158 level =
159 CFX_Font::s_WeightPow_SHIFTJIS[index] * 2 *
160 (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) /
161 36655;
162 } else {
163 level =
164 CFX_Font::s_WeightPow_11[index] *
165 (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) /
166 36655;
167 }
168 FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
169 }
170 FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->GetFTLibrary(),
171 FT_LCD_FILTER_DEFAULT);
172 error = FXFT_Render_Glyph(m_Face, anti_alias);
173 if (error)
174 return nullptr;
175 int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face));
176 int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face));
177 if (bmwidth > 2048 || bmheight > 2048)
178 return nullptr;
179 int dib_width = bmwidth;
180 CFX_GlyphBitmap* pGlyphBitmap = new CFX_GlyphBitmap;
181 pGlyphBitmap->m_Bitmap.Create(
182 dib_width, bmheight,
183 anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask);
184 pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face);
185 pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face);
186 int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch();
187 int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face));
188 uint8_t* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer();
189 uint8_t* pSrcBuf =
190 (uint8_t*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face));
191 if (anti_alias != FXFT_RENDER_MODE_MONO &&
192 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
193 FXFT_PIXEL_MODE_MONO) {
194 int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1;
195 for (int i = 0; i < bmheight; i++) {
196 for (int n = 0; n < bmwidth; n++) {
197 uint8_t data =
198 (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
199 for (int b = 0; b < bytes; b++)
200 pDestBuf[i * dest_pitch + n * bytes + b] = data;
201 }
202 }
203 } else {
204 FXSYS_memset(pDestBuf, 0, dest_pitch * bmheight);
205 if (anti_alias == FXFT_RENDER_MODE_MONO &&
206 FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) ==
207 FXFT_PIXEL_MODE_MONO) {
208 int rowbytes =
209 FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch);
210 for (int row = 0; row < bmheight; row++) {
211 FXSYS_memcpy(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch,
212 rowbytes);
213 }
214 } else {
215 ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch,
216 dest_pitch);
217 GammaAdjust(pDestBuf, bmheight, dest_pitch,
218 CFX_GEModule::Get()->GetTextGammaTable());
219 }
220 }
221 return pGlyphBitmap;
222 }
223
224 const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont,
225 uint32_t glyph_index,
226 int dest_width) {
227 if (!m_Face || glyph_index == (uint32_t)-1)
228 return nullptr;
229
230 uint32_t key = glyph_index;
231 if (pFont->GetSubstFont()) {
232 key += (((pFont->GetSubstFont()->m_Weight / 16) << 15) +
233 ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) +
234 ((dest_width / 16) << 25) + (pFont->IsVertical() << 31));
235 }
236 auto it = m_PathMap.find(key);
237 if (it != m_PathMap.end())
238 return it->second.get();
239
240 CFX_PathData* pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
241 m_PathMap[key] = std::unique_ptr<CFX_PathData>(pGlyphPath);
242 return pGlyphPath;
243 }
244
245 const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont,
246 uint32_t glyph_index,
247 FX_BOOL bFontStyle,
248 const CFX_Matrix* pMatrix,
249 int dest_width,
250 int anti_alias,
251 int& text_flags) {
252 if (glyph_index == (uint32_t)-1)
253 return nullptr;
254 _CFX_UniqueKeyGen keygen;
255 int pMatrixA = static_cast<int>(pMatrix->a * 10000);
Lei Zhang 2016/08/19 22:44:58 |nMatrixA| because it's not a pointer?
256 int pMatrixB = static_cast<int>(pMatrix->b * 10000);
257 int pMatrixC = static_cast<int>(pMatrix->c * 10000);
258 int pMatrixD = static_cast<int>(pMatrix->d * 10000);
259 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
260 if (pFont->GetSubstFont())
Lei Zhang 2016/08/19 22:44:58 braces braces braces
261 keygen.Generate(9, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
262 anti_alias, pFont->GetSubstFont()->m_Weight,
263 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
264 else
265 keygen.Generate(6, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
266 anti_alias);
267 #else
268 if (text_flags & FXTEXT_NO_NATIVETEXT) {
269 if (pFont->GetSubstFont())
270 keygen.Generate(9, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
271 anti_alias, pFont->GetSubstFont()->m_Weight,
272 pFont->GetSubstFont()->m_ItalicAngle,
273 pFont->IsVertical());
274 else
275 keygen.Generate(6, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
276 anti_alias);
277 } else {
278 if (pFont->GetSubstFont())
279 keygen.Generate(10, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
280 anti_alias, pFont->GetSubstFont()->m_Weight,
281 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(),
282 3);
283 else
284 keygen.Generate(7, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
285 anti_alias, 3);
286 }
287 #endif
288 CFX_ByteString FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
289 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ || defined _SKIA_SUPPORT_
290 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index,
291 bFontStyle, dest_width, anti_alias);
292 #else
293 if (text_flags & FXTEXT_NO_NATIVETEXT) {
294 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index,
295 bFontStyle, dest_width, anti_alias);
296 }
297 CFX_GlyphBitmap* pGlyphBitmap;
298 auto it = m_SizeMap.find(FaceGlyphsKey);
299 if (it != m_SizeMap.end()) {
300 CFX_SizeGlyphCache* pSizeCache = it->second.get();
301 auto it2 = pSizeCache->m_GlyphMap.find(glyph_index);
302 if (it2 != pSizeCache->m_GlyphMap.end())
303 return it2->second;
304
305 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix,
306 dest_width, anti_alias);
307 if (pGlyphBitmap) {
308 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
309 return pGlyphBitmap;
310 }
311 } else {
312 pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix,
313 dest_width, anti_alias);
314 if (pGlyphBitmap) {
315 CFX_SizeGlyphCache* pSizeCache = new CFX_SizeGlyphCache;
316 m_SizeMap[FaceGlyphsKey] =
317 std::unique_ptr<CFX_SizeGlyphCache>(pSizeCache);
318 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
319 return pGlyphBitmap;
320 }
321 }
322 if (pFont->GetSubstFont())
Lei Zhang 2016/08/19 22:44:58 braces
323 keygen.Generate(9, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
324 anti_alias, pFont->GetSubstFont()->m_Weight,
325 pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
326 else
327 keygen.Generate(6, pMatrixA, pMatrixB, pMatrixC, pMatrixD, dest_width,
328 anti_alias);
329 CFX_ByteString FaceGlyphsKey2(keygen.m_Key, keygen.m_KeyLen);
330 text_flags |= FXTEXT_NO_NATIVETEXT;
331 return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey2, glyph_index,
332 bFontStyle, dest_width, anti_alias);
333 #endif
334 }
335
336 #ifdef _SKIA_SUPPORT_
337 CFX_TypeFace* CFX_FaceCache::GetDeviceCache(CFX_Font* pFont) {
338 if (!m_pTypeface) {
339 m_pTypeface =
340 SkTypeface::MakeFromStream(
341 new SkMemoryStream(pFont->GetFontData(), pFont->GetSize()))
342 .release();
343 }
344 return m_pTypeface;
345 }
346 #endif
347
348 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
349 void CFX_FaceCache::InitPlatform() {}
350 #endif
351
352 CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(
353 CFX_Font* pFont,
354 const CFX_Matrix* pMatrix,
355 const CFX_ByteString& FaceGlyphsKey,
356 uint32_t glyph_index,
357 FX_BOOL bFontStyle,
358 int dest_width,
359 int anti_alias) {
360 CFX_SizeGlyphCache* pSizeCache;
361 auto it = m_SizeMap.find(FaceGlyphsKey);
362 if (it == m_SizeMap.end()) {
363 pSizeCache = new CFX_SizeGlyphCache;
364 m_SizeMap[FaceGlyphsKey] = std::unique_ptr<CFX_SizeGlyphCache>(pSizeCache);
365 } else {
366 pSizeCache = it->second.get();
367 }
368 auto it2 = pSizeCache->m_GlyphMap.find(glyph_index);
369 if (it2 != pSizeCache->m_GlyphMap.end())
370 return it2->second;
371
372 CFX_GlyphBitmap* pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle,
373 pMatrix, dest_width, anti_alias);
374 if (!pGlyphBitmap)
375 return nullptr;
376
377 pSizeCache->m_GlyphMap[glyph_index] = pGlyphBitmap;
378 return pGlyphBitmap;
379 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698