// 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/fx_ext.h"

#ifndef _SKIA_SUPPORT_
#include "core/fxge/agg/fx_agg_driver.h"
#endif

#include "core/fxcrt/fx_memory.h"
#include "core/fxge/cfx_gemodule.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/dib_int.h"
#include "core/fxge/fx_freetype.h"
#include "core/fxge/ge/fx_text_int.h"
#include "third_party/base/ptr_util.h"

#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
#include "core/fxge/apple/apple_int.h"
#include "core/fxge/apple/cfx_quartzdevice.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 nullptr;
  }
  CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
  switch (pBitmap->GetFormat()) {
    case FXDIB_Rgb32:
      bmpInfo |= kCGImageAlphaNoneSkipFirst;
      break;
    case FXDIB_Argb:
    default:
      return nullptr;
  }
  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(
      nullptr, pFontData, (size_t)dwFontSize, nullptr);
  if (!pDataProvider)
    return nullptr;

  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 nullptr;
  }
  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) const {
  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(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 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::FillRectWithBlend(const FX_RECT* rect,
                                                  FX_ARGB fillArgb,
                                                  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 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) {
  if (FXDC_PRINTER == m_deviceClass || bitmap->GetBPP() < 32 ||
      !(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 (!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())
    return TRUE;

  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) {
  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 = nullptr;
  if (pBitmap->IsAlphaMask()) {
    if (pBitmap->GetBuffer()) {
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    } else {
      pBitmap1 = pBitmap->Clone();
    }
    if (!pBitmap1) {
      RestoreState(false);
      return FALSE;
    }
    CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
        nullptr, pBitmap1->GetBuffer(),
        pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr);
    CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
    CGImageRef pImage = CGImageCreate(
        pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(),
        pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo,
        pBitmapProvider, nullptr, 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 (!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 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, nullptr);
  CFX_DIBitmap* pBitmap1 = nullptr;
  if (pBitmap->IsAlphaMask()) {
    if (pBitmap->GetBuffer())
      pBitmap1 = (CFX_DIBitmap*)pBitmap;
    else
      pBitmap1 = pBitmap->Clone();
    if (!pBitmap1) {
      RestoreState(false);
      return FALSE;
    }
    CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(
        nullptr, pBitmap1->GetBuffer(),
        pBitmap1->GetPitch() * pBitmap1->GetHeight(), nullptr);
    CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
    CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
    CGImageRef pImage = CGImageCreate(
        pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(),
        pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo,
        pBitmapProvider, nullptr, 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 (!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::StartDIBits(const CFX_DIBSource* pBitmap,
                                            int bitmap_alpha,
                                            uint32_t color,
                                            const CFX_Matrix* pMatrix,
                                            uint32_t flags,
                                            void*& handle,
                                            int blend_type) {
  return FALSE;
}

FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlyphRun(
    int nChars,
    const FXTEXT_CHARPOS* pCharPos,
    CFX_Font* pFont,
    const CFX_Matrix* pGlyphMatrix,
    const CFX_Matrix* pObject2Device,
    FX_FLOAT font_size,
    uint32_t argb) {
  if (nChars == 0)
    return TRUE;

  CQuartz2D& quartz2d =
      static_cast<CApplePlatform*>(CFX_GEModule::Get()->GetPlatformData())
          ->m_quartz2d;
  if (!pFont->GetPlatformFont()) {
    if (pFont->GetPsName() == "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,
                                               const CFX_Matrix* pObject2Device,
                                               FX_FLOAT font_size,
                                               uint32_t color) {
  if (!pFont || !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_DrawGlyphRun(i, pCharPos, pFont, nullptr, pObject2Device,
                              font_size, color);
        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_DrawGlyphRun(1, char_pos, pFont, &glphy_matrix, pObject2Device,
                            font_size, color);
      if (!ret) {
        RestoreState(false);
        return ret;
      }
      i++;
      pCharPos += i;
      nChars -= i;
      i = 0;
    } else {
      i++;
    }
  }
  if (i > 0) {
    ret = CG_DrawGlyphRun(i, pCharPos, pFont, nullptr, pObject2Device,
                          font_size, color);
  }
  RestoreState(false);
  return ret;
}

void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState,
                                           FX_ARGB argb,
                                           FX_FLOAT lineWidth) {
  if (!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)
    return;

  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 (!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 = nullptr;
}
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);
  SetDeviceDriver(
      pdfium::MakeUnique<CFX_QuartzDeviceDriver>(m_pContext, nDeviceClass));
  return TRUE;
}

FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap) {
  SetBitmap(pBitmap);
  m_pContext = createContextWithBitmap(pBitmap);
  if (!m_pContext)
    return FALSE;

  SetDeviceDriver(
      pdfium::MakeUnique<CFX_QuartzDeviceDriver>(m_pContext, FXDC_DISPLAY));
  return TRUE;
}

FX_BOOL CFX_QuartzDevice::Create(int32_t width,
                                 int32_t height,
                                 FXDIB_Format format) {
  if ((uint8_t)format < 32) {
    return FALSE;
  }
  std::unique_ptr<CFX_DIBitmap> pBitmap(new CFX_DIBitmap);
  if (!pBitmap->Create(width, height, format))
    return FALSE;
  m_bOwnedBitmap = TRUE;
  return Attach(pBitmap.release());
}
#endif  // _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
