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

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

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

Powered by Google App Engine
This is Rietveld 408576698