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

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

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

Powered by Google App Engine
This is Rietveld 408576698