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

Side by Side Diff: core/fpdfapi/fpdf_render/fpdf_render_text.cpp

Issue 2298163004: Move CPDF_Type3Cache and CPDF_Type3Glyphs to their own files (Closed)
Patch Set: Nits Created 4 years, 3 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/fpdfapi/fpdf_render/fpdf_render.cpp ('k') | core/fpdfapi/fpdf_render/render_int.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 "core/fpdfapi/fpdf_render/render_int.h" 7 #include "core/fpdfapi/fpdf_render/render_int.h"
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" 11 #include "core/fpdfapi/fpdf_font/cpdf_cidfont.h"
12 #include "core/fpdfapi/fpdf_font/cpdf_type3char.h" 12 #include "core/fpdfapi/fpdf_font/cpdf_type3char.h"
13 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" 13 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h"
14 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" 14 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h"
15 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" 15 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
16 #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h" 16 #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
17 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" 17 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"
18 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" 18 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h"
19 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" 19 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
20 #include "core/fpdfapi/fpdf_page/pageint.h" 20 #include "core/fpdfapi/fpdf_page/pageint.h"
21 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 21 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
22 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" 22 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
23 #include "core/fpdfapi/fpdf_render/cpdf_type3cache.h"
23 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" 24 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h"
24 #include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h" 25 #include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h"
25 #include "core/fxge/include/cfx_autofontcache.h" 26 #include "core/fxge/include/cfx_autofontcache.h"
26 #include "core/fxge/include/cfx_facecache.h" 27 #include "core/fxge/include/cfx_facecache.h"
27 #include "core/fxge/include/cfx_fontcache.h" 28 #include "core/fxge/include/cfx_fontcache.h"
28 #include "core/fxge/include/cfx_fxgedevice.h" 29 #include "core/fxge/include/cfx_fxgedevice.h"
29 #include "core/fxge/include/cfx_gemodule.h" 30 #include "core/fxge/include/cfx_gemodule.h"
30 #include "core/fxge/include/cfx_graphstatedata.h" 31 #include "core/fxge/include/cfx_graphstatedata.h"
31 #include "core/fxge/include/cfx_pathdata.h" 32 #include "core/fxge/include/cfx_pathdata.h"
32 #include "core/fxge/include/cfx_renderdevice.h" 33 #include "core/fxge/include/cfx_renderdevice.h"
33 34
34 namespace {
35
36 struct CPDF_UniqueKeyGen {
37 void Generate(int count, ...);
38 FX_CHAR m_Key[128];
39 int m_KeyLen;
40 };
41
42 void CPDF_UniqueKeyGen::Generate(int count, ...) {
43 va_list argList;
44 va_start(argList, count);
45 for (int i = 0; i < count; i++) {
46 int p = va_arg(argList, int);
47 ((uint32_t*)m_Key)[i] = p;
48 }
49 va_end(argList);
50 m_KeyLen = count * sizeof(uint32_t);
51 }
52
53 } // namespace
54
55 CPDF_Type3Cache::CPDF_Type3Cache(CPDF_Type3Font* pFont) : m_pFont(pFont) {}
56
57 CPDF_Type3Cache::~CPDF_Type3Cache() {
58 for (const auto& pair : m_SizeMap) {
59 delete pair.second;
60 }
61 m_SizeMap.clear();
62 }
63
64 CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(uint32_t charcode,
65 const CFX_Matrix* pMatrix,
66 FX_FLOAT retinaScaleX,
67 FX_FLOAT retinaScaleY) {
68 CPDF_UniqueKeyGen keygen;
69 keygen.Generate(
70 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000),
71 FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000));
72 CFX_ByteString FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
73 CPDF_Type3Glyphs* pSizeCache;
74 auto it = m_SizeMap.find(FaceGlyphsKey);
75 if (it == m_SizeMap.end()) {
76 pSizeCache = new CPDF_Type3Glyphs;
77 m_SizeMap[FaceGlyphsKey] = pSizeCache;
78 } else {
79 pSizeCache = it->second;
80 }
81 auto it2 = pSizeCache->m_GlyphMap.find(charcode);
82 if (it2 != pSizeCache->m_GlyphMap.end())
83 return it2->second;
84
85 CFX_GlyphBitmap* pGlyphBitmap =
86 RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY);
87 pSizeCache->m_GlyphMap[charcode] = pGlyphBitmap;
88 return pGlyphBitmap;
89 }
90
91 CPDF_Type3Glyphs::CPDF_Type3Glyphs()
92 : m_TopBlueCount(0), m_BottomBlueCount(0) {}
93
94 CPDF_Type3Glyphs::~CPDF_Type3Glyphs() {
95 for (const auto& pair : m_GlyphMap)
96 delete pair.second;
97 }
98
99 static int _AdjustBlue(FX_FLOAT pos, int& count, int blues[]) {
100 FX_FLOAT min_distance = 1000000.0f * 1.0f;
101 int closest_pos = -1;
102 for (int i = 0; i < count; i++) {
103 FX_FLOAT distance = (FX_FLOAT)FXSYS_fabs(pos - (FX_FLOAT)blues[i]);
104 if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) {
105 min_distance = distance;
106 closest_pos = i;
107 }
108 }
109 if (closest_pos >= 0) {
110 return blues[closest_pos];
111 }
112 int new_pos = FXSYS_round(pos);
113 if (count == TYPE3_MAX_BLUES) {
114 return new_pos;
115 }
116 blues[count++] = new_pos;
117 return new_pos;
118 }
119 void CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top,
120 FX_FLOAT bottom,
121 int& top_line,
122 int& bottom_line) {
123 top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue);
124 bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue);
125 }
126
127 static FX_BOOL _IsScanLine1bpp(uint8_t* pBuf, int width) {
128 int size = width / 8;
129 for (int i = 0; i < size; i++) {
130 if (pBuf[i])
131 return TRUE;
132 }
133 return (width % 8) && (pBuf[width / 8] & (0xff << (8 - width % 8)));
134 }
135
136 static FX_BOOL _IsScanLine8bpp(uint8_t* pBuf, int width) {
137 for (int i = 0; i < width; i++) {
138 if (pBuf[i] > 0x40)
139 return TRUE;
140 }
141 return FALSE;
142 }
143
144 static int _DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst) {
145 int height = pBitmap->GetHeight(), pitch = pBitmap->GetPitch(),
146 width = pBitmap->GetWidth();
147 int bpp = pBitmap->GetBPP();
148 if (bpp > 8) {
149 width *= bpp / 8;
150 }
151 uint8_t* pBuf = pBitmap->GetBuffer();
152 int line = bFirst ? 0 : height - 1;
153 int line_step = bFirst ? 1 : -1;
154 int line_end = bFirst ? height : -1;
155 while (line != line_end) {
156 if (bpp == 1) {
157 if (_IsScanLine1bpp(pBuf + line * pitch, width)) {
158 return line;
159 }
160 } else {
161 if (_IsScanLine8bpp(pBuf + line * pitch, width)) {
162 return line;
163 }
164 }
165 line += line_step;
166 }
167 return -1;
168 }
169
170 CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize,
171 uint32_t charcode,
172 const CFX_Matrix* pMatrix,
173 FX_FLOAT retinaScaleX,
174 FX_FLOAT retinaScaleY) {
175 const CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode);
176 if (!pChar || !pChar->m_pBitmap)
177 return nullptr;
178
179 CFX_DIBitmap* pBitmap = pChar->m_pBitmap.get();
180 CFX_Matrix image_matrix, text_matrix;
181 image_matrix = pChar->m_ImageMatrix;
182 text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0);
183 image_matrix.Concat(text_matrix);
184 std::unique_ptr<CFX_DIBitmap> pResBitmap;
185 int left = 0;
186 int top = 0;
187 if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 &&
188 FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) {
189 int top_line = _DetectFirstLastScan(pBitmap, TRUE);
190 int bottom_line = _DetectFirstLastScan(pBitmap, FALSE);
191 if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) {
192 FX_FLOAT top_y = image_matrix.d + image_matrix.f;
193 FX_FLOAT bottom_y = image_matrix.f;
194 FX_BOOL bFlipped = top_y > bottom_y;
195 if (bFlipped) {
196 FX_FLOAT temp = top_y;
197 top_y = bottom_y;
198 bottom_y = temp;
199 }
200 pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line);
201 pResBitmap.reset(pBitmap->StretchTo(
202 (int)(FXSYS_round(image_matrix.a) * retinaScaleX),
203 (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) *
204 retinaScaleY)));
205 top = top_line;
206 if (image_matrix.a < 0) {
207 image_matrix.Scale(retinaScaleX, retinaScaleY);
208 left = FXSYS_round(image_matrix.e + image_matrix.a);
209 } else {
210 left = FXSYS_round(image_matrix.e);
211 }
212 }
213 }
214 if (!pResBitmap) {
215 image_matrix.Scale(retinaScaleX, retinaScaleY);
216 pResBitmap.reset(pBitmap->TransformTo(&image_matrix, left, top));
217 }
218 if (!pResBitmap)
219 return nullptr;
220
221 CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap;
222 pGlyph->m_Left = left;
223 pGlyph->m_Top = -top;
224 pGlyph->m_Bitmap.TakeOver(pResBitmap.get());
225 return pGlyph;
226 }
227
228 FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, 35 FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj,
229 const CFX_Matrix* pObj2Device, 36 const CFX_Matrix* pObj2Device,
230 CFX_PathData* pClippingPath) { 37 CFX_PathData* pClippingPath) {
231 if (textobj->m_nChars == 0) 38 if (textobj->m_nChars == 0)
232 return TRUE; 39 return TRUE;
233 40
234 const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode(); 41 const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode();
235 if (text_render_mode == TextRenderingMode::MODE_INVISIBLE) 42 if (text_render_mode == TextRenderingMode::MODE_INVISIBLE)
236 return TRUE; 43 return TRUE;
237 44
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, 671 matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX,
865 charpos.m_OriginY); 672 charpos.m_OriginY);
866 path.m_Path.Emplace()->Append(pPath, &matrix); 673 path.m_Path.Emplace()->Append(pPath, &matrix);
867 path.m_Matrix = *pTextMatrix; 674 path.m_Matrix = *pTextMatrix;
868 path.m_bStroke = bStroke; 675 path.m_bStroke = bStroke;
869 path.m_FillType = bFill ? FXFILL_WINDING : 0; 676 path.m_FillType = bFill ? FXFILL_WINDING : 0;
870 path.CalcBoundingBox(); 677 path.CalcBoundingBox();
871 ProcessPath(&path, pObj2Device); 678 ProcessPath(&path, pObj2Device);
872 } 679 }
873 } 680 }
OLDNEW
« no previous file with comments | « core/fpdfapi/fpdf_render/fpdf_render.cpp ('k') | core/fpdfapi/fpdf_render/render_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698