// 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 "../../../include/fxcrt/fx_ext.h"
#include "../../../include/fxge/fx_freetype.h"
#include "../../../include/fxge/fx_ge.h"
#include "../agg/include/fx_agg_driver.h"
#include "../dib/dib_int.h"
#include "../ge/text_int.h"

#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
#include "apple_int.h"
#include "../../../include/fxge/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, FX_DWORD 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_AffineMatrix* 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,
                                      FX_WORD*              glyphIndices,
                                      CGPoint*           glyphPositions,
                                      int32_t              charsCount,
                                      FX_ARGB               argb,
                                      CFX_AffineMatrix*     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];
    if (!glyphPositionsCG) {
        return FALSE;
    }
    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;
    _context		= context;
    _deviceClass	= deviceClass;
    CGContextRetain(_context);
    CGRect r = CGContextGetClipBoundingBox(context);
    _width	= FXSYS_round(r.size.width);
    _height	= FXSYS_round(r.size.height);
    _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE |
                  FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE |
                  FXRC_BIT_MASK | FXRC_ALPHA_MASK;
    if (_deviceClass != FXDC_DISPLAY) {
    } else {
        CGImageRef image = CGBitmapContextCreateImage(_context);
        if (image) {
            _renderCaps |= FXRC_GET_BITS;
            _width = CGImageGetWidth(image);
            _height = CGImageGetHeight(image);
            CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image);
            if (kCGImageAlphaPremultipliedFirst == alphaInfo ||
                    kCGImageAlphaPremultipliedLast == alphaInfo ||
                    kCGImageAlphaOnly == alphaInfo) {
                _renderCaps |= FXRC_ALPHA_OUTPUT;
            }
        }
        CGImageRelease(image);
    }
    CGAffineTransform ctm = CGContextGetCTM(_context);
    CGContextSaveGState(_context);
    m_saveCount++;
    if (ctm.d >= 0) {
        CGFloat offset_x, offset_y;
        offset_x = ctm.tx;
        offset_y = ctm.ty;
        CGContextTranslateCTM(_context, -offset_x, -offset_y);
        CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y));
    }
    _foxitDevice2User = CGAffineTransformIdentity;
    _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User);
}
CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver()
{
    CGContextRestoreGState(_context);
    m_saveCount--;
    for (int i = 0; i < m_saveCount; ++i) {
        CGContextRestoreGState(_context);
    }
    if (_context) {
        CGContextRelease(_context);
    }
}
int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID)
{
    switch (capsID) {
        case FXDC_DEVICE_CLASS: {
                return _deviceClass;
            }
        case FXDC_PIXEL_WIDTH: {
                return _width;
            }
        case FXDC_PIXEL_HEIGHT: {
                return _height;
            }
        case FXDC_BITS_PIXEL: {
                return 32;
            }
        case FXDC_RENDER_CAPS: {
                return _renderCaps;
            }
        default: {
                return 0;
            }
    }
}
CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const
{
    CGAffineTransform ctm = CGContextGetCTM(_context);
    return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
}
void CFX_QuartzDeviceDriver::SaveState()
{
    CGContextSaveGState(_context);
    m_saveCount++;
}
void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved )
{
    CGContextRestoreGState(_context);
    if (isKeepSaved) {
        CGContextSaveGState(_context);
    } else {
        m_saveCount--;
    }
}
FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData*    pathData,
        const CFX_AffineMatrix*   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, _foxitDevice2User);
    CGContextConcatCTM(_context, m);
    setPathToContext(pathData);
    RestoreState(FALSE);
    if ((fillMode & 3) == FXFILL_WINDING) {
        CGContextClip(_context);
    } else {
        CGContextEOClip(_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_AffineMatrix*     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, _foxitDevice2User);
    CGContextConcatCTM(_context, m);
    FX_FLOAT lineWidth = getLineWidth(graphState, m);
    setStrokeInfo(graphState, 0xFF000000, lineWidth);
    setPathToContext(pathData);
    CGContextReplacePathWithStrokedPath(_context);
    RestoreState(FALSE);
    CGContextClip(_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_AffineMatrix*       matrix,
        const CFX_GraphStateData*     graphState,
        FX_DWORD                      fillArgb,
        FX_DWORD                      strokeArgb,
        int                           fillMode,
        int                           alpha_flag,
        void*                         pIccTransform,
        int							blend_type
                                        )
{
    SaveState();
    CGBlendMode mode = GetCGBlendMode(blend_type);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, mode);
    }
    CGAffineTransform m = CGAffineTransformIdentity;
    if (matrix) {
        m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
    }
    m = CGAffineTransformConcat(m, _foxitDevice2User);
    CGContextConcatCTM(_context, m);
    int pathMode = 0;
    if (graphState && strokeArgb) {
        CGContextSetMiterLimit(_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(_context, false);
    }
    if (pathMode == 4) {
        CGContextStrokePath(_context);
    } else if (pathMode == 1) {
        CGContextFillPath(_context);
    } else if (pathMode == 2) {
        CGContextEOFillPath(_context);
    } else if (pathMode == 5) {
        CGContextDrawPath(_context, kCGPathFillStroke);
    } else if (pathMode == 6) {
        CGContextDrawPath(_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(_context, mode);
    }
    CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
    CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
    int32_t a, r, g, b;
    ArgbDecode(fillArgb, a, r, g, b);
    CGContextSetRGBFillColor(_context,
                             r / 255.f,
                             g / 255.f,
                             b / 255.f,
                             a / 255.f);
    CGContextFillRect(_context, rect_usr);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, kCGBlendModeNormal);
    }
    return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT           x1,
        FX_FLOAT              y1,
        FX_FLOAT              x2,
        FX_FLOAT              y2,
        FX_DWORD              argb,
        int                   alphaFlag       ,
        void*                 iccTransform    ,
        int					blend_type )
{
    CGBlendMode mode = GetCGBlendMode(blend_type);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, mode);
    }
    CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User);
    x1 = pt.x;
    y1 = pt.y;
    pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
    x2 = pt.x;
    y2 = pt.y;
    int32_t a, r, g, b;
    ArgbDecode(argb, a, r, g, b);
    CGContextSetRGBStrokeColor(_context,
                               r / 255.f,
                               g / 255.f,
                               b / 255.f,
                               a / 255.f);
    CGContextMoveToPoint(_context, x1, y1);
    CGContextAddLineToPoint(_context, x2, y2);
    CGContextStrokePath(_context);
    if (mode != kCGBlendModeNormal) {
        CGContextSetBlendMode(_context, kCGBlendModeNormal);
    }
    return TRUE;
}
FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect)
{
    CGRect r = CGContextGetClipBoundingBox(_context);
    r = CGRectApplyAffineTransform(r, _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 == _deviceClass) {
        return FALSE;
    }
    if (bitmap->GetBPP() < 32) {
        return FALSE;
    }
    if (!(_renderCaps | FXRC_GET_BITS)) {
        return FALSE;
    }
    CGPoint pt = CGPointMake(left, top);
    pt = CGPointApplyAffineTransform(pt, _foxitDevice2User);
    CGAffineTransform ctm = CGContextGetCTM(_context);
    pt.x *= FXSYS_fabs(ctm.a);
    pt.y *= FXSYS_fabs(ctm.d);
    CGImageRef image = CGBitmapContextCreateImage(_context);
    if (NULL == image) {
        return FALSE;
    }
    CGFloat width	= (CGFloat) bitmap->GetWidth();
    CGFloat height	= (CGFloat) bitmap->GetHeight();
    if (width + pt.x > _width) {
        width -= (width + pt.x - _width);
    }
    if (height + pt.y > _height) {
        height -= (height + pt.y - _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(_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, _foxitDevice2User);
    CGContextBeginPath(_context);
    CGContextAddRect(_context, rect_usr);
    CGContextClip(_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(_context, rect_usr, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_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(_context, (CGBlendMode)blend_mode);
    CGContextDrawImage(_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,
        FX_DWORD                    flags,
        int                         alphaFlag	   ,
        void*                       iccTransform ,
        int							blend_type)
{
    SaveState();
    if (clipRect) {
        CGContextBeginPath(_context);
        CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
        rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
        CGContextAddRect(_context, rect_clip);
        CGContextClip(_context);
    }
    CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
    rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
    if (FXDIB_BICUBIC_INTERPOL == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
    } else if (FXDIB_DOWNSAMPLE == flags) {
        CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
    } else {
        CGContextSetInterpolationQuality(_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(_context, rect, pImage);
        CGContextSetRGBFillColor(_context,
                                 FXARGB_R(argb) / 255.f,
                                 FXARGB_G(argb) / 255.f,
                                 FXARGB_B(argb) / 255.f,
                                 FXARGB_A(argb) / 255.f);
        CGContextFillRect(_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(_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_AffineMatrix*    pGlyphMatrix,
        const CFX_AffineMatrix*    pObject2Device,
        FX_FLOAT                   font_size,
        FX_DWORD                   argb,
        int                        alpha_flag,
        void*                      pIccTransform)
{
    if (nChars == 0) {
        return TRUE;
    }
    CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
    if (!pFont->m_pPlatformFont) {
        if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
            return FALSE;
        }
        pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
        if (NULL == pFont->m_pPlatformFont) {
            return FALSE;
        }
    }
    CFX_FixedBufGrow<FX_WORD, 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_AffineMatrix 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, _foxitDevice2User);
    CGContextSetTextMatrix(_context, matrix_cg);
    CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont);
    CGContextSetFontSize(_context, FXSYS_fabs(font_size));
    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);
    SaveState();
    if (pGlyphMatrix) {
        CGPoint origin = CGPointMake( glyph_positions[0].x,  glyph_positions[0].y);
        origin = CGPointApplyAffineTransform(origin, matrix_cg);
        CGContextTranslateCTM(_context, origin.x, origin.y);
        CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a,
                                         pGlyphMatrix->b,
                                         pGlyphMatrix->c,
                                         pGlyphMatrix->d,
                                         pGlyphMatrix->e,
                                         pGlyphMatrix->f);
        if (_foxitDevice2User.d < 0) {
            glyph_matrix = CGAffineTransformInvert(glyph_matrix);
        }
        CGContextConcatCTM(_context, glyph_matrix);
        CGContextTranslateCTM(_context, -origin.x, -origin.y);
    }
    CGContextShowGlyphsAtPositions(_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_AffineMatrix*  pObject2Device,
        FX_FLOAT                 font_size,
        FX_DWORD                 color,
        int                      alpha_flag       ,
        void*                    pIccTransform)
{
    if (NULL == pFont || NULL == _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(_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_AffineMatrix 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(_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(_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(_context, join);
    if (graphState->m_DashCount) {
#if CGFLOAT_IS_DOUBLE
        CGFloat* dashArray = new CGFloat[graphState->m_DashCount];
        if (!dashArray) {
            return;
        }
        for (int index = 0; index < graphState->m_DashCount; ++index) {
            dashArray[index] = graphState->m_DashArray[index];
        }
#else
        CGFloat* dashArray = (CGFloat*)graphState->m_DashArray;
#endif
        CGContextSetLineDash(_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(_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(_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(_context);
    for (int32_t i = 0; i < count; i ++) {
        switch (points[i].m_Flag & FXPT_TYPE) {
            case FXPT_MOVETO:
                CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY);
                break;
            case FXPT_LINETO:
                CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY);
                break;
            case FXPT_BEZIERTO: {
                    CGContextAddCurveToPoint(_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(_context);
        }
    }
}
void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height,
        CGRect* rect )
{
    int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1;
    int flip_x = _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), _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(_context, transform);
        if (rect) {
            *rect = CGRectApplyAffineTransform(*rect, transform);
        }
    }
}
void CFX_QuartzDeviceDriver::ClearDriver()
{
    if (NULL == _context) {
        return;
    }
    for (int i = 0; i < m_saveCount; ++i) {
        CGContextRestoreGState(_context);
    }
    m_saveCount = 0;
    if (_context) {
        CGContextRelease(_context);
    }
}
CFX_QuartzDevice::CFX_QuartzDevice()
{
    m_bOwnedBitmap = FALSE;
    m_pContext = NULL;
}
CFX_QuartzDevice::~CFX_QuartzDevice()
{
    if (m_pContext) {
        CGContextRelease(m_pContext);
    }
    if (GetBitmap() && 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_
