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