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 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 46 void CQuartz2D::destroyGraphics(void* graphics) { 47 if (graphics) 48 CGContextRelease((CGContextRef)graphics); 49 } 50 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 62 void CQuartz2D::DestroyFont(void* pFont) { 63 CGFontRelease((CGFontRef)pFont); 64 } 65 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 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 121 void CQuartz2D::saveGraphicsState(void* graphics) { 122 if (graphics) 123 CGContextSaveGState((CGContextRef)graphics); 124 } 125 126 void CQuartz2D::restoreGraphicsState(void* graphics) { 127 if (graphics) 128 CGContextRestoreGState((CGContextRef)graphics); 129 } 130