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