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_ext.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_gemodule.h"
15 #include "core/fxge/cfx_graphstatedata.h"
16 #include "core/fxge/cfx_pathdata.h"
17 #include "core/fxge/cfx_renderdevice.h"
18 #include "core/fxge/dib/dib_int.h"
19 #include "core/fxge/fx_freetype.h"
20 #include "core/fxge/ge/fx_text_int.h"
21 #include "third_party/base/ptr_util.h"
22
23 #include "core/fxge/apple/apple_int.h"
24 #ifndef CGFLOAT_IS_DOUBLE
25 #error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
26 #endif
27
createGraphics(CFX_DIBitmap * pBitmap)28 void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) {
29 if (!pBitmap)
30 return nullptr;
31 CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
32 switch (pBitmap->GetFormat()) {
33 case FXDIB_Rgb32:
34 bmpInfo |= kCGImageAlphaNoneSkipFirst;
35 break;
36 case FXDIB_Argb:
37 default:
38 return nullptr;
39 }
40 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
41 CGContextRef context = CGBitmapContextCreate(
42 pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8,
43 pBitmap->GetPitch(), colorSpace, bmpInfo);
44 CGColorSpaceRelease(colorSpace);
45 return context;
46 }
47
destroyGraphics(void * graphics)48 void CQuartz2D::destroyGraphics(void* graphics) {
49 if (graphics)
50 CGContextRelease((CGContextRef)graphics);
51 }
52
CreateFont(const uint8_t * pFontData,uint32_t dwFontSize)53 void* CQuartz2D::CreateFont(const uint8_t* pFontData, uint32_t dwFontSize) {
54 CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(
55 nullptr, pFontData, (size_t)dwFontSize, nullptr);
56 if (!pDataProvider)
57 return nullptr;
58
59 CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
60 CGDataProviderRelease(pDataProvider);
61 return pCGFont;
62 }
63
DestroyFont(void * pFont)64 void CQuartz2D::DestroyFont(void* pFont) {
65 CGFontRelease((CGFontRef)pFont);
66 }
67
setGraphicsTextMatrix(void * graphics,CFX_Matrix * matrix)68 void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_Matrix* matrix) {
69 if (!graphics || !matrix)
70 return;
71 CGContextRef context = (CGContextRef)graphics;
72 CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
73 CGContextSetTextMatrix(
74 context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
75 matrix->e, ty));
76 }
77
drawGraphicsString(void * graphics,void * font,FX_FLOAT fontSize,uint16_t * glyphIndices,CGPoint * glyphPositions,int32_t charsCount,FX_ARGB argb,CFX_Matrix * matrix)78 bool CQuartz2D::drawGraphicsString(void* graphics,
79 void* font,
80 FX_FLOAT fontSize,
81 uint16_t* glyphIndices,
82 CGPoint* glyphPositions,
83 int32_t charsCount,
84 FX_ARGB argb,
85 CFX_Matrix* matrix) {
86 if (!graphics)
87 return false;
88 CGContextRef context = (CGContextRef)graphics;
89 CGContextSetFont(context, (CGFontRef)font);
90 CGContextSetFontSize(context, fontSize);
91 if (matrix) {
92 CGAffineTransform m = CGContextGetTextMatrix(context);
93 m = CGAffineTransformConcat(
94 m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
95 matrix->e, matrix->f));
96 CGContextSetTextMatrix(context, m);
97 }
98 int32_t a, r, g, b;
99 ArgbDecode(argb, a, r, g, b);
100 CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
101 CGContextSaveGState(context);
102 #if CGFLOAT_IS_DOUBLE
103 CGPoint* glyphPositionsCG = new CGPoint[charsCount];
104 for (int index = 0; index < charsCount; ++index) {
105 glyphPositionsCG[index].x = glyphPositions[index].x;
106 glyphPositionsCG[index].y = glyphPositions[index].y;
107 }
108 #else
109 CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
110 #endif
111 CGContextShowGlyphsAtPositions(context, (CGGlyph*)glyphIndices,
112 glyphPositionsCG, charsCount);
113 #if CGFLOAT_IS_DOUBLE
114 delete[] glyphPositionsCG;
115 #endif
116 CGContextRestoreGState(context);
117 return true;
118 }
119
saveGraphicsState(void * graphics)120 void CQuartz2D::saveGraphicsState(void* graphics) {
121 if (graphics)
122 CGContextSaveGState((CGContextRef)graphics);
123 }
124
restoreGraphicsState(void * graphics)125 void CQuartz2D::restoreGraphicsState(void* graphics) {
126 if (graphics)
127 CGContextRestoreGState((CGContextRef)graphics);
128 }
129