// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/include/fx_ext.h"
#include "core/fxge/agg/fx_agg_driver.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/ge/fx_text_int.h"
#include "core/fxge/include/fx_freetype.h"
#include "core/fxge/include/fx_ge.h"

#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
#include "core/fxge/apple/apple_int.h"
#include "core/fxge/include/fx_ge_apple.h"
#ifndef CGFLOAT_IS_DOUBLE
#error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
#endif

void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap) {
  if (!pBitmap) {
    return NULL;
  }
  CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
  switch (pBitmap->GetFormat()) {
    case FXDIB_Rgb32:
      bmpInfo |= kCGImageAlphaNoneSkipFirst;
      break;
    case FXDIB_Argb:
    default:
      return NULL;
  }
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(
      pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8,
      pBitmap->GetPitch(), colorSpace, bmpInfo);
  CGColorSpaceRelease(colorSpace);
  return context;
}
void CQuartz2D::destroyGraphics(void* graphics) {
  if (graphics) {
    CGContextRelease((CGContextRef)graphics);
  }
}
void* CQuartz2D::CreateFont(const uint8_t* pFontData, uint32_t dwFontSize) {
  CGDataProviderRef pDataProvider =
      CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL);
  if (NULL == pDataProvider) {
    return NULL;
  }
  CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
  CGDataProviderRelease(pDataProvider);
  return pCGFont;
}
void CQuartz2D::DestroyFont(void* pFont) {
  CGFontRelease((CGFontRef)pFont);
}
void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_Matrix* matrix) {
  if (!graphics || !matrix) {
    return;
  }
  CGContextRef context = (CGContextRef)graphics;
  CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
  CGContextSetTextMatrix(
      context, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
                                     matrix->e, ty));
}
FX_BOOL CQuartz2D::drawGraphicsString(void* graphics,
                                      void* font,
                                      FX_FLOAT fontSize,
                                      uint16_t* glyphIndices,
                                      CGPoint* glyphPositions,
                                      int32_t charsCount,
                                      FX_ARGB argb,
                                      CFX_Matrix* matrix) {
  if (!graphics) {
    return FALSE;
  }
  CGContextRef context = (CGContextRef)graphics;
  CGContextSetFont(context, (CGFontRef)font);
  CGContextSetFontSize(context, fontSize);
  if (matrix) {
    CGAffineTransform m = CGContextGetTextMatrix(context);
    m = CGAffineTransformConcat(
        m, CGAffineTransformMake(matrix->a, matrix->b, matrix->c, matrix->d,
                                 matrix->e, matrix->f));
    CGContextSetTextMatrix(context, m);
  }
  int32_t a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  CGContextSetRGBFillColor(context, r / 255.f, g / 255.f, b / 255.f, a / 255.f);
  CGContextSaveGState(context);
#if CGFLOAT_IS_DOUBLE
  CGPoint* glyphPositionsCG = new CGPoint[charsCount];
  for (int index = 0; index < charsCount; ++index) {
    glyphPositionsCG[index].x = glyphPositions[index].x;
    glyphPositionsCG[index].y = glyphPositions[index].y;
  }
#else
  CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
#endif
  CGContextShowGlyphsAtPositions(context, (CGGlyph*)glyphIndices,
                                 glyphPositionsCG, charsCount);
#if CGFLOAT_IS_DOUBLE
  delete[] glyphPositionsCG;
#endif
  CGContextRestoreGState(context);
  return TRUE;
}
void CQuartz2D::saveGraphicsState(void* graphics) {
  if (graphics) {
    CGContextSaveGState((CGContextRef)graphics);
  }
}
void CQuartz2D::restoreGraphicsState(void* graphics) {
  if (graphics) {
    CGContextRestoreGState((CGContextRef)graphics);
  }
}
static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap) {
  if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) {
    return NULL;
  }
  CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little;
  if (pBitmap->HasAlpha()) {
    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
  } else {
    bitmapInfo |= kCGImageAlphaNoneSkipFirst;
  }
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(
      pBitmap->GetBuffer(), pBitmap->GetWidth(), pBitmap->GetHeight(), 8,
      pBitmap->GetPitch(), colorSpace, bitmapInfo);
  CGColorSpaceRelease(colorSpace);
  return context;
}
CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context,
                                               int32_t deviceClass) {
  m_saveCount = 0;
  m_context = context;
  m_deviceClass = deviceClass;
  CGContextRetain(m_context);
  CGRect r = CGContextGetClipBoundingBox(context);
  m_width = FXSYS_round(r.size.width);
  m_height = FXSYS_round(r.size.height);
  m_renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE | FXRC_ALPHA_PATH |
                 FXRC_ALPHA_IMAGE | FXRC_BIT_MASK | FXRC_ALPHA_MASK;
  if (m_deviceClass != FXDC_DISPLAY) {
  } else {
    CGImageRef image = CGBitmapContextCreateImage(m_context);
    if (image) {
      m_renderCaps |= FXRC_GET_BITS;
      m_width = CGImageGetWidth(image);
      m_height = CGImageGetHeight(image);
      CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image);
      if (kCGImageAlphaPremultipliedFirst == alphaInfo ||
          kCGImageAlphaPremultipliedLast == alphaInfo ||
          kCGImageAlphaOnly == alphaInfo) {
        m_renderCaps |= FXRC_ALPHA_OUTPUT;
      }
    }
    CGImageRelease(image);
  }
  CGAffineTransform ctm = CGContextGetCTM(m_context);
  CGContextSaveGState(m_context);
  m_saveCount++;
  if (ctm.d >= 0) {
    CGFloat offset_x, offset_y;
    offset_x = ctm.tx;
    offset_y = ctm.ty;
    CGContextTranslateCTM(m_context, -offset_x, -offset_y);
    CGContextConcatCTM(m_context, CGAffineTransformMake(1, 0, 0, -1, offset_x,
                                                        m_height + offset_y));
  }
  m_foxitDevice2User = CGAffineTransformIdentity;
  m_user2FoxitDevice = CGAffineTransformInvert(m_foxitDevice2User);
}
CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver() {
  CGContextRestoreGState(m_context);
  m_saveCount--;
  for (int i = 0; i < m_saveCount; ++i) {
    CGContextRestoreGState(m_context);
  }
  if (m_context) {
    CGContextRelease(m_context);
  }
}
int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID) {
  switch (capsID) {
    case FXDC_DEVICE_CLASS: {
      return m_deviceClass;
    }
    case FXDC_PIXEL_WIDTH: {
      return m_width;
    }
    case FXDC_PIXEL_HEIGHT: {
      return m_height;
    }
    case FXDC_BITS_PIXEL: {
      return 32;
    }
    case FXDC_RENDER_CAPS: {
      return m_renderCaps;
    }
    default: { return 0; }
  }
}
CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const {
  CGAffineTransform ctm = CGContextGetCTM(m_context);
  return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
}
void CFX_QuartzDeviceDriver::SaveState() {
  CGContextSaveGState(m_context);
  m_saveCount++;
}
void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved) {
  CGContextRestoreGState(m_context);
  if (isKeepSaved) {
    CGContextSaveGState(m_context);
  } else {
    m_saveCount--;
  }
}
FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData,
                                                 const CFX_Matrix* matrix,
                                                 int fillMode) {
  SaveState();
  CGAffineTransform m = CGAffineTransformIdentity;
  if (matrix) {
    m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(),
                              matrix->GetD(), matrix->GetE(), matrix->GetF());
  }
  m = CGAffineTransformConcat(m, m_foxitDevice2User);
  CGContextConcatCTM(m_context, m);
  setPathToContext(pathData);
  RestoreState(FALSE);
  if ((fillMode & 3) == FXFILL_WINDING) {
    CGContextClip(m_context);
  } else {
    CGContextEOClip(m_context);
  }
  return TRUE;
}
FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(
    const CFX_GraphStateData* graphState,
    CGAffineTransform ctm) {
  FX_FLOAT lineWidth = graphState->m_LineWidth;
  if (graphState->m_LineWidth <= 0.f) {
    CGSize size;
    size.width = 1;
    size.height = 1;
    CGSize temp = CGSizeApplyAffineTransform(size, ctm);
    CGFloat x = 1 / temp.width;
    CGFloat y = 1 / temp.height;
    lineWidth = x > y ? x : y;
  }
  return lineWidth;
}
FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(
    const CFX_PathData* pathData,
    const CFX_Matrix* matrix,
    const CFX_GraphStateData* graphState) {
  SaveState();
  CGAffineTransform m = CGAffineTransformIdentity;
  if (matrix) {
    m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(),
                              matrix->GetD(), matrix->GetE(), matrix->GetF());
  }
  m = CGAffineTransformConcat(m, m_foxitDevice2User);
  CGContextConcatCTM(m_context, m);
  FX_FLOAT lineWidth = getLineWidth(graphState, m);
  setStrokeInfo(graphState, 0xFF000000, lineWidth);
  setPathToContext(pathData);
  CGContextReplacePathWithStrokedPath(m_context);
  RestoreState(FALSE);
  CGContextClip(m_context);
  return TRUE;
}
static CGBlendMode GetCGBlendMode(int blend_type) {
  CGBlendMode mode = kCGBlendModeNormal;
  switch (blend_type) {
    case FXDIB_BLEND_NORMAL:
      mode = kCGBlendModeNormal;
      break;
    case FXDIB_BLEND_MULTIPLY:
      mode = kCGBlendModeMultiply;
      break;
    case FXDIB_BLEND_SCREEN:
      mode = kCGBlendModeScreen;
      break;
    case FXDIB_BLEND_OVERLAY:
      mode = kCGBlendModeOverlay;
      break;
    case FXDIB_BLEND_DARKEN:
      mode = kCGBlendModeDarken;
      break;
    case FXDIB_BLEND_LIGHTEN:
      mode = kCGBlendModeLighten;
      break;
    case FXDIB_BLEND_COLORDODGE:
      mode = kCGBlendModeColorDodge;
      break;
    case FXDIB_BLEND_COLORBURN:
      mode = kCGBlendModeColorBurn;
      break;
    case FXDIB_BLEND_HARDLIGHT:
      mode = kCGBlendModeHardLight;
      break;
    case FXDIB_BLEND_SOFTLIGHT:
      mode = kCGBlendModeSoftLight;
      break;
    case FXDIB_BLEND_DIFFERENCE:
      mode = kCGBlendModeDifference;
      break;
    case FXDIB_BLEND_EXCLUSION:
      mode = kCGBlendModeExclusion;
      break;
    case FXDIB_BLEND_HUE:
      mode = kCGBlendModeHue;
      break;
    case FXDIB_BLEND_SATURATION:
      mode = kCGBlendModeSaturation;
      break;
    case FXDIB_BLEND_COLOR:
      mode = kCGBlendModeColor;
      break;
    case FXDIB_BLEND_LUMINOSITY:
      mode = kCGBlendModeLuminosity;
      break;
    default:
      mode = kCGBlendModeNormal;
      break;
  }
  return mode;
}
FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData,
                                         const CFX_Matrix* matrix,
                                         const CFX_GraphStateData* graphState,
                                         uint32_t fillArgb,
                                         uint32_t strokeArgb,
                                         int fillMode,
                                         int alpha_flag,
                                         void* pIccTransform,
                                         int blend_type) {
  SaveState();
  CGBlendMode mode = GetCGBlendMode(blend_type);
  if (mode != kCGBlendModeNormal) {
    CGContextSetBlendMode(m_context, mode);
  }
  CGAffineTransform m = CGAffineTransformIdentity;
  if (matrix) {
    m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(),
                              matrix->GetD(), matrix->GetE(), matrix->GetF());
  }
  m = CGAffineTransformConcat(m, m_foxitDevice2User);
  CGContextConcatCTM(m_context, m);
  int pathMode = 0;
  if (graphState && strokeArgb) {
    CGContextSetMiterLimit(m_context, graphState->m_MiterLimit);
    FX_FLOAT lineWidth = getLineWidth(graphState, m);
    setStrokeInfo(graphState, strokeArgb, lineWidth);
    pathMode |= 4;
  }
  if (fillMode && fillArgb) {
    setFillInfo(fillArgb);
    if ((fillMode & 3) == FXFILL_WINDING) {
      pathMode |= 1;
    } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
      pathMode |= 2;
    }
  }
  setPathToContext(pathData);
  if (fillMode & FXFILL_FULLCOVER) {
    CGContextSetShouldAntialias(m_context, false);
  }
  if (pathMode == 4) {
    CGContextStrokePath(m_context);
  } else if (pathMode == 1) {
    CGContextFillPath(m_context);
  } else if (pathMode == 2) {
    CGContextEOFillPath(m_context);
  } else if (pathMode == 5) {
    CGContextDrawPath(m_context, kCGPathFillStroke);
  } else if (pathMode == 6) {
    CGContextDrawPath(m_context, kCGPathEOFillStroke);
  }
  RestoreState(FALSE);
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect,
                                         FX_ARGB fillArgb,
                                         int alphaFlag,
                                         void* iccTransform,
                                         int blend_type) {
  CGBlendMode mode = GetCGBlendMode(blend_type);
  if (mode != kCGBlendModeNormal) {
    CGContextSetBlendMode(m_context, mode);
  }
  CGRect rect_fx =
      CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
  CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, m_foxitDevice2User);
  int32_t a, r, g, b;
  ArgbDecode(fillArgb, a, r, g, b);
  CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f,
                           a / 255.f);
  CGContextFillRect(m_context, rect_usr);
  if (mode != kCGBlendModeNormal) {
    CGContextSetBlendMode(m_context, kCGBlendModeNormal);
  }
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
                                                 FX_FLOAT y1,
                                                 FX_FLOAT x2,
                                                 FX_FLOAT y2,
                                                 uint32_t argb,
                                                 int alphaFlag,
                                                 void* iccTransform,
                                                 int blend_type) {
  CGBlendMode mode = GetCGBlendMode(blend_type);
  if (mode != kCGBlendModeNormal) {
    CGContextSetBlendMode(m_context, mode);
  }
  CGPoint pt =
      CGPointApplyAffineTransform(CGPointMake(x1, y1), m_foxitDevice2User);
  x1 = pt.x;
  y1 = pt.y;
  pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), m_foxitDevice2User);
  x2 = pt.x;
  y2 = pt.y;
  int32_t a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f,
                             a / 255.f);
  CGContextMoveToPoint(m_context, x1, y1);
  CGContextAddLineToPoint(m_context, x2, y2);
  CGContextStrokePath(m_context);
  if (mode != kCGBlendModeNormal) {
    CGContextSetBlendMode(m_context, kCGBlendModeNormal);
  }
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect) {
  CGRect r = CGContextGetClipBoundingBox(m_context);
  r = CGRectApplyAffineTransform(r, m_user2FoxitDevice);
  rect->left = FXSYS_floor(r.origin.x);
  rect->top = FXSYS_floor(r.origin.y);
  rect->right = FXSYS_ceil(r.origin.x + r.size.width);
  rect->bottom = FXSYS_ceil(r.origin.y + r.size.height);
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap,
                                          int32_t left,
                                          int32_t top,
                                          void* pIccTransform,
                                          FX_BOOL bDEdge) {
  if (FXDC_PRINTER == m_deviceClass) {
    return FALSE;
  }
  if (bitmap->GetBPP() < 32) {
    return FALSE;
  }
  if (!(m_renderCaps | FXRC_GET_BITS)) {
    return FALSE;
  }
  CGPoint pt = CGPointMake(left, top);
  pt = CGPointApplyAffineTransform(pt, m_foxitDevice2User);
  CGAffineTransform ctm = CGContextGetCTM(m_context);
  pt.x *= FXSYS_fabs(ctm.a);
  pt.y *= FXSYS_fabs(ctm.d);
  CGImageRef image = CGBitmapContextCreateImage(m_context);
  if (NULL == image) {
    return FALSE;
  }
  CGFloat width = (CGFloat)bitmap->GetWidth();
  CGFloat height = (CGFloat)bitmap->GetHeight();
  if (width + pt.x > m_width) {
    width -= (width + pt.x - m_width);
  }
  if (height + pt.y > m_height) {
    height -= (height + pt.y - m_height);
  }
  CGImageRef subImage = CGImageCreateWithImageInRect(
      image, CGRectMake(pt.x, pt.y, width, height));
  CGContextRef context = createContextWithBitmap(bitmap);
  CGRect rect = CGContextGetClipBoundingBox(context);
  CGContextClearRect(context, rect);
  CGContextDrawImage(context, rect, subImage);
  CGContextRelease(context);
  CGImageRelease(subImage);
  CGImageRelease(image);
  if (bitmap->HasAlpha()) {
    for (int row = 0; row < bitmap->GetHeight(); row++) {
      uint8_t* pScanline = (uint8_t*)bitmap->GetScanline(row);
      for (int col = 0; col < bitmap->GetWidth(); col++) {
        if (pScanline[3] > 0) {
          pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f);
          pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f);
          pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f);
        }
        pScanline += 4;
      }
    }
  }
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
                                          FX_ARGB argb,
                                          const FX_RECT* srcRect,
                                          int dest_left,
                                          int dest_top,
                                          int blendType,
                                          int alphaFlag,
                                          void* iccTransform) {
  SaveState();
  CGFloat src_left, src_top, src_width, src_height;
  if (srcRect) {
    src_left = srcRect->left;
    src_top = srcRect->top;
    src_width = srcRect->Width();
    src_height = srcRect->Height();
  } else {
    src_left = src_top = 0;
    src_width = pBitmap->GetWidth();
    src_height = pBitmap->GetHeight();
  }
  CGAffineTransform ctm = CGContextGetCTM(m_context);
  CGFloat scale_x = FXSYS_fabs(ctm.a);
  CGFloat scale_y = FXSYS_fabs(ctm.d);
  src_left /= scale_x;
  src_top /= scale_y;
  src_width /= scale_x;
  src_height /= scale_y;
  CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
  CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, m_foxitDevice2User);
  CGContextBeginPath(m_context);
  CGContextAddRect(m_context, rect_usr);
  CGContextClip(m_context);
  rect_usr.size =
      CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
  rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
  CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
  CFX_DIBitmap* pBitmap1 = NULL;
  if (pBitmap->IsAlphaMask()) {
    if (pBitmap->GetBuffer()) {
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    } else {
      pBitmap1 = pBitmap->Clone();
    }
    if (NULL == pBitmap1) {
      RestoreState(FALSE);
      return FALSE;
    }
    CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
        NULL, pBitmap1->GetBuffer(),
        pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL);
    CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
    CGImageRef pImage = CGImageCreate(
        pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(),
        pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo,
        pBitmapProvider, NULL, true, kCGRenderingIntentDefault);
    CGContextClipToMask(m_context, rect_usr, pImage);
    CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f,
                             FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f,
                             FXARGB_A(argb) / 255.f);
    CGContextFillRect(m_context, rect_usr);
    CGImageRelease(pImage);
    CGColorSpaceRelease(pColorSpace);
    CGDataProviderRelease(pBitmapProvider);
    if (pBitmap1 != pBitmap) {
      delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
  }
  if (pBitmap->GetBPP() < 32) {
    pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
  } else {
    if (pBitmap->GetBuffer()) {
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    } else {
      pBitmap1 = pBitmap->Clone();
    }
  }
  if (NULL == pBitmap1) {
    RestoreState(FALSE);
    return FALSE;
  }
  if (pBitmap1->HasAlpha()) {
    if (pBitmap1 == pBitmap) {
      pBitmap1 = pBitmap->Clone();
      if (!pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
      }
    }
    for (int row = 0; row < pBitmap1->GetHeight(); row++) {
      uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row);
      for (int col = 0; col < pBitmap1->GetWidth(); col++) {
        pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f);
        pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f);
        pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f);
        pScanline += 4;
      }
    }
  }
  CGContextRef ctx = createContextWithBitmap(pBitmap1);
  CGImageRef image = CGBitmapContextCreateImage(ctx);
  int blend_mode = blendType;
  if (FXDIB_BLEND_HARDLIGHT == blendType) {
    blend_mode = kCGBlendModeSoftLight;
  } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
    blend_mode = kCGBlendModeHardLight;
  } else if (blendType >= FXDIB_BLEND_NONSEPARABLE &&
             blendType <= FXDIB_BLEND_LUMINOSITY) {
    blend_mode = blendType - 9;
  } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
    blend_mode = kCGBlendModeNormal;
  }
  CGContextSetBlendMode(m_context, (CGBlendMode)blend_mode);
  CGContextDrawImage(m_context, rect_usr, image);
  CGImageRelease(image);
  CGContextRelease(ctx);
  if (pBitmap1 != pBitmap) {
    delete pBitmap1;
  }
  RestoreState(FALSE);
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap,
                                              FX_ARGB argb,
                                              int dest_left,
                                              int dest_top,
                                              int dest_width,
                                              int dest_height,
                                              const FX_RECT* clipRect,
                                              uint32_t flags,
                                              int alphaFlag,
                                              void* iccTransform,
                                              int blend_type) {
  SaveState();
  if (clipRect) {
    CGContextBeginPath(m_context);
    CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top,
                                  clipRect->Width(), clipRect->Height());
    rect_clip = CGRectApplyAffineTransform(rect_clip, m_foxitDevice2User);
    CGContextAddRect(m_context, rect_clip);
    CGContextClip(m_context);
  }
  CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
  rect = CGRectApplyAffineTransform(rect, m_foxitDevice2User);
  if (FXDIB_BICUBIC_INTERPOL == flags) {
    CGContextSetInterpolationQuality(m_context, kCGInterpolationHigh);
  } else if (FXDIB_DOWNSAMPLE == flags) {
    CGContextSetInterpolationQuality(m_context, kCGInterpolationNone);
  } else {
    CGContextSetInterpolationQuality(m_context, kCGInterpolationMedium);
  }
  CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
  CFX_DIBitmap* pBitmap1 = NULL;
  if (pBitmap->IsAlphaMask()) {
    if (pBitmap->GetBuffer()) {
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    } else {
      pBitmap1 = pBitmap->Clone();
    }
    if (NULL == pBitmap1) {
      RestoreState(FALSE);
      return FALSE;
    }
    CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
        NULL, pBitmap1->GetBuffer(),
        pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL);
    CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
    CGImageRef pImage = CGImageCreate(
        pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(),
        pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo,
        pBitmapProvider, NULL, true, kCGRenderingIntentDefault);
    CGContextClipToMask(m_context, rect, pImage);
    CGContextSetRGBFillColor(m_context, FXARGB_R(argb) / 255.f,
                             FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f,
                             FXARGB_A(argb) / 255.f);
    CGContextFillRect(m_context, rect);
    CGImageRelease(pImage);
    CGColorSpaceRelease(pColorSpace);
    CGDataProviderRelease(pBitmapProvider);
    if (pBitmap1 != pBitmap) {
      delete pBitmap1;
    }
    RestoreState(FALSE);
    return TRUE;
  }
  if (pBitmap->GetBPP() < 32) {
    pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
  } else {
    if (pBitmap->GetBuffer()) {
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    } else {
      pBitmap1 = pBitmap->Clone();
    }
  }
  if (NULL == pBitmap1) {
    RestoreState(FALSE);
    return FALSE;
  }
  if (pBitmap1->HasAlpha()) {
    if (pBitmap1 == pBitmap) {
      pBitmap1 = pBitmap->Clone();
      if (!pBitmap1) {
        RestoreState(FALSE);
        return FALSE;
      }
    }
    for (int row = 0; row < pBitmap1->GetHeight(); row++) {
      uint8_t* pScanline = (uint8_t*)pBitmap1->GetScanline(row);
      for (int col = 0; col < pBitmap1->GetWidth(); col++) {
        pScanline[0] = (uint8_t)(pScanline[0] * pScanline[3] / 255.f + .5f);
        pScanline[1] = (uint8_t)(pScanline[1] * pScanline[3] / 255.f + .5f);
        pScanline[2] = (uint8_t)(pScanline[2] * pScanline[3] / 255.f + .5f);
        pScanline += 4;
      }
    }
  }
  CGContextRef ctx = createContextWithBitmap(pBitmap1);
  CGImageRef image = CGBitmapContextCreateImage(ctx);
  CGContextDrawImage(m_context, rect, image);
  CGImageRelease(image);
  CGContextRelease(ctx);
  if (pBitmap1 != pBitmap) {
    delete pBitmap1;
  }
  RestoreState(FALSE);
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars,
                                               const FXTEXT_CHARPOS* pCharPos,
                                               CFX_Font* pFont,
                                               CFX_FontCache* pCache,
                                               const CFX_Matrix* pGlyphMatrix,
                                               const CFX_Matrix* pObject2Device,
                                               FX_FLOAT font_size,
                                               uint32_t argb,
                                               int alpha_flag,
                                               void* pIccTransform) {
  if (nChars == 0) {
    return TRUE;
  }
  CQuartz2D& quartz2d =
      static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
          ->m_quartz2d;
  if (!pFont->GetPlatformFont()) {
    if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
      return FALSE;
    }
    pFont->SetPlatformFont(
        quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize()));
    if (!pFont->GetPlatformFont()) {
      return FALSE;
    }
  }
  CFX_FixedBufGrow<uint16_t, 32> glyph_indices(nChars);
  CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
  for (int i = 0; i < nChars; i++) {
    glyph_indices[i] = pCharPos[i].m_ExtGID;
    glyph_positions[i].x = pCharPos[i].m_OriginX;
    glyph_positions[i].y = pCharPos[i].m_OriginY;
  }
  CFX_Matrix text_matrix;
  if (pObject2Device) {
    text_matrix.Concat(*pObject2Device);
  }
  CGAffineTransform matrix_cg =
      CGAffineTransformMake(text_matrix.a, text_matrix.b, text_matrix.c,
                            text_matrix.d, text_matrix.e, text_matrix.f);
  matrix_cg = CGAffineTransformConcat(matrix_cg, m_foxitDevice2User);
  CGContextSetTextMatrix(m_context, matrix_cg);
  CGContextSetFont(m_context, (CGFontRef)pFont->GetPlatformFont());
  CGContextSetFontSize(m_context, FXSYS_fabs(font_size));
  int32_t a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f,
                           a / 255.f);
  SaveState();
  if (pGlyphMatrix) {
    CGPoint origin = CGPointMake(glyph_positions[0].x, glyph_positions[0].y);
    origin = CGPointApplyAffineTransform(origin, matrix_cg);
    CGContextTranslateCTM(m_context, origin.x, origin.y);
    CGAffineTransform glyph_matrix = CGAffineTransformMake(
        pGlyphMatrix->a, pGlyphMatrix->b, pGlyphMatrix->c, pGlyphMatrix->d,
        pGlyphMatrix->e, pGlyphMatrix->f);
    if (m_foxitDevice2User.d < 0) {
      glyph_matrix = CGAffineTransformInvert(glyph_matrix);
    }
    CGContextConcatCTM(m_context, glyph_matrix);
    CGContextTranslateCTM(m_context, -origin.x, -origin.y);
  }
  CGContextShowGlyphsAtPositions(m_context, (CGGlyph*)glyph_indices,
                                 glyph_positions, nChars);
  RestoreState(FALSE);
  return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars,
                                               const FXTEXT_CHARPOS* pCharPos,
                                               CFX_Font* pFont,
                                               CFX_FontCache* pCache,
                                               const CFX_Matrix* pObject2Device,
                                               FX_FLOAT font_size,
                                               uint32_t color,
                                               int alpha_flag,
                                               void* pIccTransform) {
  if (NULL == pFont || NULL == m_context)
    return FALSE;
  FX_BOOL bBold = pFont->IsBold();
  if (!bBold && pFont->GetSubstFont() &&
      pFont->GetSubstFont()->m_Weight >= 500 &&
      pFont->GetSubstFont()->m_Weight <= 600) {
    return FALSE;
  }
  SaveState();
  CGContextSetTextDrawingMode(m_context, kCGTextFillClip);
  FX_BOOL ret = FALSE;
  int32_t i = 0;
  while (i < nChars) {
    if (pCharPos[i].m_bGlyphAdjust || font_size < 0) {
      if (i > 0) {
        ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device,
                             font_size, color, alpha_flag, pIccTransform);
        if (!ret) {
          RestoreState(FALSE);
          return ret;
        }
      }
      const FXTEXT_CHARPOS* char_pos = pCharPos + i;
      CFX_Matrix glphy_matrix;
      if (font_size < 0) {
        glphy_matrix.Concat(-1, 0, 0, -1, 0, 0);
      }
      if (char_pos->m_bGlyphAdjust) {
        glphy_matrix.Concat(
            char_pos->m_AdjustMatrix[0], char_pos->m_AdjustMatrix[1],
            char_pos->m_AdjustMatrix[2], char_pos->m_AdjustMatrix[3], 0, 0);
      }
      ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix,
                           pObject2Device, font_size, color, alpha_flag,
                           pIccTransform);
      if (!ret) {
        RestoreState(FALSE);
        return ret;
      }
      i++;
      pCharPos += i;
      nChars -= i;
      i = 0;
    } else {
      i++;
    }
  }
  if (i > 0) {
    ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device,
                         font_size, color, alpha_flag, pIccTransform);
  }
  RestoreState(FALSE);
  return ret;
}
void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState,
                                           FX_ARGB argb,
                                           FX_FLOAT lineWidth) {
  if (NULL == graphState) {
    return;
  }
  CGContextSetLineWidth(m_context, lineWidth);
  CGLineCap cap;
  switch (graphState->m_LineCap) {
    case CFX_GraphStateData::LineCapRound: {
      cap = kCGLineCapRound;
      break;
    }
    case CFX_GraphStateData::LineCapSquare: {
      cap = kCGLineCapSquare;
      break;
    }
    case CFX_GraphStateData::LineCapButt:
    default: { cap = kCGLineCapButt; }
  }
  CGContextSetLineCap(m_context, cap);
  CGLineJoin join;
  switch (graphState->m_LineJoin) {
    case CFX_GraphStateData::LineJoinRound: {
      join = kCGLineJoinRound;
      break;
    }
    case CFX_GraphStateData::LineJoinBevel: {
      join = kCGLineJoinBevel;
      break;
    }
    case CFX_GraphStateData::LineJoinMiter:
    default: { join = kCGLineJoinMiter; }
  }
  CGContextSetLineJoin(m_context, join);
  if (graphState->m_DashCount) {
#if CGFLOAT_IS_DOUBLE
    CGFloat* dashArray = new CGFloat[graphState->m_DashCount];
    for (int index = 0; index < graphState->m_DashCount; ++index) {
      dashArray[index] = graphState->m_DashArray[index];
    }
#else
    CGFloat* dashArray = (CGFloat*)graphState->m_DashArray;
#endif
    CGContextSetLineDash(m_context, graphState->m_DashPhase, dashArray,
                         graphState->m_DashCount);
#if CGFLOAT_IS_DOUBLE
    delete[] dashArray;
#endif
  }
  int32_t a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  CGContextSetRGBStrokeColor(m_context, r / 255.f, g / 255.f, b / 255.f,
                             a / 255.f);
}
void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb) {
  int32_t a, r, g, b;
  ArgbDecode(argb, a, r, g, b);
  CGContextSetRGBFillColor(m_context, r / 255.f, g / 255.f, b / 255.f,
                           a / 255.f);
}
void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData) {
  int32_t count = pathData->GetPointCount();
  FX_PATHPOINT* points = pathData->GetPoints();
  CGContextBeginPath(m_context);
  for (int32_t i = 0; i < count; i++) {
    switch (points[i].m_Flag & FXPT_TYPE) {
      case FXPT_MOVETO:
        CGContextMoveToPoint(m_context, points[i].m_PointX, points[i].m_PointY);
        break;
      case FXPT_LINETO:
        CGContextAddLineToPoint(m_context, points[i].m_PointX,
                                points[i].m_PointY);
        break;
      case FXPT_BEZIERTO: {
        CGContextAddCurveToPoint(m_context, points[i].m_PointX,
                                 points[i].m_PointY, points[i + 1].m_PointX,
                                 points[i + 1].m_PointY, points[i + 2].m_PointX,
                                 points[i + 2].m_PointY);
        i += 2;
      }
    }
    if (points[i].m_Flag & FXPT_CLOSEFIGURE) {
      CGContextClosePath(m_context);
    }
  }
}
void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left,
                                                  int dest_top,
                                                  int dest_width,
                                                  int dest_height,
                                                  CGRect* rect) {
  int flip_y = m_foxitDevice2User.d * dest_height < 0 ? 1 : -1;
  int flip_x = m_foxitDevice2User.a * dest_width > 0 ? 1 : -1;
  if (flip_y < 0 || flip_x < 0) {
    if (dest_height < 0) {
      dest_height = -dest_height;
      dest_top -= dest_height;
    }
    CGRect rt = CGRectApplyAffineTransform(
        CGRectMake(dest_left, dest_top, dest_width, dest_height),
        m_foxitDevice2User);
    CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f,
            offset_y = (rt.origin.y) + rt.size.height / 2.f;
    CGAffineTransform transform = CGAffineTransformIdentity;
    transform = CGAffineTransformConcat(
        transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y));
    transform = CGAffineTransformConcat(
        transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0));
    transform = CGAffineTransformConcat(
        transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y));
    CGContextConcatCTM(m_context, transform);
    if (rect) {
      *rect = CGRectApplyAffineTransform(*rect, transform);
    }
  }
}
void CFX_QuartzDeviceDriver::ClearDriver() {
  if (NULL == m_context) {
    return;
  }
  for (int i = 0; i < m_saveCount; ++i) {
    CGContextRestoreGState(m_context);
  }
  m_saveCount = 0;
  if (m_context) {
    CGContextRelease(m_context);
  }
}
CFX_QuartzDevice::CFX_QuartzDevice() {
  m_bOwnedBitmap = FALSE;
  m_pContext = NULL;
}
CFX_QuartzDevice::~CFX_QuartzDevice() {
  if (m_pContext) {
    CGContextRelease(m_pContext);
  }
  if (m_bOwnedBitmap) {
    delete GetBitmap();
  }
}
CGContextRef CFX_QuartzDevice::GetContext() {
  return m_pContext;
}
FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, int32_t nDeviceClass) {
  if (m_pContext) {
    CGContextRelease(m_pContext);
  }
  m_pContext = context;
  CGContextRetain(m_pContext);
  IFX_RenderDeviceDriver* pDriver =
      new CFX_QuartzDeviceDriver(m_pContext, nDeviceClass);
  SetDeviceDriver(pDriver);
  return TRUE;
}
FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) {
  SetBitmap(pBitmap);
  m_pContext = createContextWithBitmap(pBitmap);
  if (NULL == m_pContext) {
    return FALSE;
  }
  IFX_RenderDeviceDriver* pDriver =
      new CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY);
  SetDeviceDriver(pDriver);
  return TRUE;
}
FX_BOOL CFX_QuartzDevice::Create(int32_t width,
                                 int32_t height,
                                 FXDIB_Format format) {
  if ((uint8_t)format < 32) {
    return FALSE;
  }
  CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
  if (!pBitmap->Create(width, height, format)) {
    delete pBitmap;
    return FALSE;
  }
  m_bOwnedBitmap = TRUE;
  return Attach(pBitmap);
}
#endif  // _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
