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 "../../../include/fxge/fx_ge.h" | 7 #include "../../../include/fxge/fx_ge.h" |
8 CFX_RenderDevice::CFX_RenderDevice() | 8 CFX_RenderDevice::CFX_RenderDevice() { |
9 { | 9 m_pDeviceDriver = NULL; |
10 m_pDeviceDriver = NULL; | 10 m_pBitmap = NULL; |
11 m_pBitmap = NULL; | 11 } |
12 } | 12 CFX_RenderDevice::~CFX_RenderDevice() { |
13 CFX_RenderDevice::~CFX_RenderDevice() | 13 delete m_pDeviceDriver; |
14 { | 14 } |
15 delete m_pDeviceDriver; | 15 void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver) { |
16 } | 16 delete m_pDeviceDriver; |
17 void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver) | 17 m_pDeviceDriver = pDriver; |
18 { | 18 InitDeviceInfo(); |
19 delete m_pDeviceDriver; | 19 } |
20 m_pDeviceDriver = pDriver; | 20 void CFX_RenderDevice::InitDeviceInfo() { |
21 InitDeviceInfo(); | 21 ASSERT(m_pDeviceDriver != NULL); |
22 } | 22 m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH); |
23 void CFX_RenderDevice::InitDeviceInfo() | 23 m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT); |
24 { | 24 m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL); |
25 ASSERT(m_pDeviceDriver != NULL); | 25 m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS); |
26 m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH); | 26 m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS); |
27 m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT); | 27 if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) { |
28 m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL); | |
29 m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS); | |
30 m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS); | |
31 if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) { | |
32 m_ClipBox.left = 0; | |
33 m_ClipBox.top = 0; | |
34 m_ClipBox.right = m_Width; | |
35 m_ClipBox.bottom = m_Height; | |
36 } | |
37 } | |
38 FX_BOOL CFX_RenderDevice::StartRendering() | |
39 { | |
40 return m_pDeviceDriver->StartRendering(); | |
41 } | |
42 void CFX_RenderDevice::EndRendering() | |
43 { | |
44 m_pDeviceDriver->EndRendering(); | |
45 } | |
46 void CFX_RenderDevice::SaveState() | |
47 { | |
48 m_pDeviceDriver->SaveState(); | |
49 } | |
50 void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved) | |
51 { | |
52 m_pDeviceDriver->RestoreState(bKeepSaved); | |
53 UpdateClipBox(); | |
54 } | |
55 int CFX_RenderDevice::GetDeviceCaps(int caps_id) const | |
56 { | |
57 return m_pDeviceDriver->GetDeviceCaps(caps_id); | |
58 } | |
59 CFX_Matrix CFX_RenderDevice::GetCTM() const | |
60 { | |
61 return m_pDeviceDriver->GetCTM(); | |
62 } | |
63 FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, int width,
int height) const | |
64 { | |
65 if (m_RenderCaps & FXRC_CMYK_OUTPUT) { | |
66 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FX
DIB_Cmyka : FXDIB_Cmyk); | |
67 } | |
68 if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) { | |
69 return pDIB->Create(width, height, FXDIB_8bppMask); | |
70 } | |
71 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ | |
72 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_
Argb : FXDIB_Rgb32); | |
73 #else | |
74 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_
Argb : FXDIB_Rgb); | |
75 #endif | |
76 } | |
77 FX_BOOL CFX_RenderDevice::SetClip_PathFill(const CFX_PathData* pPathData, | |
78 const CFX_AffineMatrix* pObject2Device, | |
79 int fill_mode | |
80 ) | |
81 { | |
82 if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, fill_mode)
) { | |
83 return FALSE; | |
84 } | |
85 UpdateClipBox(); | |
86 return TRUE; | |
87 } | |
88 FX_BOOL CFX_RenderDevice::SetClip_PathStroke(const CFX_PathData* pPathData, | |
89 const CFX_AffineMatrix* pObject2Device, | |
90 const CFX_GraphStateData* pGraphState | |
91 ) | |
92 { | |
93 if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, pGraphSt
ate)) { | |
94 return FALSE; | |
95 } | |
96 UpdateClipBox(); | |
97 return TRUE; | |
98 } | |
99 FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect) | |
100 { | |
101 CFX_PathData path; | |
102 path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), (FX_FLOA
T)(pRect->right), (FX_FLOAT)(pRect->top)); | |
103 if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) { | |
104 return FALSE; | |
105 } | |
106 UpdateClipBox(); | |
107 return TRUE; | |
108 } | |
109 void CFX_RenderDevice::UpdateClipBox() | |
110 { | |
111 if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) { | |
112 return; | |
113 } | |
114 m_ClipBox.left = 0; | 28 m_ClipBox.left = 0; |
115 m_ClipBox.top = 0; | 29 m_ClipBox.top = 0; |
116 m_ClipBox.right = m_Width; | 30 m_ClipBox.right = m_Width; |
117 m_ClipBox.bottom = m_Height; | 31 m_ClipBox.bottom = m_Height; |
| 32 } |
| 33 } |
| 34 FX_BOOL CFX_RenderDevice::StartRendering() { |
| 35 return m_pDeviceDriver->StartRendering(); |
| 36 } |
| 37 void CFX_RenderDevice::EndRendering() { |
| 38 m_pDeviceDriver->EndRendering(); |
| 39 } |
| 40 void CFX_RenderDevice::SaveState() { |
| 41 m_pDeviceDriver->SaveState(); |
| 42 } |
| 43 void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved) { |
| 44 m_pDeviceDriver->RestoreState(bKeepSaved); |
| 45 UpdateClipBox(); |
| 46 } |
| 47 int CFX_RenderDevice::GetDeviceCaps(int caps_id) const { |
| 48 return m_pDeviceDriver->GetDeviceCaps(caps_id); |
| 49 } |
| 50 CFX_Matrix CFX_RenderDevice::GetCTM() const { |
| 51 return m_pDeviceDriver->GetCTM(); |
| 52 } |
| 53 FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, |
| 54 int width, |
| 55 int height) const { |
| 56 if (m_RenderCaps & FXRC_CMYK_OUTPUT) { |
| 57 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT |
| 58 ? FXDIB_Cmyka |
| 59 : FXDIB_Cmyk); |
| 60 } |
| 61 if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) { |
| 62 return pDIB->Create(width, height, FXDIB_8bppMask); |
| 63 } |
| 64 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ |
| 65 return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT |
| 66 ? FXDIB_Argb |
| 67 : FXDIB_Rgb32); |
| 68 #else |
| 69 return pDIB->Create( |
| 70 width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb); |
| 71 #endif |
| 72 } |
| 73 FX_BOOL CFX_RenderDevice::SetClip_PathFill( |
| 74 const CFX_PathData* pPathData, |
| 75 const CFX_AffineMatrix* pObject2Device, |
| 76 int fill_mode) { |
| 77 if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, |
| 78 fill_mode)) { |
| 79 return FALSE; |
| 80 } |
| 81 UpdateClipBox(); |
| 82 return TRUE; |
| 83 } |
| 84 FX_BOOL CFX_RenderDevice::SetClip_PathStroke( |
| 85 const CFX_PathData* pPathData, |
| 86 const CFX_AffineMatrix* pObject2Device, |
| 87 const CFX_GraphStateData* pGraphState) { |
| 88 if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, |
| 89 pGraphState)) { |
| 90 return FALSE; |
| 91 } |
| 92 UpdateClipBox(); |
| 93 return TRUE; |
| 94 } |
| 95 FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect) { |
| 96 CFX_PathData path; |
| 97 path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), |
| 98 (FX_FLOAT)(pRect->right), (FX_FLOAT)(pRect->top)); |
| 99 if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) { |
| 100 return FALSE; |
| 101 } |
| 102 UpdateClipBox(); |
| 103 return TRUE; |
| 104 } |
| 105 void CFX_RenderDevice::UpdateClipBox() { |
| 106 if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) { |
| 107 return; |
| 108 } |
| 109 m_ClipBox.left = 0; |
| 110 m_ClipBox.top = 0; |
| 111 m_ClipBox.right = m_Width; |
| 112 m_ClipBox.bottom = m_Height; |
118 } | 113 } |
119 FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData, | 114 FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData, |
120 const CFX_AffineMatrix* pObject2Device, | 115 const CFX_AffineMatrix* pObject2Device, |
121 const CFX_GraphStateData* pGraphState, | 116 const CFX_GraphStateData* pGraphState, |
122 FX_DWORD fill_color, FX_DWORD stroke_color, i
nt fill_mode, | 117 FX_DWORD fill_color, |
123 int alpha_flag, void* pIccTransform, int blen
d_type) | 118 FX_DWORD stroke_color, |
124 { | 119 int fill_mode, |
125 uint8_t fill_alpha, stroke_alpha; | 120 int alpha_flag, |
126 if (FXGETFLAG_COLORTYPE(alpha_flag)) { | 121 void* pIccTransform, |
127 fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag); | 122 int blend_type) { |
128 stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag); | 123 uint8_t fill_alpha, stroke_alpha; |
| 124 if (FXGETFLAG_COLORTYPE(alpha_flag)) { |
| 125 fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag); |
| 126 stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag); |
| 127 } else { |
| 128 fill_alpha = FXARGB_A(fill_color); |
| 129 stroke_alpha = FXARGB_A(stroke_color); |
| 130 } |
| 131 if ((fill_mode & 3) == 0) { |
| 132 fill_alpha = 0; |
| 133 } |
| 134 if (pGraphState == NULL) { |
| 135 stroke_alpha = 0; |
| 136 } |
| 137 if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) { |
| 138 FX_PATHPOINT* pPoints = pPathData->GetPoints(); |
| 139 FX_FLOAT x1, x2, y1, y2; |
| 140 if (pObject2Device) { |
| 141 pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, |
| 142 y1); |
| 143 pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, |
| 144 y2); |
129 } else { | 145 } else { |
130 fill_alpha = FXARGB_A(fill_color); | 146 x1 = pPoints[0].m_PointX; |
131 stroke_alpha = FXARGB_A(stroke_color); | 147 y1 = pPoints[0].m_PointY; |
132 } | 148 x2 = pPoints[1].m_PointX; |
133 if ((fill_mode & 3) == 0) { | 149 y2 = pPoints[1].m_PointY; |
134 fill_alpha = 0; | 150 } |
135 } | 151 DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, |
136 if (pGraphState == NULL) { | 152 pIccTransform, blend_type); |
137 stroke_alpha = 0; | 153 return TRUE; |
138 } | 154 } |
139 if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) { | 155 if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && |
140 FX_PATHPOINT* pPoints = pPathData->GetPoints(); | 156 stroke_alpha == 0) { |
141 FX_FLOAT x1, x2, y1, y2; | 157 CFX_FloatRect rect_f; |
142 if (pObject2Device) { | 158 if (!(fill_mode & FXFILL_RECT_AA) && |
143 pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY,
x1, y1); | 159 pPathData->IsRect(pObject2Device, &rect_f)) { |
144 pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY,
x2, y2); | 160 FX_RECT rect_i = rect_f.GetOutterRect(); |
| 161 int width = (int)FXSYS_ceil(rect_f.right - rect_f.left); |
| 162 if (width < 1) { |
| 163 width = 1; |
| 164 if (rect_i.left == rect_i.right) { |
| 165 rect_i.right++; |
| 166 } |
| 167 } |
| 168 int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom); |
| 169 if (height < 1) { |
| 170 height = 1; |
| 171 if (rect_i.bottom == rect_i.top) { |
| 172 rect_i.bottom++; |
| 173 } |
| 174 } |
| 175 if (rect_i.Width() >= width + 1) { |
| 176 if (rect_f.left - (FX_FLOAT)(rect_i.left) > |
| 177 (FX_FLOAT)(rect_i.right) - rect_f.right) { |
| 178 rect_i.left++; |
145 } else { | 179 } else { |
146 x1 = pPoints[0].m_PointX; | 180 rect_i.right--; |
147 y1 = pPoints[0].m_PointY; | |
148 x2 = pPoints[1].m_PointX; | |
149 y2 = pPoints[1].m_PointY; | |
150 } | 181 } |
151 DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, pIcc
Transform, blend_type); | 182 } |
| 183 if (rect_i.Height() >= height + 1) { |
| 184 if (rect_f.top - (FX_FLOAT)(rect_i.top) > |
| 185 (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) { |
| 186 rect_i.top++; |
| 187 } else { |
| 188 rect_i.bottom--; |
| 189 } |
| 190 } |
| 191 if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, |
| 192 blend_type)) { |
152 return TRUE; | 193 return TRUE; |
153 } | 194 } |
154 if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
stroke_alpha == 0) { | 195 } |
155 CFX_FloatRect rect_f; | 196 } |
156 if (!(fill_mode & FXFILL_RECT_AA) && pPathData->IsRect(pObject2Device, &
rect_f)) { | 197 if ((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) && |
157 FX_RECT rect_i = rect_f.GetOutterRect(); | 198 !(fill_mode & FX_FILL_TEXT_MODE)) { |
158 int width = (int)FXSYS_ceil(rect_f.right - rect_f.left); | 199 CFX_PathData newPath; |
159 if (width < 1) { | 200 FX_BOOL bThin = FALSE; |
160 width = 1; | 201 if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, |
161 if (rect_i.left == rect_i.right) { | 202 m_pDeviceDriver->GetDriverType())) { |
162 rect_i.right ++; | 203 CFX_GraphStateData graphState; |
163 } | 204 graphState.m_LineWidth = 0.0f; |
164 } | 205 FX_DWORD strokecolor = fill_color; |
165 int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom); | 206 if (bThin) { |
166 if (height < 1) { | 207 if (FXGETFLAG_COLORTYPE(alpha_flag)) { |
167 height = 1; | 208 FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2); |
168 if (rect_i.bottom == rect_i.top) { | 209 } else { |
169 rect_i.bottom ++; | 210 strokecolor = |
170 } | 211 (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff)); |
171 } | |
172 if (rect_i.Width() >= width + 1) { | |
173 if (rect_f.left - (FX_FLOAT)(rect_i.left) > (FX_FLOAT)(rect_i.ri
ght) - rect_f.right) { | |
174 rect_i.left ++; | |
175 } else { | |
176 rect_i.right --; | |
177 } | |
178 } | |
179 if (rect_i.Height() >= height + 1) { | |
180 if (rect_f.top - (FX_FLOAT)(rect_i.top) > (FX_FLOAT)(rect_i.bott
om) - rect_f.bottom) { | |
181 rect_i.top ++; | |
182 } else { | |
183 rect_i.bottom --; | |
184 } | |
185 } | |
186 if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, blend_t
ype)) { | |
187 return TRUE; | |
188 } | |
189 } | 212 } |
190 } | 213 } |
191 if((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) &&
!(fill_mode & FX_FILL_TEXT_MODE)) { | 214 CFX_AffineMatrix* pMatrix = NULL; |
192 CFX_PathData newPath; | 215 if (pObject2Device && !pObject2Device->IsIdentity()) { |
193 FX_BOOL bThin = FALSE; | 216 pMatrix = (CFX_AffineMatrix*)pObject2Device; |
194 if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bTh
in, m_pDeviceDriver->GetDriverType())) { | 217 } |
195 CFX_GraphStateData graphState; | 218 int smooth_path = FX_ZEROAREA_FILL; |
196 graphState.m_LineWidth = 0.0f; | 219 if (fill_mode & FXFILL_NOPATHSMOOTH) { |
197 FX_DWORD strokecolor = fill_color; | 220 smooth_path |= FXFILL_NOPATHSMOOTH; |
198 if (bThin) { | 221 } |
199 if (FXGETFLAG_COLORTYPE(alpha_flag)) { | 222 m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, |
200 FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2); | 223 smooth_path, alpha_flag, pIccTransform, |
201 } else { | 224 blend_type); |
202 strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x
00ffffff)); | 225 } |
203 } | 226 } |
204 } | 227 if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && |
205 CFX_AffineMatrix* pMatrix = NULL; | 228 (fill_mode & FX_FILL_STROKE)) { |
206 if (pObject2Device && !pObject2Device->IsIdentity()) { | |
207 pMatrix = (CFX_AffineMatrix*)pObject2Device; | |
208 } | |
209 int smooth_path = FX_ZEROAREA_FILL; | |
210 if (fill_mode & FXFILL_NOPATHSMOOTH) { | |
211 smooth_path |= FXFILL_NOPATHSMOOTH; | |
212 } | |
213 m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokec
olor, smooth_path, alpha_flag, pIccTransform, blend_type); | |
214 } | |
215 } | |
216 if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && (fill_mode & FX_
FILL_STROKE)) { | |
217 if (!(m_RenderCaps & FXRC_GET_BITS)) { | |
218 return FALSE; | |
219 } | |
220 CFX_FloatRect bbox; | |
221 if (pGraphState) { | |
222 bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphSta
te->m_MiterLimit); | |
223 } else { | |
224 bbox = pPathData->GetBoundingBox(); | |
225 } | |
226 if (pObject2Device) { | |
227 bbox.Transform(pObject2Device); | |
228 } | |
229 CFX_Matrix ctm = GetCTM(); | |
230 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); | |
231 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); | |
232 FX_RECT rect = bbox.GetOutterRect(); | |
233 CFX_DIBitmap bitmap, Backdrop; | |
234 if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX)
, FXSYS_round(rect.Height() * fScaleY))) { | |
235 return FALSE; | |
236 } | |
237 if (bitmap.HasAlpha()) { | |
238 bitmap.Clear(0); | |
239 Backdrop.Copy(&bitmap); | |
240 } else { | |
241 if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL))
{ | |
242 return FALSE; | |
243 } | |
244 Backdrop.Copy(&bitmap); | |
245 } | |
246 CFX_FxgeDevice bitmap_device; | |
247 bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE); | |
248 CFX_AffineMatrix matrix; | |
249 if (pObject2Device) { | |
250 matrix = *pObject2Device; | |
251 } | |
252 matrix.TranslateI(-rect.left, -rect.top); | |
253 matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); | |
254 if (!bitmap_device.GetDeviceDriver()->DrawPath(pPathData, &matrix, pGrap
hState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_ty
pe)) { | |
255 return FALSE; | |
256 } | |
257 FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(
rect.Height() * fScaleY)); | |
258 return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, rect
.top, FXDIB_BLEND_NORMAL); | |
259 } | |
260 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, fil
l_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type); | |
261 } | |
262 FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, FX_DWORD color, int alpha_flag,
void* pIccTransform) | |
263 { | |
264 if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) { | |
265 return TRUE; | |
266 } | |
267 FX_RECT rect(x, y, x + 1, y + 1); | |
268 return FillRect(&rect, color, alpha_flag, pIccTransform); | |
269 } | |
270 FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, in
t alpha_flag, void* pIccTransform, int blend_type) | |
271 { | |
272 if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform,
blend_type)) { | |
273 return TRUE; | |
274 } | |
275 if (!(m_RenderCaps & FXRC_GET_BITS)) { | 229 if (!(m_RenderCaps & FXRC_GET_BITS)) { |
276 return FALSE; | 230 return FALSE; |
277 } | 231 } |
278 CFX_DIBitmap bitmap; | 232 CFX_FloatRect bbox; |
279 if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) { | 233 if (pGraphState) { |
280 return FALSE; | 234 bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, |
281 } | 235 pGraphState->m_MiterLimit); |
282 if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) { | 236 } else { |
283 return FALSE; | 237 bbox = pPathData->GetBoundingBox(); |
284 } | 238 } |
285 if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color,
alpha_flag, pIccTransform)) { | 239 if (pObject2Device) { |
286 return FALSE; | 240 bbox.Transform(pObject2Device); |
287 } | 241 } |
288 FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height()); | 242 CFX_Matrix ctm = GetCTM(); |
289 m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, F
XDIB_BLEND_NORMAL); | |
290 return TRUE; | |
291 } | |
292 FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2
, FX_FLOAT y2, FX_DWORD color, | |
293 int fill_mode, int alpha_flag, void* pIccTransform, int blend_type) | |
294 { | |
295 if (((m_RenderCaps & FXRC_ALPHA_PATH) && | |
296 (FXGETFLAG_COLORTYPE(alpha_flag) && FXGETFLAG_ALPHA_FILL(alpha_flag)
== 0xff)) || | |
297 color >= 0xff000000) | |
298 if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag,
pIccTransform, blend_type)) { | |
299 return TRUE; | |
300 } | |
301 CFX_GraphStateData graph_state; | |
302 CFX_PathData path; | |
303 path.SetPointCount(2); | |
304 path.SetPoint(0, x1, y1, FXPT_MOVETO); | |
305 path.SetPoint(1, x2, y2, FXPT_LINETO); | |
306 return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, fill_m
ode, alpha_flag, pIccTransform, blend_type); | |
307 } | |
308 FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, vo
id* pIccTransform) | |
309 { | |
310 if (!(m_RenderCaps & FXRC_GET_BITS)) { | |
311 return FALSE; | |
312 } | |
313 return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform); | |
314 } | |
315 CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() | |
316 { | |
317 return m_pDeviceDriver->GetBackDrop(); | |
318 } | |
319 FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, int left, int
top, int blend_mode, | |
320 void* pIccTransform) | |
321 { | |
322 ASSERT(!pBitmap->IsAlphaMask()); | |
323 CFX_AffineMatrix ctm = GetCTM(); | |
324 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); | 243 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); |
325 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); | 244 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); |
326 FX_RECT dest_rect(left, top, FXSYS_round(left + pBitmap->GetWidth() / fScale
X), FXSYS_round(top + pBitmap->GetHeight() / fScaleY)); | 245 FX_RECT rect = bbox.GetOutterRect(); |
327 dest_rect.Intersect(m_ClipBox); | 246 CFX_DIBitmap bitmap, Backdrop; |
328 if (dest_rect.IsEmpty()) { | 247 if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX), |
329 return TRUE; | 248 FXSYS_round(rect.Height() * fScaleY))) { |
330 } | 249 return FALSE; |
331 FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top, | 250 } |
332 dest_rect.left - left + dest_rect.Width(), dest_rect.top -
top + dest_rect.Height()); | 251 if (bitmap.HasAlpha()) { |
333 src_rect.left = FXSYS_round(src_rect.left * fScaleX); | 252 bitmap.Clear(0); |
334 src_rect.top = FXSYS_round(src_rect.top * fScaleY); | 253 Backdrop.Copy(&bitmap); |
335 src_rect.right = FXSYS_round(src_rect.right * fScaleX); | 254 } else { |
336 src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY); | 255 if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL)) { |
337 if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE))
|| | 256 return FALSE; |
338 (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) { | 257 } |
339 if (!(m_RenderCaps & FXRC_GET_BITS)) { | 258 Backdrop.Copy(&bitmap); |
340 return FALSE; | 259 } |
341 } | 260 CFX_FxgeDevice bitmap_device; |
342 int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX); | 261 bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE); |
343 int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY); | 262 CFX_AffineMatrix matrix; |
344 CFX_DIBitmap background; | 263 if (pObject2Device) { |
345 if (!background.Create(bg_pixel_width, bg_pixel_height, | 264 matrix = *pObject2Device; |
346 (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk :
FXDIB_Rgb32)) { | 265 } |
347 return FALSE; | 266 matrix.TranslateI(-rect.left, -rect.top); |
348 } | 267 matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); |
349 if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, dest_rect.t
op)) { | 268 if (!bitmap_device.GetDeviceDriver()->DrawPath( |
350 return FALSE; | 269 pPathData, &matrix, pGraphState, fill_color, stroke_color, |
351 } | 270 fill_mode, alpha_flag, pIccTransform, blend_type)) { |
352 if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height, | 271 return FALSE; |
353 pBitmap, src_rect.left, src_rect.top, | 272 } |
354 blend_mode, NULL, FALSE, pIccTransform))
{ | 273 FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), |
355 return FALSE; | 274 FXSYS_round(rect.Height() * fScaleY)); |
356 } | 275 return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, |
357 FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height); | 276 rect.top, FXDIB_BLEND_NORMAL); |
358 return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.l
eft, dest_rect.top, FXDIB_BLEND_NORMAL); | 277 } |
359 } | 278 return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, |
360 return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, des
t_rect.top, blend_mode, 0, pIccTransform); | 279 fill_color, stroke_color, fill_mode, |
361 } | 280 alpha_flag, pIccTransform, blend_type); |
362 FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, int left,
int top, | 281 } |
363 int dest_width, int dest_height, FX_DWOR
D flags, | 282 FX_BOOL CFX_RenderDevice::SetPixel(int x, |
364 void* pIccTransform, int blend_mode) | 283 int y, |
365 { | 284 FX_DWORD color, |
366 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); | 285 int alpha_flag, |
367 FX_RECT clip_box = m_ClipBox; | 286 void* pIccTransform) { |
368 clip_box.Intersect(dest_rect); | 287 if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) { |
369 if (clip_box.IsEmpty()) { | 288 return TRUE; |
370 return TRUE; | 289 } |
371 } | 290 FX_RECT rect(x, y, x + 1, y + 1); |
372 return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, des
t_height, &clip_box, flags, 0, pIccTransform, blend_mode); | 291 return FillRect(&rect, color, alpha_flag, pIccTransform); |
373 } | 292 } |
374 FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, int left, int
top, FX_DWORD argb, | 293 FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, |
375 int alpha_flag, void* pIccTransform) | 294 FX_DWORD fill_color, |
376 { | 295 int alpha_flag, |
377 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); | 296 void* pIccTransform, |
378 return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, FXDIB
_BLEND_NORMAL, alpha_flag, pIccTransform); | 297 int blend_type) { |
379 } | 298 if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform, |
380 FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, int left,
int top, | 299 blend_type)) { |
381 int dest_width, int dest_height, FX_DWORD argb, FX_DWORD flags, | 300 return TRUE; |
382 int alpha_flag, void* pIccTransform) | 301 } |
383 { | 302 if (!(m_RenderCaps & FXRC_GET_BITS)) { |
384 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); | 303 return FALSE; |
385 FX_RECT clip_box = m_ClipBox; | 304 } |
386 clip_box.Intersect(dest_rect); | 305 CFX_DIBitmap bitmap; |
387 return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width,
dest_height, &clip_box, flags, alpha_flag, pIccTransform); | 306 if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) { |
388 } | 307 return FALSE; |
389 FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_a
lpha, FX_DWORD argb, | 308 } |
390 const CFX_AffineMatrix* pMatrix, FX_DWORD
flags, void*& handle, | 309 if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) { |
391 int alpha_flag, void* pIccTransform, int b
lend_mode) | 310 return FALSE; |
392 { | 311 } |
393 return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, fl
ags, handle, alpha_flag, pIccTransform, blend_mode); | 312 if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color, |
394 } | 313 alpha_flag, pIccTransform)) { |
395 FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) | 314 return FALSE; |
396 { | 315 } |
397 return m_pDeviceDriver->ContinueDIBits(handle, pPause); | 316 FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height()); |
398 } | 317 m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, |
399 void CFX_RenderDevice::CancelDIBits(void* handle) | 318 FXDIB_BLEND_NORMAL); |
400 { | 319 return TRUE; |
401 m_pDeviceDriver->CancelDIBits(handle); | 320 } |
402 } | 321 FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, |
| 322 FX_FLOAT y1, |
| 323 FX_FLOAT x2, |
| 324 FX_FLOAT y2, |
| 325 FX_DWORD color, |
| 326 int fill_mode, |
| 327 int alpha_flag, |
| 328 void* pIccTransform, |
| 329 int blend_type) { |
| 330 if (((m_RenderCaps & FXRC_ALPHA_PATH) && |
| 331 (FXGETFLAG_COLORTYPE(alpha_flag) && |
| 332 FXGETFLAG_ALPHA_FILL(alpha_flag) == 0xff)) || |
| 333 color >= 0xff000000) |
| 334 if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag, |
| 335 pIccTransform, blend_type)) { |
| 336 return TRUE; |
| 337 } |
| 338 CFX_GraphStateData graph_state; |
| 339 CFX_PathData path; |
| 340 path.SetPointCount(2); |
| 341 path.SetPoint(0, x1, y1, FXPT_MOVETO); |
| 342 path.SetPoint(1, x2, y2, FXPT_LINETO); |
| 343 return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, |
| 344 fill_mode, alpha_flag, pIccTransform, |
| 345 blend_type); |
| 346 } |
| 347 FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, |
| 348 int left, |
| 349 int top, |
| 350 void* pIccTransform) { |
| 351 if (!(m_RenderCaps & FXRC_GET_BITS)) { |
| 352 return FALSE; |
| 353 } |
| 354 return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform); |
| 355 } |
| 356 CFX_DIBitmap* CFX_RenderDevice::GetBackDrop() { |
| 357 return m_pDeviceDriver->GetBackDrop(); |
| 358 } |
| 359 FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, |
| 360 int left, |
| 361 int top, |
| 362 int blend_mode, |
| 363 void* pIccTransform) { |
| 364 ASSERT(!pBitmap->IsAlphaMask()); |
| 365 CFX_AffineMatrix ctm = GetCTM(); |
| 366 FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); |
| 367 FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); |
| 368 FX_RECT dest_rect(left, top, |
| 369 FXSYS_round(left + pBitmap->GetWidth() / fScaleX), |
| 370 FXSYS_round(top + pBitmap->GetHeight() / fScaleY)); |
| 371 dest_rect.Intersect(m_ClipBox); |
| 372 if (dest_rect.IsEmpty()) { |
| 373 return TRUE; |
| 374 } |
| 375 FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top, |
| 376 dest_rect.left - left + dest_rect.Width(), |
| 377 dest_rect.top - top + dest_rect.Height()); |
| 378 src_rect.left = FXSYS_round(src_rect.left * fScaleX); |
| 379 src_rect.top = FXSYS_round(src_rect.top * fScaleY); |
| 380 src_rect.right = FXSYS_round(src_rect.right * fScaleX); |
| 381 src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY); |
| 382 if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) || |
| 383 (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) { |
| 384 if (!(m_RenderCaps & FXRC_GET_BITS)) { |
| 385 return FALSE; |
| 386 } |
| 387 int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX); |
| 388 int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY); |
| 389 CFX_DIBitmap background; |
| 390 if (!background.Create( |
| 391 bg_pixel_width, bg_pixel_height, |
| 392 (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) { |
| 393 return FALSE; |
| 394 } |
| 395 if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, |
| 396 dest_rect.top)) { |
| 397 return FALSE; |
| 398 } |
| 399 if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height, |
| 400 pBitmap, src_rect.left, src_rect.top, |
| 401 blend_mode, NULL, FALSE, pIccTransform)) { |
| 402 return FALSE; |
| 403 } |
| 404 FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height); |
| 405 return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.left, |
| 406 dest_rect.top, FXDIB_BLEND_NORMAL); |
| 407 } |
| 408 return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, |
| 409 dest_rect.top, blend_mode, 0, |
| 410 pIccTransform); |
| 411 } |
| 412 FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, |
| 413 int left, |
| 414 int top, |
| 415 int dest_width, |
| 416 int dest_height, |
| 417 FX_DWORD flags, |
| 418 void* pIccTransform, |
| 419 int blend_mode) { |
| 420 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); |
| 421 FX_RECT clip_box = m_ClipBox; |
| 422 clip_box.Intersect(dest_rect); |
| 423 if (clip_box.IsEmpty()) { |
| 424 return TRUE; |
| 425 } |
| 426 return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, |
| 427 dest_height, &clip_box, flags, 0, |
| 428 pIccTransform, blend_mode); |
| 429 } |
| 430 FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, |
| 431 int left, |
| 432 int top, |
| 433 FX_DWORD argb, |
| 434 int alpha_flag, |
| 435 void* pIccTransform) { |
| 436 FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight()); |
| 437 return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, |
| 438 FXDIB_BLEND_NORMAL, alpha_flag, |
| 439 pIccTransform); |
| 440 } |
| 441 FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, |
| 442 int left, |
| 443 int top, |
| 444 int dest_width, |
| 445 int dest_height, |
| 446 FX_DWORD argb, |
| 447 FX_DWORD flags, |
| 448 int alpha_flag, |
| 449 void* pIccTransform) { |
| 450 FX_RECT dest_rect(left, top, left + dest_width, top + dest_height); |
| 451 FX_RECT clip_box = m_ClipBox; |
| 452 clip_box.Intersect(dest_rect); |
| 453 return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width, |
| 454 dest_height, &clip_box, flags, |
| 455 alpha_flag, pIccTransform); |
| 456 } |
| 457 FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, |
| 458 int bitmap_alpha, |
| 459 FX_DWORD argb, |
| 460 const CFX_AffineMatrix* pMatrix, |
| 461 FX_DWORD flags, |
| 462 void*& handle, |
| 463 int alpha_flag, |
| 464 void* pIccTransform, |
| 465 int blend_mode) { |
| 466 return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, |
| 467 flags, handle, alpha_flag, pIccTransform, |
| 468 blend_mode); |
| 469 } |
| 470 FX_BOOL CFX_RenderDevice::ContinueDIBits(void* handle, IFX_Pause* pPause) { |
| 471 return m_pDeviceDriver->ContinueDIBits(handle, pPause); |
| 472 } |
| 473 void CFX_RenderDevice::CancelDIBits(void* handle) { |
| 474 m_pDeviceDriver->CancelDIBits(handle); |
| 475 } |
OLD | NEW |