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