Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "psputil.hxx"
31 : :
32 : : #include "generic/printergfx.hxx"
33 : : #include "vcl/strhelper.hxx"
34 : :
35 : : namespace psp {
36 : :
37 : : const sal_uInt32 nLineLength = 80;
38 : : const sal_uInt32 nBufferSize = 16384;
39 : :
40 : : /*
41 : : *
42 : : * Bitmap compression / Hex encoding / Ascii85 Encoding
43 : : *
44 : : */
45 : :
46 : 0 : PrinterBmp::~PrinterBmp ()
47 [ # # ]: 0 : { /* dont need this, but C50 does */ }
48 : :
49 : : /* virtual base class */
50 : :
51 : 0 : class ByteEncoder
52 : : {
53 : : private:
54 : :
55 : : public:
56 : :
57 : : virtual void EncodeByte (sal_uInt8 nByte) = 0;
58 : : virtual ~ByteEncoder () = 0;
59 : : };
60 : :
61 : 0 : ByteEncoder::~ByteEncoder ()
62 [ # # ]: 0 : { /* dont need this, but the C50 does */ }
63 : :
64 : : /* HexEncoder */
65 : :
66 : : class HexEncoder : public ByteEncoder
67 : : {
68 : : private:
69 : :
70 : : osl::File* mpFile;
71 : : sal_uInt32 mnColumn;
72 : : sal_uInt32 mnOffset;
73 : : sal_Char mpFileBuffer[nBufferSize + 16];
74 : :
75 : : HexEncoder (); /* dont use */
76 : :
77 : : public:
78 : :
79 : : HexEncoder (osl::File* pFile);
80 : : virtual ~HexEncoder ();
81 : : void WriteAscii (sal_uInt8 nByte);
82 : : virtual void EncodeByte (sal_uInt8 nByte);
83 : : void FlushLine ();
84 : : };
85 : :
86 : 0 : HexEncoder::HexEncoder (osl::File* pFile) :
87 : : mpFile (pFile),
88 : : mnColumn (0),
89 : 0 : mnOffset (0)
90 : 0 : {}
91 : :
92 : 0 : HexEncoder::~HexEncoder ()
93 : : {
94 [ # # ]: 0 : FlushLine ();
95 [ # # ]: 0 : if (mnColumn > 0)
96 [ # # ]: 0 : WritePS (mpFile, "\n");
97 [ # # ]: 0 : }
98 : :
99 : : void
100 : 0 : HexEncoder::WriteAscii (sal_uInt8 nByte)
101 : : {
102 : 0 : sal_uInt32 nOff = psp::getHexValueOf (nByte, mpFileBuffer + mnOffset);
103 : 0 : mnColumn += nOff;
104 : 0 : mnOffset += nOff;
105 : :
106 [ # # ]: 0 : if (mnColumn >= nLineLength)
107 : : {
108 : 0 : mnOffset += psp::appendStr ("\n", mpFileBuffer + mnOffset);
109 : 0 : mnColumn = 0;
110 : : }
111 [ # # ]: 0 : if (mnOffset >= nBufferSize)
112 : 0 : FlushLine ();
113 : 0 : }
114 : :
115 : : void
116 : 0 : HexEncoder::EncodeByte (sal_uInt8 nByte)
117 : : {
118 : 0 : WriteAscii (nByte);
119 : 0 : }
120 : :
121 : : void
122 : 0 : HexEncoder::FlushLine ()
123 : : {
124 [ # # ]: 0 : if (mnOffset > 0)
125 : : {
126 : 0 : WritePS (mpFile, mpFileBuffer, mnOffset);
127 : 0 : mnOffset = 0;
128 : : }
129 : 0 : }
130 : :
131 : : /* Ascii85 encoder, is abi compatible with HexEncoder but writes a ~> to
132 : : indicate end of data EOD */
133 : :
134 : : class Ascii85Encoder : public ByteEncoder
135 : : {
136 : : private:
137 : :
138 : : osl::File* mpFile;
139 : : sal_uInt32 mnByte;
140 : : sal_uInt8 mpByteBuffer[4];
141 : :
142 : : sal_uInt32 mnColumn;
143 : : sal_uInt32 mnOffset;
144 : : sal_Char mpFileBuffer[nBufferSize + 16];
145 : :
146 : : Ascii85Encoder (); /* dont use */
147 : :
148 : : inline void PutByte (sal_uInt8 nByte);
149 : : inline void PutEOD ();
150 : : void ConvertToAscii85 ();
151 : : void FlushLine ();
152 : :
153 : : public:
154 : :
155 : : Ascii85Encoder (osl::File* pFile);
156 : : virtual ~Ascii85Encoder ();
157 : : virtual void EncodeByte (sal_uInt8 nByte);
158 : : void WriteAscii (sal_uInt8 nByte);
159 : : };
160 : :
161 : 0 : Ascii85Encoder::Ascii85Encoder (osl::File* pFile) :
162 : : mpFile (pFile),
163 : : mnByte (0),
164 : : mnColumn (0),
165 : 0 : mnOffset (0)
166 : 0 : {}
167 : :
168 : : inline void
169 : 0 : Ascii85Encoder::PutByte (sal_uInt8 nByte)
170 : : {
171 : 0 : mpByteBuffer [mnByte++] = nByte;
172 : 0 : }
173 : :
174 : : inline void
175 : 0 : Ascii85Encoder::PutEOD ()
176 : : {
177 : 0 : WritePS (mpFile, "~>\n");
178 : 0 : }
179 : :
180 : : void
181 : 0 : Ascii85Encoder::ConvertToAscii85 ()
182 : : {
183 [ # # ]: 0 : if (mnByte < 4)
184 : 0 : std::memset (mpByteBuffer + mnByte, 0, (4 - mnByte) * sizeof(sal_uInt8));
185 : :
186 : 0 : sal_uInt32 nByteValue = mpByteBuffer[0] * 256 * 256 * 256
187 : 0 : + mpByteBuffer[1] * 256 * 256
188 : 0 : + mpByteBuffer[2] * 256
189 : 0 : + mpByteBuffer[3];
190 : :
191 [ # # ][ # # ]: 0 : if (nByteValue == 0 && mnByte == 4)
192 : : {
193 : : /* special case of 4 Bytes in row */
194 : 0 : mpFileBuffer [mnOffset] = 'z';
195 : :
196 : 0 : mnOffset += 1;
197 : 0 : mnColumn += 1;
198 : : }
199 : : else
200 : : {
201 : : /* real ascii85 encoding */
202 : 0 : mpFileBuffer [mnOffset + 4] = (nByteValue % 85) + 33;
203 : 0 : nByteValue /= 85;
204 : 0 : mpFileBuffer [mnOffset + 3] = (nByteValue % 85) + 33;
205 : 0 : nByteValue /= 85;
206 : 0 : mpFileBuffer [mnOffset + 2] = (nByteValue % 85) + 33;
207 : 0 : nByteValue /= 85;
208 : 0 : mpFileBuffer [mnOffset + 1] = (nByteValue % 85) + 33;
209 : 0 : nByteValue /= 85;
210 : 0 : mpFileBuffer [mnOffset + 0] = (nByteValue % 85) + 33;
211 : :
212 : 0 : mnColumn += (mnByte + 1);
213 : 0 : mnOffset += (mnByte + 1);
214 : :
215 : : /* insert a newline if necessary */
216 [ # # ]: 0 : if (mnColumn > nLineLength)
217 : : {
218 : 0 : sal_uInt32 nEolOff = mnColumn - nLineLength;
219 : 0 : sal_uInt32 nBufOff = mnOffset - nEolOff;
220 : :
221 : 0 : std::memmove (mpFileBuffer + nBufOff + 1, mpFileBuffer + nBufOff, nEolOff);
222 : 0 : mpFileBuffer[ nBufOff ] = '\n';
223 : :
224 : 0 : mnOffset++;
225 : 0 : mnColumn = nEolOff;
226 : : }
227 : : }
228 : :
229 : 0 : mnByte = 0;
230 : 0 : }
231 : :
232 : : void
233 : 0 : Ascii85Encoder::WriteAscii (sal_uInt8 nByte)
234 : : {
235 : 0 : PutByte (nByte);
236 [ # # ]: 0 : if (mnByte == 4)
237 : 0 : ConvertToAscii85 ();
238 : :
239 [ # # ]: 0 : if (mnColumn >= nLineLength)
240 : : {
241 : 0 : mnOffset += psp::appendStr ("\n", mpFileBuffer + mnOffset);
242 : 0 : mnColumn = 0;
243 : : }
244 [ # # ]: 0 : if (mnOffset >= nBufferSize)
245 : 0 : FlushLine ();
246 : 0 : }
247 : :
248 : : void
249 : 0 : Ascii85Encoder::EncodeByte (sal_uInt8 nByte)
250 : : {
251 : 0 : WriteAscii (nByte);
252 : 0 : }
253 : :
254 : : void
255 : 0 : Ascii85Encoder::FlushLine ()
256 : : {
257 [ # # ]: 0 : if (mnOffset > 0)
258 : : {
259 : 0 : WritePS (mpFile, mpFileBuffer, mnOffset);
260 : 0 : mnOffset = 0;
261 : : }
262 : 0 : }
263 : :
264 : 0 : Ascii85Encoder::~Ascii85Encoder ()
265 : : {
266 [ # # ]: 0 : if (mnByte > 0)
267 : 0 : ConvertToAscii85 ();
268 [ # # ]: 0 : if (mnOffset > 0)
269 [ # # ]: 0 : FlushLine ();
270 [ # # ]: 0 : PutEOD ();
271 [ # # ]: 0 : }
272 : :
273 : : /* LZW encoder */
274 : :
275 : : class LZWEncoder : public Ascii85Encoder
276 : : {
277 : : private:
278 : :
279 : : struct LZWCTreeNode
280 : : {
281 : : LZWCTreeNode* mpBrother; // next node with same parent
282 : : LZWCTreeNode* mpFirstChild; // first son
283 : : sal_uInt16 mnCode; // code for the string
284 : : sal_uInt16 mnValue; // pixelvalue
285 : : };
286 : :
287 : : LZWCTreeNode* mpTable; // LZW compression data
288 : : LZWCTreeNode* mpPrefix; // the compression is as same as the TIFF compression
289 : : sal_uInt16 mnDataSize;
290 : : sal_uInt16 mnClearCode;
291 : : sal_uInt16 mnEOICode;
292 : : sal_uInt16 mnTableSize;
293 : : sal_uInt16 mnCodeSize;
294 : : sal_uInt32 mnOffset;
295 : : sal_uInt32 mdwShift;
296 : :
297 : : LZWEncoder ();
298 : : void WriteBits (sal_uInt16 nCode, sal_uInt16 nCodeLen);
299 : :
300 : : public:
301 : :
302 : : LZWEncoder (osl::File* pOutputFile);
303 : : ~LZWEncoder ();
304 : :
305 : : virtual void EncodeByte (sal_uInt8 nByte);
306 : : };
307 : :
308 : 0 : LZWEncoder::LZWEncoder(osl::File* pOutputFile) :
309 : 0 : Ascii85Encoder (pOutputFile)
310 : : {
311 : 0 : mnDataSize = 8;
312 : :
313 : 0 : mnClearCode = 1 << mnDataSize;
314 : 0 : mnEOICode = mnClearCode + 1;
315 : 0 : mnTableSize = mnEOICode + 1;
316 : 0 : mnCodeSize = mnDataSize + 1;
317 : :
318 : 0 : mnOffset = 32; // free bits in dwShift
319 : 0 : mdwShift = 0;
320 : :
321 [ # # ]: 0 : mpTable = new LZWCTreeNode[ 4096 ];
322 : :
323 [ # # ]: 0 : for (sal_uInt32 i = 0; i < 4096; i++)
324 : : {
325 : 0 : mpTable[i].mpBrother = NULL;
326 : 0 : mpTable[i].mpFirstChild = NULL;
327 : 0 : mpTable[i].mnCode = i;
328 : 0 : mpTable[i].mnValue = (sal_uInt8)mpTable[i].mnCode;
329 : : }
330 : :
331 : 0 : mpPrefix = NULL;
332 : :
333 [ # # ]: 0 : WriteBits( mnClearCode, mnCodeSize );
334 : 0 : }
335 : :
336 : 0 : LZWEncoder::~LZWEncoder()
337 : : {
338 [ # # ]: 0 : if (mpPrefix)
339 [ # # ]: 0 : WriteBits (mpPrefix->mnCode, mnCodeSize);
340 : :
341 [ # # ]: 0 : WriteBits (mnEOICode, mnCodeSize);
342 : :
343 [ # # ]: 0 : delete[] mpTable;
344 [ # # ]: 0 : }
345 : :
346 : : void
347 : 0 : LZWEncoder::WriteBits (sal_uInt16 nCode, sal_uInt16 nCodeLen)
348 : : {
349 : 0 : mdwShift |= (nCode << (mnOffset - nCodeLen));
350 : 0 : mnOffset -= nCodeLen;
351 [ # # ]: 0 : while (mnOffset < 24)
352 : : {
353 : 0 : WriteAscii ((sal_uInt8)(mdwShift >> 24));
354 : 0 : mdwShift <<= 8;
355 : 0 : mnOffset += 8;
356 : : }
357 [ # # ][ # # ]: 0 : if (nCode == 257 && mnOffset != 32)
358 : 0 : WriteAscii ((sal_uInt8)(mdwShift >> 24));
359 : 0 : }
360 : :
361 : : void
362 : 0 : LZWEncoder::EncodeByte (sal_uInt8 nByte )
363 : : {
364 : : LZWCTreeNode* p;
365 : : sal_uInt16 i;
366 : : sal_uInt8 nV;
367 : :
368 [ # # ]: 0 : if (!mpPrefix)
369 : : {
370 : 0 : mpPrefix = mpTable + nByte;
371 : : }
372 : : else
373 : : {
374 : 0 : nV = nByte;
375 [ # # ]: 0 : for (p = mpPrefix->mpFirstChild; p != NULL; p = p->mpBrother)
376 : : {
377 [ # # ]: 0 : if (p->mnValue == nV)
378 : 0 : break;
379 : : }
380 : :
381 [ # # ]: 0 : if (p != NULL)
382 : : {
383 : 0 : mpPrefix = p;
384 : : }
385 : : else
386 : : {
387 : 0 : WriteBits (mpPrefix->mnCode, mnCodeSize);
388 : :
389 [ # # ]: 0 : if (mnTableSize == 409)
390 : : {
391 : 0 : WriteBits (mnClearCode, mnCodeSize);
392 : :
393 [ # # ]: 0 : for (i = 0; i < mnClearCode; i++)
394 : 0 : mpTable[i].mpFirstChild = NULL;
395 : :
396 : 0 : mnCodeSize = mnDataSize + 1;
397 : 0 : mnTableSize = mnEOICode + 1;
398 : : }
399 : : else
400 : : {
401 [ # # ]: 0 : if(mnTableSize == (sal_uInt16)((1 << mnCodeSize) - 1))
402 : 0 : mnCodeSize++;
403 : :
404 : 0 : p = mpTable + (mnTableSize++);
405 : 0 : p->mpBrother = mpPrefix->mpFirstChild;
406 : 0 : mpPrefix->mpFirstChild = p;
407 : 0 : p->mnValue = nV;
408 : 0 : p->mpFirstChild = NULL;
409 : : }
410 : :
411 : 0 : mpPrefix = mpTable + nV;
412 : : }
413 : : }
414 : 0 : }
415 : :
416 : : /*
417 : : *
418 : : * bitmap handling routines
419 : : *
420 : : */
421 : :
422 : : void
423 : 0 : PrinterGfx::DrawBitmap (const Rectangle& rDest, const Rectangle& rSrc,
424 : : const PrinterBmp& rBitmap)
425 : : {
426 : 0 : double fScaleX = (double)rDest.GetWidth() / (double)rSrc.GetWidth();
427 : 0 : double fScaleY = (double)rDest.GetHeight() / (double)rSrc.GetHeight();
428 : :
429 : 0 : PSGSave ();
430 [ # # ]: 0 : PSTranslate (rDest.BottomLeft());
431 : 0 : PSScale (fScaleX, fScaleY);
432 : :
433 [ # # ]: 0 : if (mnPSLevel >= 2)
434 : : {
435 [ # # ]: 0 : if (rBitmap.GetDepth() == 1)
436 : : {
437 : 0 : DrawPS2MonoImage (rBitmap, rSrc);
438 : : }
439 : : else
440 [ # # ][ # # ]: 0 : if (rBitmap.GetDepth() == 8 && mbColor)
[ # # ]
441 : : {
442 : : // if the palette is larger than the image itself print it as a truecolor
443 : : // image to save diskspace. This is important for printing transparent
444 : : // bitmaps that are disassembled into small pieces
445 : 0 : sal_Int32 nImageSz = rSrc.GetWidth() * rSrc.GetHeight();
446 : 0 : sal_Int32 nPaletteSz = rBitmap.GetPaletteEntryCount();
447 [ # # ][ # # ]: 0 : if ((nImageSz < nPaletteSz) || (nImageSz < 24) )
448 : 0 : DrawPS2TrueColorImage (rBitmap, rSrc);
449 : : else
450 : 0 : DrawPS2PaletteImage (rBitmap, rSrc);
451 : : }
452 : : else
453 [ # # ][ # # ]: 0 : if (rBitmap.GetDepth() == 24 && mbColor)
[ # # ]
454 : : {
455 : 0 : DrawPS2TrueColorImage (rBitmap, rSrc);
456 : : }
457 : : else
458 : : {
459 : 0 : DrawPS2GrayImage (rBitmap, rSrc);
460 : : }
461 : : }
462 : : else
463 : : {
464 : 0 : DrawPS1GrayImage (rBitmap, rSrc);
465 : : }
466 : :
467 : 0 : PSGRestore ();
468 : 0 : }
469 : :
470 : : /*
471 : : *
472 : : * Implementation: PS Level 1
473 : : *
474 : : */
475 : :
476 : : void
477 : 0 : PrinterGfx::DrawPS1GrayImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
478 : : {
479 [ # # ]: 0 : sal_uInt32 nWidth = rArea.GetWidth();
480 [ # # ]: 0 : sal_uInt32 nHeight = rArea.GetHeight();
481 : :
482 : : sal_Char pGrayImage [512];
483 : 0 : sal_Int32 nChar = 0;
484 : :
485 : : // image header
486 [ # # ]: 0 : nChar += psp::getValueOf (nWidth, pGrayImage + nChar);
487 [ # # ]: 0 : nChar += psp::appendStr (" ", pGrayImage + nChar);
488 [ # # ]: 0 : nChar += psp::getValueOf (nHeight, pGrayImage + nChar);
489 [ # # ]: 0 : nChar += psp::appendStr (" 8 ", pGrayImage + nChar);
490 [ # # ]: 0 : nChar += psp::appendStr ("[ 1 0 0 1 0 ", pGrayImage + nChar);
491 [ # # ]: 0 : nChar += psp::getValueOf (nHeight, pGrayImage + nChar);
492 [ # # ]: 0 : nChar += psp::appendStr ("]", pGrayImage + nChar);
493 [ # # ]: 0 : nChar += psp::appendStr (" {currentfile ", pGrayImage + nChar);
494 [ # # ]: 0 : nChar += psp::getValueOf (nWidth, pGrayImage + nChar);
495 [ # # ]: 0 : nChar += psp::appendStr (" string readhexstring pop}\n", pGrayImage + nChar);
496 [ # # ]: 0 : nChar += psp::appendStr ("image\n", pGrayImage + nChar);
497 : :
498 [ # # ]: 0 : WritePS (mpPageBody, pGrayImage);
499 : :
500 : : // image body
501 [ # # ]: 0 : HexEncoder* pEncoder = new HexEncoder (mpPageBody);
502 : :
503 [ # # ]: 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
504 : : {
505 [ # # ]: 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
506 : : {
507 [ # # ]: 0 : sal_uChar nByte = rBitmap.GetPixelGray (nRow, nColumn);
508 [ # # ]: 0 : pEncoder->EncodeByte (nByte);
509 : : }
510 : : }
511 : :
512 [ # # ][ # # ]: 0 : delete pEncoder;
513 : :
514 [ # # ]: 0 : WritePS (mpPageBody, "\n");
515 : 0 : }
516 : :
517 : : /*
518 : : *
519 : : * Implementation: PS Level 2
520 : : *
521 : : */
522 : :
523 : : void
524 : 0 : PrinterGfx::writePS2ImageHeader (const Rectangle& rArea, psp::ImageType nType)
525 : : {
526 : 0 : sal_Int32 nChar = 0;
527 : : sal_Char pImage [512];
528 : :
529 : 0 : sal_Int32 nDictType = 0;
530 [ # # # # : 0 : switch (nType)
# ]
531 : : {
532 : 0 : case psp::TrueColorImage: nDictType = 0; break;
533 : 0 : case psp::PaletteImage: nDictType = 1; break;
534 : 0 : case psp::GrayScaleImage: nDictType = 2; break;
535 : 0 : case psp::MonochromeImage: nDictType = 3; break;
536 : 0 : default: break;
537 : : }
538 [ # # ]: 0 : sal_Int32 nCompressType = mbCompressBmp ? 1 : 0;
539 : :
540 [ # # ][ # # ]: 0 : nChar += psp::getValueOf (rArea.GetWidth(), pImage + nChar);
541 [ # # ]: 0 : nChar += psp::appendStr (" ", pImage + nChar);
542 [ # # ][ # # ]: 0 : nChar += psp::getValueOf (rArea.GetHeight(), pImage + nChar);
543 [ # # ]: 0 : nChar += psp::appendStr (" ", pImage + nChar);
544 [ # # ]: 0 : nChar += psp::getValueOf (nDictType, pImage + nChar);
545 [ # # ]: 0 : nChar += psp::appendStr (" ", pImage + nChar);
546 [ # # ]: 0 : nChar += psp::getValueOf (nCompressType, pImage + nChar);
547 [ # # ]: 0 : nChar += psp::appendStr (" psp_imagedict image\n", pImage + nChar);
548 : :
549 [ # # ]: 0 : WritePS (mpPageBody, pImage);
550 : 0 : }
551 : :
552 : : void
553 : 0 : PrinterGfx::writePS2Colorspace(const PrinterBmp& rBitmap, psp::ImageType nType)
554 : : {
555 [ # # # # ]: 0 : switch (nType)
556 : : {
557 : : case psp::GrayScaleImage:
558 : :
559 : 0 : WritePS (mpPageBody, "/DeviceGray setcolorspace\n");
560 : 0 : break;
561 : :
562 : : case psp::TrueColorImage:
563 : :
564 : 0 : WritePS (mpPageBody, "/DeviceRGB setcolorspace\n");
565 : 0 : break;
566 : :
567 : : case psp::MonochromeImage:
568 : : case psp::PaletteImage:
569 : : {
570 : :
571 : 0 : sal_Int32 nChar = 0;
572 : : sal_Char pImage [4096];
573 : :
574 [ # # ]: 0 : const sal_uInt32 nSize = rBitmap.GetPaletteEntryCount();
575 : :
576 [ # # ]: 0 : nChar += psp::appendStr ("[/Indexed /DeviceRGB ", pImage + nChar);
577 [ # # ]: 0 : nChar += psp::getValueOf (nSize - 1, pImage + nChar);
578 [ # # ]: 0 : if (mbCompressBmp)
579 [ # # ]: 0 : nChar += psp::appendStr ("\npsp_lzwstring\n", pImage + nChar);
580 : : else
581 [ # # ]: 0 : nChar += psp::appendStr ("\npsp_ascii85string\n", pImage + nChar);
582 [ # # ]: 0 : WritePS (mpPageBody, pImage);
583 : :
584 [ # # ]: 0 : ByteEncoder* pEncoder = mbCompressBmp ? new LZWEncoder(mpPageBody)
585 [ # # ][ # # ]: 0 : : new Ascii85Encoder(mpPageBody);
[ # # ]
586 [ # # ]: 0 : for (sal_uInt32 i = 0; i < nSize; i++)
587 : : {
588 [ # # ]: 0 : PrinterColor aColor = rBitmap.GetPaletteColor(i);
589 : :
590 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetRed());
591 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetGreen());
592 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetBlue());
593 : 0 : }
594 [ # # ][ # # ]: 0 : delete pEncoder;
595 : :
596 [ # # ]: 0 : WritePS (mpPageBody, "pop ] setcolorspace\n");
597 : : }
598 : 0 : break;
599 : 0 : default: break;
600 : : }
601 : 0 : }
602 : :
603 : : void
604 : 0 : PrinterGfx::DrawPS2GrayImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
605 : : {
606 : 0 : writePS2Colorspace(rBitmap, psp::GrayScaleImage);
607 : 0 : writePS2ImageHeader(rArea, psp::GrayScaleImage);
608 : :
609 [ # # ]: 0 : ByteEncoder* pEncoder = mbCompressBmp ? new LZWEncoder(mpPageBody)
610 [ # # ]: 0 : : new Ascii85Encoder(mpPageBody);
611 : :
612 [ # # ]: 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
613 : : {
614 [ # # ]: 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
615 : : {
616 : 0 : sal_uChar nByte = rBitmap.GetPixelGray (nRow, nColumn);
617 : 0 : pEncoder->EncodeByte (nByte);
618 : : }
619 : : }
620 : :
621 [ # # ]: 0 : delete pEncoder;
622 : 0 : }
623 : :
624 : : void
625 : 0 : PrinterGfx::DrawPS2MonoImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
626 : : {
627 : 0 : writePS2Colorspace(rBitmap, psp::MonochromeImage);
628 : 0 : writePS2ImageHeader(rArea, psp::MonochromeImage);
629 : :
630 [ # # ]: 0 : ByteEncoder* pEncoder = mbCompressBmp ? new LZWEncoder(mpPageBody)
631 [ # # ]: 0 : : new Ascii85Encoder(mpPageBody);
632 : :
633 [ # # ]: 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
634 : : {
635 : 0 : long nBitPos = 0;
636 : 0 : sal_uChar nBit = 0;
637 : 0 : sal_uChar nByte = 0;
638 : :
639 [ # # ]: 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
640 : : {
641 : 0 : nBit = rBitmap.GetPixelIdx (nRow, nColumn);
642 : 0 : nByte |= nBit << (7 - nBitPos);
643 : :
644 [ # # ]: 0 : if (++nBitPos == 8)
645 : : {
646 : 0 : pEncoder->EncodeByte (nByte);
647 : 0 : nBitPos = 0;
648 : 0 : nByte = 0;
649 : : }
650 : : }
651 : : // keep the row byte aligned
652 [ # # ]: 0 : if (nBitPos != 0)
653 : 0 : pEncoder->EncodeByte (nByte);
654 : : }
655 : :
656 [ # # ]: 0 : delete pEncoder;
657 : 0 : }
658 : :
659 : : void
660 : 0 : PrinterGfx::DrawPS2PaletteImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
661 : : {
662 : 0 : writePS2Colorspace(rBitmap, psp::PaletteImage);
663 : 0 : writePS2ImageHeader(rArea, psp::PaletteImage);
664 : :
665 [ # # ]: 0 : ByteEncoder* pEncoder = mbCompressBmp ? new LZWEncoder(mpPageBody)
666 [ # # ]: 0 : : new Ascii85Encoder(mpPageBody);
667 : :
668 [ # # ]: 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
669 : : {
670 [ # # ]: 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
671 : : {
672 : 0 : sal_uChar nByte = rBitmap.GetPixelIdx (nRow, nColumn);
673 : 0 : pEncoder->EncodeByte (nByte);
674 : : }
675 : : }
676 : :
677 [ # # ]: 0 : delete pEncoder;
678 : 0 : }
679 : :
680 : : void
681 : 0 : PrinterGfx::DrawPS2TrueColorImage (const PrinterBmp& rBitmap, const Rectangle& rArea)
682 : : {
683 : 0 : writePS2Colorspace(rBitmap, psp::TrueColorImage);
684 : 0 : writePS2ImageHeader(rArea, psp::TrueColorImage);
685 : :
686 [ # # ]: 0 : ByteEncoder* pEncoder = mbCompressBmp ? new LZWEncoder(mpPageBody)
687 [ # # ]: 0 : : new Ascii85Encoder(mpPageBody);
688 : :
689 [ # # ]: 0 : for (long nRow = rArea.Top(); nRow <= rArea.Bottom(); nRow++)
690 : : {
691 [ # # ]: 0 : for (long nColumn = rArea.Left(); nColumn <= rArea.Right(); nColumn++)
692 : : {
693 [ # # ]: 0 : PrinterColor aColor = rBitmap.GetPixelRGB (nRow, nColumn);
694 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetRed());
695 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetGreen());
696 [ # # ]: 0 : pEncoder->EncodeByte (aColor.GetBlue());
697 : 0 : }
698 : : }
699 : :
700 [ # # ]: 0 : delete pEncoder;
701 : 0 : }
702 : :
703 : : } /* namespace psp */
704 : :
705 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|