Home | History | Annotate | Download | only in apple
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../../include/fxcrt/fx_ext.h"
      8 #include "../../../include/fxge/fx_ge.h"
      9 #if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
     10 #include "apple_int.h"
     11 #include "../../../include/fxge/fx_ge_apple.h"
     12 #include "../agg/include/fxfx_agg_clip_liang_barsky.h"
     13 #include "../ge/text_int.h"
     14 #include "../dib/dib_int.h"
     15 #include "../agg/include/fx_agg_driver.h"
     16 #include "../../../include/fxge/fx_freetype.h"
     17 #if (_FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
     18 void CFX_AggDeviceDriver::InitPlatform()
     19 {
     20     CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
     21     m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap);
     22 }
     23 void CFX_AggDeviceDriver::DestroyPlatform()
     24 {
     25     CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
     26     if (m_pPlatformGraphics) {
     27         quartz2d.destroyGraphics(m_pPlatformGraphics);
     28         m_pPlatformGraphics = NULL;
     29     }
     30 }
     31 void CFX_FaceCache::InitPlatform() {}
     32 void CFX_FaceCache::DestroyPlatform() {}
     33 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font *				pFont,
     34         FX_DWORD					glyph_index,
     35         const CFX_AffineMatrix *	pMatrix,
     36         int						dest_width,
     37         int						anti_alias)
     38 {
     39     return NULL;
     40 }
     41 static FX_BOOL _CGDrawGlyphRun(CGContextRef               pContext,
     42                                int                        nChars,
     43                                const FXTEXT_CHARPOS*      pCharPos,
     44                                CFX_Font*                  pFont,
     45                                CFX_FontCache*             pCache,
     46                                const CFX_AffineMatrix*    pObject2Device,
     47                                FX_FLOAT                   font_size,
     48                                FX_DWORD                   argb,
     49                                int                        alpha_flag,
     50                                void*                      pIccTransform)
     51 {
     52     if (nChars == 0) {
     53         return TRUE;
     54     }
     55     CFX_AffineMatrix new_matrix;
     56     FX_BOOL bNegSize = font_size < 0;
     57     if (bNegSize) {
     58         font_size = -font_size;
     59     }
     60     FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY;
     61     new_matrix.Transform(ori_x, ori_y);
     62     if (pObject2Device) {
     63         new_matrix.Concat(*pObject2Device);
     64     }
     65     CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
     66     if (!pFont->m_pPlatformFont) {
     67         if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
     68             return FALSE;
     69         }
     70         pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
     71         if (NULL == pFont->m_pPlatformFont) {
     72             return FALSE;
     73         }
     74     }
     75     CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
     76     CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
     77     for (int i = 0; i < nChars; i++ ) {
     78         glyph_indices[i] = pCharPos[i].m_ExtGID;
     79         if (bNegSize) {
     80             glyph_positions[i].x = -pCharPos[i].m_OriginX;
     81         } else {
     82             glyph_positions[i].x = pCharPos[i].m_OriginX;
     83         }
     84         glyph_positions[i].y = pCharPos[i].m_OriginY;
     85     }
     86     if (bNegSize) {
     87         new_matrix.a = -new_matrix.a;
     88     } else {
     89         new_matrix.b = -new_matrix.b;
     90         new_matrix.d = -new_matrix.d;
     91     }
     92     quartz2d.setGraphicsTextMatrix(pContext, &new_matrix);
     93     return quartz2d.drawGraphicsString(pContext,
     94                                        pFont->m_pPlatformFont,
     95                                        font_size,
     96                                        glyph_indices,
     97                                        glyph_positions,
     98                                        nChars,
     99                                        argb,
    100                                        NULL);
    101 }
    102 static void _DoNothing(void *info, const void *data, size_t size) {}
    103 FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int						 nChars,
    104         const FXTEXT_CHARPOS *	 pCharPos,
    105         CFX_Font *				 pFont,
    106         CFX_FontCache *			 pCache,
    107         const CFX_AffineMatrix * pObject2Device,
    108         FX_FLOAT				 font_size,
    109         FX_DWORD				 argb,
    110         int alpha_flag, void* pIccTransform)
    111 {
    112     if (!pFont) {
    113         return FALSE;
    114     }
    115     FX_BOOL bBold = pFont->IsBold();
    116     if (!bBold && pFont->GetSubstFont() &&
    117             pFont->GetSubstFont()->m_Weight >= 500 &&
    118             pFont->GetSubstFont()->m_Weight <= 600) {
    119         return FALSE;
    120     }
    121     for (int i = 0; i < nChars; i ++) {
    122         if (pCharPos[i].m_bGlyphAdjust) {
    123             return FALSE;
    124         }
    125     }
    126     CGContextRef ctx = CGContextRef(m_pPlatformGraphics);
    127     if (NULL == ctx) {
    128         return FALSE;
    129     }
    130     CGContextSaveGState(ctx);
    131     CGContextSetTextDrawingMode(ctx, kCGTextFillClip);
    132     CGRect rect_cg;
    133     CGImageRef pImageCG = NULL;
    134     if (m_pClipRgn) {
    135         rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height());
    136         const CFX_DIBitmap*	pClipMask = m_pClipRgn->GetMask();
    137         if (pClipMask) {
    138             CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL,
    139                     pClipMask->GetBuffer(),
    140                     pClipMask->GetPitch() * pClipMask->GetHeight(),
    141                     _DoNothing);
    142             CGFloat decode_f[2] = {255.f, 0.f};
    143             pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(),
    144                                          8, 8, pClipMask->GetPitch(), pClipMaskDataProvider,
    145                                          decode_f, FALSE);
    146             CGDataProviderRelease(pClipMaskDataProvider);
    147         }
    148     } else {
    149         rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
    150     }
    151     rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg);
    152     if (pImageCG) {
    153         CGContextClipToMask(ctx, rect_cg, pImageCG);
    154     } else {
    155         CGContextClipToRect(ctx, rect_cg);
    156     }
    157     FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform);
    158     if (pImageCG) {
    159         CGImageRelease(pImageCG);
    160     }
    161     CGContextRestoreGState(ctx);
    162     return ret;
    163 }
    164 void CFX_Font::ReleasePlatformResource()
    165 {
    166     if (m_pPlatformFont) {
    167         CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
    168         quartz2d.DestroyFont(m_pPlatformFont);
    169         m_pPlatformFont = NULL;
    170     }
    171 }
    172 #endif
    173 #endif
    174