1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxcrt/fx_extension.h"
8
9 #if !defined _SKIA_SUPPORT_ && !defined _SKIA_SUPPORT_PATHS_
10 #include "core/fxge/agg/fx_agg_driver.h"
11 #endif
12
13 #include "core/fxcrt/fx_memory.h"
14 #include "core/fxge/cfx_graphstatedata.h"
15 #include "core/fxge/cfx_pathdata.h"
16 #include "core/fxge/cfx_renderdevice.h"
17 #include "core/fxge/dib/cfx_dibitmap.h"
18 #include "core/fxge/fx_freetype.h"
19 #include "third_party/base/ptr_util.h"
20
21 #include "core/fxge/apple/apple_int.h"
22 #ifndef CGFLOAT_IS_DOUBLE
23 #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
24 #endif
25
createGraphics(const RetainPtr<CFX_DIBitmap> & pBitmap)26 void* CQuartz2D::createGraphics(const RetainPtr<CFX_DIBitmap>& pBitmap) {
27 if (!pBitmap)
28 return nullptr;
29 CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
30 switch (pBitmap->GetFormat()) {
31 case FXDIB_Rgb32:
32 bmpInfo |= kCGImageAlphaNoneSkipFirst;
33 break;
34 case FXDIB_Argb:
35 default:
36 return nullptr;
37 }
38 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
39 CGContextRef context = CGBitmapContextCreate(
40 pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8,
41 pBitmap->GetPitch(), colorSpace, bmpInfo);
42 CGColorSpaceRelease(colorSpace);
43 return context;
44 }
45
destroyGraphics(void * graphics)46 void CQuartz2D::destroyGraphics(void* graphics) {
47 if (graphics)
48 CGContextRelease((CGContextRef)graphics);
49 }
50
CreateFont(const uint8_t * pFontData,uint32_t dwFontSize)51 void* CQuartz2D::CreateFont(const uint8_t* pFontData, uint32_t dwFontSize) {
52 CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(
53 nullptr, pFontData, static_cast<size_t>(dwFontSize), nullptr);
54 if (!pDataProvider)
55 return nullptr;
56
57 CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
58 CGDataProviderRelease(pDataProvider);
59 return pCGFont;
60 }
61
DestroyFont(void * pFont)62 void CQuartz2D::DestroyFont(void* pFont) {
63 CGFontRelease((CGFontRef)pFont);
64 }
65
setGraphicsTextMatrix(void * graphics,CFX_Matrix * matrix)66 void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_Matrix* matrix) {
67 if (!graphics || !matrix)
68 return;
69 CGContextRef context = (CGContextRef)graphics;
70 CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
71 CGContextSetTextMatrix(
72 context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
73 matrix->e, ty));
74 }
75
drawGraphicsString(void * graphics,void * font,float fontSize,uint16_t * glyphIndices,CGPoint * glyphPositions,int32_t charsCount,FX_ARGB argb,CFX_Matrix * matrix)76 bool CQuartz2D::drawGraphicsString(void* graphics,
77 void* font,
78 float fontSize,
79 uint16_t* glyphIndices,
80 CGPoint* glyphPositions,
81 int32_t charsCount,
82 FX_ARGB argb,
83 CFX_Matrix* matrix) {
84 if (!graphics)
85 return false;
86 CGContextRef context = (CGContextRef)graphics;
87 CGContextSetFont(context, (CGFontRef)font);
88 CGContextSetFontSize(context, fontSize);
89 if (matrix) {
90 CGAffineTransform m = CGContextGetTextMatrix(context);
91 m = CGAffineTransformConcat(
92 m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
93 matrix->e, matrix->f));
94 CGContextSetTextMatrix(context, m);
95 }
96 int32_t a;
97 int32_t r;
98 int32_t g;
99 int32_t b;
100 std::tie(a, r, g, b) = ArgbDecode(argb);
101 CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
102 CGContextSaveGState(context);
103 #if CGFLOAT_IS_DOUBLE
104 CGPoint* glyphPositionsCG = new CGPoint[charsCount];
105 for (int index = 0; index < charsCount; ++index) {
106 glyphPositionsCG[index].x = glyphPositions[index].x;
107 glyphPositionsCG[index].y = glyphPositions[index].y;
108 }
109 #else
110 CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
111 #endif
112 CGContextShowGlyphsAtPositions(context, (CGGlyph*)glyphIndices,
113 glyphPositionsCG, charsCount);
114 #if CGFLOAT_IS_DOUBLE
115 delete[] glyphPositionsCG;
116 #endif
117 CGContextRestoreGState(context);
118 return true;
119 }
120
saveGraphicsState(void * graphics)121 void CQuartz2D::saveGraphicsState(void* graphics) {
122 if (graphics)
123 CGContextSaveGState((CGContextRef)graphics);
124 }
125
restoreGraphicsState(void * graphics)126 void CQuartz2D::restoreGraphicsState(void* graphics) {
127 if (graphics)
128 CGContextRestoreGState((CGContextRef)graphics);
129 }
130