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