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

Side by Side Diff: core/fxge/win32/cfx_psrenderer.cpp

Issue 2615703002: Revert postscript code removal. (Closed)
Patch Set: Move files, remove extra class, remove non const refs Created 3 years, 11 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/win32/cfx_psrenderer.h ('k') | core/fxge/win32/cpsoutput.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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/win32/cfx_psrenderer.h"
8
9 #include <memory>
10
11 #include "core/fxcodec/fx_codec.h"
12 #include "core/fxcrt/cfx_maybe_owned.h"
13 #include "core/fxge/cfx_facecache.h"
14 #include "core/fxge/cfx_fontcache.h"
15 #include "core/fxge/cfx_pathdata.h"
16 #include "core/fxge/cfx_renderdevice.h"
17 #include "core/fxge/ge/fx_text_int.h"
18 #include "core/fxge/win32/cpsoutput.h"
19
20 struct PSGlyph {
21 CFX_Font* m_pFont;
22 uint32_t m_GlyphIndex;
23 bool m_bGlyphAdjust;
24 FX_FLOAT m_AdjustMatrix[4];
25 };
26
27 class CPSFont {
28 public:
29 PSGlyph m_Glyphs[256];
30 int m_nGlyphs;
31 };
32
33 CFX_PSRenderer::CFX_PSRenderer() {
34 m_pOutput = nullptr;
35 m_bColorSet = m_bGraphStateSet = false;
36 m_bInited = false;
37 }
38
39 CFX_PSRenderer::~CFX_PSRenderer() {
40 for (int i = 0; i < static_cast<int>(m_PSFontList.GetSize()); i++) {
41 CPSFont* pFont = m_PSFontList[i];
42 delete pFont;
43 }
44 }
45
46 #define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str - 1)
47
48 void CFX_PSRenderer::Init(CPSOutput* pOutput,
49 int pslevel,
50 int width,
51 int height,
52 bool bCmykOutput) {
53 m_PSLevel = pslevel;
54 m_pOutput = pOutput;
55 m_ClipBox.left = m_ClipBox.top = 0;
56 m_ClipBox.right = width;
57 m_ClipBox.bottom = height;
58 m_bCmykOutput = bCmykOutput;
59 }
60
61 bool CFX_PSRenderer::StartRendering() {
62 if (m_bInited) {
63 return true;
64 }
65 static const char init_str[] =
66 "\nsave\n/im/initmatrix load def\n"
67 "/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load "
68 "def/h/closepath load def\n"
69 "/f/fill load def/F/eofill load def/s/stroke load def/W/clip load "
70 "def/W*/eoclip load def\n"
71 "/rg/setrgbcolor load def/k/setcmykcolor load def\n"
72 "/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load "
73 "def/M/setmiterlimit load def/d/setdash load def\n"
74 "/q/gsave load def/Q/grestore load def/iM/imagemask load def\n"
75 "/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont "
76 "load def\n"
77 "/cm/concat load def/Cm/currentmatrix load def/mx/matrix load "
78 "def/sm/setmatrix load def\n";
79 OUTPUT_PS(init_str);
80 m_bInited = true;
81 return true;
82 }
83
84 void CFX_PSRenderer::EndRendering() {
85 if (m_bInited) {
86 OUTPUT_PS("\nrestore\n");
87 }
88 m_bInited = false;
89 }
90
91 void CFX_PSRenderer::SaveState() {
92 StartRendering();
93 OUTPUT_PS("q\n");
94 m_ClipBoxStack.Add(m_ClipBox);
95 }
96
97 void CFX_PSRenderer::RestoreState(bool bKeepSaved) {
98 StartRendering();
99 if (bKeepSaved) {
100 OUTPUT_PS("Q\nq\n");
101 } else {
102 OUTPUT_PS("Q\n");
103 }
104 m_bColorSet = false;
105 m_bGraphStateSet = false;
106 int size = m_ClipBoxStack.GetSize();
107 if (!size)
108 return;
109
110 m_ClipBox = m_ClipBoxStack.GetAt(size - 1);
111 if (!bKeepSaved)
112 m_ClipBoxStack.RemoveAt(size - 1);
113 }
114
115 void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData,
116 const CFX_Matrix* pObject2Device) {
117 int nPoints = pPathData->GetPointCount();
118 CFX_ByteTextBuf buf;
119 buf.EstimateSize(nPoints * 10);
120 for (int i = 0; i < nPoints; i++) {
121 uint8_t flag = pPathData->GetFlag(i);
122 FX_FLOAT x = pPathData->GetPointX(i);
123 FX_FLOAT y = pPathData->GetPointY(i);
124 if (pObject2Device) {
125 pObject2Device->Transform(x, y);
126 }
127 buf << x << " " << y;
128 switch (flag & FXPT_TYPE) {
129 case FXPT_MOVETO:
130 buf << " m ";
131 break;
132 case FXPT_LINETO:
133 if (flag & FXPT_CLOSEFIGURE) {
134 buf << " l h ";
135 } else {
136 buf << " l ";
137 }
138 break;
139 case FXPT_BEZIERTO: {
140 FX_FLOAT x1 = pPathData->GetPointX(i + 1);
141 FX_FLOAT x2 = pPathData->GetPointX(i + 2);
142 FX_FLOAT y1 = pPathData->GetPointY(i + 1);
143 FX_FLOAT y2 = pPathData->GetPointY(i + 2);
144 if (pObject2Device) {
145 pObject2Device->Transform(x1, y1);
146 pObject2Device->Transform(x2, y2);
147 }
148 buf << " " << x1 << " " << y1 << " " << x2 << " " << y2;
149 if (flag & FXPT_CLOSEFIGURE) {
150 buf << " c h\n";
151 } else {
152 buf << " c\n";
153 }
154 i += 2;
155 break;
156 }
157 }
158 }
159 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
160 }
161
162 void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData,
163 const CFX_Matrix* pObject2Device,
164 int fill_mode) {
165 StartRendering();
166 OutputPath(pPathData, pObject2Device);
167 CFX_FloatRect rect = pPathData->GetBoundingBox();
168 if (pObject2Device) {
169 rect.Transform(pObject2Device);
170 }
171 m_ClipBox.Intersect(rect.GetOuterRect());
172 if ((fill_mode & 3) == FXFILL_WINDING) {
173 OUTPUT_PS("W n\n");
174 } else {
175 OUTPUT_PS("W* n\n");
176 }
177 }
178
179 void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData,
180 const CFX_Matrix* pObject2Device,
181 const CFX_GraphStateData* pGraphState) {
182 StartRendering();
183 SetGraphState(pGraphState);
184 if (pObject2Device) {
185 CFX_ByteTextBuf buf;
186 buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " "
187 << pObject2Device->c << " " << pObject2Device->d << " "
188 << pObject2Device->e << " " << pObject2Device->f << "]cm ";
189 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
190 }
191 OutputPath(pPathData, nullptr);
192 CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth,
193 pGraphState->m_MiterLimit);
194 rect.Transform(pObject2Device);
195 m_ClipBox.Intersect(rect.GetOuterRect());
196 if (pObject2Device) {
197 OUTPUT_PS("strokepath W n sm\n");
198 } else {
199 OUTPUT_PS("strokepath W n\n");
200 }
201 }
202
203 bool CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData,
204 const CFX_Matrix* pObject2Device,
205 const CFX_GraphStateData* pGraphState,
206 uint32_t fill_color,
207 uint32_t stroke_color,
208 int fill_mode) {
209 StartRendering();
210 int fill_alpha = FXARGB_A(fill_color);
211 int stroke_alpha = FXARGB_A(stroke_color);
212 if (fill_alpha && fill_alpha < 255) {
213 return false;
214 }
215 if (stroke_alpha && stroke_alpha < 255) {
216 return false;
217 }
218 if (fill_alpha == 0 && stroke_alpha == 0) {
219 return false;
220 }
221 if (stroke_alpha) {
222 SetGraphState(pGraphState);
223 if (pObject2Device) {
224 CFX_ByteTextBuf buf;
225 buf << "mx Cm [" << pObject2Device->a << " " << pObject2Device->b << " "
226 << pObject2Device->c << " " << pObject2Device->d << " "
227 << pObject2Device->e << " " << pObject2Device->f << "]cm ";
228 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
229 }
230 }
231 OutputPath(pPathData, stroke_alpha ? nullptr : pObject2Device);
232 if (fill_mode && fill_alpha) {
233 SetColor(fill_color);
234 if ((fill_mode & 3) == FXFILL_WINDING) {
235 if (stroke_alpha) {
236 OUTPUT_PS("q f Q ");
237 } else {
238 OUTPUT_PS("f");
239 }
240 } else if ((fill_mode & 3) == FXFILL_ALTERNATE) {
241 if (stroke_alpha) {
242 OUTPUT_PS("q F Q ");
243 } else {
244 OUTPUT_PS("F");
245 }
246 }
247 }
248 if (stroke_alpha) {
249 SetColor(stroke_color);
250 if (pObject2Device) {
251 OUTPUT_PS("s sm");
252 } else {
253 OUTPUT_PS("s");
254 }
255 }
256 OUTPUT_PS("\n");
257 return true;
258 }
259
260 void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState) {
261 CFX_ByteTextBuf buf;
262 if (!m_bGraphStateSet ||
263 m_CurGraphState.m_LineCap != pGraphState->m_LineCap) {
264 buf << pGraphState->m_LineCap << " J\n";
265 }
266 if (!m_bGraphStateSet ||
267 m_CurGraphState.m_DashCount != pGraphState->m_DashCount ||
268 FXSYS_memcmp(m_CurGraphState.m_DashArray, pGraphState->m_DashArray,
269 sizeof(FX_FLOAT) * m_CurGraphState.m_DashCount)) {
270 buf << "[";
271 for (int i = 0; i < pGraphState->m_DashCount; i++) {
272 buf << pGraphState->m_DashArray[i] << " ";
273 }
274 buf << "]" << pGraphState->m_DashPhase << " d\n";
275 }
276 if (!m_bGraphStateSet ||
277 m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) {
278 buf << pGraphState->m_LineJoin << " j\n";
279 }
280 if (!m_bGraphStateSet ||
281 m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) {
282 buf << pGraphState->m_LineWidth << " w\n";
283 }
284 if (!m_bGraphStateSet ||
285 m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) {
286 buf << pGraphState->m_MiterLimit << " M\n";
287 }
288 m_CurGraphState.Copy(*pGraphState);
289 m_bGraphStateSet = TRUE;
290 if (buf.GetSize()) {
291 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
292 }
293 }
294
295 static void FaxCompressData(uint8_t* src_buf,
296 int width,
297 int height,
298 std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
299 uint32_t* dest_size) {
300 if (width * height > 128) {
301 CCodec_FaxModule::FaxEncode(src_buf, width, height, (width + 7) / 8,
302 dest_buf, dest_size);
303 FX_Free(src_buf);
304 } else {
305 (*dest_buf).reset(src_buf);
306 *dest_size = (width + 7) / 8 * height;
307 }
308 }
309
310 static void PSCompressData(int PSLevel,
311 uint8_t* src_buf,
312 uint32_t src_size,
313 uint8_t** output_buf,
314 uint32_t* output_size,
315 const FX_CHAR** filter) {
316 *output_buf = src_buf;
317 *output_size = src_size;
318 *filter = "";
319 if (src_size < 1024) {
320 return;
321 }
322 CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
323 uint8_t* dest_buf = NULL;
324 uint32_t dest_size = src_size;
325 if (PSLevel >= 3) {
326 if (pEncoders &&
327 pEncoders->GetFlateModule()->Encode(src_buf, src_size, &dest_buf,
328 &dest_size)) {
329 *filter = "/FlateDecode filter ";
330 }
331 } else {
332 if (pEncoders &&
333 pEncoders->GetBasicModule()->RunLengthEncode(src_buf, src_size,
334 &dest_buf, &dest_size)) {
335 *filter = "/RunLengthDecode filter ";
336 }
337 }
338 if (dest_size < src_size) {
339 *output_buf = dest_buf;
340 *output_size = dest_size;
341 } else {
342 *filter = NULL;
343 FX_Free(dest_buf);
344 }
345 }
346
347 bool CFX_PSRenderer::SetDIBits(const CFX_DIBSource* pSource,
348 uint32_t color,
349 int left,
350 int top) {
351 StartRendering();
352 CFX_Matrix matrix((FX_FLOAT)(pSource->GetWidth()), 0.0f, 0.0f,
353 -(FX_FLOAT)(pSource->GetHeight()), (FX_FLOAT)(left),
354 (FX_FLOAT)(top + pSource->GetHeight()));
355 return DrawDIBits(pSource, color, &matrix, 0);
356 }
357
358 bool CFX_PSRenderer::StretchDIBits(const CFX_DIBSource* pSource,
359 uint32_t color,
360 int dest_left,
361 int dest_top,
362 int dest_width,
363 int dest_height,
364 uint32_t flags) {
365 StartRendering();
366 CFX_Matrix matrix((FX_FLOAT)(dest_width), 0.0f, 0.0f,
367 (FX_FLOAT)(-dest_height), (FX_FLOAT)(dest_left),
368 (FX_FLOAT)(dest_top + dest_height));
369 return DrawDIBits(pSource, color, &matrix, flags);
370 }
371
372 bool CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource,
373 uint32_t color,
374 const CFX_Matrix* pMatrix,
375 uint32_t flags) {
376 StartRendering();
377 if ((pMatrix->a == 0 && pMatrix->b == 0) ||
378 (pMatrix->c == 0 && pMatrix->d == 0)) {
379 return true;
380 }
381 if (pSource->HasAlpha()) {
382 return false;
383 }
384 int alpha = FXARGB_A(color);
385 if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1))
386 return false;
387
388 OUTPUT_PS("q\n");
389 CFX_ByteTextBuf buf;
390 buf << "[" << pMatrix->a << " " << pMatrix->b << " " << pMatrix->c << " "
391 << pMatrix->d << " " << pMatrix->e << " " << pMatrix->f << "]cm ";
392 int width = pSource->GetWidth();
393 int height = pSource->GetHeight();
394 buf << width << " " << height;
395 if (pSource->GetBPP() == 1 && !pSource->GetPalette()) {
396 int pitch = (width + 7) / 8;
397 uint32_t src_size = height * pitch;
398 uint8_t* src_buf = FX_Alloc(uint8_t, src_size);
399 for (int row = 0; row < height; row++) {
400 const uint8_t* src_scan = pSource->GetScanline(row);
401 FXSYS_memcpy(src_buf + row * pitch, src_scan, pitch);
402 }
403 std::unique_ptr<uint8_t, FxFreeDeleter> output_buf;
404 uint32_t output_size;
405 FaxCompressData(src_buf, width, height, &output_buf, &output_size);
406 if (pSource->IsAlphaMask()) {
407 SetColor(color);
408 m_bColorSet = false;
409 buf << " true[";
410 } else {
411 buf << " 1[";
412 }
413 buf << width << " 0 0 -" << height << " 0 " << height
414 << "]currentfile/ASCII85Decode filter ";
415 if (output_buf.get() != src_buf)
416 buf << "<</K -1/EndOfBlock false/Columns " << width << "/Rows " << height
417 << ">>/CCITTFaxDecode filter ";
418 if (pSource->IsAlphaMask()) {
419 buf << "iM\n";
420 } else {
421 buf << "false 1 colorimage\n";
422 }
423 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
424 WritePSBinary(output_buf.get(), output_size);
425 output_buf.release();
426 } else {
427 CFX_MaybeOwned<CFX_DIBSource> pConverted((CFX_DIBSource*)pSource);
428 switch (pSource->GetFormat()) {
429 case FXDIB_1bppRgb:
430 case FXDIB_Rgb32:
431 pConverted = pSource->CloneConvert(FXDIB_Rgb);
432 break;
433 case FXDIB_8bppRgb:
434 if (pSource->GetPalette()) {
435 pConverted = pSource->CloneConvert(FXDIB_Rgb);
436 }
437 break;
438 case FXDIB_1bppCmyk:
439 pConverted = pSource->CloneConvert(FXDIB_Cmyk);
440 break;
441 case FXDIB_8bppCmyk:
442 if (pSource->GetPalette()) {
443 pConverted = pSource->CloneConvert(FXDIB_Cmyk);
444 }
445 break;
446 default:
447 break;
448 }
449 if (!pConverted) {
450 OUTPUT_PS("\nQ\n");
451 return false;
452 }
453 int Bpp = pConverted->GetBPP() / 8;
454 uint8_t* output_buf = nullptr;
455 FX_STRSIZE output_size = 0;
456 const FX_CHAR* filter = nullptr;
457 if (flags & FXRENDER_IMAGE_LOSSY) {
458 CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
459 if (pEncoders &&
460 pEncoders->GetJpegModule()->JpegEncode(pConverted.Get(), &output_buf,
461 &output_size)) {
462 filter = "/DCTDecode filter ";
463 }
464 }
465 if (!filter) {
466 int src_pitch = width * Bpp;
467 output_size = height * src_pitch;
468 output_buf = FX_Alloc(uint8_t, output_size);
469 for (int row = 0; row < height; row++) {
470 const uint8_t* src_scan = pConverted->GetScanline(row);
471 uint8_t* dest_scan = output_buf + row * src_pitch;
472 if (Bpp == 3) {
473 for (int col = 0; col < width; col++) {
474 *dest_scan++ = src_scan[2];
475 *dest_scan++ = src_scan[1];
476 *dest_scan++ = *src_scan;
477 src_scan += 3;
478 }
479 } else {
480 FXSYS_memcpy(dest_scan, src_scan, src_pitch);
481 }
482 }
483 uint8_t* compressed_buf;
484 uint32_t compressed_size;
485 PSCompressData(m_PSLevel, output_buf, output_size, &compressed_buf,
486 &compressed_size, &filter);
487 if (output_buf != compressed_buf) {
488 FX_Free(output_buf);
489 }
490 output_buf = compressed_buf;
491 output_size = compressed_size;
492 }
493 CFX_DIBSource* converted = pConverted.Get();
494 if (converted != pSource) {
495 delete converted;
496 pConverted.Reset();
497 }
498 buf << " 8[";
499 buf << width << " 0 0 -" << height << " 0 " << height << "]";
500 buf << "currentfile/ASCII85Decode filter ";
501 if (filter) {
502 buf << filter;
503 }
504 buf << "false " << Bpp;
505 buf << " colorimage\n";
506 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
507 WritePSBinary(output_buf, output_size);
508 FX_Free(output_buf);
509 }
510 OUTPUT_PS("\nQ\n");
511 return true;
512 }
513
514 void CFX_PSRenderer::SetColor(uint32_t color) {
515 bool bCMYK = false;
516 if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) {
517 CFX_ByteTextBuf buf;
518 if (bCMYK) {
519 buf << FXSYS_GetCValue(color) / 255.0 << " "
520 << FXSYS_GetMValue(color) / 255.0 << " "
521 << FXSYS_GetYValue(color) / 255.0 << " "
522 << FXSYS_GetKValue(color) / 255.0 << " k\n";
523 } else {
524 buf << FXARGB_R(color) / 255.0 << " " << FXARGB_G(color) / 255.0 << " "
525 << FXARGB_B(color) / 255.0 << " rg\n";
526 }
527 if (bCMYK == m_bCmykOutput) {
528 m_bColorSet = true;
529 m_LastColor = color;
530 }
531 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
532 }
533 }
534
535 void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache,
536 CFX_Font* pFont,
537 const FXTEXT_CHARPOS& charpos,
538 int* ps_fontnum,
539 int* ps_glyphindex) {
540 for (int i = 0; i < m_PSFontList.GetSize(); i++) {
541 CPSFont* pPSFont = m_PSFontList[i];
542 for (int j = 0; j < pPSFont->m_nGlyphs; j++)
543 if (pPSFont->m_Glyphs[j].m_pFont == pFont &&
544 pPSFont->m_Glyphs[j].m_GlyphIndex == charpos.m_GlyphIndex) {
545 if ((!pPSFont->m_Glyphs[j].m_bGlyphAdjust && !charpos.m_bGlyphAdjust) ||
546 (pPSFont->m_Glyphs[j].m_bGlyphAdjust && charpos.m_bGlyphAdjust &&
547 (FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[0] -
548 charpos.m_AdjustMatrix[0]) < 0.01 &&
549 FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[1] -
550 charpos.m_AdjustMatrix[1]) < 0.01 &&
551 FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[2] -
552 charpos.m_AdjustMatrix[2]) < 0.01 &&
553 FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[3] -
554 charpos.m_AdjustMatrix[3]) < 0.01))) {
555 *ps_fontnum = i;
556 *ps_glyphindex = j;
557 return;
558 }
559 }
560 }
561 if (m_PSFontList.GetSize() == 0 ||
562 m_PSFontList[m_PSFontList.GetSize() - 1]->m_nGlyphs == 256) {
563 CPSFont* pPSFont = new CPSFont;
564 pPSFont->m_nGlyphs = 0;
565 m_PSFontList.Add(pPSFont);
566 CFX_ByteTextBuf buf;
567 buf << "8 dict begin/FontType 3 def/FontMatrix[1 0 0 1 0 0]def\n"
568 "/FontBBox[0 0 0 0]def/Encoding 256 array def 0 1 255{Encoding "
569 "exch/.notdef put}for\n"
570 "/CharProcs 1 dict def CharProcs begin/.notdef {} def end\n"
571 "/BuildGlyph{1 0 -10 -10 10 10 setcachedevice exch/CharProcs get "
572 "exch 2 copy known not{pop/.notdef}if get exec}bind def\n"
573 "/BuildChar{1 index/Encoding get exch get 1 index/BuildGlyph get "
574 "exec}bind def\n"
575 "currentdict end\n";
576 buf << "/X" << m_PSFontList.GetSize() - 1 << " exch definefont pop\n";
577 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
578 buf.Clear();
579 }
580 *ps_fontnum = m_PSFontList.GetSize() - 1;
581 CPSFont* pPSFont = m_PSFontList[*ps_fontnum];
582 int glyphindex = pPSFont->m_nGlyphs;
583 *ps_glyphindex = glyphindex;
584 pPSFont->m_Glyphs[glyphindex].m_GlyphIndex = charpos.m_GlyphIndex;
585 pPSFont->m_Glyphs[glyphindex].m_pFont = pFont;
586 pPSFont->m_Glyphs[glyphindex].m_bGlyphAdjust = charpos.m_bGlyphAdjust;
587 if (charpos.m_bGlyphAdjust) {
588 pPSFont->m_Glyphs[glyphindex].m_AdjustMatrix[0] = charpos.m_AdjustMatrix[0];
589 pPSFont->m_Glyphs[glyphindex].m_AdjustMatrix[1] = charpos.m_AdjustMatrix[1];
590 pPSFont->m_Glyphs[glyphindex].m_AdjustMatrix[2] = charpos.m_AdjustMatrix[2];
591 pPSFont->m_Glyphs[glyphindex].m_AdjustMatrix[3] = charpos.m_AdjustMatrix[3];
592 }
593 pPSFont->m_nGlyphs++;
594 CFX_Matrix matrix;
595 if (charpos.m_bGlyphAdjust)
596 matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
597 charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
598 matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0);
599 const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath(
600 pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
601 if (!pPathData) {
602 return;
603 }
604 CFX_PathData TransformedPath(*pPathData);
605 if (charpos.m_bGlyphAdjust) {
606 TransformedPath.Transform(&matrix);
607 }
608 CFX_ByteTextBuf buf;
609 buf << "/X" << *ps_fontnum << " Ff/CharProcs get begin/" << glyphindex
610 << "{n ";
611 for (int p = 0; p < TransformedPath.GetPointCount(); p++) {
612 FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p);
613 switch (TransformedPath.GetFlag(p) & FXPT_TYPE) {
614 case FXPT_MOVETO: {
615 buf << x << " " << y << " m\n";
616 break;
617 }
618 case FXPT_LINETO: {
619 buf << x << " " << y << " l\n";
620 break;
621 }
622 case FXPT_BEZIERTO: {
623 buf << x << " " << y << " " << TransformedPath.GetPointX(p + 1) << " "
624 << TransformedPath.GetPointY(p + 1) << " "
625 << TransformedPath.GetPointX(p + 2) << " "
626 << TransformedPath.GetPointY(p + 2) << " c\n";
627 p += 2;
628 break;
629 }
630 }
631 }
632 buf << "f}bind def end\n";
633 buf << "/X" << *ps_fontnum << " Ff/Encoding get " << glyphindex << "/"
634 << glyphindex << " put\n";
635 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
636 }
637
638 bool CFX_PSRenderer::DrawText(int nChars,
639 const FXTEXT_CHARPOS* pCharPos,
640 CFX_Font* pFont,
641 const CFX_Matrix* pObject2Device,
642 FX_FLOAT font_size,
643 uint32_t color) {
644 StartRendering();
645 int alpha = FXARGB_A(color);
646 if (alpha < 255)
647 return false;
648
649 if ((pObject2Device->a == 0 && pObject2Device->b == 0) ||
650 (pObject2Device->c == 0 && pObject2Device->d == 0)) {
651 return true;
652 }
653 SetColor(color);
654 CFX_ByteTextBuf buf;
655 buf << "q[" << pObject2Device->a << " " << pObject2Device->b << " "
656 << pObject2Device->c << " " << pObject2Device->d << " "
657 << pObject2Device->e << " " << pObject2Device->f << "]cm\n";
658
659 CFX_FontCache* pCache = CFX_GEModule::Get()->GetFontCache();
660 CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
661 int last_fontnum = -1;
662 for (int i = 0; i < nChars; i++) {
663 int ps_fontnum, ps_glyphindex;
664 FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], &ps_fontnum,
665 &ps_glyphindex);
666 if (last_fontnum != ps_fontnum) {
667 buf << "/X" << ps_fontnum << " Ff " << font_size << " Fs Sf ";
668 last_fontnum = ps_fontnum;
669 }
670 buf << pCharPos[i].m_OriginX << " " << pCharPos[i].m_OriginY << " m";
671 CFX_ByteString hex;
672 hex.Format("<%02X>", ps_glyphindex);
673 buf << hex.AsStringC() << "Tj\n";
674 }
675 buf << "Q\n";
676 m_pOutput->OutputPS((const FX_CHAR*)buf.GetBuffer(), buf.GetSize());
677 pCache->ReleaseCachedFace(pFont);
678 return true;
679 }
680
681 void CFX_PSRenderer::WritePSBinary(const uint8_t* data, int len) {
682 uint8_t* dest_buf;
683 uint32_t dest_size;
684 CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
685 if (pEncoders &&
686 pEncoders->GetBasicModule()->A85Encode(data, len, &dest_buf,
687 &dest_size)) {
688 m_pOutput->OutputPS((const FX_CHAR*)dest_buf, dest_size);
689 FX_Free(dest_buf);
690 } else {
691 m_pOutput->OutputPS((const FX_CHAR*)data, len);
692 }
693 }
OLDNEW
« no previous file with comments | « core/fxge/win32/cfx_psrenderer.h ('k') | core/fxge/win32/cpsoutput.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698