// 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_ge.h"
#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
#include "../ge/text_int.h"
#include "../dib/dib_int.h"
#include "../agg/include/fx_agg_driver.h"
#include "../../../include/fxge/fx_freetype.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(FX_LPCBYTE 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 ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)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 ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)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 ++) {
            FX_LPBYTE pScanline = (FX_LPBYTE)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
