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