// 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"
#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
#include "apple_int.h"
#include "../../../include/fxge/fx_ge_apple.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_ && (!defined(_FPDFAPI_MINI_)))
void CFX_AggDeviceDriver::InitPlatform()
{
    CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
    m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap);
}
void CFX_AggDeviceDriver::DestroyPlatform()
{
    CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
    if (m_pPlatformGraphics) {
        quartz2d.destroyGraphics(m_pPlatformGraphics);
        m_pPlatformGraphics = NULL;
    }
}
void CFX_FaceCache::InitPlatform() {}
void CFX_FaceCache::DestroyPlatform() {}
CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font *				pFont,
        FX_DWORD					glyph_index,
        const CFX_AffineMatrix *	pMatrix,
        int						dest_width,
        int						anti_alias)
{
    return NULL;
}
static FX_BOOL _CGDrawGlyphRun(CGContextRef               pContext,
                               int                        nChars,
                               const FXTEXT_CHARPOS*      pCharPos,
                               CFX_Font*                  pFont,
                               CFX_FontCache*             pCache,
                               const CFX_AffineMatrix*    pObject2Device,
                               FX_FLOAT                   font_size,
                               FX_DWORD                   argb,
                               int                        alpha_flag,
                               void*                      pIccTransform)
{
    if (nChars == 0) {
        return TRUE;
    }
    CFX_AffineMatrix new_matrix;
    FX_BOOL bNegSize = font_size < 0;
    if (bNegSize) {
        font_size = -font_size;
    }
    FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY;
    new_matrix.Transform(ori_x, ori_y);
    if (pObject2Device) {
        new_matrix.Concat(*pObject2Device);
    }
    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;
        if (bNegSize) {
            glyph_positions[i].x = -pCharPos[i].m_OriginX;
        } else {
            glyph_positions[i].x = pCharPos[i].m_OriginX;
        }
        glyph_positions[i].y = pCharPos[i].m_OriginY;
    }
    if (bNegSize) {
        new_matrix.a = -new_matrix.a;
    } else {
        new_matrix.b = -new_matrix.b;
        new_matrix.d = -new_matrix.d;
    }
    quartz2d.setGraphicsTextMatrix(pContext, &new_matrix);
    return quartz2d.drawGraphicsString(pContext,
                                       pFont->m_pPlatformFont,
                                       font_size,
                                       glyph_indices,
                                       glyph_positions,
                                       nChars,
                                       argb,
                                       NULL);
}
static void _DoNothing(void *info, const void *data, size_t size) {}
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int						 nChars,
        const FXTEXT_CHARPOS *	 pCharPos,
        CFX_Font *				 pFont,
        CFX_FontCache *			 pCache,
        const CFX_AffineMatrix * pObject2Device,
        FX_FLOAT				 font_size,
        FX_DWORD				 argb,
        int alpha_flag, void* pIccTransform)
{
    if (!pFont) {
        return FALSE;
    }
    FX_BOOL bBold = pFont->IsBold();
    if (!bBold && pFont->GetSubstFont() &&
            pFont->GetSubstFont()->m_Weight >= 500 &&
            pFont->GetSubstFont()->m_Weight <= 600) {
        return FALSE;
    }
    for (int i = 0; i < nChars; i ++) {
        if (pCharPos[i].m_bGlyphAdjust) {
            return FALSE;
        }
    }
    CGContextRef ctx = CGContextRef(m_pPlatformGraphics);
    if (NULL == ctx) {
        return FALSE;
    }
    CGContextSaveGState(ctx);
    CGContextSetTextDrawingMode(ctx, kCGTextFillClip);
    CGRect rect_cg;
    CGImageRef pImageCG = NULL;
    if (m_pClipRgn) {
        rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height());
        const CFX_DIBitmap*	pClipMask = m_pClipRgn->GetMask();
        if (pClipMask) {
            CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL,
                    pClipMask->GetBuffer(),
                    pClipMask->GetPitch() * pClipMask->GetHeight(),
                    _DoNothing);
            CGFloat decode_f[2] = {255.f, 0.f};
            pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(),
                                         8, 8, pClipMask->GetPitch(), pClipMaskDataProvider,
                                         decode_f, FALSE);
            CGDataProviderRelease(pClipMaskDataProvider);
        }
    } else {
        rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
    }
    rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg);
    if (pImageCG) {
        CGContextClipToMask(ctx, rect_cg, pImageCG);
    } else {
        CGContextClipToRect(ctx, rect_cg);
    }
    FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform);
    if (pImageCG) {
        CGImageRelease(pImageCG);
    }
    CGContextRestoreGState(ctx);
    return ret;
}
void CFX_Font::ReleasePlatformResource()
{
    if (m_pPlatformFont) {
        CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
        quartz2d.DestroyFont(m_pPlatformFont);
        m_pPlatformFont = NULL;
    }
}
#endif
#endif
