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

Side by Side Diff: core/src/fxge/apple/fx_quartz_device.cpp

Issue 453133004: clang-format all code (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 6 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 "../../../include/fxcrt/fx_ext.h" 7 #include "../../../include/fxcrt/fx_ext.h"
8 #include "../../../include/fxge/fx_ge.h" 8 #include "../../../include/fxge/fx_ge.h"
9 #include "../agg/include/fxfx_agg_clip_liang_barsky.h" 9 #include "../agg/include/fxfx_agg_clip_liang_barsky.h"
10 #include "../ge/text_int.h" 10 #include "../ge/text_int.h"
11 #include "../dib/dib_int.h" 11 #include "../dib/dib_int.h"
12 #include "../agg/include/fx_agg_driver.h" 12 #include "../agg/include/fx_agg_driver.h"
13 #include "../../../include/fxge/fx_freetype.h" 13 #include "../../../include/fxge/fx_freetype.h"
14 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 14 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
15 #include "apple_int.h" 15 #include "apple_int.h"
16 #include "../../../include/fxge/fx_ge_apple.h" 16 #include "../../../include/fxge/fx_ge_apple.h"
17 #ifndef CGFLOAT_IS_DOUBLE 17 #ifndef CGFLOAT_IS_DOUBLE
18 #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers 18 #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
19 #endif 19 #endif
20 void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) 20 void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) {
21 { 21 if (!pBitmap) {
22 if (!pBitmap) { 22 return NULL;
23 return NULL; 23 }
24 } 24 CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
25 CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little; 25 switch (pBitmap->GetFormat()) {
26 switch (pBitmap->GetFormat()) { 26 case FXDIB_Rgb32:
27 case FXDIB_Rgb32: 27 bmpInfo |= kCGImageAlphaNoneSkipFirst;
28 bmpInfo |= kCGImageAlphaNoneSkipFirst; 28 break;
29 break; 29 case FXDIB_Argb:
30 case FXDIB_Argb: 30 default:
31 default: 31 return NULL;
32 return NULL; 32 }
33 } 33 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
34 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 34 CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
35 CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), 35 pBitmap->GetWidth(),
36 pBitmap->GetWidth(), 36 pBitmap->GetHeight(),
37 pBitmap->GetHeight(), 37 8,
38 8, 38 pBitmap->GetPitch(),
39 pBitmap->GetPitch(), 39 colorSpace,
40 colorSpace, 40 bmpInfo);
41 bmpInfo); 41 CGColorSpaceRelease(colorSpace);
42 CGColorSpaceRelease(colorSpace); 42 return context;
43 return context; 43 }
44 } 44 void CQuartz2D::destroyGraphics(void* graphics) {
45 void CQuartz2D::destroyGraphics(void* graphics) 45 if (graphics) {
46 { 46 CGContextRelease((CGContextRef)graphics);
47 if (graphics) { 47 }
48 CGContextRelease((CGContextRef) graphics); 48 }
49 } 49 void* CQuartz2D::CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize) {
50 } 50 CGDataProviderRef pDataProvider =
51 void* CQuartz2D::CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize) 51 CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL);
52 { 52 if (NULL == pDataProvider) {
53 CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(NULL, pFontDa ta, (size_t)dwFontSize, NULL); 53 return NULL;
54 if (NULL == pDataProvider) { 54 }
55 return NULL; 55 CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
56 } 56 CGDataProviderRelease(pDataProvider);
57 CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider); 57 return pCGFont;
58 CGDataProviderRelease(pDataProvider); 58 }
59 return pCGFont; 59 void CQuartz2D::DestroyFont(void* pFont) {
60 } 60 CGFontRelease((CGFontRef)pFont);
61 void CQuartz2D::DestroyFont(void* pFont) 61 }
62 { 62 void CQuartz2D::setGraphicsTextMatrix(void* graphics,
63 CGFontRelease((CGFontRef)pFont); 63 CFX_AffineMatrix* matrix) {
64 } 64 if (!graphics || !matrix) {
65 void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix) 65 return;
66 { 66 }
67 if (!graphics || !matrix) { 67 CGContextRef context = (CGContextRef)graphics;
68 return; 68 CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
69 } 69 CGContextSetTextMatrix(
70 CGContextRef context = (CGContextRef) graphics; 70 context,
71 CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f; 71 CGAffineTransformMake(
72 CGContextSetTextMatrix(context, CGAffineTransformMake(matrix->a, 72 matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, ty));
73 matrix->b, 73 }
74 matrix->c, 74 FX_BOOL CQuartz2D::drawGraphicsString(void* graphics,
75 matrix->d, 75 void* font,
76 matrix->e, 76 FX_FLOAT fontSize,
77 ty)); 77 FX_WORD* glyphIndices,
78 } 78 CGPoint* glyphPositions,
79 FX_BOOL CQuartz2D::drawGraphicsString(void* graphics, 79 FX_INT32 charsCount,
80 void* font, 80 FX_ARGB argb,
81 FX_FLOAT fontSize, 81 CFX_AffineMatrix* matrix) {
82 FX_WORD* glyphIndices, 82 if (!graphics) {
83 CGPoint* glyphPositions, 83 return FALSE;
84 FX_INT32 charsCount, 84 }
85 FX_ARGB argb, 85 CGContextRef context = (CGContextRef)graphics;
86 CFX_AffineMatrix* matrix ) 86 CGContextSetFont(context, (CGFontRef)font);
87 { 87 CGContextSetFontSize(context, fontSize);
88 if (!graphics) { 88 if (matrix) {
89 return FALSE; 89 CGAffineTransform m = CGContextGetTextMatrix(context);
90 } 90 m = CGAffineTransformConcat(
91 CGContextRef context = (CGContextRef) graphics; 91 m,
92 CGContextSetFont(context, (CGFontRef)font); 92 CGAffineTransformMake(
93 CGContextSetFontSize(context, fontSize); 93 matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f));
94 if (matrix) { 94 CGContextSetTextMatrix(context, m);
95 CGAffineTransform m = CGContextGetTextMatrix(context); 95 }
96 m = CGAffineTransformConcat(m, 96 FX_INT32 a, r, g, b;
97 CGAffineTransformMake(matrix->a, 97 ArgbDecode(argb, a, r, g, b);
98 matrix->b, 98 CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
99 matrix->c, 99 CGContextSaveGState(context);
100 matrix->d,
101 matrix->e,
102 matrix->f));
103 CGContextSetTextMatrix(context, m);
104 }
105 FX_INT32 a, r, g, b;
106 ArgbDecode(argb, a, r, g, b);
107 CGContextSetRGBFillColor(context,
108 r / 255.f,
109 g / 255.f,
110 b / 255.f,
111 a / 255.f);
112 CGContextSaveGState(context);
113 #if CGFLOAT_IS_DOUBLE 100 #if CGFLOAT_IS_DOUBLE
114 CGPoint* glyphPositionsCG = new CGPoint[charsCount]; 101 CGPoint* glyphPositionsCG = new CGPoint[charsCount];
115 if (!glyphPositionsCG) { 102 if (!glyphPositionsCG) {
116 return FALSE; 103 return FALSE;
117 } 104 }
118 for (int index = 0; index < charsCount; ++index) { 105 for (int index = 0; index < charsCount; ++index) {
119 glyphPositionsCG[index].x = glyphPositions[index].x; 106 glyphPositionsCG[index].x = glyphPositions[index].x;
120 glyphPositionsCG[index].y = glyphPositions[index].y; 107 glyphPositionsCG[index].y = glyphPositions[index].y;
121 } 108 }
122 #else 109 #else
123 CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions; 110 CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
124 #endif 111 #endif
125 CGContextShowGlyphsAtPositions(context, 112 CGContextShowGlyphsAtPositions(
126 (CGGlyph *) glyphIndices, 113 context, (CGGlyph*)glyphIndices, glyphPositionsCG, charsCount);
127 glyphPositionsCG,
128 charsCount);
129 #if CGFLOAT_IS_DOUBLE 114 #if CGFLOAT_IS_DOUBLE
130 delete[] glyphPositionsCG; 115 delete[] glyphPositionsCG;
131 #endif 116 #endif
132 CGContextRestoreGState(context); 117 CGContextRestoreGState(context);
133 return TRUE; 118 return TRUE;
134 } 119 }
135 void CQuartz2D::saveGraphicsState(void * graphics) 120 void CQuartz2D::saveGraphicsState(void* graphics) {
136 { 121 if (graphics) {
137 if (graphics) { 122 CGContextSaveGState((CGContextRef)graphics);
138 CGContextSaveGState((CGContextRef) graphics); 123 }
139 } 124 }
140 } 125 void CQuartz2D::restoreGraphicsState(void* graphics) {
141 void CQuartz2D::restoreGraphicsState(void * graphics) 126 if (graphics) {
142 { 127 CGContextRestoreGState((CGContextRef)graphics);
143 if (graphics) { 128 }
144 CGContextRestoreGState((CGContextRef) graphics); 129 }
145 } 130 static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) {
146 } 131 if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) {
147 static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) 132 return NULL;
148 { 133 }
149 if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) { 134 CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little;
150 return NULL; 135 if (pBitmap->HasAlpha()) {
151 } 136 bitmapInfo |= kCGImageAlphaPremultipliedFirst;
152 CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little; 137 } else {
153 if (pBitmap->HasAlpha()) { 138 bitmapInfo |= kCGImageAlphaNoneSkipFirst;
154 bitmapInfo |= kCGImageAlphaPremultipliedFirst; 139 }
140 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
141 CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
142 pBitmap->GetWidth(),
143 pBitmap->GetHeight(),
144 8,
145 pBitmap->GetPitch(),
146 colorSpace,
147 bitmapInfo);
148 CGColorSpaceRelease(colorSpace);
149 return context;
150 }
151 CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context,
152 FX_INT32 deviceClass) {
153 m_saveCount = 0;
154 _context = context;
155 _deviceClass = deviceClass;
156 CGContextRetain(_context);
157 CGRect r = CGContextGetClipBoundingBox(context);
158 _width = FXSYS_round(r.size.width);
159 _height = FXSYS_round(r.size.height);
160 _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH |
161 FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK;
162 if (_deviceClass != FXDC_DISPLAY) {
163 } else {
164 CGImageRef image = CGBitmapContextCreateImage(_context);
165 if (image) {
166 _renderCaps |= FXRC_GET_BITS;
167 _width = CGImageGetWidth(image);
168 _height = CGImageGetHeight(image);
169 CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image);
170 if (kCGImageAlphaPremultipliedFirst == alphaInfo ||
171 kCGImageAlphaPremultipliedLast == alphaInfo ||
172 kCGImageAlphaOnly == alphaInfo) {
173 _renderCaps |= FXRC_ALPHA_OUTPUT;
174 }
175 }
176 CGImageRelease(image);
177 }
178 CGAffineTransform ctm = CGContextGetCTM(_context);
179 CGContextSaveGState(_context);
180 m_saveCount++;
181 if (ctm.d >= 0) {
182 CGFloat offset_x, offset_y;
183 offset_x = ctm.tx;
184 offset_y = ctm.ty;
185 CGContextTranslateCTM(_context, -offset_x, -offset_y);
186 CGContextConcatCTM(
187 _context,
188 CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y));
189 }
190 _foxitDevice2User = CGAffineTransformIdentity;
191 _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User);
192 }
193 CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() {
194 CGContextRestoreGState(_context);
195 m_saveCount--;
196 for (int i = 0; i < m_saveCount; ++i) {
197 CGContextRestoreGState(_context);
198 }
199 if (_context) {
200 CGContextRelease(_context);
201 }
202 }
203 int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) {
204 switch (capsID) {
205 case FXDC_DEVICE_CLASS: {
206 return _deviceClass;
207 }
208 case FXDC_PIXEL_WIDTH: {
209 return _width;
210 }
211 case FXDC_PIXEL_HEIGHT: {
212 return _height;
213 }
214 case FXDC_BITS_PIXEL: {
215 return 32;
216 }
217 case FXDC_RENDER_CAPS: {
218 return _renderCaps;
219 }
220 default: { return 0; }
221 }
222 }
223 CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const {
224 CGAffineTransform ctm = CGContextGetCTM(_context);
225 return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
226 }
227 void CFX_QuartzDeviceDriver::SaveState() {
228 CGContextSaveGState(_context);
229 m_saveCount++;
230 }
231 void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved) {
232 CGContextRestoreGState(_context);
233 if (isKeepSaved) {
234 CGContextSaveGState(_context);
235 } else {
236 m_saveCount--;
237 }
238 }
239 FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData,
240 const CFX_AffineMatrix* matrix,
241 int fillMode) {
242 SaveState();
243 CGAffineTransform m = CGAffineTransformIdentity;
244 if (matrix) {
245 m = CGAffineTransformMake(matrix->GetA(),
246 matrix->GetB(),
247 matrix->GetC(),
248 matrix->GetD(),
249 matrix->GetE(),
250 matrix->GetF());
251 }
252 m = CGAffineTransformConcat(m, _foxitDevice2User);
253 CGContextConcatCTM(_context, m);
254 setPathToContext(pathData);
255 RestoreState(FALSE);
256 if ((fillMode & 3) == FXFILL_WINDING) {
257 CGContextClip(_context);
258 } else {
259 CGContextEOClip(_context);
260 }
261 return TRUE;
262 }
263 FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(
264 const CFX_GraphStateData* graphState,
265 CGAffineTransform ctm) {
266 FX_FLOAT lineWidth = graphState->m_LineWidth;
267 if (graphState->m_LineWidth <= 0.f) {
268 CGSize size;
269 size.width = 1;
270 size.height = 1;
271 CGSize temp = CGSizeApplyAffineTransform(size, ctm);
272 CGFloat x = 1 / temp.width;
273 CGFloat y = 1 / temp.height;
274 lineWidth = x > y ? x : y;
275 }
276 return lineWidth;
277 }
278 FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(
279 const CFX_PathData* pathData,
280 const CFX_AffineMatrix* matrix,
281 const CFX_GraphStateData* graphState) {
282 SaveState();
283 CGAffineTransform m = CGAffineTransformIdentity;
284 if (matrix) {
285 m = CGAffineTransformMake(matrix->GetA(),
286 matrix->GetB(),
287 matrix->GetC(),
288 matrix->GetD(),
289 matrix->GetE(),
290 matrix->GetF());
291 }
292 m = CGAffineTransformConcat(m, _foxitDevice2User);
293 CGContextConcatCTM(_context, m);
294 FX_FLOAT lineWidth = getLineWidth(graphState, m);
295 setStrokeInfo(graphState, 0xFF000000, lineWidth);
296 setPathToContext(pathData);
297 CGContextReplacePathWithStrokedPath(_context);
298 RestoreState(FALSE);
299 CGContextClip(_context);
300 return TRUE;
301 }
302 static CGBlendMode GetCGBlendMode(int blend_type) {
303 CGBlendMode mode = kCGBlendModeNormal;
304 switch (blend_type) {
305 case FXDIB_BLEND_NORMAL:
306 mode = kCGBlendModeNormal;
307 break;
308 case FXDIB_BLEND_MULTIPLY:
309 mode = kCGBlendModeMultiply;
310 break;
311 case FXDIB_BLEND_SCREEN:
312 mode = kCGBlendModeScreen;
313 break;
314 case FXDIB_BLEND_OVERLAY:
315 mode = kCGBlendModeOverlay;
316 break;
317 case FXDIB_BLEND_DARKEN:
318 mode = kCGBlendModeDarken;
319 break;
320 case FXDIB_BLEND_LIGHTEN:
321 mode = kCGBlendModeLighten;
322 break;
323 case FXDIB_BLEND_COLORDODGE:
324 mode = kCGBlendModeColorDodge;
325 break;
326 case FXDIB_BLEND_COLORBURN:
327 mode = kCGBlendModeColorBurn;
328 break;
329 case FXDIB_BLEND_HARDLIGHT:
330 mode = kCGBlendModeHardLight;
331 break;
332 case FXDIB_BLEND_SOFTLIGHT:
333 mode = kCGBlendModeSoftLight;
334 break;
335 case FXDIB_BLEND_DIFFERENCE:
336 mode = kCGBlendModeDifference;
337 break;
338 case FXDIB_BLEND_EXCLUSION:
339 mode = kCGBlendModeExclusion;
340 break;
341 case FXDIB_BLEND_HUE:
342 mode = kCGBlendModeHue;
343 break;
344 case FXDIB_BLEND_SATURATION:
345 mode = kCGBlendModeSaturation;
346 break;
347 case FXDIB_BLEND_COLOR:
348 mode = kCGBlendModeColor;
349 break;
350 case FXDIB_BLEND_LUMINOSITY:
351 mode = kCGBlendModeLuminosity;
352 break;
353 default:
354 mode = kCGBlendModeNormal;
355 break;
356 }
357 return mode;
358 }
359 FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData,
360 const CFX_AffineMatrix* matrix,
361 const CFX_GraphStateData* graphState,
362 FX_DWORD fillArgb,
363 FX_DWORD strokeArgb,
364 int fillMode,
365 int alpha_flag,
366 void* pIccTransform,
367 int blend_type) {
368 SaveState();
369 CGBlendMode mode = GetCGBlendMode(blend_type);
370 if (mode != kCGBlendModeNormal) {
371 CGContextSetBlendMode(_context, mode);
372 }
373 CGAffineTransform m = CGAffineTransformIdentity;
374 if (matrix) {
375 m = CGAffineTransformMake(matrix->GetA(),
376 matrix->GetB(),
377 matrix->GetC(),
378 matrix->GetD(),
379 matrix->GetE(),
380 matrix->GetF());
381 }
382 m = CGAffineTransformConcat(m, _foxitDevice2User);
383 CGContextConcatCTM(_context, m);
384 int pathMode = 0;
385 if (graphState && strokeArgb) {
386 CGContextSetMiterLimit(_context, graphState->m_MiterLimit);
387 FX_FLOAT lineWidth = getLineWidth(graphState, m);
388 setStrokeInfo(graphState, strokeArgb, lineWidth);
389 pathMode |= 4;
390 }
391 if (fillMode && fillArgb) {
392 setFillInfo(fillArgb);
393 if ((fillMode & 3) == FXFILL_WINDING) {
394 pathMode |= 1;
395 } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
396 pathMode |= 2;
397 }
398 }
399 setPathToContext(pathData);
400 if (fillMode & FXFILL_FULLCOVER) {
401 CGContextSetShouldAntialias(_context, false);
402 }
403 if (pathMode == 4) {
404 CGContextStrokePath(_context);
405 } else if (pathMode == 1) {
406 CGContextFillPath(_context);
407 } else if (pathMode == 2) {
408 CGContextEOFillPath(_context);
409 } else if (pathMode == 5) {
410 CGContextDrawPath(_context, kCGPathFillStroke);
411 } else if (pathMode == 6) {
412 CGContextDrawPath(_context, kCGPathEOFillStroke);
413 }
414 RestoreState(FALSE);
415 return TRUE;
416 }
417 FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect,
418 FX_ARGB fillArgb,
419 int alphaFlag,
420 void* iccTransform,
421 int blend_type) {
422 CGBlendMode mode = GetCGBlendMode(blend_type);
423 if (mode != kCGBlendModeNormal) {
424 CGContextSetBlendMode(_context, mode);
425 }
426 CGRect rect_fx =
427 CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
428 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
429 FX_INT32 a, r, g, b;
430 ArgbDecode(fillArgb, a, r, g, b);
431 CGContextSetRGBFillColor(
432 _context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
433 CGContextFillRect(_context, rect_usr);
434 if (mode != kCGBlendModeNormal) {
435 CGContextSetBlendMode(_context, kCGBlendModeNormal);
436 }
437 return TRUE;
438 }
439 FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
440 FX_FLOAT y1,
441 FX_FLOAT x2,
442 FX_FLOAT y2,
443 FX_DWORD argb,
444 int alphaFlag,
445 void* iccTransform,
446 int blend_type) {
447 CGBlendMode mode = GetCGBlendMode(blend_type);
448 if (mode != kCGBlendModeNormal) {
449 CGContextSetBlendMode(_context, mode);
450 }
451 CGPoint pt =
452 CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User);
453 x1 = pt.x;
454 y1 = pt.y;
455 pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
456 x2 = pt.x;
457 y2 = pt.y;
458 FX_INT32 a, r, g, b;
459 ArgbDecode(argb, a, r, g, b);
460 CGContextSetRGBStrokeColor(
461 _context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
462 CGContextMoveToPoint(_context, x1, y1);
463 CGContextAddLineToPoint(_context, x2, y2);
464 CGContextStrokePath(_context);
465 if (mode != kCGBlendModeNormal) {
466 CGContextSetBlendMode(_context, kCGBlendModeNormal);
467 }
468 return TRUE;
469 }
470 FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) {
471 CGRect r = CGContextGetClipBoundingBox(_context);
472 r = CGRectApplyAffineTransform(r, _user2FoxitDevice);
473 rect->left = FXSYS_floor(r.origin.x);
474 rect->top = FXSYS_floor(r.origin.y);
475 rect->right = FXSYS_ceil(r.origin.x + r.size.width);
476 rect->bottom = FXSYS_ceil(r.origin.y + r.size.height);
477 return TRUE;
478 }
479 FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap,
480 FX_INT32 left,
481 FX_INT32 top,
482 void* pIccTransform,
483 FX_BOOL bDEdge) {
484 if (FXDC_PRINTER == _deviceClass) {
485 return FALSE;
486 }
487 if (bitmap->GetBPP() < 32) {
488 return FALSE;
489 }
490 if (!(_renderCaps | FXRC_GET_BITS)) {
491 return FALSE;
492 }
493 CGPoint pt = CGPointMake(left, top);
494 pt = CGPointApplyAffineTransform(pt, _foxitDevice2User);
495 CGAffineTransform ctm = CGContextGetCTM(_context);
496 pt.x *= FXSYS_fabs(ctm.a);
497 pt.y *= FXSYS_fabs(ctm.d);
498 CGImageRef image = CGBitmapContextCreateImage(_context);
499 if (NULL == image) {
500 return FALSE;
501 }
502 CGFloat width = (CGFloat)bitmap->GetWidth();
503 CGFloat height = (CGFloat)bitmap->GetHeight();
504 if (width + pt.x > _width) {
505 width -= (width + pt.x - _width);
506 }
507 if (height + pt.y > _height) {
508 height -= (height + pt.y - _height);
509 }
510 CGImageRef subImage = CGImageCreateWithImageInRect(
511 image, CGRectMake(pt.x, pt.y, width, height));
512 CGContextRef context = createContextWithBitmap(bitmap);
513 CGRect rect = CGContextGetClipBoundingBox(context);
514 CGContextClearRect(context, rect);
515 CGContextDrawImage(context, rect, subImage);
516 CGContextRelease(context);
517 CGImageRelease(subImage);
518 CGImageRelease(image);
519 if (bitmap->HasAlpha()) {
520 for (int row = 0; row < bitmap->GetHeight(); row++) {
521 FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row);
522 for (int col = 0; col < bitmap->GetWidth(); col++) {
523 if (pScanline[3] > 0) {
524 pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f);
525 pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f);
526 pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f);
527 }
528 pScanline += 4;
529 }
530 }
531 }
532 return TRUE;
533 }
534 FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
535 FX_ARGB argb,
536 const FX_RECT* srcRect,
537 int dest_left,
538 int dest_top,
539 int blendType,
540 int alphaFlag,
541 void* iccTransform) {
542 SaveState();
543 CGFloat src_left, src_top, src_width, src_height;
544 if (srcRect) {
545 src_left = srcRect->left;
546 src_top = srcRect->top;
547 src_width = srcRect->Width();
548 src_height = srcRect->Height();
549 } else {
550 src_left = src_top = 0;
551 src_width = pBitmap->GetWidth();
552 src_height = pBitmap->GetHeight();
553 }
554 CGAffineTransform ctm = CGContextGetCTM(_context);
555 CGFloat scale_x = FXSYS_fabs(ctm.a);
556 CGFloat scale_y = FXSYS_fabs(ctm.d);
557 src_left /= scale_x;
558 src_top /= scale_y;
559 src_width /= scale_x;
560 src_height /= scale_y;
561 CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
562 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
563 CGContextBeginPath(_context);
564 CGContextAddRect(_context, rect_usr);
565 CGContextClip(_context);
566 rect_usr.size =
567 CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
568 rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
569 CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
570 CFX_DIBitmap* pBitmap1 = NULL;
571 if (pBitmap->IsAlphaMask()) {
572 if (pBitmap->GetBuffer()) {
573 pBitmap1 = (CFX_DIBitmap*)pBitmap;
155 } else { 574 } else {
156 bitmapInfo |= kCGImageAlphaNoneSkipFirst; 575 pBitmap1 = pBitmap->Clone();
157 } 576 }
158 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 577 if (NULL == pBitmap1) {
159 CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(), 578 RestoreState(FALSE);
160 pBitmap->GetWidth(), 579 return FALSE;
161 pBitmap->GetHeight(), 580 }
162 8, 581 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
163 pBitmap->GetPitch(), 582 NULL,
164 colorSpace, 583 pBitmap1->GetBuffer(),
165 bitmapInfo); 584 pBitmap1->GetPitch() * pBitmap1->GetHeight(),
166 CGColorSpaceRelease(colorSpace); 585 NULL);
167 return context; 586 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
168 } 587 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
169 CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 de viceClass) 588 CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
170 { 589 pBitmap1->GetHeight(),
171 m_saveCount = 0; 590 pBitmap1->GetBPP(),
172 _context = context; 591 pBitmap1->GetBPP(),
173 _deviceClass = deviceClass; 592 pBitmap1->GetPitch(),
174 CGContextRetain(_context); 593 pColorSpace,
175 CGRect r = CGContextGetClipBoundingBox(context); 594 bitmapInfo,
176 _width = FXSYS_round(r.size.width); 595 pBitmapProvider,
177 _height = FXSYS_round(r.size.height); 596 NULL,
178 _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | 597 true,
179 FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | 598 kCGRenderingIntentDefault);
180 FXRC_BIT_MASK | FXRC_ALPHA_MASK; 599 CGContextClipToMask(_context, rect_usr, pImage);
181 if (_deviceClass != FXDC_DISPLAY) { 600 CGContextSetRGBFillColor(_context,
182 } else { 601 FXARGB_R(argb) / 255.f,
183 CGImageRef image = CGBitmapContextCreateImage(_context); 602 FXARGB_G(argb) / 255.f,
184 if (image) { 603 FXARGB_B(argb) / 255.f,
185 _renderCaps |= FXRC_GET_BITS; 604 FXARGB_A(argb) / 255.f);
186 _width = CGImageGetWidth(image); 605 CGContextFillRect(_context, rect_usr);
187 _height = CGImageGetHeight(image); 606 CGImageRelease(pImage);
188 CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image); 607 CGColorSpaceRelease(pColorSpace);
189 if (kCGImageAlphaPremultipliedFirst == alphaInfo || 608 CGDataProviderRelease(pBitmapProvider);
190 kCGImageAlphaPremultipliedLast == alphaInfo || 609 if (pBitmap1 != pBitmap) {
191 kCGImageAlphaOnly == alphaInfo) { 610 delete pBitmap1;
192 _renderCaps |= FXRC_ALPHA_OUTPUT;
193 }
194 }
195 CGImageRelease(image);
196 }
197 CGAffineTransform ctm = CGContextGetCTM(_context);
198 CGContextSaveGState(_context);
199 m_saveCount++;
200 if (ctm.d >= 0) {
201 CGFloat offset_x, offset_y;
202 offset_x = ctm.tx;
203 offset_y = ctm.ty;
204 CGContextTranslateCTM(_context, -offset_x, -offset_y);
205 CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x , _height + offset_y));
206 }
207 _foxitDevice2User = CGAffineTransformIdentity;
208 _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User);
209 }
210 CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver()
211 {
212 CGContextRestoreGState(_context);
213 m_saveCount--;
214 for (int i = 0; i < m_saveCount; ++i) {
215 CGContextRestoreGState(_context);
216 }
217 if (_context) {
218 CGContextRelease(_context);
219 }
220 }
221 int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID)
222 {
223 switch (capsID) {
224 case FXDC_DEVICE_CLASS: {
225 return _deviceClass;
226 }
227 case FXDC_PIXEL_WIDTH: {
228 return _width;
229 }
230 case FXDC_PIXEL_HEIGHT: {
231 return _height;
232 }
233 case FXDC_BITS_PIXEL: {
234 return 32;
235 }
236 case FXDC_RENDER_CAPS: {
237 return _renderCaps;
238 }
239 default: {
240 return 0;
241 }
242 }
243 }
244 CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const
245 {
246 CGAffineTransform ctm = CGContextGetCTM(_context);
247 return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
248 }
249 void CFX_QuartzDeviceDriver::SaveState()
250 {
251 CGContextSaveGState(_context);
252 m_saveCount++;
253 }
254 void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved )
255 {
256 CGContextRestoreGState(_context);
257 if (isKeepSaved) {
258 CGContextSaveGState(_context);
259 } else {
260 m_saveCount--;
261 }
262 }
263 FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData ,
264 const CFX_AffineMatrix* matrix,
265 int fillMode )
266 {
267 SaveState();
268 CGAffineTransform m = CGAffineTransformIdentity;
269 if (matrix) {
270 m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC() , matrix->GetD(), matrix->GetE(), matrix->GetF());
271 }
272 m = CGAffineTransformConcat(m, _foxitDevice2User);
273 CGContextConcatCTM(_context, m);
274 setPathToContext(pathData);
275 RestoreState(FALSE);
276 if ((fillMode & 3) == FXFILL_WINDING) {
277 CGContextClip(_context);
278 } else {
279 CGContextEOClip(_context);
280 }
281 return TRUE;
282 }
283 FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(const CFX_GraphStateData * graphSt ate, CGAffineTransform ctm)
284 {
285 FX_FLOAT lineWidth = graphState->m_LineWidth;
286 if (graphState->m_LineWidth <= 0.f) {
287 CGSize size;
288 size.width = 1;
289 size.height = 1;
290 CGSize temp = CGSizeApplyAffineTransform(size, ctm);
291 CGFloat x = 1 / temp.width;
292 CGFloat y = 1 / temp.height;
293 lineWidth = x > y ? x : y;
294 }
295 return lineWidth;
296 }
297 FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* path Data,
298 const CFX_AffineMatrix* matrix,
299 const CFX_GraphStateData* graphState )
300 {
301 SaveState();
302 CGAffineTransform m = CGAffineTransformIdentity;
303 if (matrix) {
304 m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC() , matrix->GetD(), matrix->GetE(), matrix->GetF());
305 }
306 m = CGAffineTransformConcat(m, _foxitDevice2User);
307 CGContextConcatCTM(_context, m);
308 FX_FLOAT lineWidth = getLineWidth(graphState, m);
309 setStrokeInfo(graphState, 0xFF000000, lineWidth);
310 setPathToContext(pathData);
311 CGContextReplacePathWithStrokedPath(_context);
312 RestoreState(FALSE);
313 CGContextClip(_context);
314 return TRUE;
315 }
316 static CGBlendMode GetCGBlendMode(int blend_type)
317 {
318 CGBlendMode mode = kCGBlendModeNormal;
319 switch (blend_type) {
320 case FXDIB_BLEND_NORMAL:
321 mode = kCGBlendModeNormal;
322 break;
323 case FXDIB_BLEND_MULTIPLY:
324 mode = kCGBlendModeMultiply;
325 break;
326 case FXDIB_BLEND_SCREEN:
327 mode = kCGBlendModeScreen;
328 break;
329 case FXDIB_BLEND_OVERLAY:
330 mode = kCGBlendModeOverlay;
331 break;
332 case FXDIB_BLEND_DARKEN:
333 mode = kCGBlendModeDarken;
334 break;
335 case FXDIB_BLEND_LIGHTEN:
336 mode = kCGBlendModeLighten;
337 break;
338 case FXDIB_BLEND_COLORDODGE:
339 mode = kCGBlendModeColorDodge;
340 break;
341 case FXDIB_BLEND_COLORBURN:
342 mode = kCGBlendModeColorBurn;
343 break;
344 case FXDIB_BLEND_HARDLIGHT:
345 mode = kCGBlendModeHardLight;
346 break;
347 case FXDIB_BLEND_SOFTLIGHT:
348 mode = kCGBlendModeSoftLight;
349 break;
350 case FXDIB_BLEND_DIFFERENCE:
351 mode = kCGBlendModeDifference;
352 break;
353 case FXDIB_BLEND_EXCLUSION:
354 mode = kCGBlendModeExclusion;
355 break;
356 case FXDIB_BLEND_HUE:
357 mode = kCGBlendModeHue;
358 break;
359 case FXDIB_BLEND_SATURATION:
360 mode = kCGBlendModeSaturation;
361 break;
362 case FXDIB_BLEND_COLOR:
363 mode = kCGBlendModeColor;
364 break;
365 case FXDIB_BLEND_LUMINOSITY:
366 mode = kCGBlendModeLuminosity;
367 break;
368 default:
369 mode = kCGBlendModeNormal;
370 break;
371 }
372 return mode;
373 }
374 FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData,
375 const CFX_AffineMatrix* matrix,
376 const CFX_GraphStateData* graphState,
377 FX_DWORD fillArgb,
378 FX_DWORD strokeArgb,
379 int fillMode,
380 int alpha_flag,
381 void* pIccTransform,
382 int blend_type
383 )
384 {
385 SaveState();
386 CGBlendMode mode = GetCGBlendMode(blend_type);
387 if (mode != kCGBlendModeNormal) {
388 CGContextSetBlendMode(_context, mode);
389 }
390 CGAffineTransform m = CGAffineTransformIdentity;
391 if (matrix) {
392 m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC() , matrix->GetD(), matrix->GetE(), matrix->GetF());
393 }
394 m = CGAffineTransformConcat(m, _foxitDevice2User);
395 CGContextConcatCTM(_context, m);
396 int pathMode = 0;
397 if (graphState && strokeArgb) {
398 CGContextSetMiterLimit(_context, graphState->m_MiterLimit);
399 FX_FLOAT lineWidth = getLineWidth(graphState, m);
400 setStrokeInfo(graphState, strokeArgb, lineWidth);
401 pathMode |= 4;
402 }
403 if (fillMode && fillArgb) {
404 setFillInfo(fillArgb);
405 if ((fillMode & 3) == FXFILL_WINDING) {
406 pathMode |= 1;
407 } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
408 pathMode |= 2;
409 }
410 }
411 setPathToContext(pathData);
412 if (fillMode & FXFILL_FULLCOVER) {
413 CGContextSetShouldAntialias(_context, false);
414 }
415 if (pathMode == 4) {
416 CGContextStrokePath(_context);
417 } else if (pathMode == 1) {
418 CGContextFillPath(_context);
419 } else if (pathMode == 2) {
420 CGContextEOFillPath(_context);
421 } else if (pathMode == 5) {
422 CGContextDrawPath(_context, kCGPathFillStroke);
423 } else if (pathMode == 6) {
424 CGContextDrawPath(_context, kCGPathEOFillStroke);
425 } 611 }
426 RestoreState(FALSE); 612 RestoreState(FALSE);
427 return TRUE; 613 return TRUE;
428 } 614 }
429 FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect, 615 if (pBitmap->GetBPP() < 32) {
430 FX_ARGB fillArgb, 616 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
431 int alphaFlag» , 617 } else {
432 void* iccTransform , 618 if (pBitmap->GetBuffer()) {
433 int» » » » » » blend_type ) 619 pBitmap1 = (CFX_DIBitmap*)pBitmap;
434 {
435 CGBlendMode mode = GetCGBlendMode(blend_type);
436 if (mode != kCGBlendModeNormal) {
437 CGContextSetBlendMode(_context, mode);
438 }
439 CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Heig ht());
440 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
441 FX_INT32 a, r, g, b;
442 ArgbDecode(fillArgb, a, r, g, b);
443 CGContextSetRGBFillColor(_context,
444 r / 255.f,
445 g / 255.f,
446 b / 255.f,
447 a / 255.f);
448 CGContextFillRect(_context, rect_usr);
449 if (mode != kCGBlendModeNormal) {
450 CGContextSetBlendMode(_context, kCGBlendModeNormal);
451 }
452 return TRUE;
453 }
454 FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
455 FX_FLOAT y1,
456 FX_FLOAT x2,
457 FX_FLOAT y2,
458 FX_DWORD argb,
459 int alphaFlag ,
460 void* iccTransform ,
461 int» » » » » blend_type )
462 {
463 CGBlendMode mode = GetCGBlendMode(blend_type);
464 if (mode != kCGBlendModeNormal) {
465 CGContextSetBlendMode(_context, mode);
466 }
467 CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2U ser);
468 x1 = pt.x;
469 y1 = pt.y;
470 pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
471 x2 = pt.x;
472 y2 = pt.y;
473 FX_INT32 a, r, g, b;
474 ArgbDecode(argb, a, r, g, b);
475 CGContextSetRGBStrokeColor(_context,
476 r / 255.f,
477 g / 255.f,
478 b / 255.f,
479 a / 255.f);
480 CGContextMoveToPoint(_context, x1, y1);
481 CGContextAddLineToPoint(_context, x2, y2);
482 CGContextStrokePath(_context);
483 if (mode != kCGBlendModeNormal) {
484 CGContextSetBlendMode(_context, kCGBlendModeNormal);
485 }
486 return TRUE;
487 }
488 FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect)
489 {
490 CGRect r = CGContextGetClipBoundingBox(_context);
491 r = CGRectApplyAffineTransform(r, _user2FoxitDevice);
492 rect->left» » = FXSYS_floor(r.origin.x);
493 rect->top» » = FXSYS_floor(r.origin.y);
494 rect->right»» = FXSYS_ceil(r.origin.x + r.size.width);
495 rect->bottom» = FXSYS_ceil(r.origin.y + r.size.height);
496 return TRUE;
497 }
498 FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap,
499 FX_INT32 left,
500 FX_INT32 top,
501 void* pIccTransform,
502 FX_BOOL bDEdge)
503 {
504 if (FXDC_PRINTER == _deviceClass) {
505 return FALSE;
506 }
507 if (bitmap->GetBPP() < 32) {
508 return FALSE;
509 }
510 if (!(_renderCaps | FXRC_GET_BITS)) {
511 return FALSE;
512 }
513 CGPoint pt = CGPointMake(left, top);
514 pt = CGPointApplyAffineTransform(pt, _foxitDevice2User);
515 CGAffineTransform ctm = CGContextGetCTM(_context);
516 pt.x *= FXSYS_fabs(ctm.a);
517 pt.y *= FXSYS_fabs(ctm.d);
518 CGImageRef image = CGBitmapContextCreateImage(_context);
519 if (NULL == image) {
520 return FALSE;
521 }
522 CGFloat width» = (CGFloat) bitmap->GetWidth();
523 CGFloat height» = (CGFloat) bitmap->GetHeight();
524 if (width + pt.x > _width) {
525 width -= (width + pt.x - _width);
526 }
527 if (height + pt.y > _height) {
528 height -= (height + pt.y - _height);
529 }
530 CGImageRef subImage = CGImageCreateWithImageInRect(image,
531 CGRectMake(pt.x,
532 pt.y,
533 width,
534 height));
535 CGContextRef context = createContextWithBitmap(bitmap);
536 CGRect rect = CGContextGetClipBoundingBox(context);
537 CGContextClearRect(context, rect);
538 CGContextDrawImage(context, rect, subImage);
539 CGContextRelease(context);
540 CGImageRelease(subImage);
541 CGImageRelease(image);
542 if (bitmap->HasAlpha()) {
543 for (int row = 0; row < bitmap->GetHeight(); row ++) {
544 FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row);
545 for (int col = 0; col < bitmap->GetWidth(); col ++) {
546 if (pScanline[3] > 0) {
547 pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f);
548 pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f);
549 pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f);
550 }
551 pScanline += 4;
552 }
553 }
554 }
555 return TRUE;
556 }
557 FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
558 FX_ARGB argb,
559 const FX_RECT* srcRect,
560 int dest_left,
561 int dest_top,
562 int blendType,
563 int alphaFlag ,
564 void* iccTransform )
565 {
566 SaveState();
567 CGFloat src_left, src_top, src_width, src_height;
568 if (srcRect) {
569 src_left = srcRect->left;
570 src_top = srcRect->top;
571 src_width = srcRect->Width();
572 src_height = srcRect->Height();
573 } else { 620 } else {
574 src_left = src_top = 0; 621 pBitmap1 = pBitmap->Clone();
575 src_width = pBitmap->GetWidth(); 622 }
576 src_height = pBitmap->GetHeight(); 623 }
577 } 624 if (NULL == pBitmap1) {
578 CGAffineTransform ctm = CGContextGetCTM(_context); 625 RestoreState(FALSE);
579 CGFloat scale_x = FXSYS_fabs(ctm.a); 626 return FALSE;
580 CGFloat scale_y = FXSYS_fabs(ctm.d); 627 }
581 src_left /= scale_x; 628 if (pBitmap1->HasAlpha()) {
582 src_top /= scale_y; 629 if (pBitmap1 == pBitmap) {
583 src_width /= scale_x; 630 pBitmap1 = pBitmap->Clone();
584 src_height /= scale_y; 631 if (!pBitmap1) {
585 CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
586 CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
587 CGContextBeginPath(_context);
588 CGContextAddRect(_context, rect_usr);
589 CGContextClip(_context);
590 rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight () / scale_y);
591 rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
592 CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
593 CFX_DIBitmap* pBitmap1 = NULL;
594 if (pBitmap->IsAlphaMask()) {
595 if (pBitmap->GetBuffer()) {
596 pBitmap1 = (CFX_DIBitmap*)pBitmap;
597 } else {
598 pBitmap1 = pBitmap->Clone();
599 }
600 if (NULL == pBitmap1) {
601 RestoreState(FALSE);
602 return FALSE;
603 }
604 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
605 pBitmap1->GetBuffer(),
606 pBitmap1->GetPitch() * pBitmap1->Get Height(),
607 NULL);
608 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
609 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
610 CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
611 pBitmap1->GetHeight(),
612 pBitmap1->GetBPP(),
613 pBitmap1->GetBPP(),
614 pBitmap1->GetPitch(),
615 pColorSpace,
616 bitmapInfo,
617 pBitmapProvider, NULL, true,
618 kCGRenderingIntentDefault);
619 CGContextClipToMask(_context, rect_usr, pImage);
620 CGContextSetRGBFillColor(_context,
621 FXARGB_R(argb) / 255.f,
622 FXARGB_G(argb) / 255.f,
623 FXARGB_B(argb) / 255.f,
624 FXARGB_A(argb) / 255.f);
625 CGContextFillRect(_context, rect_usr);
626 CGImageRelease(pImage);
627 CGColorSpaceRelease(pColorSpace);
628 CGDataProviderRelease(pBitmapProvider);
629 if (pBitmap1 != pBitmap) {
630 delete pBitmap1;
631 }
632 RestoreState(FALSE);
633 return TRUE;
634 }
635 if (pBitmap->GetBPP() < 32) {
636 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
637 } else {
638 if (pBitmap->GetBuffer()) {
639 pBitmap1 = (CFX_DIBitmap*)pBitmap;
640 } else {
641 pBitmap1 = pBitmap->Clone();
642 }
643 }
644 if (NULL == pBitmap1) {
645 RestoreState(FALSE); 632 RestoreState(FALSE);
646 return FALSE; 633 return FALSE;
647 } 634 }
648 if (pBitmap1->HasAlpha()) { 635 }
649 if (pBitmap1 == pBitmap) { 636 for (int row = 0; row < pBitmap1->GetHeight(); row++) {
650 pBitmap1 = pBitmap->Clone(); 637 FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
651 if (!pBitmap1) { 638 for (int col = 0; col < pBitmap1->GetWidth(); col++) {
652 RestoreState(FALSE); 639 pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
653 return FALSE; 640 pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
654 } 641 pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
655 } 642 pScanline += 4;
656 for (int row = 0; row < pBitmap1->GetHeight(); row ++) { 643 }
657 FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); 644 }
658 for (int col = 0; col < pBitmap1->GetWidth(); col ++) { 645 }
659 pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + . 5f); 646 CGContextRef ctx = createContextWithBitmap(pBitmap1);
660 pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + . 5f); 647 CGImageRef image = CGBitmapContextCreateImage(ctx);
661 pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + . 5f); 648 int blend_mode = blendType;
662 pScanline += 4; 649 if (FXDIB_BLEND_HARDLIGHT == blendType) {
663 } 650 blend_mode = kCGBlendModeSoftLight;
664 } 651 } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
665 } 652 blend_mode = kCGBlendModeHardLight;
666 CGContextRef ctx = createContextWithBitmap(pBitmap1); 653 } else if (blendType >= FXDIB_BLEND_NONSEPARABLE &&
667 CGImageRef image = CGBitmapContextCreateImage(ctx); 654 blendType <= FXDIB_BLEND_LUMINOSITY) {
668 int blend_mode = blendType; 655 blend_mode = blendType - 9;
669 if (FXDIB_BLEND_HARDLIGHT == blendType) { 656 } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
670 blend_mode = kCGBlendModeSoftLight; 657 blend_mode = kCGBlendModeNormal;
671 } else if (FXDIB_BLEND_SOFTLIGHT == blendType) { 658 }
672 blend_mode = kCGBlendModeHardLight; 659 CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
673 } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND _LUMINOSITY) { 660 CGContextDrawImage(_context, rect_usr, image);
674 blend_mode = blendType - 9; 661 CGImageRelease(image);
675 } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) { 662 CGContextRelease(ctx);
676 blend_mode = kCGBlendModeNormal; 663 if (pBitmap1 != pBitmap) {
677 } 664 delete pBitmap1;
678 CGContextSetBlendMode(_context, (CGBlendMode)blend_mode); 665 }
679 CGContextDrawImage(_context, rect_usr, image); 666 RestoreState(FALSE);
680 CGImageRelease(image); 667 return TRUE;
681 CGContextRelease(ctx); 668 }
669 FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap,
670 FX_ARGB argb,
671 int dest_left,
672 int dest_top,
673 int dest_width,
674 int dest_height,
675 const FX_RECT* clipRect,
676 FX_DWORD flags,
677 int alphaFlag,
678 void* iccTransform,
679 int blend_type) {
680 SaveState();
681 if (clipRect) {
682 CGContextBeginPath(_context);
683 CGRect rect_clip = CGRectMake(
684 clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
685 rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
686 CGContextAddRect(_context, rect_clip);
687 CGContextClip(_context);
688 }
689 CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
690 rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
691 if (FXDIB_BICUBIC_INTERPOL == flags) {
692 CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
693 } else if (FXDIB_DOWNSAMPLE == flags) {
694 CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
695 } else {
696 CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
697 }
698 CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
699 CFX_DIBitmap* pBitmap1 = NULL;
700 if (pBitmap->IsAlphaMask()) {
701 if (pBitmap->GetBuffer()) {
702 pBitmap1 = (CFX_DIBitmap*)pBitmap;
703 } else {
704 pBitmap1 = pBitmap->Clone();
705 }
706 if (NULL == pBitmap1) {
707 RestoreState(FALSE);
708 return FALSE;
709 }
710 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
711 NULL,
712 pBitmap1->GetBuffer(),
713 pBitmap1->GetPitch() * pBitmap1->GetHeight(),
714 NULL);
715 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
716 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
717 CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
718 pBitmap1->GetHeight(),
719 pBitmap1->GetBPP(),
720 pBitmap1->GetBPP(),
721 pBitmap1->GetPitch(),
722 pColorSpace,
723 bitmapInfo,
724 pBitmapProvider,
725 NULL,
726 true,
727 kCGRenderingIntentDefault);
728 CGContextClipToMask(_context, rect, pImage);
729 CGContextSetRGBFillColor(_context,
730 FXARGB_R(argb) / 255.f,
731 FXARGB_G(argb) / 255.f,
732 FXARGB_B(argb) / 255.f,
733 FXARGB_A(argb) / 255.f);
734 CGContextFillRect(_context, rect);
735 CGImageRelease(pImage);
736 CGColorSpaceRelease(pColorSpace);
737 CGDataProviderRelease(pBitmapProvider);
682 if (pBitmap1 != pBitmap) { 738 if (pBitmap1 != pBitmap) {
683 delete pBitmap1; 739 delete pBitmap1;
684 } 740 }
685 RestoreState(FALSE); 741 RestoreState(FALSE);
686 return TRUE; 742 return TRUE;
687 } 743 }
688 FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, 744 if (pBitmap->GetBPP() < 32) {
689 FX_ARGB argb, 745 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
690 int dest_left, 746 } else {
691 int dest_top, 747 if (pBitmap->GetBuffer()) {
692 int dest_width, 748 pBitmap1 = (CFX_DIBitmap*)pBitmap;
693 int dest_height,
694 const FX_RECT* clipRect,
695 FX_DWORD flags,
696 int alphaFlag» ,
697 void* iccTransform ,
698 int» » » » » » » blend_type)
699 {
700 SaveState();
701 if (clipRect) {
702 CGContextBeginPath(_context);
703 CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->W idth(), clipRect->Height());
704 rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
705 CGContextAddRect(_context, rect_clip);
706 CGContextClip(_context);
707 }
708 CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
709 rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
710 if (FXDIB_BICUBIC_INTERPOL == flags) {
711 CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
712 } else if (FXDIB_DOWNSAMPLE == flags) {
713 CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
714 } else { 749 } else {
715 CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); 750 pBitmap1 = pBitmap->Clone();
716 } 751 }
717 CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); 752 }
718 CFX_DIBitmap* pBitmap1 = NULL; 753 if (NULL == pBitmap1) {
719 if (pBitmap->IsAlphaMask()) { 754 RestoreState(FALSE);
720 if (pBitmap->GetBuffer()) { 755 return FALSE;
721 pBitmap1 = (CFX_DIBitmap*)pBitmap; 756 }
722 } else { 757 if (pBitmap1->HasAlpha()) {
723 pBitmap1 = pBitmap->Clone(); 758 if (pBitmap1 == pBitmap) {
724 } 759 pBitmap1 = pBitmap->Clone();
725 if (NULL == pBitmap1) { 760 if (!pBitmap1) {
726 RestoreState(FALSE);
727 return FALSE;
728 }
729 CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
730 pBitmap1->GetBuffer(),
731 pBitmap1->GetPitch() * pBitmap1->Get Height(),
732 NULL);
733 CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
734 CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
735 CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
736 pBitmap1->GetHeight(),
737 pBitmap1->GetBPP(),
738 pBitmap1->GetBPP(),
739 pBitmap1->GetPitch(),
740 pColorSpace,
741 bitmapInfo,
742 pBitmapProvider, NULL, true,
743 kCGRenderingIntentDefault);
744 CGContextClipToMask(_context, rect, pImage);
745 CGContextSetRGBFillColor(_context,
746 FXARGB_R(argb) / 255.f,
747 FXARGB_G(argb) / 255.f,
748 FXARGB_B(argb) / 255.f,
749 FXARGB_A(argb) / 255.f);
750 CGContextFillRect(_context, rect);
751 CGImageRelease(pImage);
752 CGColorSpaceRelease(pColorSpace);
753 CGDataProviderRelease(pBitmapProvider);
754 if (pBitmap1 != pBitmap) {
755 delete pBitmap1;
756 }
757 RestoreState(FALSE);
758 return TRUE;
759 }
760 if (pBitmap->GetBPP() < 32) {
761 pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
762 } else {
763 if (pBitmap->GetBuffer()) {
764 pBitmap1 = (CFX_DIBitmap*)pBitmap;
765 } else {
766 pBitmap1 = pBitmap->Clone();
767 }
768 }
769 if (NULL == pBitmap1) {
770 RestoreState(FALSE); 761 RestoreState(FALSE);
771 return FALSE; 762 return FALSE;
772 } 763 }
773 if (pBitmap1->HasAlpha()) { 764 }
774 if (pBitmap1 == pBitmap) { 765 for (int row = 0; row < pBitmap1->GetHeight(); row++) {
775 pBitmap1 = pBitmap->Clone(); 766 FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
776 if (!pBitmap1) { 767 for (int col = 0; col < pBitmap1->GetWidth(); col++) {
777 RestoreState(FALSE); 768 pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
778 return FALSE; 769 pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
779 } 770 pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
771 pScanline += 4;
772 }
773 }
774 }
775 CGContextRef ctx = createContextWithBitmap(pBitmap1);
776 CGImageRef image = CGBitmapContextCreateImage(ctx);
777 CGContextDrawImage(_context, rect, image);
778 CGImageRelease(image);
779 CGContextRelease(ctx);
780 if (pBitmap1 != pBitmap) {
781 delete pBitmap1;
782 }
783 RestoreState(FALSE);
784 return TRUE;
785 }
786 FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(
787 int nChars,
788 const FXTEXT_CHARPOS* pCharPos,
789 CFX_Font* pFont,
790 CFX_FontCache* pCache,
791 const CFX_AffineMatrix* pGlyphMatrix,
792 const CFX_AffineMatrix* pObject2Device,
793 FX_FLOAT font_size,
794 FX_DWORD argb,
795 int alpha_flag,
796 void* pIccTransform) {
797 if (nChars == 0) {
798 return TRUE;
799 }
800 CQuartz2D& quartz2d =
801 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
802 if (!pFont->m_pPlatformFont) {
803 if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
804 return FALSE;
805 }
806 pFont->m_pPlatformFont =
807 quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
808 if (NULL == pFont->m_pPlatformFont) {
809 return FALSE;
810 }
811 }
812 CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
813 CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
814 for (int i = 0; i < nChars; i++) {
815 glyph_indices[i] = pCharPos[i].m_ExtGID;
816 glyph_positions[i].x = pCharPos[i].m_OriginX;
817 glyph_positions[i].y = pCharPos[i].m_OriginY;
818 }
819 CFX_AffineMatrix text_matrix;
820 if (pObject2Device) {
821 text_matrix.Concat(*pObject2Device);
822 }
823 CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a,
824 text_matrix.b,
825 text_matrix.c,
826 text_matrix.d,
827 text_matrix.e,
828 text_matrix.f);
829 matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User);
830 CGContextSetTextMatrix(_context, matrix_cg);
831 CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont);
832 CGContextSetFontSize(_context, FXSYS_fabs(font_size));
833 FX_INT32 a, r, g, b;
834 ArgbDecode(argb, a, r, g, b);
835 CGContextSetRGBFillColor(
836 _context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
837 SaveState();
838 if (pGlyphMatrix) {
839 CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y);
840 origin = CGPointApplyAffineTransform(origin, matrix_cg);
841 CGContextTranslateCTM(_context, origin.x, origin.y);
842 CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a,
843 pGlyphMatrix->b,
844 pGlyphMatrix->c,
845 pGlyphMatrix->d,
846 pGlyphMatrix->e,
847 pGlyphMatrix->f);
848 if (_foxitDevice2User.d < 0) {
849 glyph_matrix = CGAffineTransformInvert(glyph_matrix);
850 }
851 CGContextConcatCTM(_context, glyph_matrix);
852 CGContextTranslateCTM(_context, -origin.x, -origin.y);
853 }
854 CGContextShowGlyphsAtPositions(
855 _context, (CGGlyph*)glyph_indices, glyph_positions, nChars);
856 RestoreState(FALSE);
857 return TRUE;
858 }
859 FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(
860 int nChars,
861 const FXTEXT_CHARPOS* pCharPos,
862 CFX_Font* pFont,
863 CFX_FontCache* pCache,
864 const CFX_AffineMatrix* pObject2Device,
865 FX_FLOAT font_size,
866 FX_DWORD color,
867 int alpha_flag,
868 void* pIccTransform) {
869 if (NULL == pFont || NULL == _context) {
870 return FALSE;
871 }
872 FX_BOOL bBold = pFont->IsBold();
873 if (!bBold && pFont->GetSubstFont() &&
874 pFont->GetSubstFont()->m_Weight >= 500 &&
875 pFont->GetSubstFont()->m_Weight <= 600) {
876 return FALSE;
877 }
878 SaveState();
879 CGContextSetTextDrawingMode(_context, kCGTextFillClip);
880 FX_BOOL ret = FALSE;
881 FX_INT32 i = 0;
882 while (i < nChars) {
883 if (pCharPos[i].m_bGlyphAdjust || font_size < 0) {
884 if (i > 0) {
885 ret = CG_DrawGlypRun(i,
886 pCharPos,
887 pFont,
888 pCache,
889 NULL,
890 pObject2Device,
891 font_size,
892 color,
893 alpha_flag,
894 pIccTransform);
895 if (!ret) {
896 RestoreState(FALSE);
897 return ret;
780 } 898 }
781 for (int row = 0; row < pBitmap1->GetHeight(); row ++) { 899 }
782 FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); 900 const FXTEXT_CHARPOS* char_pos = pCharPos + i;
783 for (int col = 0; col < pBitmap1->GetWidth(); col ++) { 901 CFX_AffineMatrix glphy_matrix;
784 pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + . 5f); 902 if (font_size < 0) {
785 pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + . 5f); 903 glphy_matrix.Concat(-1, 0, 0, -1, 0, 0);
786 pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + . 5f); 904 }
787 pScanline += 4; 905 if (char_pos->m_bGlyphAdjust) {
788 } 906 glphy_matrix.Concat(char_pos->m_AdjustMatrix[0],
789 } 907 char_pos->m_AdjustMatrix[1],
790 } 908 char_pos->m_AdjustMatrix[2],
791 CGContextRef ctx = createContextWithBitmap(pBitmap1); 909 char_pos->m_AdjustMatrix[3],
792 CGImageRef image = CGBitmapContextCreateImage(ctx); 910 0,
793 CGContextDrawImage(_context, rect, image); 911 0);
794 CGImageRelease(image); 912 }
795 CGContextRelease(ctx); 913 ret = CG_DrawGlypRun(1,
796 if (pBitmap1 != pBitmap) { 914 char_pos,
797 delete pBitmap1; 915 pFont,
798 } 916 pCache,
799 RestoreState(FALSE); 917 &glphy_matrix,
800 return TRUE; 918 pObject2Device,
801 } 919 font_size,
802 FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars , 920 color,
803 const FXTEXT_CHARPOS* pCharPos, 921 alpha_flag,
804 CFX_Font* pFont, 922 pIccTransform);
805 CFX_FontCache* pCache, 923 if (!ret) {
806 const CFX_AffineMatrix* pGlyphMatrix, 924 RestoreState(FALSE);
807 const CFX_AffineMatrix* pObject2Device, 925 return ret;
808 FX_FLOAT font_size, 926 }
809 FX_DWORD argb, 927 i++;
810 int alpha_flag, 928 pCharPos += i;
811 void* pIccTransform) 929 nChars -= i;
812 { 930 i = 0;
813 if (nChars == 0) { 931 } else {
814 return TRUE; 932 i++;
815 } 933 }
816 CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformDa ta())->_quartz2d; 934 }
817 if (!pFont->m_pPlatformFont) { 935 if (i > 0) {
818 if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { 936 ret = CG_DrawGlypRun(i,
819 return FALSE; 937 pCharPos,
820 } 938 pFont,
821 pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont-> m_dwSize); 939 pCache,
822 if (NULL == pFont->m_pPlatformFont) { 940 NULL,
823 return FALSE; 941 pObject2Device,
824 } 942 font_size,
825 } 943 color,
826 CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars); 944 alpha_flag,
827 CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); 945 pIccTransform);
828 for (int i = 0; i < nChars; i++ ) { 946 }
829 glyph_indices[i] = pCharPos[i].m_ExtGID; 947 RestoreState(FALSE);
830 glyph_positions[i].x = pCharPos[i].m_OriginX; 948 return ret;
831 glyph_positions[i].y = pCharPos[i].m_OriginY; 949 }
832 } 950 void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState,
833 CFX_AffineMatrix text_matrix; 951 FX_ARGB argb,
834 if (pObject2Device) { 952 FX_FLOAT lineWidth) {
835 text_matrix.Concat(*pObject2Device); 953 if (NULL == graphState) {
836 } 954 return;
837 CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a, 955 }
838 text_matrix.b, 956 CGContextSetLineWidth(_context, lineWidth);
839 text_matrix.c, 957 CGLineCap cap;
840 text_matrix.d, 958 switch (graphState->m_LineCap) {
841 text_matrix.e, 959 case CFX_GraphStateData::LineCapRound: {
842 text_matrix.f); 960 cap = kCGLineCapRound;
843 matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User); 961 break;
844 CGContextSetTextMatrix(_context, matrix_cg); 962 }
845 CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont); 963 case CFX_GraphStateData::LineCapSquare: {
846 CGContextSetFontSize(_context, FXSYS_fabs(font_size)); 964 cap = kCGLineCapSquare;
847 FX_INT32 a, r, g, b; 965 break;
848 ArgbDecode(argb, a, r, g, b); 966 }
849 CGContextSetRGBFillColor(_context, 967 case CFX_GraphStateData::LineCapButt:
850 r / 255.f, 968 default: { cap = kCGLineCapButt; }
851 g / 255.f, 969 }
852 b / 255.f, 970 CGContextSetLineCap(_context, cap);
853 a / 255.f); 971 CGLineJoin join;
854 SaveState(); 972 switch (graphState->m_LineJoin) {
855 if (pGlyphMatrix) { 973 case CFX_GraphStateData::LineJoinRound: {
856 CGPoint origin = CGPointMake( glyph_positions[0].x, glyph_positions[0]. y); 974 join = kCGLineJoinRound;
857 origin = CGPointApplyAffineTransform(origin, matrix_cg); 975 break;
858 CGContextTranslateCTM(_context, origin.x, origin.y); 976 }
859 CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a, 977 case CFX_GraphStateData::LineJoinBevel: {
860 pGlyphMatrix->b, 978 join = kCGLineJoinBevel;
861 pGlyphMatrix->c, 979 break;
862 pGlyphMatrix->d, 980 }
863 pGlyphMatrix->e, 981 case CFX_GraphStateData::LineJoinMiter:
864 pGlyphMatrix->f); 982 default: { join = kCGLineJoinMiter; }
865 if (_foxitDevice2User.d < 0) { 983 }
866 glyph_matrix = CGAffineTransformInvert(glyph_matrix); 984 CGContextSetLineJoin(_context, join);
867 } 985 if (graphState->m_DashCount) {
868 CGContextConcatCTM(_context, glyph_matrix);
869 CGContextTranslateCTM(_context, -origin.x, -origin.y);
870 }
871 CGContextShowGlyphsAtPositions(_context,
872 (CGGlyph*)glyph_indices,
873 glyph_positions,
874 nChars);
875 RestoreState(FALSE);
876 return TRUE;
877 }
878 FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars,
879 const FXTEXT_CHARPOS* pCharPos,
880 CFX_Font* pFont,
881 CFX_FontCache* pCache,
882 const CFX_AffineMatrix* pObject2Device,
883 FX_FLOAT font_size,
884 FX_DWORD color,
885 int alpha_flag ,
886 void* pIccTransform)
887 {
888 if (NULL == pFont || NULL == _context) {
889 return FALSE;
890 }
891 FX_BOOL bBold = pFont->IsBold();
892 if (!bBold && pFont->GetSubstFont() &&
893 pFont->GetSubstFont()->m_Weight >= 500 &&
894 pFont->GetSubstFont()->m_Weight <= 600) {
895 return FALSE;
896 }
897 SaveState();
898 CGContextSetTextDrawingMode(_context, kCGTextFillClip);
899 FX_BOOL ret = FALSE;
900 FX_INT32 i = 0;
901 while (i < nChars) {
902 if (pCharPos[i].m_bGlyphAdjust || font_size < 0) {
903 if (i > 0) {
904 ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2D evice, font_size, color, alpha_flag, pIccTransform);
905 if (!ret) {
906 RestoreState(FALSE);
907 return ret;
908 }
909 }
910 const FXTEXT_CHARPOS* char_pos = pCharPos + i;
911 CFX_AffineMatrix glphy_matrix;
912 if (font_size < 0) {
913 glphy_matrix.Concat(-1, 0, 0, -1, 0, 0);
914 }
915 if (char_pos->m_bGlyphAdjust) {
916 glphy_matrix.Concat(char_pos->m_AdjustMatrix[0],
917 char_pos->m_AdjustMatrix[1],
918 char_pos->m_AdjustMatrix[2],
919 char_pos->m_AdjustMatrix[3], 0, 0);
920 }
921 ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObj ect2Device, font_size, color, alpha_flag, pIccTransform);
922 if (!ret) {
923 RestoreState(FALSE);
924 return ret;
925 }
926 i ++;
927 pCharPos += i;
928 nChars -= i;
929 i = 0;
930 } else {
931 i ++;
932 }
933 }
934 if (i > 0) {
935 ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, f ont_size, color, alpha_flag, pIccTransform);
936 }
937 RestoreState(FALSE);
938 return ret;
939 }
940 void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, FX_ARGB argb, FX_FLOAT lineWidth)
941 {
942 if (NULL == graphState) {
943 return;
944 }
945 CGContextSetLineWidth(_context, lineWidth);
946 CGLineCap cap;
947 switch (graphState->m_LineCap) {
948 case CFX_GraphStateData::LineCapRound: {
949 cap = kCGLineCapRound;
950 break;
951 }
952 case CFX_GraphStateData::LineCapSquare: {
953 cap = kCGLineCapSquare;
954 break;
955 }
956 case CFX_GraphStateData::LineCapButt:
957 default: {
958 cap = kCGLineCapButt;
959 }
960 }
961 CGContextSetLineCap(_context, cap);
962 CGLineJoin join;
963 switch (graphState->m_LineJoin) {
964 case CFX_GraphStateData::LineJoinRound: {
965 join = kCGLineJoinRound;
966 break;
967 }
968 case CFX_GraphStateData::LineJoinBevel: {
969 join = kCGLineJoinBevel;
970 break;
971 }
972 case CFX_GraphStateData::LineJoinMiter:
973 default: {
974 join = kCGLineJoinMiter;
975 }
976 }
977 CGContextSetLineJoin(_context, join);
978 if (graphState->m_DashCount) {
979 #if CGFLOAT_IS_DOUBLE 986 #if CGFLOAT_IS_DOUBLE
980 CGFloat* dashArray = new CGFloat[graphState->m_DashCount]; 987 CGFloat* dashArray = new CGFloat[graphState->m_DashCount];
981 if (!dashArray) { 988 if (!dashArray) {
982 return; 989 return;
983 } 990 }
984 for (int index = 0; index < graphState->m_DashCount; ++index) { 991 for (int index = 0; index < graphState->m_DashCount; ++index) {
985 dashArray[index] = graphState->m_DashArray[index]; 992 dashArray[index] = graphState->m_DashArray[index];
986 } 993 }
987 #else 994 #else
988 CGFloat* dashArray = (CGFloat*)graphState->m_DashArray; 995 CGFloat* dashArray = (CGFloat*)graphState->m_DashArray;
989 #endif 996 #endif
990 CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, graph State->m_DashCount); 997 CGContextSetLineDash(
998 _context, graphState->m_DashPhase, dashArray, graphState->m_DashCount);
991 #if CGFLOAT_IS_DOUBLE 999 #if CGFLOAT_IS_DOUBLE
992 delete[] dashArray; 1000 delete[] dashArray;
993 #endif 1001 #endif
994 } 1002 }
995 FX_INT32 a, r, g, b; 1003 FX_INT32 a, r, g, b;
996 ArgbDecode(argb, a, r, g, b); 1004 ArgbDecode(argb, a, r, g, b);
997 CGContextSetRGBStrokeColor(_context, 1005 CGContextSetRGBStrokeColor(
998 r / 255.f, 1006 _context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
999 g / 255.f, 1007 }
1000 b / 255.f, 1008 void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) {
1001 a / 255.f); 1009 FX_INT32 a, r, g, b;
1002 } 1010 ArgbDecode(argb, a, r, g, b);
1003 void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) 1011 CGContextSetRGBFillColor(
1004 { 1012 _context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
1005 FX_INT32 a, r, g, b; 1013 }
1006 ArgbDecode(argb, a, r, g, b); 1014 void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) {
1007 CGContextSetRGBFillColor(_context, 1015 FX_INT32 count = pathData->GetPointCount();
1008 r / 255.f, 1016 FX_PATHPOINT* points = pathData->GetPoints();
1009 g / 255.f, 1017 CGContextBeginPath(_context);
1010 b / 255.f, 1018 for (FX_INT32 i = 0; i < count; i++) {
1011 a / 255.f); 1019 switch (points[i].m_Flag & FXPT_TYPE) {
1012 } 1020 case FXPT_MOVETO:
1013 void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) 1021 CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY);
1014 { 1022 break;
1015 FX_INT32 count = pathData->GetPointCount(); 1023 case FXPT_LINETO:
1016 FX_PATHPOINT* points = pathData->GetPoints(); 1024 CGContextAddLineToPoint(
1017 CGContextBeginPath(_context); 1025 _context, points[i].m_PointX, points[i].m_PointY);
1018 for (FX_INT32 i = 0; i < count; i ++) { 1026 break;
1019 switch (points[i].m_Flag & FXPT_TYPE) { 1027 case FXPT_BEZIERTO: {
1020 case FXPT_MOVETO: 1028 CGContextAddCurveToPoint(_context,
1021 CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_P ointY); 1029 points[i].m_PointX,
1022 break; 1030 points[i].m_PointY,
1023 case FXPT_LINETO: 1031 points[i + 1].m_PointX,
1024 CGContextAddLineToPoint(_context, points[i].m_PointX, points[i]. m_PointY); 1032 points[i + 1].m_PointY,
1025 break; 1033 points[i + 2].m_PointX,
1026 case FXPT_BEZIERTO: { 1034 points[i + 2].m_PointY);
1027 CGContextAddCurveToPoint(_context, 1035 i += 2;
1028 points[i].m_PointX, points[i].m_Poi ntY, 1036 }
1029 points[i + 1].m_PointX, points[i + 1].m_PointY, 1037 }
1030 points[i + 2].m_PointX, points[i + 2].m_PointY); 1038 if (points[i].m_Flag & FXPT_CLOSEFIGURE) {
1031 i += 2; 1039 CGContextClosePath(_context);
1032 } 1040 }
1033 } 1041 }
1034 if (points[i].m_Flag & FXPT_CLOSEFIGURE) { 1042 }
1035 CGContextClosePath(_context); 1043 void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left,
1036 } 1044 int dest_top,
1037 } 1045 int dest_width,
1038 } 1046 int dest_height,
1039 void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, i nt dest_width, int dest_height, 1047 CGRect* rect) {
1040 CGRect* rect ) 1048 int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1;
1041 { 1049 int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1;
1042 int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1; 1050 if (flip_y < 0 || flip_x < 0) {
1043 int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1; 1051 if (dest_height < 0) {
1044 if (flip_y < 0 || flip_x < 0) { 1052 dest_height = -dest_height;
1045 if (dest_height < 0) { 1053 dest_top -= dest_height;
1046 dest_height = -dest_height; 1054 }
1047 dest_top -= dest_height; 1055 CGRect rt = CGRectApplyAffineTransform(
1048 } 1056 CGRectMake(dest_left, dest_top, dest_width, dest_height),
1049 CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, d est_width, dest_height), _foxitDevice2User); 1057 _foxitDevice2User);
1050 CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f, 1058 CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f,
1051 offset_y = (rt.origin.y) + rt.size.height / 2.f; 1059 offset_y = (rt.origin.y) + rt.size.height / 2.f;
1052 CGAffineTransform transform = CGAffineTransformIdentity; 1060 CGAffineTransform transform = CGAffineTransformIdentity;
1053 transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y)); 1061 transform = CGAffineTransformConcat(
1054 transform = CGAffineTransformConcat(transform, CGAffineTransformMake(fli p_x, 0, 0, flip_y, 0, 0)); 1062 transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y));
1055 transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y)); 1063 transform = CGAffineTransformConcat(
1056 CGContextConcatCTM(_context, transform); 1064 transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0));
1057 if (rect) { 1065 transform = CGAffineTransformConcat(
1058 *rect = CGRectApplyAffineTransform(*rect, transform); 1066 transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y));
1059 } 1067 CGContextConcatCTM(_context, transform);
1060 } 1068 if (rect) {
1061 } 1069 *rect = CGRectApplyAffineTransform(*rect, transform);
1062 void CFX_QuartzDeviceDriver::ClearDriver() 1070 }
1063 { 1071 }
1064 if (NULL == _context) { 1072 }
1065 return; 1073 void CFX_QuartzDeviceDriver::ClearDriver() {
1066 } 1074 if (NULL == _context) {
1067 for (int i = 0; i < m_saveCount; ++i) { 1075 return;
1068 CGContextRestoreGState(_context); 1076 }
1069 } 1077 for (int i = 0; i < m_saveCount; ++i) {
1070 m_saveCount = 0; 1078 CGContextRestoreGState(_context);
1071 if (_context) { 1079 }
1072 CGContextRelease(_context); 1080 m_saveCount = 0;
1073 } 1081 if (_context) {
1074 } 1082 CGContextRelease(_context);
1075 CFX_QuartzDevice::CFX_QuartzDevice() 1083 }
1076 { 1084 }
1077 m_bOwnedBitmap = FALSE; 1085 CFX_QuartzDevice::CFX_QuartzDevice() {
1078 m_pContext = NULL; 1086 m_bOwnedBitmap = FALSE;
1079 } 1087 m_pContext = NULL;
1080 CFX_QuartzDevice::~CFX_QuartzDevice() 1088 }
1081 { 1089 CFX_QuartzDevice::~CFX_QuartzDevice() {
1082 if (m_pContext) { 1090 if (m_pContext) {
1083 CGContextRelease(m_pContext); 1091 CGContextRelease(m_pContext);
1084 } 1092 }
1085 if (GetBitmap() && m_bOwnedBitmap) { 1093 if (GetBitmap() && m_bOwnedBitmap) {
1086 delete GetBitmap(); 1094 delete GetBitmap();
1087 } 1095 }
1088 } 1096 }
1089 CGContextRef CFX_QuartzDevice::GetContext() 1097 CGContextRef CFX_QuartzDevice::GetContext() {
1090 { 1098 return m_pContext;
1091 return m_pContext; 1099 }
1092 } 1100 FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, FX_INT32 nDeviceClass) {
1093 FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, FX_INT32 nDeviceClass) 1101 if (m_pContext) {
1094 { 1102 CGContextRelease(m_pContext);
1095 if (m_pContext) { 1103 }
1096 CGContextRelease(m_pContext); 1104 m_pContext = context;
1097 } 1105 CGContextRetain(m_pContext);
1098 m_pContext = context; 1106 IFX_RenderDeviceDriver* pDriver =
1099 CGContextRetain(m_pContext); 1107 FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass);
1100 IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass); 1108 if (!pDriver) {
1101 if (!pDriver) { 1109 return FALSE;
1102 return FALSE; 1110 }
1103 } 1111 SetDeviceDriver(pDriver);
1104 SetDeviceDriver(pDriver); 1112 return TRUE;
1105 return TRUE; 1113 }
1106 } 1114 FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) {
1107 FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) 1115 SetBitmap(pBitmap);
1108 { 1116 m_pContext = createContextWithBitmap(pBitmap);
1109 SetBitmap(pBitmap); 1117 if (NULL == m_pContext) {
1110 m_pContext = createContextWithBitmap(pBitmap); 1118 return FALSE;
1111 if (NULL == m_pContext) { 1119 }
1112 return FALSE; 1120 IFX_RenderDeviceDriver* pDriver =
1113 } 1121 FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY);
1114 IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY); 1122 if (!pDriver) {
1115 if (!pDriver) { 1123 return FALSE;
1116 return FALSE; 1124 }
1117 } 1125 SetDeviceDriver(pDriver);
1118 SetDeviceDriver(pDriver); 1126 return TRUE;
1119 return TRUE; 1127 }
1120 } 1128 FX_BOOL CFX_QuartzDevice::Create(FX_INT32 width,
1121 FX_BOOL CFX_QuartzDevice::Create(FX_INT32 width, FX_INT32 height, FXDIB_Format f ormat) 1129 FX_INT32 height,
1122 { 1130 FXDIB_Format format) {
1123 if ((FX_BYTE)format < 32) { 1131 if ((FX_BYTE)format < 32) {
1124 return FALSE; 1132 return FALSE;
1125 } 1133 }
1126 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap; 1134 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
1127 if (!pBitmap) { 1135 if (!pBitmap) {
1128 return FALSE; 1136 return FALSE;
1129 } 1137 }
1130 if (!pBitmap->Create(width, height, format)) { 1138 if (!pBitmap->Create(width, height, format)) {
1131 delete pBitmap; 1139 delete pBitmap;
1132 return FALSE; 1140 return FALSE;
1133 } 1141 }
1134 m_bOwnedBitmap = TRUE; 1142 m_bOwnedBitmap = TRUE;
1135 return Attach(pBitmap); 1143 return Attach(pBitmap);
1136 } 1144 }
1137 #endif 1145 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698