• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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