Changeset 3436 for pkpgcounter/trunk/pkpgpdls/pclxl.py
- Timestamp:
- 10/06/08 00:22:07 (16 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
pkpgcounter/trunk/pkpgpdls/pclxl.py
r3409 r3436 8 8 # the Free Software Foundation, either version 3 of the License, or 9 9 # (at your option) any later version. 10 # 10 # 11 11 # This program is distributed in the hope that it will be useful, 12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 # GNU General Public License for more details. 15 # 15 # 16 16 # You should have received a copy of the GNU General Public License 17 17 # along with this program. If not, see <http://www.gnu.org/licenses/>. … … 32 32 class Parser(pdlparser.PDLParser) : 33 33 """A parser for PCLXL (aka PCL6) documents.""" 34 totiffcommands = [ 'pcl6 -sDEVICE=pdfwrite -r"%(dpi)i" -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -', 34 totiffcommands = [ 'pcl6 -sDEVICE=pdfwrite -r"%(dpi)i" -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -', 35 35 'pcl6 -sDEVICE=pswrite -r"%(dpi)i" -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -sOutputFile=- "%(infname)s" | gs -sDEVICE=tiff24nc -dPARANOIDSAFER -dNOPAUSE -dBATCH -dQUIET -r"%(dpi)i" -sOutputFile="%(outfname)s" -', 36 36 ] 37 37 required = [ "pcl6", "gs" ] 38 38 format = "PCLXL (aka PCL6)" 39 mediasizes = { 39 mediasizes = { 40 40 0 : "Letter", 41 41 1 : "Legal", … … 61 61 21 : "JISExec", 62 62 96 : "Default", 63 } 64 65 mediasources = { 63 } 64 65 mediasources = { 66 66 0 : "Default", 67 67 1 : "Auto", … … 73 73 7 : "ThirdCassette", 74 74 } 75 76 orientations = { 75 76 orientations = { 77 77 0 : "Portrait", 78 78 1 : "Landscape", … … 81 81 4 : "Default", 82 82 } 83 84 def isValid(self) : 83 84 def isValid(self) : 85 85 """Returns True if data is HP PCLXL aka PCL6, or Brother's' XL2HB, else False.""" 86 86 if (((self.firstblock[:128].find("\033%-12345X") != -1) and \ … … 94 94 self.format = "XL2HB" 95 95 return True 96 else : 96 else : 97 97 return False 98 98 99 99 def beginPage(self, nextpos) : 100 100 """Indicates the beginning of a new page, and extracts media information.""" 101 101 # self.logdebug("BeginPage at %x" % nextpos) 102 102 self.pagecount += 1 103 103 104 104 # Default values 105 105 mediatypelabel = "Plain" … … 108 108 orientationlabel = "Portrait" 109 109 duplexmode = None 110 110 111 111 # Now go upstream to decode media type, size, source, and orientation 112 112 # this saves time because we don't need a complete parser ! … … 117 117 if val in (0x44, 0x48, 0x41) : # if previous endPage or openDataSource or beginSession (first page) 118 118 break 119 if val == 0x26 : 119 if val == 0x26 : 120 120 mediasource = ord(minfile[pos - 2]) 121 121 mediasourcelabel = self.mediasources.get(mediasource, str(mediasource)) … … 132 132 mediasizelabel = minfile[pos+2:pos+2+arraylength].title() 133 133 pos -= 1 134 else : 134 else : 135 135 # if we just found an ubyte, then the media 136 136 # size is known by its index 137 137 mediasize = ord(minfile[pos+1]) 138 138 mediasizelabel = self.mediasizes.get(mediasize, str(mediasize)) 139 pos -= 1 139 pos -= 1 140 140 # self.logdebug("Media size : %s" % mediasizelabel) 141 elif val == 0x28 : 141 elif val == 0x28 : 142 142 orientation = ord(minfile[pos - 2]) 143 143 orientationlabel = self.orientations.get(orientation, str(orientation)) 144 144 pos -= 4 145 elif val == 0x27 : 145 elif val == 0x27 : 146 146 savepos = pos 147 147 pos -= 1 148 startpos = size = None 148 startpos = size = None 149 149 while pos > 0 : # safety check : don't go back to far ! 150 150 val = ord(minfile[pos]) 151 pos -= 1 151 pos -= 1 152 152 if val == 0xc8 : 153 153 length = self.tags[ord(minfile[pos+2])] # will probably always be a byte or uint16 154 if length == 1 : 154 if length == 1 : 155 155 startpos = pos + 4 156 156 size = unpack("B", self.minfile[pos+3:startpos])[0] 157 elif length == 2 : 157 elif length == 2 : 158 158 startpos = pos + 5 159 159 size = unpack(self.unpackShort, self.minfile[pos+3:startpos])[0] 160 elif length == 4 : 160 elif length == 4 : 161 161 startpos = pos + 7 162 162 size = unpack(self.unpackLong, self.minfile[pos+3:startpos])[0] 163 else : 163 else : 164 164 raise pdlparser.PDLParserError, "Error on size at %s : %s" % (pos+2, length) 165 165 break 166 166 mediatypelabel = minfile[startpos:startpos+size] 167 167 # self.logdebug("Media type : %s" % mediatypelabel) 168 elif val == 0x34 : 168 elif val == 0x34 : 169 169 duplexmode = "Simplex" 170 170 pos -= 2 171 elif val in (0x35, 0x36) : 171 elif val in (0x35, 0x36) : 172 172 duplexmode = "Duplex" 173 173 pos -= 2 174 # else : TODO : CUSTOM MEDIA SIZE AND UNIT ! 175 else : 174 # else : TODO : CUSTOM MEDIA SIZE AND UNIT ! 175 else : 176 176 pos -= 1 # ignored 177 self.pages[self.pagecount] = { "copies" : 1, 178 "orientation" : orientationlabel, 179 "mediatype" : mediatypelabel, 177 self.pages[self.pagecount] = { "copies" : 1, 178 "orientation" : orientationlabel, 179 "mediatype" : mediatypelabel, 180 180 "mediasize" : mediasizelabel, 181 181 "mediasource" : mediasourcelabel, 182 182 "duplex" : duplexmode, 183 } 183 } 184 184 return 0 185 186 def endPage(self, nextpos) : 185 186 def endPage(self, nextpos) : 187 187 """Indicates the end of a page.""" 188 188 # self.logdebug("EndPage at %x" % nextpos) … … 198 198 # self.logdebug("Number of copies : %i" % nbcopies) 199 199 self.pages[self.pagecount]["copies"] = nbcopies 200 except KeyError : 200 except KeyError : 201 201 self.logdebug("It looks like this PCLXL file is corrupted.") 202 202 return 0 203 204 def setColorSpace(self, nextpos) : 203 204 def setColorSpace(self, nextpos) : 205 205 """Changes the color space.""" 206 206 if self.minfile[nextpos-4:nextpos-1] == self.RGBColorSpace : # TODO : doesn't seem to handle all cases ! 207 207 self.iscolor = True 208 208 return 0 209 209 210 210 def array_Generic(self, nextpos, size) : 211 211 """Handles all arrays.""" … … 220 220 except KeyError : 221 221 raise pdlparser.PDLParserError, "Error on array size at %x" % nextpos 222 223 def array_8(self, nextpos) : 222 223 def array_8(self, nextpos) : 224 224 """Handles byte arrays.""" 225 225 return self.array_Generic(nextpos, 1) 226 226 227 227 def array_16(self, nextpos) : 228 228 """Handles 16 bits arrays.""" 229 229 return self.array_Generic(nextpos, 2) 230 230 231 231 def array_32(self, nextpos) : 232 232 """Handles 32 bits arrays and Canon ImageRunner tags.""" … … 243 243 toskip += length 244 244 # self.logdebug("Canon ImageRunner skip until %x" % (nextpos+toskip)) 245 return toskip 245 return toskip 246 246 else : 247 247 # This is a normal PCLXL array 248 248 return self.array_Generic(nextpos, 4) 249 249 250 250 def embeddedDataSmall(self, nextpos) : 251 251 """Handle small amounts of data.""" 252 252 return 1 + ord(self.minfile[nextpos]) 253 253 254 254 def embeddedData(self, nextpos) : 255 255 """Handle normal amounts of data.""" 256 256 return 4 + unpack(self.unpackLong, self.minfile[nextpos:nextpos+4])[0] 257 258 def skipHPPCLXL(self, nextpos) : 257 258 def skipHPPCLXL(self, nextpos) : 259 259 """Skip the 'HP-PCL XL' statement if needed.""" 260 260 minfile = self.minfile … … 265 265 while minfile[pos] != '\n' : 266 266 pos += 1 267 length = (pos - nextpos + 1) 268 # self.logdebug("Skip HP PCLXL statement until %x" % (nextpos + length)) 267 length = (pos - nextpos + 1) 268 # self.logdebug("Skip HP PCLXL statement until %x" % (nextpos + length)) 269 269 return length 270 else : 270 else : 271 271 return 0 272 272 273 273 def littleEndian(self, nextpos) : 274 274 """Toggles to little endianness.""" … … 278 278 # self.logdebug("LittleEndian at %x" % (nextpos - 1)) 279 279 return self.skipHPPCLXL(nextpos) 280 280 281 281 def bigEndian(self, nextpos) : 282 282 """Toggles to big endianness.""" … … 286 286 # self.logdebug("BigEndian at %x" % (nextpos - 1)) 287 287 return self.skipHPPCLXL(nextpos) 288 288 289 289 def reservedForFutureUse(self, nextpos) : 290 290 """Outputs something when a reserved byte is encountered.""" 291 291 self.logdebug("Byte at %x is out of the PCLXL Protocol Class 2.0 Specification" % nextpos) 292 return 0 293 292 return 0 293 294 294 def x46_class3(self, nextpos) : 295 295 """Undocumented tag 0x46 in class 3.0 streams.""" … … 301 301 try : 302 302 offset = self.x46_functions[funcid] 303 except KeyError : 303 except KeyError : 304 304 self.logdebug("Unexpected subfunction 0x%02x for undocumented tag 0x46 at %x" % (funcid, nextpos)) 305 305 break 306 else : 306 else : 307 307 pos -= offset 308 308 length = self.tags[ord(self.minfile[pos])] … … 315 315 raise pdlparser.PDLParserError, "Error on size '%s' at %x" % (length, pos+1) 316 316 val = ord(minfile[pos]) 317 return 0 318 319 def escape(self, nextpos) : 317 return 0 318 319 def escape(self, nextpos) : 320 320 """Handles the ESC code.""" 321 321 pos = endpos = nextpos … … 331 331 quotes += 1 332 332 endpos += 1 333 334 # Store this in a per page mapping. 333 334 # Store this in a per page mapping. 335 335 # NB : First time will be at page 0 (i.e. **before** page 1) ! 336 336 stuff = self.escapedStuff.setdefault(self.pagecount, []) … … 338 338 self.logdebug("Escaped datas : [%s]" % repr(minfile[pos : endpos])) 339 339 return endpos - pos 340 340 341 341 def skipKyoceraPrescribe(self, nextpos) : 342 342 """Skips Kyocera Prescribe commands.""" … … 351 351 self.logdebug("Prescribe commands : [%s]" % repr(minfile[nextpos-1:pos])) 352 352 break 353 pos += 1 353 pos += 1 354 354 return (pos - nextpos) 355 355 else : 356 356 return 0 357 357 358 358 def getJobSize(self) : 359 359 """Counts pages in a PCLXL (PCL6) document. 360 360 361 361 Algorithm by Jerome Alet. 362 362 363 363 The documentation used for this was : 364 364 365 365 HP PCL XL Feature Reference 366 366 Protocol Class 2.0 367 http://www.hpdevelopersolutions.com/downloads/64/358/xl_ref20r22.pdf 368 367 http://www.hpdevelopersolutions.com/downloads/64/358/xl_ref20r22.pdf 368 369 369 Protocol Class 2.1 Supplement 370 370 xl_ref21.pdf 371 371 372 372 Protocol Class 3.0 Supplement 373 373 xl_refsup30r089.pdf 374 374 """ 375 375 376 376 infileno = self.infile.fileno() 377 377 self.minfile = minfile = mmap.mmap(infileno, os.fstat(infileno)[6], prot=mmap.PROT_READ, flags=mmap.MAP_SHARED) 378 378 379 379 self.iscolor = False 380 380 381 381 found = False 382 382 while not found : … … 392 392 if endian == 0x29 : 393 393 self.littleEndian(0) 394 elif endian == 0x28 : 394 elif endian == 0x28 : 395 395 self.bigEndian(0) 396 396 # elif endian == 0x27 : # TODO : This is the ASCII binding code : what does it do exactly ? 397 # 398 else : 397 # 398 else : 399 399 raise pdlparser.PDLParserError, "Unknown endianness marker 0x%02x at start !" % endian 400 400 if not found : 401 401 raise pdlparser.PDLParserError, "This file doesn't seem to be PCLXL (aka PCL6)" 402 402 403 403 # Initialize Media Sources 404 404 for i in range(8, 256) : 405 405 self.mediasources[i] = "ExternalTray%03i" % (i - 7) 406 406 407 407 # Initialize table of tags 408 self.tags = [ 0 ] * 256 409 408 self.tags = [ 0 ] * 256 409 410 410 self.tags[0x1b] = self.escape # The escape code 411 411 412 412 self.tags[0x21] = self.skipKyoceraPrescribe # 0x21 is not normally used 413 413 414 414 # GhostScript's sources tell us that HP printers 415 415 # only accept little endianness, but we can handle both. 416 416 self.tags[0x28] = self.bigEndian # BigEndian 417 417 self.tags[0x29] = self.littleEndian # LittleEndian 418 418 419 419 self.tags[0x43] = self.beginPage # BeginPage 420 420 self.tags[0x44] = self.endPage # EndPage 421 421 self.tags[0x45] = self.reservedForFutureUse # reserved 422 423 self.tags[0x46] = self.x46_class3 424 422 423 self.tags[0x46] = self.x46_class3 424 425 425 self.tags[0x4a] = self.reservedForFutureUse # reserved 426 426 self.tags[0x4b] = self.reservedForFutureUse # reserved … … 428 428 self.tags[0x4d] = self.reservedForFutureUse # reserved 429 429 self.tags[0x4e] = self.reservedForFutureUse # reserved 430 430 431 431 self.tags[0x56] = self.reservedForFutureUse # TODO : documentation not clear about reserved status 432 432 433 433 self.tags[0x57] = self.reservedForFutureUse # reserved 434 434 435 435 self.tags[0x59] = self.reservedForFutureUse # reserved 436 436 self.tags[0x5a] = self.reservedForFutureUse # reserved 437 437 438 438 self.tags[0x6a] = self.setColorSpace # to detect color/b&w mode 439 439 440 440 self.tags[0x87] = self.reservedForFutureUse # reserved 441 441 self.tags[0x88] = self.reservedForFutureUse # reserved 442 442 self.tags[0x89] = self.reservedForFutureUse # reserved 443 443 self.tags[0x8a] = self.reservedForFutureUse # reserved 444 444 445 445 self.tags[0x8b] = self.reservedForFutureUse # reserved 446 446 447 447 self.tags[0x8c] = self.reservedForFutureUse # reserved 448 448 self.tags[0x8d] = self.reservedForFutureUse # reserved … … 450 450 self.tags[0x8f] = self.reservedForFutureUse # reserved 451 451 self.tags[0x90] = self.reservedForFutureUse # reserved 452 452 453 453 self.tags[0x9a] = self.reservedForFutureUse # reserved 454 454 self.tags[0x9c] = self.reservedForFutureUse # reserved 455 455 456 456 self.tags[0xa4] = self.reservedForFutureUse # reserved 457 457 self.tags[0xa5] = self.reservedForFutureUse # reserved 458 458 self.tags[0xa6] = self.reservedForFutureUse # reserved 459 459 self.tags[0xa7] = self.reservedForFutureUse # reserved 460 460 461 461 self.tags[0xaa] = self.reservedForFutureUse # reserved 462 462 self.tags[0xab] = self.reservedForFutureUse # reserved … … 465 465 self.tags[0xae] = self.reservedForFutureUse # reserved 466 466 self.tags[0xaf] = self.reservedForFutureUse # reserved 467 467 468 468 self.tags[0xb7] = self.reservedForFutureUse # reserved 469 469 470 470 self.tags[0xba] = self.reservedForFutureUse # reserved 471 471 self.tags[0xbb] = self.reservedForFutureUse # reserved … … 473 473 self.tags[0xbd] = self.reservedForFutureUse # reserved 474 474 self.tags[0xbe] = self.reservedForFutureUse # reserved 475 475 476 476 # self.tags[0xbf] = self.passThrough # PassThrough mode should already be taken care of automatically 477 477 478 478 self.tags[0xc0] = 1 # ubyte 479 479 self.tags[0xc1] = 2 # uint16 … … 482 482 self.tags[0xc4] = 4 # sint32 483 483 self.tags[0xc5] = 4 # real32 484 484 485 485 self.tags[0xc6] = self.reservedForFutureUse # reserved 486 486 self.tags[0xc7] = self.reservedForFutureUse # reserved 487 487 488 488 self.tags[0xc8] = self.array_8 # ubyte_array 489 489 self.tags[0xc9] = self.array_16 # uint16_array … … 492 492 self.tags[0xcc] = self.array_32 # sint32_array 493 493 self.tags[0xcd] = self.array_32 # real32_array and unfortunately Canon ImageRunner 494 494 495 495 self.tags[0xce] = self.reservedForFutureUse # reserved 496 496 self.tags[0xcf] = self.reservedForFutureUse # reserved 497 497 498 498 self.tags[0xd0] = 2 # ubyte_xy 499 499 self.tags[0xd1] = 4 # uint16_xy … … 512 512 self.tags[0xde] = self.reservedForFutureUse # reserved 513 513 self.tags[0xdf] = self.reservedForFutureUse # reserved 514 514 515 515 self.tags[0xe0] = 4 # ubyte_box 516 516 self.tags[0xe1] = 8 # uint16_box … … 529 529 self.tags[0xee] = self.reservedForFutureUse # reserved 530 530 self.tags[0xef] = self.reservedForFutureUse # reserved 531 531 532 532 self.tags[0xf0] = self.reservedForFutureUse # reserved 533 533 self.tags[0xf1] = self.reservedForFutureUse # reserved … … 538 538 self.tags[0xf6] = self.reservedForFutureUse # reserved 539 539 self.tags[0xf7] = self.reservedForFutureUse # reserved 540 540 541 541 self.tags[0xf8] = 1 # attr_ubyte 542 542 self.tags[0xf9] = 2 # attr_uint16 543 543 544 544 self.tags[0xfa] = self.embeddedData # dataLength 545 545 self.tags[0xfb] = self.embeddedDataSmall # dataLengthByte 546 546 547 547 self.tags[0xfc] = self.reservedForFutureUse # reserved 548 548 self.tags[0xfd] = self.reservedForFutureUse # reserved 549 549 self.tags[0xfe] = self.reservedForFutureUse # reserved 550 550 self.tags[0xff] = self.reservedForFutureUse # reserved 551 552 # color spaces 551 552 # color spaces 553 553 self.BWColorSpace = "".join([chr(0x00), chr(0xf8), chr(0x03)]) 554 554 self.GrayColorSpace = "".join([chr(0x01), chr(0xf8), chr(0x03)]) 555 555 self.RGBColorSpace = "".join([chr(0x02), chr(0xf8), chr(0x03)]) 556 556 557 557 # set number of copies 558 self.setNumberOfCopies = "".join([chr(0xf8), chr(0x31)]) 559 558 self.setNumberOfCopies = "".join([chr(0xf8), chr(0x31)]) 559 560 560 # subcodes for undocumented tag 0x46 and the negative 561 561 # offset to grab the value from. … … 569 569 0x98 : 2, 570 570 } 571 571 572 572 # Markers for Canon ImageRunner printers 573 573 self.imagerunnermarker1 = chr(0xcd) + chr(0xca) + chr(0x10) + chr(0x00) 574 574 self.imagerunnermarker2 = chr(0xcd) + chr(0xca) + chr(0x10) + chr(0x02) 575 576 self.pages = { 0 : { "copies" : 1, 577 "orientation" : "Default", 578 "mediatype" : "Plain", 579 "mediasize" : "Default", 580 "mediasource" : "Default", 575 576 self.pages = { 0 : { "copies" : 1, 577 "orientation" : "Default", 578 "mediatype" : "Plain", 579 "mediasize" : "Default", 580 "mediasource" : "Default", 581 581 "duplex" : None, 582 } 583 } 582 } 583 } 584 584 tags = self.tags 585 585 self.pagecount = 0 … … 592 592 try : 593 593 tag = ord(minfile[pos]) 594 except OverflowError : 594 except OverflowError : 595 595 pos = oldpos + 1 596 596 pos += 1 597 597 length = tags[tag] 598 598 if length : 599 if callable(length) : 599 if callable(length) : 600 600 length = length(pos) 601 oldpos = pos 602 pos += length 603 except IndexError : # EOF ? 601 oldpos = pos 602 pos += length 603 except IndexError : # EOF ? 604 604 pass 605 605 finally : 606 606 self.minfile.close() 607 607 608 608 # now handle number of copies for each page (may differ). 609 609 if self.iscolor : 610 610 colormode = "Color" 611 else : 611 else : 612 612 colormode = "BW" 613 613 614 614 defaultduplexmode = "Simplex" 615 615 defaultpapersize = "" 616 defaultpjlcopies = 1 616 defaultpjlcopies = 1 617 617 oldpjlcopies = -1 618 618 oldduplexmode = "" … … 622 622 # in PCLXL documentation. 623 623 # NB : is number of copies is 0, the page won't be output 624 # but the formula below is still correct : we want 624 # but the formula below is still correct : we want 625 625 # to decrease the total number of pages in this case. 626 626 page = self.pages.get(pnum, self.pages.get(1, { "copies" : 1, "mediasize" : "Default", "duplex" : None })) … … 641 641 pjlcopies = nbqty 642 642 else : 643 if oldpjlcopies == -1 : 643 if oldpjlcopies == -1 : 644 644 pjlcopies = defaultpjlcopies 645 else : 646 pjlcopies = oldpjlcopies 647 if page["duplex"] : 645 else : 646 pjlcopies = oldpjlcopies 647 if page["duplex"] : 648 648 duplexmode = page["duplex"] 649 else : 649 else : 650 650 defaultdm = pjlparser.default_variables.get("DUPLEX", "") 651 651 if defaultdm : 652 652 if defaultdm.upper() == "ON" : 653 653 defaultduplexmode = "Duplex" 654 else : 654 else : 655 655 defaultduplexmode = "Simplex" 656 656 envdm = pjlparser.environment_variables.get("DUPLEX", "") … … 658 658 if envdm.upper() == "ON" : 659 659 duplexmode = "Duplex" 660 else : 660 else : 661 661 duplexmode = "Simplex" 662 else : 662 else : 663 663 if not oldduplexmode : 664 664 duplexmode = defaultduplexmode 665 else : 665 else : 666 666 duplexmode = oldduplexmode 667 667 defaultps = pjlparser.default_variables.get("PAPER", "") … … 671 671 if envps : 672 672 papersize = envps 673 else : 673 else : 674 674 if not oldpapersize : 675 675 papersize = defaultpapersize 676 else : 676 else : 677 677 papersize = oldpapersize 678 else : 678 else : 679 679 if oldpjlcopies == -1 : 680 680 pjlcopies = defaultpjlcopies 681 else : 681 else : 682 682 pjlcopies = oldpjlcopies 683 683 if not oldduplexmode : 684 684 duplexmode = defaultduplexmode 685 else : 685 else : 686 686 duplexmode = oldduplexmode 687 if not oldpapersize : 687 if not oldpapersize : 688 688 papersize = defaultpapersize 689 else : 689 else : 690 690 papersize = oldpapersize 691 691 duplexmode = oldduplexmode … … 693 693 if page["mediasize"] != "Default" : 694 694 papersize = page["mediasize"] 695 if not duplexmode : 695 if not duplexmode : 696 696 duplexmode = oldduplexmode or defaultduplexmode 697 oldpjlcopies = pjlcopies 697 oldpjlcopies = pjlcopies 698 698 oldduplexmode = duplexmode 699 699 oldpapersize = papersize 700 700 copies = max(pjlcopies, page["copies"]) # Was : pjlcopies * page["copies"] 701 701 self.pagecount += (copies - 1) 702 self.logdebug("%s*%s*%s*%s*%s*%s*%s" % (copies, 703 page["mediatype"], 704 papersize, 705 page["orientation"], 706 page["mediasource"], 707 duplexmode, 702 self.logdebug("%s*%s*%s*%s*%s*%s*%s" % (copies, 703 page["mediatype"], 704 papersize, 705 page["orientation"], 706 page["mediasource"], 707 duplexmode, 708 708 colormode)) 709 709 return self.pagecount