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 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ | 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ |
9 #include <windows.h> | 9 #include <windows.h> |
10 #include "../../../include/fxge/fx_ge_win32.h" | 10 #include "../../../include/fxge/fx_ge_win32.h" |
11 #include "win32_int.h" | 11 #include "win32_int.h" |
12 #include "../../../include/fxge/fx_freetype.h" | 12 #include "../../../include/fxge/fx_freetype.h" |
13 #include "../ge/text_int.h" | 13 #include "../ge/text_int.h" |
14 #include "../dib/dib_int.h" | 14 #include "../dib/dib_int.h" |
15 #define SIZETHRESHOLD 1000 | 15 #define SIZETHRESHOLD 1000 |
16 #define OUTPUTPSLEN 4096 | 16 #define OUTPUTPSLEN 4096 |
17 CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINT
ER) | 17 CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) |
18 { | 18 : CGdiDeviceDriver(hDC, FXDC_PRINTER) { |
19 m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); | 19 m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); |
20 m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); | 20 m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); |
21 m_bSupportROP = TRUE; | 21 m_bSupportROP = TRUE; |
22 } | 22 } |
23 int CGdiPrinterDriver::GetDeviceCaps(int caps_id) | 23 int CGdiPrinterDriver::GetDeviceCaps(int caps_id) { |
24 { | 24 if (caps_id == FXDC_HORZ_SIZE) { |
25 if (caps_id == FXDC_HORZ_SIZE) { | 25 return m_HorzSize; |
26 return m_HorzSize; | 26 } |
27 } | 27 if (caps_id == FXDC_VERT_SIZE) { |
28 if (caps_id == FXDC_VERT_SIZE) { | 28 return m_VertSize; |
29 return m_VertSize; | 29 } |
30 } | 30 return CGdiDeviceDriver::GetDeviceCaps(caps_id); |
31 return CGdiDeviceDriver::GetDeviceCaps(caps_id); | 31 } |
32 } | 32 FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, |
33 FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD colo
r, const FX_RECT* pSrcRect, int left, int top, int blend_type, | 33 FX_DWORD color, |
34 int alpha_flag, void* pIccTransform) | 34 const FX_RECT* pSrcRect, |
35 { | 35 int left, |
36 if (pSource->IsAlphaMask()) { | 36 int top, |
37 FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->H
eight()); | 37 int blend_type, |
38 return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRe
ct->top, pSource->GetWidth(), pSource->GetHeight(), | 38 int alpha_flag, |
39 &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLE
ND_NORMAL); | 39 void* pIccTransform) { |
40 } | 40 if (pSource->IsAlphaMask()) { |
41 ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL); | 41 FX_RECT clip_rect( |
42 ASSERT(blend_type == FXDIB_BLEND_NORMAL); | 42 left, top, left + pSrcRect->Width(), top + pSrcRect->Height()); |
43 if (pSource->HasAlpha()) { | 43 return StretchDIBits(pSource, |
| 44 color, |
| 45 left - pSrcRect->left, |
| 46 top - pSrcRect->top, |
| 47 pSource->GetWidth(), |
| 48 pSource->GetHeight(), |
| 49 &clip_rect, |
| 50 0, |
| 51 alpha_flag, |
| 52 pIccTransform, |
| 53 FXDIB_BLEND_NORMAL); |
| 54 } |
| 55 ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL); |
| 56 ASSERT(blend_type == FXDIB_BLEND_NORMAL); |
| 57 if (pSource->HasAlpha()) { |
| 58 return FALSE; |
| 59 } |
| 60 CFX_DIBExtractor temp(pSource); |
| 61 CFX_DIBitmap* pBitmap = temp; |
| 62 if (pBitmap == NULL) { |
| 63 return FALSE; |
| 64 } |
| 65 return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); |
| 66 } |
| 67 FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, |
| 68 FX_DWORD color, |
| 69 int dest_left, |
| 70 int dest_top, |
| 71 int dest_width, |
| 72 int dest_height, |
| 73 const FX_RECT* pClipRect, |
| 74 FX_DWORD flags, |
| 75 int alpha_flag, |
| 76 void* pIccTransform, |
| 77 int blend_type) { |
| 78 if (pSource->IsAlphaMask()) { |
| 79 int alpha = FXGETFLAG_COLORTYPE(alpha_flag) |
| 80 ? FXGETFLAG_ALPHA_FILL(alpha_flag) |
| 81 : FXARGB_A(color); |
| 82 if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) { |
| 83 return FALSE; |
| 84 } |
| 85 if (dest_width < 0 || dest_height < 0) { |
| 86 CFX_DIBitmap* pFlipped = |
| 87 pSource->FlipImage(dest_width < 0, dest_height < 0); |
| 88 if (pFlipped == NULL) { |
44 return FALSE; | 89 return FALSE; |
| 90 } |
| 91 if (dest_width < 0) { |
| 92 dest_left += dest_width; |
| 93 } |
| 94 if (dest_height < 0) { |
| 95 dest_top += dest_height; |
| 96 } |
| 97 FX_BOOL ret = GDI_StretchBitMask(pFlipped, |
| 98 dest_left, |
| 99 dest_top, |
| 100 abs(dest_width), |
| 101 abs(dest_height), |
| 102 color, |
| 103 flags, |
| 104 alpha_flag, |
| 105 pIccTransform); |
| 106 delete pFlipped; |
| 107 return ret; |
45 } | 108 } |
46 CFX_DIBExtractor temp(pSource); | 109 CFX_DIBExtractor temp(pSource); |
47 CFX_DIBitmap* pBitmap = temp; | 110 CFX_DIBitmap* pBitmap = temp; |
48 if (pBitmap == NULL) { | 111 if (pBitmap == NULL) { |
| 112 return FALSE; |
| 113 } |
| 114 return GDI_StretchBitMask(pBitmap, |
| 115 dest_left, |
| 116 dest_top, |
| 117 dest_width, |
| 118 dest_height, |
| 119 color, |
| 120 flags, |
| 121 alpha_flag, |
| 122 pIccTransform); |
| 123 } else { |
| 124 ASSERT(pSource != NULL); |
| 125 if (pSource->HasAlpha()) { |
| 126 return FALSE; |
| 127 } |
| 128 if (dest_width < 0 || dest_height < 0) { |
| 129 CFX_DIBitmap* pFlipped = |
| 130 pSource->FlipImage(dest_width < 0, dest_height < 0); |
| 131 if (pFlipped == NULL) { |
49 return FALSE; | 132 return FALSE; |
50 } | 133 } |
51 return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform); | 134 if (dest_width < 0) { |
52 } | 135 dest_left += dest_width; |
53 FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD
color, int dest_left, int dest_top, | 136 } |
54 int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flag
s, | 137 if (dest_height < 0) { |
55 int alpha_flag, void* pIccTransform, int blend_type) | 138 dest_top += dest_height; |
56 { | 139 } |
57 if (pSource->IsAlphaMask()) { | 140 FX_BOOL ret = GDI_StretchDIBits(pFlipped, |
58 int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha
_flag) : FXARGB_A(color); | 141 dest_left, |
59 if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) { | 142 dest_top, |
60 return FALSE; | 143 abs(dest_width), |
| 144 abs(dest_height), |
| 145 flags, |
| 146 pIccTransform); |
| 147 delete pFlipped; |
| 148 return ret; |
| 149 } |
| 150 CFX_DIBExtractor temp(pSource); |
| 151 CFX_DIBitmap* pBitmap = temp; |
| 152 if (pBitmap == NULL) { |
| 153 return FALSE; |
| 154 } |
| 155 return GDI_StretchDIBits(pBitmap, |
| 156 dest_left, |
| 157 dest_top, |
| 158 dest_width, |
| 159 dest_height, |
| 160 flags, |
| 161 pIccTransform); |
| 162 } |
| 163 } |
| 164 static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, |
| 165 const CFX_AffineMatrix* pDestMatrix) { |
| 166 ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || |
| 167 pSrc->GetFormat() == FXDIB_1bppMask || |
| 168 pSrc->GetFormat() == FXDIB_1bppCmyk); |
| 169 CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); |
| 170 FX_RECT full_rect = unit_rect.GetOutterRect(); |
| 171 int full_left = full_rect.left; |
| 172 int full_top = full_rect.top; |
| 173 CFX_DIBExtractor src_bitmap(pSrc); |
| 174 CFX_DIBitmap* pSrcBitmap = src_bitmap; |
| 175 if (pSrcBitmap == NULL) { |
| 176 return NULL; |
| 177 } |
| 178 int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight(); |
| 179 FX_LPBYTE src_buf = pSrcBitmap->GetBuffer(); |
| 180 FX_DWORD src_pitch = pSrcBitmap->GetPitch(); |
| 181 FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); |
| 182 FX_FLOAT area_scale = |
| 183 FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area); |
| 184 FX_FLOAT size_scale = FXSYS_sqrt(area_scale); |
| 185 CFX_AffineMatrix adjusted_matrix(*pDestMatrix); |
| 186 adjusted_matrix.Scale(size_scale, size_scale); |
| 187 CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); |
| 188 FX_RECT result_rect = result_rect_f.GetOutterRect(); |
| 189 CFX_AffineMatrix src2result; |
| 190 src2result.e = adjusted_matrix.c + adjusted_matrix.e; |
| 191 src2result.f = adjusted_matrix.d + adjusted_matrix.f; |
| 192 src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); |
| 193 src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); |
| 194 src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); |
| 195 src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); |
| 196 src2result.TranslateI(-result_rect.left, -result_rect.top); |
| 197 CFX_AffineMatrix result2src; |
| 198 result2src.SetReverse(src2result); |
| 199 CPDF_FixedMatrix result2src_fix(result2src, 8); |
| 200 int result_width = result_rect.Width(); |
| 201 int result_height = result_rect.Height(); |
| 202 CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap; |
| 203 if (!pTempBitmap) { |
| 204 if (pSrcBitmap != src_bitmap) { |
| 205 delete pSrcBitmap; |
| 206 } |
| 207 return NULL; |
| 208 } |
| 209 if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { |
| 210 delete pTempBitmap; |
| 211 if (pSrcBitmap != src_bitmap) { |
| 212 delete pSrcBitmap; |
| 213 } |
| 214 return NULL; |
| 215 } |
| 216 pTempBitmap->CopyPalette(pSrc->GetPalette()); |
| 217 FX_LPBYTE dest_buf = pTempBitmap->GetBuffer(); |
| 218 int dest_pitch = pTempBitmap->GetPitch(); |
| 219 FXSYS_memset8( |
| 220 dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height); |
| 221 if (pSrcBitmap->IsAlphaMask()) { |
| 222 for (int dest_y = 0; dest_y < result_height; dest_y++) { |
| 223 FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch; |
| 224 for (int dest_x = 0; dest_x < result_width; dest_x++) { |
| 225 int src_x, src_y; |
| 226 result2src_fix.Transform(dest_x, dest_y, src_x, src_y); |
| 227 if (src_x < 0 || src_x >= src_width || src_y < 0 || |
| 228 src_y >= src_height) { |
| 229 continue; |
61 } | 230 } |
62 if (dest_width < 0 || dest_height < 0) { | 231 if (!((src_buf + src_pitch * src_y)[src_x / 8] & |
63 CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_hei
ght < 0); | 232 (1 << (7 - src_x % 8)))) { |
64 if (pFlipped == NULL) { | 233 continue; |
65 return FALSE; | |
66 } | |
67 if (dest_width < 0) { | |
68 dest_left += dest_width; | |
69 } | |
70 if (dest_height < 0) { | |
71 dest_top += dest_height; | |
72 } | |
73 FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(
dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform); | |
74 delete pFlipped; | |
75 return ret; | |
76 } | 234 } |
77 CFX_DIBExtractor temp(pSource); | 235 dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); |
78 CFX_DIBitmap* pBitmap = temp; | 236 } |
79 if (pBitmap == NULL) { | 237 } |
80 return FALSE; | 238 } else { |
| 239 for (int dest_y = 0; dest_y < result_height; dest_y++) { |
| 240 FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch; |
| 241 for (int dest_x = 0; dest_x < result_width; dest_x++) { |
| 242 int src_x, src_y; |
| 243 result2src_fix.Transform(dest_x, dest_y, src_x, src_y); |
| 244 if (src_x < 0 || src_x >= src_width || src_y < 0 || |
| 245 src_y >= src_height) { |
| 246 continue; |
81 } | 247 } |
82 return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest
_height, color, flags, alpha_flag, pIccTransform); | 248 if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) { |
83 } else { | 249 continue; |
84 ASSERT(pSource != NULL); | |
85 if (pSource->HasAlpha()) { | |
86 return FALSE; | |
87 } | 250 } |
88 if (dest_width < 0 || dest_height < 0) { | 251 dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); |
89 CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_hei
ght < 0); | 252 } |
90 if (pFlipped == NULL) { | 253 } |
91 return FALSE; | 254 } |
92 } | 255 if (pSrcBitmap != src_bitmap) { |
93 if (dest_width < 0) { | 256 delete pSrcBitmap; |
94 dest_left += dest_width; | 257 } |
95 } | 258 return pTempBitmap; |
96 if (dest_height < 0) { | 259 } |
97 dest_top += dest_height; | 260 FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, |
98 } | 261 int bitmap_alpha, |
99 FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(d
est_width), abs(dest_height), flags, pIccTransform); | 262 FX_DWORD color, |
100 delete pFlipped; | 263 const CFX_AffineMatrix* pMatrix, |
101 return ret; | 264 FX_DWORD render_flags, |
| 265 FX_LPVOID& handle, |
| 266 int alpha_flag, |
| 267 void* pIccTransform, |
| 268 int blend_type) { |
| 269 if (bitmap_alpha < 255 || pSource->HasAlpha() || |
| 270 (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) { |
| 271 return FALSE; |
| 272 } |
| 273 CFX_FloatRect unit_rect = pMatrix->GetUnitRect(); |
| 274 FX_RECT full_rect = unit_rect.GetOutterRect(); |
| 275 if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && |
| 276 FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) { |
| 277 FX_BOOL bFlipX = pMatrix->a < 0; |
| 278 FX_BOOL bFlipY = pMatrix->d > 0; |
| 279 return StretchDIBits(pSource, |
| 280 color, |
| 281 bFlipX ? full_rect.right : full_rect.left, |
| 282 bFlipY ? full_rect.bottom : full_rect.top, |
| 283 bFlipX ? -full_rect.Width() : full_rect.Width(), |
| 284 bFlipY ? -full_rect.Height() : full_rect.Height(), |
| 285 NULL, |
| 286 0, |
| 287 alpha_flag, |
| 288 pIccTransform, |
| 289 blend_type); |
| 290 } |
| 291 if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) { |
| 292 CFX_DIBitmap* pTransformed = |
| 293 pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0); |
| 294 if (pTransformed == NULL) { |
| 295 return FALSE; |
| 296 } |
| 297 FX_BOOL ret = StretchDIBits(pTransformed, |
| 298 color, |
| 299 full_rect.left, |
| 300 full_rect.top, |
| 301 full_rect.Width(), |
| 302 full_rect.Height(), |
| 303 NULL, |
| 304 0, |
| 305 alpha_flag, |
| 306 pIccTransform, |
| 307 blend_type); |
| 308 delete pTransformed; |
| 309 return ret; |
| 310 } |
| 311 if (pSource->GetBPP() == 1) { |
| 312 CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix); |
| 313 if (pIccTransform == NULL) { |
| 314 return FALSE; |
| 315 } |
| 316 SaveState(); |
| 317 CFX_PathData path; |
| 318 path.AppendRect(0, 0, 1.0f, 1.0f); |
| 319 SetClip_PathFill(&path, pMatrix, WINDING); |
| 320 FX_BOOL ret = StretchDIBits(pTransformed, |
| 321 color, |
| 322 full_rect.left, |
| 323 full_rect.top, |
| 324 full_rect.Width(), |
| 325 full_rect.Height(), |
| 326 NULL, |
| 327 0, |
| 328 alpha_flag, |
| 329 pIccTransform, |
| 330 blend_type); |
| 331 RestoreState(); |
| 332 delete pTransformed; |
| 333 handle = NULL; |
| 334 return ret; |
| 335 } |
| 336 return FALSE; |
| 337 } |
| 338 CPSOutput::CPSOutput(HDC hDC) { |
| 339 m_hDC = hDC; |
| 340 m_pBuf = NULL; |
| 341 } |
| 342 CPSOutput::~CPSOutput() { |
| 343 if (m_pBuf) { |
| 344 FX_Free(m_pBuf); |
| 345 } |
| 346 } |
| 347 void CPSOutput::Init() { |
| 348 m_pBuf = FX_Alloc(FX_CHAR, 1026); |
| 349 } |
| 350 void CPSOutput::OutputPS(FX_LPCSTR string, int len) { |
| 351 if (len < 0) { |
| 352 len = (int)FXSYS_strlen(string); |
| 353 } |
| 354 int sent_len = 0; |
| 355 while (len > 0) { |
| 356 int send_len = len > 1024 ? 1024 : len; |
| 357 *(FX_WORD*)m_pBuf = send_len; |
| 358 FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len); |
| 359 int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL); |
| 360 sent_len += send_len; |
| 361 len -= send_len; |
| 362 } |
| 363 } |
| 364 CPSPrinterDriver::CPSPrinterDriver() { |
| 365 m_pPSOutput = NULL; |
| 366 m_bCmykOutput = FALSE; |
| 367 } |
| 368 CPSPrinterDriver::~CPSPrinterDriver() { |
| 369 EndRendering(); |
| 370 if (m_pPSOutput) { |
| 371 delete m_pPSOutput; |
| 372 } |
| 373 } |
| 374 FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput) { |
| 375 m_hDC = hDC; |
| 376 m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); |
| 377 m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); |
| 378 m_Width = ::GetDeviceCaps(m_hDC, HORZRES); |
| 379 m_Height = ::GetDeviceCaps(m_hDC, VERTRES); |
| 380 m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); |
| 381 m_pPSOutput = FX_NEW CPSOutput(hDC); |
| 382 if (!m_pPSOutput) { |
| 383 return FALSE; |
| 384 } |
| 385 ((CPSOutput*)m_pPSOutput)->Init(); |
| 386 m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput); |
| 387 m_bCmykOutput = bCmykOutput; |
| 388 HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); |
| 389 int ret = ::GetClipRgn(hDC, hRgn); |
| 390 if (ret == 1) { |
| 391 ret = ::GetRegionData(hRgn, 0, NULL); |
| 392 if (ret) { |
| 393 RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret); |
| 394 if (!pData) { |
| 395 return FALSE; |
| 396 } |
| 397 ret = ::GetRegionData(hRgn, ret, pData); |
| 398 if (ret) { |
| 399 CFX_PathData path; |
| 400 path.AllocPointCount(pData->rdh.nCount * 5); |
| 401 for (FX_DWORD i = 0; i < pData->rdh.nCount; i++) { |
| 402 RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i); |
| 403 path.AppendRect((FX_FLOAT)pRect->left, |
| 404 (FX_FLOAT)pRect->bottom, |
| 405 (FX_FLOAT)pRect->right, |
| 406 (FX_FLOAT)pRect->top); |
102 } | 407 } |
103 CFX_DIBExtractor temp(pSource); | 408 m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING); |
104 CFX_DIBitmap* pBitmap = temp; | 409 } |
105 if (pBitmap == NULL) { | 410 FX_Free(pData); |
106 return FALSE; | 411 } |
107 } | 412 } |
108 return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_
height, flags, pIccTransform); | 413 ::DeleteObject(hRgn); |
109 } | 414 return TRUE; |
110 } | 415 } |
111 static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_Af
fineMatrix* pDestMatrix) | 416 int CPSPrinterDriver::GetDeviceCaps(int caps_id) { |
112 { | 417 switch (caps_id) { |
113 ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bpp
Mask || pSrc->GetFormat() == FXDIB_1bppCmyk); | 418 case FXDC_DEVICE_CLASS: |
114 CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect(); | 419 return FXDC_PRINTER; |
115 FX_RECT full_rect = unit_rect.GetOutterRect(); | 420 case FXDC_PIXEL_WIDTH: |
116 int full_left = full_rect.left; | 421 return m_Width; |
117 int full_top = full_rect.top; | 422 case FXDC_PIXEL_HEIGHT: |
118 CFX_DIBExtractor src_bitmap(pSrc); | 423 return m_Height; |
119 CFX_DIBitmap* pSrcBitmap = src_bitmap; | 424 case FXDC_BITS_PIXEL: |
120 if (pSrcBitmap == NULL) { | 425 return m_nBitsPerPixel; |
121 return NULL; | 426 case FXDC_RENDER_CAPS: |
122 } | 427 return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK; |
123 int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight()
; | 428 case FXDC_HORZ_SIZE: |
124 FX_LPBYTE src_buf = pSrcBitmap->GetBuffer(); | 429 return m_HorzSize; |
125 FX_DWORD src_pitch = pSrcBitmap->GetPitch(); | 430 case FXDC_VERT_SIZE: |
126 FX_FLOAT dest_area = pDestMatrix->GetUnitArea(); | 431 return m_VertSize; |
127 FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_are
a); | 432 } |
128 FX_FLOAT size_scale = FXSYS_sqrt(area_scale); | 433 return 0; |
129 CFX_AffineMatrix adjusted_matrix(*pDestMatrix); | 434 } |
130 adjusted_matrix.Scale(size_scale, size_scale); | 435 FX_BOOL CPSPrinterDriver::StartRendering() { |
131 CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect(); | 436 return m_PSRenderer.StartRendering(); |
132 FX_RECT result_rect = result_rect_f.GetOutterRect(); | 437 } |
133 CFX_AffineMatrix src2result; | 438 void CPSPrinterDriver::EndRendering() { |
134 src2result.e = adjusted_matrix.c + adjusted_matrix.e; | 439 m_PSRenderer.EndRendering(); |
135 src2result.f = adjusted_matrix.d + adjusted_matrix.f; | 440 } |
136 src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth(); | 441 void CPSPrinterDriver::SaveState() { |
137 src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth(); | 442 m_PSRenderer.SaveState(); |
138 src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight(); | 443 } |
139 src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight(); | 444 void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved) { |
140 src2result.TranslateI(-result_rect.left, -result_rect.top); | 445 m_PSRenderer.RestoreState(bKeepSaved); |
141 CFX_AffineMatrix result2src; | 446 } |
142 result2src.SetReverse(src2result); | 447 FX_BOOL CPSPrinterDriver::SetClip_PathFill( |
143 CPDF_FixedMatrix result2src_fix(result2src, 8); | 448 const CFX_PathData* pPathData, |
144 int result_width = result_rect.Width(); | 449 const CFX_AffineMatrix* pObject2Device, |
145 int result_height = result_rect.Height(); | 450 int fill_mode) { |
146 CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap; | 451 m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode); |
147 if (!pTempBitmap) { | 452 return TRUE; |
148 if (pSrcBitmap != src_bitmap) { | 453 } |
149 delete pSrcBitmap; | 454 FX_BOOL CPSPrinterDriver::SetClip_PathStroke( |
150 } | 455 const CFX_PathData* pPathData, |
151 return NULL; | 456 const CFX_AffineMatrix* pObject2Device, |
152 } | 457 const CFX_GraphStateData* pGraphState) { |
153 if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) { | 458 m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState); |
154 delete pTempBitmap; | 459 return TRUE; |
155 if (pSrcBitmap != src_bitmap) { | 460 } |
156 delete pSrcBitmap; | 461 FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData, |
157 } | |
158 return NULL; | |
159 } | |
160 pTempBitmap->CopyPalette(pSrc->GetPalette()); | |
161 FX_LPBYTE dest_buf = pTempBitmap->GetBuffer(); | |
162 int dest_pitch = pTempBitmap->GetPitch(); | |
163 FXSYS_memset8(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_
height); | |
164 if (pSrcBitmap->IsAlphaMask()) { | |
165 for (int dest_y = 0; dest_y < result_height; dest_y ++) { | |
166 FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch; | |
167 for (int dest_x = 0; dest_x < result_width; dest_x ++) { | |
168 int src_x, src_y; | |
169 result2src_fix.Transform(dest_x, dest_y, src_x, src_y); | |
170 if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src
_height) { | |
171 continue; | |
172 } | |
173 if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_
x % 8)))) { | |
174 continue; | |
175 } | |
176 dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8); | |
177 } | |
178 } | |
179 } else { | |
180 for (int dest_y = 0; dest_y < result_height; dest_y ++) { | |
181 FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch; | |
182 for (int dest_x = 0; dest_x < result_width; dest_x ++) { | |
183 int src_x, src_y; | |
184 result2src_fix.Transform(dest_x, dest_y, src_x, src_y); | |
185 if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src
_height) { | |
186 continue; | |
187 } | |
188 if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x
% 8))) { | |
189 continue; | |
190 } | |
191 dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8)); | |
192 } | |
193 } | |
194 } | |
195 if (pSrcBitmap != src_bitmap) { | |
196 delete pSrcBitmap; | |
197 } | |
198 return pTempBitmap; | |
199 } | |
200 FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_
alpha, FX_DWORD color, | |
201 const CFX_AffineMatrix* pMatrix, FX_DWORD
render_flags, FX_LPVOID& handle, | |
202 int alpha_flag, void* pIccTransform, int
blend_type) | |
203 { | |
204 if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() &&
(pSource->GetBPP() != 1 || !m_bSupportROP))) { | |
205 return FALSE; | |
206 } | |
207 CFX_FloatRect unit_rect = pMatrix->GetUnitRect(); | |
208 FX_RECT full_rect = unit_rect.GetOutterRect(); | |
209 if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->
c) < 0.5f && pMatrix->d != 0) { | |
210 FX_BOOL bFlipX = pMatrix->a < 0; | |
211 FX_BOOL bFlipY = pMatrix->d > 0; | |
212 return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rec
t.left, bFlipY ? full_rect.bottom : full_rect.top, | |
213 bFlipX ? -full_rect.Width() : full_rect.Width(), bF
lipY ? -full_rect.Height() : full_rect.Height(), NULL, 0, | |
214 alpha_flag, pIccTransform, blend_type); | |
215 } | |
216 if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) { | |
217 CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b
< 0); | |
218 if (pTransformed == NULL) { | |
219 return FALSE; | |
220 } | |
221 FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_re
ct.top, full_rect.Width(), full_rect.Height(), NULL, 0, | |
222 alpha_flag, pIccTransform, blend_type); | |
223 delete pTransformed; | |
224 return ret; | |
225 } | |
226 if (pSource->GetBPP() == 1) { | |
227 CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix); | |
228 if (pIccTransform == NULL) { | |
229 return FALSE; | |
230 } | |
231 SaveState(); | |
232 CFX_PathData path; | |
233 path.AppendRect(0, 0, 1.0f, 1.0f); | |
234 SetClip_PathFill(&path, pMatrix, WINDING); | |
235 FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_re
ct.top, full_rect.Width(), full_rect.Height(), NULL, 0, | |
236 alpha_flag, pIccTransform, blend_type); | |
237 RestoreState(); | |
238 delete pTransformed; | |
239 handle = NULL; | |
240 return ret; | |
241 } | |
242 return FALSE; | |
243 } | |
244 CPSOutput::CPSOutput(HDC hDC) | |
245 { | |
246 m_hDC = hDC; | |
247 m_pBuf = NULL; | |
248 } | |
249 CPSOutput::~CPSOutput() | |
250 { | |
251 if (m_pBuf) { | |
252 FX_Free(m_pBuf); | |
253 } | |
254 } | |
255 void CPSOutput::Init() | |
256 { | |
257 m_pBuf = FX_Alloc(FX_CHAR, 1026); | |
258 } | |
259 void CPSOutput::OutputPS(FX_LPCSTR string, int len) | |
260 { | |
261 if (len < 0) { | |
262 len = (int)FXSYS_strlen(string); | |
263 } | |
264 int sent_len = 0; | |
265 while (len > 0) { | |
266 int send_len = len > 1024 ? 1024 : len; | |
267 *(FX_WORD*)m_pBuf = send_len; | |
268 FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len); | |
269 int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL); | |
270 sent_len += send_len; | |
271 len -= send_len; | |
272 } | |
273 } | |
274 CPSPrinterDriver::CPSPrinterDriver() | |
275 { | |
276 m_pPSOutput = NULL; | |
277 m_bCmykOutput = FALSE; | |
278 } | |
279 CPSPrinterDriver::~CPSPrinterDriver() | |
280 { | |
281 EndRendering(); | |
282 if (m_pPSOutput) { | |
283 delete m_pPSOutput; | |
284 } | |
285 } | |
286 FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput) | |
287 { | |
288 m_hDC = hDC; | |
289 m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE); | |
290 m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE); | |
291 m_Width = ::GetDeviceCaps(m_hDC, HORZRES); | |
292 m_Height = ::GetDeviceCaps(m_hDC, VERTRES); | |
293 m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); | |
294 m_pPSOutput = FX_NEW CPSOutput(hDC); | |
295 if (!m_pPSOutput) { | |
296 return FALSE; | |
297 } | |
298 ((CPSOutput*)m_pPSOutput)->Init(); | |
299 m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput); | |
300 m_bCmykOutput = bCmykOutput; | |
301 HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1); | |
302 int ret = ::GetClipRgn(hDC, hRgn); | |
303 if (ret == 1) { | |
304 ret = ::GetRegionData(hRgn, 0, NULL); | |
305 if (ret) { | |
306 RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret); | |
307 if (!pData) { | |
308 return FALSE; | |
309 } | |
310 ret = ::GetRegionData(hRgn, ret, pData); | |
311 if (ret) { | |
312 CFX_PathData path; | |
313 path.AllocPointCount(pData->rdh.nCount * 5); | |
314 for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) { | |
315 RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize *
i); | |
316 path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bott
om, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top); | |
317 } | |
318 m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING); | |
319 } | |
320 FX_Free(pData); | |
321 } | |
322 } | |
323 ::DeleteObject(hRgn); | |
324 return TRUE; | |
325 } | |
326 int CPSPrinterDriver::GetDeviceCaps(int caps_id) | |
327 { | |
328 switch (caps_id) { | |
329 case FXDC_DEVICE_CLASS: | |
330 return FXDC_PRINTER; | |
331 case FXDC_PIXEL_WIDTH: | |
332 return m_Width; | |
333 case FXDC_PIXEL_HEIGHT: | |
334 return m_Height; | |
335 case FXDC_BITS_PIXEL: | |
336 return m_nBitsPerPixel; | |
337 case FXDC_RENDER_CAPS: | |
338 return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_M
ASK; | |
339 case FXDC_HORZ_SIZE: | |
340 return m_HorzSize; | |
341 case FXDC_VERT_SIZE: | |
342 return m_VertSize; | |
343 } | |
344 return 0; | |
345 } | |
346 FX_BOOL CPSPrinterDriver::StartRendering() | |
347 { | |
348 return m_PSRenderer.StartRendering(); | |
349 } | |
350 void CPSPrinterDriver::EndRendering() | |
351 { | |
352 m_PSRenderer.EndRendering(); | |
353 } | |
354 void CPSPrinterDriver::SaveState() | |
355 { | |
356 m_PSRenderer.SaveState(); | |
357 } | |
358 void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved) | |
359 { | |
360 m_PSRenderer.RestoreState(bKeepSaved); | |
361 } | |
362 FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const
CFX_AffineMatrix* pObject2Device, | |
363 int fill_mode) | |
364 { | |
365 m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode); | |
366 return TRUE; | |
367 } | |
368 FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData, | |
369 const CFX_AffineMatrix* pObject2Device, | |
370 const CFX_GraphStateData* pGraphState) | |
371 { | |
372 m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState); | |
373 return TRUE; | |
374 } | |
375 FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData, | |
376 const CFX_AffineMatrix* pObject2Device, | 462 const CFX_AffineMatrix* pObject2Device, |
377 const CFX_GraphStateData* pGraphState, FX_ARG
B fill_color, FX_ARGB stroke_color, | 463 const CFX_GraphStateData* pGraphState, |
378 int fill_mode, int alpha_flag, void* pIccTran
sform, int blend_type) | 464 FX_ARGB fill_color, |
379 { | 465 FX_ARGB stroke_color, |
380 if (blend_type != FXDIB_BLEND_NORMAL) { | 466 int fill_mode, |
381 return FALSE; | 467 int alpha_flag, |
382 } | 468 void* pIccTransform, |
383 return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_co
lor, stroke_color, fill_mode & 3, alpha_flag, pIccTransform); | 469 int blend_type) { |
384 } | 470 if (blend_type != FXDIB_BLEND_NORMAL) { |
385 FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect) | 471 return FALSE; |
386 { | 472 } |
387 *pRect = m_PSRenderer.GetClipBox(); | 473 return m_PSRenderer.DrawPath(pPathData, |
388 return TRUE; | 474 pObject2Device, |
389 } | 475 pGraphState, |
390 FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color
, const FX_RECT* pSrcRect, int left, int top, int blend_type, | 476 fill_color, |
391 int alpha_flag, void* pIccTransform) | 477 stroke_color, |
392 { | 478 fill_mode & 3, |
393 if (blend_type != FXDIB_BLEND_NORMAL) { | 479 alpha_flag, |
394 return FALSE; | 480 pIccTransform); |
395 } | 481 } |
396 return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTra
nsform); | 482 FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect) { |
397 } | 483 *pRect = m_PSRenderer.GetClipBox(); |
398 FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD c
olor, int dest_left, int dest_top, | 484 return TRUE; |
399 int dest_width, int dest_height, const F
X_RECT* pClipRect, FX_DWORD flags, | 485 } |
400 int alpha_flag, void* pIccTransform, int
blend_type) | 486 FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, |
401 { | 487 FX_DWORD color, |
402 if (blend_type != FXDIB_BLEND_NORMAL) { | 488 const FX_RECT* pSrcRect, |
403 return FALSE; | 489 int left, |
404 } | 490 int top, |
405 return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_
width, dest_height, flags, alpha_flag, pIccTransform); | 491 int blend_type, |
406 } | 492 int alpha_flag, |
407 FX_BOOL»CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_a
lpha, FX_DWORD color, | 493 void* pIccTransform) { |
408 const CFX_AffineMatrix* pMatrix, FX_DWORD
render_flags, FX_LPVOID& handle, | 494 if (blend_type != FXDIB_BLEND_NORMAL) { |
409 int alpha_flag, void* pIccTransform, int b
lend_type) | 495 return FALSE; |
410 { | 496 } |
411 if (blend_type != FXDIB_BLEND_NORMAL) { | 497 return m_PSRenderer.SetDIBits( |
412 return FALSE; | 498 pBitmap, color, left, top, alpha_flag, pIccTransform); |
413 } | 499 } |
414 if (bitmap_alpha < 255) { | 500 FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, |
415 return FALSE; | 501 FX_DWORD color, |
416 } | 502 int dest_left, |
417 handle = NULL; | 503 int dest_top, |
418 return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_
flag, pIccTransform); | 504 int dest_width, |
419 } | 505 int dest_height, |
420 FX_BOOL»CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pChar
Pos, CFX_Font* pFont, | 506 const FX_RECT* pClipRect, |
421 CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT
font_size, FX_DWORD color, | 507 FX_DWORD flags, |
422 int alpha_flag, void* pIccTransform) | 508 int alpha_flag, |
423 { | 509 void* pIccTransform, |
424 return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device
, font_size, color, alpha_flag, pIccTransform); | 510 int blend_type) { |
| 511 if (blend_type != FXDIB_BLEND_NORMAL) { |
| 512 return FALSE; |
| 513 } |
| 514 return m_PSRenderer.StretchDIBits(pBitmap, |
| 515 color, |
| 516 dest_left, |
| 517 dest_top, |
| 518 dest_width, |
| 519 dest_height, |
| 520 flags, |
| 521 alpha_flag, |
| 522 pIccTransform); |
| 523 } |
| 524 FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, |
| 525 int bitmap_alpha, |
| 526 FX_DWORD color, |
| 527 const CFX_AffineMatrix* pMatrix, |
| 528 FX_DWORD render_flags, |
| 529 FX_LPVOID& handle, |
| 530 int alpha_flag, |
| 531 void* pIccTransform, |
| 532 int blend_type) { |
| 533 if (blend_type != FXDIB_BLEND_NORMAL) { |
| 534 return FALSE; |
| 535 } |
| 536 if (bitmap_alpha < 255) { |
| 537 return FALSE; |
| 538 } |
| 539 handle = NULL; |
| 540 return m_PSRenderer.DrawDIBits( |
| 541 pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform); |
| 542 } |
| 543 FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, |
| 544 const FXTEXT_CHARPOS* pCharPos, |
| 545 CFX_Font* pFont, |
| 546 CFX_FontCache* pCache, |
| 547 const CFX_AffineMatrix* pObject2Device, |
| 548 FX_FLOAT font_size, |
| 549 FX_DWORD color, |
| 550 int alpha_flag, |
| 551 void* pIccTransform) { |
| 552 return m_PSRenderer.DrawText(nChars, |
| 553 pCharPos, |
| 554 pFont, |
| 555 pCache, |
| 556 pObject2Device, |
| 557 font_size, |
| 558 color, |
| 559 alpha_flag, |
| 560 pIccTransform); |
425 } | 561 } |
426 #endif | 562 #endif |
OLD | NEW |