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