Home | History | Annotate | Download | only in apple
      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