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 "core/include/fxcrt/fx_system.h" 8 #include "core/include/fxge/fx_ge.h" 9 10 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 11 12 #include "apple_int.h" 13 #include "core/include/fxge/fx_freetype.h" 14 #include "core/include/fxge/fx_ge_apple.h" 15 #include "core/src/fxge/agg/include/fx_agg_driver.h" 16 #include "core/src/fxge/dib/dib_int.h" 17 #include "core/src/fxge/ge/text_int.h" 18 19 void CFX_AggDeviceDriver::InitPlatform() { 20 CQuartz2D& quartz2d = 21 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; 22 m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap); 23 } 24 void CFX_AggDeviceDriver::DestroyPlatform() { 25 CQuartz2D& quartz2d = 26 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; 27 if (m_pPlatformGraphics) { 28 quartz2d.destroyGraphics(m_pPlatformGraphics); 29 m_pPlatformGraphics = NULL; 30 } 31 } 32 void CFX_FaceCache::InitPlatform() {} 33 void CFX_FaceCache::DestroyPlatform() {} 34 CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext( 35 CFX_Font* pFont, 36 FX_DWORD glyph_index, 37 const CFX_Matrix* pMatrix, 38 int dest_width, 39 int anti_alias) { 40 return NULL; 41 } 42 static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext, 43 int nChars, 44 const FXTEXT_CHARPOS* pCharPos, 45 CFX_Font* pFont, 46 CFX_FontCache* pCache, 47 const CFX_Matrix* pObject2Device, 48 FX_FLOAT font_size, 49 FX_DWORD argb, 50 int alpha_flag, 51 void* pIccTransform) { 52 if (nChars == 0) { 53 return TRUE; 54 } 55 CFX_Matrix 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 = 66 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; 67 if (!pFont->GetPlatformFont()) { 68 if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) { 69 return FALSE; 70 } 71 pFont->SetPlatformFont( 72 quartz2d.CreateFont(pFont->GetFontData(), pFont->GetSize())); 73 if (!pFont->GetPlatformFont()) { 74 return FALSE; 75 } 76 } 77 CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars); 78 CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars); 79 for (int i = 0; i < nChars; i++) { 80 glyph_indices[i] = pCharPos[i].m_ExtGID; 81 if (bNegSize) { 82 glyph_positions[i].x = -pCharPos[i].m_OriginX; 83 } else { 84 glyph_positions[i].x = pCharPos[i].m_OriginX; 85 } 86 glyph_positions[i].y = pCharPos[i].m_OriginY; 87 } 88 if (bNegSize) { 89 new_matrix.a = -new_matrix.a; 90 } else { 91 new_matrix.b = -new_matrix.b; 92 new_matrix.d = -new_matrix.d; 93 } 94 quartz2d.setGraphicsTextMatrix(pContext, &new_matrix); 95 return quartz2d.drawGraphicsString(pContext, pFont->GetPlatformFont(), 96 font_size, glyph_indices, glyph_positions, 97 nChars, argb, NULL); 98 } 99 static void _DoNothing(void* info, const void* data, size_t size) {} 100 FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, 101 const FXTEXT_CHARPOS* pCharPos, 102 CFX_Font* pFont, 103 CFX_FontCache* pCache, 104 const CFX_Matrix* pObject2Device, 105 FX_FLOAT font_size, 106 FX_DWORD argb, 107 int alpha_flag, 108 void* pIccTransform) { 109 if (!pFont) { 110 return FALSE; 111 } 112 FX_BOOL bBold = pFont->IsBold(); 113 if (!bBold && pFont->GetSubstFont() && 114 pFont->GetSubstFont()->m_Weight >= 500 && 115 pFont->GetSubstFont()->m_Weight <= 600) { 116 return FALSE; 117 } 118 for (int i = 0; i < nChars; i++) { 119 if (pCharPos[i].m_bGlyphAdjust) { 120 return FALSE; 121 } 122 } 123 CGContextRef ctx = CGContextRef(m_pPlatformGraphics); 124 if (NULL == ctx) { 125 return FALSE; 126 } 127 CGContextSaveGState(ctx); 128 CGContextSetTextDrawingMode(ctx, kCGTextFillClip); 129 CGRect rect_cg; 130 CGImageRef pImageCG = NULL; 131 if (m_pClipRgn) { 132 rect_cg = 133 CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, 134 m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); 135 const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); 136 if (pClipMask) { 137 CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData( 138 NULL, pClipMask->GetBuffer(), 139 pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); 140 CGFloat decode_f[2] = {255.f, 0.f}; 141 pImageCG = CGImageMaskCreate( 142 pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, 143 pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); 144 CGDataProviderRelease(pClipMaskDataProvider); 145 } 146 } else { 147 rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); 148 } 149 rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); 150 if (pImageCG) { 151 CGContextClipToMask(ctx, rect_cg, pImageCG); 152 } else { 153 CGContextClipToRect(ctx, rect_cg); 154 } 155 FX_BOOL ret = 156 _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, 157 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 if (m_pPlatformFont) { 166 CQuartz2D& quartz2d = 167 ((CApplePlatform*)CFX_GEModule::Get()->GetPlatformData())->_quartz2d; 168 quartz2d.DestroyFont(m_pPlatformFont); 169 m_pPlatformFont = NULL; 170 } 171 } 172 173 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 174