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