From 13d6dc3a6a5e8bd3c17997351a0e6f087eb301a2 Mon Sep 17 00:00:00 2001 From: tknall Date: Tue, 25 Nov 2008 12:04:30 +0000 Subject: Removing itext from source. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@302 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- src/main/java/com/lowagie/text/pdf/AcroFields.java | 1883 ----------- .../com/lowagie/text/pdf/ArabicLigaturizer.java | 771 ----- .../java/com/lowagie/text/pdf/AsianFontMapper.java | 103 - .../lowagie/text/pdf/BadPdfFormatException.java | 85 - src/main/java/com/lowagie/text/pdf/Barcode.java | 477 --- src/main/java/com/lowagie/text/pdf/Barcode128.java | 825 ----- src/main/java/com/lowagie/text/pdf/Barcode39.java | 392 --- .../java/com/lowagie/text/pdf/BarcodeCodabar.java | 345 -- src/main/java/com/lowagie/text/pdf/BarcodeEAN.java | 718 ----- .../java/com/lowagie/text/pdf/BarcodeEANSUPP.java | 153 - .../java/com/lowagie/text/pdf/BarcodeInter25.java | 338 -- .../java/com/lowagie/text/pdf/BarcodePDF417.java | 1604 ---------- .../java/com/lowagie/text/pdf/BarcodePostnet.java | 233 -- src/main/java/com/lowagie/text/pdf/BaseField.java | 665 ---- src/main/java/com/lowagie/text/pdf/BaseFont.java | 1137 ------- src/main/java/com/lowagie/text/pdf/BidiLine.java | 915 ------ src/main/java/com/lowagie/text/pdf/BidiOrder.java | 1240 -------- src/main/java/com/lowagie/text/pdf/ByteBuffer.java | 623 ---- src/main/java/com/lowagie/text/pdf/CFFFont.java | 1184 ------- .../java/com/lowagie/text/pdf/CFFFontSubset.java | 1633 ---------- src/main/java/com/lowagie/text/pdf/CJKFont.java | 626 ---- src/main/java/com/lowagie/text/pdf/CMYKColor.java | 129 - .../java/com/lowagie/text/pdf/ColorDetails.java | 101 - src/main/java/com/lowagie/text/pdf/ColumnText.java | 1520 --------- .../com/lowagie/text/pdf/DefaultFontMapper.java | 308 -- .../java/com/lowagie/text/pdf/DocumentFont.java | 599 ---- .../java/com/lowagie/text/pdf/EnumerateTTC.java | 118 - .../java/com/lowagie/text/pdf/ExtendedColor.java | 122 - .../java/com/lowagie/text/pdf/ExtraEncoding.java | 74 - src/main/java/com/lowagie/text/pdf/FdfReader.java | 214 -- src/main/java/com/lowagie/text/pdf/FdfWriter.java | 333 -- .../java/com/lowagie/text/pdf/FontDetails.java | 275 -- src/main/java/com/lowagie/text/pdf/FontMapper.java | 80 - .../java/com/lowagie/text/pdf/FontSelector.java | 124 - src/main/java/com/lowagie/text/pdf/GlyphList.java | 2200 ------------- src/main/java/com/lowagie/text/pdf/GrayColor.java | 85 - .../java/com/lowagie/text/pdf/HyphenationAuto.java | 125 - .../com/lowagie/text/pdf/HyphenationEvent.java | 78 - .../java/com/lowagie/text/pdf/IntHashtable.java | 338 -- src/main/java/com/lowagie/text/pdf/LZWDecoder.java | 231 -- .../java/com/lowagie/text/pdf/MultiColumnText.java | 575 ---- .../com/lowagie/text/pdf/OutputStreamCounter.java | 170 - src/main/java/com/lowagie/text/pdf/PRAcroForm.java | 210 -- .../com/lowagie/text/pdf/PRIndirectReference.java | 103 - src/main/java/com/lowagie/text/pdf/PRStream.java | 229 -- .../java/com/lowagie/text/pdf/PRTokeniser.java | 585 ---- .../java/com/lowagie/text/pdf/PageResources.java | 187 -- .../java/com/lowagie/text/pdf/PatternColor.java | 79 - .../java/com/lowagie/text/pdf/PdfAcroForm.java | 744 ----- src/main/java/com/lowagie/text/pdf/PdfAction.java | 558 ---- .../java/com/lowagie/text/pdf/PdfAnnotation.java | 742 ----- .../java/com/lowagie/text/pdf/PdfAppearance.java | 155 - src/main/java/com/lowagie/text/pdf/PdfArray.java | 227 -- src/main/java/com/lowagie/text/pdf/PdfBoolean.java | 134 - .../java/com/lowagie/text/pdf/PdfBorderArray.java | 82 - .../com/lowagie/text/pdf/PdfBorderDictionary.java | 100 - src/main/java/com/lowagie/text/pdf/PdfCell.java | 890 ------ src/main/java/com/lowagie/text/pdf/PdfChunk.java | 781 ----- src/main/java/com/lowagie/text/pdf/PdfColor.java | 80 - .../java/com/lowagie/text/pdf/PdfContentByte.java | 3053 ------------------ .../com/lowagie/text/pdf/PdfContentParser.java | 204 -- .../java/com/lowagie/text/pdf/PdfContents.java | 147 - src/main/java/com/lowagie/text/pdf/PdfCopy.java | 474 --- .../java/com/lowagie/text/pdf/PdfCopyFields.java | 208 -- .../com/lowagie/text/pdf/PdfCopyFieldsImp.java | 639 ---- .../java/com/lowagie/text/pdf/PdfDashPattern.java | 144 - src/main/java/com/lowagie/text/pdf/PdfDate.java | 210 -- .../java/com/lowagie/text/pdf/PdfDestination.java | 221 -- .../java/com/lowagie/text/pdf/PdfDictionary.java | 353 --- .../java/com/lowagie/text/pdf/PdfDocument.java | 3279 -------------------- .../java/com/lowagie/text/pdf/PdfEncodings.java | 716 ----- .../java/com/lowagie/text/pdf/PdfEncryption.java | 390 --- .../com/lowagie/text/pdf/PdfEncryptionStream.java | 85 - .../java/com/lowagie/text/pdf/PdfEncryptor.java | 176 -- .../java/com/lowagie/text/pdf/PdfException.java | 86 - .../com/lowagie/text/pdf/PdfFileSpecification.java | 194 -- src/main/java/com/lowagie/text/pdf/PdfFont.java | 188 -- .../java/com/lowagie/text/pdf/PdfFormField.java | 347 --- .../java/com/lowagie/text/pdf/PdfFormXObject.java | 103 - .../java/com/lowagie/text/pdf/PdfFunction.java | 142 - src/main/java/com/lowagie/text/pdf/PdfGState.java | 144 - .../java/com/lowagie/text/pdf/PdfGraphics2D.java | 1450 --------- .../java/com/lowagie/text/pdf/PdfICCBased.java | 86 - src/main/java/com/lowagie/text/pdf/PdfImage.java | 279 -- .../java/com/lowagie/text/pdf/PdfImportedPage.java | 149 - .../com/lowagie/text/pdf/PdfIndirectObject.java | 170 - .../com/lowagie/text/pdf/PdfIndirectReference.java | 133 - src/main/java/com/lowagie/text/pdf/PdfLayer.java | 302 -- .../com/lowagie/text/pdf/PdfLayerMembership.java | 139 - src/main/java/com/lowagie/text/pdf/PdfLine.java | 477 --- src/main/java/com/lowagie/text/pdf/PdfLister.java | 187 -- src/main/java/com/lowagie/text/pdf/PdfLiteral.java | 111 - .../com/lowagie/text/pdf/PdfMediaClipData.java | 63 - src/main/java/com/lowagie/text/pdf/PdfName.java | 1141 ------- .../java/com/lowagie/text/pdf/PdfNameTree.java | 165 - src/main/java/com/lowagie/text/pdf/PdfNull.java | 87 - src/main/java/com/lowagie/text/pdf/PdfNumber.java | 159 - .../java/com/lowagie/text/pdf/PdfNumberTree.java | 159 - src/main/java/com/lowagie/text/pdf/PdfOCG.java | 67 - .../java/com/lowagie/text/pdf/PdfOCProperties.java | 59 - src/main/java/com/lowagie/text/pdf/PdfObject.java | 369 --- src/main/java/com/lowagie/text/pdf/PdfOutline.java | 542 ---- src/main/java/com/lowagie/text/pdf/PdfPCell.java | 735 ----- .../java/com/lowagie/text/pdf/PdfPCellEvent.java | 74 - src/main/java/com/lowagie/text/pdf/PdfPKCS7.java | 1276 -------- src/main/java/com/lowagie/text/pdf/PdfPRow.java | 659 ---- .../java/com/lowagie/text/pdf/PdfPSXObject.java | 99 - src/main/java/com/lowagie/text/pdf/PdfPTable.java | 1081 ------- .../java/com/lowagie/text/pdf/PdfPTableEvent.java | 94 - src/main/java/com/lowagie/text/pdf/PdfPage.java | 197 -- .../java/com/lowagie/text/pdf/PdfPageElement.java | 78 - .../java/com/lowagie/text/pdf/PdfPageEvent.java | 190 -- .../com/lowagie/text/pdf/PdfPageEventHelper.java | 202 -- .../java/com/lowagie/text/pdf/PdfPageLabels.java | 191 -- src/main/java/com/lowagie/text/pdf/PdfPages.java | 205 -- src/main/java/com/lowagie/text/pdf/PdfPattern.java | 83 - .../com/lowagie/text/pdf/PdfPatternPainter.java | 391 --- .../com/lowagie/text/pdf/PdfPrinterGraphics2D.java | 73 - src/main/java/com/lowagie/text/pdf/PdfReader.java | 3172 ------------------- .../com/lowagie/text/pdf/PdfReaderInstance.java | 182 -- .../java/com/lowagie/text/pdf/PdfRectangle.java | 284 -- .../java/com/lowagie/text/pdf/PdfRendition.java | 61 - .../java/com/lowagie/text/pdf/PdfResources.java | 91 - src/main/java/com/lowagie/text/pdf/PdfShading.java | 261 -- .../com/lowagie/text/pdf/PdfShadingPattern.java | 119 - .../com/lowagie/text/pdf/PdfSigGenericPKCS.java | 230 -- .../java/com/lowagie/text/pdf/PdfSignature.java | 97 - .../lowagie/text/pdf/PdfSignatureAppearance.java | 1349 -------- .../java/com/lowagie/text/pdf/PdfSpotColor.java | 132 - src/main/java/com/lowagie/text/pdf/PdfStamper.java | 667 ---- .../java/com/lowagie/text/pdf/PdfStamperImp.java | 1461 --------- src/main/java/com/lowagie/text/pdf/PdfStream.java | 313 -- src/main/java/com/lowagie/text/pdf/PdfString.java | 236 -- .../com/lowagie/text/pdf/PdfStructureElement.java | 130 - .../com/lowagie/text/pdf/PdfStructureTreeRoot.java | 146 - src/main/java/com/lowagie/text/pdf/PdfTable.java | 316 -- .../java/com/lowagie/text/pdf/PdfTemplate.java | 267 -- .../java/com/lowagie/text/pdf/PdfTextArray.java | 99 - .../java/com/lowagie/text/pdf/PdfTransition.java | 253 -- .../com/lowagie/text/pdf/PdfTransparencyGroup.java | 85 - src/main/java/com/lowagie/text/pdf/PdfWriter.java | 2752 ---------------- .../lowagie/text/pdf/PdfXConformanceException.java | 70 - src/main/java/com/lowagie/text/pdf/Pfm2afm.java | 773 ----- .../java/com/lowagie/text/pdf/PushbuttonField.java | 601 ---- .../java/com/lowagie/text/pdf/RadioCheckField.java | 416 --- .../lowagie/text/pdf/RandomAccessFileOrArray.java | 609 ---- .../java/com/lowagie/text/pdf/SequenceList.java | 317 -- .../java/com/lowagie/text/pdf/ShadingColor.java | 83 - .../java/com/lowagie/text/pdf/SimpleBookmark.java | 745 ----- .../lowagie/text/pdf/SimpleNamedDestination.java | 335 -- .../com/lowagie/text/pdf/SimpleXMLDocHandler.java | 80 - .../text/pdf/SimpleXMLDocHandlerComment.java | 59 - .../java/com/lowagie/text/pdf/SimpleXMLParser.java | 1177 ------- src/main/java/com/lowagie/text/pdf/SpotColor.java | 90 - .../java/com/lowagie/text/pdf/StampContent.java | 81 - src/main/java/com/lowagie/text/pdf/TextField.java | 661 ---- .../java/com/lowagie/text/pdf/TrueTypeFont.java | 1377 -------- .../com/lowagie/text/pdf/TrueTypeFontSubSet.java | 428 --- .../com/lowagie/text/pdf/TrueTypeFontUnicode.java | 456 --- src/main/java/com/lowagie/text/pdf/Type1Font.java | 807 ----- src/main/java/com/lowagie/text/pdf/Type3Font.java | 306 -- src/main/java/com/lowagie/text/pdf/Type3Glyph.java | 94 - .../java/com/lowagie/text/pdf/VerticalText.java | 349 --- src/main/java/com/lowagie/text/pdf/XfdfReader.java | 208 -- .../java/com/lowagie/text/pdf/codec/BmpImage.java | 1282 -------- .../com/lowagie/text/pdf/codec/CCITTG4Encoder.java | 600 ---- .../java/com/lowagie/text/pdf/codec/GifImage.java | 593 ---- .../java/com/lowagie/text/pdf/codec/PngImage.java | 987 ------ .../com/lowagie/text/pdf/codec/TIFFConstants.java | 296 -- .../com/lowagie/text/pdf/codec/TIFFDirectory.java | 656 ---- .../com/lowagie/text/pdf/codec/TIFFFaxDecoder.java | 1477 --------- .../java/com/lowagie/text/pdf/codec/TIFFField.java | 472 --- .../com/lowagie/text/pdf/codec/TIFFLZWDecoder.java | 255 -- .../java/com/lowagie/text/pdf/codec/TiffImage.java | 522 ---- .../text/pdf/codec/postscript/JavaCharStream.java | 547 ---- .../text/pdf/codec/postscript/MetaDoPS.java | 98 - .../text/pdf/codec/postscript/PACommand.java | 19 - .../text/pdf/codec/postscript/PAContext.java | 2772 ----------------- .../text/pdf/codec/postscript/PAEngine.java | 155 - .../text/pdf/codec/postscript/PAParser.java | 351 --- .../pdf/codec/postscript/PAParserConstants.java | 60 - .../pdf/codec/postscript/PAParserTokenManager.java | 1011 ------ .../text/pdf/codec/postscript/PAPencil.java | 431 --- .../lowagie/text/pdf/codec/postscript/PAToken.java | 66 - .../pdf/codec/postscript/PainterException.java | 20 - .../text/pdf/codec/postscript/ParseException.java | 192 -- .../lowagie/text/pdf/codec/postscript/Token.java | 81 - .../text/pdf/codec/postscript/TokenMgrError.java | 133 - .../com/lowagie/text/pdf/codec/wmf/InputMeta.java | 112 - .../com/lowagie/text/pdf/codec/wmf/MetaBrush.java | 94 - .../com/lowagie/text/pdf/codec/wmf/MetaDo.java | 760 ----- .../com/lowagie/text/pdf/codec/wmf/MetaFont.java | 211 -- .../com/lowagie/text/pdf/codec/wmf/MetaObject.java | 71 - .../com/lowagie/text/pdf/codec/wmf/MetaPen.java | 91 - .../com/lowagie/text/pdf/codec/wmf/MetaState.java | 372 --- .../text/pdf/events/FieldPositioningEvents.java | 186 -- .../com/lowagie/text/pdf/events/IndexEvents.java | 401 --- .../text/pdf/events/PdfPCellEventForwarder.java | 91 - .../text/pdf/events/PdfPTableEventForwarder.java | 90 - .../text/pdf/events/PdfPageEventForwarder.java | 312 -- .../text/pdf/fonts/FontsResourceAnchor.java | 62 - .../lowagie/text/pdf/hyphenation/ByteVector.java | 124 - .../lowagie/text/pdf/hyphenation/CharVector.java | 134 - .../com/lowagie/text/pdf/hyphenation/Hyphen.java | 68 - .../lowagie/text/pdf/hyphenation/Hyphenation.java | 83 - .../text/pdf/hyphenation/HyphenationException.java | 28 - .../text/pdf/hyphenation/HyphenationTree.java | 454 --- .../lowagie/text/pdf/hyphenation/Hyphenator.java | 240 -- .../text/pdf/hyphenation/PatternConsumer.java | 55 - .../text/pdf/hyphenation/SimplePatternParser.java | 278 -- .../lowagie/text/pdf/hyphenation/TernaryTree.java | 667 ---- 211 files changed, 93945 deletions(-) delete mode 100644 src/main/java/com/lowagie/text/pdf/AcroFields.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ArabicLigaturizer.java delete mode 100644 src/main/java/com/lowagie/text/pdf/AsianFontMapper.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BadPdfFormatException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Barcode.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Barcode128.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Barcode39.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodeCodabar.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodeEAN.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodeEANSUPP.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodeInter25.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodePDF417.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BarcodePostnet.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BaseField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BaseFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BidiLine.java delete mode 100644 src/main/java/com/lowagie/text/pdf/BidiOrder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ByteBuffer.java delete mode 100644 src/main/java/com/lowagie/text/pdf/CFFFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/CFFFontSubset.java delete mode 100644 src/main/java/com/lowagie/text/pdf/CJKFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/CMYKColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ColorDetails.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ColumnText.java delete mode 100644 src/main/java/com/lowagie/text/pdf/DefaultFontMapper.java delete mode 100644 src/main/java/com/lowagie/text/pdf/DocumentFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/EnumerateTTC.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ExtendedColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ExtraEncoding.java delete mode 100644 src/main/java/com/lowagie/text/pdf/FdfReader.java delete mode 100644 src/main/java/com/lowagie/text/pdf/FdfWriter.java delete mode 100644 src/main/java/com/lowagie/text/pdf/FontDetails.java delete mode 100644 src/main/java/com/lowagie/text/pdf/FontMapper.java delete mode 100644 src/main/java/com/lowagie/text/pdf/FontSelector.java delete mode 100644 src/main/java/com/lowagie/text/pdf/GlyphList.java delete mode 100644 src/main/java/com/lowagie/text/pdf/GrayColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/HyphenationAuto.java delete mode 100644 src/main/java/com/lowagie/text/pdf/HyphenationEvent.java delete mode 100644 src/main/java/com/lowagie/text/pdf/IntHashtable.java delete mode 100644 src/main/java/com/lowagie/text/pdf/LZWDecoder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/MultiColumnText.java delete mode 100644 src/main/java/com/lowagie/text/pdf/OutputStreamCounter.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PRAcroForm.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PRIndirectReference.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PRStream.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PRTokeniser.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PageResources.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PatternColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfAcroForm.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfAction.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfAnnotation.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfAppearance.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfArray.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfBoolean.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfBorderArray.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfBorderDictionary.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfCell.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfChunk.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfContentByte.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfContentParser.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfContents.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfCopy.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfCopyFields.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfCopyFieldsImp.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfDashPattern.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfDate.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfDestination.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfDictionary.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfDocument.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfEncodings.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfEncryption.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfEncryptionStream.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfEncryptor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfFileSpecification.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfFormField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfFormXObject.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfFunction.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfGState.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfGraphics2D.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfICCBased.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfImage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfImportedPage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfIndirectObject.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfIndirectReference.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfLayer.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfLayerMembership.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfLine.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfLister.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfLiteral.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfMediaClipData.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfName.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfNameTree.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfNull.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfNumber.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfNumberTree.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfOCG.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfOCProperties.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfObject.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfOutline.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPCell.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPCellEvent.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPKCS7.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPRow.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPSXObject.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPTable.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPTableEvent.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPageElement.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPageEvent.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPageEventHelper.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPageLabels.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPages.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPattern.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPatternPainter.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfPrinterGraphics2D.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfReader.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfReaderInstance.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfRectangle.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfRendition.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfResources.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfShading.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfShadingPattern.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfSigGenericPKCS.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfSignature.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfSignatureAppearance.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfSpotColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfStamper.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfStamperImp.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfStream.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfString.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfStructureElement.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfStructureTreeRoot.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfTable.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfTemplate.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfTextArray.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfTransition.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfTransparencyGroup.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfWriter.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PdfXConformanceException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Pfm2afm.java delete mode 100644 src/main/java/com/lowagie/text/pdf/PushbuttonField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/RadioCheckField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/RandomAccessFileOrArray.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SequenceList.java delete mode 100644 src/main/java/com/lowagie/text/pdf/ShadingColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SimpleBookmark.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SimpleNamedDestination.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandler.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandlerComment.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SimpleXMLParser.java delete mode 100644 src/main/java/com/lowagie/text/pdf/SpotColor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/StampContent.java delete mode 100644 src/main/java/com/lowagie/text/pdf/TextField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/TrueTypeFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/TrueTypeFontSubSet.java delete mode 100644 src/main/java/com/lowagie/text/pdf/TrueTypeFontUnicode.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Type1Font.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Type3Font.java delete mode 100644 src/main/java/com/lowagie/text/pdf/Type3Glyph.java delete mode 100644 src/main/java/com/lowagie/text/pdf/VerticalText.java delete mode 100644 src/main/java/com/lowagie/text/pdf/XfdfReader.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/BmpImage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/CCITTG4Encoder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/GifImage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/PngImage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TIFFConstants.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TIFFDirectory.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TIFFField.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/TiffImage.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/JavaCharStream.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/MetaDoPS.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PACommand.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAContext.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAEngine.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAParser.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserConstants.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserTokenManager.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAPencil.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PAToken.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/PainterException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/ParseException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/Token.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/postscript/TokenMgrError.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java delete mode 100644 src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java delete mode 100644 src/main/java/com/lowagie/text/pdf/events/FieldPositioningEvents.java delete mode 100644 src/main/java/com/lowagie/text/pdf/events/IndexEvents.java delete mode 100644 src/main/java/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/events/PdfPageEventForwarder.java delete mode 100644 src/main/java/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/ByteVector.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/CharVector.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/Hyphen.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenation.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationException.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationTree.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenator.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/PatternConsumer.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java delete mode 100644 src/main/java/com/lowagie/text/pdf/hyphenation/TernaryTree.java (limited to 'src/main/java/com/lowagie/text/pdf') diff --git a/src/main/java/com/lowagie/text/pdf/AcroFields.java b/src/main/java/com/lowagie/text/pdf/AcroFields.java deleted file mode 100644 index 30e33ca..0000000 --- a/src/main/java/com/lowagie/text/pdf/AcroFields.java +++ /dev/null @@ -1,1883 +0,0 @@ -/* - * Copyright 2003-2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Iterator; -import java.util.Comparator; -import java.util.Collections; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Element; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.DocumentException; -import java.io.IOException; -import java.io.InputStream; -import java.awt.Color; - -/** Query and change fields in existing documents either by method - * calls or by FDF merging. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class AcroFields { - - PdfReader reader; - PdfWriter writer; - HashMap fields; - private int topFirst; - private HashMap sigNames; - private boolean append; - static private final int DA_FONT = 0; - static private final int DA_SIZE = 1; - static private final int DA_COLOR = 2; - private HashMap extensionFonts = new HashMap(); - /** - * A field type invalid or not found. - */ - public static final int FIELD_TYPE_NONE = 0; - /** - * A field type. - */ - public static final int FIELD_TYPE_PUSHBUTTON = 1; - /** - * A field type. - */ - public static final int FIELD_TYPE_CHECKBOX = 2; - /** - * A field type. - */ - public static final int FIELD_TYPE_RADIOBUTTON = 3; - /** - * A field type. - */ - public static final int FIELD_TYPE_TEXT = 4; - /** - * A field type. - */ - public static final int FIELD_TYPE_LIST = 5; - /** - * A field type. - */ - public static final int FIELD_TYPE_COMBO = 6; - /** - * A field type. - */ - public static final int FIELD_TYPE_SIGNATURE = 7; - - private boolean lastWasString; - - /** Holds value of property generateAppearances. */ - private boolean generateAppearances = true; - - private HashMap localFonts = new HashMap(); - - private float extraMarginLeft; - private float extraMarginTop; - private ArrayList substitutionFonts; - - AcroFields(PdfReader reader, PdfWriter writer) { - this.reader = reader; - this.writer = writer; - if (writer instanceof PdfStamperImp) { - append = ((PdfStamperImp)writer).isAppend(); - } - fill(); - } - - void fill() { - fields = new HashMap(); - PdfDictionary top = (PdfDictionary)PdfReader.getPdfObjectRelease(reader.getCatalog().get(PdfName.ACROFORM)); - if (top == null) - return; - PdfArray arrfds = (PdfArray)PdfReader.getPdfObjectRelease(top.get(PdfName.FIELDS)); - if (arrfds == null || arrfds.size() == 0) - return; - arrfds = null; - for (int k = 1; k <= reader.getNumberOfPages(); ++k) { - if ((k % 100) == 0) - System.out.println(k); - PdfDictionary page = reader.getPageNRelease(k); - PdfArray annots = (PdfArray)PdfReader.getPdfObjectRelease(page.get(PdfName.ANNOTS), page); - if (annots == null) - continue; - ArrayList arr = annots.getArrayList(); - for (int j = 0; j < arr.size(); ++j) { - PdfObject annoto = PdfReader.getPdfObject((PdfObject)arr.get(j), annots); - if ((annoto instanceof PdfIndirectReference) && !annoto.isIndirect()) { - PdfReader.releaseLastXrefPartial((PdfObject)arr.get(j)); - continue; - } - PdfDictionary annot = (PdfDictionary)annoto; - if (!PdfName.WIDGET.equals(annot.get(PdfName.SUBTYPE))) { - PdfReader.releaseLastXrefPartial((PdfObject)arr.get(j)); - continue; - } - PdfDictionary widget = annot; - PdfDictionary dic = new PdfDictionary(); - dic.putAll(annot); - String name = ""; - PdfDictionary value = null; - PdfObject lastV = null; - while (annot != null) { - dic.mergeDifferent(annot); - PdfString t = (PdfString)PdfReader.getPdfObject(annot.get(PdfName.T)); - if (t != null) - name = t.toUnicodeString() + "." + name; - if (lastV == null && annot.get(PdfName.V) != null) - lastV = PdfReader.getPdfObjectRelease(annot.get(PdfName.V)); - if (value == null && t != null) { - value = annot; - if (annot.get(PdfName.V) == null && lastV != null) - value.put(PdfName.V, lastV); - } - annot = (PdfDictionary)PdfReader.getPdfObject(annot.get(PdfName.PARENT), annot); - } - if (name.length() > 0) - name = name.substring(0, name.length() - 1); - Item item = (Item)fields.get(name); - if (item == null) { - item = new Item(); - fields.put(name, item); - } - if (value == null) - item.values.add(widget); - else - item.values.add(value); - item.widgets.add(widget); - item.widget_refs.add(arr.get(j)); // must be a reference - if (top != null) - dic.mergeDifferent(top); - item.merged.add(dic); - item.page.add(new Integer(k)); - item.tabOrder.add(new Integer(j)); - } - } - } - - /** Gets the list of appearance names. Use it to get the names allowed - * with radio and checkbox fields. If the /Opt key exists the values will - * also be included. The name 'Off' may also be valid - * even if not returned in the list. - * @param fieldName the fully qualified field name - * @return the list of names or null if the field does not exist - */ - public String[] getAppearanceStates(String fieldName) { - Item fd = (Item)fields.get(fieldName); - if (fd == null) - return null; - HashMap names = new HashMap(); - PdfDictionary vals = (PdfDictionary)fd.values.get(0); - PdfObject opts = PdfReader.getPdfObject(vals.get(PdfName.OPT)); - if (opts != null) { - if (opts.isString()) - names.put(((PdfString)opts).toUnicodeString(), null); - else if (opts.isArray()) { - ArrayList list = ((PdfArray)opts).getArrayList(); - for (int k = 0; k < list.size(); ++k) { - PdfObject v = PdfReader.getPdfObject((PdfObject)list.get(k)); - if (v != null && v.isString()) - names.put(((PdfString)v).toUnicodeString(), null); - } - } - } - ArrayList wd = fd.widgets; - for (int k = 0; k < wd.size(); ++k) { - PdfDictionary dic = (PdfDictionary)wd.get(k); - dic = (PdfDictionary)PdfReader.getPdfObject(dic.get(PdfName.AP)); - if (dic == null) - continue; - PdfObject ob = PdfReader.getPdfObject(dic.get(PdfName.N)); - if (ob == null || !ob.isDictionary()) - continue; - dic = (PdfDictionary)ob; - for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { - String name = PdfName.decodeName(((PdfName)it.next()).toString()); - names.put(name, null); - } - } - String out[] = new String[names.size()]; - return (String[])names.keySet().toArray(out); - } - - private String[] getListOption(String fieldName, int idx) { - Item fd = (Item)fields.get(fieldName); - if (fd == null) - return null; - PdfObject obj = PdfReader.getPdfObject(((PdfDictionary)fd.merged.get(0)).get(PdfName.OPT)); - if (obj == null || !obj.isArray()) - return null; - PdfArray ar = (PdfArray)obj; - String[] ret = new String[ar.size()]; - ArrayList a = ar.getArrayList(); - for (int k = 0; k < a.size(); ++k) { - obj = PdfReader.getPdfObject((PdfObject)a.get(k)); - try { - if (obj.isArray()) { - obj = (PdfObject)((PdfArray)obj).getArrayList().get(idx); - } - if (obj.isString()) - ret[k] = ((PdfString)obj).toUnicodeString(); - else - ret[k] = obj.toString(); - } - catch (Exception e) { - ret[k] = ""; - } - } - return ret; - } - - /** - * Gets the list of export option values from fields of type list or combo. - * If the field doesn't exist or the field type is not list or combo it will return - * null. - * @param fieldName the field name - * @return the list of export option values from fields of type list or combo - */ - public String[] getListOptionExport(String fieldName) { - return getListOption(fieldName, 0); - } - - /** - * Gets the list of display option values from fields of type list or combo. - * If the field doesn't exist or the field type is not list or combo it will return - * null. - * @param fieldName the field name - * @return the list of export option values from fields of type list or combo - */ - public String[] getListOptionDisplay(String fieldName) { - return getListOption(fieldName, 1); - } - - /** - * Sets the option list for fields of type list or combo. One of exportValues - * or displayValues may be null but not both. This method will only - * set the list but will not set the value or appearance. For that, calling setField() - * is required. - *

- * An example: - *

- *

-     * PdfReader pdf = new PdfReader("input.pdf");
-     * PdfStamper stp = new PdfStamper(pdf, new FileOutputStream("output.pdf"));
-     * AcroFields af = stp.getAcroFields();
-     * af.setListOption("ComboBox", new String[]{"a", "b", "c"}, new String[]{"first", "second", "third"});
-     * af.setField("ComboBox", "b");
-     * stp.close();
-     * 
- * @param fieldName the field name - * @param exportValues the export values - * @param displayValues the display values - * @return true if the operation succeeded, false otherwise - */ - public boolean setListOption(String fieldName, String[] exportValues, String[] displayValues) { - if (exportValues == null && displayValues == null) - return false; - if (exportValues != null && displayValues != null && exportValues.length != displayValues.length) - throw new IllegalArgumentException("The export and the display array must have the same size."); - int ftype = getFieldType(fieldName); - if (ftype != FIELD_TYPE_COMBO && ftype != FIELD_TYPE_LIST) - return false; - Item fd = (Item)fields.get(fieldName); - String[] sing = null; - if (exportValues == null && displayValues != null) - sing = displayValues; - else if (exportValues != null && displayValues == null) - sing = exportValues; - PdfArray opt = new PdfArray(); - if (sing != null) { - for (int k = 0; k < sing.length; ++k) - opt.add(new PdfString(sing[k], PdfObject.TEXT_UNICODE)); - } - else { - for (int k = 0; k < exportValues.length; ++k) { - PdfArray a = new PdfArray(); - a.add(new PdfString(exportValues[k], PdfObject.TEXT_UNICODE)); - a.add(new PdfString(displayValues[k], PdfObject.TEXT_UNICODE)); - opt.add(a); - } - } - ((PdfDictionary)fd.values.get(0)).put(PdfName.OPT, opt); - for (int j = 0; j < fd.merged.size(); ++j) - ((PdfDictionary)fd.merged.get(j)).put(PdfName.OPT, opt); - return true; - } - - /** - * Gets the field type. The type can be one of: FIELD_TYPE_PUSHBUTTON, - * FIELD_TYPE_CHECKBOX, FIELD_TYPE_RADIOBUTTON, - * FIELD_TYPE_TEXT, FIELD_TYPE_LIST, - * FIELD_TYPE_COMBO or FIELD_TYPE_SIGNATURE. - *

- * If the field does not exist or is invalid it returns - * FIELD_TYPE_NONE. - * @param fieldName the field name - * @return the field type - */ - public int getFieldType(String fieldName) { - Item fd = (Item)fields.get(fieldName); - if (fd == null) - return FIELD_TYPE_NONE; - PdfObject type = PdfReader.getPdfObject(((PdfDictionary)fd.merged.get(0)).get(PdfName.FT)); - if (type == null) - return FIELD_TYPE_NONE; - int ff = 0; - PdfObject ffo = PdfReader.getPdfObject(((PdfDictionary)fd.merged.get(0)).get(PdfName.FF)); - if (ffo != null && ffo.type() == PdfObject.NUMBER) - ff = ((PdfNumber)ffo).intValue(); - if (PdfName.BTN.equals(type)) { - if ((ff & PdfFormField.FF_PUSHBUTTON) != 0) - return FIELD_TYPE_PUSHBUTTON; - if ((ff & PdfFormField.FF_RADIO) != 0) - return FIELD_TYPE_RADIOBUTTON; - else - return FIELD_TYPE_CHECKBOX; - } - else if (PdfName.TX.equals(type)) { - return FIELD_TYPE_TEXT; - } - else if (PdfName.CH.equals(type)) { - if ((ff & PdfFormField.FF_COMBO) != 0) - return FIELD_TYPE_COMBO; - else - return FIELD_TYPE_LIST; - } - else if (PdfName.SIG.equals(type)) { - return FIELD_TYPE_SIGNATURE; - } - return FIELD_TYPE_NONE; - } - - /** - * Export the fields as a FDF. - * @param writer the FDF writer - */ - public void exportAsFdf(FdfWriter writer) { - for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - Item item = (Item)entry.getValue(); - String name = (String)entry.getKey(); - PdfObject v = PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.V)); - if (v == null) - continue; - String value = getField(name); - if (lastWasString) - writer.setFieldAsString(name, value); - else - writer.setFieldAsName(name, value); - } - } - - /** - * Renames a field. Only the last part of the name can be renamed. For example, - * if the original field is "ab.cd.ef" only the "ef" part can be renamed. - * @param oldName the old field name - * @param newName the new field name - * @return true if the renaming was successful, false - * otherwise - */ - public boolean renameField(String oldName, String newName) { - int idx1 = oldName.lastIndexOf('.') + 1; - int idx2 = newName.lastIndexOf('.') + 1; - if (idx1 != idx2) - return false; - if (!oldName.substring(0, idx1).equals(newName.substring(0, idx2))) - return false; - if (fields.containsKey(newName)) - return false; - Item item = (Item)fields.get(oldName); - if (item == null) - return false; - newName = newName.substring(idx2); - PdfString ss = new PdfString(newName, PdfObject.TEXT_UNICODE); - for (int k = 0; k < item.merged.size(); ++k) { - PdfDictionary dic = (PdfDictionary)item.values.get(k); - dic.put(PdfName.T, ss); - markUsed(dic); - dic = (PdfDictionary)item.merged.get(k); - dic.put(PdfName.T, ss); - } - fields.remove(oldName); - fields.put(newName, item); - return true; - } - - static private Object[] splitDAelements(String da) { - try { - PRTokeniser tk = new PRTokeniser(PdfEncodings.convertToBytes(da, null)); - ArrayList stack = new ArrayList(); - Object ret[] = new Object[3]; - while (tk.nextToken()) { - if (tk.getTokenType() == PRTokeniser.TK_COMMENT) - continue; - if (tk.getTokenType() == PRTokeniser.TK_OTHER) { - String operator = tk.getStringValue(); - if (operator.equals("Tf")) { - if (stack.size() >= 2) { - ret[DA_FONT] = stack.get(stack.size() - 2); - ret[DA_SIZE] = new Float((String)stack.get(stack.size() - 1)); - } - } - else if (operator.equals("g")) { - if (stack.size() >= 1) { - float gray = new Float((String)stack.get(stack.size() - 1)).floatValue(); - if (gray != 0) - ret[DA_COLOR] = new GrayColor(gray); - } - } - else if (operator.equals("rg")) { - if (stack.size() >= 3) { - float red = new Float((String)stack.get(stack.size() - 3)).floatValue(); - float green = new Float((String)stack.get(stack.size() - 2)).floatValue(); - float blue = new Float((String)stack.get(stack.size() - 1)).floatValue(); - ret[DA_COLOR] = new Color(red, green, blue); - } - } - else if (operator.equals("k")) { - if (stack.size() >= 4) { - float cyan = new Float((String)stack.get(stack.size() - 4)).floatValue(); - float magenta = new Float((String)stack.get(stack.size() - 3)).floatValue(); - float yellow = new Float((String)stack.get(stack.size() - 2)).floatValue(); - float black = new Float((String)stack.get(stack.size() - 1)).floatValue(); - ret[DA_COLOR] = new CMYKColor(cyan, magenta, yellow, black); - } - } - stack.clear(); - } - else - stack.add(tk.getStringValue()); - } - return ret; - } - catch (IOException ioe) { - throw new ExceptionConverter(ioe); - } - } - - PdfAppearance getAppearance(PdfDictionary merged, String text, String fieldName) throws IOException, DocumentException { - topFirst = 0; - int flags = 0; - TextField tx = null; - if (fieldCache == null || !fieldCache.containsKey(fieldName)) { - tx = new TextField(writer, null, null); - tx.setExtraMargin(extraMarginLeft, extraMarginTop); - tx.setBorderWidth(0); - tx.setSubstitutionFonts(substitutionFonts); - // the text size and color - PdfString da = (PdfString)PdfReader.getPdfObject(merged.get(PdfName.DA)); - if (da != null) { - Object dab[] = splitDAelements(da.toUnicodeString()); - if (dab[DA_SIZE] != null) - tx.setFontSize(((Float)dab[DA_SIZE]).floatValue()); - if (dab[DA_COLOR] != null) - tx.setTextColor((Color)dab[DA_COLOR]); - if (dab[DA_FONT] != null) { - PdfDictionary font = (PdfDictionary)PdfReader.getPdfObject(merged.get(PdfName.DR)); - if (font != null) { - font = (PdfDictionary)PdfReader.getPdfObject(font.get(PdfName.FONT)); - if (font != null) { - PdfObject po = font.get(new PdfName((String)dab[DA_FONT])); - if (po != null && po.type() == PdfObject.INDIRECT) { - PRIndirectReference por = (PRIndirectReference)po; - BaseFont bp = new DocumentFont((PRIndirectReference)po); - tx.setFont(bp); - Integer porkey = new Integer(por.getNumber()); - BaseFont porf = (BaseFont)extensionFonts.get(porkey); - if (porf == null) { - if (!extensionFonts.containsKey(porkey)) { - PdfDictionary fo = (PdfDictionary)PdfReader.getPdfObject(po); - PdfDictionary fd = (PdfDictionary)PdfReader.getPdfObject(fo.get(PdfName.FONTDESCRIPTOR)); - if (fd != null) { - PRStream prs = (PRStream)PdfReader.getPdfObject(fd.get(PdfName.FONTFILE2)); - if (prs == null) - prs = (PRStream)PdfReader.getPdfObject(fd.get(PdfName.FONTFILE3)); - if (prs == null) { - extensionFonts.put(porkey, null); - } - else { - try { - porf = BaseFont.createFont("font.ttf", BaseFont.IDENTITY_H, true, false, PdfReader.getStreamBytes(prs), null); - } - catch (Exception e) { - porf = null; - } - extensionFonts.put(porkey, porf); - } - } - } - } - tx.setExtensionFont(porf); - } - else { - BaseFont bf = (BaseFont)localFonts.get(dab[DA_FONT]); - if (bf == null) { - String fn[] = (String[])stdFieldFontNames.get(dab[DA_FONT]); - if (fn != null) { - try { - String enc = "winansi"; - if (fn.length > 1) - enc = fn[1]; - bf = BaseFont.createFont(fn[0], enc, false); - tx.setFont(bf); - } - catch (Exception e) { - // empty - } - } - } - else - tx.setFont(bf); - } - } - } - } - } - //rotation, border and backgound color - PdfDictionary mk = (PdfDictionary)PdfReader.getPdfObject(merged.get(PdfName.MK)); - if (mk != null) { - PdfArray ar = (PdfArray)PdfReader.getPdfObject(mk.get(PdfName.BC)); - Color border = getMKColor(ar); - tx.setBorderColor(border); - if (border != null) - tx.setBorderWidth(1); - ar = (PdfArray)PdfReader.getPdfObject(mk.get(PdfName.BG)); - tx.setBackgroundColor(getMKColor(ar)); - PdfNumber rotation = (PdfNumber)PdfReader.getPdfObject(mk.get(PdfName.R)); - if (rotation != null) - tx.setRotation(rotation.intValue()); - } - //multiline - PdfNumber nfl = (PdfNumber)PdfReader.getPdfObject(merged.get(PdfName.FF)); - if (nfl != null) - flags = nfl.intValue(); - tx.setOptions(((flags & PdfFormField.FF_MULTILINE) == 0 ? 0 : TextField.MULTILINE) | ((flags & PdfFormField.FF_COMB) == 0 ? 0 : TextField.COMB)); - if ((flags & PdfFormField.FF_COMB) != 0) { - PdfNumber maxLen = (PdfNumber)PdfReader.getPdfObject(merged.get(PdfName.MAXLEN)); - int len = 0; - if (maxLen != null) - len = maxLen.intValue(); - tx.setMaxCharacterLength(len); - } - //alignment - nfl = (PdfNumber)PdfReader.getPdfObject(merged.get(PdfName.Q)); - if (nfl != null) { - if (nfl.intValue() == PdfFormField.Q_CENTER) - tx.setAlignment(Element.ALIGN_CENTER); - else if (nfl.intValue() == PdfFormField.Q_RIGHT) - tx.setAlignment(Element.ALIGN_RIGHT); - } - //border styles - PdfDictionary bs = (PdfDictionary)PdfReader.getPdfObject(merged.get(PdfName.BS)); - if (bs != null) { - PdfNumber w = (PdfNumber)PdfReader.getPdfObject(bs.get(PdfName.W)); - if (w != null) - tx.setBorderWidth(w.floatValue()); - PdfName s = (PdfName)PdfReader.getPdfObject(bs.get(PdfName.S)); - if (PdfName.D.equals(s)) - tx.setBorderStyle(PdfBorderDictionary.STYLE_DASHED); - else if (PdfName.B.equals(s)) - tx.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED); - else if (PdfName.I.equals(s)) - tx.setBorderStyle(PdfBorderDictionary.STYLE_INSET); - else if (PdfName.U.equals(s)) - tx.setBorderStyle(PdfBorderDictionary.STYLE_UNDERLINE); - } - else { - PdfArray bd = (PdfArray)PdfReader.getPdfObject(merged.get(PdfName.BORDER)); - if (bd != null) { - ArrayList ar = bd.getArrayList(); - if (ar.size() >= 3) - tx.setBorderWidth(((PdfNumber)ar.get(2)).floatValue()); - if (ar.size() >= 4) - tx.setBorderStyle(PdfBorderDictionary.STYLE_DASHED); - } - } - //rect - PdfArray rect = (PdfArray)PdfReader.getPdfObject(merged.get(PdfName.RECT)); - Rectangle box = PdfReader.getNormalizedRectangle(rect); - if (tx.getRotation() == 90 || tx.getRotation() == 270) - box = box.rotate(); - tx.setBox(box); - if (fieldCache != null) - fieldCache.put(fieldName, tx); - } - else { - tx = (TextField)fieldCache.get(fieldName); - tx.setWriter(writer); - } - PdfName fieldType = (PdfName)PdfReader.getPdfObject(merged.get(PdfName.FT)); - if (PdfName.TX.equals(fieldType)) { - tx.setText(text); - return tx.getAppearance(); - } - if (!PdfName.CH.equals(fieldType)) - throw new DocumentException("An appearance was requested without a variable text field."); - PdfArray opt = (PdfArray)PdfReader.getPdfObject(merged.get(PdfName.OPT)); - if ((flags & PdfFormField.FF_COMBO) != 0 && opt == null) { - tx.setText(text); - return tx.getAppearance(); - } - if (opt != null) { - ArrayList op = opt.getArrayList(); - String choices[] = new String[op.size()]; - String choicesExp[] = new String[op.size()]; - for (int k = 0; k < op.size(); ++k) { - PdfObject obj = (PdfObject)op.get(k); - if (obj.isString()) { - choices[k] = choicesExp[k] = ((PdfString)obj).toUnicodeString(); - } - else { - ArrayList opar = ((PdfArray)obj).getArrayList(); - choicesExp[k] = ((PdfString)opar.get(0)).toUnicodeString(); - choices[k] = ((PdfString)opar.get(1)).toUnicodeString(); - } - } - if ((flags & PdfFormField.FF_COMBO) != 0) { - for (int k = 0; k < choices.length; ++k) { - if (text.equals(choicesExp[k])) { - text = choices[k]; - break; - } - } - tx.setText(text); - return tx.getAppearance(); - } - int idx = 0; - for (int k = 0; k < choicesExp.length; ++k) { - if (text.equals(choicesExp[k])) { - idx = k; - break; - } - } - tx.setChoices(choices); - tx.setChoiceExports(choicesExp); - tx.setChoiceSelection(idx); - } - PdfAppearance app = tx.getListAppearance(); - topFirst = tx.getTopFirst(); - return app; - } - - Color getMKColor(PdfArray ar) { - if (ar == null) - return null; - ArrayList cc = ar.getArrayList(); - switch (cc.size()) { - case 1: - return new GrayColor(((PdfNumber)cc.get(0)).floatValue()); - case 3: - return new Color(((PdfNumber)cc.get(0)).floatValue(), ((PdfNumber)cc.get(1)).floatValue(), ((PdfNumber)cc.get(2)).floatValue()); - case 4: - return new CMYKColor(((PdfNumber)cc.get(0)).floatValue(), ((PdfNumber)cc.get(1)).floatValue(), ((PdfNumber)cc.get(2)).floatValue(), ((PdfNumber)cc.get(3)).floatValue()); - default: - return null; - } - } - - /** Gets the field value. - * @param name the fully qualified field name - * @return the field value - */ - public String getField(String name) { - Item item = (Item)fields.get(name); - if (item == null) - return null; - lastWasString = false; - PdfObject v = PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.V)); - if (v == null) - return ""; - PdfName type = (PdfName)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.FT)); - if (PdfName.BTN.equals(type)) { - PdfNumber ff = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.FF)); - int flags = 0; - if (ff != null) - flags = ff.intValue(); - if ((flags & PdfFormField.FF_PUSHBUTTON) != 0) - return ""; - String value = ""; - if (v.isName()) - value = PdfName.decodeName(v.toString()); - else if (v.isString()) - value = ((PdfString)v).toUnicodeString(); - PdfObject opts = PdfReader.getPdfObject(((PdfDictionary)item.values.get(0)).get(PdfName.OPT)); - if (opts != null && opts.isArray()) { - ArrayList list = ((PdfArray)opts).getArrayList(); - int idx = 0; - try { - idx = Integer.parseInt(value); - PdfString ps = (PdfString)list.get(idx); - value = ps.toUnicodeString(); - lastWasString = true; - } - catch (Exception e) { - } - } - return value; - } - if (v.isString()) { - lastWasString = true; - return ((PdfString)v).toUnicodeString(); - } - return PdfName.decodeName(v.toString()); - } - - /** - * Sets a field property. Valid property names are: - *

- *

- * @param field the field name - * @param name the property name - * @param value the property value - * @param inst an array of int indexing into AcroField.Item.merged elements to process. - * Set to null to process all - * @return true if the property exists, false otherwise - */ - public boolean setFieldProperty(String field, String name, Object value, int inst[]) { - if (writer == null) - throw new RuntimeException("This AcroFields instance is read-only."); - try { - Item item = (Item)fields.get(field); - if (item == null) - return false; - InstHit hit = new InstHit(inst); - if (name.equalsIgnoreCase("textfont")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfString da = (PdfString)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(k)).get(PdfName.DA)); - PdfDictionary dr = (PdfDictionary)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(k)).get(PdfName.DR)); - if (da != null && dr != null) { - Object dao[] = splitDAelements(da.toUnicodeString()); - PdfAppearance cb = new PdfAppearance(); - if (dao[DA_FONT] != null) { - BaseFont bf = (BaseFont)value; - PdfName psn = (PdfName)PdfAppearance.stdFieldFontNames.get(bf.getPostscriptFontName()); - if (psn == null) { - psn = new PdfName(bf.getPostscriptFontName()); - } - PdfDictionary fonts = (PdfDictionary)PdfReader.getPdfObject(dr.get(PdfName.FONT)); - if (fonts == null) { - fonts = new PdfDictionary(); - dr.put(PdfName.FONT, fonts); - } - PdfIndirectReference fref = (PdfIndirectReference)fonts.get(psn); - PdfDictionary top = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM)); - markUsed(top); - dr = (PdfDictionary)PdfReader.getPdfObject(top.get(PdfName.DR)); - if (dr == null) { - dr = new PdfDictionary(); - top.put(PdfName.DR, dr); - } - markUsed(dr); - PdfDictionary fontsTop = (PdfDictionary)PdfReader.getPdfObject(dr.get(PdfName.FONT)); - if (fontsTop == null) { - fontsTop = new PdfDictionary(); - dr.put(PdfName.FONT, fontsTop); - } - markUsed(fontsTop); - PdfIndirectReference frefTop = (PdfIndirectReference)fontsTop.get(psn); - if (frefTop != null) { - if (fref == null) - fonts.put(psn, frefTop); - } - else if (fref == null) { - FontDetails fd; - if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { - fd = new FontDetails(null, ((DocumentFont)bf).getIndirectReference(), bf); - } - else { - bf.setSubset(false); - fd = writer.addSimple(bf); - localFonts.put(psn.toString().substring(1), bf); - } - fontsTop.put(psn, fd.getIndirectReference()); - fonts.put(psn, fd.getIndirectReference()); - } - ByteBuffer buf = cb.getInternalBuffer(); - buf.append(psn.getBytes()).append(' ').append(((Float)dao[DA_SIZE]).floatValue()).append(" Tf "); - if (dao[DA_COLOR] != null) - cb.setColorFill((Color)dao[DA_COLOR]); - PdfString s = new PdfString(cb.toString()); - ((PdfDictionary)item.merged.get(k)).put(PdfName.DA, s); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.DA, s); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - } - } - else if (name.equalsIgnoreCase("textcolor")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfString da = (PdfString)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(k)).get(PdfName.DA)); - if (da != null) { - Object dao[] = splitDAelements(da.toUnicodeString()); - PdfAppearance cb = new PdfAppearance(); - if (dao[DA_FONT] != null) { - ByteBuffer buf = cb.getInternalBuffer(); - buf.append(new PdfName((String)dao[DA_FONT]).getBytes()).append(' ').append(((Float)dao[DA_SIZE]).floatValue()).append(" Tf "); - cb.setColorFill((Color)value); - PdfString s = new PdfString(cb.toString()); - ((PdfDictionary)item.merged.get(k)).put(PdfName.DA, s); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.DA, s); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - } - } - else if (name.equalsIgnoreCase("textsize")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfString da = (PdfString)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(k)).get(PdfName.DA)); - if (da != null) { - Object dao[] = splitDAelements(da.toUnicodeString()); - PdfAppearance cb = new PdfAppearance(); - if (dao[DA_FONT] != null) { - ByteBuffer buf = cb.getInternalBuffer(); - buf.append(new PdfName((String)dao[DA_FONT]).getBytes()).append(' ').append(((Float)value).floatValue()).append(" Tf "); - if (dao[DA_COLOR] != null) - cb.setColorFill((Color)dao[DA_COLOR]); - PdfString s = new PdfString(cb.toString()); - ((PdfDictionary)item.merged.get(k)).put(PdfName.DA, s); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.DA, s); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - } - } - else if (name.equalsIgnoreCase("bgcolor") || name.equalsIgnoreCase("bordercolor")) { - PdfName dname = (name.equalsIgnoreCase("bgcolor") ? PdfName.BG : PdfName.BC); - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfObject obj = PdfReader.getPdfObject(((PdfDictionary)item.merged.get(k)).get(PdfName.MK)); - markUsed(obj); - PdfDictionary mk = (PdfDictionary)obj; - if (mk == null) { - if (value == null) - return true; - mk = new PdfDictionary(); - ((PdfDictionary)item.merged.get(k)).put(PdfName.MK, mk); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.MK, mk); - markUsed((PdfDictionary)item.widgets.get(k)); - } - if (value == null) - mk.remove(dname); - else - mk.put(dname, PdfFormField.getMKColor((Color)value)); - } - } - } - else - return false; - return true; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Sets a field property. Valid property names are: - *

- *

- * @param field the field name - * @param name the property name - * @param value the property value - * @param inst an array of int indexing into AcroField.Item.merged elements to process. - * Set to null to process all - * @return true if the property exists, false otherwise - */ - public boolean setFieldProperty(String field, String name, int value, int inst[]) { - if (writer == null) - throw new RuntimeException("This AcroFields instance is read-only."); - Item item = (Item)fields.get(field); - if (item == null) - return false; - InstHit hit = new InstHit(inst); - if (name.equalsIgnoreCase("flags")) { - PdfNumber num = new PdfNumber(value); - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - ((PdfDictionary)item.merged.get(k)).put(PdfName.F, num); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.F, num); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - else if (name.equalsIgnoreCase("setflags")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfNumber num = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.widgets.get(k)).get(PdfName.F)); - int val = 0; - if (num != null) - val = num.intValue(); - num = new PdfNumber(val | value); - ((PdfDictionary)item.merged.get(k)).put(PdfName.F, num); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.F, num); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - else if (name.equalsIgnoreCase("clrflags")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfNumber num = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.widgets.get(k)).get(PdfName.F)); - int val = 0; - if (num != null) - val = num.intValue(); - num = new PdfNumber(val & (~value)); - ((PdfDictionary)item.merged.get(k)).put(PdfName.F, num); - ((PdfDictionary)item.widgets.get(k)).put(PdfName.F, num); - markUsed((PdfDictionary)item.widgets.get(k)); - } - } - } - else if (name.equalsIgnoreCase("fflags")) { - PdfNumber num = new PdfNumber(value); - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - ((PdfDictionary)item.merged.get(k)).put(PdfName.FF, num); - ((PdfDictionary)item.values.get(k)).put(PdfName.FF, num); - markUsed((PdfDictionary)item.values.get(k)); - } - } - } - else if (name.equalsIgnoreCase("setfflags")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfNumber num = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.values.get(k)).get(PdfName.FF)); - int val = 0; - if (num != null) - val = num.intValue(); - num = new PdfNumber(val | value); - ((PdfDictionary)item.merged.get(k)).put(PdfName.FF, num); - ((PdfDictionary)item.values.get(k)).put(PdfName.FF, num); - markUsed((PdfDictionary)item.values.get(k)); - } - } - } - else if (name.equalsIgnoreCase("clrfflags")) { - for (int k = 0; k < item.merged.size(); ++k) { - if (hit.isHit(k)) { - PdfNumber num = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.values.get(k)).get(PdfName.FF)); - int val = 0; - if (num != null) - val = num.intValue(); - num = new PdfNumber(val & (~value)); - ((PdfDictionary)item.merged.get(k)).put(PdfName.FF, num); - ((PdfDictionary)item.values.get(k)).put(PdfName.FF, num); - markUsed((PdfDictionary)item.values.get(k)); - } - } - } - else - return false; - return true; - } - - /** Sets the fields by FDF merging. - * @param fdf the FDF form - * @throws IOException on error - * @throws DocumentException on error - */ - public void setFields(FdfReader fdf) throws IOException, DocumentException { - HashMap fd = fdf.getFields(); - for (Iterator i = fd.keySet().iterator(); i.hasNext();) { - String f = (String)i.next(); - String v = fdf.getFieldValue(f); - if (v != null) - setField(f, v); - } - } - - /** Sets the fields by XFDF merging. - * @param xfdf the XFDF form - * @throws IOException on error - * @throws DocumentException on error - */ - - public void setFields(XfdfReader xfdf) throws IOException, DocumentException { - HashMap fd = xfdf.getFields(); - for (Iterator i = fd.keySet().iterator(); i.hasNext();) { - String f = (String)i.next(); - String v = xfdf.getFieldValue(f); - if (v != null) - setField(f, v); - } - } - - /** Sets the field value. - * @param name the fully qualified field name - * @param value the field value - * @throws IOException on error - * @throws DocumentException on error - * @return true if the field was found and changed, - * false otherwise - */ - public boolean setField(String name, String value) throws IOException, DocumentException { - return setField(name, value, value); - } - - /** Sets the field value and the display string. The display string - * is used to build the appearance in the cases where the value - * is modified by Acrobat with JavaScript and the algorithm is - * known. - * @param name the fully qualified field name - * @param value the field value - * @param display the string that is used for the appearance - * @return true if the field was found and changed, - * false otherwise - * @throws IOException on error - * @throws DocumentException on error - */ - public boolean setField(String name, String value, String display) throws IOException, DocumentException { - if (writer == null) - throw new DocumentException("This AcroFields instance is read-only."); - Item item = (Item)fields.get(name); - if (item == null) - return false; - PdfName type = (PdfName)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.FT)); - if (PdfName.TX.equals(type)) { - PdfNumber maxLen = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.MAXLEN)); - int len = 0; - if (maxLen != null) - len = maxLen.intValue(); - if (len > 0) - value = value.substring(0, Math.min(len, value.length())); - } - if (PdfName.TX.equals(type) || PdfName.CH.equals(type)) { - PdfString v = new PdfString(value, PdfObject.TEXT_UNICODE); - for (int idx = 0; idx < item.values.size(); ++idx) { - PdfDictionary valueDic = (PdfDictionary)item.values.get(idx); - valueDic.put(PdfName.V, v); - valueDic.remove(PdfName.I); - markUsed(valueDic); - PdfDictionary merged = (PdfDictionary)item.merged.get(idx); - merged.remove(PdfName.I); - merged.put(PdfName.V, v); - PdfDictionary widget = (PdfDictionary)item.widgets.get(idx); - if (generateAppearances) { - PdfAppearance app = getAppearance(merged, display, name); - if (PdfName.CH.equals(type)) { - PdfNumber n = new PdfNumber(topFirst); - widget.put(PdfName.TI, n); - merged.put(PdfName.TI, n); - } - PdfDictionary appDic = (PdfDictionary)PdfReader.getPdfObject(widget.get(PdfName.AP)); - if (appDic == null) { - appDic = new PdfDictionary(); - widget.put(PdfName.AP, appDic); - merged.put(PdfName.AP, appDic); - } - appDic.put(PdfName.N, app.getIndirectReference()); - writer.releaseTemplate(app); - } - else { - widget.remove(PdfName.AP); - merged.remove(PdfName.AP); - } - markUsed(widget); - } - return true; - } - else if (PdfName.BTN.equals(type)) { - PdfNumber ff = (PdfNumber)PdfReader.getPdfObject(((PdfDictionary)item.merged.get(0)).get(PdfName.FF)); - int flags = 0; - if (ff != null) - flags = ff.intValue(); - if ((flags & PdfFormField.FF_PUSHBUTTON) != 0) - return true; - PdfName v = new PdfName(value); - if ((flags & PdfFormField.FF_RADIO) == 0) { - for (int idx = 0; idx < item.values.size(); ++idx) { - ((PdfDictionary)item.values.get(idx)).put(PdfName.V, v); - markUsed((PdfDictionary)item.values.get(idx)); - PdfDictionary merged = (PdfDictionary)item.merged.get(idx); - merged.put(PdfName.V, v); - merged.put(PdfName.AS, v); - PdfDictionary widget = (PdfDictionary)item.widgets.get(idx); - if (isInAP(widget, v)) - widget.put(PdfName.AS, v); - else - widget.put(PdfName.AS, PdfName.Off); - markUsed(widget); - } - } - else { - ArrayList lopt = new ArrayList(); - PdfObject opts = PdfReader.getPdfObject(((PdfDictionary)item.values.get(0)).get(PdfName.OPT)); - if (opts != null && opts.isArray()) { - ArrayList list = ((PdfArray)opts).getArrayList(); - for (int k = 0; k < list.size(); ++k) { - PdfObject vv = PdfReader.getPdfObject((PdfObject)list.get(k)); - if (vv != null && vv.isString()) - lopt.add(((PdfString)vv).toUnicodeString()); - else - lopt.add(null); - } - } - int vidx = lopt.indexOf(value); - PdfName valt = null; - PdfName vt; - if (vidx >= 0) { - vt = valt = new PdfName(String.valueOf(vidx)); - } - else - vt = v; - for (int idx = 0; idx < item.values.size(); ++idx) { - PdfDictionary merged = (PdfDictionary)item.merged.get(idx); - PdfDictionary widget = (PdfDictionary)item.widgets.get(idx); - markUsed((PdfDictionary)item.values.get(idx)); - if (valt != null) { - PdfString ps = new PdfString(value, PdfObject.TEXT_UNICODE); - ((PdfDictionary)item.values.get(idx)).put(PdfName.V, ps); - merged.put(PdfName.V, ps); - } - else { - ((PdfDictionary)item.values.get(idx)).put(PdfName.V, v); - merged.put(PdfName.V, v); - } - markUsed(widget); - if (isInAP(widget, vt)) { - merged.put(PdfName.AS, vt); - widget.put(PdfName.AS, vt); - } - else { - merged.put(PdfName.AS, PdfName.Off); - widget.put(PdfName.AS, PdfName.Off); - } - } - } - return true; - } - return false; - } - - boolean isInAP(PdfDictionary dic, PdfName check) { - PdfDictionary appDic = (PdfDictionary)PdfReader.getPdfObject(dic.get(PdfName.AP)); - if (appDic == null) - return false; - PdfDictionary NDic = (PdfDictionary)PdfReader.getPdfObject(appDic.get(PdfName.N)); - return (NDic != null && NDic.get(check) != null); - } - - /** Gets all the fields. The fields are keyed by the fully qualified field name and - * the value is an instance of AcroFields.Item. - * @return all the fields - */ - public HashMap getFields() { - return fields; - } - - /** - * Gets the field structure. - * @param name the name of the field - * @return the field structure or null if the field - * does not exist - */ - public Item getFieldItem(String name) { - return (Item)fields.get(name); - } - - /** - * Gets the field box positions in the document. The return is an array of float - * multiple of 5. For each of this groups the values are: [page, llx, lly, urx, - * ury]. - * @param name the field name - * @return the positions or null if field does not exist - */ - public float[] getFieldPositions(String name) { - Item item = (Item)fields.get(name); - if (item == null) - return null; - float ret[] = new float[item.page.size() * 5]; - int ptr = 0; - for (int k = 0; k < item.page.size(); ++k) { - try { - PdfDictionary wd = (PdfDictionary)item.widgets.get(k); - PdfArray rect = (PdfArray)wd.get(PdfName.RECT); - if (rect == null) - continue; - Rectangle r = PdfReader.getNormalizedRectangle(rect); - ret[ptr] = ((Integer)item.page.get(k)).floatValue(); - ++ptr; - ret[ptr++] = r.left(); - ret[ptr++] = r.bottom(); - ret[ptr++] = r.right(); - ret[ptr++] = r.top(); - } - catch (Exception e) { - // empty on purpose - } - } - if (ptr < ret.length) { - float ret2[] = new float[ptr]; - System.arraycopy(ret, 0, ret2, 0, ptr); - return ret2; - } - return ret; - } - - private int removeRefFromArray(PdfArray array, PdfObject refo) { - ArrayList ar = array.getArrayList(); - if (refo == null || !refo.isIndirect()) - return ar.size(); - PdfIndirectReference ref = (PdfIndirectReference)refo; - for (int j = 0; j < ar.size(); ++j) { - PdfObject obj = (PdfObject)ar.get(j); - if (!obj.isIndirect()) - continue; - if (((PdfIndirectReference)obj).getNumber() == ref.getNumber()) - ar.remove(j--); - } - return ar.size(); - } - - /** - * Removes all the fields from page. - * @param page the page to remove the fields from - * @return true if any field was removed, false otherwise - */ - public boolean removeFieldsFromPage(int page) { - if (page < 1) - return false; - String names[] = new String[fields.size()]; - fields.keySet().toArray(names); - boolean found = false; - for (int k = 0; k < names.length; ++k) { - boolean fr = removeField(names[k], page); - found = (found || fr); - } - return found; - } - - /** - * Removes a field from the document. If page equals -1 all the fields with this - * name are removed from the document otherwise only the fields in - * that particular page are removed. - * @param name the field name - * @param page the page to remove the field from or -1 to remove it from all the pages - * @return true if the field exists, false otherwise - */ - public boolean removeField(String name, int page) { - Item item = (Item)fields.get(name); - if (item == null) - return false; - PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM), reader.getCatalog()); - - if (acroForm == null) - return false; - PdfArray arrayf = (PdfArray)PdfReader.getPdfObject(acroForm.get(PdfName.FIELDS), acroForm); - if (arrayf == null) - return false; - for (int k = 0; k < item.widget_refs.size(); ++k) { - int pageV = ((Integer)item.page.get(k)).intValue(); - if (page != -1 && page != pageV) - continue; - PdfIndirectReference ref = (PdfIndirectReference)item.widget_refs.get(k); - PdfDictionary wd = (PdfDictionary)PdfReader.getPdfObject(ref); - PdfDictionary pageDic = reader.getPageN(pageV); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS), pageDic); - if (annots != null) { - if (removeRefFromArray(annots, ref) == 0) { - pageDic.remove(PdfName.ANNOTS); - markUsed(pageDic); - } - else - markUsed(annots); - } - PdfReader.killIndirect(ref); - PdfIndirectReference kid = ref; - while ((ref = (PdfIndirectReference)wd.get(PdfName.PARENT)) != null) { - wd = (PdfDictionary)PdfReader.getPdfObject(ref); - PdfArray kids = (PdfArray)PdfReader.getPdfObject(wd.get(PdfName.KIDS)); - if (removeRefFromArray(kids, kid) != 0) - break; - kid = ref; - PdfReader.killIndirect(ref); - } - if (ref == null) { - removeRefFromArray(arrayf, kid); - markUsed(arrayf); - } - if (page != -1) { - item.merged.remove(k); - item.page.remove(k); - item.values.remove(k); - item.widget_refs.remove(k); - item.widgets.remove(k); - --k; - } - } - if (page == -1 || item.merged.size() == 0) - fields.remove(name); - return true; - } - - /** - * Removes a field from the document. - * @param name the field name - * @return true if the field exists, false otherwise - */ - public boolean removeField(String name) { - return removeField(name, -1); - } - - /** Gets the property generateAppearances. - * @return the property generateAppearances - */ - public boolean isGenerateAppearances() { - return this.generateAppearances; - } - - /** Sets the option to generate appearances. Not generating apperances - * will speed-up form filling but the results can be - * unexpected in Acrobat. Don't use it unless your environment is well - * controlled. The default is true. - * @param generateAppearances the option to generate appearances - */ - public void setGenerateAppearances(boolean generateAppearances) { - this.generateAppearances = generateAppearances; - PdfDictionary top = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM)); - if (generateAppearances) - top.remove(PdfName.NEEDAPPEARANCES); - else - top.put(PdfName.NEEDAPPEARANCES, PdfBoolean.PDFTRUE); - } - - /** The field representations for retrieval and modification. */ - public static class Item { - /** An array of PdfDictionary where the value tag /V - * is present. - */ - public ArrayList values = new ArrayList(); - /** An array of PdfDictionary with the widgets. - */ - public ArrayList widgets = new ArrayList(); - /** An array of PdfDictionary with the widget references. - */ - public ArrayList widget_refs = new ArrayList(); - /** An array of PdfDictionary with all the field - * and widget tags merged. - */ - public ArrayList merged = new ArrayList(); - /** An array of Integer with the page numbers where - * the widgets are displayed. - */ - public ArrayList page = new ArrayList(); - /** An array of Integer with the tab order of the field in the page. - */ - public ArrayList tabOrder = new ArrayList(); - } - - private static class InstHit { - IntHashtable hits; - public InstHit(int inst[]) { - if (inst == null) - return; - hits = new IntHashtable(); - for (int k = 0; k < inst.length; ++k) - hits.put(inst[k], 1); - } - - public boolean isHit(int n) { - if (hits == null) - return true; - return hits.containsKey(n); - } - } - - /** - * Gets the field names that have signatures and are signed. - * @return the field names that have signatures and are signed - */ - public ArrayList getSignatureNames() { - if (sigNames != null) - return new ArrayList(sigNames.keySet()); - sigNames = new HashMap(); - ArrayList sorter = new ArrayList(); - for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - Item item = (Item)entry.getValue(); - PdfDictionary merged = (PdfDictionary)item.merged.get(0); - if (!PdfName.SIG.equals(merged.get(PdfName.FT))) - continue; - PdfObject vo = PdfReader.getPdfObject(merged.get(PdfName.V)); - if (vo == null || vo.type() != PdfObject.DICTIONARY) - continue; - PdfDictionary v = (PdfDictionary)vo; - PdfObject contents = v.get(PdfName.CONTENTS); - if (contents == null || contents.type() != PdfObject.STRING) - continue; - PdfObject ro = v.get(PdfName.BYTERANGE); - if (ro == null || ro.type() != PdfObject.ARRAY) - continue; - ArrayList ra = ((PdfArray)ro).getArrayList(); - if (ra.size() < 2) - continue; - int length = ((PdfNumber)ra.get(ra.size() - 1)).intValue() + ((PdfNumber)ra.get(ra.size() - 2)).intValue(); - sorter.add(new Object[]{entry.getKey(), new int[]{length, 0}}); - } - Collections.sort(sorter, new AcroFields.SorterComparator()); - if (sorter.size() > 0) { - if (((int[])((Object[])sorter.get(sorter.size() - 1))[1])[0] == reader.getFileLength()) - totalRevisions = sorter.size(); - else - totalRevisions = sorter.size() + 1; - for (int k = 0; k < sorter.size(); ++k) { - Object objs[] = (Object[])sorter.get(k); - String name = (String)objs[0]; - int p[] = (int[])objs[1]; - p[1] = k + 1; - sigNames.put(name, p); - } - } - return new ArrayList(sigNames.keySet()); - } - - /** - * Gets the field names that have blank signatures. - * @return the field names that have blank signatures - */ - public ArrayList getBlankSignatureNames() { - getSignatureNames(); - ArrayList sigs = new ArrayList(); - for (Iterator it = fields.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - Item item = (Item)entry.getValue(); - PdfDictionary merged = (PdfDictionary)item.merged.get(0); - if (!PdfName.SIG.equals(merged.get(PdfName.FT))) - continue; - if (sigNames.containsKey(entry.getKey())) - continue; - sigs.add(entry.getKey()); - } - return sigs; - } - - /** - * Gets the signature dictionary, the one keyed by /V. - * @param name the field name - * @return the signature dictionary keyed by /V or null if the field is not - * a signature - */ - public PdfDictionary getSignatureDictionary(String name) { - getSignatureNames(); - if (!sigNames.containsKey(name)) - return null; - Item item = (Item)fields.get(name); - PdfDictionary merged = (PdfDictionary)item.merged.get(0); - return (PdfDictionary)PdfReader.getPdfObject(merged.get(PdfName.V)); - } - - /** - * Checks is the signature covers the entire document or just part of it. - * @param name the signature field name - * @return true if the signature covers the entire document, - * false otherwise - */ - public boolean signatureCoversWholeDocument(String name) { - getSignatureNames(); - if (!sigNames.containsKey(name)) - return false; - return ((int[])sigNames.get(name))[0] == reader.getFileLength(); - } - - /** - * Verifies a signature. An example usage is: - *

- *

-     * KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
-     * PdfReader reader = new PdfReader("my_signed_doc.pdf");
-     * AcroFields af = reader.getAcroFields();
-     * ArrayList names = af.getSignatureNames();
-     * for (int k = 0; k < names.size(); ++k) {
-     *    String name = (String)names.get(k);
-     *    System.out.println("Signature name: " + name);
-     *    System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
-     *    PdfPKCS7 pk = af.verifySignature(name);
-     *    Calendar cal = pk.getSignDate();
-     *    Certificate pkc[] = pk.getCertificates();
-     *    System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
-     *    System.out.println("Document modified: " + !pk.verify());
-     *    Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
-     *    if (fails == null)
-     *        System.out.println("Certificates verified against the KeyStore");
-     *    else
-     *        System.out.println("Certificate failed: " + fails[1]);
-     * }
-     * 
- * @param name the signature field name - * @return a PdfPKCS7 class to continue the verification - */ - public PdfPKCS7 verifySignature(String name) { - return verifySignature(name, null); - } - - /** - * Verifies a signature. An example usage is: - *

- *

-     * KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
-     * PdfReader reader = new PdfReader("my_signed_doc.pdf");
-     * AcroFields af = reader.getAcroFields();
-     * ArrayList names = af.getSignatureNames();
-     * for (int k = 0; k < names.size(); ++k) {
-     *    String name = (String)names.get(k);
-     *    System.out.println("Signature name: " + name);
-     *    System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
-     *    PdfPKCS7 pk = af.verifySignature(name);
-     *    Calendar cal = pk.getSignDate();
-     *    Certificate pkc[] = pk.getCertificates();
-     *    System.out.println("Subject: " + PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
-     *    System.out.println("Document modified: " + !pk.verify());
-     *    Object fails[] = PdfPKCS7.verifyCertificates(pkc, kall, null, cal);
-     *    if (fails == null)
-     *        System.out.println("Certificates verified against the KeyStore");
-     *    else
-     *        System.out.println("Certificate failed: " + fails[1]);
-     * }
-     * 
- * @param name the signature field name - * @param provider the provider or null for the default provider - * @return a PdfPKCS7 class to continue the verification - */ - public PdfPKCS7 verifySignature(String name, String provider) { - PdfDictionary v = getSignatureDictionary(name); - if (v == null) - return null; - try { - PdfName sub = (PdfName)PdfReader.getPdfObject(v.get(PdfName.SUBFILTER)); - PdfString contents = (PdfString)PdfReader.getPdfObject(v.get(PdfName.CONTENTS)); - PdfPKCS7 pk = null; - if (sub.equals(PdfName.ADBE_X509_RSA_SHA1)) { - PdfString cert = (PdfString)PdfReader.getPdfObject(v.get(PdfName.CERT)); - pk = new PdfPKCS7(contents.getOriginalBytes(), cert.getBytes(), provider); - } - else - pk = new PdfPKCS7(contents.getOriginalBytes(), provider); - updateByteRange(pk, v); - PdfString str = (PdfString)PdfReader.getPdfObject(v.get(PdfName.M)); - if (str != null) - pk.setSignDate(PdfDate.decode(str.toString())); - str = (PdfString)PdfReader.getPdfObject(v.get(PdfName.NAME)); - if (str != null) - pk.setSignName(str.toUnicodeString()); - str = (PdfString)PdfReader.getPdfObject(v.get(PdfName.REASON)); - if (str != null) - pk.setReason(str.toUnicodeString()); - str = (PdfString)PdfReader.getPdfObject(v.get(PdfName.LOCATION)); - if (str != null) - pk.setLocation(str.toUnicodeString()); - return pk; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - private void updateByteRange(PdfPKCS7 pkcs7, PdfDictionary v) { - PdfArray b = (PdfArray)PdfReader.getPdfObject(v.get(PdfName.BYTERANGE)); - RandomAccessFileOrArray rf = reader.getSafeFile(); - try { - rf.reOpen(); - byte buf[] = new byte[8192]; - ArrayList ar = b.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - int start = ((PdfNumber)ar.get(k)).intValue(); - int length = ((PdfNumber)ar.get(++k)).intValue(); - rf.seek(start); - while (length > 0) { - int rd = rf.read(buf, 0, Math.min(length, buf.length)); - if (rd <= 0) - break; - length -= rd; - pkcs7.update(buf, 0, rd); - } - } - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - finally { - try{rf.close();}catch(Exception e){} - } - } - - private void markUsed(PdfObject obj) { - if (!append) - return; - ((PdfStamperImp)writer).markUsed(obj); - } - - /** - * Gets the total number of revisions this document has. - * @return the total number of revisions - */ - public int getTotalRevisions() { - getSignatureNames(); - return this.totalRevisions; - } - - /** - * Gets this field revision. - * @param field the signature field name - * @return the revision or zero if it's not a signature field - */ - public int getRevision(String field) { - getSignatureNames(); - if (!sigNames.containsKey(field)) - return 0; - return ((int[])sigNames.get(field))[1]; - } - - /** - * Extracts a revision from the document. - * @param field the signature field name - * @return an InputStream covering the revision. Returns null if - * it's not a signature field - * @throws IOException on error - */ - public InputStream extractRevision(String field) throws IOException { - getSignatureNames(); - int length = ((int[])sigNames.get(field))[0]; - RandomAccessFileOrArray raf = reader.getSafeFile(); - raf.reOpen(); - raf.seek(0); - return new RevisionStream(raf, length); - } - - /** - * Gets the appearances cache. - * @return the appearances cache - */ - public HashMap getFieldCache() { - return this.fieldCache; - } - - /** - * Sets a cache for field appearances. Parsing the existing PDF to - * create a new TextField is time expensive. For those tasks that repeatedly - * fill the same PDF with different field values the use of the cache has dramatic - * speed advantages. An example usage: - *

- *

-     * String pdfFile = ...;// the pdf file used as template
-     * ArrayList xfdfFiles = ...;// the xfdf file names
-     * ArrayList pdfOutFiles = ...;// the output file names, one for each element in xpdfFiles
-     * HashMap cache = new HashMap();// the appearances cache
-     * PdfReader originalReader = new PdfReader(pdfFile);
-     * for (int k = 0; k < xfdfFiles.size(); ++k) {
-     *    PdfReader reader = new PdfReader(originalReader);
-     *    XfdfReader xfdf = new XfdfReader((String)xfdfFiles.get(k));
-     *    PdfStamper stp = new PdfStamper(reader, new FileOutputStream((String)pdfOutFiles.get(k)));
-     *    AcroFields af = stp.getAcroFields();
-     *    af.setFieldCache(cache);
-     *    af.setFields(xfdf);
-     *    stp.close();
-     * }
-     * 
- * @param fieldCache an HasMap that will carry the cached appearances - */ - public void setFieldCache(HashMap fieldCache) { - this.fieldCache = fieldCache; - } - - /** - * Sets extra margins in text fields to better mimic the Acrobat layout. - * @param extraMarginLeft the extra marging left - * @param extraMarginTop the extra margin top - */ - public void setExtraMargin(float extraMarginLeft, float extraMarginTop) { - this.extraMarginLeft = extraMarginLeft; - this.extraMarginTop = extraMarginTop; - } - - /** - * Adds a substitution font to the list. The fonts in this list will be used if the original - * font doesn't contain the needed glyphs. - * @param font the font - */ - public void addSubstitutionFont(BaseFont font) { - if (substitutionFonts == null) - substitutionFonts = new ArrayList(); - substitutionFonts.add(font); - } - - private static final HashMap stdFieldFontNames = new HashMap(); - - /** - * Holds value of property totalRevisions. - */ - private int totalRevisions; - - /** - * Holds value of property fieldCache. - */ - private HashMap fieldCache; - - static { - stdFieldFontNames.put("CoBO", new String[]{"Courier-BoldOblique"}); - stdFieldFontNames.put("CoBo", new String[]{"Courier-Bold"}); - stdFieldFontNames.put("CoOb", new String[]{"Courier-Oblique"}); - stdFieldFontNames.put("Cour", new String[]{"Courier"}); - stdFieldFontNames.put("HeBO", new String[]{"Helvetica-BoldOblique"}); - stdFieldFontNames.put("HeBo", new String[]{"Helvetica-Bold"}); - stdFieldFontNames.put("HeOb", new String[]{"Helvetica-Oblique"}); - stdFieldFontNames.put("Helv", new String[]{"Helvetica"}); - stdFieldFontNames.put("Symb", new String[]{"Symbol"}); - stdFieldFontNames.put("TiBI", new String[]{"Times-BoldItalic"}); - stdFieldFontNames.put("TiBo", new String[]{"Times-Bold"}); - stdFieldFontNames.put("TiIt", new String[]{"Times-Italic"}); - stdFieldFontNames.put("TiRo", new String[]{"Times-Roman"}); - stdFieldFontNames.put("ZaDb", new String[]{"ZapfDingbats"}); - stdFieldFontNames.put("HySm", new String[]{"HYSMyeongJo-Medium", "UniKS-UCS2-H"}); - stdFieldFontNames.put("HyGo", new String[]{"HYGoThic-Medium", "UniKS-UCS2-H"}); - stdFieldFontNames.put("KaGo", new String[]{"HeiseiKakuGo-W5", "UniKS-UCS2-H"}); - stdFieldFontNames.put("KaMi", new String[]{"HeiseiMin-W3", "UniJIS-UCS2-H"}); - stdFieldFontNames.put("MHei", new String[]{"MHei-Medium", "UniCNS-UCS2-H"}); - stdFieldFontNames.put("MSun", new String[]{"MSung-Light", "UniCNS-UCS2-H"}); - stdFieldFontNames.put("STSo", new String[]{"STSong-Light", "UniGB-UCS2-H"}); - } - - private static class RevisionStream extends InputStream { - private byte b[] = new byte[1]; - private RandomAccessFileOrArray raf; - private int length; - private int rangePosition = 0; - private boolean closed; - - private RevisionStream(RandomAccessFileOrArray raf, int length) { - this.raf = raf; - this.length = length; - } - - public int read() throws IOException { - int n = read(b); - if (n != 1) - return -1; - return b[0] & 0xff; - } - - public int read(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } else if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - if (rangePosition >= length) { - close(); - return -1; - } - int elen = Math.min(len, length - rangePosition); - raf.readFully(b, off, elen); - rangePosition += elen; - return elen; - } - - public void close() throws IOException { - if (!closed) { - raf.close(); - closed = true; - } - } - } - - private static class SorterComparator implements Comparator { - public int compare(Object o1, Object o2) { - int n1 = ((int[])((Object[])o1)[1])[0]; - int n2 = ((int[])((Object[])o2)[1])[0]; - return n1 - n2; - } - } - - /** - * Gets the list of substitution fonts. The list is composed of BaseFont and can be null. The fonts in this list will be used if the original - * font doesn't contain the needed glyphs. - * @return the list - */ - public ArrayList getSubstitutionFonts() { - return substitutionFonts; - } - - /** - * Sets a list of substitution fonts. The list is composed of BaseFont and can also be null. The fonts in this list will be used if the original - * font doesn't contain the needed glyphs. - * @param substitutionFonts the list - */ - public void setSubstitutionFonts(ArrayList substitutionFonts) { - this.substitutionFonts = substitutionFonts; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/ArabicLigaturizer.java b/src/main/java/com/lowagie/text/pdf/ArabicLigaturizer.java deleted file mode 100644 index 959b7b5..0000000 --- a/src/main/java/com/lowagie/text/pdf/ArabicLigaturizer.java +++ /dev/null @@ -1,771 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** Shape arabic characters. This code was converted from a C version - * at www.pango.org. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class ArabicLigaturizer { - - static boolean isVowel(char s) { - return ((s >= 0x064B) && (s <= 0x0655)) || (s == 0x0670); - } - - static char charshape(char s, int which) - /* which 0=isolated 1=final 2=initial 3=medial */ - { - int l, r, m; - if ((s >= 0x0621) && (s <= 0x06D3)) { - l = 0; - r = chartable.length - 1; - while (l <= r) { - m = (l + r) / 2; - if (s == chartable[m][0]) { - return chartable[m][which + 1]; - } - else if (s < chartable[m][0]) { - r = m - 1; - } - else { - l = m + 1; - } - } - } - else if (s >= 0xfef5 && s <= 0xfefb) - return (char)(s + which); - return s; - } - - static int shapecount(char s) { - int l, r, m; - if ((s >= 0x0621) && (s <= 0x06D3) && !isVowel(s)) { - l = 0; - r = chartable.length - 1; - while (l <= r) { - m = (l + r) / 2; - if (s == chartable[m][0]) { - return chartable[m].length - 1; - } - else if (s < chartable[m][0]) { - r = m - 1; - } - else { - l = m + 1; - } - } - } - else if (s == ZWJ) { - return 4; - } - return 1; - } - - static int ligature(char newchar, charstruct oldchar) { - /* 0 == no ligature possible; 1 == vowel; 2 == two chars; 3 == Lam+Alef */ - int retval = 0; - - if (oldchar.basechar == 0) - return 0; - if (isVowel(newchar)) { - retval = 1; - if ((oldchar.vowel != 0) && (newchar != SHADDA)) { - retval = 2; /* we eliminate the old vowel .. */ - } - switch (newchar) { - case SHADDA: - if (oldchar.mark1 == 0) { - oldchar.mark1 = SHADDA; - } - else { - return 0; /* no ligature possible */ - } - break; - case HAMZABELOW: - switch (oldchar.basechar) { - case ALEF: - oldchar.basechar = ALEFHAMZABELOW; - retval = 2; - break; - case LAM_ALEF: - oldchar.basechar = LAM_ALEFHAMZABELOW; - retval = 2; - break; - default: - oldchar.mark1 = HAMZABELOW; - break; - } - break; - case HAMZAABOVE: - switch (oldchar.basechar) { - case ALEF: - oldchar.basechar = ALEFHAMZA; - retval = 2; - break; - case LAM_ALEF: - oldchar.basechar = LAM_ALEFHAMZA; - retval = 2; - break; - case WAW: - oldchar.basechar = WAWHAMZA; - retval = 2; - break; - case YEH: - case ALEFMAKSURA: - case FARSIYEH: - oldchar.basechar = YEHHAMZA; - retval = 2; - break; - default: /* whatever sense this may make .. */ - oldchar.mark1 = HAMZAABOVE; - break; - } - break; - case MADDA: - switch (oldchar.basechar) { - case ALEF: - oldchar.basechar = ALEFMADDA; - retval = 2; - break; - } - break; - default: - oldchar.vowel = newchar; - break; - } - if (retval == 1) { - oldchar.lignum++; - } - return retval; - } - if (oldchar.vowel != 0) { /* if we already joined a vowel, we can't join a Hamza */ - return 0; - } - - switch (oldchar.basechar) { - case LAM: - switch (newchar) { - case ALEF: - oldchar.basechar = LAM_ALEF; - oldchar.numshapes = 2; - retval = 3; - break; - case ALEFHAMZA: - oldchar.basechar = LAM_ALEFHAMZA; - oldchar.numshapes = 2; - retval = 3; - break; - case ALEFHAMZABELOW: - oldchar.basechar = LAM_ALEFHAMZABELOW; - oldchar.numshapes = 2; - retval = 3; - break; - case ALEFMADDA: - oldchar.basechar = LAM_ALEFMADDA; - oldchar.numshapes = 2; - retval = 3; - break; - } - break; - case 0: - oldchar.basechar = newchar; - oldchar.numshapes = shapecount(newchar); - retval = 1; - break; - } - return retval; - } - - static void copycstostring(StringBuffer string, charstruct s, int level) { - /* s is a shaped charstruct; i is the index into the string */ - if (s.basechar == 0) - return; - - string.append(s.basechar); - s.lignum--; - if (s.mark1 != 0) { - if ((level & ar_novowel) == 0) { - string.append(s.mark1); - s.lignum--; - } - else { - s.lignum--; - } - } - if (s.vowel != 0) { - if ((level & ar_novowel) == 0) { - string.append(s.vowel); - s.lignum--; - } - else { /* vowel elimination */ - s.lignum--; - } - } -// while (s.lignum > 0) { /* NULL-insertion for Langbox-font */ -// string[i] = 0; -// i++; -// (s.lignum)--; -// } -// return i; - } - - // return len - static void doublelig(StringBuffer string, int level) - /* Ok. We have presentation ligatures in our font. */ - { - int len; - int olen = len = string.length(); - int j = 0, si = 1; - char lapresult; - - while (si < olen) { - lapresult = 0; - if ((level & ar_composedtashkeel) != 0) { - switch (string.charAt(j)) { - case SHADDA: - switch (string.charAt(si)) { - case KASRA: - lapresult = 0xFC62; - break; - case FATHA: - lapresult = 0xFC60; - break; - case DAMMA: - lapresult = 0xFC61; - break; - case 0x064C: - lapresult = 0xFC5E; - break; - case 0x064D: - lapresult = 0xFC5F; - break; - } - break; - case KASRA: - if (string.charAt(si) == SHADDA) - lapresult = 0xFC62; - break; - case FATHA: - if (string.charAt(si) == SHADDA) - lapresult = 0xFC60; - break; - case DAMMA: - if (string.charAt(si) == SHADDA) - lapresult = 0xFC61; - break; - } - } - - if ((level & ar_lig) != 0) { - switch (string.charAt(j)) { - case 0xFEDF: /* LAM initial */ - switch (string.charAt(si)) { - case 0xFE9E: - lapresult = 0xFC3F; - break; /* JEEM final */ - case 0xFEA0: - lapresult = 0xFCC9; - break; /* JEEM medial */ - case 0xFEA2: - lapresult = 0xFC40; - break; /* HAH final */ - case 0xFEA4: - lapresult = 0xFCCA; - break; /* HAH medial */ - case 0xFEA6: - lapresult = 0xFC41; - break; /* KHAH final */ - case 0xFEA8: - lapresult = 0xFCCB; - break; /* KHAH medial */ - case 0xFEE2: - lapresult = 0xFC42; - break; /* MEEM final */ - case 0xFEE4: - lapresult = 0xFCCC; - break; /* MEEM medial */ - } - break; - case 0xFE97: /* TEH inital */ - switch (string.charAt(si)) { - case 0xFEA0: - lapresult = 0xFCA1; - break; /* JEEM medial */ - case 0xFEA4: - lapresult = 0xFCA2; - break; /* HAH medial */ - case 0xFEA8: - lapresult = 0xFCA3; - break; /* KHAH medial */ - } - break; - case 0xFE91: /* BEH inital */ - switch (string.charAt(si)) { - case 0xFEA0: - lapresult = 0xFC9C; - break; /* JEEM medial */ - case 0xFEA4: - lapresult = 0xFC9D; - break; /* HAH medial */ - case 0xFEA8: - lapresult = 0xFC9E; - break; /* KHAH medial */ - } - break; - case 0xFEE7: /* NOON inital */ - switch (string.charAt(si)) { - case 0xFEA0: - lapresult = 0xFCD2; - break; /* JEEM initial */ - case 0xFEA4: - lapresult = 0xFCD3; - break; /* HAH medial */ - case 0xFEA8: - lapresult = 0xFCD4; - break; /* KHAH medial */ - } - break; - - case 0xFEE8: /* NOON medial */ - switch (string.charAt(si)) { - case 0xFEAE: - lapresult = 0xFC8A; - break; /* REH final */ - case 0xFEB0: - lapresult = 0xFC8B; - break; /* ZAIN final */ - } - break; - case 0xFEE3: /* MEEM initial */ - switch (string.charAt(si)) { - case 0xFEA0: - lapresult = 0xFCCE; - break; /* JEEM medial */ - case 0xFEA4: - lapresult = 0xFCCF; - break; /* HAH medial */ - case 0xFEA8: - lapresult = 0xFCD0; - break; /* KHAH medial */ - case 0xFEE4: - lapresult = 0xFCD1; - break; /* MEEM medial */ - } - break; - - case 0xFED3: /* FEH initial */ - switch (string.charAt(si)) { - case 0xFEF2: - lapresult = 0xFC32; - break; /* YEH final */ - } - break; - - default: - break; - } /* end switch string[si] */ - } - if (lapresult != 0) { - string.setCharAt(j, lapresult); - len--; - si++; /* jump over one character */ - /* we'll have to change this, too. */ - } - else { - j++; - string.setCharAt(j, string.charAt(si)); - si++; - } - } - string.setLength(len); - } - - static boolean connects_to_left(charstruct a) { - return a.numshapes > 2; - } - - static void shape(char text[], StringBuffer string, int level) { - /* string is assumed to be empty and big enough. - * text is the original text. - * This routine does the basic arabic reshaping. - * *len the number of non-null characters. - * - * Note: We have to unshape each character first! - */ - int join; - int which; - char nextletter; - - int p = 0; /* initialize for output */ - charstruct oldchar = new charstruct(); - charstruct curchar = new charstruct(); - while (p < text.length) { - nextletter = text[p++]; - //nextletter = unshape (nextletter); - - join = ligature(nextletter, curchar); - if (join == 0) { /* shape curchar */ - int nc = shapecount(nextletter); - //(*len)++; - if (nc == 1) { - which = 0; /* final or isolated */ - } - else { - which = 2; /* medial or initial */ - } - if (connects_to_left(oldchar)) { - which++; - } - - which = which % (curchar.numshapes); - curchar.basechar = charshape(curchar.basechar, which); - - /* get rid of oldchar */ - copycstostring(string, oldchar, level); - oldchar = curchar; /* new values in oldchar */ - - /* init new curchar */ - curchar = new charstruct(); - curchar.basechar = nextletter; - curchar.numshapes = nc; - curchar.lignum++; - // (*len) += unligature (&curchar, level); - } - else if (join == 1) { - } - // else - // { - // (*len) += unligature (&curchar, level); - // } - // p = g_utf8_next_char (p); - } - - /* Handle last char */ - if (connects_to_left(oldchar)) - which = 1; - else - which = 0; - which = which % (curchar.numshapes); - curchar.basechar = charshape(curchar.basechar, which); - - /* get rid of oldchar */ - copycstostring(string, oldchar, level); - copycstostring(string, curchar, level); - } - - static int arabic_shape(char src[], int srcoffset, int srclength, char dest[], int destoffset, int destlength, int level) { - char str[] = new char[srclength]; - for (int k = srclength + srcoffset - 1; k >= srcoffset; --k) - str[k - srcoffset] = src[k]; - StringBuffer string = new StringBuffer(srclength); - shape(str, string, level); - if ((level & (ar_composedtashkeel | ar_lig)) != 0) - doublelig(string, level); -// string.reverse(); - System.arraycopy(string.toString().toCharArray(), 0, dest, destoffset, string.length()); - return string.length(); - } - - static void processNumbers(char text[], int offset, int length, int options) { - int limit = offset + length; - if ((options & DIGITS_MASK) != 0) { - char digitBase = '\u0030'; // European digits - switch (options & DIGIT_TYPE_MASK) { - case DIGIT_TYPE_AN: - digitBase = '\u0660'; // Arabic-Indic digits - break; - - case DIGIT_TYPE_AN_EXTENDED: - digitBase = '\u06f0'; // Eastern Arabic-Indic digits (Persian and Urdu) - break; - - default: - break; - } - - switch (options & DIGITS_MASK) { - case DIGITS_EN2AN: { - int digitDelta = digitBase - '\u0030'; - for (int i = offset; i < limit; ++i) { - char ch = text[i]; - if (ch <= '\u0039' && ch >= '\u0030') { - text[i] += digitDelta; - } - } - } - break; - - case DIGITS_AN2EN: { - char digitTop = (char)(digitBase + 9); - int digitDelta = '\u0030' - digitBase; - for (int i = offset; i < limit; ++i) { - char ch = text[i]; - if (ch <= digitTop && ch >= digitBase) { - text[i] += digitDelta; - } - } - } - break; - - case DIGITS_EN2AN_INIT_LR: - shapeToArabicDigitsWithContext(text, 0, length, digitBase, false); - break; - - case DIGITS_EN2AN_INIT_AL: - shapeToArabicDigitsWithContext(text, 0, length, digitBase, true); - break; - - default: - break; - } - } - } - - static void shapeToArabicDigitsWithContext(char[] dest, int start, int length, char digitBase, boolean lastStrongWasAL) { - digitBase -= '0'; // move common adjustment out of loop - - int limit = start + length; - for(int i = start; i < limit; ++i) { - char ch = dest[i]; - switch (BidiOrder.getDirection(ch)) { - case BidiOrder.L: - case BidiOrder.R: - lastStrongWasAL = false; - break; - case BidiOrder.AL: - lastStrongWasAL = true; - break; - case BidiOrder.EN: - if (lastStrongWasAL && ch <= '\u0039') { - dest[i] = (char)(ch + digitBase); - } - break; - default: - break; - } - } - } - - private static final char ALEF = 0x0627; - private static final char ALEFHAMZA = 0x0623; - private static final char ALEFHAMZABELOW = 0x0625; - private static final char ALEFMADDA = 0x0622; - private static final char LAM = 0x0644; - private static final char HAMZA = 0x0621; - private static final char TATWEEL = 0x0640; - private static final char ZWJ = 0x200D; - - private static final char HAMZAABOVE = 0x0654; - private static final char HAMZABELOW = 0x0655; - - private static final char WAWHAMZA = 0x0624; - private static final char YEHHAMZA = 0x0626; - private static final char WAW = 0x0648; - private static final char ALEFMAKSURA = 0x0649; - private static final char YEH = 0x064A; - private static final char FARSIYEH = 0x06CC; - - private static final char SHADDA = 0x0651; - private static final char KASRA = 0x0650; - private static final char FATHA = 0x064E; - private static final char DAMMA = 0x064F; - private static final char MADDA = 0x0653; - - private static final char LAM_ALEF = 0xFEFB; - private static final char LAM_ALEFHAMZA = 0xFEF7; - private static final char LAM_ALEFHAMZABELOW = 0xFEF9; - private static final char LAM_ALEFMADDA = 0xFEF5; - - private static final char chartable[][] = { - {0x0621, 0xFE80}, /* HAMZA */ - {0x0622, 0xFE81, 0xFE82}, /* ALEF WITH MADDA ABOVE */ - {0x0623, 0xFE83, 0xFE84}, /* ALEF WITH HAMZA ABOVE */ - {0x0624, 0xFE85, 0xFE86}, /* WAW WITH HAMZA ABOVE */ - {0x0625, 0xFE87, 0xFE88}, /* ALEF WITH HAMZA BELOW */ - {0x0626, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C}, /* YEH WITH HAMZA ABOVE */ - {0x0627, 0xFE8D, 0xFE8E}, /* ALEF */ - {0x0628, 0xFE8F, 0xFE90, 0xFE91, 0xFE92}, /* BEH */ - {0x0629, 0xFE93, 0xFE94}, /* TEH MARBUTA */ - {0x062A, 0xFE95, 0xFE96, 0xFE97, 0xFE98}, /* TEH */ - {0x062B, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C}, /* THEH */ - {0x062C, 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0}, /* JEEM */ - {0x062D, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4}, /* HAH */ - {0x062E, 0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8}, /* KHAH */ - {0x062F, 0xFEA9, 0xFEAA}, /* DAL */ - {0x0630, 0xFEAB, 0xFEAC}, /* THAL */ - {0x0631, 0xFEAD, 0xFEAE}, /* REH */ - {0x0632, 0xFEAF, 0xFEB0}, /* ZAIN */ - {0x0633, 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4}, /* SEEN */ - {0x0634, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8}, /* SHEEN */ - {0x0635, 0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC}, /* SAD */ - {0x0636, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0}, /* DAD */ - {0x0637, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4}, /* TAH */ - {0x0638, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8}, /* ZAH */ - {0x0639, 0xFEC9, 0xFECA, 0xFECB, 0xFECC}, /* AIN */ - {0x063A, 0xFECD, 0xFECE, 0xFECF, 0xFED0}, /* GHAIN */ - {0x0640, 0x0640, 0x0640, 0x0640, 0x0640}, /* TATWEEL */ - {0x0641, 0xFED1, 0xFED2, 0xFED3, 0xFED4}, /* FEH */ - {0x0642, 0xFED5, 0xFED6, 0xFED7, 0xFED8}, /* QAF */ - {0x0643, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC}, /* KAF */ - {0x0644, 0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0}, /* LAM */ - {0x0645, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4}, /* MEEM */ - {0x0646, 0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8}, /* NOON */ - {0x0647, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC}, /* HEH */ - {0x0648, 0xFEED, 0xFEEE}, /* WAW */ - {0x0649, 0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9}, /* ALEF MAKSURA */ - {0x064A, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4}, /* YEH */ - {0x0671, 0xFB50, 0xFB51}, /* ALEF WASLA */ - {0x0679, 0xFB66, 0xFB67, 0xFB68, 0xFB69}, /* TTEH */ - {0x067A, 0xFB5E, 0xFB5F, 0xFB60, 0xFB61}, /* TTEHEH */ - {0x067B, 0xFB52, 0xFB53, 0xFB54, 0xFB55}, /* BEEH */ - {0x067E, 0xFB56, 0xFB57, 0xFB58, 0xFB59}, /* PEH */ - {0x067F, 0xFB62, 0xFB63, 0xFB64, 0xFB65}, /* TEHEH */ - {0x0680, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D}, /* BEHEH */ - {0x0683, 0xFB76, 0xFB77, 0xFB78, 0xFB79}, /* NYEH */ - {0x0684, 0xFB72, 0xFB73, 0xFB74, 0xFB75}, /* DYEH */ - {0x0686, 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D}, /* TCHEH */ - {0x0687, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81}, /* TCHEHEH */ - {0x0688, 0xFB88, 0xFB89}, /* DDAL */ - {0x068C, 0xFB84, 0xFB85}, /* DAHAL */ - {0x068D, 0xFB82, 0xFB83}, /* DDAHAL */ - {0x068E, 0xFB86, 0xFB87}, /* DUL */ - {0x0691, 0xFB8C, 0xFB8D}, /* RREH */ - {0x0698, 0xFB8A, 0xFB8B}, /* JEH */ - {0x06A4, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D}, /* VEH */ - {0x06A6, 0xFB6E, 0xFB6F, 0xFB70, 0xFB71}, /* PEHEH */ - {0x06A9, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91}, /* KEHEH */ - {0x06AD, 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6}, /* NG */ - {0x06AF, 0xFB92, 0xFB93, 0xFB94, 0xFB95}, /* GAF */ - {0x06B1, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D}, /* NGOEH */ - {0x06B3, 0xFB96, 0xFB97, 0xFB98, 0xFB99}, /* GUEH */ - {0x06BA, 0xFB9E, 0xFB9F}, /* NOON GHUNNA */ - {0x06BB, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3}, /* RNOON */ - {0x06BE, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD}, /* HEH DOACHASHMEE */ - {0x06C0, 0xFBA4, 0xFBA5}, /* HEH WITH YEH ABOVE */ - {0x06C1, 0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9}, /* HEH GOAL */ - {0x06C5, 0xFBE0, 0xFBE1}, /* KIRGHIZ OE */ - {0x06C6, 0xFBD9, 0xFBDA}, /* OE */ - {0x06C7, 0xFBD7, 0xFBD8}, /* U */ - {0x06C8, 0xFBDB, 0xFBDC}, /* YU */ - {0x06C9, 0xFBE2, 0xFBE3}, /* KIRGHIZ YU */ - {0x06CB, 0xFBDE, 0xFBDF}, /* VE */ - {0x06CC, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF}, /* FARSI YEH */ - {0x06D0, 0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7}, /* E */ - {0x06D2, 0xFBAE, 0xFBAF}, /* YEH BARREE */ - {0x06D3, 0xFBB0, 0xFBB1} /* YEH BARREE WITH HAMZA ABOVE */ - }; - - public static final int ar_nothing = 0x0; - public static final int ar_novowel = 0x1; - public static final int ar_composedtashkeel = 0x4; - public static final int ar_lig = 0x8; - /** - * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits. - */ - public static final int DIGITS_EN2AN = 0x20; - - /** - * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039). - */ - public static final int DIGITS_AN2EN = 0x40; - - /** - * Digit shaping option: - * Replace European digits (U+0030...U+0039) by Arabic-Indic digits - * if the most recent strongly directional character - * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). - * The initial state at the start of the text is assumed to be not an Arabic, - * letter, so European digits at the start of the text will not change. - * Compare to DIGITS_ALEN2AN_INIT_AL. - */ - public static final int DIGITS_EN2AN_INIT_LR = 0x60; - - /** - * Digit shaping option: - * Replace European digits (U+0030...U+0039) by Arabic-Indic digits - * if the most recent strongly directional character - * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). - * The initial state at the start of the text is assumed to be an Arabic, - * letter, so European digits at the start of the text will change. - * Compare to DIGITS_ALEN2AN_INT_LR. - */ - public static final int DIGITS_EN2AN_INIT_AL = 0x80; - - /** Not a valid option value. */ - private static final int DIGITS_RESERVED = 0xa0; - - /** - * Bit mask for digit shaping options. - */ - public static final int DIGITS_MASK = 0xe0; - - /** - * Digit type option: Use Arabic-Indic digits (U+0660...U+0669). - */ - public static final int DIGIT_TYPE_AN = 0; - - /** - * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9). - */ - public static final int DIGIT_TYPE_AN_EXTENDED = 0x100; - - /** - * Bit mask for digit type options. - */ - public static final int DIGIT_TYPE_MASK = 0x0100; // 0x3f00? - - static class charstruct { - char basechar; - char mark1; /* has to be initialized to zero */ - char vowel; - int lignum; /* is a ligature with lignum aditional characters */ - int numshapes = 1; - }; - - -} diff --git a/src/main/java/com/lowagie/text/pdf/AsianFontMapper.java b/src/main/java/com/lowagie/text/pdf/AsianFontMapper.java deleted file mode 100644 index 484ab0e..0000000 --- a/src/main/java/com/lowagie/text/pdf/AsianFontMapper.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2004 by Takenori. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.awt.Font; - -import com.lowagie.text.pdf.BaseFont; -import com.lowagie.text.pdf.DefaultFontMapper; - -public class AsianFontMapper extends DefaultFontMapper { - - public static String ChineseSimplifiedFont = "STSong-Light"; - public static String ChineseSimplifiedEncoding_H = "UniGB-UCS2-H"; - public static String ChineseSimplifiedEncoding_V = "UniGB-UCS2-V"; - - public static String ChineseTraditionalFont_MHei = "MHei-Medium"; - public static String ChineseTraditionalFont_MSung = "MSung-Light"; - public static String ChineseTraditionalEncoding_H = "UniCNS-UCS2-H"; - public static String ChineseTraditionalEncoding_V = "UniCNS-UCS2-V"; - - public static String JapaneseFont_Go = "HeiseiKakuGo-W5"; - public static String JapaneseFont_Min = "HeiseiMin-W3"; - public static String JapaneseEncoding_H = "UniJIS-UCS2-H"; - public static String JapaneseEncoding_V = "UniJIS-UCS2-V"; - public static String JapaneseEncoding_HW_H = "UniJIS-UCS2-HW-H"; - public static String JapaneseEncoding_HW_V = "UniJIS-UCS2-HW-V"; - - public static String KoreanFont_GoThic = "HYGoThic-Medium"; - public static String KoreanFont_SMyeongJo = "HYSMyeongJo-Medium"; - public static String KoreanEncoding_H = "UniKS-UCS2-H"; - public static String KoreanEncoding_V = "UniKS-UCS2-V"; - - private String defaultFont; - private String encoding; - - public AsianFontMapper(String font, String encoding) { - super(); - - this.defaultFont = font; - this.encoding = encoding; - } - - public BaseFont awtToPdf(Font font) { - try { - BaseFontParameters p = getBaseFontParameters(font.getFontName()); - if (p != null){ - return BaseFont.createFont(p.fontName, p.encoding, p.embedded, p.cached, p.ttfAfm, p.pfb); - }else{ - return BaseFont.createFont(defaultFont, encoding, true); - } - } - catch (Exception e) { - e.printStackTrace(); - } - return null; - - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/BadPdfFormatException.java b/src/main/java/com/lowagie/text/pdf/BadPdfFormatException.java deleted file mode 100644 index 70c4001..0000000 --- a/src/main/java/com/lowagie/text/pdf/BadPdfFormatException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * $Id: BadPdfFormatException.java,v 1.55 2006/02/16 16:17:48 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * Signals that a bad PDF format has been used to construct a PdfObject. - * - * @see PdfException - * @see PdfBoolean - * @see PdfNumber - * @see PdfString - * @see PdfName - * @see PdfDictionary - */ - -public class BadPdfFormatException extends PdfException { - - // constructors - -/** - * Constructs a BadPdfFormatException whithout a message. - */ - - BadPdfFormatException() { - super(); - } - -/** - * Constructs a BadPdfFormatException with a message. - * - * @param message a message describing the exception - */ - - BadPdfFormatException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/Barcode.java b/src/main/java/com/lowagie/text/pdf/Barcode.java deleted file mode 100644 index 5eea0dc..0000000 --- a/src/main/java/com/lowagie/text/pdf/Barcode.java +++ /dev/null @@ -1,477 +0,0 @@ -/* - * $Id: Barcode.java,v 1.20 2006/02/09 18:07:56 psoares33 Exp $ - * - * Copyright 2002-2006 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Image; -import java.awt.Color; -/** Base class containing properties and methods commom to all - * barcode types. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public abstract class Barcode { - /** A type of barcode */ - public static final int EAN13 = 1; - /** A type of barcode */ - public static final int EAN8 = 2; - /** A type of barcode */ - public static final int UPCA = 3; - /** A type of barcode */ - public static final int UPCE = 4; - /** A type of barcode */ - public static final int SUPP2 = 5; - /** A type of barcode */ - public static final int SUPP5 = 6; - /** A type of barcode */ - public static final int POSTNET = 7; - /** A type of barcode */ - public static final int PLANET = 8; - /** A type of barcode */ - public static final int CODE128 = 9; - /** A type of barcode */ - public static final int CODE128_UCC = 10; - /** A type of barcode */ - public static final int CODE128_RAW = 11; - /** A type of barcode */ - public static final int CODABAR = 12; - - /** The minimum bar width. - */ - protected float x; - - /** The bar multiplier for wide bars or the distance between - * bars for Postnet and Planet. - */ - protected float n; - - /** The text font. null if no text. - */ - protected BaseFont font; - - /** The size of the text or the height of the shorter bar - * in Postnet. - */ - protected float size; - - /** If positive, the text distance under the bars. If zero or negative, - * the text distance above the bars. - */ - protected float baseline; - - /** The height of the bars. - */ - protected float barHeight; - - /** The text alignment. Can be Element.ALIGN_LEFT, - * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. - */ - protected int textAlignment; - - /** The optional checksum generation. - */ - protected boolean generateChecksum; - - /** Shows the generated checksum in the the text. - */ - protected boolean checksumText; - - /** Show the start and stop character '*' in the text for - * the barcode 39 or 'ABCD' for codabar. - */ - protected boolean startStopText; - - /** Generates extended barcode 39. - */ - protected boolean extended; - - /** The code to generate. - */ - protected String code = ""; - - /** Show the guard bars for barcode EAN. - */ - protected boolean guardBars; - - /** The code type. - */ - protected int codeType; - - /** The ink spreading. */ - protected float inkSpreading = 0; - - /** Gets the minimum bar width. - * @return the minimum bar width - */ - public float getX() { - return x; - } - - /** Sets the minimum bar width. - * @param x the minimum bar width - */ - public void setX(float x) { - this.x = x; - } - - /** Gets the bar multiplier for wide bars. - * @return the bar multiplier for wide bars - */ - public float getN() { - return n; - } - - /** Sets the bar multiplier for wide bars. - * @param n the bar multiplier for wide bars - */ - public void setN(float n) { - this.n = n; - } - - /** Gets the text font. null if no text. - * @return the text font. null if no text - */ - public BaseFont getFont() { - return font; - } - - /** Sets the text font. - * @param font the text font. Set to null to suppress any text - */ - public void setFont(BaseFont font) { - this.font = font; - } - - /** Gets the size of the text. - * @return the size of the text - */ - public float getSize() { - return size; - } - - /** Sets the size of the text. - * @param size the size of the text - */ - public void setSize(float size) { - this.size = size; - } - - /** Gets the text baseline. - * If positive, the text distance under the bars. If zero or negative, - * the text distance above the bars. - * @return the baseline. - */ - public float getBaseline() { - return baseline; - } - - /** Sets the text baseline. - * If positive, the text distance under the bars. If zero or negative, - * the text distance above the bars. - * @param baseline the baseline. - */ - public void setBaseline(float baseline) { - this.baseline = baseline; - } - - /** Gets the height of the bars. - * @return the height of the bars - */ - public float getBarHeight() { - return barHeight; - } - - /** Sets the height of the bars. - * @param barHeight the height of the bars - */ - public void setBarHeight(float barHeight) { - this.barHeight = barHeight; - } - - /** Gets the text alignment. Can be Element.ALIGN_LEFT, - * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. - * @return the text alignment - */ - public int getTextAlignment() { - return textAlignment; - } - - /** Sets the text alignment. Can be Element.ALIGN_LEFT, - * Element.ALIGN_CENTER or Element.ALIGN_RIGHT. - * @param textAlignment the text alignment - */ - public void setTextAlignment(int textAlignment) { - this.textAlignment = textAlignment; - } - - /** Gets the optional checksum generation. - * @return the optional checksum generation - */ - public boolean isGenerateChecksum() { - return generateChecksum; - } - - /** Setter for property generateChecksum. - * @param generateChecksum New value of property generateChecksum. - */ - public void setGenerateChecksum(boolean generateChecksum) { - this.generateChecksum = generateChecksum; - } - - /** Gets the property to show the generated checksum in the the text. - * @return value of property checksumText - */ - public boolean isChecksumText() { - return checksumText; - } - - /** Sets the property to show the generated checksum in the the text. - * @param checksumText new value of property checksumText - */ - public void setChecksumText(boolean checksumText) { - this.checksumText = checksumText; - } - - /** Sets the property to show the start and stop character '*' in the text for - * the barcode 39. - * @return value of property startStopText - */ - public boolean isStartStopText() { - return startStopText; - } - - /** Gets the property to show the start and stop character '*' in the text for - * the barcode 39. - * @param startStopText new value of property startStopText - */ - public void setStartStopText(boolean startStopText) { - this.startStopText = startStopText; - } - - /** Gets the property to generate extended barcode 39. - * @return value of property extended. - */ - public boolean isExtended() { - return extended; - } - - /** Sets the property to generate extended barcode 39. - * @param extended new value of property extended - */ - public void setExtended(boolean extended) { - this.extended = extended; - } - - /** Gets the code to generate. - * @return the code to generate - */ - public String getCode() { - return code; - } - - /** Sets the code to generate. - * @param code the code to generate - */ - public void setCode(String code) { - this.code = code; - } - - /** Gets the property to show the guard bars for barcode EAN. - * @return value of property guardBars - */ - public boolean isGuardBars() { - return guardBars; - } - - /** Sets the property to show the guard bars for barcode EAN. - * @param guardBars new value of property guardBars - */ - public void setGuardBars(boolean guardBars) { - this.guardBars = guardBars; - } - - /** Gets the code type. - * @return the code type - */ - public int getCodeType() { - return codeType; - } - - /** Sets the code type. - * @param codeType the code type - */ - public void setCodeType(int codeType) { - this.codeType = codeType; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public abstract Rectangle getBarcodeSize(); - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public abstract Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor); - - /** Creates a template with the barcode. - * @param cb the PdfContentByte to create the template. It - * serves no other use - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the template - * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor) - */ - public PdfTemplate createTemplateWithBarcode(PdfContentByte cb, Color barColor, Color textColor) { - PdfTemplate tp = cb.createTemplate(0, 0); - Rectangle rect = placeBarcode(tp, barColor, textColor); - tp.setBoundingBox(rect); - return tp; - } - - /** Creates an Image with the barcode. - * @param cb the PdfContentByte to create the Image. It - * serves no other use - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the Image - * @see #placeBarcode(PdfContentByte cb, Color barColor, Color textColor) - */ - public Image createImageWithBarcode(PdfContentByte cb, Color barColor, Color textColor) { - try { - return Image.getInstance(createTemplateWithBarcode(cb, barColor, textColor)); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public abstract java.awt.Image createAwtImage(Color foreground, Color background); - - /** Gets the amount of ink spreading. - * @return the ink spreading - * - */ - public float getInkSpreading() { - return this.inkSpreading; - } - - /** Sets the amount of ink spreading. This value will be subtracted - * to the width of each bar. The actual value will depend on the ink - * and the printing medium. - * @param inkSpreading the ink spreading - * - */ - public void setInkSpreading(float inkSpreading) { - } - - /** - * The alternate text to be used, if present. - */ - protected String altText; - - /** - * Gets the alternate text. - * @return the alternate text - */ - public String getAltText() { - return this.altText; - } - - /** - * Sets the alternate text. If present, this text will be used instead of the - * text derived from the supplied code. - * @param altText the alternate text - */ - public void setAltText(String altText) { - this.altText = altText; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/Barcode128.java b/src/main/java/com/lowagie/text/pdf/Barcode128.java deleted file mode 100644 index f9fb656..0000000 --- a/src/main/java/com/lowagie/text/pdf/Barcode128.java +++ /dev/null @@ -1,825 +0,0 @@ -/* - * $Id: Barcode128.java,v 1.18 2006/02/09 18:07:56 psoares33 Exp $ - * - * Copyright 2002-2006 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Element; -import com.lowagie.text.ExceptionConverter; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** - * Implements the code 128 and UCC/EAN-128. Other symbologies are allowed in raw mode.

- * The code types allowed are:
- *

- * The default parameters are: - *
- * x = 0.8f;
- * font = BaseFont.createFont("Helvetica", "winansi", false);
- * size = 8;
- * baseline = size;
- * barHeight = size * 3;
- * textAlignment = Element.ALIGN_CENTER;
- * codeType = CODE128;
- * 
- * @author Paulo Soares (psoares@consiste.pt) - */ -public class Barcode128 extends Barcode{ - - /** The bars to generate the code. - */ - static byte BARS[][] = - { - {2, 1, 2, 2, 2, 2}, - {2, 2, 2, 1, 2, 2}, - {2, 2, 2, 2, 2, 1}, - {1, 2, 1, 2, 2, 3}, - {1, 2, 1, 3, 2, 2}, - {1, 3, 1, 2, 2, 2}, - {1, 2, 2, 2, 1, 3}, - {1, 2, 2, 3, 1, 2}, - {1, 3, 2, 2, 1, 2}, - {2, 2, 1, 2, 1, 3}, - {2, 2, 1, 3, 1, 2}, - {2, 3, 1, 2, 1, 2}, - {1, 1, 2, 2, 3, 2}, - {1, 2, 2, 1, 3, 2}, - {1, 2, 2, 2, 3, 1}, - {1, 1, 3, 2, 2, 2}, - {1, 2, 3, 1, 2, 2}, - {1, 2, 3, 2, 2, 1}, - {2, 2, 3, 2, 1, 1}, - {2, 2, 1, 1, 3, 2}, - {2, 2, 1, 2, 3, 1}, - {2, 1, 3, 2, 1, 2}, - {2, 2, 3, 1, 1, 2}, - {3, 1, 2, 1, 3, 1}, - {3, 1, 1, 2, 2, 2}, - {3, 2, 1, 1, 2, 2}, - {3, 2, 1, 2, 2, 1}, - {3, 1, 2, 2, 1, 2}, - {3, 2, 2, 1, 1, 2}, - {3, 2, 2, 2, 1, 1}, - {2, 1, 2, 1, 2, 3}, - {2, 1, 2, 3, 2, 1}, - {2, 3, 2, 1, 2, 1}, - {1, 1, 1, 3, 2, 3}, - {1, 3, 1, 1, 2, 3}, - {1, 3, 1, 3, 2, 1}, - {1, 1, 2, 3, 1, 3}, - {1, 3, 2, 1, 1, 3}, - {1, 3, 2, 3, 1, 1}, - {2, 1, 1, 3, 1, 3}, - {2, 3, 1, 1, 1, 3}, - {2, 3, 1, 3, 1, 1}, - {1, 1, 2, 1, 3, 3}, - {1, 1, 2, 3, 3, 1}, - {1, 3, 2, 1, 3, 1}, - {1, 1, 3, 1, 2, 3}, - {1, 1, 3, 3, 2, 1}, - {1, 3, 3, 1, 2, 1}, - {3, 1, 3, 1, 2, 1}, - {2, 1, 1, 3, 3, 1}, - {2, 3, 1, 1, 3, 1}, - {2, 1, 3, 1, 1, 3}, - {2, 1, 3, 3, 1, 1}, - {2, 1, 3, 1, 3, 1}, - {3, 1, 1, 1, 2, 3}, - {3, 1, 1, 3, 2, 1}, - {3, 3, 1, 1, 2, 1}, - {3, 1, 2, 1, 1, 3}, - {3, 1, 2, 3, 1, 1}, - {3, 3, 2, 1, 1, 1}, - {3, 1, 4, 1, 1, 1}, - {2, 2, 1, 4, 1, 1}, - {4, 3, 1, 1, 1, 1}, - {1, 1, 1, 2, 2, 4}, - {1, 1, 1, 4, 2, 2}, - {1, 2, 1, 1, 2, 4}, - {1, 2, 1, 4, 2, 1}, - {1, 4, 1, 1, 2, 2}, - {1, 4, 1, 2, 2, 1}, - {1, 1, 2, 2, 1, 4}, - {1, 1, 2, 4, 1, 2}, - {1, 2, 2, 1, 1, 4}, - {1, 2, 2, 4, 1, 1}, - {1, 4, 2, 1, 1, 2}, - {1, 4, 2, 2, 1, 1}, - {2, 4, 1, 2, 1, 1}, - {2, 2, 1, 1, 1, 4}, - {4, 1, 3, 1, 1, 1}, - {2, 4, 1, 1, 1, 2}, - {1, 3, 4, 1, 1, 1}, - {1, 1, 1, 2, 4, 2}, - {1, 2, 1, 1, 4, 2}, - {1, 2, 1, 2, 4, 1}, - {1, 1, 4, 2, 1, 2}, - {1, 2, 4, 1, 1, 2}, - {1, 2, 4, 2, 1, 1}, - {4, 1, 1, 2, 1, 2}, - {4, 2, 1, 1, 1, 2}, - {4, 2, 1, 2, 1, 1}, - {2, 1, 2, 1, 4, 1}, - {2, 1, 4, 1, 2, 1}, - {4, 1, 2, 1, 2, 1}, - {1, 1, 1, 1, 4, 3}, - {1, 1, 1, 3, 4, 1}, - {1, 3, 1, 1, 4, 1}, - {1, 1, 4, 1, 1, 3}, - {1, 1, 4, 3, 1, 1}, - {4, 1, 1, 1, 1, 3}, - {4, 1, 1, 3, 1, 1}, - {1, 1, 3, 1, 4, 1}, - {1, 1, 4, 1, 3, 1}, - {3, 1, 1, 1, 4, 1}, - {4, 1, 1, 1, 3, 1}, - {2, 1, 1, 4, 1, 2}, - {2, 1, 1, 2, 1, 4}, - {2, 1, 1, 2, 3, 2} - }; - - /** The stop bars. - */ - static byte BARS_STOP[] = {2, 3, 3, 1, 1, 1, 2}; - /** The charset code change. - */ - public static final char CODE_AB_TO_C = 99; - /** The charset code change. - */ - public static final char CODE_AC_TO_B = 100; - /** The charset code change. - */ - public static final char CODE_BC_TO_A = 101; - /** The code for UCC/EAN-128. - */ - public static final char FNC1_INDEX = 102; - /** The start code. - */ - public static final char START_A = 103; - /** The start code. - */ - public static final char START_B = 104; - /** The start code. - */ - public static final char START_C = 105; - - public static final char FNC1 = '\u00ca'; - public static final char DEL = '\u00c3'; - public static final char FNC3 = '\u00c4'; - public static final char FNC2 = '\u00c5'; - public static final char SHIFT = '\u00c6'; - public static final char CODE_C = '\u00c7'; - public static final char CODE_A = '\u00c8'; - public static final char FNC4 = '\u00c8'; - public static final char STARTA = '\u00cb'; - public static final char STARTB = '\u00cc'; - public static final char STARTC = '\u00cd'; - - private static final IntHashtable ais = new IntHashtable(); - /** Creates new Barcode128 */ - public Barcode128() { - try { - x = 0.8f; - font = BaseFont.createFont("Helvetica", "winansi", false); - size = 8; - baseline = size; - barHeight = size * 3; - textAlignment = Element.ALIGN_CENTER; - codeType = CODE128; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Removes the FNC1 codes in the text. - * @param code the text to clean - * @return the cleaned text - */ - public static String removeFNC1(String code) { - int len = code.length(); - StringBuffer buf = new StringBuffer(len); - for (int k = 0; k < len; ++k) { - char c = code.charAt(k); - if (c >= 32 && c <= 126) - buf.append(c); - } - return buf.toString(); - } - - /** - * Gets the human readable text of a sequence of AI. - * @param code the text - * @return the human readable text - */ - public static String getHumanReadableUCCEAN(String code) { - StringBuffer buf = new StringBuffer(); - String fnc1 = String.valueOf(FNC1); - try { - while (true) { - if (code.startsWith(fnc1)) { - code = code.substring(1); - continue; - } - int n = 0; - int idlen = 0; - for (int k = 2; k < 5; ++k) { - if (code.length() < k) - break; - if ((n = ais.get(Integer.parseInt(code.substring(0, k)))) != 0) { - idlen = k; - break; - } - } - if (idlen == 0) - break; - buf.append('(').append(code.substring(0, idlen)).append(')'); - code = code.substring(idlen); - if (n > 0) { - n -= idlen; - if (code.length() <= n) - break; - buf.append(removeFNC1(code.substring(0, n))); - code = code.substring(n); - } - else { - int idx = code.indexOf(FNC1); - if (idx < 0) - break; - buf.append(code.substring(0,idx)); - code = code.substring(idx + 1); - } - } - } - catch (Exception e) { - //empty - } - buf.append(removeFNC1(code)); - return buf.toString(); - } - - /** Returns true if the next numDigits - * starting from index textIndex are numeric skipping any FNC1. - * @param text the text to check - * @param textIndex where to check from - * @param numDigits the number of digits to check - * @return the check result - */ - static boolean isNextDigits(String text, int textIndex, int numDigits) { - int len = text.length(); - while (textIndex < len && numDigits > 0) { - if (text.charAt(textIndex) == FNC1) { - ++textIndex; - continue; - } - int n = Math.min(2, numDigits); - if (textIndex + n > len) - return false; - while (n-- > 0) { - char c = text.charAt(textIndex++); - if (c < '0' || c > '9') - return false; - --numDigits; - } - } - return numDigits == 0; - } - - /** Packs the digits for charset C also considering FNC1. It assumes that all the parameters - * are valid. - * @param text the text to pack - * @param textIndex where to pack from - * @param numDigits the number of digits to pack. It is always an even number - * @return the packed digits, two digits per character - */ - static String getPackedRawDigits(String text, int textIndex, int numDigits) { - String out = ""; - int start = textIndex; - while (numDigits > 0) { - if (text.charAt(textIndex) == FNC1) { - out += FNC1_INDEX; - ++textIndex; - continue; - } - numDigits -= 2; - int c1 = text.charAt(textIndex++) - '0'; - int c2 = text.charAt(textIndex++) - '0'; - out += (char)(c1 * 10 + c2); - } - return (char)(textIndex - start) + out; - } - - /** Converts the human readable text to the characters needed to - * create a barcode. Some optimization is done to get the shortest code. - * @param text the text to convert - * @param ucc true if it is an UCC/EAN-128. In this case - * the character FNC1 is added - * @return the code ready to be fed to getBarsCode128Raw() - */ - public static String getRawText(String text, boolean ucc) { - String out = ""; - int tLen = text.length(); - if (tLen == 0) { - out += START_B; - if (ucc) - out += FNC1_INDEX; - return out; - } - int c = 0; - for (int k = 0; k < tLen; ++k) { - c = text.charAt(k); - if (c > 127 && c != FNC1) - throw new RuntimeException("There are illegal characters for barcode 128 in '" + text + "'."); - } - c = text.charAt(0); - char currentCode = START_B; - int index = 0; - if (isNextDigits(text, index, 2)) { - currentCode = START_C; - out += currentCode; - if (ucc) - out += FNC1_INDEX; - String out2 = getPackedRawDigits(text, index, 2); - index += (int)out2.charAt(0); - out += out2.substring(1); - } - else if (c < ' ') { - currentCode = START_A; - out += currentCode; - if (ucc) - out += FNC1_INDEX; - out += (char)(c + 64); - ++index; - } - else { - out += currentCode; - if (ucc) - out += FNC1_INDEX; - if (c == FNC1) - out += FNC1_INDEX; - else - out += (char)(c - ' '); - ++index; - } - while (index < tLen) { - switch (currentCode) { - case START_A: - { - if (isNextDigits(text, index, 4)) { - currentCode = START_C; - out += CODE_AB_TO_C; - String out2 = getPackedRawDigits(text, index, 4); - index += (int)out2.charAt(0); - out += out2.substring(1); - } - else { - c = text.charAt(index++); - if (c == FNC1) - out += FNC1_INDEX; - else if (c > '_') { - currentCode = START_B; - out += CODE_AC_TO_B; - out += (char)(c - ' '); - } - else if (c < ' ') - out += (char)(c + 64); - else - out += (char)(c - ' '); - } - } - break; - case START_B: - { - if (isNextDigits(text, index, 4)) { - currentCode = START_C; - out += CODE_AB_TO_C; - String out2 = getPackedRawDigits(text, index, 4); - index += (int)out2.charAt(0); - out += out2.substring(1); - } - else { - c = text.charAt(index++); - if (c == FNC1) - out += FNC1_INDEX; - else if (c < ' ') { - currentCode = START_A; - out += CODE_BC_TO_A; - out += (char)(c + 64); - } - else { - out += (char)(c - ' '); - } - } - } - break; - case START_C: - { - if (isNextDigits(text, index, 2)) { - String out2 = getPackedRawDigits(text, index, 2); - index += (int)out2.charAt(0); - out += out2.substring(1); - } - else { - c = text.charAt(index++); - if (c == FNC1) - out += FNC1_INDEX; - else if (c < ' ') { - currentCode = START_A; - out += CODE_BC_TO_A; - out += (char)(c + 64); - } - else { - currentCode = START_B; - out += CODE_AC_TO_B; - out += (char)(c - ' '); - } - } - } - break; - } - } - return out; - } - - /** Generates the bars. The input has the actual barcodes, not - * the human readable text. - * @param text the barcode - * @return the bars - */ - public static byte[] getBarsCode128Raw(String text) { - int idx = text.indexOf('\uffff'); - if (idx >= 0) - text = text.substring(0, idx); - int chk = text.charAt(0); - for (int k = 1; k < text.length(); ++k) - chk += k * text.charAt(k); - chk = chk % 103; - text += (char)chk; - byte bars[] = new byte[(text.length() + 1) * 6 + 7]; - int k; - for (k = 0; k < text.length(); ++k) - System.arraycopy(BARS[text.charAt(k)], 0, bars, k * 6, 6); - System.arraycopy(BARS_STOP, 0, bars, k * 6, 7); - return bars; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float fontX = 0; - float fontY = 0; - String fullCode; - if (font != null) { - if (baseline > 0) - fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); - else - fontY = -baseline + size; - if (codeType == CODE128_RAW) { - int idx = code.indexOf('\uffff'); - if (idx < 0) - fullCode = ""; - else - fullCode = code.substring(idx + 1); - } - else if (codeType == CODE128_UCC) - fullCode = getHumanReadableUCCEAN(code); - else - fullCode = removeFNC1(code); - fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); - } - if (codeType == CODE128_RAW) { - int idx = code.indexOf('\uffff'); - if (idx >= 0) - fullCode = code.substring(0, idx); - else - fullCode = code; - } - else { - fullCode = getRawText(code, codeType == CODE128_UCC); - } - int len = fullCode.length(); - float fullWidth = (len + 2) * 11 * x + 2 * x; - fullWidth = Math.max(fullWidth, fontX); - float fullHeight = barHeight + fontY; - return new Rectangle(fullWidth, fullHeight); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - String fullCode; - if (codeType == CODE128_RAW) { - int idx = code.indexOf('\uffff'); - if (idx < 0) - fullCode = ""; - else - fullCode = code.substring(idx + 1); - } - else if (codeType == CODE128_UCC) - fullCode = getHumanReadableUCCEAN(code); - else - fullCode = removeFNC1(code); - float fontX = 0; - if (font != null) { - fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); - } - String bCode; - if (codeType == CODE128_RAW) { - int idx = code.indexOf('\uffff'); - if (idx >= 0) - bCode = code.substring(0, idx); - else - bCode = code; - } - else { - bCode = getRawText(code, codeType == CODE128_UCC); - } - int len = bCode.length(); - float fullWidth = (len + 2) * 11 * x + 2 * x; - float barStartX = 0; - float textStartX = 0; - switch (textAlignment) { - case Element.ALIGN_LEFT: - break; - case Element.ALIGN_RIGHT: - if (fontX > fullWidth) - barStartX = fontX - fullWidth; - else - textStartX = fullWidth - fontX; - break; - default: - if (fontX > fullWidth) - barStartX = (fontX - fullWidth) / 2; - else - textStartX = (fullWidth - fontX) / 2; - break; - } - float barStartY = 0; - float textStartY = 0; - if (font != null) { - if (baseline <= 0) - textStartY = barHeight - baseline; - else { - textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); - barStartY = textStartY + baseline; - } - } - byte bars[] = getBarsCode128Raw(bCode); - boolean print = true; - if (barColor != null) - cb.setColorFill(barColor); - for (int k = 0; k < bars.length; ++k) { - float w = bars[k] * x; - if (print) - cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); - print = !print; - barStartX += w; - } - cb.fill(); - if (font != null) { - if (textColor != null) - cb.setColorFill(textColor); - cb.beginText(); - cb.setFontAndSize(font, size); - cb.setTextMatrix(textStartX, textStartY); - cb.showText(fullCode); - cb.endText(); - } - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - String bCode; - if (codeType == CODE128_RAW) { - int idx = code.indexOf('\uffff'); - if (idx >= 0) - bCode = code.substring(0, idx); - else - bCode = code; - } - else { - bCode = getRawText(code, codeType == CODE128_UCC); - } - int len = bCode.length(); - int fullWidth = (len + 2) * 11 + 2; - byte bars[] = getBarsCode128Raw(bCode); - - boolean print = true; - int ptr = 0; - int height = (int)barHeight; - int pix[] = new int[fullWidth * height]; - for (int k = 0; k < bars.length; ++k) { - int w = bars[k]; - int c = g; - if (print) - c = f; - print = !print; - for (int j = 0; j < w; ++j) - pix[ptr++] = c; - } - for (int k = fullWidth; k < pix.length; k += fullWidth) { - System.arraycopy(pix, 0, pix, k, fullWidth); - } - Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); - - return img; - } - - /** - * Sets the code to generate. If it's an UCC code and starts with '(' it will - * be split by the AI. This code in UCC mode is valid: - *

- * (01)00000090311314(10)ABC123(15)060916 - * @param code the code to generate - */ - public void setCode(String code) { - if (getCodeType() == Barcode128.CODE128_UCC && code.startsWith("(")) { - int idx = 0; - String ret = ""; - while (idx >= 0) { - int end = code.indexOf(')', idx); - if (end < 0) - throw new IllegalArgumentException("Badly formed UCC string: " + code); - String sai = code.substring(idx + 1, end); - if (sai.length() < 2) - throw new IllegalArgumentException("AI too short: (" + sai + ")"); - int ai = Integer.parseInt(sai); - int len = ais.get(ai); - if (len == 0) - throw new IllegalArgumentException("AI not found: (" + sai + ")"); - sai = String.valueOf(ai); - if (sai.length() == 1) - sai = "0" + sai; - idx = code.indexOf('(', end); - int next = (idx < 0 ? code.length() : idx); - ret += sai + code.substring(end + 1, next); - if (len < 0) { - if (idx >= 0) - ret += FNC1; - } - else if (next - end - 1 + sai.length() != len) - throw new IllegalArgumentException("Invalid AI length: (" + sai + ")"); - } - super.setCode(ret); - } - else - super.setCode(code); - } - - static { - ais.put(0, 20); - ais.put(1, 16); - ais.put(2, 16); - ais.put(10, -1); - ais.put(11, 9); - ais.put(12, 8); - ais.put(13, 8); - ais.put(15, 8); - ais.put(17, 8); - ais.put(20, 4); - ais.put(21, -1); - ais.put(22, -1); - ais.put(23, -1); - ais.put(240, -1); - ais.put(241, -1); - ais.put(250, -1); - ais.put(251, -1); - ais.put(252, -1); - ais.put(30, -1); - for (int k = 3100; k < 3700; ++k) - ais.put(k, 10); - ais.put(37, -1); - for (int k = 3900; k < 3940; ++k) - ais.put(k, -1); - ais.put(400, -1); - ais.put(401, -1); - ais.put(402, 20); - ais.put(403, -1); - for (int k = 410; k < 416; ++k) - ais.put(k, 16); - ais.put(420, -1); - ais.put(421, -1); - ais.put(422, 6); - ais.put(423, -1); - ais.put(424, 6); - ais.put(425, 6); - ais.put(426, 6); - ais.put(7001, 17); - ais.put(7002, -1); - for (int k = 7030; k < 704; ++k) - ais.put(k, -1); - ais.put(8001, 18); - ais.put(8002, -1); - ais.put(8003, -1); - ais.put(8004, -1); - ais.put(8005, 10); - ais.put(8006, 22); - ais.put(8007, -1); - ais.put(8008, -1); - ais.put(8018, 22); - ais.put(8020, -1); - ais.put(8100, 10); - ais.put(8101, 14); - ais.put(8102, 6); - for (int k = 90; k < 100; ++k) - ais.put(k, -1); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/Barcode39.java b/src/main/java/com/lowagie/text/pdf/Barcode39.java deleted file mode 100644 index cf9ecdf..0000000 --- a/src/main/java/com/lowagie/text/pdf/Barcode39.java +++ /dev/null @@ -1,392 +0,0 @@ -/* - * $Id: Barcode39.java,v 1.18 2006/02/09 18:07:56 psoares33 Exp $ - * - * Copyright 2002-2006 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Element; -import com.lowagie.text.Rectangle; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Implements the code 39 and code 39 extended. The default parameters are: - *

- *x = 0.8f;
- *n = 2;
- *font = BaseFont.createFont("Helvetica", "winansi", false);
- *size = 8;
- *baseline = size;
- *barHeight = size * 3;
- *textAlignment = Element.ALIGN_CENTER;
- *generateChecksum = false;
- *checksumText = false;
- *startStopText = true;
- *extended = false;
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class Barcode39 extends Barcode{ - - /** The bars to generate the code. - */ - static byte BARS[][] = - { - {0,0,0,1,1,0,1,0,0}, - {1,0,0,1,0,0,0,0,1}, - {0,0,1,1,0,0,0,0,1}, - {1,0,1,1,0,0,0,0,0}, - {0,0,0,1,1,0,0,0,1}, - {1,0,0,1,1,0,0,0,0}, - {0,0,1,1,1,0,0,0,0}, - {0,0,0,1,0,0,1,0,1}, - {1,0,0,1,0,0,1,0,0}, - {0,0,1,1,0,0,1,0,0}, - {1,0,0,0,0,1,0,0,1}, - {0,0,1,0,0,1,0,0,1}, - {1,0,1,0,0,1,0,0,0}, - {0,0,0,0,1,1,0,0,1}, - {1,0,0,0,1,1,0,0,0}, - {0,0,1,0,1,1,0,0,0}, - {0,0,0,0,0,1,1,0,1}, - {1,0,0,0,0,1,1,0,0}, - {0,0,1,0,0,1,1,0,0}, - {0,0,0,0,1,1,1,0,0}, - {1,0,0,0,0,0,0,1,1}, - {0,0,1,0,0,0,0,1,1}, - {1,0,1,0,0,0,0,1,0}, - {0,0,0,0,1,0,0,1,1}, - {1,0,0,0,1,0,0,1,0}, - {0,0,1,0,1,0,0,1,0}, - {0,0,0,0,0,0,1,1,1}, - {1,0,0,0,0,0,1,1,0}, - {0,0,1,0,0,0,1,1,0}, - {0,0,0,0,1,0,1,1,0}, - {1,1,0,0,0,0,0,0,1}, - {0,1,1,0,0,0,0,0,1}, - {1,1,1,0,0,0,0,0,0}, - {0,1,0,0,1,0,0,0,1}, - {1,1,0,0,1,0,0,0,0}, - {0,1,1,0,1,0,0,0,0}, - {0,1,0,0,0,0,1,0,1}, - {1,1,0,0,0,0,1,0,0}, - {0,1,1,0,0,0,1,0,0}, - {0,1,0,1,0,1,0,0,0}, - {0,1,0,1,0,0,0,1,0}, - {0,1,0,0,0,1,0,1,0}, - {0,0,0,1,0,1,0,1,0}, - {0,1,0,0,1,0,1,0,0} - }; - - /** The index chars to BARS. - */ - static String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*"; - - /** The character combinations to make the code 39 extended. - */ - static String EXTENDED = "%U" + - "$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z" + - "%A%B%C%D%E /A/B/C/D/E/F/G/H/I/J/K/L - ./O" + - " 0 1 2 3 4 5 6 7 8 9/Z%F%G%H%I%J%V" + - " A B C D E F G H I J K L M N O P Q R S T U V W X Y Z" + - "%K%L%M%N%O%W" + - "+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z" + - "%P%Q%R%S%T"; - - /** Creates a new Barcode39. - */ - public Barcode39() { - try { - x = 0.8f; - n = 2; - font = BaseFont.createFont("Helvetica", "winansi", false); - size = 8; - baseline = size; - barHeight = size * 3; - textAlignment = Element.ALIGN_CENTER; - generateChecksum = false; - checksumText = false; - startStopText = true; - extended = false; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Creates the bars. - * @param text the text to create the bars. This text does not include the start and - * stop characters - * @return the bars - */ - public static byte[] getBarsCode39(String text) { - text = "*" + text + "*"; - byte bars[] = new byte[text.length() * 10 - 1]; - for (int k = 0; k < text.length(); ++k) { - int idx = CHARS.indexOf(text.charAt(k)); - if (idx < 0) - throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in code 39."); - System.arraycopy(BARS[idx], 0, bars, k * 10, 9); - } - return bars; - } - - /** Converts the extended text into a normal, escaped text, - * ready to generate bars. - * @param text the extended text - * @return the escaped text - */ - public static String getCode39Ex(String text) { - String out = ""; - for (int k = 0; k < text.length(); ++k) { - char c = text.charAt(k); - if (c > 127) - throw new IllegalArgumentException("The character '" + c + "' is illegal in code 39 extended."); - char c1 = EXTENDED.charAt(c * 2); - char c2 = EXTENDED.charAt(c * 2 + 1); - if (c1 != ' ') - out += c1; - out += c2; - } - return out; - } - - /** Calculates the checksum. - * @param text the text - * @return the checksum - */ - static char getChecksum(String text) { - int chk = 0; - for (int k = 0; k < text.length(); ++k) { - int idx = CHARS.indexOf(text.charAt(k)); - if (idx < 0) - throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in code 39."); - chk += idx; - } - return CHARS.charAt(chk % 43); - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float fontX = 0; - float fontY = 0; - if (font != null) { - if (baseline > 0) - fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); - else - fontY = -baseline + size; - String fullCode = code; - if (generateChecksum && checksumText) - fullCode += getChecksum(fullCode); - if (startStopText) - fullCode = "*" + fullCode + "*"; - fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); - } - String fullCode = code; - if (extended) - fullCode = getCode39Ex(code); - int len = fullCode.length() + 2; - if (generateChecksum) - ++len; - float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x; - fullWidth = Math.max(fullWidth, fontX); - float fullHeight = barHeight + fontY; - return new Rectangle(fullWidth, fullHeight); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - String fullCode = code; - float fontX = 0; - if (font != null) { - if (generateChecksum && checksumText) - fullCode += getChecksum(fullCode); - if (startStopText) - fullCode = "*" + fullCode + "*"; - fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); - } - String bCode = code; - if (extended) - bCode = getCode39Ex(code); - if (generateChecksum) - bCode += getChecksum(bCode); - int len = bCode.length() + 2; - float fullWidth = len * (6 * x + 3 * x * n) + (len - 1) * x; - float barStartX = 0; - float textStartX = 0; - switch (textAlignment) { - case Element.ALIGN_LEFT: - break; - case Element.ALIGN_RIGHT: - if (fontX > fullWidth) - barStartX = fontX - fullWidth; - else - textStartX = fullWidth - fontX; - break; - default: - if (fontX > fullWidth) - barStartX = (fontX - fullWidth) / 2; - else - textStartX = (fullWidth - fontX) / 2; - break; - } - float barStartY = 0; - float textStartY = 0; - if (font != null) { - if (baseline <= 0) - textStartY = barHeight - baseline; - else { - textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); - barStartY = textStartY + baseline; - } - } - byte bars[] = getBarsCode39(bCode); - boolean print = true; - if (barColor != null) - cb.setColorFill(barColor); - for (int k = 0; k < bars.length; ++k) { - float w = (bars[k] == 0 ? x : x * n); - if (print) - cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); - print = !print; - barStartX += w; - } - cb.fill(); - if (font != null) { - if (textColor != null) - cb.setColorFill(textColor); - cb.beginText(); - cb.setFontAndSize(font, size); - cb.setTextMatrix(textStartX, textStartY); - cb.showText(fullCode); - cb.endText(); - } - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - - String bCode = code; - if (extended) - bCode = getCode39Ex(code); - if (generateChecksum) - bCode += getChecksum(bCode); - int len = bCode.length() + 2; - int nn = (int)n; - int fullWidth = len * (6 + 3 * nn) + (len - 1); - byte bars[] = getBarsCode39(bCode); - boolean print = true; - int ptr = 0; - int height = (int)barHeight; - int pix[] = new int[fullWidth * height]; - for (int k = 0; k < bars.length; ++k) { - int w = (bars[k] == 0 ? 1 : nn); - int c = g; - if (print) - c = f; - print = !print; - for (int j = 0; j < w; ++j) - pix[ptr++] = c; - } - for (int k = fullWidth; k < pix.length; k += fullWidth) { - System.arraycopy(pix, 0, pix, k, fullWidth); - } - Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); - - return img; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BarcodeCodabar.java b/src/main/java/com/lowagie/text/pdf/BarcodeCodabar.java deleted file mode 100644 index 7b9537c..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodeCodabar.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * $Id: BarcodeCodabar.java,v 1.14 2006/02/09 18:07:56 psoares33 Exp $ - * - * Copyright 2002-2006 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Element; -import com.lowagie.text.Rectangle; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Implements the code codabar. The default parameters are: - *

- *x = 0.8f;
- *n = 2;
- *font = BaseFont.createFont("Helvetica", "winansi", false);
- *size = 8;
- *baseline = size;
- *barHeight = size * 3;
- *textAlignment = Element.ALIGN_CENTER;
- *generateChecksum = false;
- *checksumText = false;
- *startStopText = false;
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodeCodabar extends Barcode{ - - /** The bars to generate the code. - */ - static byte BARS[][] = - { - {0,0,0,0,0,1,1}, // 0 - {0,0,0,0,1,1,0}, // 1 - {0,0,0,1,0,0,1}, // 2 - {1,1,0,0,0,0,0}, // 3 - {0,0,1,0,0,1,0}, // 4 - {1,0,0,0,0,1,0}, // 5 - {0,1,0,0,0,0,1}, // 6 - {0,1,0,0,1,0,0}, // 7 - {0,1,1,0,0,0,0}, // 8 - {1,0,0,1,0,0,0}, // 9 - {0,0,0,1,1,0,0}, // - - {0,0,1,1,0,0,0}, // $ - {1,0,0,0,1,0,1}, // : - {1,0,1,0,0,0,1}, // / - {1,0,1,0,1,0,0}, // . - {0,0,1,0,1,0,1}, // + - {0,0,1,1,0,1,0}, // a - {0,1,0,1,0,0,1}, // b - {0,0,0,1,0,1,1}, // c - {0,0,0,1,1,1,0} // d - }; - - /** The index chars to BARS. - */ - static String CHARS = "0123456789-$:/.+ABCD"; - - static final int START_STOP_IDX = 16; - /** Creates a new BarcodeCodabar. - */ - public BarcodeCodabar() { - try { - x = 0.8f; - n = 2; - font = BaseFont.createFont("Helvetica", "winansi", false); - size = 8; - baseline = size; - barHeight = size * 3; - textAlignment = Element.ALIGN_CENTER; - generateChecksum = false; - checksumText = false; - startStopText = false; - codeType = CODABAR; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Creates the bars. - * @param text the text to create the bars - * @return the bars - */ - public static byte[] getBarsCodabar(String text) { - text = text.toUpperCase(); - int len = text.length(); - if (len < 2) - throw new IllegalArgumentException("Codabar must have at least a start and stop character."); - if (CHARS.indexOf(text.charAt(0)) < START_STOP_IDX || CHARS.indexOf(text.charAt(len - 1)) < START_STOP_IDX) - throw new IllegalArgumentException("Codabar must have one of 'ABCD' as start/stop character."); - byte bars[] = new byte[text.length() * 8 - 1]; - for (int k = 0; k < len; ++k) { - int idx = CHARS.indexOf(text.charAt(k)); - if (idx >= START_STOP_IDX && k > 0 && k < len - 1) - throw new IllegalArgumentException("In codabar, start/stop characters are only allowed at the extremes."); - if (idx < 0) - throw new IllegalArgumentException("The character '" + text.charAt(k) + "' is illegal in codabar."); - System.arraycopy(BARS[idx], 0, bars, k * 8, 7); - } - return bars; - } - - public static String calculateChecksum(String code) { - if (code.length() < 2) - return code; - String text = code.toUpperCase(); - int sum = 0; - int len = text.length(); - for (int k = 0; k < len; ++k) - sum += CHARS.indexOf(text.charAt(k)); - sum = (sum + 15) / 16 * 16 - sum; - return code.substring(0, len - 1) + CHARS.charAt(sum) + code.substring(len - 1); - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float fontX = 0; - float fontY = 0; - String text = code; - if (generateChecksum && checksumText) - text = calculateChecksum(code); - if (!startStopText) - text = text.substring(1, text.length() - 1); - if (font != null) { - if (baseline > 0) - fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); - else - fontY = -baseline + size; - fontX = font.getWidthPoint(altText != null ? altText : text, size); - } - text = code; - if (generateChecksum) - text = calculateChecksum(code); - byte bars[] = getBarsCodabar(text); - int wide = 0; - for (int k = 0; k < bars.length; ++k) { - wide += (int)bars[k]; - } - int narrow = bars.length - wide; - float fullWidth = x * (narrow + wide * n); - fullWidth = Math.max(fullWidth, fontX); - float fullHeight = barHeight + fontY; - return new Rectangle(fullWidth, fullHeight); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - String fullCode = code; - if (generateChecksum && checksumText) - fullCode = calculateChecksum(code); - if (!startStopText) - fullCode = fullCode.substring(1, fullCode.length() - 1); - float fontX = 0; - if (font != null) { - fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); - } - byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code); - int wide = 0; - for (int k = 0; k < bars.length; ++k) { - wide += (int)bars[k]; - } - int narrow = bars.length - wide; - float fullWidth = x * (narrow + wide * n); - float barStartX = 0; - float textStartX = 0; - switch (textAlignment) { - case Element.ALIGN_LEFT: - break; - case Element.ALIGN_RIGHT: - if (fontX > fullWidth) - barStartX = fontX - fullWidth; - else - textStartX = fullWidth - fontX; - break; - default: - if (fontX > fullWidth) - barStartX = (fontX - fullWidth) / 2; - else - textStartX = (fullWidth - fontX) / 2; - break; - } - float barStartY = 0; - float textStartY = 0; - if (font != null) { - if (baseline <= 0) - textStartY = barHeight - baseline; - else { - textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); - barStartY = textStartY + baseline; - } - } - boolean print = true; - if (barColor != null) - cb.setColorFill(barColor); - for (int k = 0; k < bars.length; ++k) { - float w = (bars[k] == 0 ? x : x * n); - if (print) - cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); - print = !print; - barStartX += w; - } - cb.fill(); - if (font != null) { - if (textColor != null) - cb.setColorFill(textColor); - cb.beginText(); - cb.setFontAndSize(font, size); - cb.setTextMatrix(textStartX, textStartY); - cb.showText(fullCode); - cb.endText(); - } - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - - String fullCode = code; - if (generateChecksum && checksumText) - fullCode = calculateChecksum(code); - if (!startStopText) - fullCode = fullCode.substring(1, fullCode.length() - 1); - byte bars[] = getBarsCodabar(generateChecksum ? calculateChecksum(code) : code); - int wide = 0; - for (int k = 0; k < bars.length; ++k) { - wide += (int)bars[k]; - } - int narrow = bars.length - wide; - int fullWidth = narrow + wide * (int)n; - boolean print = true; - int ptr = 0; - int height = (int)barHeight; - int pix[] = new int[fullWidth * height]; - for (int k = 0; k < bars.length; ++k) { - int w = (bars[k] == 0 ? 1 : (int)n); - int c = g; - if (print) - c = f; - print = !print; - for (int j = 0; j < w; ++j) - pix[ptr++] = c; - } - for (int k = fullWidth; k < pix.length; k += fullWidth) { - System.arraycopy(pix, 0, pix, k, fullWidth); - } - Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); - - return img; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BarcodeEAN.java b/src/main/java/com/lowagie/text/pdf/BarcodeEAN.java deleted file mode 100644 index c6d5f28..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodeEAN.java +++ /dev/null @@ -1,718 +0,0 @@ -/* - * Copyright 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.ExceptionConverter; -import java.util.Arrays; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Generates barcodes in several formats: EAN13, EAN8, UPCA, UPCE, - * supplemental 2 and 5. The default parameters are: - *

- *x = 0.8f;
- *font = BaseFont.createFont("Helvetica", "winansi", false);
- *size = 8;
- *baseline = size;
- *barHeight = size * 3;
- *guardBars = true;
- *codeType = EAN13;
- *code = "";
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodeEAN extends Barcode{ - - /** The bar positions that are guard bars.*/ - static int GUARD_EMPTY[] = {}; - /** The bar positions that are guard bars.*/ - static int GUARD_UPCA[] = {0, 2, 4, 6, 28, 30, 52, 54, 56, 58}; - /** The bar positions that are guard bars.*/ - static int GUARD_EAN13[] = {0, 2, 28, 30, 56, 58}; - /** The bar positions that are guard bars.*/ - static int GUARD_EAN8[] = {0, 2, 20, 22, 40, 42}; - /** The bar positions that are guard bars.*/ - static int GUARD_UPCE[] = {0, 2, 28, 30, 32}; - /** The x coordinates to place the text.*/ - static float TEXTPOS_EAN13[] = {6.5f, 13.5f, 20.5f, 27.5f, 34.5f, 41.5f, 53.5f, 60.5f, 67.5f, 74.5f, 81.5f, 88.5f}; - /** The x coordinates to place the text.*/ - static float TEXTPOS_EAN8[] = {6.5f, 13.5f, 20.5f, 27.5f, 39.5f, 46.5f, 53.5f, 60.5f}; - /** The basic bar widths.*/ - static byte BARS[][] = - { - {3, 2, 1, 1}, // 0 - {2, 2, 2, 1}, // 1 - {2, 1, 2, 2}, // 2 - {1, 4, 1, 1}, // 3 - {1, 1, 3, 2}, // 4 - {1, 2, 3, 1}, // 5 - {1, 1, 1, 4}, // 6 - {1, 3, 1, 2}, // 7 - {1, 2, 1, 3}, // 8 - {3, 1, 1, 2} // 9 - }; - - /** The total number of bars for EAN13.*/ - static final int TOTALBARS_EAN13 = 11 + 12 * 4; - /** The total number of bars for EAN8.*/ - static final int TOTALBARS_EAN8 = 11 + 8 * 4; - /** The total number of bars for UPCE.*/ - static final int TOTALBARS_UPCE = 9 + 6 * 4; - /** The total number of bars for supplemental 2.*/ - static final int TOTALBARS_SUPP2 = 13; - /** The total number of bars for supplemental 5.*/ - static final int TOTALBARS_SUPP5 = 31; - /** Marker for odd parity.*/ - static final int ODD = 0; - /** Marker for even parity.*/ - static final int EVEN = 1; - - /** Sequence of parities to be used with EAN13.*/ - static byte PARITY13[][] = - { - {ODD, ODD, ODD, ODD, ODD, ODD}, // 0 - {ODD, ODD, EVEN, ODD, EVEN, EVEN}, // 1 - {ODD, ODD, EVEN, EVEN, ODD, EVEN}, // 2 - {ODD, ODD, EVEN, EVEN, EVEN, ODD}, // 3 - {ODD, EVEN, ODD, ODD, EVEN, EVEN}, // 4 - {ODD, EVEN, EVEN, ODD, ODD, EVEN}, // 5 - {ODD, EVEN, EVEN, EVEN, ODD, ODD}, // 6 - {ODD, EVEN, ODD, EVEN, ODD, EVEN}, // 7 - {ODD, EVEN, ODD, EVEN, EVEN, ODD}, // 8 - {ODD, EVEN, EVEN, ODD, EVEN, ODD} // 9 - }; - - /** Sequence of parities to be used with supplemental 2.*/ - static byte PARITY2[][] = - { - {ODD, ODD}, // 0 - {ODD, EVEN}, // 1 - {EVEN, ODD}, // 2 - {EVEN, EVEN} // 3 - }; - - /** Sequence of parities to be used with supplemental 2.*/ - static byte PARITY5[][] = - { - {EVEN, EVEN, ODD, ODD, ODD}, // 0 - {EVEN, ODD, EVEN, ODD, ODD}, // 1 - {EVEN, ODD, ODD, EVEN, ODD}, // 2 - {EVEN, ODD, ODD, ODD, EVEN}, // 3 - {ODD, EVEN, EVEN, ODD, ODD}, // 4 - {ODD, ODD, EVEN, EVEN, ODD}, // 5 - {ODD, ODD, ODD, EVEN, EVEN}, // 6 - {ODD, EVEN, ODD, EVEN, ODD}, // 7 - {ODD, EVEN, ODD, ODD, EVEN}, // 8 - {ODD, ODD, EVEN, ODD, EVEN} // 9 - }; - - /** Sequence of parities to be used with UPCE.*/ - static byte PARITYE[][] = - { - {EVEN, EVEN, EVEN, ODD, ODD, ODD}, // 0 - {EVEN, EVEN, ODD, EVEN, ODD, ODD}, // 1 - {EVEN, EVEN, ODD, ODD, EVEN, ODD}, // 2 - {EVEN, EVEN, ODD, ODD, ODD, EVEN}, // 3 - {EVEN, ODD, EVEN, EVEN, ODD, ODD}, // 4 - {EVEN, ODD, ODD, EVEN, EVEN, ODD}, // 5 - {EVEN, ODD, ODD, ODD, EVEN, EVEN}, // 6 - {EVEN, ODD, EVEN, ODD, EVEN, ODD}, // 7 - {EVEN, ODD, EVEN, ODD, ODD, EVEN}, // 8 - {EVEN, ODD, ODD, EVEN, ODD, EVEN} // 9 - }; - - /** Creates new BarcodeEAN */ - public BarcodeEAN() { - try { - x = 0.8f; - font = BaseFont.createFont("Helvetica", "winansi", false); - size = 8; - baseline = size; - barHeight = size * 3; - guardBars = true; - codeType = EAN13; - code = ""; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Calculates the EAN parity character. - * @param code the code - * @return the parity character - */ - public static int calculateEANParity(String code) { - int mul = 3; - int total = 0; - for (int k = code.length() - 1; k >= 0; --k) { - int n = code.charAt(k) - '0'; - total += mul * n; - mul ^= 2; - } - return (10 - (total % 10)) % 10; - } - - /** Converts an UPCA code into an UPCE code. If the code can not - * be converted a null is returned. - * @param text the code to convert. It must have 12 numeric characters - * @return the 8 converted digits or null if the - * code could not be converted - */ - static public String convertUPCAtoUPCE(String text) { - if (text.length() != 12 || !(text.startsWith("0") || text.startsWith("1"))) - return null; - if (text.substring(3, 6).equals("000") || text.substring(3, 6).equals("100") - || text.substring(3, 6).equals("200")) { - if (text.substring(6, 8).equals("00")) - return text.substring(0, 1) + text.substring(1, 3) + text.substring(8, 11) + text.substring(3, 4) + text.substring(11); - } - else if (text.substring(4, 6).equals("00")) { - if (text.substring(6, 9).equals("000")) - return text.substring(0, 1) + text.substring(1, 4) + text.substring(9, 11) + "3" + text.substring(11); - } - else if (text.substring(5, 6).equals("0")) { - if (text.substring(6, 10).equals("0000")) - return text.substring(0, 1) + text.substring(1, 5) + text.substring(10, 11) + "4" + text.substring(11); - } - else if (text.charAt(10) >= '5') { - if (text.substring(6, 10).equals("0000")) - return text.substring(0, 1) + text.substring(1, 6) + text.substring(10, 11) + text.substring(11); - } - return null; - } - - /** Creates the bars for the barcode EAN13 and UPCA. - * @param _code the text with 13 digits - * @return the barcode - */ - public static byte[] getBarsEAN13(String _code) { - int code[] = new int[_code.length()]; - for (int k = 0; k < code.length; ++k) - code[k] = _code.charAt(k) - '0'; - byte bars[] = new byte[TOTALBARS_EAN13]; - int pb = 0; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - byte sequence[] = PARITY13[code[0]]; - for (int k = 0; k < sequence.length; ++k) { - int c = code[k + 1]; - byte stripes[] = BARS[c]; - if (sequence[k] == ODD) { - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - else { - bars[pb++] = stripes[3]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[0]; - } - } - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - for (int k = 7; k < 13; ++k) { - int c = code[k]; - byte stripes[] = BARS[c]; - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - return bars; - } - - /** Creates the bars for the barcode EAN8. - * @param _code the text with 8 digits - * @return the barcode - */ - public static byte[] getBarsEAN8(String _code) { - int code[] = new int[_code.length()]; - for (int k = 0; k < code.length; ++k) - code[k] = _code.charAt(k) - '0'; - byte bars[] = new byte[TOTALBARS_EAN8]; - int pb = 0; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - for (int k = 0; k < 4; ++k) { - int c = code[k]; - byte stripes[] = BARS[c]; - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - for (int k = 4; k < 8; ++k) { - int c = code[k]; - byte stripes[] = BARS[c]; - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - return bars; - } - - /** Creates the bars for the barcode UPCE. - * @param _code the text with 8 digits - * @return the barcode - */ - public static byte[] getBarsUPCE(String _code) { - int code[] = new int[_code.length()]; - for (int k = 0; k < code.length; ++k) - code[k] = _code.charAt(k) - '0'; - byte bars[] = new byte[TOTALBARS_UPCE]; - boolean flip = (code[0] != 0); - int pb = 0; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - byte sequence[] = PARITYE[code[code.length - 1]]; - for (int k = 1; k < code.length - 1; ++k) { - int c = code[k]; - byte stripes[] = BARS[c]; - if (sequence[k - 1] == (flip ? EVEN : ODD)) { - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - else { - bars[pb++] = stripes[3]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[0]; - } - } - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 1; - return bars; - } - - /** Creates the bars for the barcode supplemental 2. - * @param _code the text with 2 digits - * @return the barcode - */ - public static byte[] getBarsSupplemental2(String _code) { - int code[] = new int[2]; - for (int k = 0; k < code.length; ++k) - code[k] = _code.charAt(k) - '0'; - byte bars[] = new byte[TOTALBARS_SUPP2]; - int pb = 0; - int parity = (code[0] * 10 + code[1]) % 4; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 2; - byte sequence[] = PARITY2[parity]; - for (int k = 0; k < sequence.length; ++k) { - if (k == 1) { - bars[pb++] = 1; - bars[pb++] = 1; - } - int c = code[k]; - byte stripes[] = BARS[c]; - if (sequence[k] == ODD) { - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - else { - bars[pb++] = stripes[3]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[0]; - } - } - return bars; - } - - /** Creates the bars for the barcode supplemental 5. - * @param _code the text with 5 digits - * @return the barcode - */ - public static byte[] getBarsSupplemental5(String _code) { - int code[] = new int[5]; - for (int k = 0; k < code.length; ++k) - code[k] = _code.charAt(k) - '0'; - byte bars[] = new byte[TOTALBARS_SUPP5]; - int pb = 0; - int parity = (((code[0] + code[2] + code[4]) * 3) + ((code[1] + code[3]) * 9)) % 10; - bars[pb++] = 1; - bars[pb++] = 1; - bars[pb++] = 2; - byte sequence[] = PARITY5[parity]; - for (int k = 0; k < sequence.length; ++k) { - if (k != 0) { - bars[pb++] = 1; - bars[pb++] = 1; - } - int c = code[k]; - byte stripes[] = BARS[c]; - if (sequence[k] == ODD) { - bars[pb++] = stripes[0]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[3]; - } - else { - bars[pb++] = stripes[3]; - bars[pb++] = stripes[2]; - bars[pb++] = stripes[1]; - bars[pb++] = stripes[0]; - } - } - return bars; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float width = 0; - float height = barHeight; - if (font != null) { - if (baseline <= 0) - height += -baseline + size; - else - height += baseline - font.getFontDescriptor(BaseFont.DESCENT, size); - } - switch (codeType) { - case EAN13: - width = x * (11 + 12 * 7); - if (font != null) { - width += font.getWidthPoint(code.charAt(0), size); - } - break; - case EAN8: - width = x * (11 + 8 * 7); - break; - case UPCA: - width = x * (11 + 12 * 7); - if (font != null) { - width += font.getWidthPoint(code.charAt(0), size) + font.getWidthPoint(code.charAt(11), size); - } - break; - case UPCE: - width = x * (9 + 6 * 7); - if (font != null) { - width += font.getWidthPoint(code.charAt(0), size) + font.getWidthPoint(code.charAt(7), size); - } - break; - case SUPP2: - width = x * (6 + 2 * 7); - break; - case SUPP5: - width = x * (4 + 5 * 7 + 4 * 2); - break; - default: - throw new RuntimeException("Invalid code type."); - } - return new Rectangle(width, height); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - Rectangle rect = getBarcodeSize(); - float barStartX = 0; - float barStartY = 0; - float textStartY = 0; - if (font != null) { - if (baseline <= 0) - textStartY = barHeight - baseline; - else { - textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); - barStartY = textStartY + baseline; - } - } - switch (codeType) { - case EAN13: - case UPCA: - case UPCE: - if (font != null) - barStartX += font.getWidthPoint(code.charAt(0), size); - break; - } - byte bars[] = null; - int guard[] = GUARD_EMPTY; - switch (codeType) { - case EAN13: - bars = getBarsEAN13(code); - guard = GUARD_EAN13; - break; - case EAN8: - bars = getBarsEAN8(code); - guard = GUARD_EAN8; - break; - case UPCA: - bars = getBarsEAN13("0" + code); - guard = GUARD_UPCA; - break; - case UPCE: - bars = getBarsUPCE(code); - guard = GUARD_UPCE; - break; - case SUPP2: - bars = getBarsSupplemental2(code); - break; - case SUPP5: - bars = getBarsSupplemental5(code); - break; - } - float keepBarX = barStartX; - boolean print = true; - float gd = 0; - if (font != null && baseline > 0 && guardBars) { - gd = baseline / 2; - } - if (barColor != null) - cb.setColorFill(barColor); - for (int k = 0; k < bars.length; ++k) { - float w = bars[k] * x; - if (print) { - if (Arrays.binarySearch(guard, k) >= 0) - cb.rectangle(barStartX, barStartY - gd, w - inkSpreading, barHeight + gd); - else - cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); - } - print = !print; - barStartX += w; - } - cb.fill(); - if (font != null) { - if (textColor != null) - cb.setColorFill(textColor); - cb.beginText(); - cb.setFontAndSize(font, size); - switch (codeType) { - case EAN13: - cb.setTextMatrix(0, textStartY); - cb.showText(code.substring(0, 1)); - for (int k = 1; k < 13; ++k) { - String c = code.substring(k, k + 1); - float len = font.getWidthPoint(c, size); - float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2; - cb.setTextMatrix(pX, textStartY); - cb.showText(c); - } - break; - case EAN8: - for (int k = 0; k < 8; ++k) { - String c = code.substring(k, k + 1); - float len = font.getWidthPoint(c, size); - float pX = TEXTPOS_EAN8[k] * x - len / 2; - cb.setTextMatrix(pX, textStartY); - cb.showText(c); - } - break; - case UPCA: - cb.setTextMatrix(0, textStartY); - cb.showText(code.substring(0, 1)); - for (int k = 1; k < 11; ++k) { - String c = code.substring(k, k + 1); - float len = font.getWidthPoint(c, size); - float pX = keepBarX + TEXTPOS_EAN13[k] * x - len / 2; - cb.setTextMatrix(pX, textStartY); - cb.showText(c); - } - cb.setTextMatrix(keepBarX + x * (11 + 12 * 7), textStartY); - cb.showText(code.substring(11, 12)); - break; - case UPCE: - cb.setTextMatrix(0, textStartY); - cb.showText(code.substring(0, 1)); - for (int k = 1; k < 7; ++k) { - String c = code.substring(k, k + 1); - float len = font.getWidthPoint(c, size); - float pX = keepBarX + TEXTPOS_EAN13[k - 1] * x - len / 2; - cb.setTextMatrix(pX, textStartY); - cb.showText(c); - } - cb.setTextMatrix(keepBarX + x * (9 + 6 * 7), textStartY); - cb.showText(code.substring(7, 8)); - break; - case SUPP2: - case SUPP5: - for (int k = 0; k < code.length(); ++k) { - String c = code.substring(k, k + 1); - float len = font.getWidthPoint(c, size); - float pX = (7.5f + (9 * k)) * x - len / 2; - cb.setTextMatrix(pX, textStartY); - cb.showText(c); - } - break; - } - cb.endText(); - } - return rect; - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - - int width = 0; - byte bars[] = null; - switch (codeType) { - case EAN13: - bars = getBarsEAN13(code); - width = 11 + 12 * 7; - break; - case EAN8: - bars = getBarsEAN8(code); - width = 11 + 8 * 7; - break; - case UPCA: - bars = getBarsEAN13("0" + code); - width = 11 + 12 * 7; - break; - case UPCE: - bars = getBarsUPCE(code); - width = 9 + 6 * 7; - break; - case SUPP2: - bars = getBarsSupplemental2(code); - width = 6 + 2 * 7; - break; - case SUPP5: - bars = getBarsSupplemental5(code); - width = 4 + 5 * 7 + 4 * 2; - break; - default: - throw new RuntimeException("Invalid code type."); - } - - boolean print = true; - int ptr = 0; - int height = (int)barHeight; - int pix[] = new int[width * height]; - for (int k = 0; k < bars.length; ++k) { - int w = bars[k]; - int c = g; - if (print) - c = f; - print = !print; - for (int j = 0; j < w; ++j) - pix[ptr++] = c; - } - for (int k = width; k < pix.length; k += width) { - System.arraycopy(pix, 0, pix, k, width); - } - Image img = canvas.createImage(new MemoryImageSource(width, height, pix, 0, width)); - - return img; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BarcodeEANSUPP.java b/src/main/java/com/lowagie/text/pdf/BarcodeEANSUPP.java deleted file mode 100644 index 7e0d794..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodeEANSUPP.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; -import com.lowagie.text.Rectangle; -import java.awt.Color; - -/** This class takes 2 barcodes, an EAN/UPC and a supplemental - * and creates a single barcode with both combined in the - * expected layout. The UPC/EAN should have a positive text - * baseline and the supplemental a negative one (in the supplemental - * the text is on the top of the barcode.

- * The default parameters are: - *

- *n = 8; // horizontal distance between the two barcodes
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodeEANSUPP extends Barcode{ - - /** The barcode with the EAN/UPC. - */ - protected Barcode ean; - /** The barcode with the supplemental. - */ - protected Barcode supp; - - /** Creates new combined barcode. - * @param ean the EAN/UPC barcode - * @param supp the supplemental barcode - */ - public BarcodeEANSUPP(Barcode ean, Barcode supp) { - n = 8; // horizontal distance between the two barcodes - this.ean = ean; - this.supp = supp; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - Rectangle rect = ean.getBarcodeSize(); - rect.setRight(rect.width() + supp.getBarcodeSize().width() + n); - return rect; - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - if (supp.getFont() != null) - supp.setBarHeight(ean.getBarHeight() + supp.getBaseline() - supp.getFont().getFontDescriptor(BaseFont.CAPHEIGHT, supp.getSize())); - else - supp.setBarHeight(ean.getBarHeight()); - Rectangle eanR = ean.getBarcodeSize(); - cb.saveState(); - ean.placeBarcode(cb, barColor, textColor); - cb.restoreState(); - cb.saveState(); - cb.concatCTM(1, 0, 0, 1, eanR.width() + n, eanR.height() - ean.getBarHeight()); - supp.placeBarcode(cb, barColor, textColor); - cb.restoreState(); - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - throw new UnsupportedOperationException("The two barcodes must be composed externally."); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BarcodeInter25.java b/src/main/java/com/lowagie/text/pdf/BarcodeInter25.java deleted file mode 100644 index f8700d6..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodeInter25.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * $Id: BarcodeInter25.java,v 1.17 2006/02/09 18:07:56 psoares33 Exp $ - * - * Copyright 2002-2006 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Element; -import com.lowagie.text.Rectangle; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Implements the code interleaved 2 of 5. The text can include - * non numeric characters that are printed but do not generate bars. - * The default parameters are: - *

- *x = 0.8f;
- *n = 2;
- *font = BaseFont.createFont("Helvetica", "winansi", false);
- *size = 8;
- *baseline = size;
- *barHeight = size * 3;
- *textAlignment = Element.ALIGN_CENTER;
- *generateChecksum = false;
- *checksumText = false;
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodeInter25 extends Barcode{ - - /** The bars to generate the code. - */ - static byte BARS[][] = - { - {0,0,1,1,0}, - {1,0,0,0,1}, - {0,1,0,0,1}, - {1,1,0,0,0}, - {0,0,1,0,1}, - {1,0,1,0,0}, - {0,1,1,0,0}, - {0,0,0,1,1}, - {1,0,0,1,0}, - {0,1,0,1,0} - }; - - /** Creates new BarcodeInter25 */ - public BarcodeInter25() { - try { - x = 0.8f; - n = 2; - font = BaseFont.createFont("Helvetica", "winansi", false); - size = 8; - baseline = size; - barHeight = size * 3; - textAlignment = Element.ALIGN_CENTER; - generateChecksum = false; - checksumText = false; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Deletes all the non numeric characters from text. - * @param text the text - * @return a String with only numeric characters - */ - public static String keepNumbers(String text) { - StringBuffer sb = new StringBuffer(); - for (int k = 0; k < text.length(); ++k) { - char c = text.charAt(k); - if (c >= '0' && c <= '9') - sb.append(c); - } - return sb.toString(); - } - - /** Calculates the checksum. - * @param text the numeric text - * @return the checksum - */ - public static char getChecksum(String text) { - int mul = 3; - int total = 0; - for (int k = text.length() - 1; k >= 0; --k) { - int n = text.charAt(k) - '0'; - total += mul * n; - mul ^= 2; - } - return (char)(((10 - (total % 10)) % 10) + '0'); - } - - /** Creates the bars for the barcode. - * @param text the text. It can contain non numeric characters - * @return the barcode - */ - public static byte[] getBarsInter25(String text) { - text = keepNumbers(text); - if ((text.length() & 1) != 0) - throw new IllegalArgumentException("The text length must be even."); - byte bars[] = new byte[text.length() * 5 + 7]; - int pb = 0; - bars[pb++] = 0; - bars[pb++] = 0; - bars[pb++] = 0; - bars[pb++] = 0; - int len = text.length() / 2; - for (int k = 0; k < len; ++k) { - int c1 = text.charAt(k * 2) - '0'; - int c2 = text.charAt(k * 2 + 1) - '0'; - byte b1[] = BARS[c1]; - byte b2[] = BARS[c2]; - for (int j = 0; j < 5; ++j) { - bars[pb++] = b1[j]; - bars[pb++] = b2[j]; - } - } - bars[pb++] = 1; - bars[pb++] = 0; - bars[pb++] = 0; - return bars; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float fontX = 0; - float fontY = 0; - if (font != null) { - if (baseline > 0) - fontY = baseline - font.getFontDescriptor(BaseFont.DESCENT, size); - else - fontY = -baseline + size; - String fullCode = code; - if (generateChecksum && checksumText) - fullCode += getChecksum(fullCode); - fontX = font.getWidthPoint(altText != null ? altText : fullCode, size); - } - String fullCode = keepNumbers(code); - int len = fullCode.length(); - if (generateChecksum) - ++len; - float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x; - fullWidth = Math.max(fullWidth, fontX); - float fullHeight = barHeight + fontY; - return new Rectangle(fullWidth, fullHeight); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - String fullCode = code; - float fontX = 0; - if (font != null) { - if (generateChecksum && checksumText) - fullCode += getChecksum(fullCode); - fontX = font.getWidthPoint(fullCode = altText != null ? altText : fullCode, size); - } - String bCode = keepNumbers(code); - if (generateChecksum) - bCode += getChecksum(bCode); - int len = bCode.length(); - float fullWidth = len * (3 * x + 2 * x * n) + (6 + n ) * x; - float barStartX = 0; - float textStartX = 0; - switch (textAlignment) { - case Element.ALIGN_LEFT: - break; - case Element.ALIGN_RIGHT: - if (fontX > fullWidth) - barStartX = fontX - fullWidth; - else - textStartX = fullWidth - fontX; - break; - default: - if (fontX > fullWidth) - barStartX = (fontX - fullWidth) / 2; - else - textStartX = (fullWidth - fontX) / 2; - break; - } - float barStartY = 0; - float textStartY = 0; - if (font != null) { - if (baseline <= 0) - textStartY = barHeight - baseline; - else { - textStartY = -font.getFontDescriptor(BaseFont.DESCENT, size); - barStartY = textStartY + baseline; - } - } - byte bars[] = getBarsInter25(bCode); - boolean print = true; - if (barColor != null) - cb.setColorFill(barColor); - for (int k = 0; k < bars.length; ++k) { - float w = (bars[k] == 0 ? x : x * n); - if (print) - cb.rectangle(barStartX, barStartY, w - inkSpreading, barHeight); - print = !print; - barStartX += w; - } - cb.fill(); - if (font != null) { - if (textColor != null) - cb.setColorFill(textColor); - cb.beginText(); - cb.setFontAndSize(font, size); - cb.setTextMatrix(textStartX, textStartY); - cb.showText(fullCode); - cb.endText(); - } - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - - String bCode = keepNumbers(code); - if (generateChecksum) - bCode += getChecksum(bCode); - int len = bCode.length(); - int nn = (int)n; - int fullWidth = len * (3 + 2 * nn) + (6 + nn ); - byte bars[] = getBarsInter25(bCode); - boolean print = true; - int ptr = 0; - int height = (int)barHeight; - int pix[] = new int[fullWidth * height]; - for (int k = 0; k < bars.length; ++k) { - int w = (bars[k] == 0 ? 1 : nn); - int c = g; - if (print) - c = f; - print = !print; - for (int j = 0; j < w; ++j) - pix[ptr++] = c; - } - for (int k = fullWidth; k < pix.length; k += fullWidth) { - System.arraycopy(pix, 0, pix, k, fullWidth); - } - Image img = canvas.createImage(new MemoryImageSource(fullWidth, height, pix, 0, fullWidth)); - - return img; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/BarcodePDF417.java b/src/main/java/com/lowagie/text/pdf/BarcodePDF417.java deleted file mode 100644 index c0d3c6e..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodePDF417.java +++ /dev/null @@ -1,1604 +0,0 @@ -/* - * - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Image; -import com.lowagie.text.BadElementException; -import java.util.ArrayList; -import java.io.UnsupportedEncodingException; -import com.lowagie.text.pdf.codec.CCITTG4Encoder; -import java.awt.Color; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Generates the 2D barcode PDF417. Supports dimensioning auto-sizing, fixed - * and variable sizes, automatic and manual error levels, raw codeword input, - * codeword size optimization and bitmap inversion. The output can - * be a CCITT G4 Image or a raw bitmap. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodePDF417 { - - /** Auto-size is made based on aspectRatio and yHeight. */ - public static final int PDF417_USE_ASPECT_RATIO = 0; - /** The size of the barcode will be at least codeColumns*codeRows. */ - public static final int PDF417_FIXED_RECTANGLE = 1; - /** The size will be at least codeColumns - * with a variable number of codeRows. - */ - public static final int PDF417_FIXED_COLUMNS = 2; - /** The size will be at least codeRows - * with a variable number of codeColumns. - */ - public static final int PDF417_FIXED_ROWS = 4; - /** The error level correction is set automatically according - * to ISO 15438 recomendations. - */ - public static final int PDF417_AUTO_ERROR_LEVEL = 0; - /** The error level correction is set by the user. It can be 0 to 8. */ - public static final int PDF417_USE_ERROR_LEVEL = 16; - /** - * One single binary segment is used - */ - public static final int PDF417_FORCE_BINARY = 32; - /** No text interpretation is done and the content of codewords - * is used directly. - */ - public static final int PDF417_USE_RAW_CODEWORDS = 64; - /** Inverts the output bits of the raw bitmap that is normally - * bit one for black. It has only effect for the raw bitmap. - */ - public static final int PDF417_INVERT_BITMAP = 128; - /** Use Macro PDF417 Encoding - * @see #setMacroFileId(String) - * @see #setMacroSegmentId(int) - * @see #setMacroSegmentCount(int) - */ - public static final int PDF417_USE_MACRO = 256; - - - private int macroSegmentCount=0; - private int macroSegmentId=-1; - private String macroFileId; - protected int bitPtr; - protected int cwPtr; - protected SegmentList segmentList; - - /** Creates a new BarcodePDF417 with the default settings. */ - public BarcodePDF417() { - setDefaultParameters(); - } - - /** - * Sets the segment id for macro PDF417 encoding - * @param id the id (starting at 0) - * @see #setMacroSegmentCount(int) - */ - public void setMacroSegmentId(int id) { - this.macroSegmentId = id; - } - - /** - * Sets the segment count for macro PDF417 encoding - * @param cnt the number of macro segments - * @see #setMacroSegmentId(int) - */ - public void setMacroSegmentCount(int cnt) { - this.macroSegmentCount = cnt; - } - - /** - * Sets the File ID for macro PDF417 encoding - * @param id the file id - */ - public void setMacroFileId(String id) { - this.macroFileId = id; - } - - protected boolean checkSegmentType(Segment segment, char type) { - if (segment == null) - return false; - return segment.type == type; - } - - protected int getSegmentLength(Segment segment) { - if (segment == null) - return 0; - return segment.end - segment.start; - } - - /** Set the default settings that correspond to PDF417_USE_ASPECT_RATIO - * and PDF417_AUTO_ERROR_LEVEL. - */ - public void setDefaultParameters() { - options = 0; - outBits = null; - text = new byte[0]; - yHeight = 3; - aspectRatio = 0.5f; - } - - protected void outCodeword17(int codeword) { - int bytePtr = bitPtr / 8; - int bit = bitPtr - bytePtr * 8; - outBits[bytePtr++] |= codeword >> (9 + bit); - outBits[bytePtr++] |= codeword >> (1 + bit); - codeword <<= 8; - outBits[bytePtr] |= codeword >> (1 + bit); - bitPtr += 17; - } - - protected void outCodeword18(int codeword) { - int bytePtr = bitPtr / 8; - int bit = bitPtr - bytePtr * 8; - outBits[bytePtr++] |= codeword >> (10 + bit); - outBits[bytePtr++] |= codeword >> (2 + bit); - codeword <<= 8; - outBits[bytePtr] |= codeword >> (2 + bit); - if (bit == 7) - outBits[++bytePtr] |= 0x80; - bitPtr += 18; - } - - protected void outCodeword(int codeword) { - outCodeword17(codeword); - } - - protected void outStopPattern() { - outCodeword18(STOP_PATTERN); - } - - protected void outStartPattern() { - outCodeword17(START_PATTERN); - } - - protected void outPaintCode() { - int codePtr = 0; - bitColumns = START_CODE_SIZE * (codeColumns + 3) + STOP_SIZE; - int lenBits = ((bitColumns - 1) / 8 + 1) * codeRows; - outBits = new byte[lenBits]; - for (int row = 0; row < codeRows; ++row) { - bitPtr = ((bitColumns - 1) / 8 + 1) * 8 * row; - int rowMod = row % 3; - int cluster[] = CLUSTERS[rowMod]; - outStartPattern(); - int edge = 0; - switch (rowMod) { - case 0: - edge = 30 * (row / 3) + ((codeRows - 1) / 3); - break; - case 1: - edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); - break; - default: - edge = 30 * (row / 3) + codeColumns - 1; - break; - } - outCodeword(cluster[edge]); - - for (int column = 0; column < codeColumns; ++column) { - outCodeword(cluster[codewords[codePtr++]]); - } - - switch (rowMod) { - case 0: - edge = 30 * (row / 3) + codeColumns - 1; - break; - case 1: - edge = 30 * (row / 3) + ((codeRows - 1) / 3); - break; - default: - edge = 30 * (row / 3) + errorLevel * 3 + ((codeRows - 1) % 3); - break; - } - outCodeword(cluster[edge]); - outStopPattern(); - } - if ((options & PDF417_INVERT_BITMAP) != 0) { - for (int k = 0; k < outBits.length; ++k) - outBits[k] ^= 0xff; - } - } - - protected void calculateErrorCorrection(int dest) { - if (errorLevel < 0 || errorLevel > 8) - errorLevel = 0; - int A[] = ERROR_LEVEL[errorLevel]; - int Alength = 2 << errorLevel; - for (int k = 0; k < Alength; ++k) - codewords[dest + k] = 0; - int lastE = Alength - 1; - for (int k = 0; k < lenCodewords; ++k) { - int t1 = codewords[k] + codewords[dest]; - for (int e = 0; e <= lastE; ++e) { - int t2 = (t1 * A[lastE - e]) % MOD; - int t3 = MOD - t2; - codewords[dest + e] = ((e == lastE ? 0 : codewords[dest + e + 1]) + t3) % MOD; - } - } - for (int k = 0; k < Alength; ++k) - codewords[dest + k] = (MOD - codewords[dest + k]) % MOD; - } - - private static int getTextTypeAndValue(byte[] input, int maxLength, int idx) { - if (idx >= maxLength) - return 0; - char c = (char)(input[idx] & 0xff); - if (c >= 'A' && c <= 'Z') - return (ALPHA + c - 'A'); - if (c >= 'a' && c <= 'z') - return (LOWER + c - 'a'); - if (c == ' ') - return (ALPHA + LOWER + MIXED + SPACE); - int ms = MIXED_SET.indexOf(c); - int ps = PUNCTUATION_SET.indexOf(c); - if (ms < 0 && ps < 0) - return (ISBYTE + c); - if (ms == ps) - return (MIXED + PUNCTUATION + ms); - if (ms >= 0) - return (MIXED + ms); - return (PUNCTUATION + ps); - } - - protected int getTextTypeAndValue(int maxLength, int idx) { - return getTextTypeAndValue(text, maxLength,idx); - } - - private void textCompaction(byte[] input, int start, int length) { - int dest[] = new int[ABSOLUTE_MAX_TEXT_SIZE * 2]; - int mode = ALPHA; - int ptr = 0; - int fullBytes = 0; - int v = 0; - int k; - int size; - length += start; - for (k = start; k < length; ++k) { - v = getTextTypeAndValue(input, length, k); - if ((v & mode) != 0) { - dest[ptr++] = v & 0xff; - continue; - } - if ((v & ISBYTE) != 0) { - if ((ptr & 1) != 0) { - dest[ptr++] = (mode & PUNCTUATION) != 0 ? PAL : PS; - mode = (mode & PUNCTUATION) != 0 ? ALPHA : mode; - } - dest[ptr++] = BYTESHIFT; - dest[ptr++] = v & 0xff; - fullBytes += 2; - continue; - } - switch (mode) { - case ALPHA: - if ((v & LOWER) != 0) { - dest[ptr++] = LL; - dest[ptr++] = v & 0xff; - mode = LOWER; - } - else if ((v & MIXED) != 0) { - dest[ptr++] = ML; - dest[ptr++] = v & 0xff; - mode = MIXED; - } - else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { - dest[ptr++] = ML; - dest[ptr++] = PL; - dest[ptr++] = v & 0xff; - mode = PUNCTUATION; - } - else { - dest[ptr++] = PS; - dest[ptr++] = v & 0xff; - } - break; - case LOWER: - if ((v & ALPHA) != 0) { - if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & ALPHA) != 0) { - dest[ptr++] = ML; - dest[ptr++] = AL; - mode = ALPHA; - } - else { - dest[ptr++] = AS; - } - dest[ptr++] = v & 0xff; - } - else if ((v & MIXED) != 0) { - dest[ptr++] = ML; - dest[ptr++] = v & 0xff; - mode = MIXED; - } - else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { - dest[ptr++] = ML; - dest[ptr++] = PL; - dest[ptr++] = v & 0xff; - mode = PUNCTUATION; - } - else { - dest[ptr++] = PS; - dest[ptr++] = v & 0xff; - } - break; - case MIXED: - if ((v & LOWER) != 0) { - dest[ptr++] = LL; - dest[ptr++] = v & 0xff; - mode = LOWER; - } - else if ((v & ALPHA) != 0) { - dest[ptr++] = AL; - dest[ptr++] = v & 0xff; - mode = ALPHA; - } - else if ((getTextTypeAndValue(input, length, k + 1) & getTextTypeAndValue(input, length, k + 2) & PUNCTUATION) != 0) { - dest[ptr++] = PL; - dest[ptr++] = v & 0xff; - mode = PUNCTUATION; - } - else { - dest[ptr++] = PS; - dest[ptr++] = v & 0xff; - } - break; - case PUNCTUATION: - dest[ptr++] = PAL; - mode = ALPHA; - --k; - break; - } - } - if ((ptr & 1) != 0) - dest[ptr++] = PS; - size = (ptr + fullBytes) / 2; - if (size + cwPtr > MAX_DATA_CODEWORDS) { - throw new IndexOutOfBoundsException("The text is too big."); - } - length = ptr; - ptr = 0; - while (ptr < length) { - v = dest[ptr++]; - if (v >= 30) { - codewords[cwPtr++] = v; - codewords[cwPtr++] = dest[ptr++]; - } - else - codewords[cwPtr++] = v * 30 + dest[ptr++]; - } - } - protected void textCompaction(int start, int length) { - textCompaction(text, start, length); - } - - protected void basicNumberCompaction(int start, int length) { - basicNumberCompaction(text, start, length); - } - - private void basicNumberCompaction(byte[] input, int start, int length) { - int ret = cwPtr; - int retLast = length / 3; - int ni, k; - cwPtr += retLast + 1; - for (k = 0; k <= retLast; ++k) - codewords[ret + k] = 0; - codewords[ret + retLast] = 1; - length += start; - for (ni = start; ni < length; ++ni) { - // multiply by 10 - for (k = retLast; k >= 0; --k) - codewords[ret + k] *= 10; - // add the digit - codewords[ret + retLast] += input[ni] - '0'; - // propagate carry - for (k = retLast; k > 0; --k) { - codewords[ret + k - 1] += codewords[ret + k] / 900; - codewords[ret + k] %= 900; - } - } - } - - private void numberCompaction(byte[] input, int start, int length) { - int full = (length / 44) * 15; - int size = length % 44; - int k; - if (size == 0) - size = full; - else - size = full + size / 3 + 1; - if (size + cwPtr > MAX_DATA_CODEWORDS) { - throw new IndexOutOfBoundsException("The text is too big."); - } - length += start; - for (k = start; k < length; k += 44) { - size = length - k < 44 ? length - k : 44; - basicNumberCompaction(input, k, size); - } - } - - protected void numberCompaction(int start, int length) { - numberCompaction(text, start, length); - } - - protected void byteCompaction6(int start) { - int length = 6; - int ret = cwPtr; - int retLast = 4; - int ni, k; - cwPtr += retLast + 1; - for (k = 0; k <= retLast ; ++k) - codewords[ret + k] = 0; - length += start; - for (ni = start; ni < length; ++ni) { - // multiply by 256 - for (k = retLast; k >= 0; --k) - codewords[ret + k] *= 256; - // add the digit - codewords[ret + retLast] += (int)text[ni] & 0xff; - // propagate carry - for (k = retLast; k > 0; --k) { - codewords[ret + k - 1] += codewords[ret + k] / 900; - codewords[ret + k] %= 900; - } - } - } - - void byteCompaction(int start, int length) { - int k, j; - int size = (length / 6) * 5 + (length % 6); - if (size + cwPtr > MAX_DATA_CODEWORDS) { - throw new IndexOutOfBoundsException("The text is too big."); - } - length += start; - for (k = start; k < length; k += 6) { - size = length - k < 44 ? length - k : 6; - if (size < 6) { - for (j = 0; j < size; ++j) - codewords[cwPtr++] = (int)text[k + j] & 0xff; - } - else { - byteCompaction6(k); - } - } - } - - void breakString() { - int textLength = text.length; - int lastP = 0; - int startN = 0; - int nd = 0; - char c = 0; - int k, j; - boolean lastTxt, txt; - Segment v; - Segment vp; - Segment vn; - - if ((options & PDF417_FORCE_BINARY) != 0) { - segmentList.add('B', 0, textLength); - return; - } - for (k = 0; k < textLength; ++k) { - c = (char)(text[k] & 0xff); - if (c >= '0' && c <= '9') { - if (nd == 0) - startN = k; - ++nd; - continue; - } - if (nd >= 13) { - if (lastP != startN) { - c = (char)(text[lastP] & 0xff); - lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; - for (j = lastP; j < startN; ++j) { - c = (char)(text[j] & 0xff); - txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; - if (txt != lastTxt) { - segmentList.add(lastTxt ? 'T' : 'B', lastP, j); - lastP = j; - lastTxt = txt; - } - } - segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); - } - segmentList.add('N', startN, k); - lastP = k; - } - nd = 0; - } - if (nd < 13) - startN = textLength; - if (lastP != startN) { - c = (char)(text[lastP] & 0xff); - lastTxt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; - for (j = lastP; j < startN; ++j) { - c = (char)(text[j] & 0xff); - txt = (c >= ' ' && c < 127) || c == '\r' || c == '\n' || c == '\t'; - if (txt != lastTxt) { - segmentList.add(lastTxt ? 'T' : 'B', lastP, j); - lastP = j; - lastTxt = txt; - } - } - segmentList.add(lastTxt ? 'T' : 'B', lastP, startN); - } - if (nd >= 13) - segmentList.add('N', startN, textLength); - //optimize - //merge short binary - for (k = 0; k < segmentList.size(); ++k) { - v = segmentList.get(k); - vp = segmentList.get(k - 1); - vn = segmentList.get(k + 1);; - if (checkSegmentType(v, 'B') && getSegmentLength(v) == 1) { - if (checkSegmentType(vp, 'T') && checkSegmentType(vn, 'T') - && getSegmentLength(vp) + getSegmentLength(vn) >= 3) { - vp.end = vn.end; - segmentList.remove(k); - segmentList.remove(k); - k = -1; - continue; - } - } - } - //merge text sections - for (k = 0; k < segmentList.size(); ++k) { - v = segmentList.get(k); - vp = segmentList.get(k - 1); - vn = segmentList.get(k + 1);; - if (checkSegmentType(v, 'T') && getSegmentLength(v) >= 5) { - boolean redo = false; - if ((checkSegmentType(vp, 'B') && getSegmentLength(vp) == 1) || checkSegmentType(vp, 'T')) { - redo = true; - v.start = vp.start; - segmentList.remove(k - 1); - --k; - } - if ((checkSegmentType(vn, 'B') && getSegmentLength(vn) == 1) || checkSegmentType(vn, 'T')) { - redo = true; - v.end = vn.end; - segmentList.remove(k + 1); - } - if (redo) { - k = -1; - continue; - } - } - } - //merge binary sections - for (k = 0; k < segmentList.size(); ++k) { - v = segmentList.get(k); - vp = segmentList.get(k - 1); - vn = segmentList.get(k + 1);; - if (checkSegmentType(v, 'B')) { - boolean redo = false; - if ((checkSegmentType(vp, 'T') && getSegmentLength(vp) < 5) || checkSegmentType(vp, 'B')) { - redo = true; - v.start = vp.start; - segmentList.remove(k - 1); - --k; - } - if ((checkSegmentType(vn, 'T') && getSegmentLength(vn) < 5) || checkSegmentType(vn, 'B')) { - redo = true; - v.end = vn.end; - segmentList.remove(k + 1); - } - if (redo) { - k = -1; - continue; - } - } - } - // check if all numbers - if (segmentList.size() == 1 && (v = segmentList.get(0)).type == 'T' && getSegmentLength(v) >= 8) { - for (k = v.start; k < v.end; ++k) { - c = (char)(text[k] & 0xff); - if (c < '0' || c > '9') - break; - } - if (k == v.end) - v.type = 'N'; - } - } - - protected void assemble() { - int k; - if (segmentList.size() == 0) - return; - cwPtr = 1; - for (k = 0; k < segmentList.size(); ++k) { - Segment v = segmentList.get(k); - switch (v.type) { - case 'T': - if (k != 0) - codewords[cwPtr++] = TEXT_MODE; - textCompaction(v.start, getSegmentLength(v)); - break; - case 'N': - codewords[cwPtr++] = NUMERIC_MODE; - numberCompaction(v.start, getSegmentLength(v)); - break; - case 'B': - codewords[cwPtr++] = (getSegmentLength(v) % 6) != 0 ? BYTE_MODE : BYTE_MODE_6; - byteCompaction(v.start, getSegmentLength(v)); - break; - } - } - - if ((options & PDF417_USE_MACRO) != 0) { - macroCodes(); - } - - } - - private void macroCodes() { - if (macroSegmentId < 0) { - throw new IllegalStateException("macroSegmentId must be >=0"); - } - if (macroSegmentId >= macroSegmentCount) { - throw new IllegalStateException("macroSegmentId must be < macroSemgentCount"); - } - if (macroSegmentCount < 1) { - throw new IllegalStateException("macroSemgentCount must be > 0"); - } - - codewords[cwPtr++] = MACRO_SEGMENT_ID; - append(macroSegmentId, 5); - - if (macroFileId != null) { - append(macroFileId); - } - - codewords[cwPtr++] = MACRO_SEGMENT_COUNT; - codewords[cwPtr++] = 1; - append(macroSegmentCount, 5); - - if (macroSegmentId >= macroSegmentCount-1) { - codewords[cwPtr++] = MACRO_LAST_SEGMENT; - } - - } - - private void append(int in, int len) { - StringBuffer sb = new StringBuffer(len+1); - sb.append(Integer.toString(in)); - for(int i = sb.length(); i < len; i++) { - sb.insert(0, "0"); - } - - byte[] bytes = PdfEncodings.convertToBytes(sb.toString(), "cp437"); - numberCompaction(bytes, 0, bytes.length); - } - - private void append(String s) { - byte[] bytes = PdfEncodings.convertToBytes(s, "cp437"); - textCompaction(bytes, 0, bytes.length); - } - - - protected static int maxPossibleErrorLevel(int remain) { - int level = 8; - int size = 512; - while (level > 0) { - if (remain >= size) - return level; - --level; - size >>= 1; - } - return 0; - } - - protected void dumpList() { - if (segmentList.size() == 0) - return; - for (int k = 0; k < segmentList.size(); ++k) { - Segment v = segmentList.get(k); - int len = getSegmentLength(v); - char c[] = new char[len]; - for (int j = 0; j < len; ++j) { - c[j] = (char)(text[v.start + j] & 0xff); - if (c[j] == '\r') - c[j] = '\n'; - } - System.out.println("" + v.type + new String(c)); - } - } - - protected int getMaxSquare() { - if (codeColumns > 21) { - codeColumns = 29; - codeRows = 32; - } - else { - codeColumns = 16; - codeRows = 58; - } - return MAX_DATA_CODEWORDS + 2; - } - - /** Paints the barcode. If no exception was thrown a valid barcode is available. */ - public void paintCode() { - int maxErr, lenErr, tot, pad; - if ((options & PDF417_USE_RAW_CODEWORDS) != 0) { - if (lenCodewords > MAX_DATA_CODEWORDS || lenCodewords < 1 || lenCodewords != codewords[0]) { - throw new IllegalArgumentException("Invalid codeword size."); - } - } - else { - if (text == null) - throw new NullPointerException("Text cannot be null."); - if (text.length > ABSOLUTE_MAX_TEXT_SIZE) { - throw new IndexOutOfBoundsException("The text is too big."); - } - segmentList = new SegmentList(); - breakString(); - //dumpList(); - assemble(); - segmentList = null; - codewords[0] = lenCodewords = cwPtr; - } - maxErr = maxPossibleErrorLevel(MAX_DATA_CODEWORDS + 2 - lenCodewords); - if ((options & PDF417_USE_ERROR_LEVEL) == 0) { - if (lenCodewords < 41) - errorLevel = 2; - else if (lenCodewords < 161) - errorLevel = 3; - else if (lenCodewords < 321) - errorLevel = 4; - else - errorLevel = 5; - } - if (errorLevel < 0) - errorLevel = 0; - else if (errorLevel > maxErr) - errorLevel = maxErr; - if (codeColumns < 1) - codeColumns = 1; - else if (codeColumns > 30) - codeColumns = 30; - if (codeRows < 3) - codeRows = 3; - else if (codeRows > 90) - codeRows = 90; - lenErr = 2 << errorLevel; - boolean fixedColumn = (options & PDF417_FIXED_ROWS) == 0; - boolean skipRowColAdjust = false; - tot = lenCodewords + lenErr; - if ((options & PDF417_FIXED_RECTANGLE) != 0) { - tot = codeColumns * codeRows; - if (tot > MAX_DATA_CODEWORDS + 2) { - tot = getMaxSquare(); - } - if (tot < lenCodewords + lenErr) - tot = lenCodewords + lenErr; - else - skipRowColAdjust = true; - } - else if ((options & (PDF417_FIXED_COLUMNS | PDF417_FIXED_ROWS)) == 0) { - double c, b; - fixedColumn = true; - if (aspectRatio < 0.001) - aspectRatio = 0.001f; - else if (aspectRatio > 1000) - aspectRatio = 1000; - b = 73 * aspectRatio - 4; - c = (-b + Math.sqrt(b * b + 4 * 17 * aspectRatio * (lenCodewords + lenErr) * yHeight)) / (2 * 17 * aspectRatio); - codeColumns = (int)(c + 0.5); - if (codeColumns < 1) - codeColumns = 1; - else if (codeColumns > 30) - codeColumns = 30; - } - if (!skipRowColAdjust) { - if (fixedColumn) { - codeRows = (tot - 1) / codeColumns + 1; - if (codeRows < 3) - codeRows = 3; - else if (codeRows > 90) { - codeRows = 90; - codeColumns = (tot - 1) / 90 + 1; - } - } - else { - codeColumns = (tot - 1) / codeRows + 1; - if (codeColumns > 30) { - codeColumns = 30; - codeRows = (tot - 1) / 30 + 1; - } - } - tot = codeRows * codeColumns; - } - if (tot > MAX_DATA_CODEWORDS + 2) { - tot = getMaxSquare(); - } - errorLevel = maxPossibleErrorLevel(tot - lenCodewords); - lenErr = 2 << errorLevel; - pad = tot - lenErr - lenCodewords; - cwPtr = lenCodewords; - while (pad-- != 0) - codewords[cwPtr++] = TEXT_MODE; - codewords[0] = lenCodewords = cwPtr; - calculateErrorCorrection(lenCodewords); - lenCodewords = tot; - outPaintCode(); - } - - /** Gets an Image with the barcode. The image will have to be - * scaled in the Y direction by yHeightfor the barcode - * to have the right printing aspect. - * @return the barcode Image - * @throws BadElementException on error - */ - public Image getImage() throws BadElementException { - paintCode(); - byte g4[] = CCITTG4Encoder.compress(outBits, bitColumns, codeRows); - return Image.getInstance(bitColumns, codeRows, false, Image.CCITTG4, (options & PDF417_INVERT_BITMAP) == 0 ? 0 : Image.CCITT_BLACKIS1, g4, null); - } - - /** Creates a java.awt.Image. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - - paintCode(); - int h = (int)yHeight; - int pix[] = new int[bitColumns * codeRows * h]; - int stride = (bitColumns + 7) / 8; - int ptr = 0; - for (int k = 0; k < codeRows; ++k) { - int p = k * stride; - for (int j = 0; j < bitColumns; ++j) { - int b = outBits[p + (j / 8)] & 0xff; - b <<= j % 8; - pix[ptr++] = (b & 0x80) == 0 ? g : f; - } - for (int j = 1; j < h; ++j) { - System.arraycopy(pix, ptr - bitColumns, pix, ptr + bitColumns * (j - 1), bitColumns); - } - ptr += bitColumns * (h - 1); - } - - java.awt.Image img = canvas.createImage(new MemoryImageSource(bitColumns, codeRows * h, pix, 0, bitColumns)); - return img; - } - - /** Gets the raw image bits of the barcode. The image will have to - * be scaled in the Y direction by yHeight. - * @return The raw barcode image - */ - public byte[] getOutBits() { - return this.outBits; - } - - /** Gets the number of X pixels of outBits. - * @return the number of X pixels of outBits - */ - public int getBitColumns() { - return this.bitColumns; - } - - /** Gets the number of Y pixels of outBits. - * It is also the number of rows in the barcode. - * @return the number of Y pixels of outBits - */ - public int getCodeRows() { - return this.codeRows; - } - - /** Sets the number of barcode rows. This number may be changed - * to keep the barcode valid. - * @param codeRows the number of barcode rows - */ - public void setCodeRows(int codeRows) { - this.codeRows = codeRows; - } - - /** Gets the number of barcode data columns. - * @return he number of barcode data columns - */ - public int getCodeColumns() { - return this.codeColumns; - } - - /** Sets the number of barcode data columns. - * This number may be changed to keep the barcode valid. - * @param codeColumns the number of barcode data columns - */ - public void setCodeColumns(int codeColumns) { - this.codeColumns = codeColumns; - } - - /** Gets the codeword array. This array is always 928 elements long. - * It can be writen to if the option PDF417_USE_RAW_CODEWORDS - * is set. - * @return the codeword array - */ - public int[] getCodewords() { - return this.codewords; - } - - /** Gets the length of the codewords. - * @return the length of the codewords - */ - public int getLenCodewords() { - return this.lenCodewords; - } - - /** Sets the length of the codewords. - * @param lenCodewords the length of the codewords - */ - public void setLenCodewords(int lenCodewords) { - this.lenCodewords = lenCodewords; - } - - /** Gets the error level correction used for the barcode. It may different - * from the previously set value. - * @return the error level correction used for the barcode - */ - public int getErrorLevel() { - return this.errorLevel; - } - - /** Sets the error level correction for the barcode. - * @param errorLevel the error level correction for the barcode - */ - public void setErrorLevel(int errorLevel) { - this.errorLevel = errorLevel; - } - - /** Gets the bytes that form the barcode. This bytes should - * be interpreted in the codepage Cp437. - * @return the bytes that form the barcode - */ - public byte[] getText() { - return this.text; - } - - /** Sets the bytes that form the barcode. This bytes should - * be interpreted in the codepage Cp437. - * @param text the bytes that form the barcode - */ - public void setText(byte[] text) { - this.text = text; - } - - /** Sets the text that will form the barcode. This text is converted - * to bytes using the encoding Cp437. - * @param s the text that will form the barcode - * @throws UnsupportedEncodingException if the encoding Cp437 is not supported - */ - public void setText(String s) { - this.text = PdfEncodings.convertToBytes(s, "cp437"); - } - - /** Gets the options to generate the barcode. - * @return the options to generate the barcode - */ - public int getOptions() { - return this.options; - } - - /** Sets the options to generate the barcode. This can be all - * the PDF417_* constants. - * @param options the options to generate the barcode - */ - public void setOptions(int options) { - this.options = options; - } - - /** Gets the barcode aspect ratio. - * @return the barcode aspect ratio - */ - public float getAspectRatio() { - return this.aspectRatio; - } - - /** Sets the barcode aspect ratio. A ratio or 0.5 will make the - * barcode width twice as large as the height. - * @param aspectRatio the barcode aspect ratio - */ - public void setAspectRatio(float aspectRatio) { - this.aspectRatio = aspectRatio; - } - - /** Gets the Y pixel height relative to X. - * @return the Y pixel height relative to X - */ - public float getYHeight() { - return this.yHeight; - } - - /** Sets the Y pixel height relative to X. It is usually 3. - * @param yHeight the Y pixel height relative to X - */ - public void setYHeight(float yHeight) { - this.yHeight = yHeight; - } - - protected static final int START_PATTERN = 0x1fea8; - protected static final int STOP_PATTERN = 0x3fa29; - protected static final int START_CODE_SIZE = 17; - protected static final int STOP_SIZE = 18; - protected static final int MOD = 929; - protected static final int ALPHA = 0x10000; - protected static final int LOWER = 0x20000; - protected static final int MIXED = 0x40000; - protected static final int PUNCTUATION = 0x80000; - protected static final int ISBYTE = 0x100000; - protected static final int BYTESHIFT = 913; - protected static final int PL = 25; - protected static final int LL = 27; - protected static final int AS = 27; - protected static final int ML = 28; - protected static final int AL = 28; - protected static final int PS = 29; - protected static final int PAL = 29; - protected static final int SPACE = 26; - protected static final int TEXT_MODE = 900; - protected static final int BYTE_MODE_6 = 924; - protected static final int BYTE_MODE = 901; - protected static final int NUMERIC_MODE = 902; - protected static final int ABSOLUTE_MAX_TEXT_SIZE = 5420; - protected static final int MAX_DATA_CODEWORDS = 926; - protected static final int MACRO_SEGMENT_ID=928; - protected static final int MACRO_SEGMENT_COUNT=923; - protected static final int MACRO_LAST_SEGMENT=922; - - static String MIXED_SET = "0123456789&\r\t,:#-.$/+%*=^"; - static String PUNCTUATION_SET = ";<>@[\\]_`~!\r\t,:\n-.$/\"|*()?{}'"; - - static int CLUSTERS[][] = - {{ - 0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e, 0x1a8c0, 0x1d470, - 0x1a860, 0x15040, 0x1a830, 0x15020, 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, - 0x1d678, 0x1eb3e, 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c, - 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0, 0x1af7c, 0x15e78, - 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0, 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, - 0x1e93c, 0x1a460, 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418, - 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670, 0x1d33c, 0x14c60, - 0x1a638, 0x1d31e, 0x14c30, 0x1a61c, 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, - 0x1a73c, 0x14e38, 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0, - 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440, 0x1a230, 0x1d11c, - 0x14420, 0x1a218, 0x14410, 0x14408, 0x146c0, 0x1a370, 0x1d1bc, 0x14660, - 0x1a338, 0x1d19e, 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc, - 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8, 0x1e85e, 0x14240, - 0x1a130, 0x1d09c, 0x14220, 0x1a118, 0x1d08e, 0x14210, 0x1a10c, 0x14208, - 0x1a106, 0x14360, 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e, - 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0, 0x1d05c, 0x14120, - 0x1a098, 0x1d04e, 0x14110, 0x1a08c, 0x14108, 0x1a086, 0x14104, 0x141b0, - 0x14198, 0x1418c, 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0, - 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460, 0x1ca38, 0x1e51e, - 0x12840, 0x19430, 0x12820, 0x196e0, 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, - 0x1cb3c, 0x12c60, 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe, - 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be, 0x12f3c, 0x12fbe, - 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60, 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, - 0x1ed1c, 0x1b420, 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970, - 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660, 0x1db38, 0x1ed9e, - 0x16c40, 0x12420, 0x19218, 0x1c90e, 0x16c20, 0x1b618, 0x16c10, 0x126c0, - 0x19370, 0x1c9bc, 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738, - 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc, 0x16f70, 0x12738, - 0x1939e, 0x16f38, 0x1b79e, 0x16f1c, 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, - 0x1d960, 0x1ecb8, 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918, - 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160, 0x1c8b8, 0x1e45e, - 0x1b360, 0x19130, 0x1c89c, 0x16640, 0x12220, 0x1d99c, 0x1c88e, 0x16620, - 0x12210, 0x1910c, 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8, - 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c, 0x1918e, 0x16718, - 0x1230c, 0x12306, 0x123b8, 0x191de, 0x167b8, 0x1239c, 0x1679c, 0x1238e, - 0x1678e, 0x167de, 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e, - 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102, 0x12140, 0x190b0, - 0x1c85c, 0x16340, 0x12120, 0x19098, 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, - 0x16310, 0x12108, 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc, - 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c, 0x12186, 0x16386, - 0x163dc, 0x163ce, 0x1b0a0, 0x1d858, 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, - 0x1d846, 0x1b084, 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090, - 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084, 0x16184, 0x12082, - 0x120d8, 0x161d8, 0x161cc, 0x161c6, 0x1d82c, 0x1d826, 0x1b042, 0x1902c, - 0x12048, 0x160c8, 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60, - 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18, 0x11410, 0x11408, - 0x116c0, 0x18b70, 0x1c5bc, 0x11660, 0x18b38, 0x1c59e, 0x11630, 0x18b1c, - 0x11618, 0x1160c, 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc, - 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30, 0x1e69c, 0x19a20, - 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c, 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, - 0x1e25e, 0x19b60, 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e, - 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608, 0x11360, 0x189b8, - 0x1c4de, 0x13760, 0x11330, 0x1cdde, 0x13730, 0x19b9c, 0x1898e, 0x13718, - 0x1130c, 0x1370c, 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e, - 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20, 0x1ee98, 0x1f74e, - 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86, 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, - 0x1bb40, 0x19920, 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10, - 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140, 0x188b0, 0x1c45c, - 0x13340, 0x11120, 0x18898, 0x1c44e, 0x17740, 0x13320, 0x19998, 0x1ccce, - 0x17720, 0x1bb98, 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708, - 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce, 0x177b0, 0x13398, - 0x199ce, 0x17798, 0x1bbce, 0x11186, 0x13386, 0x111dc, 0x133dc, 0x111ce, - 0x177dc, 0x133ce, 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88, - 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e, 0x1b9a0, 0x19890, - 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46, 0x1b988, 0x19884, 0x1b984, 0x19882, - 0x1b982, 0x110a0, 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0, - 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084, 0x17388, 0x13184, - 0x11082, 0x13182, 0x110d8, 0x1886e, 0x131d8, 0x110cc, 0x173d8, 0x131cc, - 0x110c6, 0x173cc, 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48, - 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0, 0x19848, 0x1cc26, - 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842, 0x1b8c2, 0x11050, 0x1882c, 0x130d0, - 0x11048, 0x18826, 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042, - 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6, 0x1ee16, 0x1dc22, - 0x1cc16, 0x19824, 0x19822, 0x11028, 0x13068, 0x170e8, 0x11022, 0x13062, - 0x18560, 0x10a40, 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c, - 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30, 0x1859c, 0x10b18, - 0x1858e, 0x10b0c, 0x10b06, 0x10bb8, 0x185de, 0x10b9c, 0x10b8e, 0x10bde, - 0x18d40, 0x1c6b0, 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08, - 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40, 0x10920, 0x1c6dc, - 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce, 0x11b10, 0x10908, 0x18486, 0x11b08, - 0x18d86, 0x10902, 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98, - 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce, 0x11bce, 0x1cea0, - 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c, 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, - 0x18ca0, 0x1c658, 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646, - 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0, 0x18458, 0x119a0, - 0x10890, 0x1c66e, 0x13ba0, 0x11990, 0x18ccc, 0x18446, 0x13b90, 0x19dcc, - 0x10884, 0x13b88, 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8, - 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6, 0x108ee, 0x119ee, - 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48, 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, - 0x1e72c, 0x1ded0, 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42, - 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626, 0x1bdd0, 0x19cc8, - 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42, 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, - 0x1842c, 0x118d0, 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0, - 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2, 0x17bc4, 0x1086c, - 0x118ec, 0x10866, 0x139ec, 0x118e6, 0x17bec, 0x139e6, 0x17be6, 0x1ef28, - 0x1f796, 0x1ef24, 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64, - 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24, 0x1bce8, 0x19c64, - 0x18c22, 0x1bce4, 0x19c62, 0x1bce2, 0x10828, 0x18416, 0x11868, 0x18c36, - 0x138e8, 0x11864, 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2, - 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32, 0x19c34, 0x1bc74, - 0x1bc72, 0x11834, 0x13874, 0x178f4, 0x178f2, 0x10540, 0x10520, 0x18298, - 0x10510, 0x10508, 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc, - 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346, 0x18684, 0x18682, - 0x104a0, 0x18258, 0x10da0, 0x186d8, 0x1824c, 0x10d90, 0x186cc, 0x10d88, - 0x186c6, 0x10d84, 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee, - 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750, 0x1c748, 0x1c744, - 0x1c742, 0x18650, 0x18ed0, 0x1c76c, 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, - 0x18642, 0x18ec2, 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8, - 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2, 0x1046c, 0x10cec, - 0x10466, 0x11dec, 0x10ce6, 0x11de6, 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, - 0x1cf68, 0x1e7b6, 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68, - 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62, 0x19ee2, 0x10428, - 0x18216, 0x10c68, 0x18636, 0x11ce8, 0x10c64, 0x10422, 0x13de8, 0x11ce4, - 0x10c62, 0x13de4, 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4, - 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714, 0x1cf34, 0x1c712, - 0x1df74, 0x1cf32, 0x1df72, 0x18614, 0x18e34, 0x18612, 0x19e74, 0x18e32, - 0x1bef4 - }, { - 0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20, 0x1f518, 0x1fa8e, - 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506, 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, - 0x1d640, 0x1eb30, 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c, - 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de, 0x1ae40, 0x1d730, - 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e, 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, - 0x1ae04, 0x1af60, 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20, - 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06, 0x15f60, 0x1afb8, - 0x1d7de, 0x15f30, 0x1af9c, 0x15f18, 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, - 0x15f9c, 0x15f8e, 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e, - 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902, 0x1d340, 0x1e9b0, - 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce, 0x1d310, 0x1e98c, 0x1d308, 0x1e986, - 0x1d304, 0x1d302, 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce, - 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702, 0x14f40, 0x1a7b0, - 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce, 0x14f10, 0x1a78c, 0x14f08, 0x1a786, - 0x14f04, 0x14fb0, 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc, - 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c, 0x1e888, 0x1f446, - 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8, 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, - 0x1e8c6, 0x1d184, 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc, - 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8, 0x1d1ee, 0x14790, - 0x1a3cc, 0x14788, 0x1a3c6, 0x14784, 0x14782, 0x147d8, 0x1a3ee, 0x147cc, - 0x147c6, 0x147ee, 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842, - 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2, 0x1a1d0, 0x1d0ec, - 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2, 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, - 0x143c4, 0x143c2, 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822, - 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076, 0x1a0e4, 0x1a0e2, - 0x141e8, 0x1a0f6, 0x141e4, 0x141e2, 0x1e814, 0x1e812, 0x1d034, 0x1d032, - 0x1a074, 0x1a072, 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e, - 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502, 0x1cb40, 0x1e5b0, - 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce, 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, - 0x1cb04, 0x1cb02, 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce, - 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702, 0x12f40, 0x197b0, - 0x1cbdc, 0x12f20, 0x19798, 0x1cbce, 0x12f10, 0x1978c, 0x12f08, 0x19786, - 0x12f04, 0x12fb0, 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc, - 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c, 0x169f8, 0x1f688, - 0x1fb46, 0x168fc, 0x1f684, 0x1f682, 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, - 0x1e490, 0x1fb6e, 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84, - 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0, 0x1c990, 0x1e4cc, - 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88, 0x1c984, 0x1db84, 0x1c982, 0x1db82, - 0x193a0, 0x1c9d8, 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc, - 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782, 0x127a0, 0x193d8, - 0x1c9ee, 0x16fa0, 0x12790, 0x193cc, 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, - 0x12784, 0x16f84, 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc, - 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8, 0x1f648, 0x1fb26, - 0x164fc, 0x1f644, 0x1647e, 0x1f642, 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, - 0x1f226, 0x1ecc8, 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c, - 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4, 0x1c8c2, 0x1d9c2, - 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8, 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, - 0x191c2, 0x1b3c2, 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8, - 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec, 0x123e6, 0x167e6, - 0x1f628, 0x1fb16, 0x162fc, 0x1f624, 0x1627e, 0x1f622, 0x1e428, 0x1f216, - 0x1ec68, 0x1f636, 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8, - 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876, 0x1b1e8, 0x1d8f6, - 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8, 0x190f6, 0x163e8, 0x121e4, 0x163e4, - 0x121e2, 0x163e2, 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414, - 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832, 0x1d872, 0x19074, - 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4, 0x161f4, 0x120f2, 0x161f2, 0x1f60a, - 0x1e40a, 0x1ec1a, 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158, - 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284, 0x1e282, 0x1c5a0, - 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc, 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, - 0x18ba0, 0x1c5d8, 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84, - 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc, 0x11788, 0x18bc6, - 0x11784, 0x11782, 0x117d8, 0x18bee, 0x117cc, 0x117c6, 0x117ee, 0x1f350, - 0x1f9ac, 0x135f8, 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342, - 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8, 0x1f366, 0x1e6c4, - 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c, 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, - 0x1e6e6, 0x1cdc4, 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8, - 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2, 0x113d0, 0x189ec, - 0x137d0, 0x113c8, 0x189e6, 0x137c8, 0x19be6, 0x137c4, 0x113c2, 0x137c2, - 0x113ec, 0x137ec, 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4, - 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328, 0x1f996, 0x132fc, - 0x1f768, 0x1fbb6, 0x176fc, 0x1327e, 0x1f764, 0x1f322, 0x1767e, 0x1f762, - 0x1e228, 0x1f116, 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4, - 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464, 0x1dde8, 0x1cce4, - 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2, 0x188e8, 0x1c476, 0x199e8, 0x188e4, - 0x1bbe8, 0x199e4, 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6, - 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4, 0x133e2, 0x177e2, - 0x111f6, 0x133f6, 0x1fb94, 0x172f8, 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, - 0x1f314, 0x1317e, 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634, - 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74, 0x1c432, 0x1dcf4, - 0x1cc72, 0x1dcf2, 0x18874, 0x198f4, 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, - 0x110f4, 0x131f4, 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c, - 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a, 0x1c41a, 0x1cc3a, - 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa, 0x1107a, 0x130fa, 0x171fa, 0x170be, - 0x1e150, 0x1f0ac, 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c, - 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec, 0x185c8, 0x1c2e6, - 0x185c4, 0x185c2, 0x10bd0, 0x185ec, 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, - 0x10bec, 0x10be6, 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2, - 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122, 0x1e362, 0x1c268, - 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4, 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, - 0x18de8, 0x184e4, 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8, - 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6, 0x1f9d4, 0x13af8, - 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e, 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, - 0x13b7e, 0x1f3b2, 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772, - 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2, 0x18474, 0x18cf4, - 0x18472, 0x19df4, 0x18cf2, 0x19df2, 0x108f4, 0x119f4, 0x108f2, 0x13bf4, - 0x119f2, 0x13bf2, 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e, - 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e, 0x1f18a, 0x1f39a, - 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a, 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, - 0x1defa, 0x1843a, 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa, - 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be, 0x178bc, 0x1789e, - 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2, 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, - 0x182e8, 0x1c176, 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2, - 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4, 0x1e092, 0x1e1b2, - 0x1c134, 0x1c374, 0x1c132, 0x1c372, 0x18274, 0x186f4, 0x18272, 0x186f2, - 0x104f4, 0x10df4, 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca, - 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a, 0x1c77a, 0x1823a, - 0x1867a, 0x18efa, 0x1047a, 0x10cfa, 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, - 0x13d1e, 0x11cbe, 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c, - 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8, 0x1be5e, 0x17c9c, - 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c, 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, - 0x18174, 0x18172, 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a, - 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e, 0x13eb8, 0x19f5e, - 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede, 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, - 0x17e8c, 0x17e86, 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e, - 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26, 0x10f5e, 0x11f5c, - 0x11f4e, 0x13f58, 0x19fae, 0x13f4c, 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, - 0x13f26 - }, { - 0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0, 0x1a8f8, 0x1d47e, - 0x150f0, 0x1a87c, 0x15078, 0x1fad0, 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, - 0x1acfc, 0x1fac4, 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec, - 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e, 0x1f5c2, 0x1ebd0, - 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4, 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, - 0x1ebe6, 0x1d7c4, 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4, - 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e, 0x148f0, 0x1a47c, - 0x14878, 0x1a43e, 0x1483c, 0x1fa68, 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, - 0x1a67e, 0x1fa62, 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4, - 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2, 0x1d3e8, 0x1e9f6, - 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6, 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, - 0x1d17e, 0x144f0, 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34, - 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474, 0x1477e, 0x1f472, - 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2, 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, - 0x14278, 0x1a13e, 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a, - 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e, 0x141be, 0x140bc, - 0x1409e, 0x12bc0, 0x195f0, 0x1cafc, 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, - 0x1947c, 0x12878, 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964, - 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8, 0x1f976, 0x12efc, - 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8, 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, - 0x1e5f6, 0x1cbe4, 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0, - 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0, 0x1b478, 0x1da3e, - 0x16870, 0x1b43c, 0x16838, 0x1b41e, 0x1681c, 0x125e0, 0x192f8, 0x1c97e, - 0x16de0, 0x124f0, 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c, - 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e, 0x1fb74, 0x1f932, - 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c, 0x1263e, 0x16e3e, 0x1f274, 0x1277e, - 0x1f6f4, 0x1f272, 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2, - 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2, 0x165c0, 0x1b2f0, - 0x1d97c, 0x164e0, 0x1b278, 0x1d93e, 0x16470, 0x1b23c, 0x16438, 0x1b21e, - 0x1641c, 0x1640e, 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678, - 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c, 0x1fb3a, 0x1677c, - 0x1233e, 0x1673e, 0x1f23a, 0x1f67a, 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, - 0x191fa, 0x162e0, 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e, - 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c, 0x1633c, 0x1211e, - 0x1631e, 0x121be, 0x163be, 0x16170, 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, - 0x1610e, 0x120bc, 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c, - 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0, 0x18af8, 0x1c57e, - 0x114f0, 0x18a7c, 0x11478, 0x18a3e, 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, - 0x18b7e, 0x1f8b2, 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4, - 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0, 0x19af0, 0x1cd7c, - 0x134e0, 0x19a78, 0x1cd3e, 0x13470, 0x19a3c, 0x13438, 0x19a1e, 0x1341c, - 0x1340e, 0x112f0, 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e, - 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba, 0x1377c, 0x1133e, - 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a, 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, - 0x1bae0, 0x1dd78, 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38, - 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c, 0x132e0, 0x19978, - 0x1ccbe, 0x176e0, 0x13270, 0x1993c, 0x17670, 0x1bb3c, 0x1991e, 0x17638, - 0x1321c, 0x1761c, 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c, - 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e, 0x111be, 0x133be, - 0x177be, 0x172c0, 0x1b970, 0x1dcbc, 0x17260, 0x1b938, 0x1dc9e, 0x17230, - 0x1b91c, 0x17218, 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370, - 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e, 0x1730e, 0x110bc, - 0x131bc, 0x1109e, 0x173bc, 0x1319e, 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, - 0x17130, 0x1b89c, 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e, - 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e, 0x130de, 0x171de, - 0x170b0, 0x1b85c, 0x17098, 0x1b84e, 0x1708c, 0x17086, 0x1305c, 0x170dc, - 0x1304e, 0x170ce, 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e, - 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e, 0x10a3c, 0x10a1e, - 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a, 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, - 0x1c6be, 0x11a70, 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978, - 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e, 0x109be, 0x11bbe, - 0x13ac0, 0x19d70, 0x1cebc, 0x13a60, 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, - 0x13a18, 0x19d0e, 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938, - 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e, 0x108bc, 0x119bc, - 0x1089e, 0x13bbc, 0x1199e, 0x13b9e, 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, - 0x1bd30, 0x1de9c, 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08, - 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60, 0x13930, 0x19c9c, - 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18, 0x1390c, 0x17b0c, 0x13906, 0x17b06, - 0x118b8, 0x18c5e, 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c, - 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde, 0x17940, 0x1bcb0, - 0x1de5c, 0x17920, 0x1bc98, 0x1de4e, 0x17910, 0x1bc8c, 0x17908, 0x1bc86, - 0x17904, 0x17902, 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998, - 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc, 0x1184e, 0x179dc, - 0x138ce, 0x179ce, 0x178a0, 0x1bc58, 0x1de2e, 0x17890, 0x1bc4c, 0x17888, - 0x1bc46, 0x17884, 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc, - 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850, 0x1bc2c, 0x17848, - 0x1bc26, 0x17844, 0x17842, 0x1382c, 0x1786c, 0x13826, 0x17866, 0x17828, - 0x1bc16, 0x17824, 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c, - 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e, 0x10d1c, 0x10d0e, - 0x104bc, 0x10dbc, 0x1049e, 0x10d9e, 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, - 0x18e9c, 0x11d18, 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8, - 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde, 0x11dde, 0x13d40, - 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98, 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, - 0x19e86, 0x13d04, 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e, - 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c, 0x11cdc, 0x10c4e, - 0x13ddc, 0x11cce, 0x13dce, 0x1bea0, 0x1df58, 0x1efae, 0x1be90, 0x1df4c, - 0x1be88, 0x1df46, 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0, - 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88, 0x13c84, 0x17d84, - 0x13c82, 0x17d82, 0x11c58, 0x18e2e, 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, - 0x11c46, 0x17dcc, 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee, - 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42, 0x13c50, 0x19e2c, - 0x17cd0, 0x13c48, 0x19e26, 0x17cc8, 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, - 0x11c2c, 0x13c6c, 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16, - 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24, 0x17c64, 0x13c22, - 0x17c62, 0x11c16, 0x13c36, 0x17c76, 0x1be14, 0x1be12, 0x13c14, 0x17c34, - 0x13c12, 0x17c32, 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e, - 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e, 0x10e8c, 0x10e86, - 0x1065c, 0x10edc, 0x1064e, 0x10ece, 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, - 0x18f4c, 0x11e88, 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8, - 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e, 0x11eee, 0x19f50, - 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44, 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, - 0x19f6c, 0x18f26, 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c, - 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8, 0x1efd6, 0x1dfa4, - 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68, 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, - 0x11e28, 0x18f16, 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4, - 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6, 0x1df94, 0x1df92, - 0x19f14, 0x1bf34, 0x19f12, 0x1bf32, 0x11e14, 0x13e34, 0x11e12, 0x17e74, - 0x13e32, 0x17e72, 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a, - 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746, 0x1032e, 0x1076e, - 0x10f50, 0x187ac, 0x10f48, 0x187a6, 0x10f44, 0x10f42, 0x1072c, 0x10f6c, - 0x10726, 0x10f66, 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796, - 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716, 0x10f36, 0x11f76, - 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4, 0x18f92, 0x19fb2, 0x10f14, 0x11f34, - 0x10f12, 0x13f74, 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a, - 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6, 0x107a4, 0x107a2, - 0x10396, 0x107b6, 0x187d4, 0x187d2, 0x10794, 0x10fb4, 0x10792, 0x10fb2, - 0x1c7ea - }}; - - static int ERROR_LEVEL[][] = - {{ - 27, 917 - }, { - 522, 568, 723, 809 - }, { - 237, 308, 436, 284, 646, 653, 428, 379 - }, { - 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65 - }, { - 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517, - 273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410 - }, { - 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612, - 723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184, - 440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, - 648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543 - }, { - 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415, - 822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704, - 516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, - 193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776, - 171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898, - 784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, - 157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34, - 211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539 - }, { - 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720, - 858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757, - 710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, - 439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884, - 315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521, - 307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, - 637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90, - 2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134, - 628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, - 722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621, - 895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528, - 503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, - 73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754, - 605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532, - 609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, - 404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10 - }, { - 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492, - 197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781, - 846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, - 539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41, - 542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741, - 290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, - 808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258, - 240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303, - 570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, - 40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785, - 288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543, - 152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, - 669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578, - 37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911, - 283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, - 842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729, - 624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772, - 677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, - 618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45, - 787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905, - 789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, - 242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808, - 851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249, - 321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, - 660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437, - 375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842, - 37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, - 342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656, - 447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433, - 717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, - 407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647, - 63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 - }}; - - /** Holds value of property outBits. */ - private byte[] outBits; - - /** Holds value of property bitColumns. */ - private int bitColumns; - - /** Holds value of property codeRows. */ - private int codeRows; - - /** Holds value of property codeColumns. */ - private int codeColumns; - - /** Holds value of property codewords. */ - private int[] codewords = new int[MAX_DATA_CODEWORDS + 2]; - - /** Holds value of property lenCodewords. */ - private int lenCodewords; - - /** Holds value of property errorLevel. */ - private int errorLevel; - - /** Holds value of property text. */ - private byte[] text; - - /** Holds value of property options. */ - private int options; - - /** Holds value of property aspectRatio. */ - private float aspectRatio; - - /** Holds value of property yHeight. */ - private float yHeight; - - protected static class Segment { - public char type; - public int start; - public int end; - - public Segment(char type, int start, int end) { - this.type = type; - this.start = start; - this.end = end; - } - } - - protected static class SegmentList { - protected ArrayList list = new ArrayList(); - - public void add(char type, int start, int end) { - list.add(new Segment(type, start, end)); - } - - public Segment get(int idx) { - if (idx < 0 || idx >= list.size()) - return null; - return (Segment)list.get(idx); - } - - public void remove(int idx) { - if (idx < 0 || idx >= list.size()) - return; - list.remove(idx); - } - - public int size() { - return list.size(); - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BarcodePostnet.java b/src/main/java/com/lowagie/text/pdf/BarcodePostnet.java deleted file mode 100644 index 5befa67..0000000 --- a/src/main/java/com/lowagie/text/pdf/BarcodePostnet.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; -import com.lowagie.text.Rectangle; -import java.awt.Color; -import java.awt.Image; -import java.awt.Canvas; -import java.awt.image.MemoryImageSource; - -/** Implements the Postnet and Planet barcodes. The default parameters are: - *

- *n = 72f / 22f; // distance between bars
- *x = 0.02f * 72f; // bar width
- *barHeight = 0.125f * 72f; // height of the tall bars
- *size = 0.05f * 72f; // height of the short bars
- *codeType = POSTNET; // type of code
- * 
- * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BarcodePostnet extends Barcode{ - - /** The bars for each character. - */ - static byte BARS[][] = - { - {1,1,0,0,0}, - {0,0,0,1,1}, - {0,0,1,0,1}, - {0,0,1,1,0}, - {0,1,0,0,1}, - {0,1,0,1,0}, - {0,1,1,0,0}, - {1,0,0,0,1}, - {1,0,0,1,0}, - {1,0,1,0,0} - }; - - /** Creates new BarcodePostnet */ - public BarcodePostnet() { - n = 72f / 22f; // distance between bars - x = 0.02f * 72f; // bar width - barHeight = 0.125f * 72f; // height of the tall bars - size = 0.05f * 72f; // height of the short bars - codeType = POSTNET; // type of code - } - - /** Creates the bars for Postnet. - * @param text the code to be created without checksum - * @return the bars - */ - public static byte[] getBarsPostnet(String text) { - int total = 0; - for (int k = text.length() - 1; k >= 0; --k) { - int n = text.charAt(k) - '0'; - total += n; - } - text += (char)(((10 - (total % 10)) % 10) + '0'); - byte bars[] = new byte[text.length() * 5 + 2]; - bars[0] = 1; - bars[bars.length - 1] = 1; - for (int k = 0; k < text.length(); ++k) { - int c = text.charAt(k) - '0'; - System.arraycopy(BARS[c], 0, bars, k * 5 + 1, 5); - } - return bars; - } - - /** Gets the maximum area that the barcode and the text, if - * any, will occupy. The lower left corner is always (0, 0). - * @return the size the barcode occupies. - */ - public Rectangle getBarcodeSize() { - float width = ((code.length() + 1) * 5 + 1) * n + x; - return new Rectangle(width, barHeight); - } - - /** Places the barcode in a PdfContentByte. The - * barcode is always placed at coodinates (0, 0). Use the - * translation matrix to move it elsewhere.

- * The bars and text are written in the following colors:

- *

- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *

barColor

textColor

Result

null

null

bars and text painted with current fill color

barColor

null

bars and text painted with barColor

null

textColor

bars painted with current color
text painted with textColor

barColor

textColor

bars painted with barColor
text painted with textColor

- * @param cb the PdfContentByte where the barcode will be placed - * @param barColor the color of the bars. It can be null - * @param textColor the color of the text. It can be null - * @return the dimensions the barcode occupies - */ - public Rectangle placeBarcode(PdfContentByte cb, Color barColor, Color textColor) { - if (barColor != null) - cb.setColorFill(barColor); - byte bars[] = getBarsPostnet(code); - byte flip = 1; - if (codeType == PLANET) { - flip = 0; - bars[0] = 0; - bars[bars.length - 1] = 0; - } - float startX = 0; - for (int k = 0; k < bars.length; ++k) { - cb.rectangle(startX, 0, x - inkSpreading, bars[k] == flip ? barHeight : size); - startX += n; - } - cb.fill(); - return getBarcodeSize(); - } - - /** Creates a java.awt.Image. This image only - * contains the bars without any text. - * @param foreground the color of the bars - * @param background the color of the background - * @return the image - * - */ - public java.awt.Image createAwtImage(Color foreground, Color background) { - int f = foreground.getRGB(); - int g = background.getRGB(); - Canvas canvas = new Canvas(); - int barWidth = (int)x; - if (barWidth <= 0) - barWidth = 1; - int barDistance = (int)n; - if (barDistance <= barWidth) - barDistance = barWidth + 1; - int barShort = (int)size; - if (barShort <= 0) - barShort = 1; - int barTall = (int)barHeight; - if (barTall <= barShort) - barTall = barShort + 1; - int width = ((code.length() + 1) * 5 + 1) * barDistance + barWidth; - int pix[] = new int[width * barTall]; - byte bars[] = getBarsPostnet(code); - byte flip = 1; - if (codeType == PLANET) { - flip = 0; - bars[0] = 0; - bars[bars.length - 1] = 0; - } - int idx = 0; - for (int k = 0; k < bars.length; ++k) { - boolean dot = (bars[k] == flip); - for (int j = 0; j < barDistance; ++j) { - pix[idx + j] = ((dot && j < barWidth) ? f : g); - } - idx += barDistance; - } - int limit = width * (barTall - barShort); - for (int k = width; k < limit; k += width) - System.arraycopy(pix, 0, pix, k, width); - idx = limit; - for (int k = 0; k < bars.length; ++k) { - for (int j = 0; j < barDistance; ++j) { - pix[idx + j] = ((j < barWidth) ? f : g); - } - idx += barDistance; - } - for (int k = limit + width; k < pix.length; k += width) - System.arraycopy(pix, limit, pix, k, width); - Image img = canvas.createImage(new MemoryImageSource(width, barTall, pix, 0, width)); - - return img; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/BaseField.java b/src/main/java/com/lowagie/text/pdf/BaseField.java deleted file mode 100644 index 8817bbd..0000000 --- a/src/main/java/com/lowagie/text/pdf/BaseField.java +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; -import com.lowagie.text.Element; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Rectangle; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.HashMap; - -/** Common field variables. - * @author Paulo Soares (psoares@consiste.pt) - */ -public abstract class BaseField { - - /** A thin border with 1 point width. */ - public static final float BORDER_WIDTH_THIN = 1; - /** A medium border with 2 point width. */ - public static final float BORDER_WIDTH_MEDIUM = 2; - /** A thick border with 3 point width. */ - public static final float BORDER_WIDTH_THICK = 3; - /** The field is visible. */ - public static final int VISIBLE = 0; - /** The field is hidden. */ - public static final int HIDDEN = 1; - /** The field is visible but does not print. */ - public static final int VISIBLE_BUT_DOES_NOT_PRINT = 2; - /** The field is hidden but is printable. */ - public static final int HIDDEN_BUT_PRINTABLE = 3; - /** The user may not change the value of the field. */ - public static final int READ_ONLY = 1; - /** The field must have a value at the time it is exported by a submit-form - * action. - */ - public static final int REQUIRED = 2; - /** The field may contain multiple lines of text. - * This flag is only meaningful with text fields. - */ - public static final int MULTILINE = 4; - /** The field will not scroll (horizontally for single-line - * fields, vertically for multiple-line fields) to accommodate more text - * than will fit within its annotation rectangle. Once the field is full, no - * further text will be accepted. - */ - public static final int DO_NOT_SCROLL = 8; - /** The field is intended for entering a secure password that should - * not be echoed visibly to the screen. - */ - public static final int PASSWORD = 16; - /** The text entered in the field represents the pathname of - * a file whose contents are to be submitted as the value of the field. - */ - public static final int FILE_SELECTION = 32; - /** The text entered in the field will not be spell-checked. - * This flag is meaningful only in text fields and in combo - * fields with the EDIT flag set. - */ - public static final int DO_NOT_SPELL_CHECK = 64; - /** If set the combo box includes an editable text box as well as a drop list; if - * clear, it includes only a drop list. - * This flag is only meaningful with combo fields. - */ - public static final int EDIT = 128; - - /** - * combo box flag. - */ - public static final int COMB = 256; - - protected float borderWidth = BORDER_WIDTH_THIN; - protected int borderStyle = PdfBorderDictionary.STYLE_SOLID; - protected Color borderColor; - protected Color backgroundColor; - protected Color textColor; - protected BaseFont font; - protected float fontSize = 0; - protected int alignment = Element.ALIGN_LEFT; - protected PdfWriter writer; - protected String text; - protected Rectangle box; - - /** Holds value of property rotation. */ - protected int rotation = 0; - - /** Holds value of property visibility. */ - protected int visibility; - - /** Holds value of property fieldName. */ - protected String fieldName; - - /** Holds value of property options. */ - protected int options; - - /** Holds value of property maxCharacterLength. */ - protected int maxCharacterLength; - - private final static HashMap fieldKeys = new HashMap(); - - static { - fieldKeys.putAll(PdfCopyFieldsImp.fieldKeys); - fieldKeys.put(PdfName.T, new Integer(1)); - } - /** Creates a new TextField. - * @param writer the document PdfWriter - * @param box the field location and dimensions - * @param fieldName the field name. If null only the widget keys - * will be included in the field allowing it to be used as a kid field. - */ - public BaseField(PdfWriter writer, Rectangle box, String fieldName) { - this.writer = writer; - this.box = box; - this.fieldName = fieldName; - } - - protected BaseFont getRealFont() throws IOException, DocumentException { - if (font == null) - return BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, false); - else - return font; - } - - protected PdfAppearance getBorderAppearance() throws IOException, DocumentException { - PdfAppearance app = new PdfContentByte(writer).createAppearance(box.width(), box.height()); - switch (rotation) { - case 90: - app.setMatrix(0, 1, -1, 0, box.height(), 0); - break; - case 180: - app.setMatrix(-1, 0, 0, -1, box.width(), box.height()); - break; - case 270: - app.setMatrix(0, -1, 1, 0, 0, box.width()); - break; - } - // background - if (backgroundColor != null) { - app.setColorFill(backgroundColor); - app.rectangle(0, 0, box.width(), box.height()); - app.fill(); - } - // border - if (borderStyle == PdfBorderDictionary.STYLE_UNDERLINE) { - if (borderWidth != 0 && borderColor != null) { - app.setColorStroke(borderColor); - app.setLineWidth(borderWidth); - app.moveTo(0, borderWidth / 2); - app.lineTo(box.width(), borderWidth / 2); - app.stroke(); - } - } - else if (borderStyle == PdfBorderDictionary.STYLE_BEVELED) { - if (borderWidth != 0 && borderColor != null) { - app.setColorStroke(borderColor); - app.setLineWidth(borderWidth); - app.rectangle(borderWidth / 2, borderWidth / 2, box.width() - borderWidth, box.height() - borderWidth); - app.stroke(); - } - // beveled - Color actual = backgroundColor; - if (actual == null) - actual = Color.white; - app.setGrayFill(1); - drawTopFrame(app); - app.setColorFill(actual.darker()); - drawBottomFrame(app); - } - else if (borderStyle == PdfBorderDictionary.STYLE_INSET) { - if (borderWidth != 0 && borderColor != null) { - app.setColorStroke(borderColor); - app.setLineWidth(borderWidth); - app.rectangle(borderWidth / 2, borderWidth / 2, box.width() - borderWidth, box.height() - borderWidth); - app.stroke(); - } - // inset - app.setGrayFill(0.5f); - drawTopFrame(app); - app.setGrayFill(0.75f); - drawBottomFrame(app); - } - else { - if (borderWidth != 0 && borderColor != null) { - if (borderStyle == PdfBorderDictionary.STYLE_DASHED) - app.setLineDash(3, 0); - app.setColorStroke(borderColor); - app.setLineWidth(borderWidth); - app.rectangle(borderWidth / 2, borderWidth / 2, box.width() - borderWidth, box.height() - borderWidth); - app.stroke(); - if ((options & COMB) != 0 && maxCharacterLength > 1) { - float step = box.width() / maxCharacterLength; - float yb = borderWidth / 2; - float yt = box.height() - borderWidth / 2; - for (int k = 1; k < maxCharacterLength; ++k) { - float x = step * k; - app.moveTo(x, yb); - app.lineTo(x, yt); - } - app.stroke(); - } - } - } - return app; - } - - protected static ArrayList getHardBreaks(String text) { - ArrayList arr = new ArrayList(); - char cs[] = text.toCharArray(); - int len = cs.length; - StringBuffer buf = new StringBuffer(); - for (int k = 0; k < len; ++k) { - char c = cs[k]; - if (c == '\r') { - if (k + 1 < len && cs[k + 1] == '\n') - ++k; - arr.add(buf.toString()); - buf = new StringBuffer(); - } - else if (c == '\n') { - arr.add(buf.toString()); - buf = new StringBuffer(); - } - else - buf.append(c); - } - arr.add(buf.toString()); - return arr; - } - - protected static void trimRight(StringBuffer buf) { - int len = buf.length(); - while (true) { - if (len == 0) - return; - if (buf.charAt(--len) != ' ') - return; - buf.setLength(len); - } - } - - protected static ArrayList breakLines(ArrayList breaks, BaseFont font, float fontSize, float width) { - ArrayList lines = new ArrayList(); - StringBuffer buf = new StringBuffer(); - for (int ck = 0; ck < breaks.size(); ++ck) { - buf.setLength(0); - float w = 0; - char cs[] = ((String)breaks.get(ck)).toCharArray(); - int len = cs.length; - // 0 inline first, 1 inline, 2 spaces - int state = 0; - int lastspace = -1; - char c = 0; - int refk = 0; - for (int k = 0; k < len; ++k) { - c = cs[k]; - switch (state) { - case 0: - w += font.getWidthPoint(c, fontSize); - buf.append(c); - if (w > width) { - w = 0; - if (buf.length() > 1) { - --k; - buf.setLength(buf.length() - 1); - } - lines.add(buf.toString()); - buf.setLength(0); - refk = k; - if (c == ' ') - state = 2; - else - state = 1; - } - else { - if (c != ' ') - state = 1; - } - break; - case 1: - w += font.getWidthPoint(c, fontSize); - buf.append(c); - if (c == ' ') - lastspace = k; - if (w > width) { - w = 0; - if (lastspace >= 0) { - k = lastspace; - buf.setLength(lastspace - refk); - trimRight(buf); - lines.add(buf.toString()); - buf.setLength(0); - refk = k; - lastspace = -1; - state = 2; - } - else { - if (buf.length() > 1) { - --k; - buf.setLength(buf.length() - 1); - } - lines.add(buf.toString()); - buf.setLength(0); - refk = k; - if (c == ' ') - state = 2; - } - } - break; - case 2: - if (c != ' ') { - w = 0; - --k; - state = 1; - } - break; - } - } - trimRight(buf); - lines.add(buf.toString()); - } - return lines; - } - - private void drawTopFrame(PdfAppearance app) { - app.moveTo(borderWidth, borderWidth); - app.lineTo(borderWidth, box.height() - borderWidth); - app.lineTo(box.width() - borderWidth, box.height() - borderWidth); - app.lineTo(box.width() - 2 * borderWidth, box.height() - 2 * borderWidth); - app.lineTo(2 * borderWidth, box.height() - 2 * borderWidth); - app.lineTo(2 * borderWidth, 2 * borderWidth); - app.lineTo(borderWidth, borderWidth); - app.fill(); - } - - private void drawBottomFrame(PdfAppearance app) { - app.moveTo(borderWidth, borderWidth); - app.lineTo(box.width() - borderWidth, borderWidth); - app.lineTo(box.width() - borderWidth, box.height() - borderWidth); - app.lineTo(box.width() - 2 * borderWidth, box.height() - 2 * borderWidth); - app.lineTo(box.width() - 2 * borderWidth, 2 * borderWidth); - app.lineTo(2 * borderWidth, 2 * borderWidth); - app.lineTo(borderWidth, borderWidth); - app.fill(); - } - /** Gets the border width in points. - * @return the border width in points - */ - public float getBorderWidth() { - return this.borderWidth; - } - - /** Sets the border width in points. To eliminate the border - * set the border color to null. - * @param borderWidth the border width in points - */ - public void setBorderWidth(float borderWidth) { - this.borderWidth = borderWidth; - } - - /** Gets the border style. - * @return the border style - */ - public int getBorderStyle() { - return this.borderStyle; - } - - /** Sets the border style. The styles are found in PdfBorderDictionary - * and can be STYLE_SOLID, STYLE_DASHED, - * STYLE_BEVELED, STYLE_INSET and - * STYLE_UNDERLINE. - * @param borderStyle the border style - */ - public void setBorderStyle(int borderStyle) { - this.borderStyle = borderStyle; - } - - /** Gets the border color. - * @return the border color - */ - public Color getBorderColor() { - return this.borderColor; - } - - /** Sets the border color. Set to null to remove - * the border. - * @param borderColor the border color - */ - public void setBorderColor(Color borderColor) { - this.borderColor = borderColor; - } - - /** Gets the background color. - * @return the background color - */ - public Color getBackgroundColor() { - return this.backgroundColor; - } - - /** Sets the background color. Set to null for - * transparent background. - * @param backgroundColor the background color - */ - public void setBackgroundColor(Color backgroundColor) { - this.backgroundColor = backgroundColor; - } - - /** Gets the text color. - * @return the text color - */ - public Color getTextColor() { - return this.textColor; - } - - /** Sets the text color. If null the color used - * will be black. - * @param textColor the text color - */ - public void setTextColor(Color textColor) { - this.textColor = textColor; - } - - /** Gets the text font. - * @return the text font - */ - public BaseFont getFont() { - return this.font; - } - - /** Sets the text font. If null then Helvetica - * will be used. - * @param font the text font - */ - public void setFont(BaseFont font) { - this.font = font; - } - - /** Gets the font size. - * @return the font size - */ - public float getFontSize() { - return this.fontSize; - } - - /** Sets the font size. If 0 then auto-sizing will be used but - * only for text fields. - * @param fontSize the font size - */ - public void setFontSize(float fontSize) { - this.fontSize = fontSize; - } - - /** Gets the text horizontal alignment. - * @return the text horizontal alignment - */ - public int getAlignment() { - return this.alignment; - } - - /** Sets the text horizontal alignment. It can be Element.ALIGN_LEFT, - * Element.ALIGN_CENTER and Element.ALIGN_RIGHT. - * @param alignment the text horizontal alignment - */ - public void setAlignment(int alignment) { - this.alignment = alignment; - } - - /** Gets the text. - * @return the text - */ - public String getText() { - return this.text; - } - - /** Sets the text for text fields. - * @param text the text - */ - public void setText(String text) { - this.text = text; - } - - /** Gets the field dimension and position. - * @return the field dimension and position - */ - public Rectangle getBox() { - return this.box; - } - - /** Sets the field dimension and position. - * @param box the field dimension and position - */ - public void setBox(Rectangle box) { - this.box = box; - } - - /** Gets the field rotation. - * @return the field rotation - */ - public int getRotation() { - return this.rotation; - } - - /** Sets the field rotation. This value should be the same as - * the page rotation where the field will be shown. - * @param rotation the field rotation - */ - public void setRotation(int rotation) { - if (rotation % 90 != 0) - throw new IllegalArgumentException("Rotation must be a multiple of 90."); - rotation %= 360; - if (rotation < 0) - rotation += 360; - this.rotation = rotation; - } - - /** Convenience method to set the field rotation the same as the - * page rotation. - * @param page the page - */ - public void setRotationFromPage(Rectangle page) { - setRotation(page.getRotation()); - } - - /** Gets the field visibility flag. - * @return the field visibility flag - */ - public int getVisibility() { - return this.visibility; - } - - /** Sets the field visibility flag. This flags can be one of - * VISIBLE, HIDDEN, VISIBLE_BUT_DOES_NOT_PRINT - * and HIDDEN_BUT_PRINTABLE. - * @param visibility field visibility flag - */ - public void setVisibility(int visibility) { - this.visibility = visibility; - } - - /** Gets the field name. - * @return the field name - */ - public String getFieldName() { - return this.fieldName; - } - - /** Sets the field name. - * @param fieldName the field name. If null only the widget keys - * will be included in the field allowing it to be used as a kid field. - */ - public void setFieldName(String fieldName) { - this.fieldName = fieldName; - } - - /** Gets the option flags. - * @return the option flags - */ - public int getOptions() { - return this.options; - } - - /** Sets the option flags. The option flags can be a combination by oring of - * READ_ONLY, REQUIRED, - * MULTILINE, DO_NOT_SCROLL, - * PASSWORD, FILE_SELECTION, - * DO_NOT_SPELL_CHECK and EDIT. - * @param options the option flags - */ - public void setOptions(int options) { - this.options = options; - } - - /** Gets the maximum length of the field’s text, in characters. - * @return the maximum length of the field’s text, in characters. - */ - public int getMaxCharacterLength() { - return this.maxCharacterLength; - } - - /** Sets the maximum length of the field’s text, in characters. - * It is only meaningful for text fields. - * @param maxCharacterLength the maximum length of the field’s text, in characters - */ - public void setMaxCharacterLength(int maxCharacterLength) { - this.maxCharacterLength = maxCharacterLength; - } - - /** - * Getter for property writer. - * @return Value of property writer. - */ - public PdfWriter getWriter() { - return writer; - } - - /** - * Setter for property writer. - * @param writer New value of property writer. - */ - public void setWriter(PdfWriter writer) { - this.writer = writer; - } - - /** - * Moves the field keys from from to to. The moved keys - * are removed from from. - * @param from the source - * @param to the destination. It may be null - */ - public static void moveFields(PdfDictionary from, PdfDictionary to) { - for (Iterator i = from.getKeys().iterator(); i.hasNext();) { - PdfName key = (PdfName)i.next(); - if (fieldKeys.containsKey(key)) { - if (to != null) - to.put(key, from.get(key)); - i.remove(); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/BaseFont.java b/src/main/java/com/lowagie/text/pdf/BaseFont.java deleted file mode 100644 index a393e38..0000000 --- a/src/main/java/com/lowagie/text/pdf/BaseFont.java +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * $Id: BaseFont.java,v 1.68 2006/02/23 16:45:48 psoares33 Exp $ - * $Name: $ - * - * Copyright 2000, 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.*; -import com.lowagie.text.DocumentException; -import java.util.HashMap; -import java.util.ArrayList; -import java.util.Iterator; - -/** - * Base class for the several font types supported - * - * @author Paulo Soares (psoares@consiste.pt) - */ - -public abstract class BaseFont { - - /** This is a possible value of a base 14 type 1 font */ - public static final String COURIER = "Courier"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String COURIER_BOLD = "Courier-Bold"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String COURIER_OBLIQUE = "Courier-Oblique"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String COURIER_BOLDOBLIQUE = "Courier-BoldOblique"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String HELVETICA = "Helvetica"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String HELVETICA_BOLD = "Helvetica-Bold"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String HELVETICA_OBLIQUE = "Helvetica-Oblique"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String HELVETICA_BOLDOBLIQUE = "Helvetica-BoldOblique"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String SYMBOL = "Symbol"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String TIMES_ROMAN = "Times-Roman"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String TIMES_BOLD = "Times-Bold"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String TIMES_ITALIC = "Times-Italic"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String TIMES_BOLDITALIC = "Times-BoldItalic"; - - /** This is a possible value of a base 14 type 1 font */ - public static final String ZAPFDINGBATS = "ZapfDingbats"; - - /** The maximum height above the baseline reached by glyphs in this - * font, excluding the height of glyphs for accented characters. - */ - public static final int ASCENT = 1; - /** The y coordinate of the top of flat capital letters, measured from - * the baseline. - */ - public static final int CAPHEIGHT = 2; - /** The maximum depth below the baseline reached by glyphs in this - * font. The value is a negative number. - */ - public static final int DESCENT = 3; - /** The angle, expressed in degrees counterclockwise from the vertical, - * of the dominant vertical strokes of the font. The value is - * negative for fonts that slope to the right, as almost all italic fonts do. - */ - public static final int ITALICANGLE = 4; - /** The lower left x glyph coordinate. - */ - public static final int BBOXLLX = 5; - /** The lower left y glyph coordinate. - */ - public static final int BBOXLLY = 6; - /** The upper right x glyph coordinate. - */ - public static final int BBOXURX = 7; - /** The upper right y glyph coordinate. - */ - public static final int BBOXURY = 8; - - /** java.awt.Font property */ - public static final int AWT_ASCENT = 9; - /** java.awt.Font property */ - public static final int AWT_DESCENT = 10; - /** java.awt.Font property */ - public static final int AWT_LEADING = 11; - /** java.awt.Font property */ - public static final int AWT_MAXADVANCE = 12; - - /** The font is Type 1. - */ - public static final int FONT_TYPE_T1 = 0; - /** The font is True Type with a standard encoding. - */ - public static final int FONT_TYPE_TT = 1; - /** The font is CJK. - */ - public static final int FONT_TYPE_CJK = 2; - /** The font is True Type with a Unicode encoding. - */ - public static final int FONT_TYPE_TTUNI = 3; - /** A font already inside the document. - */ - public static final int FONT_TYPE_DOCUMENT = 4; - /** A Type3 font. - */ - public static final int FONT_TYPE_T3 = 5; - /** The Unicode encoding with horizontal writing. - */ - public static final String IDENTITY_H = "Identity-H"; - /** The Unicode encoding with vertical writing. - */ - public static final String IDENTITY_V = "Identity-V"; - - /** A possible encoding. */ - public static final String CP1250 = "Cp1250"; - - /** A possible encoding. */ - public static final String CP1252 = "Cp1252"; - - /** A possible encoding. */ - public static final String CP1257 = "Cp1257"; - - /** A possible encoding. */ - public static final String WINANSI = "Cp1252"; - - /** A possible encoding. */ - public static final String MACROMAN = "MacRoman"; - - public static final int[] CHAR_RANGE_LATIN = {0, 0x17f, 0x2000, 0x206f, 0x20a0, 0x20cf, 0xfb00, 0xfb06}; - public static final int[] CHAR_RANGE_ARABIC = {0, 0x7f, 0x0600, 0x067f, 0x20a0, 0x20cf, 0xfb50, 0xfbff, 0xfe70, 0xfeff}; - public static final int[] CHAR_RANGE_HEBREW = {0, 0x7f, 0x0590, 0x05ff, 0x20a0, 0x20cf, 0xfb1d, 0xfb4f}; - public static final int[] CHAR_RANGE_CYRILLIC = {0, 0x7f, 0x0400, 0x052f, 0x2000, 0x206f, 0x20a0, 0x20cf}; - -/** if the font has to be embedded */ - public static final boolean EMBEDDED = true; - -/** if the font doesn't have to be embedded */ - public static final boolean NOT_EMBEDDED = false; -/** if the font has to be cached */ - public static final boolean CACHED = true; -/** if the font doesn't have to be cached */ - public static final boolean NOT_CACHED = false; - - /** The path to the font resources. */ - public static final String RESOURCE_PATH = "com/lowagie/text/pdf/fonts/"; - /** The fake CID code that represents a newline. */ - public static final char CID_NEWLINE = '\u7fff'; - - protected ArrayList subsetRanges; - /** The font type. - */ - int fontType; -/** a not defined character in a custom PDF encoding */ - public static final String notdef = ".notdef"; - -/** table of characters widths for this encoding */ - protected int widths[] = new int[256]; - -/** encoding names */ - protected String differences[] = new String[256]; -/** same as differences but with the unicode codes */ - protected char unicodeDifferences[] = new char[256]; - - protected int charBBoxes[][] = new int[256][]; -/** encoding used with this font */ - protected String encoding; - -/** true if the font is to be embedded in the PDF */ - protected boolean embedded; - -/** - * true if the font must use it's built in encoding. In that case the - * encoding is only used to map a char to the position inside - * the font, not to the expected char name. - */ - protected boolean fontSpecific = true; - -/** cache for the fonts already used. */ - protected static HashMap fontCache = new HashMap(); - -/** list of the 14 built in fonts. */ - protected static final HashMap BuiltinFonts14 = new HashMap(); - - /** Forces the output of the width array. Only matters for the 14 - * built-in fonts. - */ - protected boolean forceWidthsOutput = false; - - /** Converts char directly to byte - * by casting. - */ - protected boolean directTextToByte = false; - - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. - */ - protected boolean subset = true; - - protected boolean fastWinansi = false; - - static { - BuiltinFonts14.put(COURIER, PdfName.COURIER); - BuiltinFonts14.put(COURIER_BOLD, PdfName.COURIER_BOLD); - BuiltinFonts14.put(COURIER_BOLDOBLIQUE, PdfName.COURIER_BOLDOBLIQUE); - BuiltinFonts14.put(COURIER_OBLIQUE, PdfName.COURIER_OBLIQUE); - BuiltinFonts14.put(HELVETICA, PdfName.HELVETICA); - BuiltinFonts14.put(HELVETICA_BOLD, PdfName.HELVETICA_BOLD); - BuiltinFonts14.put(HELVETICA_BOLDOBLIQUE, PdfName.HELVETICA_BOLDOBLIQUE); - BuiltinFonts14.put(HELVETICA_OBLIQUE, PdfName.HELVETICA_OBLIQUE); - BuiltinFonts14.put(SYMBOL, PdfName.SYMBOL); - BuiltinFonts14.put(TIMES_ROMAN, PdfName.TIMES_ROMAN); - BuiltinFonts14.put(TIMES_BOLD, PdfName.TIMES_BOLD); - BuiltinFonts14.put(TIMES_BOLDITALIC, PdfName.TIMES_BOLDITALIC); - BuiltinFonts14.put(TIMES_ITALIC, PdfName.TIMES_ITALIC); - BuiltinFonts14.put(ZAPFDINGBATS, PdfName.ZAPFDINGBATS); - } - - /** Generates the PDF stream with the Type1 and Truetype fonts returning - * a PdfStream. - */ - static class StreamFont extends PdfStream { - - /** Generates the PDF stream with the Type1 and Truetype fonts returning - * a PdfStream. - * @param contents the content of the stream - * @param lengths an array of int that describes the several lengths of each part of the font - * @throws DocumentException error in the stream compression - */ - public StreamFont(byte contents[], int lengths[]) throws DocumentException { - try { - bytes = contents; - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - for (int k = 0; k < lengths.length; ++k) { - put(new PdfName("Length" + (k + 1)), new PdfNumber(lengths[k])); - } - flateCompress(); - } - catch (Exception e) { - throw new DocumentException(e); - } - } - - /** - * Generates the PDF stream for a font. - * @param contents the content of a stream - * @param subType the subtype of the font. - * @throws DocumentException - */ - public StreamFont(byte contents[], String subType) throws DocumentException { - try { - bytes = contents; - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - if (subType != null) - put(PdfName.SUBTYPE, new PdfName(subType)); - flateCompress(); - } - catch (Exception e) { - throw new DocumentException(e); - } - } - } - - /** - *Creates new BaseFont - */ - protected BaseFont() { - } - - /** Creates a new font. This font can be one of the 14 built in types, - * a Type1 font referred by an AFM file, a TrueType font (simple or collection) or a CJK font from the - * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier - * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An - * example would be "STSong-Light,Bold". Note that this modifiers do not work if - * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". - * This would get the second font (indexes start at 0), in this case "MS PGothic". - *

- * The fonts are cached and if they already exist they are extracted from the cache, - * not parsed again. - *

- * This method calls:
- *

-     * createFont(name, encoding, embedded, true, null, null);
-     * 
- * @param name the name of the font or it's location on file - * @param encoding the encoding to be applied to this font - * @param embedded true if the font is to be embedded in the PDF - * @return returns a new font. This font may come from the cache - * @throws DocumentException the font is invalid - * @throws IOException the font file could not be read - */ - public static BaseFont createFont(String name, String encoding, boolean embedded) throws DocumentException, IOException { - return createFont(name, encoding, embedded, true, null, null); - } - - /** Creates a new font. This font can be one of the 14 built in types, - * a Type1 font referred by an AFM file, a TrueType font (simple or collection) or a CJK font from the - * Adobe Asian Font Pack. TrueType fonts and CJK fonts can have an optional style modifier - * appended to the name. These modifiers are: Bold, Italic and BoldItalic. An - * example would be "STSong-Light,Bold". Note that this modifiers do not work if - * the font is embedded. Fonts in TrueType collections are addressed by index such as "msgothic.ttc,1". - * This would get the second font (indexes start at 0), in this case "MS PGothic". - *

- * The fonts may or may not be cached depending on the flag cached. - * If the byte arrays are present the font will be - * read from them instead of the name. The name is still required to identify - * the font type. - * @param name the name of the font or it's location on file - * @param encoding the encoding to be applied to this font - * @param embedded true if the font is to be embedded in the PDF - * @param cached true if the font comes from the cache or is added to - * the cache if new, false if the font is always created new - * @param ttfAfm the true type font or the afm in a byte array - * @param pfb the pfb in a byte array - * @return returns a new font. This font may come from the cache but only if cached - * is true, otherwise it will always be created new - * @throws DocumentException the font is invalid - * @throws IOException the font file could not be read - */ - public static BaseFont createFont(String name, String encoding, boolean embedded, boolean cached, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException { - String nameBase = getBaseName(name); - encoding = normalizeEncoding(encoding); - boolean isBuiltinFonts14 = BuiltinFonts14.containsKey(name); - boolean isCJKFont = isBuiltinFonts14 ? false : CJKFont.isCJKFont(nameBase, encoding); - if (isBuiltinFonts14 || isCJKFont) - embedded = false; - else if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) - embedded = true; - BaseFont fontFound = null; - BaseFont fontBuilt = null; - String key = name + "\n" + encoding + "\n" + embedded; - if (cached) { - synchronized (fontCache) { - fontFound = (BaseFont)fontCache.get(key); - } - if (fontFound != null) - return fontFound; - } - if (isBuiltinFonts14 || name.toLowerCase().endsWith(".afm") || name.toLowerCase().endsWith(".pfm")) { - fontBuilt = new Type1Font(name, encoding, embedded, ttfAfm, pfb); - fontBuilt.fastWinansi = encoding.equals(CP1252); - } - else if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) { - if (encoding.equals(IDENTITY_H) || encoding.equals(IDENTITY_V)) - fontBuilt = new TrueTypeFontUnicode(name, encoding, embedded, ttfAfm); - else { - fontBuilt = new TrueTypeFont(name, encoding, embedded, ttfAfm); - fontBuilt.fastWinansi = encoding.equals(CP1252); - } - } - else if (isCJKFont) - fontBuilt = new CJKFont(name, encoding, embedded); - else - throw new DocumentException("Font '" + name + "' with '" + encoding + "' is not recognized."); - if (cached) { - synchronized (fontCache) { - fontFound = (BaseFont)fontCache.get(key); - if (fontFound != null) - return fontFound; - fontCache.put(key, fontBuilt); - } - } - return fontBuilt; - } - - /** - * Creates a font based on an existing document font. The created font font may not - * behave as expected, depending on the encoding or subset. - * @param fontRef the reference to the document font - * @return the font - */ - public static BaseFont createFont(PRIndirectReference fontRef) { - return new DocumentFont(fontRef); - } - - /** - * Gets the name without the modifiers Bold, Italic or BoldItalic. - * @param name the full name of the font - * @return the name without the modifiers Bold, Italic or BoldItalic - */ - protected static String getBaseName(String name) { - if (name.endsWith(",Bold")) - return name.substring(0, name.length() - 5); - else if (name.endsWith(",Italic")) - return name.substring(0, name.length() - 7); - else if (name.endsWith(",BoldItalic")) - return name.substring(0, name.length() - 11); - else - return name; - } - - /** - * Normalize the encoding names. "winansi" is changed to "Cp1252" and - * "macroman" is changed to "MacRoman". - * @param enc the encoding to be normalized - * @return the normalized encoding - */ - protected static String normalizeEncoding(String enc) { - if (enc.equals("winansi") || enc.equals("")) - return CP1252; - else if (enc.equals("macroman")) - return MACROMAN; - else - return enc; - } - - /** - * Creates the widths and the differences arrays - */ - protected void createEncoding() { - if (fontSpecific) { - for (int k = 0; k < 256; ++k) { - widths[k] = getRawWidth(k, null); - charBBoxes[k] = getRawCharBBox(k, null); - } - } - else { - String s; - String name; - char c; - byte b[] = new byte[1]; - for (int k = 0; k < 256; ++k) { - b[0] = (byte)k; - s = PdfEncodings.convertToString(b, encoding); - if (s.length() > 0) { - c = s.charAt(0); - } - else { - c = '?'; - } - name = GlyphList.unicodeToName((int)c); - if (name == null) - name = notdef; - differences[k] = name; - unicodeDifferences[k] = c; - widths[k] = getRawWidth((int)c, name); - charBBoxes[k] = getRawCharBBox((int)c, name); - } - } - } - - /** - * Gets the width from the font according to the Unicode char c - * or the name. If the name is null it's a symbolic font. - * @param c the unicode char - * @param name the glyph name - * @return the width of the char - */ - abstract int getRawWidth(int c, String name); - - /** - * Gets the kerning between two Unicode chars. - * @param char1 the first char - * @param char2 the second char - * @return the kerning to be applied in normalized 1000 units - */ - public abstract int getKerning(char char1, char char2); - - /** - * Sets the kerning between two Unicode chars. - * @param char1 the first char - * @param char2 the second char - * @param kern the kerning to apply in normalized 1000 units - * @return true if the kerning was applied, false otherwise - */ - public abstract boolean setKerning(char char1, char char2, int kern); - - /** - * Gets the width of a char in normalized 1000 units. - * @param char1 the unicode char to get the width of - * @return the width in normalized 1000 units - */ - public int getWidth(char char1) { - if (fastWinansi) { - if (char1 < 128 || (char1 >= 160 && char1 <= 255)) - return widths[char1]; - return widths[PdfEncodings.winansi.get(char1)]; - } - return getWidth(new String(new char[]{char1})); - } - - /** - * Gets the width of a String in normalized 1000 units. - * @param text the String to get the witdth of - * @return the width in normalized 1000 units - */ - public int getWidth(String text) { - int total = 0; - if (fastWinansi) { - int len = text.length(); - for (int k = 0; k < len; ++k) { - char char1 = text.charAt(k); - if (char1 < 128 || (char1 >= 160 && char1 <= 255)) - total += widths[char1]; - else - total += widths[PdfEncodings.winansi.get(char1)]; - } - return total; - } - else { - byte mbytes[] = convertToBytes(text); - for (int k = 0; k < mbytes.length; ++k) - total += widths[0xff & mbytes[k]]; - } - return total; - } - -/** - * Gets the descent of a String in normalized 1000 units. The descent will always be - * less than or equal to zero even if all the characters have an higher descent. - * @param text the String to get the descent of - * @return the dexcent in normalized 1000 units - */ - public int getDescent(String text) { - int min = 0; - char chars[] = text.toCharArray(); - for (int k = 0; k < chars.length; ++k) { - int bbox[] = getCharBBox(chars[k]); - if (bbox != null && bbox[1] < min) - min = bbox[1]; - } - return min; - } - -/** - * Gets the ascent of a String in normalized 1000 units. The ascent will always be - * greater than or equal to zero even if all the characters have a lower ascent. - * @param text the String to get the ascent of - * @return the ascent in normalized 1000 units - */ - public int getAscent(String text) { - int max = 0; - char chars[] = text.toCharArray(); - for (int k = 0; k < chars.length; ++k) { - int bbox[] = getCharBBox(chars[k]); - if (bbox != null && bbox[3] > max) - max = bbox[3]; - } - return max; - } - -/** - * Gets the descent of a String in points. The descent will always be - * less than or equal to zero even if all the characters have an higher descent. - * @param text the String to get the descent of - * @param fontSize the size of the font - * @return the dexcent in points - */ - public float getDescentPoint(String text, float fontSize) - { - return (float)getDescent(text) * 0.001f * fontSize; - } - -/** - * Gets the ascent of a String in points. The ascent will always be - * greater than or equal to zero even if all the characters have a lower ascent. - * @param text the String to get the ascent of - * @param fontSize the size of the font - * @return the ascent in points - */ - public float getAscentPoint(String text, float fontSize) - { - return (float)getAscent(text) * 0.001f * fontSize; - } -// ia> - - /** - * Gets the width of a String in points taking kerning - * into account. - * @param text the String to get the witdth of - * @param fontSize the font size - * @return the width in points - */ - public float getWidthPointKerned(String text, float fontSize) { - float size = (float)getWidth(text) * 0.001f * fontSize; - if (!hasKernPairs()) - return size; - int len = text.length() - 1; - int kern = 0; - char c[] = text.toCharArray(); - for (int k = 0; k < len; ++k) { - kern += getKerning(c[k], c[k + 1]); - } - return size + kern * 0.001f * fontSize; - } - - /** - * Gets the width of a String in points. - * @param text the String to get the witdth of - * @param fontSize the font size - * @return the width in points - */ - public float getWidthPoint(String text, float fontSize) { - return (float)getWidth(text) * 0.001f * fontSize; - } - - /** - * Gets the width of a char in points. - * @param char1 the char to get the witdth of - * @param fontSize the font size - * @return the width in points - */ - public float getWidthPoint(char char1, float fontSize) { - return getWidth(char1) * 0.001f * fontSize; - } - - /** - * Converts a String to a byte array according - * to the font's encoding. - * @param text the String to be converted - * @return an array of byte representing the conversion according to the font's encoding - */ - byte[] convertToBytes(String text) { - if (directTextToByte) - return PdfEncodings.convertToBytes(text, null); - return PdfEncodings.convertToBytes(text, encoding); - } - - /** Outputs to the writer the font dictionaries and streams. - * @param writer the writer for this document - * @param ref the font indirect reference - * @param params several parameters that depend on the font type - * @throws IOException on error - * @throws DocumentException error in generating the object - */ - abstract void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException; - - /** Gets the encoding used to convert String into byte[]. - * @return the encoding name - */ - public String getEncoding() { - return encoding; - } - - /** Gets the font parameter identified by key. Valid values - * for key are ASCENT, AWT_ASCENT, CAPHEIGHT, - * DESCENT, AWT_DESCENT, - * ITALICANGLE, BBOXLLX, BBOXLLY, BBOXURX - * and BBOXURY. - * @param key the parameter to be extracted - * @param fontSize the font size in points - * @return the parameter in points - */ - public abstract float getFontDescriptor(int key, float fontSize); - - /** Gets the font type. The font types can be: FONT_TYPE_T1, - * FONT_TYPE_TT, FONT_TYPE_CJK and FONT_TYPE_TTUNI. - * @return the font type - */ - public int getFontType() { - return fontType; - } - - /** Gets the embedded flag. - * @return true if the font is embedded. - */ - public boolean isEmbedded() { - return embedded; - } - - /** Gets the symbolic flag of the font. - * @return true if the font is symbolic - */ - public boolean isFontSpecific() { - return fontSpecific; - } - - /** Creates a unique subset prefix to be added to the font name when the font is embedded and subset. - * @return the subset prefix - */ - public static String createSubsetPrefix() { - String s = ""; - for (int k = 0; k < 6; ++k) - s += (char)(Math.random() * 26 + 'A'); - return s + "+"; - } - - /** Gets the Unicode character corresponding to the byte output to the pdf stream. - * @param index the byte index - * @return the Unicode character - */ - char getUnicodeDifferences(int index) { - return unicodeDifferences[index]; - } - - /** Gets the postscript font name. - * @return the postscript font name - */ - public abstract String getPostscriptFontName(); - - /** - * Sets the font name that will appear in the pdf font dictionary. - * Use with care as it can easily make a font unreadable if not embedded. - * @param name the new font name - */ - public abstract void setPostscriptFontName(String name); - - /** Gets the full name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the full name of the font - */ - public abstract String[][] getFullFontName(); - - /** Gets the full name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @param name the name of the font - * @param encoding the encoding of the font - * @param ttfAfm the true type font or the afm in a byte array - * @throws DocumentException on error - * @throws IOException on error - * @return the full name of the font - */ - public static String[][] getFullFontName(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { - String nameBase = getBaseName(name); - BaseFont fontBuilt = null; - if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) - fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true); - else - fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); - return fontBuilt.getFullFontName(); - } - - /** Gets all the names from the font. Only the required tables are read. - * @param name the name of the font - * @param encoding the encoding of the font - * @param ttfAfm the true type font or the afm in a byte array - * @throws DocumentException on error - * @throws IOException on error - * @return an array of Object[] built with {getPostscriptFontName(), getFamilyFontName(), getFullFontName()} - */ - public static Object[] getAllFontNames(String name, String encoding, byte ttfAfm[]) throws DocumentException, IOException { - String nameBase = getBaseName(name); - BaseFont fontBuilt = null; - if (nameBase.toLowerCase().endsWith(".ttf") || nameBase.toLowerCase().endsWith(".otf") || nameBase.toLowerCase().indexOf(".ttc,") > 0) - fontBuilt = new TrueTypeFont(name, CP1252, false, ttfAfm, true); - else - fontBuilt = createFont(name, encoding, false, false, ttfAfm, null); - return new Object[]{fontBuilt.getPostscriptFontName(), fontBuilt.getFamilyFontName(), fontBuilt.getFullFontName()}; - } - - /** Gets the family name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the family name of the font - */ - public abstract String[][] getFamilyFontName(); - - /** Gets the code pages supported by the font. This has only meaning - * with True Type fonts. - * @return the code pages supported by the font - */ - public String[] getCodePagesSupported() { - return new String[0]; - } - - /** Enumerates the postscript font names present inside a - * True Type Collection. - * @param ttcFile the file name of the font - * @throws DocumentException on error - * @throws IOException on error - * @return the postscript font names - */ - public static String[] enumerateTTCNames(String ttcFile) throws DocumentException, IOException { - return new EnumerateTTC(ttcFile).getNames(); - } - - /** Enumerates the postscript font names present inside a - * True Type Collection. - * @param ttcArray the font as a byte array - * @throws DocumentException on error - * @throws IOException on error - * @return the postscript font names - */ - public static String[] enumerateTTCNames(byte ttcArray[]) throws DocumentException, IOException { - return new EnumerateTTC(ttcArray).getNames(); - } - - /** Gets the font width array. - * @return the font width array - */ - public int[] getWidths() { - return widths; - } - - /** Gets the array with the names of the characters. - * @return the array with the names of the characters - */ - public String[] getDifferences() { - return differences; - } - - /** Gets the array with the unicode characters. - * @return the array with the unicode characters - */ - public char[] getUnicodeDifferences() { - return unicodeDifferences; - } - - /** Gets the state of the property. - * @return value of property forceWidthsOutput - */ - public boolean isForceWidthsOutput() { - return forceWidthsOutput; - } - - /** Set to true to force the generation of the - * widths array. - * @param forceWidthsOutput true to force the generation of the - * widths array - */ - public void setForceWidthsOutput(boolean forceWidthsOutput) { - this.forceWidthsOutput = forceWidthsOutput; - } - - /** Gets the direct conversion of char to byte. - * @return value of property directTextToByte. - * @see #setDirectTextToByte(boolean directTextToByte) - */ - public boolean isDirectTextToByte() { - return directTextToByte; - } - - /** Sets the conversion of char directly to byte - * by casting. This is a low level feature to put the bytes directly in - * the content stream without passing through String.getBytes(). - * @param directTextToByte New value of property directTextToByte. - */ - public void setDirectTextToByte(boolean directTextToByte) { - this.directTextToByte = directTextToByte; - } - - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. - * @return false to include all the glyphs and widths. - */ - public boolean isSubset() { - return subset; - } - - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. When set to true - * only the glyphs used will be included in the font. When set to false - * and {@link #addSubsetRange(int[])} was not called the full font will be included - * otherwise just the characters ranges will be included. - * @param subset new value of property subset - */ - public void setSubset(boolean subset) { - this.subset = subset; - } - - /** Gets the font resources. - * @param key the full name of the resource - * @return the InputStream to get the resource or - * null if not found - */ - public static InputStream getResourceStream(String key) { - return getResourceStream(key, null); - } - - /** Gets the font resources. - * @param key the full name of the resource - * @param loader the ClassLoader to load the resource or null to try the ones available - * @return the InputStream to get the resource or - * null if not found - */ - public static InputStream getResourceStream(String key, ClassLoader loader) { - if (key.startsWith("/")) - key = key.substring(1); - InputStream is = null; - if (loader != null) { - is = loader.getResourceAsStream(key); - if (is != null) - return is; - } - // Try to use Context Class Loader to load the properties file. - try { - java.lang.reflect.Method getCCL = - Thread.class.getMethod("getContextClassLoader", new Class[0]); - if (getCCL != null) { - ClassLoader contextClassLoader = - (ClassLoader)getCCL.invoke(Thread.currentThread(), - new Object[0]); - if (contextClassLoader != null) - is = contextClassLoader.getResourceAsStream(key); - } - } catch (Throwable e) {} - - if (is == null) { - is = BaseFont.class.getResourceAsStream("/" + key); - } - if (is == null) { - is = ClassLoader.getSystemResourceAsStream(key); - } - return is; - } - - /** Gets the Unicode equivalent to a CID. - * The (inexistent) CID is translated as '\n'. - * It has only meaning with CJK fonts with Identity encoding. - * @param c the CID code - * @return the Unicode equivalent - */ - public char getUnicodeEquivalent(char c) { - return c; - } - - /** Gets the CID code given an Unicode. - * It has only meaning with CJK fonts. - * @param c the Unicode - * @return the CID equivalent - */ - public char getCidCode(char c) { - return c; - } - - /** Checks if the font has any kerning pairs. - * @return true if the font has any kerning pairs - */ - public abstract boolean hasKernPairs(); - - /** - * Checks if a character exists in this font. - * @param c the character to check - * @return true if the character has a glyph, - * false otherwise - */ - public boolean charExists(char c) { - byte b[] = convertToBytes(new String(new char[]{c})); - return b.length > 0; - } - - /** - * Sets the character advance. - * @param c the character - * @param advance the character advance normalized to 1000 units - * @return true if the advance was set, - * false otherwise - */ - public boolean setCharAdvance(char c, int advance) { - byte b[] = convertToBytes(new String(new char[]{c})); - if (b.length == 0) - return false; - widths[0xff & b[0]] = advance; - return true; - } - - private static void addFont(PRIndirectReference fontRef, IntHashtable hits, ArrayList fonts) { - PdfObject obj = PdfReader.getPdfObject(fontRef); - if (!obj.isDictionary()) - return; - PdfDictionary font = (PdfDictionary)obj; - PdfName subtype = (PdfName)PdfReader.getPdfObject(font.get(PdfName.SUBTYPE)); - if (!PdfName.TYPE1.equals(subtype) && !PdfName.TRUETYPE.equals(subtype)) - return; - PdfName name = (PdfName)PdfReader.getPdfObject(font.get(PdfName.BASEFONT)); - fonts.add(new Object[]{PdfName.decodeName(name.toString()), fontRef}); - hits.put(fontRef.getNumber(), 1); - } - - private static void recourseFonts(PdfDictionary page, IntHashtable hits, ArrayList fonts, int level) { - ++level; - if (level > 50) // in case we have an endless loop - return; - PdfDictionary resources = (PdfDictionary)PdfReader.getPdfObject(page.get(PdfName.RESOURCES)); - if (resources == null) - return; - PdfDictionary font = (PdfDictionary)PdfReader.getPdfObject(resources.get(PdfName.FONT)); - if (font != null) { - for (Iterator it = font.getKeys().iterator(); it.hasNext();) { - PdfObject ft = font.get((PdfName)it.next()); - if (ft == null || !ft.isIndirect()) - continue; - int hit = ((PRIndirectReference)ft).getNumber(); - if (hits.containsKey(hit)) - continue; - addFont((PRIndirectReference)ft, hits, fonts); - } - } - PdfDictionary xobj = (PdfDictionary)PdfReader.getPdfObject(resources.get(PdfName.XOBJECT)); - if (xobj != null) { - for (Iterator it = xobj.getKeys().iterator(); it.hasNext();) { - recourseFonts((PdfDictionary)PdfReader.getPdfObject(xobj.get((PdfName)it.next())), hits, fonts, level); - } - } - } - - /** - * Gets a list of all document fonts. Each element of the ArrayList - * contains a Object[]{String,PRIndirectReference} with the font name - * and the indirect reference to it. - * @param reader the document where the fonts are to be listed from - * @return the list of fonts and references - */ - public static ArrayList getDocumentFonts(PdfReader reader) { - IntHashtable hits = new IntHashtable(); - ArrayList fonts = new ArrayList(); - int npages = reader.getNumberOfPages(); - for (int k = 1; k <= npages; ++k) - recourseFonts(reader.getPageN(k), hits, fonts, 1); - return fonts; - } - - /** - * Gets a list of the document fonts in a particular page. Each element of the ArrayList - * contains a Object[]{String,PRIndirectReference} with the font name - * and the indirect reference to it. - * @param reader the document where the fonts are to be listed from - * @param page the page to list the fonts from - * @return the list of fonts and references - */ - public static ArrayList getDocumentFonts(PdfReader reader, int page) { - IntHashtable hits = new IntHashtable(); - ArrayList fonts = new ArrayList(); - recourseFonts(reader.getPageN(page), hits, fonts, 1); - return fonts; - } - - /** - * Gets the smallest box enclosing the character contours. It will return - * null if the font has not the information or the character has no - * contours, as in the case of the space, for example. Characters with no contours may - * also return [0,0,0,0]. - * @param c the character to get the contour bounding box from - * @return an array of four floats with the bounding box in the format [llx,lly,urx,ury] or - * null - */ - public int[] getCharBBox(char c) { - byte b[] = convertToBytes(new String(new char[]{c})); - if (b.length == 0) - return null; - else - return charBBoxes[b[0] & 0xff]; - } - - protected abstract int[] getRawCharBBox(int c, String name); - - /** - * iText expects Arabic Diactrics (tashkeel) to have zero advance but some fonts, - * most notably those that come with Windows, like times.ttf, have non-zero - * advance for those characters. This method makes those character to have zero - * width advance and work correctly in the iText Arabic shaping and reordering - * context. - */ - public void correctArabicAdvance() { - for (char c = '\u064b'; c <= '\u0658'; ++c) - setCharAdvance(c, 0); - setCharAdvance('\u0670', 0); - for (char c = '\u06d6'; c <= '\u06dc'; ++c) - setCharAdvance(c, 0); - for (char c = '\u06df'; c <= '\u06e4'; ++c) - setCharAdvance(c, 0); - for (char c = '\u06e7'; c <= '\u06e8'; ++c) - setCharAdvance(c, 0); - for (char c = '\u06ea'; c <= '\u06ed'; ++c) - setCharAdvance(c, 0); - } - - /** - * Adds a character range when subsetting. The range is an int array - * where the first element is the start range inclusive and the second element is the - * end range inclusive. Several ranges are allowed in the same array. - * @param range the character range - */ - public void addSubsetRange(int[] range) { - if (subsetRanges == null) - subsetRanges = new ArrayList(); - subsetRanges.add(range); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/BidiLine.java b/src/main/java/com/lowagie/text/pdf/BidiLine.java deleted file mode 100644 index 54dd32e..0000000 --- a/src/main/java/com/lowagie/text/pdf/BidiLine.java +++ /dev/null @@ -1,915 +0,0 @@ -/* - * - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; - -import com.lowagie.text.Chunk; - -/** Does all the line bidirectional processing with PdfChunk assembly. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class BidiLine { - - protected int runDirection; - protected int pieceSize = 2048; - protected char text[] = new char[pieceSize]; - protected PdfChunk detailChunks[] = new PdfChunk[pieceSize]; - protected int totalTextLength = 0; - - protected byte orderLevels[] = new byte[pieceSize]; - protected int indexChars[] = new int[pieceSize]; - - protected ArrayList chunks = new ArrayList(); - protected int indexChunk = 0; - protected int indexChunkChar = 0; - protected int currentChar = 0; - - protected int storedRunDirection; - protected char storedText[] = new char[0]; - protected PdfChunk storedDetailChunks[] = new PdfChunk[0]; - protected int storedTotalTextLength = 0; - - protected byte storedOrderLevels[] = new byte[0]; - protected int storedIndexChars[] = new int[0]; - - protected int storedIndexChunk = 0; - protected int storedIndexChunkChar = 0; - protected int storedCurrentChar = 0; - - protected boolean shortStore; -// protected ArabicShaping arabic = new ArabicShaping(ArabicShaping.LETTERS_SHAPE | ArabicShaping.LENGTH_GROW_SHRINK | ArabicShaping.TEXT_DIRECTION_LOGICAL); - protected static final IntHashtable mirrorChars = new IntHashtable(); - protected int arabicOptions; - - /** Creates new BidiLine */ - public BidiLine() { - } - - public BidiLine(BidiLine org) { - runDirection = org.runDirection; - pieceSize = org.pieceSize; - text = (char[])org.text.clone(); - detailChunks = (PdfChunk[])org.detailChunks.clone(); - totalTextLength = org.totalTextLength; - - orderLevels = (byte[])org.orderLevels.clone(); - indexChars = (int[])org.indexChars.clone(); - - chunks = new ArrayList(org.chunks); - indexChunk = org.indexChunk; - indexChunkChar = org.indexChunkChar; - currentChar = org.currentChar; - - storedRunDirection = org.storedRunDirection; - storedText = (char[])org.storedText.clone(); - storedDetailChunks = (PdfChunk[])org.storedDetailChunks.clone(); - storedTotalTextLength = org.storedTotalTextLength; - - storedOrderLevels = (byte[])org.storedOrderLevels.clone(); - storedIndexChars = (int[])org.storedIndexChars.clone(); - - storedIndexChunk = org.storedIndexChunk; - storedIndexChunkChar = org.storedIndexChunkChar; - storedCurrentChar = org.storedCurrentChar; - - shortStore = org.shortStore; - arabicOptions = org.arabicOptions; - } - - public boolean isEmpty() { - return (currentChar >= totalTextLength && indexChunk >= chunks.size()); - } - - public void clearChunks() { - chunks.clear(); - totalTextLength = 0; - currentChar = 0; - } - - public boolean getParagraph(int runDirection) { - this.runDirection = runDirection; - currentChar = 0; - totalTextLength = 0; - boolean hasText = false; - char c; - char uniC; - BaseFont bf; - for (; indexChunk < chunks.size(); ++indexChunk) { - PdfChunk ck = (PdfChunk)chunks.get(indexChunk); - bf = ck.font().getFont(); - String s = ck.toString(); - int len = s.length(); - for (; indexChunkChar < len; ++indexChunkChar) { - c = s.charAt(indexChunkChar); - uniC = bf.getUnicodeEquivalent(c); - if (uniC == '\r' || uniC == '\n') { - // next condition is never true for CID - if (uniC == '\r' && indexChunkChar + 1 < len && s.charAt(indexChunkChar + 1) == '\n') - ++indexChunkChar; - ++indexChunkChar; - if (indexChunkChar >= len) { - indexChunkChar = 0; - ++indexChunk; - } - hasText = true; - if (totalTextLength == 0) - detailChunks[0] = ck; - break; - } - addPiece(c, ck); - } - if (hasText) - break; - indexChunkChar = 0; - } - if (totalTextLength == 0) - return hasText; - - // remove trailing WS - totalTextLength = trimRight(0, totalTextLength - 1) + 1; - if (totalTextLength == 0) - return true; - - if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { - if (orderLevels.length < totalTextLength) { - orderLevels = new byte[pieceSize]; - indexChars = new int[pieceSize]; - } - ArabicLigaturizer.processNumbers(text, 0, totalTextLength, arabicOptions); - BidiOrder order = new BidiOrder(text, 0, totalTextLength, (byte)(runDirection == PdfWriter.RUN_DIRECTION_RTL ? 1 : 0)); - byte od[] = order.getLevels(); - for (int k = 0; k < totalTextLength; ++k) { - orderLevels[k] = od[k]; - indexChars[k] = k; - } - doArabicShapping(); - mirrorGlyphs(); - } - totalTextLength = trimRightEx(0, totalTextLength - 1) + 1; - return true; - } - - public void addChunk(PdfChunk chunk) { - chunks.add(chunk); - } - - public void addChunks(ArrayList chunks) { - this.chunks.addAll(chunks); - } - - public void addPiece(char c, PdfChunk chunk) { - if (totalTextLength >= pieceSize) { - char tempText[] = text; - PdfChunk tempDetailChunks[] = detailChunks; - pieceSize *= 2; - text = new char[pieceSize]; - detailChunks = new PdfChunk[pieceSize]; - System.arraycopy(tempText, 0, text, 0, totalTextLength); - System.arraycopy(tempDetailChunks, 0, detailChunks, 0, totalTextLength); - } - text[totalTextLength] = c; - detailChunks[totalTextLength++] = chunk; - } - - public void save() { - if (indexChunk > 0) { - if (indexChunk >= chunks.size()) - chunks.clear(); - else { - for (--indexChunk; indexChunk >= 0; --indexChunk) - chunks.remove(indexChunk); - } - indexChunk = 0; - } - storedRunDirection = runDirection; - storedTotalTextLength = totalTextLength; - storedIndexChunk = indexChunk; - storedIndexChunkChar = indexChunkChar; - storedCurrentChar = currentChar; - shortStore = (currentChar < totalTextLength); - if (!shortStore) { - // long save - if (storedText.length < totalTextLength) { - storedText = new char[totalTextLength]; - storedDetailChunks = new PdfChunk[totalTextLength]; - } - System.arraycopy(text, 0, storedText, 0, totalTextLength); - System.arraycopy(detailChunks, 0, storedDetailChunks, 0, totalTextLength); - } - if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { - if (storedOrderLevels.length < totalTextLength) { - storedOrderLevels = new byte[totalTextLength]; - storedIndexChars = new int[totalTextLength]; - } - System.arraycopy(orderLevels, currentChar, storedOrderLevels, currentChar, totalTextLength - currentChar); - System.arraycopy(indexChars, currentChar, storedIndexChars, currentChar, totalTextLength - currentChar); - } - } - - public void restore() { - runDirection = storedRunDirection; - totalTextLength = storedTotalTextLength; - indexChunk = storedIndexChunk; - indexChunkChar = storedIndexChunkChar; - currentChar = storedCurrentChar; - if (!shortStore) { - // long restore - System.arraycopy(storedText, 0, text, 0, totalTextLength); - System.arraycopy(storedDetailChunks, 0, detailChunks, 0, totalTextLength); - } - if (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL) { - System.arraycopy(storedOrderLevels, currentChar, orderLevels, currentChar, totalTextLength - currentChar); - System.arraycopy(storedIndexChars, currentChar, indexChars, currentChar, totalTextLength - currentChar); - } - } - - public void mirrorGlyphs() { - for (int k = 0; k < totalTextLength; ++k) { - if ((orderLevels[k] & 1) == 1) { - int mirror = mirrorChars.get(text[k]); - if (mirror != 0) - text[k] = (char)mirror; - } - } - } - - public void doArabicShapping() { - int src = 0; - int dest = 0; - for (;;) { - while (src < totalTextLength) { - char c = text[src]; - if (c >= 0x0600 && c <= 0x06ff) - break; - if (src != dest) { - text[dest] = text[src]; - detailChunks[dest] = detailChunks[src]; - orderLevels[dest] = orderLevels[src]; - } - ++src; - ++dest; - } - if (src >= totalTextLength) { - totalTextLength = dest; - return; - } - int startArabicIdx = src; - ++src; - while (src < totalTextLength) { - char c = text[src]; - if (c < 0x0600 || c > 0x06ff) - break; - ++src; - } - int arabicWordSize = src - startArabicIdx; - int size = ArabicLigaturizer.arabic_shape(text, startArabicIdx, arabicWordSize, text, dest, arabicWordSize, arabicOptions /*PangoArabicShapping.ar_novowel PangoArabicShapping.ar_lig | PangoArabicShapping.ar_composedtashkeel*/); - if (startArabicIdx != dest) { - for (int k = 0; k < size; ++k) { - detailChunks[dest] = detailChunks[startArabicIdx]; - orderLevels[dest++] = orderLevels[startArabicIdx++]; - } - } - else - dest += size; - } - } - - public PdfLine processLine(float width, int alignment, int runDirection, int arabicOptions) { - this.arabicOptions = arabicOptions; - save(); - boolean isRTL = (runDirection == PdfWriter.RUN_DIRECTION_RTL); - if (currentChar >= totalTextLength) { - boolean hasText = getParagraph(runDirection); - if (!hasText) - return null; - if (totalTextLength == 0) { - ArrayList ar = new ArrayList(); - PdfChunk ck = new PdfChunk("", detailChunks[0]); - ar.add(ck); - return new PdfLine(0, 0, alignment, true, ar, isRTL); - } - } - float originalWidth = width; - int lastSplit = -1; - if (currentChar != 0) - currentChar = trimLeftEx(currentChar, totalTextLength - 1); - int oldCurrentChar = currentChar; - char c = 0; - char uniC = 0; - PdfChunk ck = null; - float charWidth = 0; - PdfChunk lastValidChunk = null; - for (; currentChar < totalTextLength; ++currentChar) { - c = text[currentChar]; - ck = detailChunks[currentChar]; - uniC = ck.getUnicodeEquivalent(c); - if (PdfChunk.noPrint(uniC)) - continue; - charWidth = ck.getCharWidth(c); - if (ck.isExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks)) - lastSplit = currentChar; - if (width - charWidth < 0) - break; - width -= charWidth; - lastValidChunk = ck; - } - if (lastValidChunk == null) { - // not even a single char fit; must output the first char - ++currentChar; - return new PdfLine(0, 0, alignment, false, createArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL); - } - if (currentChar >= totalTextLength) { - // there was more line than text - return new PdfLine(0, width, alignment, true, createArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL); - } - int newCurrentChar = trimRightEx(oldCurrentChar, currentChar - 1); - if (newCurrentChar < oldCurrentChar) { - // only WS - return new PdfLine(0, width, alignment, false, createArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL); - } - if (newCurrentChar == currentChar - 1) { // middle of word - HyphenationEvent he = (HyphenationEvent)lastValidChunk.getAttribute(Chunk.HYPHENATION); - if (he != null) { - int word[] = getWord(oldCurrentChar, newCurrentChar); - if (word != null) { - float testWidth = width + getWidth(word[0], currentChar - 1); - String pre = he.getHyphenatedWordPre(new String(text, word[0], word[1] - word[0]), lastValidChunk.font().getFont(), lastValidChunk.font().size(), testWidth); - String post = he.getHyphenatedWordPost(); - if (pre.length() > 0) { - PdfChunk extra = new PdfChunk(pre, lastValidChunk); - currentChar = word[1] - post.length(); - return new PdfLine(0, testWidth - lastValidChunk.font().width(pre), alignment, false, createArrayOfPdfChunks(oldCurrentChar, word[0] - 1, extra), isRTL); - } - } - } - } - if (lastSplit == -1 || lastSplit >= newCurrentChar) { - // no split point or split point ahead of end - return new PdfLine(0, width + getWidth(newCurrentChar + 1, currentChar - 1), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); - } - // standard split - currentChar = lastSplit + 1; - newCurrentChar = trimRightEx(oldCurrentChar, lastSplit); - if (newCurrentChar < oldCurrentChar) { - // only WS again - newCurrentChar = currentChar - 1; - } - return new PdfLine(0, originalWidth - getWidth(oldCurrentChar, newCurrentChar), alignment, false, createArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL); - } - - /** Gets the width of a range of characters. - * @param startIdx the first index to calculate - * @param lastIdx the last inclusive index to calculate - * @return the sum of all widths - */ - public float getWidth(int startIdx, int lastIdx) { - char c = 0; - char uniC; - PdfChunk ck = null; - float width = 0; - for (; startIdx <= lastIdx; ++startIdx) { - c = text[startIdx]; - ck = detailChunks[startIdx]; - uniC = ck.getUnicodeEquivalent(c); - if (PdfChunk.noPrint(uniC)) - continue; - width += detailChunks[startIdx].getCharWidth(c); - } - return width; - } - - public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx) { - return createArrayOfPdfChunks(startIdx, endIdx, null); - } - - public ArrayList createArrayOfPdfChunks(int startIdx, int endIdx, PdfChunk extraPdfChunk) { - boolean bidi = (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL); - if (bidi) - reorder(startIdx, endIdx); - ArrayList ar = new ArrayList(); - PdfChunk refCk = detailChunks[startIdx]; - PdfChunk ck = null; - StringBuffer buf = new StringBuffer(); - char c; - int idx = 0; - for (; startIdx <= endIdx; ++startIdx) { - idx = bidi ? indexChars[startIdx] : startIdx; - c = text[idx]; - ck = detailChunks[idx]; - if (PdfChunk.noPrint(ck.getUnicodeEquivalent(c))) - continue; - if (ck.isImage()) { - if (buf.length() > 0) { - ar.add(new PdfChunk(buf.toString(), refCk)); - buf = new StringBuffer(); - } - ar.add(ck); - } - else if (ck == refCk) { - buf.append(c); - } - else { - if (buf.length() > 0) { - ar.add(new PdfChunk(buf.toString(), refCk)); - buf = new StringBuffer(); - } - if (!ck.isImage()) - buf.append(c); - refCk = ck; - } - } - if (buf.length() > 0) { - ar.add(new PdfChunk(buf.toString(), refCk)); - } - if (extraPdfChunk != null) - ar.add(extraPdfChunk); - return ar; - } - - public int[] getWord(int startIdx, int idx) { - int last = idx; - int first = idx; - // forward - for (; last < totalTextLength; ++last) { - if (!Character.isLetter(text[last])) - break; - } - if (last == idx) - return null; - // backward - for (; first >= startIdx; --first) { - if (!Character.isLetter(text[first])) - break; - } - ++first; - return new int[]{first, last}; - } - - public int trimRight(int startIdx, int endIdx) { - int idx = endIdx; - char c; - for (; idx >= startIdx; --idx) { - c = detailChunks[idx].getUnicodeEquivalent(text[idx]); - if (!isWS(c)) - break; - } - return idx; - } - - public int trimLeft(int startIdx, int endIdx) { - int idx = startIdx; - char c; - for (; idx <= endIdx; ++idx) { - c = detailChunks[idx].getUnicodeEquivalent(text[idx]); - if (!isWS(c)) - break; - } - return idx; - } - - public int trimRightEx(int startIdx, int endIdx) { - int idx = endIdx; - char c = 0; - for (; idx >= startIdx; --idx) { - c = detailChunks[idx].getUnicodeEquivalent(text[idx]); - if (!isWS(c) && !PdfChunk.noPrint(c)) - break; - } - return idx; - } - - public int trimLeftEx(int startIdx, int endIdx) { - int idx = startIdx; - char c = 0; - for (; idx <= endIdx; ++idx) { - c = detailChunks[idx].getUnicodeEquivalent(text[idx]); - if (!isWS(c) && !PdfChunk.noPrint(c)) - break; - } - return idx; - } - - public void reorder(int start, int end) { - byte maxLevel = orderLevels[start]; - byte minLevel = maxLevel; - byte onlyOddLevels = maxLevel; - byte onlyEvenLevels = maxLevel; - for (int k = start + 1; k <= end; ++k) { - byte b = orderLevels[k]; - if (b > maxLevel) - maxLevel = b; - else if (b < minLevel) - minLevel = b; - onlyOddLevels &= b; - onlyEvenLevels |= b; - } - if ((onlyEvenLevels & 1) == 0) // nothing to do - return; - if ((onlyOddLevels & 1) == 1) { // single inversion - flip(start, end + 1); - return; - } - minLevel |= 1; - for (; maxLevel >= minLevel; --maxLevel) { - int pstart = start; - for (;;) { - for (;pstart <= end; ++pstart) { - if (orderLevels[pstart] >= maxLevel) - break; - } - if (pstart > end) - break; - int pend = pstart + 1; - for (; pend <= end; ++pend) { - if (orderLevels[pend] < maxLevel) - break; - } - flip(pstart, pend); - pstart = pend + 1; - } - } - } - - public void flip(int start, int end) { - int mid = (start + end) / 2; - --end; - for (; start < mid; ++start, --end) { - int temp = indexChars[start]; - indexChars[start] = indexChars[end]; - indexChars[end] = temp; - } - } - - public static boolean isWS(char c) { - return (c <= ' '); - } - - static { - mirrorChars.put(0x0028, 0x0029); // LEFT PARENTHESIS - mirrorChars.put(0x0029, 0x0028); // RIGHT PARENTHESIS - mirrorChars.put(0x003C, 0x003E); // LESS-THAN SIGN - mirrorChars.put(0x003E, 0x003C); // GREATER-THAN SIGN - mirrorChars.put(0x005B, 0x005D); // LEFT SQUARE BRACKET - mirrorChars.put(0x005D, 0x005B); // RIGHT SQUARE BRACKET - mirrorChars.put(0x007B, 0x007D); // LEFT CURLY BRACKET - mirrorChars.put(0x007D, 0x007B); // RIGHT CURLY BRACKET - mirrorChars.put(0x00AB, 0x00BB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - mirrorChars.put(0x00BB, 0x00AB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - mirrorChars.put(0x2039, 0x203A); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK - mirrorChars.put(0x203A, 0x2039); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - mirrorChars.put(0x2045, 0x2046); // LEFT SQUARE BRACKET WITH QUILL - mirrorChars.put(0x2046, 0x2045); // RIGHT SQUARE BRACKET WITH QUILL - mirrorChars.put(0x207D, 0x207E); // SUPERSCRIPT LEFT PARENTHESIS - mirrorChars.put(0x207E, 0x207D); // SUPERSCRIPT RIGHT PARENTHESIS - mirrorChars.put(0x208D, 0x208E); // SUBSCRIPT LEFT PARENTHESIS - mirrorChars.put(0x208E, 0x208D); // SUBSCRIPT RIGHT PARENTHESIS - mirrorChars.put(0x2208, 0x220B); // ELEMENT OF - mirrorChars.put(0x2209, 0x220C); // NOT AN ELEMENT OF - mirrorChars.put(0x220A, 0x220D); // SMALL ELEMENT OF - mirrorChars.put(0x220B, 0x2208); // CONTAINS AS MEMBER - mirrorChars.put(0x220C, 0x2209); // DOES NOT CONTAIN AS MEMBER - mirrorChars.put(0x220D, 0x220A); // SMALL CONTAINS AS MEMBER - mirrorChars.put(0x2215, 0x29F5); // DIVISION SLASH - mirrorChars.put(0x223C, 0x223D); // TILDE OPERATOR - mirrorChars.put(0x223D, 0x223C); // REVERSED TILDE - mirrorChars.put(0x2243, 0x22CD); // ASYMPTOTICALLY EQUAL TO - mirrorChars.put(0x2252, 0x2253); // APPROXIMATELY EQUAL TO OR THE IMAGE OF - mirrorChars.put(0x2253, 0x2252); // IMAGE OF OR APPROXIMATELY EQUAL TO - mirrorChars.put(0x2254, 0x2255); // COLON EQUALS - mirrorChars.put(0x2255, 0x2254); // EQUALS COLON - mirrorChars.put(0x2264, 0x2265); // LESS-THAN OR EQUAL TO - mirrorChars.put(0x2265, 0x2264); // GREATER-THAN OR EQUAL TO - mirrorChars.put(0x2266, 0x2267); // LESS-THAN OVER EQUAL TO - mirrorChars.put(0x2267, 0x2266); // GREATER-THAN OVER EQUAL TO - mirrorChars.put(0x2268, 0x2269); // [BEST FIT] LESS-THAN BUT NOT EQUAL TO - mirrorChars.put(0x2269, 0x2268); // [BEST FIT] GREATER-THAN BUT NOT EQUAL TO - mirrorChars.put(0x226A, 0x226B); // MUCH LESS-THAN - mirrorChars.put(0x226B, 0x226A); // MUCH GREATER-THAN - mirrorChars.put(0x226E, 0x226F); // [BEST FIT] NOT LESS-THAN - mirrorChars.put(0x226F, 0x226E); // [BEST FIT] NOT GREATER-THAN - mirrorChars.put(0x2270, 0x2271); // [BEST FIT] NEITHER LESS-THAN NOR EQUAL TO - mirrorChars.put(0x2271, 0x2270); // [BEST FIT] NEITHER GREATER-THAN NOR EQUAL TO - mirrorChars.put(0x2272, 0x2273); // [BEST FIT] LESS-THAN OR EQUIVALENT TO - mirrorChars.put(0x2273, 0x2272); // [BEST FIT] GREATER-THAN OR EQUIVALENT TO - mirrorChars.put(0x2274, 0x2275); // [BEST FIT] NEITHER LESS-THAN NOR EQUIVALENT TO - mirrorChars.put(0x2275, 0x2274); // [BEST FIT] NEITHER GREATER-THAN NOR EQUIVALENT TO - mirrorChars.put(0x2276, 0x2277); // LESS-THAN OR GREATER-THAN - mirrorChars.put(0x2277, 0x2276); // GREATER-THAN OR LESS-THAN - mirrorChars.put(0x2278, 0x2279); // NEITHER LESS-THAN NOR GREATER-THAN - mirrorChars.put(0x2279, 0x2278); // NEITHER GREATER-THAN NOR LESS-THAN - mirrorChars.put(0x227A, 0x227B); // PRECEDES - mirrorChars.put(0x227B, 0x227A); // SUCCEEDS - mirrorChars.put(0x227C, 0x227D); // PRECEDES OR EQUAL TO - mirrorChars.put(0x227D, 0x227C); // SUCCEEDS OR EQUAL TO - mirrorChars.put(0x227E, 0x227F); // [BEST FIT] PRECEDES OR EQUIVALENT TO - mirrorChars.put(0x227F, 0x227E); // [BEST FIT] SUCCEEDS OR EQUIVALENT TO - mirrorChars.put(0x2280, 0x2281); // [BEST FIT] DOES NOT PRECEDE - mirrorChars.put(0x2281, 0x2280); // [BEST FIT] DOES NOT SUCCEED - mirrorChars.put(0x2282, 0x2283); // SUBSET OF - mirrorChars.put(0x2283, 0x2282); // SUPERSET OF - mirrorChars.put(0x2284, 0x2285); // [BEST FIT] NOT A SUBSET OF - mirrorChars.put(0x2285, 0x2284); // [BEST FIT] NOT A SUPERSET OF - mirrorChars.put(0x2286, 0x2287); // SUBSET OF OR EQUAL TO - mirrorChars.put(0x2287, 0x2286); // SUPERSET OF OR EQUAL TO - mirrorChars.put(0x2288, 0x2289); // [BEST FIT] NEITHER A SUBSET OF NOR EQUAL TO - mirrorChars.put(0x2289, 0x2288); // [BEST FIT] NEITHER A SUPERSET OF NOR EQUAL TO - mirrorChars.put(0x228A, 0x228B); // [BEST FIT] SUBSET OF WITH NOT EQUAL TO - mirrorChars.put(0x228B, 0x228A); // [BEST FIT] SUPERSET OF WITH NOT EQUAL TO - mirrorChars.put(0x228F, 0x2290); // SQUARE IMAGE OF - mirrorChars.put(0x2290, 0x228F); // SQUARE ORIGINAL OF - mirrorChars.put(0x2291, 0x2292); // SQUARE IMAGE OF OR EQUAL TO - mirrorChars.put(0x2292, 0x2291); // SQUARE ORIGINAL OF OR EQUAL TO - mirrorChars.put(0x2298, 0x29B8); // CIRCLED DIVISION SLASH - mirrorChars.put(0x22A2, 0x22A3); // RIGHT TACK - mirrorChars.put(0x22A3, 0x22A2); // LEFT TACK - mirrorChars.put(0x22A6, 0x2ADE); // ASSERTION - mirrorChars.put(0x22A8, 0x2AE4); // TRUE - mirrorChars.put(0x22A9, 0x2AE3); // FORCES - mirrorChars.put(0x22AB, 0x2AE5); // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE - mirrorChars.put(0x22B0, 0x22B1); // PRECEDES UNDER RELATION - mirrorChars.put(0x22B1, 0x22B0); // SUCCEEDS UNDER RELATION - mirrorChars.put(0x22B2, 0x22B3); // NORMAL SUBGROUP OF - mirrorChars.put(0x22B3, 0x22B2); // CONTAINS AS NORMAL SUBGROUP - mirrorChars.put(0x22B4, 0x22B5); // NORMAL SUBGROUP OF OR EQUAL TO - mirrorChars.put(0x22B5, 0x22B4); // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - mirrorChars.put(0x22B6, 0x22B7); // ORIGINAL OF - mirrorChars.put(0x22B7, 0x22B6); // IMAGE OF - mirrorChars.put(0x22C9, 0x22CA); // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT - mirrorChars.put(0x22CA, 0x22C9); // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT - mirrorChars.put(0x22CB, 0x22CC); // LEFT SEMIDIRECT PRODUCT - mirrorChars.put(0x22CC, 0x22CB); // RIGHT SEMIDIRECT PRODUCT - mirrorChars.put(0x22CD, 0x2243); // REVERSED TILDE EQUALS - mirrorChars.put(0x22D0, 0x22D1); // DOUBLE SUBSET - mirrorChars.put(0x22D1, 0x22D0); // DOUBLE SUPERSET - mirrorChars.put(0x22D6, 0x22D7); // LESS-THAN WITH DOT - mirrorChars.put(0x22D7, 0x22D6); // GREATER-THAN WITH DOT - mirrorChars.put(0x22D8, 0x22D9); // VERY MUCH LESS-THAN - mirrorChars.put(0x22D9, 0x22D8); // VERY MUCH GREATER-THAN - mirrorChars.put(0x22DA, 0x22DB); // LESS-THAN EQUAL TO OR GREATER-THAN - mirrorChars.put(0x22DB, 0x22DA); // GREATER-THAN EQUAL TO OR LESS-THAN - mirrorChars.put(0x22DC, 0x22DD); // EQUAL TO OR LESS-THAN - mirrorChars.put(0x22DD, 0x22DC); // EQUAL TO OR GREATER-THAN - mirrorChars.put(0x22DE, 0x22DF); // EQUAL TO OR PRECEDES - mirrorChars.put(0x22DF, 0x22DE); // EQUAL TO OR SUCCEEDS - mirrorChars.put(0x22E0, 0x22E1); // [BEST FIT] DOES NOT PRECEDE OR EQUAL - mirrorChars.put(0x22E1, 0x22E0); // [BEST FIT] DOES NOT SUCCEED OR EQUAL - mirrorChars.put(0x22E2, 0x22E3); // [BEST FIT] NOT SQUARE IMAGE OF OR EQUAL TO - mirrorChars.put(0x22E3, 0x22E2); // [BEST FIT] NOT SQUARE ORIGINAL OF OR EQUAL TO - mirrorChars.put(0x22E4, 0x22E5); // [BEST FIT] SQUARE IMAGE OF OR NOT EQUAL TO - mirrorChars.put(0x22E5, 0x22E4); // [BEST FIT] SQUARE ORIGINAL OF OR NOT EQUAL TO - mirrorChars.put(0x22E6, 0x22E7); // [BEST FIT] LESS-THAN BUT NOT EQUIVALENT TO - mirrorChars.put(0x22E7, 0x22E6); // [BEST FIT] GREATER-THAN BUT NOT EQUIVALENT TO - mirrorChars.put(0x22E8, 0x22E9); // [BEST FIT] PRECEDES BUT NOT EQUIVALENT TO - mirrorChars.put(0x22E9, 0x22E8); // [BEST FIT] SUCCEEDS BUT NOT EQUIVALENT TO - mirrorChars.put(0x22EA, 0x22EB); // [BEST FIT] NOT NORMAL SUBGROUP OF - mirrorChars.put(0x22EB, 0x22EA); // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP - mirrorChars.put(0x22EC, 0x22ED); // [BEST FIT] NOT NORMAL SUBGROUP OF OR EQUAL TO - mirrorChars.put(0x22ED, 0x22EC); // [BEST FIT] DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - mirrorChars.put(0x22F0, 0x22F1); // UP RIGHT DIAGONAL ELLIPSIS - mirrorChars.put(0x22F1, 0x22F0); // DOWN RIGHT DIAGONAL ELLIPSIS - mirrorChars.put(0x22F2, 0x22FA); // ELEMENT OF WITH LONG HORIZONTAL STROKE - mirrorChars.put(0x22F3, 0x22FB); // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - mirrorChars.put(0x22F4, 0x22FC); // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - mirrorChars.put(0x22F6, 0x22FD); // ELEMENT OF WITH OVERBAR - mirrorChars.put(0x22F7, 0x22FE); // SMALL ELEMENT OF WITH OVERBAR - mirrorChars.put(0x22FA, 0x22F2); // CONTAINS WITH LONG HORIZONTAL STROKE - mirrorChars.put(0x22FB, 0x22F3); // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - mirrorChars.put(0x22FC, 0x22F4); // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - mirrorChars.put(0x22FD, 0x22F6); // CONTAINS WITH OVERBAR - mirrorChars.put(0x22FE, 0x22F7); // SMALL CONTAINS WITH OVERBAR - mirrorChars.put(0x2308, 0x2309); // LEFT CEILING - mirrorChars.put(0x2309, 0x2308); // RIGHT CEILING - mirrorChars.put(0x230A, 0x230B); // LEFT FLOOR - mirrorChars.put(0x230B, 0x230A); // RIGHT FLOOR - mirrorChars.put(0x2329, 0x232A); // LEFT-POINTING ANGLE BRACKET - mirrorChars.put(0x232A, 0x2329); // RIGHT-POINTING ANGLE BRACKET - mirrorChars.put(0x2768, 0x2769); // MEDIUM LEFT PARENTHESIS ORNAMENT - mirrorChars.put(0x2769, 0x2768); // MEDIUM RIGHT PARENTHESIS ORNAMENT - mirrorChars.put(0x276A, 0x276B); // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT - mirrorChars.put(0x276B, 0x276A); // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT - mirrorChars.put(0x276C, 0x276D); // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT - mirrorChars.put(0x276D, 0x276C); // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT - mirrorChars.put(0x276E, 0x276F); // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT - mirrorChars.put(0x276F, 0x276E); // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT - mirrorChars.put(0x2770, 0x2771); // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT - mirrorChars.put(0x2771, 0x2770); // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT - mirrorChars.put(0x2772, 0x2773); // LIGHT LEFT TORTOISE SHELL BRACKET - mirrorChars.put(0x2773, 0x2772); // LIGHT RIGHT TORTOISE SHELL BRACKET - mirrorChars.put(0x2774, 0x2775); // MEDIUM LEFT CURLY BRACKET ORNAMENT - mirrorChars.put(0x2775, 0x2774); // MEDIUM RIGHT CURLY BRACKET ORNAMENT - mirrorChars.put(0x27D5, 0x27D6); // LEFT OUTER JOIN - mirrorChars.put(0x27D6, 0x27D5); // RIGHT OUTER JOIN - mirrorChars.put(0x27DD, 0x27DE); // LONG RIGHT TACK - mirrorChars.put(0x27DE, 0x27DD); // LONG LEFT TACK - mirrorChars.put(0x27E2, 0x27E3); // WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK - mirrorChars.put(0x27E3, 0x27E2); // WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK - mirrorChars.put(0x27E4, 0x27E5); // WHITE SQUARE WITH LEFTWARDS TICK - mirrorChars.put(0x27E5, 0x27E4); // WHITE SQUARE WITH RIGHTWARDS TICK - mirrorChars.put(0x27E6, 0x27E7); // MATHEMATICAL LEFT WHITE SQUARE BRACKET - mirrorChars.put(0x27E7, 0x27E6); // MATHEMATICAL RIGHT WHITE SQUARE BRACKET - mirrorChars.put(0x27E8, 0x27E9); // MATHEMATICAL LEFT ANGLE BRACKET - mirrorChars.put(0x27E9, 0x27E8); // MATHEMATICAL RIGHT ANGLE BRACKET - mirrorChars.put(0x27EA, 0x27EB); // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET - mirrorChars.put(0x27EB, 0x27EA); // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET - mirrorChars.put(0x2983, 0x2984); // LEFT WHITE CURLY BRACKET - mirrorChars.put(0x2984, 0x2983); // RIGHT WHITE CURLY BRACKET - mirrorChars.put(0x2985, 0x2986); // LEFT WHITE PARENTHESIS - mirrorChars.put(0x2986, 0x2985); // RIGHT WHITE PARENTHESIS - mirrorChars.put(0x2987, 0x2988); // Z NOTATION LEFT IMAGE BRACKET - mirrorChars.put(0x2988, 0x2987); // Z NOTATION RIGHT IMAGE BRACKET - mirrorChars.put(0x2989, 0x298A); // Z NOTATION LEFT BINDING BRACKET - mirrorChars.put(0x298A, 0x2989); // Z NOTATION RIGHT BINDING BRACKET - mirrorChars.put(0x298B, 0x298C); // LEFT SQUARE BRACKET WITH UNDERBAR - mirrorChars.put(0x298C, 0x298B); // RIGHT SQUARE BRACKET WITH UNDERBAR - mirrorChars.put(0x298D, 0x2990); // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER - mirrorChars.put(0x298E, 0x298F); // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - mirrorChars.put(0x298F, 0x298E); // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - mirrorChars.put(0x2990, 0x298D); // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER - mirrorChars.put(0x2991, 0x2992); // LEFT ANGLE BRACKET WITH DOT - mirrorChars.put(0x2992, 0x2991); // RIGHT ANGLE BRACKET WITH DOT - mirrorChars.put(0x2993, 0x2994); // LEFT ARC LESS-THAN BRACKET - mirrorChars.put(0x2994, 0x2993); // RIGHT ARC GREATER-THAN BRACKET - mirrorChars.put(0x2995, 0x2996); // DOUBLE LEFT ARC GREATER-THAN BRACKET - mirrorChars.put(0x2996, 0x2995); // DOUBLE RIGHT ARC LESS-THAN BRACKET - mirrorChars.put(0x2997, 0x2998); // LEFT BLACK TORTOISE SHELL BRACKET - mirrorChars.put(0x2998, 0x2997); // RIGHT BLACK TORTOISE SHELL BRACKET - mirrorChars.put(0x29B8, 0x2298); // CIRCLED REVERSE SOLIDUS - mirrorChars.put(0x29C0, 0x29C1); // CIRCLED LESS-THAN - mirrorChars.put(0x29C1, 0x29C0); // CIRCLED GREATER-THAN - mirrorChars.put(0x29C4, 0x29C5); // SQUARED RISING DIAGONAL SLASH - mirrorChars.put(0x29C5, 0x29C4); // SQUARED FALLING DIAGONAL SLASH - mirrorChars.put(0x29CF, 0x29D0); // LEFT TRIANGLE BESIDE VERTICAL BAR - mirrorChars.put(0x29D0, 0x29CF); // VERTICAL BAR BESIDE RIGHT TRIANGLE - mirrorChars.put(0x29D1, 0x29D2); // BOWTIE WITH LEFT HALF BLACK - mirrorChars.put(0x29D2, 0x29D1); // BOWTIE WITH RIGHT HALF BLACK - mirrorChars.put(0x29D4, 0x29D5); // TIMES WITH LEFT HALF BLACK - mirrorChars.put(0x29D5, 0x29D4); // TIMES WITH RIGHT HALF BLACK - mirrorChars.put(0x29D8, 0x29D9); // LEFT WIGGLY FENCE - mirrorChars.put(0x29D9, 0x29D8); // RIGHT WIGGLY FENCE - mirrorChars.put(0x29DA, 0x29DB); // LEFT DOUBLE WIGGLY FENCE - mirrorChars.put(0x29DB, 0x29DA); // RIGHT DOUBLE WIGGLY FENCE - mirrorChars.put(0x29F5, 0x2215); // REVERSE SOLIDUS OPERATOR - mirrorChars.put(0x29F8, 0x29F9); // BIG SOLIDUS - mirrorChars.put(0x29F9, 0x29F8); // BIG REVERSE SOLIDUS - mirrorChars.put(0x29FC, 0x29FD); // LEFT-POINTING CURVED ANGLE BRACKET - mirrorChars.put(0x29FD, 0x29FC); // RIGHT-POINTING CURVED ANGLE BRACKET - mirrorChars.put(0x2A2B, 0x2A2C); // MINUS SIGN WITH FALLING DOTS - mirrorChars.put(0x2A2C, 0x2A2B); // MINUS SIGN WITH RISING DOTS - mirrorChars.put(0x2A2D, 0x2A2C); // PLUS SIGN IN LEFT HALF CIRCLE - mirrorChars.put(0x2A2E, 0x2A2D); // PLUS SIGN IN RIGHT HALF CIRCLE - mirrorChars.put(0x2A34, 0x2A35); // MULTIPLICATION SIGN IN LEFT HALF CIRCLE - mirrorChars.put(0x2A35, 0x2A34); // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE - mirrorChars.put(0x2A3C, 0x2A3D); // INTERIOR PRODUCT - mirrorChars.put(0x2A3D, 0x2A3C); // RIGHTHAND INTERIOR PRODUCT - mirrorChars.put(0x2A64, 0x2A65); // Z NOTATION DOMAIN ANTIRESTRICTION - mirrorChars.put(0x2A65, 0x2A64); // Z NOTATION RANGE ANTIRESTRICTION - mirrorChars.put(0x2A79, 0x2A7A); // LESS-THAN WITH CIRCLE INSIDE - mirrorChars.put(0x2A7A, 0x2A79); // GREATER-THAN WITH CIRCLE INSIDE - mirrorChars.put(0x2A7D, 0x2A7E); // LESS-THAN OR SLANTED EQUAL TO - mirrorChars.put(0x2A7E, 0x2A7D); // GREATER-THAN OR SLANTED EQUAL TO - mirrorChars.put(0x2A7F, 0x2A80); // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - mirrorChars.put(0x2A80, 0x2A7F); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - mirrorChars.put(0x2A81, 0x2A82); // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - mirrorChars.put(0x2A82, 0x2A81); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - mirrorChars.put(0x2A83, 0x2A84); // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT - mirrorChars.put(0x2A84, 0x2A83); // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT - mirrorChars.put(0x2A8B, 0x2A8C); // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN - mirrorChars.put(0x2A8C, 0x2A8B); // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN - mirrorChars.put(0x2A91, 0x2A92); // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL - mirrorChars.put(0x2A92, 0x2A91); // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL - mirrorChars.put(0x2A93, 0x2A94); // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL - mirrorChars.put(0x2A94, 0x2A93); // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL - mirrorChars.put(0x2A95, 0x2A96); // SLANTED EQUAL TO OR LESS-THAN - mirrorChars.put(0x2A96, 0x2A95); // SLANTED EQUAL TO OR GREATER-THAN - mirrorChars.put(0x2A97, 0x2A98); // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE - mirrorChars.put(0x2A98, 0x2A97); // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE - mirrorChars.put(0x2A99, 0x2A9A); // DOUBLE-LINE EQUAL TO OR LESS-THAN - mirrorChars.put(0x2A9A, 0x2A99); // DOUBLE-LINE EQUAL TO OR GREATER-THAN - mirrorChars.put(0x2A9B, 0x2A9C); // DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN - mirrorChars.put(0x2A9C, 0x2A9B); // DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN - mirrorChars.put(0x2AA1, 0x2AA2); // DOUBLE NESTED LESS-THAN - mirrorChars.put(0x2AA2, 0x2AA1); // DOUBLE NESTED GREATER-THAN - mirrorChars.put(0x2AA6, 0x2AA7); // LESS-THAN CLOSED BY CURVE - mirrorChars.put(0x2AA7, 0x2AA6); // GREATER-THAN CLOSED BY CURVE - mirrorChars.put(0x2AA8, 0x2AA9); // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - mirrorChars.put(0x2AA9, 0x2AA8); // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - mirrorChars.put(0x2AAA, 0x2AAB); // SMALLER THAN - mirrorChars.put(0x2AAB, 0x2AAA); // LARGER THAN - mirrorChars.put(0x2AAC, 0x2AAD); // SMALLER THAN OR EQUAL TO - mirrorChars.put(0x2AAD, 0x2AAC); // LARGER THAN OR EQUAL TO - mirrorChars.put(0x2AAF, 0x2AB0); // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - mirrorChars.put(0x2AB0, 0x2AAF); // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - mirrorChars.put(0x2AB3, 0x2AB4); // PRECEDES ABOVE EQUALS SIGN - mirrorChars.put(0x2AB4, 0x2AB3); // SUCCEEDS ABOVE EQUALS SIGN - mirrorChars.put(0x2ABB, 0x2ABC); // DOUBLE PRECEDES - mirrorChars.put(0x2ABC, 0x2ABB); // DOUBLE SUCCEEDS - mirrorChars.put(0x2ABD, 0x2ABE); // SUBSET WITH DOT - mirrorChars.put(0x2ABE, 0x2ABD); // SUPERSET WITH DOT - mirrorChars.put(0x2ABF, 0x2AC0); // SUBSET WITH PLUS SIGN BELOW - mirrorChars.put(0x2AC0, 0x2ABF); // SUPERSET WITH PLUS SIGN BELOW - mirrorChars.put(0x2AC1, 0x2AC2); // SUBSET WITH MULTIPLICATION SIGN BELOW - mirrorChars.put(0x2AC2, 0x2AC1); // SUPERSET WITH MULTIPLICATION SIGN BELOW - mirrorChars.put(0x2AC3, 0x2AC4); // SUBSET OF OR EQUAL TO WITH DOT ABOVE - mirrorChars.put(0x2AC4, 0x2AC3); // SUPERSET OF OR EQUAL TO WITH DOT ABOVE - mirrorChars.put(0x2AC5, 0x2AC6); // SUBSET OF ABOVE EQUALS SIGN - mirrorChars.put(0x2AC6, 0x2AC5); // SUPERSET OF ABOVE EQUALS SIGN - mirrorChars.put(0x2ACD, 0x2ACE); // SQUARE LEFT OPEN BOX OPERATOR - mirrorChars.put(0x2ACE, 0x2ACD); // SQUARE RIGHT OPEN BOX OPERATOR - mirrorChars.put(0x2ACF, 0x2AD0); // CLOSED SUBSET - mirrorChars.put(0x2AD0, 0x2ACF); // CLOSED SUPERSET - mirrorChars.put(0x2AD1, 0x2AD2); // CLOSED SUBSET OR EQUAL TO - mirrorChars.put(0x2AD2, 0x2AD1); // CLOSED SUPERSET OR EQUAL TO - mirrorChars.put(0x2AD3, 0x2AD4); // SUBSET ABOVE SUPERSET - mirrorChars.put(0x2AD4, 0x2AD3); // SUPERSET ABOVE SUBSET - mirrorChars.put(0x2AD5, 0x2AD6); // SUBSET ABOVE SUBSET - mirrorChars.put(0x2AD6, 0x2AD5); // SUPERSET ABOVE SUPERSET - mirrorChars.put(0x2ADE, 0x22A6); // SHORT LEFT TACK - mirrorChars.put(0x2AE3, 0x22A9); // DOUBLE VERTICAL BAR LEFT TURNSTILE - mirrorChars.put(0x2AE4, 0x22A8); // VERTICAL BAR DOUBLE LEFT TURNSTILE - mirrorChars.put(0x2AE5, 0x22AB); // DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE - mirrorChars.put(0x2AEC, 0x2AED); // DOUBLE STROKE NOT SIGN - mirrorChars.put(0x2AED, 0x2AEC); // REVERSED DOUBLE STROKE NOT SIGN - mirrorChars.put(0x2AF7, 0x2AF8); // TRIPLE NESTED LESS-THAN - mirrorChars.put(0x2AF8, 0x2AF7); // TRIPLE NESTED GREATER-THAN - mirrorChars.put(0x2AF9, 0x2AFA); // DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO - mirrorChars.put(0x2AFA, 0x2AF9); // DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO - mirrorChars.put(0x3008, 0x3009); // LEFT ANGLE BRACKET - mirrorChars.put(0x3009, 0x3008); // RIGHT ANGLE BRACKET - mirrorChars.put(0x300A, 0x300B); // LEFT DOUBLE ANGLE BRACKET - mirrorChars.put(0x300B, 0x300A); // RIGHT DOUBLE ANGLE BRACKET - mirrorChars.put(0x300C, 0x300D); // [BEST FIT] LEFT CORNER BRACKET - mirrorChars.put(0x300D, 0x300C); // [BEST FIT] RIGHT CORNER BRACKET - mirrorChars.put(0x300E, 0x300F); // [BEST FIT] LEFT WHITE CORNER BRACKET - mirrorChars.put(0x300F, 0x300E); // [BEST FIT] RIGHT WHITE CORNER BRACKET - mirrorChars.put(0x3010, 0x3011); // LEFT BLACK LENTICULAR BRACKET - mirrorChars.put(0x3011, 0x3010); // RIGHT BLACK LENTICULAR BRACKET - mirrorChars.put(0x3014, 0x3015); // LEFT TORTOISE SHELL BRACKET - mirrorChars.put(0x3015, 0x3014); // RIGHT TORTOISE SHELL BRACKET - mirrorChars.put(0x3016, 0x3017); // LEFT WHITE LENTICULAR BRACKET - mirrorChars.put(0x3017, 0x3016); // RIGHT WHITE LENTICULAR BRACKET - mirrorChars.put(0x3018, 0x3019); // LEFT WHITE TORTOISE SHELL BRACKET - mirrorChars.put(0x3019, 0x3018); // RIGHT WHITE TORTOISE SHELL BRACKET - mirrorChars.put(0x301A, 0x301B); // LEFT WHITE SQUARE BRACKET - mirrorChars.put(0x301B, 0x301A); // RIGHT WHITE SQUARE BRACKET - mirrorChars.put(0xFF08, 0xFF09); // FULLWIDTH LEFT PARENTHESIS - mirrorChars.put(0xFF09, 0xFF08); // FULLWIDTH RIGHT PARENTHESIS - mirrorChars.put(0xFF1C, 0xFF1E); // FULLWIDTH LESS-THAN SIGN - mirrorChars.put(0xFF1E, 0xFF1C); // FULLWIDTH GREATER-THAN SIGN - mirrorChars.put(0xFF3B, 0xFF3D); // FULLWIDTH LEFT SQUARE BRACKET - mirrorChars.put(0xFF3D, 0xFF3B); // FULLWIDTH RIGHT SQUARE BRACKET - mirrorChars.put(0xFF5B, 0xFF5D); // FULLWIDTH LEFT CURLY BRACKET - mirrorChars.put(0xFF5D, 0xFF5B); // FULLWIDTH RIGHT CURLY BRACKET - mirrorChars.put(0xFF5F, 0xFF60); // FULLWIDTH LEFT WHITE PARENTHESIS - mirrorChars.put(0xFF60, 0xFF5F); // FULLWIDTH RIGHT WHITE PARENTHESIS - mirrorChars.put(0xFF62, 0xFF63); // [BEST FIT] HALFWIDTH LEFT CORNER BRACKET - mirrorChars.put(0xFF63, 0xFF62); // [BEST FIT] HALFWIDTH RIGHT CORNER BRACKET - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/BidiOrder.java b/src/main/java/com/lowagie/text/pdf/BidiOrder.java deleted file mode 100644 index 97f9f74..0000000 --- a/src/main/java/com/lowagie/text/pdf/BidiOrder.java +++ /dev/null @@ -1,1240 +0,0 @@ -package com.lowagie.text.pdf; - -/* - * - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -/* - * (C) Copyright IBM Corp. 1999, All Rights Reserved - * - * version 1.1 - */ - -/** - * Reference implementation of the Unicode 3.0 Bidi algorithm. - * - *

- * This implementation is not optimized for performance. It is intended - * as a reference implementation that closely follows the specification - * of the Bidirectional Algorithm in The Unicode Standard version 3.0. - *

- * Input:
- * There are two levels of input to the algorithm, since clients may prefer - * to supply some information from out-of-band sources rather than relying on - * the default behavior. - *

    - *
  1. unicode type array - *
  2. unicode type array, with externally supplied base line direction - *
- *

Output:
- * Output is separated into several stages as well, to better enable clients - * to evaluate various aspects of implementation conformance. - *

    - *
  1. levels array over entire paragraph - *
  2. reordering array over entire paragraph - *
  3. levels array over line - *
  4. reordering array over line - *
- * Note that for conformance, algorithms are only required to generate correct - * reordering and character directionality (odd or even levels) over a line. - * Generating identical level arrays over a line is not required. Bidi - * explicit format codes (LRE, RLE, LRO, RLO, PDF) and BN can be assigned - * arbitrary levels and positions as long as the other text matches. - *

- * As the algorithm is defined to operate on a single paragraph at a time, - * this implementation is written to handle single paragraphs. Thus - * rule P1 is presumed by this implementation-- the data provided to the - * implementation is assumed to be a single paragraph, and either contains no - * 'B' codes, or a single 'B' code at the end of the input. 'B' is allowed - * as input to illustrate how the algorithm assigns it a level. - *

- * Also note that rules L3 and L4 depend on the rendering engine that uses - * the result of the bidi algorithm. This implementation assumes that the - * rendering engine expects combining marks in visual order (e.g. to the - * left of their base character in RTL runs) and that it adjust the glyphs - * used to render mirrored characters that are in RTL runs so that they - * render appropriately. - * - * @author Doug Felt - */ - -public final class BidiOrder { - private byte[] initialTypes; - private byte[] embeddings; // generated from processing format codes - private byte paragraphEmbeddingLevel = -1; // undefined - - private int textLength; // for convenience - private byte[] resultTypes; // for paragraph, not lines - private byte[] resultLevels; // for paragraph, not lines - - // The bidi types - - /** Left-to-right*/ - public static final byte L = 0; - - /** Left-to-Right Embedding */ - public static final byte LRE = 1; - - /** Left-to-Right Override */ - public static final byte LRO = 2; - - /** Right-to-Left */ - public static final byte R = 3; - - /** Right-to-Left Arabic */ - public static final byte AL = 4; - - /** Right-to-Left Embedding */ - public static final byte RLE = 5; - - /** Right-to-Left Override */ - public static final byte RLO = 6; - - /** Pop Directional Format */ - public static final byte PDF = 7; - - /** European Number */ - public static final byte EN = 8; - - /** European Number Separator */ - public static final byte ES = 9; - - /** European Number Terminator */ - public static final byte ET = 10; - - /** Arabic Number */ - public static final byte AN = 11; - - /** Common Number Separator */ - public static final byte CS = 12; - - /** Non-Spacing Mark */ - public static final byte NSM = 13; - - /** Boundary Neutral */ - public static final byte BN = 14; - - /** Paragraph Separator */ - public static final byte B = 15; - - /** Segment Separator */ - public static final byte S = 16; - - /** Whitespace */ - public static final byte WS = 17; - - /** Other Neutrals */ - public static final byte ON = 18; - - /** Minimum bidi type value. */ - public static final byte TYPE_MIN = 0; - - /** Maximum bidi type value. */ - public static final byte TYPE_MAX = 18; - - // - // Input - // - - /** - * Initialize using an array of direction types. Types range from TYPE_MIN to TYPE_MAX inclusive - * and represent the direction codes of the characters in the text. - * - * @param types the types array - */ - public BidiOrder(byte[] types) { - validateTypes(types); - - this.initialTypes = (byte[])types.clone(); // client type array remains unchanged - - runAlgorithm(); - } - - /** - * Initialize using an array of direction types and an externally supplied paragraph embedding level. - * The embedding level may be -1, 0, or 1. -1 means to apply the default algorithm (rules P2 and P3), - * 0 is for LTR paragraphs, and 1 is for RTL paragraphs. - * - * @param types the types array - * @param paragraphEmbeddingLevel the externally supplied paragraph embedding level. - */ - public BidiOrder(byte[] types, byte paragraphEmbeddingLevel) { - validateTypes(types); - validateParagraphEmbeddingLevel(paragraphEmbeddingLevel); - - this.initialTypes = (byte[])types.clone(); // client type array remains unchanged - this.paragraphEmbeddingLevel = paragraphEmbeddingLevel; - - runAlgorithm(); - } - - public BidiOrder(char text[], int offset, int length, byte paragraphEmbeddingLevel) { - initialTypes = new byte[length]; - for (int k = 0; k < length; ++k) { - initialTypes[k] = rtypes[text[offset + k]]; - } - validateParagraphEmbeddingLevel(paragraphEmbeddingLevel); - - this.paragraphEmbeddingLevel = paragraphEmbeddingLevel; - - runAlgorithm(); - } - - public final static byte getDirection(char c) { - return rtypes[c]; - } - - /** - * The algorithm. - * Does not include line-based processing (Rules L1, L2). - * These are applied later in the line-based phase of the algorithm. - */ - private void runAlgorithm() { - textLength = initialTypes.length; - - // Initialize output types. - // Result types initialized to input types. - resultTypes = (byte[])initialTypes.clone(); - - - // 1) determining the paragraph level - // Rule P1 is the requirement for entering this algorithm. - // Rules P2, P3. - // If no externally supplied paragraph embedding level, use default. - if (paragraphEmbeddingLevel == -1) { - determineParagraphEmbeddingLevel(); - } - - // Initialize result levels to paragraph embedding level. - resultLevels = new byte[textLength]; - setLevels(0, textLength, paragraphEmbeddingLevel); - - // 2) Explicit levels and directions - // Rules X1-X8. - determineExplicitEmbeddingLevels(); - - // Rule X9. - textLength = removeExplicitCodes(); - - // Rule X10. - // Run remainder of algorithm one level run at a time - byte prevLevel = paragraphEmbeddingLevel; - int start = 0; - while (start < textLength) { - byte level = resultLevels[start]; - byte prevType = typeForLevel(Math.max(prevLevel, level)); - - int limit = start + 1; - while (limit < textLength && resultLevels[limit] == level) { - ++limit; - } - - byte succLevel = limit < textLength ? resultLevels[limit] : paragraphEmbeddingLevel; - byte succType = typeForLevel(Math.max(succLevel, level)); - - // 3) resolving weak types - // Rules W1-W7. - resolveWeakTypes(start, limit, level, prevType, succType); - - // 4) resolving neutral types - // Rules N1-N3. - resolveNeutralTypes(start, limit, level, prevType, succType); - - // 5) resolving implicit embedding levels - // Rules I1, I2. - resolveImplicitLevels(start, limit, level, prevType, succType); - - prevLevel = level; - start = limit; - } - - // Reinsert explicit codes and assign appropriate levels to 'hide' them. - // This is for convenience, so the resulting level array maps 1-1 - // with the initial array. - // See the implementation suggestions section of TR#9 for guidelines on - // how to implement the algorithm without removing and reinserting the codes. - textLength = reinsertExplicitCodes(textLength); - } - - /** - * 1) determining the paragraph level. - *

- * Rules P2, P3. - *

- * At the end of this function, the member variable paragraphEmbeddingLevel is set to either 0 or 1. - */ - private void determineParagraphEmbeddingLevel() { - byte strongType = -1; // unknown - - // Rule P2. - for (int i = 0; i < textLength; ++i) { - byte t = resultTypes[i]; - if (t == L || t == AL || t == R) { - strongType = t; - break; - } - } - - // Rule P3. - if (strongType == -1) { // none found - // default embedding level when no strong types found is 0. - paragraphEmbeddingLevel = 0; - } else if (strongType == L) { - paragraphEmbeddingLevel = 0; - } else { // AL, R - paragraphEmbeddingLevel = 1; - } - } - - /** - * Process embedding format codes. - *

- * Calls processEmbeddings to generate an embedding array from the explicit format codes. The - * embedding overrides in the array are then applied to the result types, and the result levels are - * initialized. - * @see #processEmbeddings - */ - private void determineExplicitEmbeddingLevels() { - embeddings = processEmbeddings(resultTypes, paragraphEmbeddingLevel); - - for (int i = 0; i < textLength; ++i) { - byte level = embeddings[i]; - if ((level & 0x80) != 0) { - level &= 0x7f; - resultTypes[i] = typeForLevel(level); - } - resultLevels[i] = level; - } - } - - /** - * Rules X9. - * Remove explicit codes so that they may be ignored during the remainder - * of the main portion of the algorithm. The length of the resulting text - * is returned. - * @return the length of the data excluding explicit codes and BN. - */ - private int removeExplicitCodes() { - int w = 0; - for (int i = 0; i < textLength; ++i) { - byte t = initialTypes[i]; - if (!(t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN)) { - embeddings[w] = embeddings[i]; - resultTypes[w] = resultTypes[i]; - resultLevels[w] = resultLevels[i]; - w++; - } - } - return w; // new textLength while explicit levels are removed - } - - /** - * Reinsert levels information for explicit codes. - * This is for ease of relating the level information - * to the original input data. Note that the levels - * assigned to these codes are arbitrary, they're - * chosen so as to avoid breaking level runs. - * @param textLength the length of the data after compression - * @return the length of the data (original length of - * types array supplied to constructor) - */ - private int reinsertExplicitCodes(int textLength) { - for (int i = initialTypes.length; --i >= 0;) { - byte t = initialTypes[i]; - if (t == LRE || t == RLE || t == LRO || t == RLO || t == PDF || t == BN) { - embeddings[i] = 0; - resultTypes[i] = t; - resultLevels[i] = -1; - } else { - --textLength; - embeddings[i] = embeddings[textLength]; - resultTypes[i] = resultTypes[textLength]; - resultLevels[i] = resultLevels[textLength]; - } - } - - // now propagate forward the levels information (could have - // propagated backward, the main thing is not to introduce a level - // break where one doesn't already exist). - - if (resultLevels[0] == -1) { - resultLevels[0] = paragraphEmbeddingLevel; - } - for (int i = 1; i < initialTypes.length; ++i) { - if (resultLevels[i] == -1) { - resultLevels[i] = resultLevels[i-1]; - } - } - - // Embedding information is for informational purposes only - // so need not be adjusted. - - return initialTypes.length; - } - - /** - * 2) determining explicit levels - * Rules X1 - X8 - * - * The interaction of these rules makes handling them a bit complex. - * This examines resultTypes but does not modify it. It returns embedding and - * override information in the result array. The low 7 bits are the level, the high - * bit is set if the level is an override, and clear if it is an embedding. - */ - private static byte[] processEmbeddings(byte[] resultTypes, byte paragraphEmbeddingLevel) { - final int EXPLICIT_LEVEL_LIMIT = 62; - - int textLength = resultTypes.length; - byte[] embeddings = new byte[textLength]; - - // This stack will store the embedding levels and override status in a single byte - // as described above. - byte[] embeddingValueStack = new byte[EXPLICIT_LEVEL_LIMIT]; - int stackCounter = 0; - - // An LRE or LRO at level 60 is invalid, since the new level 62 is invalid. But - // an RLE at level 60 is valid, since the new level 61 is valid. The current wording - // of the rules requires that the RLE remain valid even if a previous LRE is invalid. - // This keeps track of ignored LRE or LRO codes at level 60, so that the matching PDFs - // will not try to pop the stack. - int overflowAlmostCounter = 0; - - // This keeps track of ignored pushes at level 61 or higher, so that matching PDFs will - // not try to pop the stack. - int overflowCounter = 0; - - // Rule X1. - - // Keep the level separate from the value (level | override status flag) for ease of access. - byte currentEmbeddingLevel = paragraphEmbeddingLevel; - byte currentEmbeddingValue = paragraphEmbeddingLevel; - - // Loop through types, handling all remaining rules - for (int i = 0; i < textLength; ++i) { - - embeddings[i] = currentEmbeddingValue; - - byte t = resultTypes[i]; - - // Rules X2, X3, X4, X5 - switch (t) { - case RLE: - case LRE: - case RLO: - case LRO: - // Only need to compute new level if current level is valid - if (overflowCounter == 0) { - byte newLevel; - if (t == RLE || t == RLO) { - newLevel = (byte)((currentEmbeddingLevel + 1) | 1); // least greater odd - } else { // t == LRE || t == LRO - newLevel = (byte)((currentEmbeddingLevel + 2) & ~1); // least greater even - } - - // If the new level is valid, push old embedding level and override status - // No check for valid stack counter, since the level check suffices. - if (newLevel < EXPLICIT_LEVEL_LIMIT) { - embeddingValueStack[stackCounter] = currentEmbeddingValue; - stackCounter++; - - currentEmbeddingLevel = newLevel; - if (t == LRO || t == RLO) { // override - currentEmbeddingValue = (byte)(newLevel | 0x80); - } else { - currentEmbeddingValue = newLevel; - } - - // Adjust level of format mark (for expositional purposes only, this gets - // removed later). - embeddings[i] = currentEmbeddingValue; - break; - } - - // Otherwise new level is invalid, but a valid level can still be achieved if this - // level is 60 and we encounter an RLE or RLO further on. So record that we - // 'almost' overflowed. - if (currentEmbeddingLevel == 60) { - overflowAlmostCounter++; - break; - } - } - - // Otherwise old or new level is invalid. - overflowCounter++; - break; - - case PDF: - // The only case where this did not actually overflow but may have almost overflowed - // is when there was an RLE or RLO on level 60, which would result in level 61. So we - // only test the almost overflow condition in that case. - // - // Also note that there may be a PDF without any pushes at all. - - if (overflowCounter > 0) { - --overflowCounter; - } else if (overflowAlmostCounter > 0 && currentEmbeddingLevel != 61) { - --overflowAlmostCounter; - } else if (stackCounter > 0) { - --stackCounter; - currentEmbeddingValue = embeddingValueStack[stackCounter]; - currentEmbeddingLevel = (byte)(currentEmbeddingValue & 0x7f); - } - break; - - case B: - // Rule X8. - - // These values are reset for clarity, in this implementation B can only - // occur as the last code in the array. - stackCounter = 0; - overflowCounter = 0; - overflowAlmostCounter = 0; - currentEmbeddingLevel = paragraphEmbeddingLevel; - currentEmbeddingValue = paragraphEmbeddingLevel; - - embeddings[i] = paragraphEmbeddingLevel; - break; - - default: - break; - } - } - - return embeddings; - } - - - /** - * 3) resolving weak types - * Rules W1-W7. - * - * Note that some weak types (EN, AN) remain after this processing is complete. - */ - private void resolveWeakTypes(int start, int limit, byte level, byte sor, byte eor) { - - // Rule W1. - // Changes all NSMs. - byte preceedingCharacterType = sor; - for (int i = start; i < limit; ++i) { - byte t = resultTypes[i]; - if (t == NSM) { - resultTypes[i] = preceedingCharacterType; - } else { - preceedingCharacterType = t; - } - } - - // Rule W2. - // EN does not change at the start of the run, because sor != AL. - for (int i = start; i < limit; ++i) { - if (resultTypes[i] == EN) { - for (int j = i - 1; j >= start; --j) { - byte t = resultTypes[j]; - if (t == L || t == R || t == AL) { - if (t == AL) { - resultTypes[i] = AN; - } - break; - } - } - } - } - - // Rule W3. - for (int i = start; i < limit; ++i) { - if (resultTypes[i] == AL) { - resultTypes[i] = R; - } - } - - // Rule W4. - // Since there must be values on both sides for this rule to have an - // effect, the scan skips the first and last value. - // - // Although the scan proceeds left to right, and changes the type values - // in a way that would appear to affect the computations later in the scan, - // there is actually no problem. A change in the current value can only - // affect the value to its immediate right, and only affect it if it is - // ES or CS. But the current value can only change if the value to its - // right is not ES or CS. Thus either the current value will not change, - // or its change will have no effect on the remainder of the analysis. - - for (int i = start + 1; i < limit - 1; ++i) { - if (resultTypes[i] == ES || resultTypes[i] == CS) { - byte prevSepType = resultTypes[i-1]; - byte succSepType = resultTypes[i+1]; - if (prevSepType == EN && succSepType == EN) { - resultTypes[i] = EN; - } else if (resultTypes[i] == CS && prevSepType == AN && succSepType == AN) { - resultTypes[i] = AN; - } - } - } - - // Rule W5. - for (int i = start; i < limit; ++i) { - if (resultTypes[i] == ET) { - // locate end of sequence - int runstart = i; - int runlimit = findRunLimit(runstart, limit, new byte[] { ET }); - - // check values at ends of sequence - byte t = runstart == start ? sor : resultTypes[runstart - 1]; - - if (t != EN) { - t = runlimit == limit ? eor : resultTypes[runlimit]; - } - - if (t == EN) { - setTypes(runstart, runlimit, EN); - } - - // continue at end of sequence - i = runlimit; - } - } - - // Rule W6. - for (int i = start; i < limit; ++i) { - byte t = resultTypes[i]; - if (t == ES || t == ET || t == CS) { - resultTypes[i] = ON; - } - } - - // Rule W7. - for (int i = start; i < limit; ++i) { - if (resultTypes[i] == EN) { - // set default if we reach start of run - byte prevStrongType = sor; - for (int j = i - 1; j >= start; --j) { - byte t = resultTypes[j]; - if (t == L || t == R) { // AL's have been removed - prevStrongType = t; - break; - } - } - if (prevStrongType == L) { - resultTypes[i] = L; - } - } - } - } - - /** - * 6) resolving neutral types - * Rules N1-N2. - */ - private void resolveNeutralTypes(int start, int limit, byte level, byte sor, byte eor) { - - for (int i = start; i < limit; ++i) { - byte t = resultTypes[i]; - if (t == WS || t == ON || t == B || t == S) { - // find bounds of run of neutrals - int runstart = i; - int runlimit = findRunLimit(runstart, limit, new byte[] {B, S, WS, ON}); - - // determine effective types at ends of run - byte leadingType; - byte trailingType; - - if (runstart == start) { - leadingType = sor; - } else { - leadingType = resultTypes[runstart - 1]; - if (leadingType == L || leadingType == R) { - // found the strong type - } else if (leadingType == AN) { - leadingType = R; - } else if (leadingType == EN) { - // Since EN's with previous strong L types have been changed - // to L in W7, the leadingType must be R. - leadingType = R; - } - } - - if (runlimit == limit) { - trailingType = eor; - } else { - trailingType = resultTypes[runlimit]; - if (trailingType == L || trailingType == R) { - // found the strong type - } else if (trailingType == AN) { - trailingType = R; - } else if (trailingType == EN) { - trailingType = R; - } - } - - byte resolvedType; - if (leadingType == trailingType) { - // Rule N1. - resolvedType = leadingType; - } else { - // Rule N2. - // Notice the embedding level of the run is used, not - // the paragraph embedding level. - resolvedType = typeForLevel(level); - } - - setTypes(runstart, runlimit, resolvedType); - - // skip over run of (former) neutrals - i = runlimit; - } - } - } - - /** - * 7) resolving implicit embedding levels - * Rules I1, I2. - */ - private void resolveImplicitLevels(int start, int limit, byte level, byte sor, byte eor) { - if ((level & 1) == 0) { // even level - for (int i = start; i < limit; ++i) { - byte t = resultTypes[i]; - // Rule I1. - if (t == L ) { - // no change - } else if (t == R) { - resultLevels[i] += 1; - } else { // t == AN || t == EN - resultLevels[i] += 2; - } - } - } else { // odd level - for (int i = start; i < limit; ++i) { - byte t = resultTypes[i]; - // Rule I2. - if (t == R) { - // no change - } else { // t == L || t == AN || t == EN - resultLevels[i] += 1; - } - } - } - } - - // - // Output - // - - public byte[] getLevels() { - return getLevels(new int[]{textLength}); - } - - /** - * Return levels array breaking lines at offsets in linebreaks.
- * Rule L1. - *

- * The returned levels array contains the resolved level for each - * bidi code passed to the constructor. - *

- * The linebreaks array must include at least one value. - * The values must be in strictly increasing order (no duplicates) - * between 1 and the length of the text, inclusive. The last value - * must be the length of the text. - * - * @param linebreaks the offsets at which to break the paragraph - * @return the resolved levels of the text - */ - public byte[] getLevels(int[] linebreaks) { - - // Note that since the previous processing has removed all - // P, S, and WS values from resultTypes, the values referred to - // in these rules are the initial types, before any processing - // has been applied (including processing of overrides). - // - // This example implementation has reinserted explicit format codes - // and BN, in order that the levels array correspond to the - // initial text. Their final placement is not normative. - // These codes are treated like WS in this implementation, - // so they don't interrupt sequences of WS. - - validateLineBreaks(linebreaks, textLength); - - byte[] result = (byte[])resultLevels.clone(); // will be returned to caller - - // don't worry about linebreaks since if there is a break within - // a series of WS values preceeding S, the linebreak itself - // causes the reset. - for (int i = 0; i < result.length; ++i) { - byte t = initialTypes[i]; - if (t == B || t == S) { - // Rule L1, clauses one and two. - result[i] = paragraphEmbeddingLevel; - - // Rule L1, clause three. - for (int j = i - 1; j >= 0; --j) { - if (isWhitespace(initialTypes[j])) { // including format codes - result[j] = paragraphEmbeddingLevel; - } else { - break; - } - } - } - } - - // Rule L1, clause four. - int start = 0; - for (int i = 0; i < linebreaks.length; ++i) { - int limit = linebreaks[i]; - for (int j = limit - 1; j >= start; --j) { - if (isWhitespace(initialTypes[j])) { // including format codes - result[j] = paragraphEmbeddingLevel; - } else { - break; - } - } - - start = limit; - } - - return result; - } - - /** - * Return reordering array breaking lines at offsets in linebreaks. - *

- * The reordering array maps from a visual index to a logical index. - * Lines are concatenated from left to right. So for example, the - * fifth character from the left on the third line is - *

 getReordering(linebreaks)[linebreaks[1] + 4]
- * (linebreaks[1] is the position after the last character of the - * second line, which is also the index of the first character on the - * third line, and adding four gets the fifth character from the left). - *

- * The linebreaks array must include at least one value. - * The values must be in strictly increasing order (no duplicates) - * between 1 and the length of the text, inclusive. The last value - * must be the length of the text. - * - * @param linebreaks the offsets at which to break the paragraph. - */ - public int[] getReordering(int[] linebreaks) { - validateLineBreaks(linebreaks, textLength); - - byte[] levels = getLevels(linebreaks); - - return computeMultilineReordering(levels, linebreaks); - } - - /** - * Return multiline reordering array for a given level array. - * Reordering does not occur across a line break. - */ - private static int[] computeMultilineReordering(byte[] levels, int[] linebreaks) { - int[] result = new int[levels.length]; - - int start = 0; - for (int i = 0; i < linebreaks.length; ++i) { - int limit = linebreaks[i]; - - byte[] templevels = new byte[limit - start]; - System.arraycopy(levels, start, templevels, 0, templevels.length); - - int[] temporder = computeReordering(templevels); - for (int j = 0; j < temporder.length; ++j) { - result[start + j] = temporder[j] + start; - } - - start = limit; - } - - return result; - } - - /** - * Return reordering array for a given level array. This reorders a single line. - * The reordering is a visual to logical map. For example, - * the leftmost char is string.charAt(order[0]). - * Rule L2. - */ - private static int[] computeReordering(byte[] levels) { - int lineLength = levels.length; - - int[] result = new int[lineLength]; - - // initialize order - for (int i = 0; i < lineLength; ++i) { - result[i] = i; - } - - // locate highest level found on line. - // Note the rules say text, but no reordering across line bounds is performed, - // so this is sufficient. - byte highestLevel = 0; - byte lowestOddLevel = 63; - for (int i = 0; i < lineLength; ++i) { - byte level = levels[i]; - if (level > highestLevel) { - highestLevel = level; - } - if (((level & 1) != 0) && level < lowestOddLevel) { - lowestOddLevel = level; - } - } - - for (int level = highestLevel; level >= lowestOddLevel; --level) { - for (int i = 0; i < lineLength; ++i) { - if (levels[i] >= level) { - // find range of text at or above this level - int start = i; - int limit = i + 1; - while (limit < lineLength && levels[limit] >= level) { - ++limit; - } - - // reverse run - for (int j = start, k = limit - 1; j < k; ++j, --k) { - int temp = result[j]; - result[j] = result[k]; - result[k] = temp; - } - - // skip to end of level run - i = limit; - } - } - } - - return result; - } - - /** - * Return the base level of the paragraph. - */ - public byte getBaseLevel() { - return paragraphEmbeddingLevel; - } - - // --- internal utilities ------------------------------------------------- - - /** - * Return true if the type is considered a whitespace type for the line break rules. - */ - private static boolean isWhitespace(byte biditype) { - switch (biditype) { - case LRE: - case RLE: - case LRO: - case RLO: - case PDF: - case BN: - case WS: - return true; - default: - return false; - } - } - - /** - * Return the strong type (L or R) corresponding to the level. - */ - private static byte typeForLevel(int level) { - return ((level & 0x1) == 0) ? L : R; - } - - /** - * Return the limit of the run starting at index that includes only resultTypes in validSet. - * This checks the value at index, and will return index if that value is not in validSet. - */ - private int findRunLimit(int index, int limit, byte[] validSet) { - --index; - loop: - while (++index < limit) { - byte t = resultTypes[index]; - for (int i = 0; i < validSet.length; ++i) { - if (t == validSet[i]) { - continue loop; - } - } - // didn't find a match in validSet - return index; - } - return limit; - } - - /** - * Return the start of the run including index that includes only resultTypes in validSet. - * This assumes the value at index is valid, and does not check it. - */ - private int findRunStart(int index, byte[] validSet) { - loop: - while (--index >= 0) { - byte t = resultTypes[index]; - for (int i = 0; i < validSet.length; ++i) { - if (t == validSet[i]) { - continue loop; - } - } - return index + 1; - } - return 0; - } - - /** - * Set resultTypes from start up to (but not including) limit to newType. - */ - private void setTypes(int start, int limit, byte newType) { - for (int i = start; i < limit; ++i) { - resultTypes[i] = newType; - } - } - - /** - * Set resultLevels from start up to (but not including) limit to newLevel. - */ - private void setLevels(int start, int limit, byte newLevel) { - for (int i = start; i < limit; ++i) { - resultLevels[i] = newLevel; - } - } - - // --- input validation --------------------------------------------------- - - /** - * Throw exception if type array is invalid. - */ - private static void validateTypes(byte[] types) { - if (types == null) { - throw new IllegalArgumentException("types is null"); - } - for (int i = 0; i < types.length; ++i) { - if (types[i] < TYPE_MIN || types[i] > TYPE_MAX) { - throw new IllegalArgumentException("illegal type value at " + i + ": " + types[i]); - } - } - for (int i = 0; i < types.length - 1; ++i) { - if (types[i] == B) { - throw new IllegalArgumentException("B type before end of paragraph at index: " + i); - } - } - } - - /** - * Throw exception if paragraph embedding level is invalid. Special allowance for -1 so that - * default processing can still be performed when using this API. - */ - private static void validateParagraphEmbeddingLevel(byte paragraphEmbeddingLevel) { - if (paragraphEmbeddingLevel != -1 && - paragraphEmbeddingLevel != 0 && - paragraphEmbeddingLevel != 1) { - throw new IllegalArgumentException("illegal paragraph embedding level: " + paragraphEmbeddingLevel); - } - } - - /** - * Throw exception if line breaks array is invalid. - */ - private static void validateLineBreaks(int[] linebreaks, int textLength) { - int prev = 0; - for (int i = 0; i < linebreaks.length; ++i) { - int next = linebreaks[i]; - if (next <= prev) { - throw new IllegalArgumentException("bad linebreak: " + next + " at index: " + i); - } - prev = next; - } - if (prev != textLength) { - throw new IllegalArgumentException("last linebreak must be at " + textLength); - } - } - - private static final byte rtypes[] = new byte[0x10000]; - - private static char baseTypes[] = { - 0, 8, (char)BN, 9, 9, (char)S, 10, 10, (char)B, 11, 11, (char)S, 12, 12, (char)WS, 13, 13, (char)B, - 14, 27, (char)BN, 28, 30, (char)B, 31, 31, (char)S, 32, 32, (char)WS, 33, 34, (char)ON, 35, 37, (char)ET, - 38, 42, (char)ON, 43, 43, (char)ET, 44, 44, (char)CS, 45, 45, (char)ET, 46, 46, (char)CS, 47, 47, (char)ES, - 48, 57, (char)EN, 58, 58, (char)CS, 59, 64, (char)ON, 65, 90, (char)L, 91, 96, (char)ON, 97, 122, (char)L, - 123, 126, (char)ON, 127, 132, (char)BN, 133, 133, (char)B, 134, 159, (char)BN, 160, 160, (char)CS, - 161, 161, (char)ON, 162, 165, (char)ET, 166, 169, (char)ON, 170, 170, (char)L, 171, 175, (char)ON, - 176, 177, (char)ET, 178, 179, (char)EN, 180, 180, (char)ON, 181, 181, (char)L, 182, 184, (char)ON, - 185, 185, (char)EN, 186, 186, (char)L, 187, 191, (char)ON, 192, 214, (char)L, 215, 215, (char)ON, - 216, 246, (char)L, 247, 247, (char)ON, 248, 696, (char)L, 697, 698, (char)ON, 699, 705, (char)L, - 706, 719, (char)ON, 720, 721, (char)L, 722, 735, (char)ON, 736, 740, (char)L, 741, 749, (char)ON, - 750, 750, (char)L, 751, 767, (char)ON, 768, 855, (char)NSM, 856, 860, (char)L, 861, 879, (char)NSM, - 880, 883, (char)L, 884, 885, (char)ON, 886, 893, (char)L, 894, 894, (char)ON, 895, 899, (char)L, - 900, 901, (char)ON, 902, 902, (char)L, 903, 903, (char)ON, 904, 1013, (char)L, 1014, 1014, (char)ON, - 1015, 1154, (char)L, 1155, 1158, (char)NSM, 1159, 1159, (char)L, 1160, 1161, (char)NSM, - 1162, 1417, (char)L, 1418, 1418, (char)ON, 1419, 1424, (char)L, 1425, 1441, (char)NSM, - 1442, 1442, (char)L, 1443, 1465, (char)NSM, 1466, 1466, (char)L, 1467, 1469, (char)NSM, - 1470, 1470, (char)R, 1471, 1471, (char)NSM, 1472, 1472, (char)R, 1473, 1474, (char)NSM, - 1475, 1475, (char)R, 1476, 1476, (char)NSM, 1477, 1487, (char)L, 1488, 1514, (char)R, - 1515, 1519, (char)L, 1520, 1524, (char)R, 1525, 1535, (char)L, 1536, 1539, (char)AL, - 1540, 1547, (char)L, 1548, 1548, (char)CS, 1549, 1549, (char)AL, 1550, 1551, (char)ON, - 1552, 1557, (char)NSM, 1558, 1562, (char)L, 1563, 1563, (char)AL, 1564, 1566, (char)L, - 1567, 1567, (char)AL, 1568, 1568, (char)L, 1569, 1594, (char)AL, 1595, 1599, (char)L, - 1600, 1610, (char)AL, 1611, 1624, (char)NSM, 1625, 1631, (char)L, 1632, 1641, (char)AN, - 1642, 1642, (char)ET, 1643, 1644, (char)AN, 1645, 1647, (char)AL, 1648, 1648, (char)NSM, - 1649, 1749, (char)AL, 1750, 1756, (char)NSM, 1757, 1757, (char)AL, 1758, 1764, (char)NSM, - 1765, 1766, (char)AL, 1767, 1768, (char)NSM, 1769, 1769, (char)ON, 1770, 1773, (char)NSM, - 1774, 1775, (char)AL, 1776, 1785, (char)EN, 1786, 1805, (char)AL, 1806, 1806, (char)L, - 1807, 1807, (char)BN, 1808, 1808, (char)AL, 1809, 1809, (char)NSM, 1810, 1839, (char)AL, - 1840, 1866, (char)NSM, 1867, 1868, (char)L, 1869, 1871, (char)AL, 1872, 1919, (char)L, - 1920, 1957, (char)AL, 1958, 1968, (char)NSM, 1969, 1969, (char)AL, 1970, 2304, (char)L, - 2305, 2306, (char)NSM, 2307, 2363, (char)L, 2364, 2364, (char)NSM, 2365, 2368, (char)L, - 2369, 2376, (char)NSM, 2377, 2380, (char)L, 2381, 2381, (char)NSM, 2382, 2384, (char)L, - 2385, 2388, (char)NSM, 2389, 2401, (char)L, 2402, 2403, (char)NSM, 2404, 2432, (char)L, - 2433, 2433, (char)NSM, 2434, 2491, (char)L, 2492, 2492, (char)NSM, 2493, 2496, (char)L, - 2497, 2500, (char)NSM, 2501, 2508, (char)L, 2509, 2509, (char)NSM, 2510, 2529, (char)L, - 2530, 2531, (char)NSM, 2532, 2545, (char)L, 2546, 2547, (char)ET, 2548, 2560, (char)L, - 2561, 2562, (char)NSM, 2563, 2619, (char)L, 2620, 2620, (char)NSM, 2621, 2624, (char)L, - 2625, 2626, (char)NSM, 2627, 2630, (char)L, 2631, 2632, (char)NSM, 2633, 2634, (char)L, - 2635, 2637, (char)NSM, 2638, 2671, (char)L, 2672, 2673, (char)NSM, 2674, 2688, (char)L, - 2689, 2690, (char)NSM, 2691, 2747, (char)L, 2748, 2748, (char)NSM, 2749, 2752, (char)L, - 2753, 2757, (char)NSM, 2758, 2758, (char)L, 2759, 2760, (char)NSM, 2761, 2764, (char)L, - 2765, 2765, (char)NSM, 2766, 2785, (char)L, 2786, 2787, (char)NSM, 2788, 2800, (char)L, - 2801, 2801, (char)ET, 2802, 2816, (char)L, 2817, 2817, (char)NSM, 2818, 2875, (char)L, - 2876, 2876, (char)NSM, 2877, 2878, (char)L, 2879, 2879, (char)NSM, 2880, 2880, (char)L, - 2881, 2883, (char)NSM, 2884, 2892, (char)L, 2893, 2893, (char)NSM, 2894, 2901, (char)L, - 2902, 2902, (char)NSM, 2903, 2945, (char)L, 2946, 2946, (char)NSM, 2947, 3007, (char)L, - 3008, 3008, (char)NSM, 3009, 3020, (char)L, 3021, 3021, (char)NSM, 3022, 3058, (char)L, - 3059, 3064, (char)ON, 3065, 3065, (char)ET, 3066, 3066, (char)ON, 3067, 3133, (char)L, - 3134, 3136, (char)NSM, 3137, 3141, (char)L, 3142, 3144, (char)NSM, 3145, 3145, (char)L, - 3146, 3149, (char)NSM, 3150, 3156, (char)L, 3157, 3158, (char)NSM, 3159, 3259, (char)L, - 3260, 3260, (char)NSM, 3261, 3275, (char)L, 3276, 3277, (char)NSM, 3278, 3392, (char)L, - 3393, 3395, (char)NSM, 3396, 3404, (char)L, 3405, 3405, (char)NSM, 3406, 3529, (char)L, - 3530, 3530, (char)NSM, 3531, 3537, (char)L, 3538, 3540, (char)NSM, 3541, 3541, (char)L, - 3542, 3542, (char)NSM, 3543, 3632, (char)L, 3633, 3633, (char)NSM, 3634, 3635, (char)L, - 3636, 3642, (char)NSM, 3643, 3646, (char)L, 3647, 3647, (char)ET, 3648, 3654, (char)L, - 3655, 3662, (char)NSM, 3663, 3760, (char)L, 3761, 3761, (char)NSM, 3762, 3763, (char)L, - 3764, 3769, (char)NSM, 3770, 3770, (char)L, 3771, 3772, (char)NSM, 3773, 3783, (char)L, - 3784, 3789, (char)NSM, 3790, 3863, (char)L, 3864, 3865, (char)NSM, 3866, 3892, (char)L, - 3893, 3893, (char)NSM, 3894, 3894, (char)L, 3895, 3895, (char)NSM, 3896, 3896, (char)L, - 3897, 3897, (char)NSM, 3898, 3901, (char)ON, 3902, 3952, (char)L, 3953, 3966, (char)NSM, - 3967, 3967, (char)L, 3968, 3972, (char)NSM, 3973, 3973, (char)L, 3974, 3975, (char)NSM, - 3976, 3983, (char)L, 3984, 3991, (char)NSM, 3992, 3992, (char)L, 3993, 4028, (char)NSM, - 4029, 4037, (char)L, 4038, 4038, (char)NSM, 4039, 4140, (char)L, 4141, 4144, (char)NSM, - 4145, 4145, (char)L, 4146, 4146, (char)NSM, 4147, 4149, (char)L, 4150, 4151, (char)NSM, - 4152, 4152, (char)L, 4153, 4153, (char)NSM, 4154, 4183, (char)L, 4184, 4185, (char)NSM, - 4186, 5759, (char)L, 5760, 5760, (char)WS, 5761, 5786, (char)L, 5787, 5788, (char)ON, - 5789, 5905, (char)L, 5906, 5908, (char)NSM, 5909, 5937, (char)L, 5938, 5940, (char)NSM, - 5941, 5969, (char)L, 5970, 5971, (char)NSM, 5972, 6001, (char)L, 6002, 6003, (char)NSM, - 6004, 6070, (char)L, 6071, 6077, (char)NSM, 6078, 6085, (char)L, 6086, 6086, (char)NSM, - 6087, 6088, (char)L, 6089, 6099, (char)NSM, 6100, 6106, (char)L, 6107, 6107, (char)ET, - 6108, 6108, (char)L, 6109, 6109, (char)NSM, 6110, 6127, (char)L, 6128, 6137, (char)ON, - 6138, 6143, (char)L, 6144, 6154, (char)ON, 6155, 6157, (char)NSM, 6158, 6158, (char)WS, - 6159, 6312, (char)L, 6313, 6313, (char)NSM, 6314, 6431, (char)L, 6432, 6434, (char)NSM, - 6435, 6438, (char)L, 6439, 6443, (char)NSM, 6444, 6449, (char)L, 6450, 6450, (char)NSM, - 6451, 6456, (char)L, 6457, 6459, (char)NSM, 6460, 6463, (char)L, 6464, 6464, (char)ON, - 6465, 6467, (char)L, 6468, 6469, (char)ON, 6470, 6623, (char)L, 6624, 6655, (char)ON, - 6656, 8124, (char)L, 8125, 8125, (char)ON, 8126, 8126, (char)L, 8127, 8129, (char)ON, - 8130, 8140, (char)L, 8141, 8143, (char)ON, 8144, 8156, (char)L, 8157, 8159, (char)ON, - 8160, 8172, (char)L, 8173, 8175, (char)ON, 8176, 8188, (char)L, 8189, 8190, (char)ON, - 8191, 8191, (char)L, 8192, 8202, (char)WS, 8203, 8205, (char)BN, 8206, 8206, (char)L, - 8207, 8207, (char)R, 8208, 8231, (char)ON, 8232, 8232, (char)WS, 8233, 8233, (char)B, - 8234, 8234, (char)LRE, 8235, 8235, (char)RLE, 8236, 8236, (char)PDF, 8237, 8237, (char)LRO, - 8238, 8238, (char)RLO, 8239, 8239, (char)WS, 8240, 8244, (char)ET, 8245, 8276, (char)ON, - 8277, 8278, (char)L, 8279, 8279, (char)ON, 8280, 8286, (char)L, 8287, 8287, (char)WS, - 8288, 8291, (char)BN, 8292, 8297, (char)L, 8298, 8303, (char)BN, 8304, 8304, (char)EN, - 8305, 8307, (char)L, 8308, 8313, (char)EN, 8314, 8315, (char)ET, 8316, 8318, (char)ON, - 8319, 8319, (char)L, 8320, 8329, (char)EN, 8330, 8331, (char)ET, 8332, 8334, (char)ON, - 8335, 8351, (char)L, 8352, 8369, (char)ET, 8370, 8399, (char)L, 8400, 8426, (char)NSM, - 8427, 8447, (char)L, 8448, 8449, (char)ON, 8450, 8450, (char)L, 8451, 8454, (char)ON, - 8455, 8455, (char)L, 8456, 8457, (char)ON, 8458, 8467, (char)L, 8468, 8468, (char)ON, - 8469, 8469, (char)L, 8470, 8472, (char)ON, 8473, 8477, (char)L, 8478, 8483, (char)ON, - 8484, 8484, (char)L, 8485, 8485, (char)ON, 8486, 8486, (char)L, 8487, 8487, (char)ON, - 8488, 8488, (char)L, 8489, 8489, (char)ON, 8490, 8493, (char)L, 8494, 8494, (char)ET, - 8495, 8497, (char)L, 8498, 8498, (char)ON, 8499, 8505, (char)L, 8506, 8507, (char)ON, - 8508, 8511, (char)L, 8512, 8516, (char)ON, 8517, 8521, (char)L, 8522, 8523, (char)ON, - 8524, 8530, (char)L, 8531, 8543, (char)ON, 8544, 8591, (char)L, 8592, 8721, (char)ON, - 8722, 8723, (char)ET, 8724, 9013, (char)ON, 9014, 9082, (char)L, 9083, 9108, (char)ON, - 9109, 9109, (char)L, 9110, 9168, (char)ON, 9169, 9215, (char)L, 9216, 9254, (char)ON, - 9255, 9279, (char)L, 9280, 9290, (char)ON, 9291, 9311, (char)L, 9312, 9371, (char)EN, - 9372, 9449, (char)L, 9450, 9450, (char)EN, 9451, 9751, (char)ON, 9752, 9752, (char)L, - 9753, 9853, (char)ON, 9854, 9855, (char)L, 9856, 9873, (char)ON, 9874, 9887, (char)L, - 9888, 9889, (char)ON, 9890, 9984, (char)L, 9985, 9988, (char)ON, 9989, 9989, (char)L, - 9990, 9993, (char)ON, 9994, 9995, (char)L, 9996, 10023, (char)ON, 10024, 10024, (char)L, - 10025, 10059, (char)ON, 10060, 10060, (char)L, 10061, 10061, (char)ON, 10062, 10062, (char)L, - 10063, 10066, (char)ON, 10067, 10069, (char)L, 10070, 10070, (char)ON, 10071, 10071, (char)L, - 10072, 10078, (char)ON, 10079, 10080, (char)L, 10081, 10132, (char)ON, 10133, 10135, (char)L, - 10136, 10159, (char)ON, 10160, 10160, (char)L, 10161, 10174, (char)ON, 10175, 10191, (char)L, - 10192, 10219, (char)ON, 10220, 10223, (char)L, 10224, 11021, (char)ON, 11022, 11903, (char)L, - 11904, 11929, (char)ON, 11930, 11930, (char)L, 11931, 12019, (char)ON, 12020, 12031, (char)L, - 12032, 12245, (char)ON, 12246, 12271, (char)L, 12272, 12283, (char)ON, 12284, 12287, (char)L, - 12288, 12288, (char)WS, 12289, 12292, (char)ON, 12293, 12295, (char)L, 12296, 12320, (char)ON, - 12321, 12329, (char)L, 12330, 12335, (char)NSM, 12336, 12336, (char)ON, 12337, 12341, (char)L, - 12342, 12343, (char)ON, 12344, 12348, (char)L, 12349, 12351, (char)ON, 12352, 12440, (char)L, - 12441, 12442, (char)NSM, 12443, 12444, (char)ON, 12445, 12447, (char)L, 12448, 12448, (char)ON, - 12449, 12538, (char)L, 12539, 12539, (char)ON, 12540, 12828, (char)L, 12829, 12830, (char)ON, - 12831, 12879, (char)L, 12880, 12895, (char)ON, 12896, 12923, (char)L, 12924, 12925, (char)ON, - 12926, 12976, (char)L, 12977, 12991, (char)ON, 12992, 13003, (char)L, 13004, 13007, (char)ON, - 13008, 13174, (char)L, 13175, 13178, (char)ON, 13179, 13277, (char)L, 13278, 13279, (char)ON, - 13280, 13310, (char)L, 13311, 13311, (char)ON, 13312, 19903, (char)L, 19904, 19967, (char)ON, - 19968, 42127, (char)L, 42128, 42182, (char)ON, 42183, 64284, (char)L, 64285, 64285, (char)R, - 64286, 64286, (char)NSM, 64287, 64296, (char)R, 64297, 64297, (char)ET, 64298, 64310, (char)R, - 64311, 64311, (char)L, 64312, 64316, (char)R, 64317, 64317, (char)L, 64318, 64318, (char)R, - 64319, 64319, (char)L, 64320, 64321, (char)R, 64322, 64322, (char)L, 64323, 64324, (char)R, - 64325, 64325, (char)L, 64326, 64335, (char)R, 64336, 64433, (char)AL, 64434, 64466, (char)L, - 64467, 64829, (char)AL, 64830, 64831, (char)ON, 64832, 64847, (char)L, 64848, 64911, (char)AL, - 64912, 64913, (char)L, 64914, 64967, (char)AL, 64968, 65007, (char)L, 65008, 65020, (char)AL, - 65021, 65021, (char)ON, 65022, 65023, (char)L, 65024, 65039, (char)NSM, 65040, 65055, (char)L, - 65056, 65059, (char)NSM, 65060, 65071, (char)L, 65072, 65103, (char)ON, 65104, 65104, (char)CS, - 65105, 65105, (char)ON, 65106, 65106, (char)CS, 65107, 65107, (char)L, 65108, 65108, (char)ON, - 65109, 65109, (char)CS, 65110, 65118, (char)ON, 65119, 65119, (char)ET, 65120, 65121, (char)ON, - 65122, 65123, (char)ET, 65124, 65126, (char)ON, 65127, 65127, (char)L, 65128, 65128, (char)ON, - 65129, 65130, (char)ET, 65131, 65131, (char)ON, 65132, 65135, (char)L, 65136, 65140, (char)AL, - 65141, 65141, (char)L, 65142, 65276, (char)AL, 65277, 65278, (char)L, 65279, 65279, (char)BN, - 65280, 65280, (char)L, 65281, 65282, (char)ON, 65283, 65285, (char)ET, 65286, 65290, (char)ON, - 65291, 65291, (char)ET, 65292, 65292, (char)CS, 65293, 65293, (char)ET, 65294, 65294, (char)CS, - 65295, 65295, (char)ES, 65296, 65305, (char)EN, 65306, 65306, (char)CS, 65307, 65312, (char)ON, - 65313, 65338, (char)L, 65339, 65344, (char)ON, 65345, 65370, (char)L, 65371, 65381, (char)ON, - 65382, 65503, (char)L, 65504, 65505, (char)ET, 65506, 65508, (char)ON, 65509, 65510, (char)ET, - 65511, 65511, (char)L, 65512, 65518, (char)ON, 65519, 65528, (char)L, 65529, 65531, (char)BN, - 65532, 65533, (char)ON, 65534, 65535, (char)L}; - - static { - for (int k = 0; k < baseTypes.length; ++k) { - int start = baseTypes[k]; - int end = baseTypes[++k]; - byte b = (byte)baseTypes[++k]; - while (start <= end) - rtypes[start++] = b; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/ByteBuffer.java b/src/main/java/com/lowagie/text/pdf/ByteBuffer.java deleted file mode 100644 index 695d4c5..0000000 --- a/src/main/java/com/lowagie/text/pdf/ByteBuffer.java +++ /dev/null @@ -1,623 +0,0 @@ -/* - * $Id: ByteBuffer.java,v 1.69 2006/01/31 18:05:22 psoares33 Exp $ - * $Name: $ - * - * Copyright 2000, 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.UnsupportedEncodingException; -import java.io.OutputStream; -import java.io.IOException; -import com.lowagie.text.DocWriter; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Locale; - -/** - * Acts like a StringBuffer but works with byte arrays. - * Floating point is converted to a format suitable to the PDF. - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class ByteBuffer extends OutputStream { - /** The count of bytes in the buffer. */ - protected int count; - - /** The buffer where the bytes are stored. */ - protected byte buf[]; - - private static int byteCacheSize = 0; - - private static byte[][] byteCache = new byte[byteCacheSize][]; - public static byte ZERO = (byte)'0'; - private static final char[] chars = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; - private static final byte[] bytes = new byte[] {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102}; - /** - * If true always output floating point numbers with 6 decimal digits. - * If false uses the faster, although less precise, representation. - */ - public static boolean HIGH_PRECISION = false; - private static final DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US); - - /** Creates new ByteBuffer with capacity 128 */ - public ByteBuffer() { - this(128); - } - - /** - * Creates a byte buffer with a certain capacity. - * @param size the initial capacity - */ - public ByteBuffer(int size) { - if (size < 1) - size = 128; - buf = new byte[size]; - } - - /** - * Sets the cache size. - *

- * This can only be used to increment the size. - * If the size that is passed through is smaller than the current size, nothing happens. - * - * @param size the size of the cache - */ - - public static void setCacheSize(int size) { - if (size > 3276700) size = 3276700; - if (size <= byteCacheSize) return; - byte[][] tmpCache = new byte[size][]; - for (int i = 0; i < byteCacheSize; i++) { - tmpCache[i] = byteCache[i]; - } - byteCache = tmpCache; - byteCacheSize = size; - } - - /** - * You can fill the cache in advance if you want to. - * - * @param decimals - */ - - public static void fillCache(int decimals) { - int step = 1; - switch(decimals) { - case 0: - step = 100; - break; - case 1: - step = 10; - break; - } - for (int i = 1; i < byteCacheSize; i += step) { - if (byteCache[i] != null) continue; - byteCache[i] = convertToBytes(i); - } - } - - /** - * Converts an double (multiplied by 100 and cast to an int) into an array of bytes. - * - * @param i the int - * @return a bytearray - */ - - private static byte[] convertToBytes(int i) { - int size = (int)Math.floor(Math.log(i) / Math.log(10)); - if (i % 100 != 0) { - size += 2; - } - if (i % 10 != 0) { - size++; - } - if (i < 100) { - size++; - if (i < 10) { - size++; - } - } - size--; - byte[] cache = new byte[size]; - size --; - if (i < 100) { - cache[0] = (byte)'0'; - } - if (i % 10 != 0) { - cache[size--] = bytes[i % 10]; - } - if (i % 100 != 0) { - cache[size--] = bytes[(i / 10) % 10]; - cache[size--] = (byte)'.'; - } - size = (int)Math.floor(Math.log(i) / Math.log(10)) - 1; - int add = 0; - while (add < size) { - cache[add] = bytes[(i / (int)Math.pow(10, size - add + 1)) % 10]; - add++; - } - return cache; - } - - /** - * Appends an int. The size of the array will grow by one. - * @param b the int to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append_i(int b) { - int newcount = count + 1; - if (newcount > buf.length) { - byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; - System.arraycopy(buf, 0, newbuf, 0, count); - buf = newbuf; - } - buf[count] = (byte)b; - count = newcount; - return this; - } - - /** - * Appends the subarray of the byte array. The buffer will grow by - * len bytes. - * @param b the array to be appended - * @param off the offset to the start of the array - * @param len the length of bytes to append - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(byte b[], int off, int len) { - if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0) || len == 0) - return this; - int newcount = count + len; - if (newcount > buf.length) { - byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)]; - System.arraycopy(buf, 0, newbuf, 0, count); - buf = newbuf; - } - System.arraycopy(b, off, buf, count, len); - count = newcount; - return this; - } - - /** - * Appends an array of bytes. - * @param b the array to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(byte b[]) { - return append(b, 0, b.length); - } - - /** - * Appends a String to the buffer. The String is - * converted according to the encoding ISO-8859-1. - * @param str the String to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(String str) { - if (str != null) - return append(DocWriter.getISOBytes(str)); - return this; - } - - /** - * Appends a char to the buffer. The char is - * converted according to the encoding ISO-8859-1. - * @param c the char to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(char c) { - return append_i(c); - } - - /** - * Appends another ByteBuffer to this buffer. - * @param buf the ByteBuffer to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(ByteBuffer buf) { - return append(buf.buf, 0, buf.count); - } - - /** - * Appends the string representation of an int. - * @param i the int to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(int i) { - return append((double)i); - } - - public ByteBuffer append(byte b) { - return append_i(b); - } - - public ByteBuffer appendHex(byte b) { - append(bytes[(b >> 4) & 0x0f]); - return append(bytes[b & 0x0f]); - } - - /** - * Appends a string representation of a float according - * to the Pdf conventions. - * @param i the float to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(float i) { - return append((double)i); - } - - /** - * Appends a string representation of a double according - * to the Pdf conventions. - * @param d the double to be appended - * @return a reference to this ByteBuffer object - */ - public ByteBuffer append(double d) { - append(formatDouble(d, this)); - return this; - } - - /** - * Outputs a double into a format suitable for the PDF. - * @param d a double - * @return the String representation of the double - */ - public static String formatDouble(double d) { - return formatDouble(d, null); - } - - /** - * Outputs a double into a format suitable for the PDF. - * @param d a double - * @param buf a ByteBuffer - * @return the String representation of the double if - * buf is null. If buf is not null, - * then the double is appended directly to the buffer and this methods returns null. - */ - public static String formatDouble(double d, ByteBuffer buf) { - if (HIGH_PRECISION) { - DecimalFormat dn = new DecimalFormat("0.######", dfs); - String sform = dn.format(d); - if (buf == null) - return sform; - else { - buf.append(sform); - return null; - } - } - boolean negative = false; - if (Math.abs(d) < 0.000015) { - if (buf != null) { - buf.append(ZERO); - return null; - } else { - return "0"; - } - } - if (d < 0) { - negative = true; - d = -d; - } - if (d < 1.0) { - d += 0.000005; - if (d >= 1) { - if (negative) { - if (buf != null) { - buf.append((byte)'-'); - buf.append((byte)'1'); - return null; - } else { - return "-1"; - } - } else { - if (buf != null) { - buf.append((byte)'1'); - return null; - } else { - return "1"; - } - } - } - if (buf != null) { - int v = (int) (d * 100000); - - if (negative) buf.append((byte)'-'); - buf.append((byte)'0'); - buf.append((byte)'.'); - - buf.append( (byte)(v / 10000 + ZERO) ); - if (v % 10000 != 0) { - buf.append( (byte)((v / 1000) % 10 + ZERO) ); - if (v % 1000 != 0) { - buf.append( (byte)((v / 100) % 10 + ZERO) ); - if (v % 100 != 0) { - buf.append((byte)((v / 10) % 10 + ZERO) ); - if (v % 10 != 0) { - buf.append((byte)((v) % 10 + ZERO) ); - } - } - } - } - return null; - } else { - int x = 100000; - int v = (int) (d * x); - - StringBuffer res = new StringBuffer(); - if (negative) res.append('-'); - res.append("0."); - - while( v < x/10 ) { - res.append('0'); - x /= 10; - } - res.append(v); - int cut = res.length() - 1; - while (res.charAt(cut) == '0') { - --cut; - } - res.setLength(cut + 1); - return res.toString(); - } - } else if (d <= 32767) { - d += 0.005; - int v = (int) (d * 100); - - if (v < byteCacheSize && byteCache[v] != null) { - if (buf != null) { - if (negative) buf.append((byte)'-'); - buf.append(byteCache[v]); - return null; - } else { - String tmp = PdfEncodings.convertToString(byteCache[v], null); - if (negative) tmp = "-" + tmp; - return tmp; - } - } - if (buf != null) { - if (v < byteCacheSize) { - //create the cachebyte[] - byte[] cache; - int size = 0; - if (v >= 1000000) { - //the original number is >=10000, we need 5 more bytes - size += 5; - } else if (v >= 100000) { - //the original number is >=1000, we need 4 more bytes - size += 4; - } else if (v >= 10000) { - //the original number is >=100, we need 3 more bytes - size += 3; - } else if (v >= 1000) { - //the original number is >=10, we need 2 more bytes - size += 2; - } else if (v >= 100) { - //the original number is >=1, we need 1 more bytes - size += 1; - } - - //now we must check if we have a decimal number - if (v % 100 != 0) { - //yes, do not forget the "." - size += 2; - } - if (v % 10 != 0) { - size++; - } - cache = new byte[size]; - int add = 0; - if (v >= 1000000) { - cache[add++] = bytes[(v / 1000000)]; - } - if (v >= 100000) { - cache[add++] = bytes[(v / 100000) % 10]; - } - if (v >= 10000) { - cache[add++] = bytes[(v / 10000) % 10]; - } - if (v >= 1000) { - cache[add++] = bytes[(v / 1000) % 10]; - } - if (v >= 100) { - cache[add++] = bytes[(v / 100) % 10]; - } - - if (v % 100 != 0) { - cache[add++] = (byte)'.'; - cache[add++] = bytes[(v / 10) % 10]; - if (v % 10 != 0) { - cache[add++] = bytes[v % 10]; - } - } - byteCache[v] = cache; - } - - if (negative) buf.append((byte)'-'); - if (v >= 1000000) { - buf.append( bytes[(v / 1000000)] ); - } - if (v >= 100000) { - buf.append( bytes[(v / 100000) % 10] ); - } - if (v >= 10000) { - buf.append( bytes[(v / 10000) % 10] ); - } - if (v >= 1000) { - buf.append( bytes[(v / 1000) % 10] ); - } - if (v >= 100) { - buf.append( bytes[(v / 100) % 10] ); - } - - if (v % 100 != 0) { - buf.append((byte)'.'); - buf.append( bytes[(v / 10) % 10] ); - if (v % 10 != 0) { - buf.append( bytes[v % 10] ); - } - } - return null; - } else { - StringBuffer res = new StringBuffer(); - if (negative) res.append('-'); - if (v >= 1000000) { - res.append( chars[(v / 1000000)] ); - } - if (v >= 100000) { - res.append( chars[(v / 100000) % 10] ); - } - if (v >= 10000) { - res.append( chars[(v / 10000) % 10] ); - } - if (v >= 1000) { - res.append( chars[(v / 1000) % 10] ); - } - if (v >= 100) { - res.append( chars[(v / 100) % 10] ); - } - - if (v % 100 != 0) { - res.append('.'); - res.append( chars[(v / 10) % 10] ); - if (v % 10 != 0) { - res.append( chars[v % 10] ); - } - } - return res.toString(); - } - } else { - StringBuffer res = new StringBuffer(); - if (negative) res.append('-'); - d += 0.5; - long v = (long) d; - return res.append(v).toString(); - } - } - - /** - * Sets the size to zero. - */ - public void reset() { - count = 0; - } - - /** - * Creates a newly allocated byte array. Its size is the current - * size of this output stream and the valid contents of the buffer - * have been copied into it. - * - * @return the current contents of this output stream, as a byte array. - */ - public byte[] toByteArray() { - byte newbuf[] = new byte[count]; - System.arraycopy(buf, 0, newbuf, 0, count); - return newbuf; - } - - /** - * Returns the current size of the buffer. - * - * @return the value of the count field, which is the number of valid bytes in this byte buffer. - */ - public int size() { - return count; - } - - public void setSize(int size) { - if (size > count || size < 0) - throw new IndexOutOfBoundsException("The new size must be positive and <= of the current size"); - count = size; - } - - /** - * Converts the buffer's contents into a string, translating bytes into - * characters according to the platform's default character encoding. - * - * @return String translated from the buffer's contents. - */ - public String toString() { - return new String(buf, 0, count); - } - - /** - * Converts the buffer's contents into a string, translating bytes into - * characters according to the specified character encoding. - * - * @param enc a character-encoding name. - * @return String translated from the buffer's contents. - * @throws UnsupportedEncodingException - * If the named encoding is not supported. - */ - public String toString(String enc) throws UnsupportedEncodingException { - return new String(buf, 0, count, enc); - } - - /** - * Writes the complete contents of this byte buffer output to - * the specified output stream argument, as if by calling the output - * stream's write method using out.write(buf, 0, count). - * - * @param out the output stream to which to write the data. - * @exception IOException if an I/O error occurs. - */ - public void writeTo(OutputStream out) throws IOException { - out.write(buf, 0, count); - } - - public void write(int b) throws IOException { - append((byte)b); - } - - public void write(byte[] b, int off, int len) { - append(b, off, len); - } - - public byte[] getBuffer() { - return buf; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/CFFFont.java b/src/main/java/com/lowagie/text/pdf/CFFFont.java deleted file mode 100644 index 2d15f96..0000000 --- a/src/main/java/com/lowagie/text/pdf/CFFFont.java +++ /dev/null @@ -1,1184 +0,0 @@ -/* - * - * Copyright 2003 Sivan Toledo - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - */ - -/* - * Comments by Sivan Toledo: - * I created this class in order to add to iText the ability to utilize - * OpenType fonts with CFF glyphs (these usually have an .otf extension). - * The CFF font within the CFF table of the OT font might be either a CID - * or a Type1 font. (CFF fonts may also contain multiple fonts; I do not - * know if this is allowed in an OT table). The PDF spec, however, only - * allow a CID font with an Identity-H or Identity-V encoding. Otherwise, - * you are limited to an 8-bit encoding. - * Adobe fonts come in both flavors. That is, the OTFs sometimes have - * a CID CFF inside (for Japanese fonts), and sometimes a Type1 CFF - * (virtually all the others, Latin/Greek/Cyrillic). So to easily use - * all the glyphs in the latter, without creating multiple 8-bit encoding, - * I wrote this class, whose main purpose is to convert a Type1 font inside - * a CFF container (which might include other fonts) into a CID CFF font - * that can be directly embeded in the PDF. - * - * Limitations of the current version: - * 1. It does not extract a single CID font from a CFF that contains that - * particular CID along with other fonts. The Adobe Japanese OTF's that - * I have only have one font in the CFF table, so these can be - * embeded in the PDF as is. - * 2. It does not yet subset fonts. - * 3. It may or may not work on CFF fonts that are not within OTF's. - * I didn't try that. In any case, that would probably only be - * useful for subsetting CID fonts, not for CFF Type1 fonts (I don't - * think there are any available. - * I plan to extend the class to support these three features at some - * future time. - */ - -package com.lowagie.text.pdf; - -/** - * @author stoledo - */ - -import java.util.Iterator; -import java.util.LinkedList; -import com.lowagie.text.ExceptionConverter; - -public class CFFFont { - - static final String operatorNames[] = { - "version", "Notice", "FullName", "FamilyName", - "Weight", "FontBBox", "BlueValues", "OtherBlues", - "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", - "UNKNOWN_12", "UniqueID", "XUID", "charset", - "Encoding", "CharStrings", "Private", "Subrs", - "defaultWidthX", "nominalWidthX", "UNKNOWN_22", "UNKNOWN_23", - "UNKNOWN_24", "UNKNOWN_25", "UNKNOWN_26", "UNKNOWN_27", - "UNKNOWN_28", "UNKNOWN_29", "UNKNOWN_30", "UNKNOWN_31", - "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", - "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", - "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", - "StemSnapH", "StemSnapV", "ForceBold", "UNKNOWN_12_15", - "UNKNOWN_12_16", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", - "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", - "UNKNOWN_12_24", "UNKNOWN_12_25", "UNKNOWN_12_26", "UNKNOWN_12_27", - "UNKNOWN_12_28", "UNKNOWN_12_29", "ROS", "CIDFontVersion", - "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", - "FDArray", "FDSelect", "FontName" - }; - - static final String standardStrings[] = { - // Automatically generated from Appendix A of the CFF specification; do - // not edit. Size should be 391. - ".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", - "percent", "ampersand", "quoteright", "parenleft", "parenright", - "asterisk", "plus", "comma", "hyphen", "period", "slash", "zero", "one", - "two", "three", "four", "five", "six", "seven", "eight", "nine", "colon", - "semicolon", "less", "equal", "greater", "question", "at", "A", "B", "C", - "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", - "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", "backslash", - "bracketright", "asciicircum", "underscore", "quoteleft", "a", "b", "c", - "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", - "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar", "braceright", - "asciitilde", "exclamdown", "cent", "sterling", "fraction", "yen", - "florin", "section", "currency", "quotesingle", "quotedblleft", - "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash", - "dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", - "quotesinglbase", "quotedblbase", "quotedblright", "guillemotright", - "ellipsis", "perthousand", "questiondown", "grave", "acute", "circumflex", - "tilde", "macron", "breve", "dotaccent", "dieresis", "ring", "cedilla", - "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine", "Lslash", - "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe", - "germandbls", "onesuperior", "logicalnot", "mu", "trademark", "Eth", - "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar", - "degree", "thorn", "threequarters", "twosuperior", "registered", "minus", - "eth", "multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", - "Adieresis", "Agrave", "Aring", "Atilde", "Ccedilla", "Eacute", - "Ecircumflex", "Edieresis", "Egrave", "Iacute", "Icircumflex", "Idieresis", - "Igrave", "Ntilde", "Oacute", "Ocircumflex", "Odieresis", "Ograve", - "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave", - "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis", - "agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", - "edieresis", "egrave", "iacute", "icircumflex", "idieresis", "igrave", - "ntilde", "oacute", "ocircumflex", "odieresis", "ograve", "otilde", - "scaron", "uacute", "ucircumflex", "udieresis", "ugrave", "yacute", - "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall", - "dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", - "parenleftsuperior", "parenrightsuperior", "twodotenleader", - "onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", - "threeoldstyle", "fouroldstyle", "fiveoldstyle", "sixoldstyle", - "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", - "threequartersemdash", "periodsuperior", "questionsmall", "asuperior", - "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior", - "lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", - "ssuperior", "tsuperior", "ff", "ffi", "ffl", "parenleftinferior", - "parenrightinferior", "Circumflexsmall", "hyphensuperior", "Gravesmall", - "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall", "Gsmall", - "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall", "Nsmall", - "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall", "Usmall", - "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary", - "onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", - "Lslashsmall", "Scaronsmall", "Zcaronsmall", "Dieresissmall", "Brevesmall", - "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash", - "hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", - "questiondownsmall", "oneeighth", "threeeighths", "fiveeighths", - "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", - "fivesuperior", "sixsuperior", "sevensuperior", "eightsuperior", - "ninesuperior", "zeroinferior", "oneinferior", "twoinferior", - "threeinferior", "fourinferior", "fiveinferior", "sixinferior", - "seveninferior", "eightinferior", "nineinferior", "centinferior", - "dollarinferior", "periodinferior", "commainferior", "Agravesmall", - "Aacutesmall", "Acircumflexsmall", "Atildesmall", "Adieresissmall", - "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall", - "Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", - "Icircumflexsmall", "Idieresissmall", "Ethsmall", "Ntildesmall", - "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", - "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall", "Uacutesmall", - "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall", - "Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", - "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" - }; - - //private String[] strings; - public String getString(char sid) { - if (sid < standardStrings.length) return standardStrings[sid]; - if (sid >= standardStrings.length+(stringOffsets.length-1)) return null; - int j = sid - standardStrings.length; - //java.lang.System.err.println("going for "+j); - int p = getPosition(); - seek(stringOffsets[j]); - StringBuffer s = new StringBuffer(); - for (int k=stringOffsets[j]; k count in the index header. 1->offset size in index header - + 2+1 - //offset array size * offset size - + (count+1)*indexOffSize - //???zero <-> one base - - 1 - // read object offset relative to object array base - + getOffset(indexOffSize); - } - //nextIndexOffset = offsets[count]; - return offsets; - } - - protected String key; - protected Object[] args = new Object[48]; - protected int arg_count = 0; - - protected void getDictItem() { - for (int i=0; i= 32 && b0 <= 246) { - byte item = (byte) (b0-139); - args[arg_count] = new Integer(item); - arg_count++; - //System.err.println(item+" "); - continue; - } - if (b0 >= 247 && b0 <= 250) { - char b1 = getCard8(); - short item = (short) ((b0-247)*256+b1+108); - args[arg_count] = new Integer(item); - arg_count++; - //System.err.println(item+" "); - continue; - } - if (b0 >= 251 && b0 <= 254) { - char b1 = getCard8(); - short item = (short) (-(b0-251)*256-b1-108); - args[arg_count] = new Integer(item); - arg_count++; - //System.err.println(item+" "); - continue; - } - if (b0 == 30) { - String item = ""; - boolean done = false; - char buffer = 0; - byte avail = 0; - int nibble = 0; - while (!done) { - // get a nibble - if (avail==0) { buffer = getCard8(); avail=2; } - if (avail==1) { nibble = (buffer / 16); avail--; } - if (avail==2) { nibble = (buffer % 16); avail--; } - switch (nibble) { - case 0xa: item += "." ; break; - case 0xb: item += "E" ; break; - case 0xc: item += "E-"; break; - case 0xe: item += "-" ; break; - case 0xf: done=true ; break; - default: - if (nibble >= 0 && nibble <= 9) - item += String.valueOf(nibble); - else { - item += ""; - done = true; - } - break; - } - } - args[arg_count] = item; - arg_count++; - //System.err.println(" real=["+item+"]"); - continue; - } - if (b0 <= 21) { - gotKey=true; - if (b0 != 12) key = operatorNames[b0]; - else key = operatorNames[32 + getCard8()]; - //for (int i=0; i>> 24) & 0xff); - i++; - case 3: - buffer[myOffset+i] = (byte) ((value >>> 16) & 0xff); - i++; - case 2: - buffer[myOffset+i] = (byte) ((value >>> 8) & 0xff); - i++; - case 1: - buffer[myOffset+i] = (byte) ((value >>> 0) & 0xff); - i++; - } - /* - int mask = 0xff; - for (int i=size-1; i>=0; i--) { - buffer[myOffset+i] = (byte) (value & mask); - mask <<= 8; - } - */ - } - } - - static protected final class IndexBaseItem extends Item { - public IndexBaseItem() {} - } - - static protected final class IndexMarkerItem extends Item { - private OffsetItem offItem; - private IndexBaseItem indexBase; - public IndexMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { - this.offItem = offItem; - this.indexBase = indexBase; - } - public void xref() { - //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset); - offItem.set(this.myOffset-indexBase.myOffset+1); - } - } - /** - * - * @author orly manor - * - * TODO To change the template for this generated type comment go to - * Window - Preferences - Java - Code Generation - Code and Comments - */ - static protected final class SubrMarkerItem extends Item { - private OffsetItem offItem; - private IndexBaseItem indexBase; - public SubrMarkerItem(OffsetItem offItem, IndexBaseItem indexBase) { - this.offItem = offItem; - this.indexBase = indexBase; - } - public void xref() { - //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset); - offItem.set(this.myOffset-indexBase.myOffset); - } - } - - - /** an unknown offset in a dictionary for the list. - * We will fix up the offset later; for now, assume it's large. - */ - static protected final class DictOffsetItem extends OffsetItem { - public final int size; - public DictOffsetItem() {this.size=5; } - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += size; - } - // this is incomplete! - public void emit(byte[] buffer) { - if (size==5) { - buffer[myOffset] = 29; - buffer[myOffset+1] = (byte) ((value >>> 24) & 0xff); - buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); - buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); - buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); - } - } - } - - /** Card24 item. - */ - - static protected final class UInt24Item extends Item { - public int value; - public UInt24Item(int value) {this.value=value;} - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += 3; - } - // this is incomplete! - public void emit(byte[] buffer) { - buffer[myOffset+0] = (byte) ((value >>> 16) & 0xff); - buffer[myOffset+1] = (byte) ((value >>> 8) & 0xff); - buffer[myOffset+2] = (byte) ((value >>> 0) & 0xff); - } - } - - /** Card32 item. - */ - - static protected final class UInt32Item extends Item { - public int value; - public UInt32Item(int value) {this.value=value;} - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += 4; - } - // this is incomplete! - public void emit(byte[] buffer) { - buffer[myOffset+0] = (byte) ((value >>> 24) & 0xff); - buffer[myOffset+1] = (byte) ((value >>> 16) & 0xff); - buffer[myOffset+2] = (byte) ((value >>> 8) & 0xff); - buffer[myOffset+3] = (byte) ((value >>> 0) & 0xff); - } - } - - /** A SID or Card16 item. - */ - - static protected final class UInt16Item extends Item { - public char value; - public UInt16Item(char value) {this.value=value;} - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += 2; - } - // this is incomplete! - public void emit(byte[] buffer) { - buffer[myOffset+0] = (byte) ((value >>> 8) & 0xff); - buffer[myOffset+1] = (byte) ((value >>> 0) & 0xff); - } - } - - /** A Card8 item. - */ - - static protected final class UInt8Item extends Item { - public char value; - public UInt8Item(char value) {this.value=value;} - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += 1; - } - // this is incomplete! - public void emit(byte[] buffer) { - buffer[myOffset+0] = (byte) ((value >>> 0) & 0xff); - } - } - - static protected final class StringItem extends Item { - public String s; - public StringItem(String s) {this.s=s;} - - public void increment(int[] currentOffset) { - super.increment(currentOffset); - currentOffset[0] += s.length(); - } - public void emit(byte[] buffer) { - for (int i=0; i>> 24) & 0xff); - buffer[myOffset+2] = (byte) ((value >>> 16) & 0xff); - buffer[myOffset+3] = (byte) ((value >>> 8) & 0xff); - buffer[myOffset+4] = (byte) ((value >>> 0) & 0xff); - } - } - } - - /** An offset-marker item for the list. - * It is used to mark an offset and to set the offset list item. - */ - - static protected final class MarkerItem extends Item { - OffsetItem p; - public MarkerItem(OffsetItem pointerToMarker) {p=pointerToMarker;} - public void xref() { - p.set(this.myOffset); - } - } - - /** a utility that creates a range item for an entire index - * - * @param indexOffset where the index is - * @return a range item representing the entire index - */ - - protected RangeItem getEntireIndexRange(int indexOffset) { - seek(indexOffset); - int count = getCard16(); - if (count==0) { - return new RangeItem(buf,indexOffset,2); - } else { - int indexOffSize = getCard8(); - seek(indexOffset+2+1+count*indexOffSize); - int size = getOffset(indexOffSize)-1; - return new RangeItem(buf,indexOffset, - 2+1+(count+1)*indexOffSize+size); - } - } - - - /** get a single CID font. The PDF architecture (1.4) - * supports 16-bit strings only with CID CFF fonts, not - * in Type-1 CFF fonts, so we convert the font to CID if - * it is in the Type-1 format. - * Two other tasks that we need to do are to select - * only a single font from the CFF package (this again is - * a PDF restriction) and to subset the CharStrings glyph - * description. - */ - - - public byte[] getCID(String fontName) - //throws java.io.FileNotFoundException - { - int j; - for (j=0; j 127) - fdFontName = fdFontName.substring(0,127); - String extraStrings = "Adobe"+"Identity"+fdFontName; - - int origStringsLen = stringOffsets[stringOffsets.length-1] - - stringOffsets[0]; - int stringsBaseOffset = stringOffsets[0]-1; - - byte stringsIndexOffSize; - if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; - else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; - else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; - else stringsIndexOffSize = 4; - - l.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count - l.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize - for (int i=0; i= 0) { - //System.err.println("has subrs="+fonts[j].privateSubrs+" ,len="+fonts[j].privateLength); - l.addLast(getEntireIndexRange(fonts[j].privateSubrs)); - } - } - - // copy the charstring index - - l.addLast(new MarkerItem(charstringsRef)); - l.addLast(getEntireIndexRange(fonts[j].charstringsOffset)); - - // now create the new CFF font - - int[] currentOffset = new int[1]; - currentOffset[0] = 0; - - Iterator listIter = l.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.increment(currentOffset); - } - - listIter = l.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.xref(); - } - - int size = currentOffset[0]; - byte[] b = new byte[size]; - - listIter = l.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.emit(b); - } - - return b; - } - - - public boolean isCID(String fontName) { - int j; - for (j=0; j"); - } - - // string index - - //strings = new String[stringOffsets.length-1]; - /* - System.err.println("std strings = "+standardStrings.length); - System.err.println("fnt strings = "+(stringOffsets.length-1)); - for (char j=0; j"); - } - */ - - // top dict - - for (int j=0; j= 0) { - //System.err.println("PRIVATE::"); - seek(fonts[j].privateOffset); - while (getPosition() < fonts[j].privateOffset+fonts[j].privateLength) { - getDictItem(); - if (key=="Subrs") - //Add the private offset to the lsubrs since the offset is - // relative to the begining of the PrivateDict - fonts[j].privateSubrs = ((Integer)args[0]).intValue()+fonts[j].privateOffset; - } - } - - // fdarray index - if (fonts[j].fdarrayOffset >= 0) { - int[] fdarrayOffsets = getIndex(fonts[j].fdarrayOffset); - - fonts[j].fdprivateOffsets = new int[fdarrayOffsets.length-1]; - fonts[j].fdprivateLengths = new int[fdarrayOffsets.length-1]; - - //System.err.println("FD Font::"); - - for (int k=0; k - * @author Oren Manor & Ygal Blum - */ -public class CFFFontSubset extends CFFFont { - - /** - * The Strings in this array represent Type1/Type2 operator names - */ - static final String SubrsFunctions[] = { - "RESERVED_0","hstem","RESERVED_2","vstem","vmoveto","rlineto","hlineto","vlineto", - "rrcurveto","RESERVED_9","callsubr","return","escape","RESERVED_13", - "endchar","RESERVED_15","RESERVED_16","RESERVED_17","hstemhm","hintmask", - "cntrmask","rmoveto","hmoveto","vstemhm","rcurveline","rlinecurve","vvcurveto", - "hhcurveto","shortint","callgsubr","vhcurveto","hvcurveto" - }; - /** - * The Strings in this array represent Type1/Type2 escape operator names - */ - static final String SubrsEscapeFuncs[] = { - "RESERVED_0","RESERVED_1","RESERVED_2","and","or","not","RESERVED_6", - "RESERVED_7","RESERVED_8","abs","add","sub","div","RESERVED_13","neg", - "eq","RESERVED_16","RESERVED_17","drop","RESERVED_19","put","get","ifelse", - "random","mul","RESERVED_25","sqrt","dup","exch","index","roll","RESERVED_31", - "RESERVED_32","RESERVED_33","hflex","flex","hflex1","flex1","RESERVED_REST" - }; - - /** - * A HashMap containing the glyphs used in the text after being converted - * to glyph number by the CMap - */ - HashMap GlyphsUsed; - /** - * The GlyphsUsed keys as an ArrayList - */ - ArrayList glyphsInList; - /** - * A HashMap for keeping the FDArrays being used by the font - */ - HashMap FDArrayUsed = new HashMap(); - /** - * A HashMaps array for keeping the subroutines used in each FontDict - */ - HashMap[] hSubrsUsed; - /** - * The SubroutinesUsed HashMaps as ArrayLists - */ - ArrayList[] lSubrsUsed; - /** - * A HashMap for keeping the Global subroutines used in the font - */ - HashMap hGSubrsUsed = new HashMap(); - /** - * The Global SubroutinesUsed HashMaps as ArrayLists - */ - ArrayList lGSubrsUsed = new ArrayList(); - /** - * A HashMap for keeping the subroutines used in a non-cid font - */ - HashMap hSubrsUsedNonCID = new HashMap(); - /** - * The SubroutinesUsed HashMap as ArrayList - */ - ArrayList lSubrsUsedNonCID = new ArrayList(); - /** - * An array of the new Indexs for the local Subr. One index for each FontDict - */ - byte[][] NewLSubrsIndex; - /** - * The new subroutines index for a non-cid font - */ - byte[] NewSubrsIndexNonCID; - /** - * The new global subroutines index of the font - */ - byte[] NewGSubrsIndex; - /** - * The new CharString of the font - */ - byte[] NewCharStringsIndex; - - /** - * The bias for the global subroutines - */ - int GBias = 0; - - /** - * The linked list for generating the new font stream - */ - LinkedList OutputList; - - /** - * Number of arguments to the stem operators in a subroutine calculated recursivly - */ - int NumOfHints=0; - - - /** - * C'tor for CFFFontSubset - * @param rf - The font file - * @param GlyphsUsed - a HashMap that contains the glyph used in the subset - */ - public CFFFontSubset(RandomAccessFileOrArray rf,HashMap GlyphsUsed){ - // Use CFFFont c'tor in order to parse the font file. - super(rf); - this.GlyphsUsed = GlyphsUsed; - //Put the glyphs into a list - glyphsInList = new ArrayList(GlyphsUsed.keySet()); - - - for (int i=0;i=0) - { - // Proces the FDSelect - readFDSelect(i); - // Build the FDArrayUsed hashmap - BuildFDArrayUsed(i); - } - if (fonts[i].isCID) - // Build the FD Array used Hash Map - ReadFDArray(i); - // compute the charset length - fonts[i].CharsetLength = CountCharset(fonts[i].charsetOffset,fonts[i].nglyphs); - } - } - - /** - * Calculates the length of the charset according to its format - * @param Offset The Charset Offset - * @param NumofGlyphs Number of glyphs in the font - * @return the length of the Charset - */ - int CountCharset(int Offset,int NumofGlyphs){ - int format; - int Length=0; - seek(Offset); - // Read the format - format = getCard8(); - // Calc according to format - switch (format){ - case 0: - Length = 1+2*NumofGlyphs; - break; - case 1: - Length = 1+3*CountRange(NumofGlyphs,1); - break; - case 2: - Length = 1+4*CountRange(NumofGlyphs,2); - break; - default: - break; - } - return Length; - } - - /** - * Function calculates the number of ranges in the Charset - * @param NumofGlyphs The number of glyphs in the font - * @param Type The format of the Charset - * @return The number of ranges in the Charset data structure - */ - int CountRange(int NumofGlyphs,int Type){ - int num=0; - char Sid; - int i=1,nLeft,Places; - while (i= 0) - GBias = CalcBias(gsubrIndexOffset,j); - - // Prepare the new CharStrings Index - BuildNewCharString(j); - // Prepare the new Global and Local Subrs Indices - BuildNewLGSubrs(j); - // Build the new file - byte[] Ret = BuildNewFile(j); - return Ret; - } - finally { - try { - buf.close(); - } - catch (Exception e) { - // empty on purpose - } - } - } - - /** - * Function calcs bias according to the CharString type and the count - * of the subrs - * @param Offset The offset to the relevent subrs index - * @param Font the font - * @return The calculated Bias - */ - protected int CalcBias(int Offset,int Font) - { - seek(Offset); - int nSubrs = getCard16(); - // If type==1 -> bias=0 - if (fonts[Font].CharstringType == 1) - return 0; - // else calc according to the count - else if (nSubrs < 1240) - return 107; - else if (nSubrs < 33900) - return 1131; - else - return 32768; - } - - /** - *Function uses BuildNewIndex to create the new index of the subset charstrings - * @param FontIndex the font - * @throws IOException - */ - protected void BuildNewCharString(int FontIndex) throws IOException - { - NewCharStringsIndex = BuildNewIndex(fonts[FontIndex].charstringsOffsets,GlyphsUsed); - } - - /** - * Function builds the new local & global subsrs indices. IF CID then All of - * the FD Array lsubrs will be subsetted. - * @param Font the font - * @throws IOException - */ - protected void BuildNewLGSubrs(int Font)throws IOException - { - // If the font is CID then the lsubrs are divided into FontDicts. - // for each FD array the lsubrs will be subsetted. - if(fonts[Font].isCID) - { - // Init the hasmap-array and the arraylist-array to hold the subrs used - // in each private dict. - hSubrsUsed = new HashMap[fonts[Font].fdprivateOffsets.length]; - lSubrsUsed = new ArrayList[fonts[Font].fdprivateOffsets.length]; - // A [][] which will store the byte array for each new FD Array lsubs index - NewLSubrsIndex = new byte[fonts[Font].fdprivateOffsets.length][]; - // An array to hold the offset for each Lsubr index - fonts[Font].PrivateSubrsOffset = new int[fonts[Font].fdprivateOffsets.length]; - // A [][] which will store the offset array for each lsubr index - fonts[Font].PrivateSubrsOffsetsArray = new int[fonts[Font].fdprivateOffsets.length][]; - - // Put the FDarrayUsed into a list - ArrayList FDInList = new ArrayList(FDArrayUsed.keySet()); - // For each FD array which is used subset the lsubr - for (int j=0;j=0) - { - //Scans the Charsting data storing the used Local and Global subroutines - // by the glyphs. Scans the Subrs recursivley. - BuildSubrUsed(Font,FD,fonts[Font].PrivateSubrsOffset[FD],fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD],lSubrsUsed[FD]); - // Builds the New Local Subrs index - NewLSubrsIndex[FD] = BuildNewIndex(fonts[Font].PrivateSubrsOffsetsArray[FD],hSubrsUsed[FD]); - } - } - } - // If the font is not CID && the Private Subr exists then subset: - else if (fonts[Font].privateSubrs>=0) - { - // Build the subrs offsets; - fonts[Font].SubrsOffsets = getIndex(fonts[Font].privateSubrs); - //Scans the Charsting data storing the used Local and Global subroutines - // by the glyphs. Scans the Subrs recursivley. - BuildSubrUsed(Font,-1,fonts[Font].privateSubrs,fonts[Font].SubrsOffsets,hSubrsUsedNonCID,lSubrsUsedNonCID); - } - // For all fonts susbset the Global Subroutines - // Scan the Global Subr Hashmap recursivly on the Gsubrs - BuildGSubrsUsed(Font); - if (fonts[Font].privateSubrs>=0) - // Builds the New Local Subrs index - NewSubrsIndexNonCID = BuildNewIndex(fonts[Font].SubrsOffsets,hSubrsUsedNonCID); - //Builds the New Global Subrs index - NewGSubrsIndex = BuildNewIndex(gsubrOffsets,hGSubrsUsed); - } - - /** - * The function finds for the FD array processed the local subr offset and its - * offset array. - * @param Font the font - * @param FD The FDARRAY processed - */ - protected void BuildFDSubrsOffsets(int Font,int FD) - { - // Initiate to -1 to indicate lsubr operator present - fonts[Font].PrivateSubrsOffset[FD] = -1; - // Goto begining of objects - seek(fonts[Font].fdprivateOffsets[FD]); - // While in the same object: - while (getPosition() < fonts[Font].fdprivateOffsets[FD]+fonts[Font].fdprivateLengths[FD]) - { - getDictItem(); - // If the dictItem is the "Subrs" then find and store offset, - if (key=="Subrs") - fonts[Font].PrivateSubrsOffset[FD] = ((Integer)args[0]).intValue()+fonts[Font].fdprivateOffsets[FD]; - } - //Read the lsub index if the lsubr was found - if (fonts[Font].PrivateSubrsOffset[FD] >= 0) - fonts[Font].PrivateSubrsOffsetsArray[FD] = getIndex(fonts[Font].PrivateSubrsOffset[FD]); - } - - /** - * Function uses ReadAsubr on the glyph used to build the LSubr & Gsubr HashMap. - * The HashMap (of the lsub only) is then scaned recursivly for Lsubr & Gsubrs - * calls. - * @param Font the font - * @param FD FD array processed. 0 indicates function was called by non CID font - * @param SubrOffset the offset to the subr index to calc the bias - * @param SubrsOffsets the offset array of the subr index - * @param hSubr HashMap of the subrs used - * @param lSubr ArrayList of the subrs used - */ - protected void BuildSubrUsed(int Font,int FD,int SubrOffset,int[] SubrsOffsets,HashMap hSubr,ArrayList lSubr) - { - - // Calc the Bias for the subr index - int LBias = CalcBias(SubrOffset,Font); - - // For each glyph used find its GID, start & end pos - for (int i=0;i= 0) - { - EmptyStack(); - NumOfHints=0; - // Using FDSELECT find the FD Array the glyph belongs to. - int GlyphFD = fonts[Font].FDSelect[glyph]; - // If the Glyph is part of the FD being processed - if (GlyphFD == FD) - // Find the Subrs called by the glyph and insert to hash: - ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); - } - else - // If the font is not CID - //Find the Subrs called by the glyph and insert to hash: - ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); - } - // For all Lsubrs used, check recusrivly for Lsubr & Gsubr used - for (int i=0;i=0) - { - // Read and process the subr - int Start = SubrsOffsets[Subr]; - int End = SubrsOffsets[Subr+1]; - ReadASubr(Start,End,GBias,LBias,hSubr,lSubr,SubrsOffsets); - } - } - } - - /** - * Function scans the Glsubr used ArrayList to find recursive calls - * to Gsubrs and adds to Hashmap & ArrayList - * @param Font the font - */ - protected void BuildGSubrsUsed(int Font) - { - int LBias = 0; - int SizeOfNonCIDSubrsUsed = 0; - if (fonts[Font].privateSubrs>=0) - { - LBias = CalcBias(fonts[Font].privateSubrs,Font); - SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); - } - - // For each global subr used - for (int i=0;i=0) - { - // Read the subr and process - int Start = gsubrOffsets[Subr]; - int End = gsubrOffsets[Subr+1]; - - if (fonts[Font].isCID) - ReadASubr(Start,End,GBias,0,hGSubrsUsed,lGSubrsUsed,null); - else - { - ReadASubr(Start,End,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); - if (SizeOfNonCIDSubrsUsed < lSubrsUsedNonCID.size()) - { - for (int j=SizeOfNonCIDSubrsUsed;j=0) - { - // Read the subr and process - int LStart = fonts[Font].SubrsOffsets[LSubr]; - int LEnd = fonts[Font].SubrsOffsets[LSubr+1]; - ReadASubr(LStart,LEnd,GBias,LBias,hSubrsUsedNonCID,lSubrsUsedNonCID,fonts[Font].SubrsOffsets); - } - } - SizeOfNonCIDSubrsUsed = lSubrsUsedNonCID.size(); - } - } - } - } - } - - /** - * The function reads a subrs (glyph info) between begin and end. - * Adds calls to a Lsubr to the hSubr and lSubrs. - * Adds calls to a Gsubr to the hGSubr and lGSubrs. - * @param begin the start point of the subr - * @param end the end point of the subr - * @param GBias the bias of the Global Subrs - * @param LBias the bias of the Local Subrs - * @param hSubr the HashMap for the lSubrs - * @param lSubr the ArrayList for the lSubrs - */ - protected void ReadASubr(int begin,int end,int GBias,int LBias,HashMap hSubr,ArrayList lSubr,int[] LSubrsOffsets) - { - // Clear the stack for the subrs - EmptyStack(); - NumOfHints = 0; - // Goto begining of the subr - seek(begin); - while (getPosition() < end) - { - // Read the next command - ReadCommand(); - int pos = getPosition(); - Object TopElement=null; - if (arg_count > 0) - TopElement = args[arg_count-1]; - int NumOfArgs = arg_count; - // Check the modification needed on the Argument Stack according to key; - HandelStack(); - // a call to a Lsubr - if (key=="callsubr") - { - // Verify that arguments are passed - if (NumOfArgs > 0) - { - // Calc the index of the Subrs - int Subr = ((Integer)TopElement).intValue() + LBias; - // If the subr isn't in the HashMap -> Put in - if (!hSubr.containsKey(new Integer (Subr))) - { - hSubr.put(new Integer(Subr),null); - lSubr.add(new Integer(Subr)); - } - CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); - seek(pos); - } - } - // a call to a Gsubr - else if (key=="callgsubr") - { - // Verify that arguments are passed - if (NumOfArgs > 0) - { - // Calc the index of the Subrs - int Subr = ((Integer)TopElement).intValue() + GBias; - // If the subr isn't in the HashMap -> Put in - if (!hGSubrsUsed.containsKey(new Integer (Subr))) - { - hGSubrsUsed.put(new Integer(Subr),null); - lGSubrsUsed.add(new Integer(Subr)); - } - CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); - seek(pos); - } - } - // A call to "stem" - else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") - // Increment the NumOfHints by the number couples of of arguments - NumOfHints += NumOfArgs/2; - // A call to "mask" - else if (key == "hintmask" || key == "cntrmask") - { - // Compute the size of the mask - int SizeOfMask = NumOfHints/8; - if (NumOfHints%8 != 0 || SizeOfMask == 0) - SizeOfMask++; - // Continue the pointer in SizeOfMask steps - for (int i=0;i flush the stack - */ - protected int StackOpp() - { - if (key == "ifelse") - return -3; - if (key == "roll" || key == "put") - return -2; - if (key == "callsubr" || key == "callgsubr" || key == "add" || key == "sub" || - key == "div" || key == "mul" || key == "drop" || key == "and" || - key == "or" || key == "eq") - return -1; - if (key == "abs" || key == "neg" || key == "sqrt" || key == "exch" || - key == "index" || key == "get" || key == "not" || key == "return") - return 0; - if (key == "random" || key == "dup") - return 1; - return 2; - } - - /** - * Empty the Type2 Stack - * - */ - protected void EmptyStack() - { - // Null the arguments - for (int i=0; i0) - { - args[arg_count-1]=null; - arg_count--; - } - } - - /** - * Add an item to the stack - * - */ - protected void PushStack() - { - arg_count++; - } - - /** - * The function reads the next command after the file pointer is set - */ - protected void ReadCommand() - { - key = null; - boolean gotKey = false; - // Until a key is found - while (!gotKey) { - // Read the first Char - char b0 = getCard8(); - // decode according to the type1/type2 format - if (b0 == 28) // the two next bytes represent a short int; - { - int first = getCard8(); - int second = getCard8(); - args[arg_count] = new Integer(first<<8 | second); - arg_count++; - continue; - } - if (b0 >= 32 && b0 <= 246) // The byte read is the byte; - { - args[arg_count] = new Integer(b0 - 139); - arg_count++; - continue; - } - if (b0 >= 247 && b0 <= 250) // The byte read and the next byte constetute a short int - { - int w = getCard8(); - args[arg_count] = new Integer((b0-247)*256 + w + 108); - arg_count++; - continue; - } - if (b0 >= 251 && b0 <= 254)// Same as above except negative - { - int w = getCard8(); - args[arg_count] = new Integer(-(b0-251)*256 - w - 108); - arg_count++; - continue; - } - if (b0 == 255)// The next for bytes represent a double. - { - int first = getCard8(); - int second = getCard8(); - int third = getCard8(); - int fourth = getCard8(); - args[arg_count] = new Integer(first<<24 | second<<16 | third<<8 | fourth); - arg_count++; - continue; - } - if (b0<=31 && b0 != 28) // An operator was found.. Set Key. - { - gotKey=true; - // 12 is an escape command therefor the next byte is a part - // of this command - if (b0 == 12) - { - int b1 = getCard8(); - if (b1>SubrsEscapeFuncs.length-1) - b1 = SubrsEscapeFuncs.length-1; - key = SubrsEscapeFuncs[b1]; - } - else - key = SubrsFunctions[b0]; - continue; - } - } - } - - /** - * The function reads the subroutine and returns the number of the hint in it. - * If a call to another subroutine is found the function calls recursively. - * @param begin the start point of the subr - * @param end the end point of the subr - * @param LBias the bias of the Local Subrs - * @param GBias the bias of the Global Subrs - * @param LSubrsOffsets The Offsets array of the subroutines - * @return The number of hints in the subroutine read. - */ - protected int CalcHints(int begin,int end,int LBias,int GBias,int[] LSubrsOffsets) - { - // Goto begining of the subr - seek(begin); - while (getPosition() < end) - { - // Read the next command - ReadCommand(); - int pos = getPosition(); - Object TopElement = null; - if (arg_count>0) - TopElement = args[arg_count-1]; - int NumOfArgs = arg_count; - //Check the modification needed on the Argument Stack according to key; - HandelStack(); - // a call to a Lsubr - if (key=="callsubr") - { - if (NumOfArgs>0) - { - int Subr = ((Integer)TopElement).intValue() + LBias; - CalcHints(LSubrsOffsets[Subr],LSubrsOffsets[Subr+1],LBias,GBias,LSubrsOffsets); - seek(pos); - } - } - // a call to a Gsubr - else if (key=="callgsubr") - { - if (NumOfArgs>0) - { - int Subr = ((Integer)TopElement).intValue() + GBias; - CalcHints(gsubrOffsets[Subr],gsubrOffsets[Subr+1],LBias,GBias,LSubrsOffsets); - seek(pos); - } - } - // A call to "stem" - else if (key == "hstem" || key == "vstem" || key == "hstemhm" || key == "vstemhm") - // Increment the NumOfHints by the number couples of of arguments - NumOfHints += NumOfArgs/2; - // A call to "mask" - else if (key == "hintmask" || key == "cntrmask") - { - // Compute the size of the mask - int SizeOfMask = NumOfHints/8; - if (NumOfHints%8 != 0 || SizeOfMask == 0) - SizeOfMask++; - // Continue the pointer in SizeOfMask steps - for (int i=0;i>> 8) & 0xff); - NewIndex[Place++] = (byte) ((Count >>> 0) & 0xff); - // Write the offsize field - NewIndex[Place++] = Offsize; - // Write the offset array according to the offsize - for (int i=0;i>> 24) & 0xff); - case 3: - NewIndex[Place++] = (byte) ((Num >>> 16) & 0xff); - case 2: - NewIndex[Place++] = (byte) ((Num >>> 8) & 0xff); - case 1: - NewIndex[Place++] = (byte) ((Num >>> 0) & 0xff); - } - } - // Write the new object array one by one - for (int i=0;i=0) - OutputList.addLast(new RangeItem(buf,fonts[Font].fdselectOffset,fonts[Font].FDSelectLength)); - // Else create a new one - else - CreateFDSelect(fdselectRef,fonts[Font].nglyphs); - - // Copy the Charset - // Mark the beginning and copy entirly - OutputList.addLast(new MarkerItem(charsetRef)); - OutputList.addLast(new RangeItem(buf,fonts[Font].charsetOffset,fonts[Font].CharsetLength)); - - // Copy the FDArray - // If an FDArray exists - if (fonts[Font].fdarrayOffset>=0) - { - // Mark the beginning - OutputList.addLast(new MarkerItem(fdarrayRef)); - // Build a new FDArray with its private dicts and their LSubrs - Reconstruct(Font); - } - else - // Else create a new one - CreateFDArray(fdarrayRef,privateRef,Font); - - } - // If the font is not CID - else - { - // create FDSelect - CreateFDSelect(fdselectRef,fonts[Font].nglyphs); - // recreate a new charset - CreateCharset(charsetRef,fonts[Font].nglyphs); - // create a font dict index (fdarray) - CreateFDArray(fdarrayRef,privateRef,Font); - } - - // if a private dict exists insert its subsetted version - if (fonts[Font].privateOffset>=0) - { - // Mark the beginning of the private dict - IndexBaseItem PrivateBase = new IndexBaseItem(); - OutputList.addLast(PrivateBase); - OutputList.addLast(new MarkerItem(privateRef)); - - OffsetItem Subr = new DictOffsetItem(); - // Build and copy the new private dict - CreateNonCIDPrivate(Font,Subr); - // Copy the new LSubrs index - CreateNonCIDSubrs(Font,PrivateBase,Subr); - } - - // copy the charstring index - OutputList.addLast(new MarkerItem(charstringsRef)); - - // Add the subsetted charstring - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewCharStringsIndex),0,NewCharStringsIndex.length)); - - // now create the new CFF font - int[] currentOffset = new int[1]; - currentOffset[0] = 0; - // Count and save the offset for each item - Iterator listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.increment(currentOffset); - } - // Compute the Xref for each of the offset items - listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.xref(); - } - - int size = currentOffset[0]; - byte[] b = new byte[size]; - - // Emit all the items into the new byte array - listIter = OutputList.iterator(); - while ( listIter.hasNext() ) { - Item item = (Item) listIter.next(); - item.emit(b); - } - // Return the new stream - return b; - } - - /** - * Function Copies the header from the original fileto the output list - */ - protected void CopyHeader() - { - seek(0); - int major = getCard8(); - int minor = getCard8(); - int hdrSize = getCard8(); - int offSize = getCard8(); - nextIndexOffset = hdrSize; - OutputList.addLast(new RangeItem(buf,0,hdrSize)); - } - - /** - * Function Build the header of an index - * @param Count the count field of the index - * @param Offsize the offsize field of the index - * @param First the first offset of the index - */ - protected void BuildIndexHeader(int Count,int Offsize,int First) - { - // Add the count field - OutputList.addLast(new UInt16Item((char)Count)); // count - // Add the offsize field - OutputList.addLast(new UInt8Item((char)Offsize)); // offSize - // Add the first offset according to the offsize - switch(Offsize){ - case 1: - OutputList.addLast(new UInt8Item((char)First)); // first offset - break; - case 2: - OutputList.addLast(new UInt16Item((char)First)); // first offset - break; - case 3: - OutputList.addLast(new UInt24Item((char)First)); // first offset - break; - case 4: - OutputList.addLast(new UInt32Item((char)First)); // first offset - break; - default: - break; - } - } - - /** - * Function adds the keys into the TopDict - * @param fdarrayRef OffsetItem for the FDArray - * @param fdselectRef OffsetItem for the FDSelect - * @param charsetRef OffsetItem for the CharSet - * @param charstringsRef OffsetItem for the CharString - */ - protected void CreateKeys(OffsetItem fdarrayRef,OffsetItem fdselectRef,OffsetItem charsetRef,OffsetItem charstringsRef) - { - // create an FDArray key - OutputList.addLast(fdarrayRef); - OutputList.addLast(new UInt8Item((char)12)); - OutputList.addLast(new UInt8Item((char)36)); - // create an FDSelect key - OutputList.addLast(fdselectRef); - OutputList.addLast(new UInt8Item((char)12)); - OutputList.addLast(new UInt8Item((char)37)); - // create an charset key - OutputList.addLast(charsetRef); - OutputList.addLast(new UInt8Item((char)15)); - // create a CharStrings key - OutputList.addLast(charstringsRef); - OutputList.addLast(new UInt8Item((char)17)); - } - - /** - * Function takes the original string item and adds the new strings - * to accomodate the CID rules - * @param Font the font - */ - protected void CreateNewStringIndex(int Font) - { - String fdFontName = fonts[Font].name+"-OneRange"; - if (fdFontName.length() > 127) - fdFontName = fdFontName.substring(0,127); - String extraStrings = "Adobe"+"Identity"+fdFontName; - - int origStringsLen = stringOffsets[stringOffsets.length-1] - - stringOffsets[0]; - int stringsBaseOffset = stringOffsets[0]-1; - - byte stringsIndexOffSize; - if (origStringsLen+extraStrings.length() <= 0xff) stringsIndexOffSize = 1; - else if (origStringsLen+extraStrings.length() <= 0xffff) stringsIndexOffSize = 2; - else if (origStringsLen+extraStrings.length() <= 0xffffff) stringsIndexOffSize = 3; - else stringsIndexOffSize = 4; - - OutputList.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count - OutputList.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize - for (int i=0; i= 0) - { - OutputList.addLast(new SubrMarkerItem(fdSubrs[i],fdPrivateBase[i])); - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewLSubrsIndex[i]),0,NewLSubrsIndex[i].length)); - } - } - } - - /** - * Calculates how many byte it took to write the offset for the subrs in a specific - * private dict. - * @param Offset The Offset for the private dict - * @param Size The size of the private dict - * @return The size of the offset of the subrs in the private dict - */ - int CalcSubrOffsetSize(int Offset,int Size) - { - // Set the size to 0 - int OffsetSize = 0; - // Go to the beginning of the private dict - seek(Offset); - // Go until the end of the private dict - while (getPosition() < Offset+Size) - { - int p1 = getPosition(); - getDictItem(); - int p2 = getPosition(); - // When reached to the subrs offset - if (key=="Subrs") { - // The Offsize (minus the subrs key) - OffsetSize = p2-p1-1; - } - // All other keys are ignored - } - // return the size - return OffsetSize; - } - - /** - * Function computes the size of an index - * @param indexOffset The offset for the computed index - * @return The size of the index - */ - protected int countEntireIndexRange(int indexOffset) - { - // Go to the beginning of the index - seek(indexOffset); - // Read the count field - int count = getCard16(); - // If count==0 -> size=2 - if (count==0) - return 2; - else - { - // Read the offsize field - int indexOffSize = getCard8(); - // Go to the last element of the offset array - seek(indexOffset+2+1+count*indexOffSize); - // The size of the object array is the value of the last element-1 - int size = getOffset(indexOffSize)-1; - // Return the size of the entire index - return 2+1+(count+1)*indexOffSize+size; - } - } - - /** - * The function creates a private dict for a font that was not CID - * All the keys are copied as is except for the subrs key - * @param Font the font - * @param Subr The OffsetItem for the subrs of the private - */ - void CreateNonCIDPrivate(int Font,OffsetItem Subr) - { - // Go to the beginning of the private dict and read untill the end - seek(fonts[Font].privateOffset); - while (getPosition() < fonts[Font].privateOffset+fonts[Font].privateLength) - { - int p1 = getPosition(); - getDictItem(); - int p2 = getPosition(); - // If the dictItem is the "Subrs" then, - // use marker for offset and write operator number - if (key=="Subrs") { - OutputList.addLast(Subr); - OutputList.addLast(new UInt8Item((char)19)); // Subrs - } - // Else copy the entire range - else - OutputList.addLast(new RangeItem(buf,p1,p2-p1)); - } - } - - /** - * the function marks the beginning of the subrs index and adds the subsetted subrs - * index to the output list. - * @param Font the font - * @param PrivateBase IndexBaseItem for the private that's referencing to the subrs - * @param Subrs OffsetItem for the subrs - * @throws IOException - */ - void CreateNonCIDSubrs(int Font,IndexBaseItem PrivateBase,OffsetItem Subrs)throws IOException - { - // Mark the beginning of the Subrs index - OutputList.addLast(new SubrMarkerItem(Subrs,PrivateBase)); - // Put the subsetted new subrs index - OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewSubrsIndexNonCID),0,NewSubrsIndexNonCID.length)); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/CJKFont.java b/src/main/java/com/lowagie/text/pdf/CJKFont.java deleted file mode 100644 index 2137faf..0000000 --- a/src/main/java/com/lowagie/text/pdf/CJKFont.java +++ /dev/null @@ -1,626 +0,0 @@ -/* - * $Id: CJKFont.java,v 1.64 2005/05/04 14:33:05 blowagie Exp $ - * $Name: $ - * - * Copyright 2000, 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.DocumentException; -import java.io.*; -import java.util.HashMap; -import java.util.Properties; -import java.util.Hashtable; -import java.util.StringTokenizer; -import java.util.Enumeration; - -/** - * Creates a CJK font compatible with the fonts in the Adobe Asian font Pack. - * - * @author Paulo Soares (psoares@consiste.pt) - */ - -class CJKFont extends BaseFont { - /** The encoding used in the PDF document for CJK fonts - */ - static final String CJK_ENCODING = "UnicodeBigUnmarked"; - private static final int FIRST = 0; - private static final int BRACKET = 1; - private static final int SERIAL = 2; - private static final int V1Y = 880; - - static Properties cjkFonts = new Properties(); - static Properties cjkEncodings = new Properties(); - static Hashtable allCMaps = new Hashtable(); - static Hashtable allFonts = new Hashtable(); - private static boolean propertiesLoaded = false; - - /** The font name */ - private String fontName; - /** The style modifier */ - private String style = ""; - /** The CMap name associated with this font */ - private String CMap; - - private boolean cidDirect = false; - - private char[] translationMap; - private IntHashtable vMetrics; - private IntHashtable hMetrics; - private HashMap fontDesc; - private boolean vertical = false; - - private static void loadProperties() { - if (propertiesLoaded) - return; - synchronized (allFonts) { - if (propertiesLoaded) - return; - try { - InputStream is = getResourceStream(RESOURCE_PATH + "cjkfonts.properties"); - cjkFonts.load(is); - is.close(); - is = getResourceStream(RESOURCE_PATH + "cjkencodings.properties"); - cjkEncodings.load(is); - is.close(); - } - catch (Exception e) { - cjkFonts = new Properties(); - cjkEncodings = new Properties(); - } - propertiesLoaded = true; - } - } - - /** Creates a CJK font. - * @param fontName the name of the font - * @param enc the encoding of the font - * @param emb always false. CJK font and not embedded - * @throws DocumentException on error - * @throws IOException on error - */ - CJKFont(String fontName, String enc, boolean emb) throws DocumentException, IOException { - loadProperties(); - fontType = FONT_TYPE_CJK; - String nameBase = getBaseName(fontName); - if (!isCJKFont(nameBase, enc)) - throw new DocumentException("Font '" + fontName + "' with '" + enc + "' encoding is not a CJK font."); - if (nameBase.length() < fontName.length()) { - style = fontName.substring(nameBase.length()); - fontName = nameBase; - } - this.fontName = fontName; - encoding = CJK_ENCODING; - vertical = enc.endsWith("V"); - CMap = enc; - if (enc.startsWith("Identity-")) { - cidDirect = true; - String s = cjkFonts.getProperty(fontName); - s = s.substring(0, s.indexOf('_')); - char c[] = (char[])allCMaps.get(s); - if (c == null) { - c = readCMap(s); - if (c == null) - throw new DocumentException("The cmap " + s + " does not exist as a resource."); - c[CID_NEWLINE] = '\n'; - allCMaps.put(s, c); - } - translationMap = c; - } - else { - char c[] = (char[])allCMaps.get(enc); - if (c == null) { - String s = cjkEncodings.getProperty(enc); - if (s == null) - throw new DocumentException("The resource cjkencodings.properties does not contain the encoding " + enc); - StringTokenizer tk = new StringTokenizer(s); - String nt = tk.nextToken(); - c = (char[])allCMaps.get(nt); - if (c == null) { - c = readCMap(nt); - allCMaps.put(nt, c); - } - if (tk.hasMoreTokens()) { - String nt2 = tk.nextToken(); - char m2[] = readCMap(nt2); - for (int k = 0; k < 0x10000; ++k) { - if (m2[k] == 0) - m2[k] = c[k]; - } - allCMaps.put(enc, m2); - c = m2; - } - } - translationMap = c; - } - fontDesc = (HashMap)allFonts.get(fontName); - if (fontDesc == null) { - fontDesc = readFontProperties(fontName); - allFonts.put(fontName, fontDesc); - } - hMetrics = (IntHashtable)fontDesc.get("W"); - vMetrics = (IntHashtable)fontDesc.get("W2"); - } - - /** Checks if its a valid CJK font. - * @param fontName the font name - * @param enc the encoding - * @return true if it is CJK font - */ - public static boolean isCJKFont(String fontName, String enc) { - loadProperties(); - String encodings = cjkFonts.getProperty(fontName); - return (encodings != null && (enc.equals("Identity-H") || enc.equals("Identity-V") || encodings.indexOf("_" + enc + "_") >= 0)); - } - - public int getWidth(String text) { - int total = 0; - for (int k = 0; k < text.length(); ++k) { - int c = text.charAt(k); - if (!cidDirect) - c = translationMap[c]; - int v; - if (vertical) - v = vMetrics.get(c); - else - v = hMetrics.get(c); - if (v > 0) - total += v; - else - total += 1000; - } - return total; - } - - int getRawWidth(int c, String name) { - return 0; - } - - public int getKerning(char char1, char char2) { - return 0; - } - - private PdfDictionary getFontDescriptor() { - PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR); - dic.put(PdfName.ASCENT, new PdfLiteral((String)fontDesc.get("Ascent"))); - dic.put(PdfName.CAPHEIGHT, new PdfLiteral((String)fontDesc.get("CapHeight"))); - dic.put(PdfName.DESCENT, new PdfLiteral((String)fontDesc.get("Descent"))); - dic.put(PdfName.FLAGS, new PdfLiteral((String)fontDesc.get("Flags"))); - dic.put(PdfName.FONTBBOX, new PdfLiteral((String)fontDesc.get("FontBBox"))); - dic.put(PdfName.FONTNAME, new PdfName(fontName + style)); - dic.put(PdfName.ITALICANGLE, new PdfLiteral((String)fontDesc.get("ItalicAngle"))); - dic.put(PdfName.STEMV, new PdfLiteral((String)fontDesc.get("StemV"))); - PdfDictionary pdic = new PdfDictionary(); - pdic.put(PdfName.PANOSE, new PdfString((String)fontDesc.get("Panose"), null)); - dic.put(PdfName.STYLE, pdic); - return dic; - } - - private PdfDictionary getCIDFont(PdfIndirectReference fontDescriptor, IntHashtable cjkTag) { - PdfDictionary dic = new PdfDictionary(PdfName.FONT); - dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0); - dic.put(PdfName.BASEFONT, new PdfName(fontName + style)); - dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor); - int keys[] = cjkTag.toOrderedKeys(); - String w = convertToHCIDMetrics(keys, hMetrics); - if (w != null) - dic.put(PdfName.W, new PdfLiteral(w)); - if (vertical) { - w = convertToVCIDMetrics(keys, vMetrics, hMetrics);; - if (w != null) - dic.put(PdfName.W2, new PdfLiteral(w)); - } - else - dic.put(PdfName.DW, new PdfNumber(1000)); - PdfDictionary cdic = new PdfDictionary(); - cdic.put(PdfName.REGISTRY, new PdfString((String)fontDesc.get("Registry"), null)); - cdic.put(PdfName.ORDERING, new PdfString((String)fontDesc.get("Ordering"), null)); - cdic.put(PdfName.SUPPLEMENT, new PdfLiteral((String)fontDesc.get("Supplement"))); - dic.put(PdfName.CIDSYSTEMINFO, cdic); - return dic; - } - - private PdfDictionary getFontBaseType(PdfIndirectReference CIDFont) { - PdfDictionary dic = new PdfDictionary(PdfName.FONT); - dic.put(PdfName.SUBTYPE, PdfName.TYPE0); - String name = fontName; - if (style.length() > 0) - name += "-" + style.substring(1); - name += "-" + CMap; - dic.put(PdfName.BASEFONT, new PdfName(name)); - dic.put(PdfName.ENCODING, new PdfName(CMap)); - dic.put(PdfName.DESCENDANTFONTS, new PdfArray(CIDFont)); - return dic; - } - - void writeFont(PdfWriter writer, PdfIndirectReference ref, Object params[]) throws DocumentException, IOException { - IntHashtable cjkTag = (IntHashtable)params[0]; - PdfIndirectReference ind_font = null; - PdfObject pobj = null; - PdfIndirectObject obj = null; - pobj = getFontDescriptor(); - if (pobj != null){ - obj = writer.addToBody(pobj); - ind_font = obj.getIndirectReference(); - } - pobj = getCIDFont(ind_font, cjkTag); - if (pobj != null){ - obj = writer.addToBody(pobj); - ind_font = obj.getIndirectReference(); - } - pobj = getFontBaseType(ind_font); - writer.addToBody(pobj, ref); - } - - private float getDescNumber(String name) { - return Integer.parseInt((String)fontDesc.get(name)); - } - - private float getBBox(int idx) { - String s = (String)fontDesc.get("FontBBox"); - StringTokenizer tk = new StringTokenizer(s, " []\r\n\t\f"); - String ret = tk.nextToken(); - for (int k = 0; k < idx; ++k) - ret = tk.nextToken(); - return Integer.parseInt(ret); - } - - /** Gets the font parameter identified by key. Valid values - * for key are ASCENT, CAPHEIGHT, DESCENT - * and ITALICANGLE. - * @param key the parameter to be extracted - * @param fontSize the font size in points - * @return the parameter in points - */ - public float getFontDescriptor(int key, float fontSize) { - switch (key) { - case AWT_ASCENT: - case ASCENT: - return getDescNumber("Ascent") * fontSize / 1000; - case CAPHEIGHT: - return getDescNumber("CapHeight") * fontSize / 1000; - case AWT_DESCENT: - case DESCENT: - return getDescNumber("Descent") * fontSize / 1000; - case ITALICANGLE: - return getDescNumber("ItalicAngle"); - case BBOXLLX: - return fontSize * getBBox(0) / 1000; - case BBOXLLY: - return fontSize * getBBox(1) / 1000; - case BBOXURX: - return fontSize * getBBox(2) / 1000; - case BBOXURY: - return fontSize * getBBox(3) / 1000; - case AWT_LEADING: - return 0; - case AWT_MAXADVANCE: - return fontSize * (getBBox(2) - getBBox(0)) / 1000; - } - return 0; - } - - public String getPostscriptFontName() { - return fontName; - } - - /** Gets the full name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the full name of the font - */ - public String[][] getFullFontName() { - return new String[][]{{"", "", "", fontName}}; - } - - /** Gets the family name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the family name of the font - */ - public String[][] getFamilyFontName() { - return getFullFontName(); - } - - static char[] readCMap(String name) { - try { - name = name + ".cmap"; - InputStream is = getResourceStream(RESOURCE_PATH + name); - char c[] = new char[0x10000]; - for (int k = 0; k < 0x10000; ++k) - c[k] = (char)((is.read() << 8) + is.read()); - return c; - } - catch (Exception e) { - // empty on purpose - } - return null; - } - - static IntHashtable createMetric(String s) { - IntHashtable h = new IntHashtable(); - StringTokenizer tk = new StringTokenizer(s); - while (tk.hasMoreTokens()) { - int n1 = Integer.parseInt(tk.nextToken()); - h.put(n1, Integer.parseInt(tk.nextToken())); - } - return h; - } - - static String convertToHCIDMetrics(int keys[], IntHashtable h) { - if (keys.length == 0) - return null; - int lastCid = 0; - int lastValue = 0; - int start; - for (start = 0; start < keys.length; ++start) { - lastCid = keys[start]; - lastValue = h.get(lastCid); - if (lastValue != 0) { - ++start; - break; - } - } - if (lastValue == 0) - return null; - StringBuffer buf = new StringBuffer(); - buf.append('['); - buf.append(lastCid); - int state = FIRST; - for (int k = start; k < keys.length; ++k) { - int cid = keys[k]; - int value = h.get(cid); - if (value == 0) - continue; - switch (state) { - case FIRST: { - if (cid == lastCid + 1 && value == lastValue) { - state = SERIAL; - } - else if (cid == lastCid + 1) { - state = BRACKET; - buf.append('[').append(lastValue); - } - else { - buf.append('[').append(lastValue).append(']').append(cid); - } - break; - } - case BRACKET: { - if (cid == lastCid + 1 && value == lastValue) { - state = SERIAL; - buf.append(']').append(lastCid); - } - else if (cid == lastCid + 1) { - buf.append(' ').append(lastValue); - } - else { - state = FIRST; - buf.append(' ').append(lastValue).append(']').append(cid); - } - break; - } - case SERIAL: { - if (cid != lastCid + 1 || value != lastValue) { - buf.append(' ').append(lastCid).append(' ').append(lastValue).append(' ').append(cid); - state = FIRST; - } - break; - } - } - lastValue = value; - lastCid = cid; - } - switch (state) { - case FIRST: { - buf.append('[').append(lastValue).append("]]"); - break; - } - case BRACKET: { - buf.append(' ').append(lastValue).append("]]"); - break; - } - case SERIAL: { - buf.append(' ').append(lastCid).append(' ').append(lastValue).append(']'); - break; - } - } - return buf.toString(); - } - - static String convertToVCIDMetrics(int keys[], IntHashtable v, IntHashtable h) { - if (keys.length == 0) - return null; - int lastCid = 0; - int lastValue = 0; - int lastHValue = 0; - int start; - for (start = 0; start < keys.length; ++start) { - lastCid = keys[start]; - lastValue = v.get(lastCid); - if (lastValue != 0) { - ++start; - break; - } - else - lastHValue = h.get(lastCid); - } - if (lastValue == 0) - return null; - if (lastHValue == 0) - lastHValue = 1000; - StringBuffer buf = new StringBuffer(); - buf.append('['); - buf.append(lastCid); - int state = FIRST; - for (int k = start; k < keys.length; ++k) { - int cid = keys[k]; - int value = v.get(cid); - if (value == 0) - continue; - int hValue = h.get(lastCid); - if (hValue == 0) - hValue = 1000; - switch (state) { - case FIRST: { - if (cid == lastCid + 1 && value == lastValue && hValue == lastHValue) { - state = SERIAL; - } - else { - buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(' ').append(cid); - } - break; - } - case SERIAL: { - if (cid != lastCid + 1 || value != lastValue || hValue != lastHValue) { - buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(' ').append(cid); - state = FIRST; - } - break; - } - } - lastValue = value; - lastCid = cid; - lastHValue = hValue; - } - buf.append(' ').append(lastCid).append(' ').append(-lastValue).append(' ').append(lastHValue / 2).append(' ').append(V1Y).append(" ]"); - return buf.toString(); - } - - static HashMap readFontProperties(String name) { - try { - name += ".properties"; - InputStream is = getResourceStream(RESOURCE_PATH + name); - Properties p = new Properties(); - p.load(is); - is.close(); - IntHashtable W = createMetric(p.getProperty("W")); - p.remove("W"); - IntHashtable W2 = createMetric(p.getProperty("W2")); - p.remove("W2"); - HashMap map = new HashMap(); - for (Enumeration e = p.keys(); e.hasMoreElements();) { - Object obj = e.nextElement(); - map.put(obj, p.getProperty((String)obj)); - } - map.put("W", W); - map.put("W2", W2); - return map; - } - catch (Exception e) { - // empty on purpose - } - return null; - } - - public char getUnicodeEquivalent(char c) { - if (cidDirect) - return translationMap[c]; - return c; - } - - public char getCidCode(char c) { - if (cidDirect) - return c; - return translationMap[c]; - } - - /** Checks if the font has any kerning pairs. - * @return always false - */ - public boolean hasKernPairs() { - return false; - } - - /** - * Checks if a character exists in this font. - * @param c the character to check - * @return true if the character has a glyph, - * false otherwise - */ - public boolean charExists(char c) { - return translationMap[c] != 0; - } - - /** - * Sets the character advance. - * @param c the character - * @param advance the character advance normalized to 1000 units - * @return true if the advance was set, - * false otherwise. Will always return false - */ - public boolean setCharAdvance(char c, int advance) { - return false; - } - - /** - * Sets the font name that will appear in the pdf font dictionary. - * Use with care as it can easily make a font unreadable if not embedded. - * @param name the new font name - */ - public void setPostscriptFontName(String name) { - fontName = name; - } - - public boolean setKerning(char char1, char char2, int kern) { - return false; - } - - public int[] getCharBBox(char c) { - return null; - } - - protected int[] getRawCharBBox(int c, String name) { - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/CMYKColor.java b/src/main/java/com/lowagie/text/pdf/CMYKColor.java deleted file mode 100644 index 4acee83..0000000 --- a/src/main/java/com/lowagie/text/pdf/CMYKColor.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * $Id: CMYKColor.java,v 1.44 2005/12/11 15:31:04 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class CMYKColor extends ExtendedColor { - - float cyan; - float magenta; - float yellow; - float black; - - /** - * Constructs a CMYK Color beased on 4 colorvalues (values are integers from 0 to 255). - * @param intCyan - * @param intMagenta - * @param intYellow - * @param intBlack - */ - public CMYKColor(int intCyan, int intMagenta, int intYellow, int intBlack) { - this((float)intCyan / 255f, (float)intMagenta / 255f, (float)intYellow / 255f, (float)intBlack / 255f); - } - - /** - * Construct a CMYK Color. - * @param floatCyan - * @param floatMagenta - * @param floatYellow - * @param floatBlack - */ - public CMYKColor(float floatCyan, float floatMagenta, float floatYellow, float floatBlack) { - super(TYPE_CMYK, 1f - floatCyan - floatBlack, 1f - floatMagenta - floatBlack, 1f - floatYellow - floatBlack); - cyan = normalize(floatCyan); - magenta = normalize(floatMagenta); - yellow = normalize(floatYellow); - black = normalize(floatBlack); - } - - /** - * @return the cyan value - */ - public float getCyan() { - return cyan; - } - - /** - * @return the magenta value - */ - public float getMagenta() { - return magenta; - } - - /** - * @return the yellow value - */ - public float getYellow() { - return yellow; - } - - /** - * @return the black value - */ - public float getBlack() { - return black; - } - - public boolean equals(Object obj) { - if (!(obj instanceof CMYKColor)) - return false; - CMYKColor c2 = (CMYKColor)obj; - return (cyan == c2.cyan && magenta == c2.magenta && yellow == c2.yellow && black == c2.black); - } - - public int hashCode() { - return Float.floatToIntBits(cyan) ^ Float.floatToIntBits(magenta) ^ Float.floatToIntBits(yellow) ^ Float.floatToIntBits(black); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/ColorDetails.java b/src/main/java/com/lowagie/text/pdf/ColorDetails.java deleted file mode 100644 index b945c06..0000000 --- a/src/main/java/com/lowagie/text/pdf/ColorDetails.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * $Id: ColorDetails.java,v 1.43 2005/05/04 14:31:49 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -/** Each spotcolor in the document will have an instance of this class - * - * @author Phillip Pan (phillip@formstar.com) - */ -class ColorDetails { - - /** The indirect reference to this color - */ - PdfIndirectReference indirectReference; - /** The color name that appears in the document body stream - */ - PdfName colorName; - /** The color - */ - PdfSpotColor spotcolor; - - /** Each spot color used in a document has an instance of this class. - * @param colorName the color name - * @param indirectReference the indirect reference to the font - * @param scolor the PDfSpotColor - */ - ColorDetails(PdfName colorName, PdfIndirectReference indirectReference, PdfSpotColor scolor) { - this.colorName = colorName; - this.indirectReference = indirectReference; - this.spotcolor = scolor; - } - - /** Gets the indirect reference to this color. - * @return the indirect reference to this color - */ - PdfIndirectReference getIndirectReference() { - return indirectReference; - } - - /** Gets the color name as it appears in the document body. - * @return the color name - */ - PdfName getColorName() { - return colorName; - } - - /** Gets the SpotColor object. - * @return the PdfSpotColor - */ - PdfObject getSpotColor(PdfWriter writer) throws IOException { - return spotcolor.getSpotObject(writer); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/ColumnText.java b/src/main/java/com/lowagie/text/pdf/ColumnText.java deleted file mode 100644 index 3197290..0000000 --- a/src/main/java/com/lowagie/text/pdf/ColumnText.java +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * $Id: ColumnText.java,v 1.68 2006/01/29 20:28:23 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Stack; -import java.util.Iterator; -import com.lowagie.text.Phrase; -import com.lowagie.text.Chunk; -import com.lowagie.text.Paragraph; -import com.lowagie.text.Graphic; -import com.lowagie.text.ListItem; -import com.lowagie.text.Element; -import com.lowagie.text.DocumentException; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Image; -import com.lowagie.text.SimpleTable; - -/** - * Formats text in a columnwise form. The text is bound - * on the left and on the right by a sequence of lines. This allows the column - * to have any shape, not only rectangular. - *

- * Several parameters can be set like the first paragraph line indent and - * extra space between paragraphs. - *

- * A call to the method go will return one of the following - * situations: the column ended or the text ended. - *

- * I the column ended, a new column definition can be loaded with the method - * setColumns and the method go can be called again. - *

- * If the text ended, more text can be loaded with addText - * and the method go can be called again.
- * The only limitation is that one or more complete paragraphs must be loaded - * each time. - *

- * Full bidirectional reordering is supported. If the run direction is - * PdfWriter.RUN_DIRECTION_RTL the meaning of the horizontal - * alignments and margins is mirrored. - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class ColumnText { - /** Eliminate the arabic vowels */ - public static final int AR_NOVOWEL = ArabicLigaturizer.ar_novowel; - /** Compose the tashkeel in the ligatures. */ - public static final int AR_COMPOSEDTASHKEEL = ArabicLigaturizer.ar_composedtashkeel; - /** Do some extra double ligatures. */ - public static final int AR_LIG = ArabicLigaturizer.ar_lig; - /** - * Digit shaping option: Replace European digits (U+0030...U+0039) by Arabic-Indic digits. - */ - public static final int DIGITS_EN2AN = ArabicLigaturizer.DIGITS_EN2AN; - - /** - * Digit shaping option: Replace Arabic-Indic digits by European digits (U+0030...U+0039). - */ - public static final int DIGITS_AN2EN = ArabicLigaturizer.DIGITS_AN2EN; - - /** - * Digit shaping option: - * Replace European digits (U+0030...U+0039) by Arabic-Indic digits - * if the most recent strongly directional character - * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). - * The initial state at the start of the text is assumed to be not an Arabic, - * letter, so European digits at the start of the text will not change. - * Compare to DIGITS_ALEN2AN_INIT_AL. - */ - public static final int DIGITS_EN2AN_INIT_LR = ArabicLigaturizer.DIGITS_EN2AN_INIT_LR; - - /** - * Digit shaping option: - * Replace European digits (U+0030...U+0039) by Arabic-Indic digits - * if the most recent strongly directional character - * is an Arabic letter (its Bidi direction value is RIGHT_TO_LEFT_ARABIC). - * The initial state at the start of the text is assumed to be an Arabic, - * letter, so European digits at the start of the text will change. - * Compare to DIGITS_ALEN2AN_INT_LR. - */ - public static final int DIGITS_EN2AN_INIT_AL = ArabicLigaturizer.DIGITS_EN2AN_INIT_AL; - - /** - * Digit type option: Use Arabic-Indic digits (U+0660...U+0669). - */ - public static final int DIGIT_TYPE_AN = ArabicLigaturizer.DIGIT_TYPE_AN; - - /** - * Digit type option: Use Eastern (Extended) Arabic-Indic digits (U+06f0...U+06f9). - */ - public static final int DIGIT_TYPE_AN_EXTENDED = ArabicLigaturizer.DIGIT_TYPE_AN_EXTENDED; - - protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT; - - /** the space char ratio */ - public static final float GLOBAL_SPACE_CHAR_RATIO = 0; - - /** Initial value of the status. */ - public static final int START_COLUMN = 0; - - /** Signals that there is no more text available. */ - public static final int NO_MORE_TEXT = 1; - - /** Signals that there is no more column. */ - public static final int NO_MORE_COLUMN = 2; - - /** The column is valid. */ - protected static final int LINE_STATUS_OK = 0; - - /** The line is out the column limits. */ - protected static final int LINE_STATUS_OFFLIMITS = 1; - - /** The line cannot fit this column position. */ - protected static final int LINE_STATUS_NOLINE = 2; - - /** Upper bound of the column. */ - protected float maxY; - - /** Lower bound of the column. */ - protected float minY; - - protected float leftX; - - protected float rightX; - - /** The column alignment. Default is left alignment. */ - protected int alignment = Element.ALIGN_LEFT; - - /** The left column bound. */ - protected ArrayList leftWall; - - /** The right column bound. */ - protected ArrayList rightWall; - - /** The chunks that form the text. */ -// protected ArrayList chunks = new ArrayList(); - protected BidiLine bidiLine; - - /** The current y line location. Text will be written at this line minus the leading. */ - protected float yLine; - - /** The leading for the current line. */ - protected float currentLeading = 16; - - /** The fixed text leading. */ - protected float fixedLeading = 16; - - /** The text leading that is multiplied by the biggest font size in the line. */ - protected float multipliedLeading = 0; - - /** The PdfContent where the text will be written to. */ - protected PdfContentByte canvas; - - protected PdfContentByte[] canvases; - - /** The line status when trying to fit a line to a column. */ - protected int lineStatus; - - /** The first paragraph line indent. */ - protected float indent = 0; - - /** The following paragraph lines indent. */ - protected float followingIndent = 0; - - /** The right paragraph lines indent. */ - protected float rightIndent = 0; - - /** The extra space between paragraphs. */ - protected float extraParagraphSpace = 0; - - /** The width of the line when the column is defined as a simple rectangle. */ - protected float rectangularWidth = -1; - - protected boolean rectangularMode = false; - /** Holds value of property spaceCharRatio. */ - private float spaceCharRatio = GLOBAL_SPACE_CHAR_RATIO; - - private boolean lastWasNewline = true; - - /** Holds value of property linesWritten. */ - private int linesWritten; - - private float firstLineY; - private boolean firstLineYDone = false; - - /** Holds value of property arabicOptions. */ - private int arabicOptions = 0; - - protected float descender; - - protected boolean composite = false; - - protected ColumnText compositeColumn; - - protected LinkedList compositeElements; - - protected int listIdx = 0; - - private boolean splittedRow; - - protected Phrase waitPhrase; - - /** if true, first line height is adjusted so that the max ascender touches the top */ - private boolean useAscender = false; - - /** - * Creates a ColumnText. - * @param canvas the place where the text will be written to. Can - * be a template. - */ - public ColumnText(PdfContentByte canvas) { - this.canvas = canvas; - } - - /** Creates an independent duplicated of the instance org. - * @param org the original ColumnText - * @return the duplicated - */ - public static ColumnText duplicate(ColumnText org) { - ColumnText ct = new ColumnText(null); - ct.setACopy(org); - return ct; - } - - /** Makes this instance an independent copy of org. - * @param org the original ColumnText - * @return itself - */ - public ColumnText setACopy(ColumnText org) { - setSimpleVars(org); - if (org.bidiLine != null) - bidiLine = new BidiLine(org.bidiLine); - return this; - } - - protected void setSimpleVars(ColumnText org) { - maxY = org.maxY; - minY = org.minY; - alignment = org.alignment; - leftWall = null; - if (org.leftWall != null) - leftWall = new ArrayList(org.leftWall); - rightWall = null; - if (org.rightWall != null) - rightWall = new ArrayList(org.rightWall); - yLine = org.yLine; - currentLeading = org.currentLeading; - fixedLeading = org.fixedLeading; - multipliedLeading = org.multipliedLeading; - canvas = org.canvas; - canvases = org.canvases; - lineStatus = org.lineStatus; - indent = org.indent; - followingIndent = org.followingIndent; - rightIndent = org.rightIndent; - extraParagraphSpace = org.extraParagraphSpace; - rectangularWidth = org.rectangularWidth; - rectangularMode = org.rectangularMode; - spaceCharRatio = org.spaceCharRatio; - lastWasNewline = org.lastWasNewline; - linesWritten = org.linesWritten; - arabicOptions = org.arabicOptions; - runDirection = org.runDirection; - descender = org.descender; - composite = org.composite; - splittedRow = org.splittedRow; - if (org.composite) { - compositeElements = new LinkedList(org.compositeElements); - if (splittedRow) { - PdfPTable table = (PdfPTable)compositeElements.getFirst(); - compositeElements.set(0, new PdfPTable(table)); - } - if (org.compositeColumn != null) - compositeColumn = duplicate(org.compositeColumn); - } - listIdx = org.listIdx; - firstLineY = org.firstLineY; - leftX = org.leftX; - rightX = org.rightX; - firstLineYDone = org.firstLineYDone; - waitPhrase = org.waitPhrase; - useAscender = org.useAscender; - filledWidth = org.filledWidth; - } - - private void addWaitingPhrase() { - if (bidiLine == null && waitPhrase != null) { - bidiLine = new BidiLine(); - for (Iterator j = waitPhrase.getChunks().iterator(); j.hasNext();) { - bidiLine.addChunk(new PdfChunk((Chunk)j.next(), null)); - } - waitPhrase = null; - } - } - - /** - * Adds a Phrase to the current text array. - * Will not have any effect if addElement() was called before. - * @param phrase the text - */ - public void addText(Phrase phrase) { - if (phrase == null || composite) - return; - addWaitingPhrase(); - if (bidiLine == null) { - waitPhrase = phrase; - return; - } - for (Iterator j = phrase.getChunks().iterator(); j.hasNext();) { - bidiLine.addChunk(new PdfChunk((Chunk)j.next(), null)); - } - } - - /** - * Replaces the current text array with this Phrase. - * Anything added previously with addElement() is lost. - * @param phrase the text - */ - public void setText(Phrase phrase) { - bidiLine = null; - composite = false; - compositeColumn = null; - compositeElements = null; - listIdx = 0; - splittedRow = false; - waitPhrase = phrase; - } - - /** - * Adds a Chunk to the current text array. - * Will not have any effect if addElement() was called before. - * @param chunk the text - */ - public void addText(Chunk chunk) { - if (chunk == null || composite) - return; - addText(new Phrase(chunk)); - } - - /** - * Adds an element. Elements supported are Paragraph, - * List, PdfPTable, Image and - * Graphic. - *

- * It removes all the text placed with addText(). - * @param element the Element - */ - public void addElement(Element element) { - if (element == null) - return; - if (element instanceof Image) { - Image img = (Image)element; - PdfPTable t = new PdfPTable(1); - float w = img.getWidthPercentage(); - if (w == 0) { - t.setTotalWidth(img.scaledWidth()); - t.setLockedWidth(true); - } - else - t.setWidthPercentage(w); - t.setSpacingAfter(img.spacingAfter()); - t.setSpacingBefore(img.spacingBefore()); - switch (img.alignment()) { - case Image.LEFT: - t.setHorizontalAlignment(Element.ALIGN_LEFT); - break; - case Image.RIGHT: - t.setHorizontalAlignment(Element.ALIGN_RIGHT); - break; - default: - t.setHorizontalAlignment(Element.ALIGN_CENTER); - break; - } - PdfPCell c = new PdfPCell(img, true); - c.setPadding(0); - c.setBorder(img.border()); - c.setBorderColor(img.borderColor()); - c.setBorderWidth(img.borderWidth()); - c.setBackgroundColor(img.backgroundColor()); - t.addCell(c); - element = t; - } - if (element.type() == Element.CHUNK) { - element = new Paragraph((Chunk)element); - } - else if (element.type() == Element.PHRASE) { - element = new Paragraph((Phrase)element); - } - if (element instanceof SimpleTable) { - try { - element = ((SimpleTable)element).createPdfPTable(); - } catch (DocumentException e) { - throw new IllegalArgumentException("Element not allowed."); - } - } - else if (element.type() != Element.PARAGRAPH && element.type() != Element.LIST && element.type() != Element.PTABLE && element.type() != Element.GRAPHIC) - throw new IllegalArgumentException("Element not allowed."); - if (!composite) { - composite = true; - compositeElements = new LinkedList(); - bidiLine = null; - waitPhrase = null; - } - compositeElements.add(element); - } - - /** - * Converts a sequence of lines representing one of the column bounds into - * an internal format. - *

- * Each array element will contain a float[4] representing - * the line x = ax + b. - * @param cLine the column array - * @return the converted array - */ - protected ArrayList convertColumn(float cLine[]) { - if (cLine.length < 4) - throw new RuntimeException("No valid column line found."); - ArrayList cc = new ArrayList(); - for (int k = 0; k < cLine.length - 2; k += 2) { - float x1 = cLine[k]; - float y1 = cLine[k + 1]; - float x2 = cLine[k + 2]; - float y2 = cLine[k + 3]; - if (y1 == y2) - continue; - // x = ay + b - float a = (x1 - x2) / (y1 - y2); - float b = x1 - a * y1; - float r[] = new float[4]; - r[0] = Math.min(y1, y2); - r[1] = Math.max(y1, y2); - r[2] = a; - r[3] = b; - cc.add(r); - maxY = Math.max(maxY, r[1]); - minY = Math.min(minY, r[0]); - } - if (cc.size() == 0) - throw new RuntimeException("No valid column line found."); - return cc; - } - - /** - * Finds the intersection between the yLine and the column. It will - * set the lineStatus apropriatly. - * @param wall the column to intersect - * @return the x coordinate of the intersection - */ - protected float findLimitsPoint(ArrayList wall) { - lineStatus = LINE_STATUS_OK; - if (yLine < minY || yLine > maxY) { - lineStatus = LINE_STATUS_OFFLIMITS; - return 0; - } - for (int k = 0; k < wall.size(); ++k) { - float r[] = (float[])wall.get(k); - if (yLine < r[0] || yLine > r[1]) - continue; - return r[2] * yLine + r[3]; - } - lineStatus = LINE_STATUS_NOLINE; - return 0; - } - - /** - * Finds the intersection between the yLine and the two - * column bounds. It will set the lineStatus apropriatly. - * @return a float[2]with the x coordinates of the intersection - */ - protected float[] findLimitsOneLine() { - float x1 = findLimitsPoint(leftWall); - if (lineStatus == LINE_STATUS_OFFLIMITS || lineStatus == LINE_STATUS_NOLINE) - return null; - float x2 = findLimitsPoint(rightWall); - if (lineStatus == LINE_STATUS_NOLINE) - return null; - return new float[]{x1, x2}; - } - - /** - * Finds the intersection between the yLine, - * the yLine-leadingand the two - * column bounds. It will set the lineStatus apropriatly. - * @return a float[4]with the x coordinates of the intersection - */ - protected float[] findLimitsTwoLines() { - boolean repeat = false; - for (;;) { - if (repeat && currentLeading == 0) - return null; - repeat = true; - float x1[] = findLimitsOneLine(); - if (lineStatus == LINE_STATUS_OFFLIMITS) - return null; - yLine -= currentLeading; - if (lineStatus == LINE_STATUS_NOLINE) { - continue; - } - float x2[] = findLimitsOneLine(); - if (lineStatus == LINE_STATUS_OFFLIMITS) - return null; - if (lineStatus == LINE_STATUS_NOLINE) { - yLine -= currentLeading; - continue; - } - if (x1[0] >= x2[1] || x2[0] >= x1[1]) - continue; - return new float[]{x1[0], x1[1], x2[0], x2[1]}; - } - } - - /** - * Sets the columns bounds. Each column bound is described by a - * float[] with the line points [x1,y1,x2,y2,...]. - * The array must have at least 4 elements. - * @param leftLine the left column bound - * @param rightLine the right column bound - */ - public void setColumns(float leftLine[], float rightLine[]) { - maxY = -10e20f; - minY = 10e20f; - rightWall = convertColumn(rightLine); - leftWall = convertColumn(leftLine); - rectangularWidth = -1; - rectangularMode = false; - } - - /** - * Simplified method for rectangular columns. - * @param phrase a Phrase - * @param llx the lower left x corner - * @param lly the lower left y corner - * @param urx the upper right x corner - * @param ury the upper right y corner - * @param leading the leading - * @param alignment the column alignment - */ - public void setSimpleColumn(Phrase phrase, float llx, float lly, float urx, float ury, float leading, int alignment) { - addText(phrase); - setSimpleColumn(llx, lly, urx, ury, leading, alignment); - } - - /** - * Simplified method for rectangular columns. - * @param llx the lower left x corner - * @param lly the lower left y corner - * @param urx the upper right x corner - * @param ury the upper right y corner - * @param leading the leading - * @param alignment the column alignment - */ - public void setSimpleColumn(float llx, float lly, float urx, float ury, float leading, int alignment) { - setLeading(leading); - this.alignment = alignment; - setSimpleColumn(llx, lly, urx, ury); - } - - /** - * Simplified method for rectangular columns. - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void setSimpleColumn(float llx, float lly, float urx, float ury) { - leftX = Math.min(llx, urx); - maxY = Math.max(lly, ury); - minY = Math.min(lly, ury); - rightX = Math.max(llx, urx); - yLine = maxY; - rectangularWidth = rightX - leftX; - if (rectangularWidth < 0) - rectangularWidth = 0; - rectangularMode = true; - } - /** - * Sets the leading to fixed - * @param leading the leading - */ - public void setLeading(float leading) { - fixedLeading = leading; - multipliedLeading = 0; - } - - /** - * Sets the leading fixed and variable. The resultant leading will be - * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the - * size of the bigest font in the line. - * @param fixedLeading the fixed leading - * @param multipliedLeading the variable leading - */ - public void setLeading(float fixedLeading, float multipliedLeading) { - this.fixedLeading = fixedLeading; - this.multipliedLeading = multipliedLeading; - } - - /** - * Gets the fixed leading - * @return the leading - */ - public float getLeading() { - return fixedLeading; - } - - /** - * Gets the variable leading - * @return the leading - */ - public float getMultipliedLeading() { - return multipliedLeading; - } - - /** - * Sets the yLine. The line will be written to yLine-leading. - * @param yLine the yLine - */ - public void setYLine(float yLine) { - this.yLine = yLine; - } - - /** - * Gets the yLine. - * @return the yLine - */ - public float getYLine() { - return yLine; - } - - /** - * Sets the alignment. - * @param alignment the alignment - */ - public void setAlignment(int alignment) { - this.alignment = alignment; - } - - /** - * Gets the alignment. - * @return the alignment - */ - public int getAlignment() { - return alignment; - } - - /** - * Sets the first paragraph line indent. - * @param indent the indent - */ - public void setIndent(float indent) { - this.indent = indent; - lastWasNewline = true; - } - - /** - * Gets the first paragraph line indent. - * @return the indent - */ - public float getIndent() { - return indent; - } - - /** - * Sets the following paragraph lines indent. - * @param indent the indent - */ - public void setFollowingIndent(float indent) { - this.followingIndent = indent; - lastWasNewline = true; - } - - /** - * Gets the following paragraph lines indent. - * @return the indent - */ - public float getFollowingIndent() { - return followingIndent; - } - - /** - * Sets the right paragraph lines indent. - * @param indent the indent - */ - public void setRightIndent(float indent) { - this.rightIndent = indent; - lastWasNewline = true; - } - - /** - * Gets the right paragraph lines indent. - * @return the indent - */ - public float getRightIndent() { - return rightIndent; - } - - /** - * Outputs the lines to the document. It is equivalent to go(false). - * @return returns the result of the operation. It can be NO_MORE_TEXT - * and/or NO_MORE_COLUMN - * @throws DocumentException on error - */ - public int go() throws DocumentException { - return go(false); - } - - /** - * Outputs the lines to the document. The output can be simulated. - * @param simulate true to simulate the writting to the document - * @return returns the result of the operation. It can be NO_MORE_TEXT - * and/or NO_MORE_COLUMN - * @throws DocumentException on error - */ - public int go(boolean simulate) throws DocumentException { - if (composite) - return goComposite(simulate); - addWaitingPhrase(); - if (bidiLine == null) - return NO_MORE_TEXT; - descender = 0; - linesWritten = 0; - boolean dirty = false; - float ratio = spaceCharRatio; - Object currentValues[] = new Object[2]; - PdfFont currentFont = null; - Float lastBaseFactor = new Float(0); - currentValues[1] = lastBaseFactor; - PdfDocument pdf = null; - PdfContentByte graphics = null; - PdfContentByte text = null; - firstLineY = Float.NaN; - int localRunDirection = PdfWriter.RUN_DIRECTION_NO_BIDI; - if (runDirection != PdfWriter.RUN_DIRECTION_DEFAULT) - localRunDirection = runDirection; - if (canvas != null) { - graphics = canvas; - pdf = canvas.getPdfDocument(); - text = canvas.getDuplicate(); - } - else if (!simulate) - throw new NullPointerException("ColumnText.go with simulate==false and text==null."); - if (!simulate) { - if (ratio == GLOBAL_SPACE_CHAR_RATIO) - ratio = text.getPdfWriter().getSpaceCharRatio(); - else if (ratio < 0.001f) - ratio = 0.001f; - } - float firstIndent = 0; - - int status = 0; - if (rectangularMode) { - for (;;) { - firstIndent = (lastWasNewline ? indent : followingIndent); - if (rectangularWidth <= firstIndent + rightIndent) { - status = NO_MORE_COLUMN; - if (bidiLine.isEmpty()) - status |= NO_MORE_TEXT; - break; - } - if (bidiLine.isEmpty()) { - status = NO_MORE_TEXT; - break; - } - PdfLine line = bidiLine.processLine(rectangularWidth - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); - if (line == null) { - status = NO_MORE_TEXT; - break; - } - float maxSize = line.getMaxSizeSimple(); - if (isUseAscender() && Float.isNaN(firstLineY)) { - currentLeading = line.getAscender(); - } - else { - currentLeading = fixedLeading + maxSize * multipliedLeading; - } - if (yLine > maxY || yLine - currentLeading < minY ) { - status = NO_MORE_COLUMN; - bidiLine.restore(); - break; - } - yLine -= currentLeading; - if (!simulate && !dirty) { - text.beginText(); - dirty = true; - } - if (Float.isNaN(firstLineY)) { - firstLineY = yLine; - } - updateFilledWidth(rectangularWidth - line.widthLeft()); - if (!simulate) { - currentValues[0] = currentFont; - text.setTextMatrix(leftX + (line.isRTL() ? rightIndent : firstIndent) + line.indentLeft(), yLine); - pdf.writeLineToContent(line, text, graphics, currentValues, ratio); - currentFont = (PdfFont)currentValues[0]; - } - lastWasNewline = line.isNewlineSplit(); - yLine -= line.isNewlineSplit() ? extraParagraphSpace : 0; - ++linesWritten; - descender = line.getDescender(); - } - } - else { - currentLeading = fixedLeading; - for (;;) { - firstIndent = (lastWasNewline ? indent : followingIndent); - float yTemp = yLine; - float xx[] = findLimitsTwoLines(); - if (xx == null) { - status = NO_MORE_COLUMN; - if (bidiLine.isEmpty()) - status |= NO_MORE_TEXT; - yLine = yTemp; - break; - } - if (bidiLine.isEmpty()) { - status = NO_MORE_TEXT; - yLine = yTemp; - break; - } - float x1 = Math.max(xx[0], xx[2]); - float x2 = Math.min(xx[1], xx[3]); - if (x2 - x1 <= firstIndent + rightIndent) - continue; - if (!simulate && !dirty) { - text.beginText(); - dirty = true; - } - PdfLine line = bidiLine.processLine(x2 - x1 - firstIndent - rightIndent, alignment, localRunDirection, arabicOptions); - if (line == null) { - status = NO_MORE_TEXT; - yLine = yTemp; - break; - } - if (!simulate) { - currentValues[0] = currentFont; - text.setTextMatrix(x1 + (line.isRTL() ? rightIndent : firstIndent) + line.indentLeft(), yLine); - pdf.writeLineToContent(line, text, graphics, currentValues, ratio); - currentFont = (PdfFont)currentValues[0]; - } - lastWasNewline = line.isNewlineSplit(); - yLine -= line.isNewlineSplit() ? extraParagraphSpace : 0; - ++linesWritten; - descender = line.getDescender(); - } - } - if (dirty) { - text.endText(); - canvas.add(text); - } - return status; - } - - /** - * Sets the extra space between paragraphs. - * @return the extra space between paragraphs - */ - public float getExtraParagraphSpace() { - return extraParagraphSpace; - } - - /** - * Sets the extra space between paragraphs. - * @param extraParagraphSpace the extra space between paragraphs - */ - public void setExtraParagraphSpace(float extraParagraphSpace) { - this.extraParagraphSpace = extraParagraphSpace; - } - - /** - * Clears the chunk array. A call to go() will always return - * NO_MORE_TEXT. - */ - public void clearChunks() { - if (bidiLine != null) - bidiLine.clearChunks(); - } - - /** Gets the space/character extra spacing ratio for - * fully justified text. - * @return the space/character extra spacing ratio - */ - public float getSpaceCharRatio() { - return spaceCharRatio; - } - - /** Sets the ratio between the extra word spacing and the extra character spacing - * when the text is fully justified. - * Extra word spacing will grow spaceCharRatio times more than extra character spacing. - * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the extra character spacing - * will be zero. - * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing - */ - public void setSpaceCharRatio(float spaceCharRatio) { - this.spaceCharRatio = spaceCharRatio; - } - - /** Sets the run direction. - * @param runDirection the run direction - */ - public void setRunDirection(int runDirection) { - if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) - throw new RuntimeException("Invalid run direction: " + runDirection); - this.runDirection = runDirection; - } - - /** Gets the run direction. - * @return the run direction - */ - public int getRunDirection() { - return runDirection; - } - - /** Gets the number of lines written. - * @return the number of lines written - */ - public int getLinesWritten() { - return this.linesWritten; - } - - /** Gets the arabic shaping options. - * @return the arabic shaping options - */ - public int getArabicOptions() { - return this.arabicOptions; - } - - /** Sets the arabic shaping options. The option can be AR_NOVOWEL, - * AR_COMPOSEDTASHKEEL and AR_LIG. - * @param arabicOptions the arabic shaping options - */ - public void setArabicOptions(int arabicOptions) { - this.arabicOptions = arabicOptions; - } - - /** Gets the biggest descender value of the last line written. - * @return the biggest descender value of the last line written - */ - public float getDescender() { - return descender; - } - - /** Gets the width that the line will occupy after writing. - * Only the width of the first line is returned. - * @param phrase the Phrase containing the line - * @param runDirection the run direction - * @param arabicOptions the options for the arabic shaping - * @return the width of the line - */ - public static float getWidth(Phrase phrase, int runDirection, int arabicOptions) { - ColumnText ct = new ColumnText(null); - ct.addText(phrase); - ct.addWaitingPhrase(); - PdfLine line = ct.bidiLine.processLine(20000, Element.ALIGN_LEFT, runDirection, arabicOptions); - if (line == null) - return 0; - else - return 20000 - line.widthLeft(); - } - - /** Gets the width that the line will occupy after writing. - * Only the width of the first line is returned. - * @param phrase the Phrase containing the line - * @return the width of the line - */ - public static float getWidth(Phrase phrase) { - return getWidth(phrase, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); - } - - /** Shows a line of text. Only the first line is written. - * @param canvas where the text is to be written to - * @param alignment the alignment. It is not influenced by the run direction - * @param phrase the Phrase with the text - * @param x the x reference position - * @param y the y reference position - * @param rotation the rotation to be applied in degrees counterclockwise - * @param runDirection the run direction - * @param arabicOptions the options for the arabic shaping - */ - public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation, int runDirection, int arabicOptions) { - if (alignment != Element.ALIGN_LEFT && alignment != Element.ALIGN_CENTER - && alignment != Element.ALIGN_RIGHT) - alignment = Element.ALIGN_LEFT; - canvas.saveState(); - ColumnText ct = new ColumnText(canvas); - if (rotation == 0) { - if (alignment == Element.ALIGN_LEFT) - ct.setSimpleColumn(phrase, x, y - 1, 20000 + x, y + 2, 2, alignment); - else if (alignment == Element.ALIGN_RIGHT) - ct.setSimpleColumn(phrase, x-20000, y-1, x, y+2, 2, alignment); - else - ct.setSimpleColumn(phrase, x-20000, y-1, x+20000, y+2, 2, alignment); - } - else { - double alpha = rotation * Math.PI / 180.0; - float cos = (float)Math.cos(alpha); - float sin = (float)Math.sin(alpha); - canvas.concatCTM(cos, sin, -sin, cos, x, y); - if (alignment == Element.ALIGN_LEFT) - ct.setSimpleColumn(phrase, 0, -1, 20000, 2, 2, alignment); - else if (alignment == Element.ALIGN_RIGHT) - ct.setSimpleColumn(phrase, -20000, -1, 0, 2, 2, alignment); - else - ct.setSimpleColumn(phrase, -20000, -1, 20000, 2, 2, alignment); - } - if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { - if (alignment == Element.ALIGN_LEFT) - alignment = Element.ALIGN_RIGHT; - else if (alignment == Element.ALIGN_RIGHT) - alignment = Element.ALIGN_LEFT; - } - ct.setAlignment(alignment); - ct.setArabicOptions(arabicOptions); - ct.setRunDirection(runDirection); - try { - ct.go(); - } - catch (DocumentException e) { - throw new ExceptionConverter(e); - } - canvas.restoreState(); - } - - /** Shows a line of text. Only the first line is written. - * @param canvas where the text is to be written to - * @param alignment the alignment - * @param phrase the Phrase with the text - * @param x the x reference position - * @param y the y reference position - * @param rotation the rotation to be applied in degrees counterclockwise - */ - public static void showTextAligned(PdfContentByte canvas, int alignment, Phrase phrase, float x, float y, float rotation) { - showTextAligned(canvas, alignment, phrase, x, y, rotation, PdfWriter.RUN_DIRECTION_NO_BIDI, 0); - } - - protected int goComposite(boolean simulate) throws DocumentException { - if (!rectangularMode) - throw new DocumentException("Irregular columns are not supported in composite mode."); - linesWritten = 0; - descender = 0; - boolean firstPass = true; - main_loop: - while (true) { - if (compositeElements.isEmpty()) - return NO_MORE_TEXT; - Element element = (Element)compositeElements.getFirst(); - if (element.type() == Element.PARAGRAPH) { - Paragraph para = (Paragraph)element; - int status = 0; - for (int keep = 0; keep < 2; ++keep) { - float lastY = yLine; - boolean createHere = false; - if (compositeColumn == null) { - compositeColumn = new ColumnText(canvas); - compositeColumn.setUseAscender(firstPass ? useAscender : false); - compositeColumn.setAlignment(para.alignment()); - compositeColumn.setIndent(para.indentationLeft() + para.getFirstLineIndent()); - compositeColumn.setExtraParagraphSpace(para.getExtraParagraphSpace()); - compositeColumn.setFollowingIndent(para.indentationLeft()); - compositeColumn.setRightIndent(para.indentationRight()); - compositeColumn.setLeading(para.leading(), para.getMultipliedLeading()); - compositeColumn.setRunDirection(runDirection); - compositeColumn.setArabicOptions(arabicOptions); - compositeColumn.setSpaceCharRatio(spaceCharRatio); - compositeColumn.addText(para); - if (!firstPass) { - yLine -= para.spacingBefore(); - } - createHere = true; - } - compositeColumn.leftX = leftX; - compositeColumn.rightX = rightX; - compositeColumn.yLine = yLine; - compositeColumn.rectangularWidth = rectangularWidth; - compositeColumn.rectangularMode = rectangularMode; - compositeColumn.minY = minY; - compositeColumn.maxY = maxY; - boolean keepCandidate = (para.getKeepTogether() && createHere && !firstPass); - status = compositeColumn.go(simulate || (keepCandidate && keep == 0)); - updateFilledWidth(compositeColumn.filledWidth); - if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { - compositeColumn = null; - yLine = lastY; - return NO_MORE_COLUMN; - } - if (simulate || !keepCandidate) - break; - if (keep == 0) { - compositeColumn = null; - yLine = lastY; - } - } - firstPass = false; - yLine = compositeColumn.yLine; - linesWritten += compositeColumn.linesWritten; - descender = compositeColumn.descender; - if ((status & NO_MORE_TEXT) != 0) { - compositeColumn = null; - compositeElements.removeFirst(); - yLine -= para.spacingAfter(); - } - if ((status & NO_MORE_COLUMN) != 0) { - return NO_MORE_COLUMN; - } - } - else if (element.type() == Element.LIST) { - com.lowagie.text.List list = (com.lowagie.text.List)element; - ArrayList items = list.getItems(); - ListItem item = null; - float listIndentation = list.indentationLeft(); - int count = 0; - Stack stack = new Stack(); - for (int k = 0; k < items.size(); ++k) { - Object obj = items.get(k); - if (obj instanceof ListItem) { - if (count == listIdx) { - item = (ListItem)obj; - break; - } - else ++count; - } - else if (obj instanceof com.lowagie.text.List) { - stack.push(new Object[]{list, new Integer(k), new Float(listIndentation)}); - list = (com.lowagie.text.List)obj; - items = list.getItems(); - listIndentation += list.indentationLeft(); - k = -1; - continue; - } - if (k == items.size() - 1) { - if (!stack.isEmpty()) { - Object objs[] = (Object[])stack.pop(); - list = (com.lowagie.text.List)objs[0]; - items = list.getItems(); - k = ((Integer)objs[1]).intValue(); - listIndentation = ((Float)objs[2]).floatValue(); - } - } - } - int status = 0; - for (int keep = 0; keep < 2; ++keep) { - float lastY = yLine; - boolean createHere = false; - if (compositeColumn == null) { - if (item == null) { - listIdx = 0; - compositeElements.removeFirst(); - continue main_loop; - } - compositeColumn = new ColumnText(canvas); - compositeColumn.setUseAscender(firstPass ? useAscender : false); - compositeColumn.setAlignment(item.alignment()); - compositeColumn.setIndent(item.indentationLeft() + listIndentation + item.getFirstLineIndent()); - compositeColumn.setExtraParagraphSpace(item.getExtraParagraphSpace()); - compositeColumn.setFollowingIndent(compositeColumn.getIndent()); - compositeColumn.setRightIndent(item.indentationRight() + list.indentationRight()); - compositeColumn.setLeading(item.leading(), item.getMultipliedLeading()); - compositeColumn.setRunDirection(runDirection); - compositeColumn.setArabicOptions(arabicOptions); - compositeColumn.setSpaceCharRatio(spaceCharRatio); - compositeColumn.addText(item); - if (!firstPass) { - yLine -= item.spacingBefore(); - } - createHere = true; - } - compositeColumn.leftX = leftX; - compositeColumn.rightX = rightX; - compositeColumn.yLine = yLine; - compositeColumn.rectangularWidth = rectangularWidth; - compositeColumn.rectangularMode = rectangularMode; - compositeColumn.minY = minY; - compositeColumn.maxY = maxY; - boolean keepCandidate = (item.getKeepTogether() && createHere && !firstPass); - status = compositeColumn.go(simulate || (keepCandidate && keep == 0)); - updateFilledWidth(compositeColumn.filledWidth); - if ((status & NO_MORE_TEXT) == 0 && keepCandidate) { - compositeColumn = null; - yLine = lastY; - return NO_MORE_COLUMN; - } - if (simulate || !keepCandidate) - break; - if (keep == 0) { - compositeColumn = null; - yLine = lastY; - } - } - firstPass = false; - yLine = compositeColumn.yLine; - linesWritten += compositeColumn.linesWritten; - descender = compositeColumn.descender; - if (!Float.isNaN(compositeColumn.firstLineY) && !compositeColumn.firstLineYDone) { - if (!simulate) - showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(item.listSymbol()), compositeColumn.leftX + listIndentation, compositeColumn.firstLineY, 0); - compositeColumn.firstLineYDone = true; - } - if ((status & NO_MORE_TEXT) != 0) { - compositeColumn = null; - ++listIdx; - yLine -= item.spacingAfter(); - } - if ((status & NO_MORE_COLUMN) != 0) { - return NO_MORE_COLUMN; - } - } - else if (element.type() == Element.PTABLE) { - if (yLine < minY || yLine > maxY) - return NO_MORE_COLUMN; - PdfPTable table = (PdfPTable)element; - if (table.size() <= table.getHeaderRows()) { - compositeElements.removeFirst(); - continue; - } - float yTemp = yLine; - float yLineWrite = yLine; - if (!firstPass && listIdx == 0) { - yTemp -= table.spacingBefore(); - yLineWrite = yTemp; - } - currentLeading = 0; - if (yTemp < minY || yTemp > maxY) - return NO_MORE_COLUMN; - float x1 = leftX; - float tableWidth; - if (table.isLockedWidth()) { - tableWidth = table.getTotalWidth(); - updateFilledWidth(tableWidth); - } - else { - tableWidth = rectangularWidth * table.getWidthPercentage() / 100f; - table.setTotalWidth(tableWidth); - } - int k; - boolean skipHeader = (!firstPass && table.isSkipFirstHeader() && listIdx <= table.getHeaderRows()); - if (!skipHeader) { - yTemp -= table.getHeaderHeight(); - if (yTemp < minY || yTemp > maxY) { - if (firstPass) { - compositeElements.removeFirst(); - continue; - } - return NO_MORE_COLUMN; - } - } - if (listIdx < table.getHeaderRows()) - listIdx = table.getHeaderRows(); - for (k = listIdx; k < table.size(); ++k) { - float rowHeight = table.getRowHeight(k); - if (yTemp - rowHeight < minY) - break; - yTemp -= rowHeight; - } - if (k < table.size()) { - if (table.isSplitRows() && (!table.isSplitLate() || (k == listIdx && firstPass))) { - if (!splittedRow) { - splittedRow = true; - table = new PdfPTable(table); - compositeElements.set(0, table); - ArrayList rows = table.getRows(); - for (int i = table.getHeaderRows(); i < listIdx; ++i) - rows.set(i, null); - } - float h = yTemp - minY; - PdfPRow newRow = table.getRow(k).splitRow(h); - if (newRow == null) { - if (k == listIdx) - return NO_MORE_COLUMN; - } - else { - yTemp = minY; - table.getRows().add(++k, newRow); - } - } - else if (!table.isSplitRows() && k == listIdx && firstPass) { - compositeElements.removeFirst(); - splittedRow = false; - continue; - } - else if (k == listIdx && !firstPass && (!table.isSplitRows() || table.isSplitLate())) { - return NO_MORE_COLUMN; - } - } - firstPass = false; - if (!simulate) { - switch (table.getHorizontalAlignment()) { - case Element.ALIGN_LEFT: - break; - case Element.ALIGN_RIGHT: - x1 += rectangularWidth - tableWidth; - break; - default: - x1 += (rectangularWidth - tableWidth) / 2f; - } - int realHeaderRows = table.getHeaderRows(); - int footerRows = table.getFooterRows(); - if (footerRows > realHeaderRows) - footerRows = realHeaderRows; - realHeaderRows -= footerRows; - PdfPTable nt = PdfPTable.shallowCopy(table); - ArrayList rows = table.getRows(); - ArrayList sub = nt.getRows(); - if (!skipHeader) { - for (int j = 0; j < realHeaderRows; ++j) - sub.add(rows.get(j)); - } - else - nt.setHeaderRows(footerRows); - for (int j = listIdx; j < k; ++j) - sub.add(rows.get(j)); - for (int j = 0; j < footerRows; ++j) - sub.add(rows.get(j + realHeaderRows)); - float rowHeight = 0; - if (table.isExtendLastRow()) { - PdfPRow last = (PdfPRow)sub.get(sub.size() - 1 - footerRows); - rowHeight = last.getMaxHeights(); - last.setMaxHeights(yTemp - minY + rowHeight); - yTemp = minY; - } - if (canvases != null) - nt.writeSelectedRows(0, -1, x1, yLineWrite, canvases); - else - nt.writeSelectedRows(0, -1, x1, yLineWrite, canvas); - if (table.isExtendLastRow()) { - PdfPRow last = (PdfPRow)sub.get(sub.size() - 1 - footerRows); - last.setMaxHeights(rowHeight); - } - } - else if (table.isExtendLastRow() && minY > PdfPRow.BOTTOM_LIMIT) - yTemp = minY; - yLine = yTemp; - if (k >= table.size()) { - yLine -= table.spacingAfter(); - compositeElements.removeFirst(); - splittedRow = false; - listIdx = 0; - } - else { - if (splittedRow) { - ArrayList rows = table.getRows(); - for (int i = listIdx; i < k; ++i) - rows.set(i, null); - } - listIdx = k; - return NO_MORE_COLUMN; - } - } - else if (element.type() == Element.GRAPHIC) { - if (!simulate) { - Graphic gr = (Graphic)element; - ByteBuffer bf = gr.getInternalBuffer(); - ByteBuffer store = null; - if (bf.size() > 0) { - store = new ByteBuffer(); - store.append(bf); - bf.reset(); - } - gr.processAttributes(leftX, minY, rightX, maxY, yLine); - canvas.add(gr); - bf.reset(); - if (store != null) { - bf.append(store); - } - } - compositeElements.removeFirst(); - } - else - compositeElements.removeFirst(); - } - } - - /** - * Gets the canvas. - * @return a PdfContentByte. - */ - public PdfContentByte getCanvas() { - return canvas; - } - - /** - * Sets the canvas. - * @param canvas - */ - public void setCanvas(PdfContentByte canvas) { - this.canvas = canvas; - this.canvases = null; - if (compositeColumn != null) - compositeColumn.setCanvas(canvas); - } - - /** - * Sets the canvases. - * @param canvases - */ - public void setCanvases(PdfContentByte[] canvases) { - this.canvases = canvases; - this.canvas = canvases[PdfPTable.TEXTCANVAS]; - if (compositeColumn != null) - compositeColumn.setCanvases(canvases); - } - - /** - * Gets the canvases. - * @return an array of PdfContentByte - */ - public PdfContentByte[] getCanvases() { - return canvases; - } - - /** - * Checks if the element has a height of 0. - * @return true or false - */ - public boolean zeroHeightElement() { - return composite == true && compositeElements.size() > 0 && ((Element)compositeElements.getFirst()).type() == Element.GRAPHIC; - } - - /** - * Checks if UseAscender is enabled/disabled. - * @return true is the adjustment of the first line height is based on max ascender. - */ - public boolean isUseAscender() { - return useAscender; - } - - /** - * Enables/Disables adjustment of first line height based on max ascender. - * @param use enable adjustment if true - */ - public void setUseAscender(boolean use) { - useAscender = use; - } - - /** - * Checks the status variable and looks if there's still some text. - */ - public static boolean hasMoreText(int status) { - return (status & ColumnText.NO_MORE_TEXT) == 0; - } - - /** - * Holds value of property filledWidth. - */ - private float filledWidth; - - /** - * Gets the real width used by the largest line. - * @return the real width used by the largest line - */ - public float getFilledWidth() { - - return this.filledWidth; - } - - /** - * Sets the real width used by the largest line. Only used to set it - * to zero to start another measurement. - * @param filledWidth the real width used by the largest line - */ - public void setFilledWidth(float filledWidth) { - - this.filledWidth = filledWidth; - } - - /** - * Replaces the filledWidth if greater than the existing one. - * @param w the new filledWidth if greater than the existing one - */ - public void updateFilledWidth(float w) { - if (w > filledWidth) - filledWidth = w; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/DefaultFontMapper.java b/src/main/java/com/lowagie/text/pdf/DefaultFontMapper.java deleted file mode 100644 index bf3b645..0000000 --- a/src/main/java/com/lowagie/text/pdf/DefaultFontMapper.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.awt.Font; -import com.lowagie.text.ExceptionConverter; -import java.util.HashMap; -import java.io.File; -/** Default class to map awt fonts to BaseFont. - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class DefaultFontMapper implements FontMapper { - - /** A representation of BaseFont parameters. - */ - public static class BaseFontParameters { - /** The font name. - */ - public String fontName; - /** The encoding for that font. - */ - public String encoding; - /** The embedding for that font. - */ - public boolean embedded; - /** Whether the font is cached of not. - */ - public boolean cached; - /** The font bytes for ttf and afm. - */ - public byte ttfAfm[]; - /** The font bytes for pfb. - */ - public byte pfb[]; - - /** Constructs default BaseFont parameters. - * @param fontName the font name or location - */ - public BaseFontParameters(String fontName) { - this.fontName = fontName; - encoding = BaseFont.CP1252; - embedded = BaseFont.EMBEDDED; - cached = BaseFont.CACHED; - } - } - - /** Maps aliases to names. - */ - private HashMap aliases = new HashMap(); - /** Maps names to BaseFont parameters. - */ - private HashMap mapper = new HashMap(); - /** - * Returns a BaseFont which can be used to represent the given AWT Font - * - * @param font the font to be converted - * @return a BaseFont which has similar properties to the provided Font - */ - - public BaseFont awtToPdf(Font font) { - try { - BaseFontParameters p = getBaseFontParameters(font.getFontName()); - if (p != null) - return BaseFont.createFont(p.fontName, p.encoding, p.embedded, p.cached, p.ttfAfm, p.pfb); - String fontKey = null; - String logicalName = font.getName(); - - if (logicalName.equalsIgnoreCase("DialogInput") || logicalName.equalsIgnoreCase("Monospaced") || logicalName.equalsIgnoreCase("Courier")) { - - if (font.isItalic()) { - if (font.isBold()) { - fontKey = BaseFont.COURIER_BOLDOBLIQUE; - - } else { - fontKey = BaseFont.COURIER_OBLIQUE; - } - - } else { - if (font.isBold()) { - fontKey = BaseFont.COURIER_BOLD; - - } else { - fontKey = BaseFont.COURIER; - } - } - - } else if (logicalName.equalsIgnoreCase("Serif") || logicalName.equalsIgnoreCase("TimesRoman")) { - - if (font.isItalic()) { - if (font.isBold()) { - fontKey = BaseFont.TIMES_BOLDITALIC; - - } else { - fontKey = BaseFont.TIMES_ITALIC; - } - - } else { - if (font.isBold()) { - fontKey = BaseFont.TIMES_BOLD; - - } else { - fontKey = BaseFont.TIMES_ROMAN; - } - } - - } else { // default, this catches Dialog and SansSerif - - if (font.isItalic()) { - if (font.isBold()) { - fontKey = BaseFont.HELVETICA_BOLDOBLIQUE; - - } else { - fontKey = BaseFont.HELVETICA_OBLIQUE; - } - - } else { - if (font.isBold()) { - fontKey = BaseFont.HELVETICA_BOLD; - } else { - fontKey = BaseFont.HELVETICA; - } - } - } - return BaseFont.createFont(fontKey, BaseFont.CP1252, false); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Returns an AWT Font which can be used to represent the given BaseFont - * - * @param font the font to be converted - * @param size the desired point size of the resulting font - * @return a Font which has similar properties to the provided BaseFont - */ - - public Font pdfToAwt(BaseFont font, int size) { - String names[][] = font.getFullFontName(); - if (names.length == 1) - return new Font(names[0][3], 0, size); - String name10 = null; - String name3x = null; - for (int k = 0; k < names.length; ++k) { - String name[] = names[k]; - if (name[0].equals("1") && name[1].equals("0")) - name10 = name[3]; - else if (name[2].equals("1033")) { - name3x = name[3]; - break; - } - } - String finalName = name3x; - if (finalName == null) - finalName = name10; - if (finalName == null) - finalName = names[0][3]; - return new Font(finalName, 0, size); - } - - /** Maps a name to a BaseFont parameter. - * @param awtName the name - * @param parameters the BaseFont parameter - */ - public void putName(String awtName, BaseFontParameters parameters) { - mapper.put(awtName, parameters); - } - - /** Maps an alias to a name. - * @param alias the alias - * @param awtName the name - */ - public void putAlias(String alias, String awtName) { - aliases.put(alias, awtName); - } - - /** Looks for a BaseFont parameter associated with a name. - * @param name the name - * @return the BaseFont parameter or null if not found. - */ - public BaseFontParameters getBaseFontParameters(String name) { - String alias = (String)aliases.get(name); - if (alias == null) - return (BaseFontParameters)mapper.get(name); - BaseFontParameters p = (BaseFontParameters)mapper.get(alias); - if (p == null) - return (BaseFontParameters)mapper.get(name); - else - return p; - } - - /** - * Inserts the names in this map. - * @param allNames the returned value of calling {@link BaseFont#getAllFontNames(String, String, byte[])} - * @param path the full path to the font - */ - public void insertNames(Object allNames[], String path) { - String names[][] = (String[][])allNames[2]; - String main = null; - for (int k = 0; k < names.length; ++k) { - String name[] = names[k]; - if (name[2].equals("1033")) { - main = name[3]; - break; - } - } - if (main == null) - main = names[0][3]; - BaseFontParameters p = new BaseFontParameters(path); - mapper.put(main, p); - for (int k = 0; k < names.length; ++k) { - aliases.put(names[k][3], main); - } - aliases.put(allNames[0], main); - } - - /** Inserts all the fonts recognized by iText in the - * directory into the map. The encoding - * will be BaseFont.CP1252 but can be - * changed later. - * @param dir the directory to scan - * @return the number of files processed - */ - public int insertDirectory(String dir) { - File file = new File(dir); - if (!file.exists() || !file.isDirectory()) - return 0; - File files[] = file.listFiles(); - int count = 0; - for (int k = 0; k < files.length; ++k) { - file = files[k]; - String name = file.getPath().toLowerCase(); - try { - if (name.endsWith(".ttf") || name.endsWith(".otf") || name.endsWith(".afm")) { - Object allNames[] = BaseFont.getAllFontNames(file.getPath(), BaseFont.CP1252, null); - insertNames(allNames, file.getPath()); - ++count; - } - else if (name.endsWith(".ttc")) { - String ttcs[] = BaseFont.enumerateTTCNames(file.getPath()); - for (int j = 0; j < ttcs.length; ++j) { - String nt = file.getPath() + "," + j; - Object allNames[] = BaseFont.getAllFontNames(nt, BaseFont.CP1252, null); - insertNames(allNames, nt); - } - ++count; - } - } - catch (Exception e) { - } - } - return count; - } - - public HashMap getMapper() { - return mapper; - } - - public HashMap getAliases() { - return aliases; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/DocumentFont.java b/src/main/java/com/lowagie/text/pdf/DocumentFont.java deleted file mode 100644 index b3c4942..0000000 --- a/src/main/java/com/lowagie/text/pdf/DocumentFont.java +++ /dev/null @@ -1,599 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.util.ArrayList; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.ExceptionConverter; -import java.util.HashMap; - -/** - * - * @author psoares - */ -public class DocumentFont extends BaseFont { - // code, [glyph, width] - private HashMap metrics = new HashMap(); - private String fontName; - private PRIndirectReference refFont; - private PdfDictionary font; - private IntHashtable uni2byte = new IntHashtable(); - private float Ascender = 800; - private float CapHeight = 700; - private float Descender = -200; - private float ItalicAngle = 0; - private float llx = -50; - private float lly = -200; - private float urx = 100; - private float ury = 900; - private boolean isType0 = false; - - private BaseFont cjkMirror; - - private static String cjkNames[] = {"HeiseiMin-W3", "HeiseiKakuGo-W5", "STSong-Light", "MHei-Medium", - "MSung-Light", "HYGoThic-Medium", "HYSMyeongJo-Medium", "MSungStd-Light", "STSongStd-Light", - "HYSMyeongJoStd-Medium", "KozMinPro-Regular"}; - - private static String cjkEncs[] = {"UniJIS-UCS2-H", "UniJIS-UCS2-H", "UniGB-UCS2-H", "UniCNS-UCS2-H", - "UniCNS-UCS2-H", "UniKS-UCS2-H", "UniKS-UCS2-H", "UniCNS-UCS2-H", "UniGB-UCS2-H", - "UniKS-UCS2-H", "UniJIS-UCS2-H"}; - - private static String cjkNames2[] = {"MSungStd-Light", "STSongStd-Light", "HYSMyeongJoStd-Medium", "KozMinPro-Regular"}; - - private static String cjkEncs2[] = {"UniCNS-UCS2-H", "UniGB-UCS2-H", "UniKS-UCS2-H", "UniJIS-UCS2-H", - "UniCNS-UTF16-H", "UniGB-UTF16-H", "UniKS-UTF16-H", "UniJIS-UTF16-H"}; - - private static final int stdEnc[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 32,33,34,35,36,37,38,8217,40,41,42,43,44,45,46,47, - 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, - 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79, - 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95, - 8216,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111, - 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,161,162,163,8260,165,402,167,164,39,8220,171,8249,8250,64257,64258, - 0,8211,8224,8225,183,0,182,8226,8218,8222,8221,187,8230,8240,0,191, - 0,96,180,710,732,175,728,729,168,0,730,184,0,733,731,711, - 8212,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,198,0,170,0,0,0,0,321,216,338,186,0,0,0,0, - 0,230,0,0,0,305,0,0,322,248,339,223,0,0,0,0}; - - /** Creates a new instance of DocumentFont */ - DocumentFont(PRIndirectReference refFont) { - encoding = ""; - fontSpecific = false; - this.refFont = refFont; - fontType = FONT_TYPE_DOCUMENT; - font = (PdfDictionary)PdfReader.getPdfObject(refFont); - fontName = PdfName.decodeName(((PdfName)PdfReader.getPdfObject(font.get(PdfName.BASEFONT))).toString()); - PdfName subType = (PdfName)PdfReader.getPdfObject(font.get(PdfName.SUBTYPE)); - if (PdfName.TYPE1.equals(subType) || PdfName.TRUETYPE.equals(subType)) - doType1TT(); - else { - for (int k = 0; k < cjkNames.length; ++k) { - if (fontName.startsWith(cjkNames[k])) { - fontName = cjkNames[k]; - try { - cjkMirror = BaseFont.createFont(fontName, cjkEncs[k], false); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - return; - } - } - String enc = PdfName.decodeName(((PdfName)PdfReader.getPdfObject(font.get(PdfName.ENCODING))).toString()); - for (int k = 0; k < cjkEncs2.length; ++k) { - if (enc.startsWith(cjkEncs2[k])) { - try { - if (k > 3) - k -= 4; - cjkMirror = BaseFont.createFont(cjkNames2[k], cjkEncs2[k], false); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - return; - } - } - if (PdfName.TYPE0.equals(subType) && enc.equals("Identity-H")) { - processType0(font); - isType0 = true; - } - } - } - - private void processType0(PdfDictionary font) { - try { - byte[] touni = PdfReader.getStreamBytes((PRStream)PdfReader.getPdfObjectRelease(font.get(PdfName.TOUNICODE))); - PdfArray df = (PdfArray)PdfReader.getPdfObjectRelease(font.get(PdfName.DESCENDANTFONTS)); - PdfDictionary cidft = (PdfDictionary)PdfReader.getPdfObjectRelease((PdfObject)df.getArrayList().get(0)); - PdfNumber dwo = (PdfNumber)PdfReader.getPdfObjectRelease(cidft.get(PdfName.DW)); - int dw = 1000; - if (dwo != null) - dw = dwo.intValue(); - IntHashtable widths = readWidths((PdfArray)PdfReader.getPdfObjectRelease(cidft.get(PdfName.W))); - PdfDictionary fontDesc = (PdfDictionary)PdfReader.getPdfObjectRelease(cidft.get(PdfName.FONTDESCRIPTOR)); - fillFontDesc(fontDesc); - fillMetrics(touni, widths, dw); - } catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - private IntHashtable readWidths(PdfArray ws) { - IntHashtable hh = new IntHashtable(); - if (ws == null) - return hh; - ArrayList ar = ws.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - int c1 = ((PdfNumber)PdfReader.getPdfObjectRelease((PdfObject)ar.get(k))).intValue(); - PdfObject obj = PdfReader.getPdfObjectRelease((PdfObject)ar.get(++k)); - if (obj.isArray()) { - ArrayList ar2 = ((PdfArray)obj).getArrayList(); - for (int j = 0; j < ar2.size(); ++j) { - int c2 = ((PdfNumber)PdfReader.getPdfObjectRelease((PdfObject)ar2.get(j))).intValue(); - hh.put(c1++, c2); - } - } - else { - int c2 = ((PdfNumber)obj).intValue(); - int w = ((PdfNumber)PdfReader.getPdfObjectRelease((PdfObject)ar.get(++k))).intValue(); - for (; c1 <= c2; ++c1) - hh.put(c1, w); - } - } - return hh; - } - - private String decodeString(PdfString ps) { - if (ps.isHexWriting()) - return PdfEncodings.convertToString(ps.getBytes(), "UnicodeBigUnmarked"); - else - return ps.toUnicodeString(); - } - - private void fillMetrics(byte[] touni, IntHashtable widths, int dw) { - try { - PdfContentParser ps = new PdfContentParser(new PRTokeniser(touni)); - PdfObject ob = null; - PdfObject last = null; - while ((ob = ps.readPRObject()) != null) { - if (ob.type() == PdfContentParser.COMMAND_TYPE) { - if (ob.toString().equals("beginbfchar")) { - int n = ((PdfNumber)last).intValue(); - for (int k = 0; k < n; ++k) { - String cid = decodeString((PdfString)ps.readPRObject()); - String uni = decodeString((PdfString)ps.readPRObject()); - if (uni.length() == 1) { - int cidc = (int)cid.charAt(0); - int unic = (int)uni.charAt(uni.length() - 1); - int w = dw; - if (widths.containsKey(cidc)) - w = widths.get(cidc); - metrics.put(new Integer(unic), new int[]{cidc, w}); - } - } - } - else if (ob.toString().equals("beginbfrange")) { - int n = ((PdfNumber)last).intValue(); - for (int k = 0; k < n; ++k) { - String cid1 = decodeString((PdfString)ps.readPRObject()); - String cid2 = decodeString((PdfString)ps.readPRObject()); - int cid1c = (int)cid1.charAt(0); - int cid2c = (int)cid2.charAt(0); - PdfObject ob2 = ps.readPRObject(); - if (ob2.isString()) { - String uni = decodeString((PdfString)ob2); - if (uni.length() == 1) { - int unic = (int)uni.charAt(uni.length() - 1); - for (; cid1c <= cid2c; cid1c++, unic++) { - int w = dw; - if (widths.containsKey(cid1c)) - w = widths.get(cid1c); - metrics.put(new Integer(unic), new int[]{cid1c, w}); - } - } - } - else { - ArrayList ar = ((PdfArray)ob2).getArrayList(); - for (int j = 0; j < ar.size(); ++j, ++cid1c) { - String uni = decodeString((PdfString)ar.get(j)); - if (uni.length() == 1) { - int unic = (int)uni.charAt(uni.length() - 1); - int w = dw; - if (widths.containsKey(cid1c)) - w = widths.get(cid1c); - metrics.put(new Integer(unic), new int[]{cid1c, w}); - } - } - } - } - } - } - else - last = ob; - } - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - private void doType1TT() { - PdfObject enc = PdfReader.getPdfObject(font.get(PdfName.ENCODING)); - if (enc == null) - fillEncoding(null); - else { - if (enc.isName()) - fillEncoding((PdfName)enc); - else { - PdfDictionary encDic = (PdfDictionary)enc; - enc = PdfReader.getPdfObject(encDic.get(PdfName.BASEENCODING)); - if (enc == null) - fillEncoding(null); - else - fillEncoding((PdfName)enc); - PdfArray diffs = (PdfArray)PdfReader.getPdfObject(encDic.get(PdfName.DIFFERENCES)); - if (diffs != null) { - ArrayList dif = diffs.getArrayList(); - int currentNumber = 0; - for (int k = 0; k < dif.size(); ++k) { - PdfObject obj = (PdfObject)dif.get(k); - if (obj.isNumber()) - currentNumber = ((PdfNumber)obj).intValue(); - else { - int c[] = GlyphList.nameToUnicode(PdfName.decodeName(((PdfName)obj).toString())); - if (c != null && c.length > 0) - uni2byte.put(c[0], currentNumber); - ++currentNumber; - } - } - } - } - } - PdfArray newWidths = (PdfArray)PdfReader.getPdfObject(font.get(PdfName.WIDTHS)); - PdfNumber first = (PdfNumber)PdfReader.getPdfObject(font.get(PdfName.FIRSTCHAR)); - PdfNumber last = (PdfNumber)PdfReader.getPdfObject(font.get(PdfName.LASTCHAR)); - if (BuiltinFonts14.containsKey(fontName)) { - BaseFont bf; - try { - bf = BaseFont.createFont(fontName, WINANSI, false); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - int e[] = uni2byte.toOrderedKeys(); - for (int k = 0; k < e.length; ++k) { - int n = uni2byte.get(e[k]); - widths[n] = bf.getRawWidth(n, GlyphList.unicodeToName(e[k])); - } - Ascender = bf.getFontDescriptor(ASCENT, 1000); - CapHeight = bf.getFontDescriptor(CAPHEIGHT, 1000); - Descender = bf.getFontDescriptor(DESCENT, 1000); - ItalicAngle = bf.getFontDescriptor(ITALICANGLE, 1000); - llx = bf.getFontDescriptor(BBOXLLX, 1000); - lly = bf.getFontDescriptor(BBOXLLY, 1000); - urx = bf.getFontDescriptor(BBOXURX, 1000); - ury = bf.getFontDescriptor(BBOXURY, 1000); - } - if (first != null && last != null && newWidths != null) { - int f = first.intValue(); - ArrayList ar = newWidths.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - widths[f + k] = ((PdfNumber)ar.get(k)).intValue(); - } - } - fillFontDesc((PdfDictionary)PdfReader.getPdfObject(font.get(PdfName.FONTDESCRIPTOR))); - } - - private void fillFontDesc(PdfDictionary fontDesc) { - if (fontDesc == null) - return; - PdfNumber v = (PdfNumber)PdfReader.getPdfObject(fontDesc.get(PdfName.ASCENT)); - if (v != null) - Ascender = v.floatValue(); - v = (PdfNumber)PdfReader.getPdfObject(fontDesc.get(PdfName.CAPHEIGHT)); - if (v != null) - CapHeight = v.floatValue(); - v = (PdfNumber)PdfReader.getPdfObject(fontDesc.get(PdfName.DESCENT)); - if (v != null) - Descender = v.floatValue(); - v = (PdfNumber)PdfReader.getPdfObject(fontDesc.get(PdfName.ITALICANGLE)); - if (v != null) - ItalicAngle = v.floatValue(); - PdfArray bbox = (PdfArray)PdfReader.getPdfObject(fontDesc.get(PdfName.FONTBBOX)); - if (bbox != null) { - ArrayList ar = bbox.getArrayList(); - llx = ((PdfNumber)ar.get(0)).floatValue(); - lly = ((PdfNumber)ar.get(1)).floatValue(); - urx = ((PdfNumber)ar.get(2)).floatValue(); - ury = ((PdfNumber)ar.get(3)).floatValue(); - if (llx > urx) { - float t = llx; - llx = urx; - urx = t; - } - if (lly > ury) { - float t = lly; - lly = ury; - ury = t; - } - } - } - - private void fillEncoding(PdfName encoding) { - if (PdfName.MAC_ROMAN_ENCODING.equals(encoding) || PdfName.WIN_ANSI_ENCODING.equals(encoding)) { - byte b[] = new byte[256]; - for (int k = 0; k < 256; ++k) - b[k] = (byte)k; - String enc = WINANSI; - if (PdfName.MAC_ROMAN_ENCODING.equals(encoding)) - enc = MACROMAN; - String cv = PdfEncodings.convertToString(b, enc); - char arr[] = cv.toCharArray(); - for (int k = 0; k < 256; ++k) - uni2byte.put(arr[k], k); - } - else { - for (int k = 0; k < 256; ++k) - uni2byte.put(stdEnc[k], k); - } - } - - /** Gets the family name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the family name of the font - * - */ - public String[][] getFamilyFontName() { - return null; - } - - /** Gets the font parameter identified by key. Valid values - * for key are ASCENT, CAPHEIGHT, DESCENT, - * ITALICANGLE, BBOXLLX, BBOXLLY, BBOXURX - * and BBOXURY. - * @param key the parameter to be extracted - * @param fontSize the font size in points - * @return the parameter in points - * - */ - public float getFontDescriptor(int key, float fontSize) { - if (cjkMirror != null) - return cjkMirror.getFontDescriptor(key, fontSize); - switch (key) { - case AWT_ASCENT: - case ASCENT: - return Ascender * fontSize / 1000; - case CAPHEIGHT: - return CapHeight * fontSize / 1000; - case AWT_DESCENT: - case DESCENT: - return Descender * fontSize / 1000; - case ITALICANGLE: - return ItalicAngle; - case BBOXLLX: - return llx * fontSize / 1000; - case BBOXLLY: - return lly * fontSize / 1000; - case BBOXURX: - return urx * fontSize / 1000; - case BBOXURY: - return ury * fontSize / 1000; - case AWT_LEADING: - return 0; - case AWT_MAXADVANCE: - return (urx - llx) * fontSize / 1000; - } - return 0; - } - - /** Gets the full name of the font. If it is a True Type font - * each array element will have {Platform ID, Platform Encoding ID, - * Language ID, font name}. The interpretation of this values can be - * found in the Open Type specification, chapter 2, in the 'name' table.
- * For the other fonts the array has a single element with {"", "", "", - * font name}. - * @return the full name of the font - * - */ - public String[][] getFullFontName() { - return null; - } - - /** Gets the kerning between two Unicode chars. - * @param char1 the first char - * @param char2 the second char - * @return the kerning to be applied - * - */ - public int getKerning(char char1, char char2) { - return 0; - } - - /** Gets the postscript font name. - * @return the postscript font name - * - */ - public String getPostscriptFontName() { - return fontName; - } - - /** Gets the width from the font according to the Unicode char c - * or the name. If the name is null it's a symbolic font. - * @param c the unicode char - * @param name the glyph name - * @return the width of the char - * - */ - int getRawWidth(int c, String name) { - return 0; - } - - /** Checks if the font has any kerning pairs. - * @return true if the font has any kerning pairs - * - */ - public boolean hasKernPairs() { - return false; - } - - /** Outputs to the writer the font dictionaries and streams. - * @param writer the writer for this document - * @param ref the font indirect reference - * @param params several parameters that depend on the font type - * @throws IOException on error - * @throws DocumentException error in generating the object - * - */ - void writeFont(PdfWriter writer, PdfIndirectReference ref, Object[] params) throws DocumentException, IOException { - } - - public int getWidth(String text) { - if (cjkMirror != null) - return cjkMirror.getWidth(text); - else if (isType0) { - char[] chars = text.toCharArray(); - int len = chars.length; - int total = 0; - for (int k = 0; k < len; ++k) { - int[] ws = (int[])metrics.get(new Integer((int)chars[k])); - if (ws != null) - total += ws[1]; - } - return total; - } - else - return super.getWidth(text); - } - - byte[] convertToBytes(String text) { - if (cjkMirror != null) - return PdfEncodings.convertToBytes(text, CJKFont.CJK_ENCODING); - else if (isType0) { - char[] chars = text.toCharArray(); - int len = chars.length; - byte[] b = new byte[len * 2]; - int bptr = 0; - for (int k = 0; k < len; ++k) { - int[] ws = (int[])metrics.get(new Integer((int)chars[k])); - if (ws != null) { - int g = ws[0]; - b[bptr++] = (byte)(g / 256); - b[bptr++] = (byte)(g); - } - } - if (bptr == b.length) - return b; - else { - byte[] nb = new byte[bptr]; - System.arraycopy(b, 0, nb, 0, bptr); - return nb; - } - } - else { - char cc[] = text.toCharArray(); - byte b[] = new byte[cc.length]; - int ptr = 0; - for (int k = 0; k < cc.length; ++k) { - if (uni2byte.containsKey(cc[k])) - b[ptr++] = (byte)uni2byte.get(cc[k]); - } - if (ptr == b.length) - return b; - else { - byte[] b2 = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - } - } - - PdfIndirectReference getIndirectReference() { - return refFont; - } - - public boolean charExists(char c) { - if (cjkMirror != null) - return cjkMirror.charExists(c); - else if (isType0) { - return metrics.containsKey(new Integer((int)c)); - } - else - return super.charExists(c); - } - - /** - * Sets the font name that will appear in the pdf font dictionary. - * It does nothing in this case as the font is already in the document. - * @param name the new font name - */ - public void setPostscriptFontName(String name) { - } - - public boolean setKerning(char char1, char char2, int kern) { - return false; - } - - public int[] getCharBBox(char c) { - return null; - } - - protected int[] getRawCharBBox(int c, String name) { - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/EnumerateTTC.java b/src/main/java/com/lowagie/text/pdf/EnumerateTTC.java deleted file mode 100644 index d4110a3..0000000 --- a/src/main/java/com/lowagie/text/pdf/EnumerateTTC.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * $Id: EnumerateTTC.java,v 1.45 2005/05/04 14:31:46 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.*; -import java.util.HashMap; -import com.lowagie.text.DocumentException; -/** Enumerates all the fonts inside a True Type Collection. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -class EnumerateTTC extends TrueTypeFont{ - - protected String[] names; - - EnumerateTTC(String ttcFile) throws DocumentException, IOException { - fileName = ttcFile; - rf = new RandomAccessFileOrArray(ttcFile); - findNames(); - } - - EnumerateTTC(byte ttcArray[]) throws DocumentException, IOException { - fileName = "Byte array TTC"; - rf = new RandomAccessFileOrArray(ttcArray); - findNames(); - } - - void findNames() throws DocumentException, IOException { - tables = new HashMap(); - - try { - String mainTag = readStandardString(4); - if (!mainTag.equals("ttcf")) - throw new DocumentException(fileName + " is not a valid TTC file."); - rf.skipBytes(4); - int dirCount = rf.readInt(); - names = new String[dirCount]; - int dirPos = rf.getFilePointer(); - for (int dirIdx = 0; dirIdx < dirCount; ++dirIdx) { - tables.clear(); - rf.seek(dirPos); - rf.skipBytes(dirIdx * 4); - directoryOffset = rf.readInt(); - rf.seek(directoryOffset); - if (rf.readInt() != 0x00010000) - throw new DocumentException(fileName + " is not a valid TTF file."); - int num_tables = rf.readUnsignedShort(); - rf.skipBytes(6); - for (int k = 0; k < num_tables; ++k) { - String tag = readStandardString(4); - rf.skipBytes(4); - int table_location[] = new int[2]; - table_location[0] = rf.readInt(); - table_location[1] = rf.readInt(); - tables.put(tag, table_location); - } - names[dirIdx] = getBaseFont(); - } - } - finally { - if (rf != null) - rf.close(); - } - } - - String[] getNames() { - return names; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/ExtendedColor.java b/src/main/java/com/lowagie/text/pdf/ExtendedColor.java deleted file mode 100644 index c0dfc66..0000000 --- a/src/main/java/com/lowagie/text/pdf/ExtendedColor.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * $Id: ExtendedColor.java,v 1.43 2005/03/29 14:08:15 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; -/** - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class ExtendedColor extends Color{ - - /** a type of extended color. */ - public static final int TYPE_RGB = 0; - /** a type of extended color. */ - public static final int TYPE_GRAY = 1; - /** a type of extended color. */ - public static final int TYPE_CMYK = 2; - /** a type of extended color. */ - public static final int TYPE_SEPARATION = 3; - /** a type of extended color. */ - public static final int TYPE_PATTERN = 4; - /** a type of extended color. */ - public static final int TYPE_SHADING = 5; - - protected int type; - - /** - * Constructs an extended color of a certain type. - * @param type - */ - public ExtendedColor(int type) { - super(0, 0, 0); - this.type = type; - } - - /** - * Constructs an extended color of a certain type and a certain color. - * @param type - * @param red - * @param green - * @param blue - */ - public ExtendedColor(int type, float red, float green, float blue) { - super(normalize(red), normalize(green), normalize(blue)); - this.type = type; - } - - /** - * Gets the type of this color. - * @return one of the types (see constants) - */ - public int getType() { - return type; - } - - /** - * Gets the type of a given color. - * @param color - * @return one of the types (see constants) - */ - public static int getType(Color color) { - if (color instanceof ExtendedColor) - return ((ExtendedColor)color).getType(); - return TYPE_RGB; - } - - static final float normalize(float value) { - if (value < 0) - return 0; - if (value > 1) - return 1; - return value; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/ExtraEncoding.java b/src/main/java/com/lowagie/text/pdf/ExtraEncoding.java deleted file mode 100644 index 5862022..0000000 --- a/src/main/java/com/lowagie/text/pdf/ExtraEncoding.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * Classes implementing this interface can create custom encodings or - * replace existing ones. It is used in the context of PdfEncoding. - * @author Paulo Soares (psoares@consiste.pt) - */ -public interface ExtraEncoding { - - /** - * Converts an Unicode string to a byte array according to some encoding. - * @param text the Unicode string - * @param encoding the requested encoding. It's mainly of use if the same class - * supports more than one encoding. - * @return the conversion or null if no conversion is supported - */ - public byte[] charToByte(String text, String encoding); - - /** - * Converts a byte array to an Unicode string according to some encoding. - * @param b the input byte array - * @param encoding the requested encoding. It's mainly of use if the same class - * supports more than one encoding. - * @return the conversion or null if no conversion is supported - */ - public String byteToChar(byte b[], String encoding); -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/FdfReader.java b/src/main/java/com/lowagie/text/pdf/FdfReader.java deleted file mode 100644 index 7a846fe..0000000 --- a/src/main/java/com/lowagie/text/pdf/FdfReader.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.ArrayList; -import java.net.URL; -/** Reads an FDF form and makes the fields available - * @author Paulo Soares (psoares@consiste.pt) - */ -public class FdfReader extends PdfReader { - - HashMap fields; - String fileSpec; - PdfName encoding; - - /** Reads an FDF form. - * @param filename the file name of the form - * @throws IOException on error - */ - public FdfReader(String filename) throws IOException { - super(filename); - } - - /** Reads an FDF form. - * @param pdfIn the byte array with the form - * @throws IOException on error - */ - public FdfReader(byte pdfIn[]) throws IOException { - super(pdfIn); - } - - /** Reads an FDF form. - * @param url the URL of the document - * @throws IOException on error - */ - public FdfReader(URL url) throws IOException { - super(url); - } - - /** Reads an FDF form. - * @param is the InputStream containing the document. The stream is read to the - * end but is not closed - * @throws IOException on error - */ - public FdfReader(InputStream is) throws IOException { - super(is); - } - - protected void readPdf() throws IOException { - fields = new HashMap(); - try { - tokens.checkFdfHeader(); - rebuildXref(); - readDocObj(); - } - finally { - try { - tokens.close(); - } - catch (Exception e) { - // empty on purpose - } - } - readFields(); - } - - protected void kidNode(PdfDictionary merged, String name) { - PdfArray kids = (PdfArray)getPdfObject(merged.get(PdfName.KIDS)); - if (kids == null || kids.getArrayList().size() == 0) { - if (name.length() > 0) - name = name.substring(1); - fields.put(name, merged); - } - else { - merged.remove(PdfName.KIDS); - ArrayList ar = kids.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - PdfDictionary dic = new PdfDictionary(); - dic.merge(merged); - PdfDictionary newDic = (PdfDictionary)getPdfObject((PdfObject)ar.get(k)); - PdfString t = (PdfString)getPdfObject(newDic.get(PdfName.T)); - String newName = name; - if (t != null) - newName += "." + t.toUnicodeString(); - dic.merge(newDic); - dic.remove(PdfName.T); - kidNode(dic, newName); - } - } - } - - protected void readFields() throws IOException { - catalog = (PdfDictionary)getPdfObject(trailer.get(PdfName.ROOT)); - PdfDictionary fdf = (PdfDictionary)getPdfObject(catalog.get(PdfName.FDF)); - PdfString fs = (PdfString)getPdfObject(fdf.get(PdfName.F)); - if (fs != null) - fileSpec = fs.toUnicodeString(); - PdfArray fld = (PdfArray)getPdfObject(fdf.get(PdfName.FIELDS)); - if (fld == null) - return; - encoding = (PdfName)getPdfObject(fdf.get(PdfName.ENCODING)); - PdfDictionary merged = new PdfDictionary(); - merged.put(PdfName.KIDS, fld); - kidNode(merged, ""); - } - - /** Gets all the fields. The map is keyed by the fully qualified - * field name and the value is a merged PdfDictionary - * with the field content. - * @return all the fields - */ - public HashMap getFields() { - return fields; - } - - /** Gets the field dictionary. - * @param name the fully qualified field name - * @return the field dictionary - */ - public PdfDictionary getField(String name) { - return (PdfDictionary)fields.get(name); - } - - /** Gets the field value or null if the field does not - * exist or has no value defined. - * @param name the fully qualified field name - * @return the field value or null - */ - public String getFieldValue(String name) { - PdfDictionary field = (PdfDictionary)fields.get(name); - if (field == null) - return null; - PdfObject v = getPdfObject(field.get(PdfName.V)); - if (v == null) - return null; - if (v.isName()) - return PdfName.decodeName(((PdfName)v).toString()); - else if (v.isString()) { - PdfString vs = (PdfString)v; - if (encoding == null || vs.getEncoding() != null) - return vs.toUnicodeString(); - byte b[] = vs.getBytes(); - if (b.length >= 2 && b[0] == (byte)254 && b[1] == (byte)255) - return vs.toUnicodeString(); - try { - if (encoding.equals(PdfName.SHIFT_JIS)) - return new String(b, "SJIS"); - else if (encoding.equals(PdfName.UHC)) - return new String(b, "MS949"); - else if (encoding.equals(PdfName.GBK)) - return new String(b, "GBK"); - else if (encoding.equals(PdfName.BIGFIVE)) - return new String(b, "Big5"); - } - catch (Exception e) { - } - return vs.toUnicodeString(); - } - return null; - } - - /** Gets the PDF file specification contained in the FDF. - * @return the PDF file specification contained in the FDF - */ - public String getFileSpec() { - return fileSpec; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/FdfWriter.java b/src/main/java/com/lowagie/text/pdf/FdfWriter.java deleted file mode 100644 index 1174e8f..0000000 --- a/src/main/java/com/lowagie/text/pdf/FdfWriter.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Iterator; -import java.util.StringTokenizer; - -import com.lowagie.text.DocWriter; -import com.lowagie.text.DocumentException; - -/** Writes an FDF form. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class FdfWriter { - static byte[] HEADER_FDF = DocWriter.getISOBytes("%FDF-1.2\n%\u00e2\u00e3\u00cf\u00d3\n"); - HashMap fields = new HashMap(); - - /** The PDF file associated with the FDF. */ - private String file; - - /** Creates a new FdfWriter. */ - public FdfWriter() { - } - - /** Writes the content to a stream. - * @param os the stream - * @throws DocumentException on error - * @throws IOException on error - */ - public void writeTo(OutputStream os) throws DocumentException, IOException { - Wrt wrt = new Wrt(os, this); - wrt.writeTo(); - } - - boolean setField(String field, PdfObject value) { - HashMap map = fields; - StringTokenizer tk = new StringTokenizer(field, "."); - if (!tk.hasMoreTokens()) - return false; - while (true) { - String s = tk.nextToken(); - Object obj = map.get(s); - if (tk.hasMoreTokens()) { - if (obj == null) { - obj = new HashMap(); - map.put(s, obj); - map = (HashMap)obj; - continue; - } - else if (obj instanceof HashMap) - map = (HashMap)obj; - else - return false; - } - else { - if (obj == null || !(obj instanceof HashMap)) { - map.put(s, value); - return true; - } - else - return false; - } - } - } - - void iterateFields(HashMap values, HashMap map, String name) { - for (Iterator it = map.keySet().iterator(); it.hasNext();) { - String s = (String)it.next(); - Object obj = map.get(s); - if (obj instanceof HashMap) - iterateFields(values, (HashMap)obj, name + "." + s); - else - values.put((name + "." + s).substring(1), obj); - } - } - - /** Removes the field value. - * @param field the field name - * @return true if the field was found and removed, - * false otherwise - */ - public boolean removeField(String field) { - HashMap map = fields; - StringTokenizer tk = new StringTokenizer(field, "."); - if (!tk.hasMoreTokens()) - return false; - ArrayList hist = new ArrayList(); - while (true) { - String s = tk.nextToken(); - Object obj = map.get(s); - if (obj == null) - return false; - hist.add(map); - hist.add(s); - if (tk.hasMoreTokens()) { - if (obj instanceof HashMap) - map = (HashMap)obj; - else - return false; - } - else { - if (obj instanceof HashMap) - return false; - else - break; - } - } - for (int k = hist.size() - 2; k >= 0; k -= 2) { - map = (HashMap)hist.get(k); - String s = (String)hist.get(k + 1); - map.remove(s); - if (map.size() > 0) - break; - } - return true; - } - - /** Gets all the fields. The map is keyed by the fully qualified - * field name and the values are PdfObject. - * @return a map with all the fields - */ - public HashMap getFields() { - HashMap values = new HashMap(); - iterateFields(values, fields, ""); - return values; - } - - /** Gets the field value. - * @param field the field name - * @return the field value or null if not found - */ - public String getField(String field) { - HashMap map = fields; - StringTokenizer tk = new StringTokenizer(field, "."); - if (!tk.hasMoreTokens()) - return null; - while (true) { - String s = tk.nextToken(); - Object obj = map.get(s); - if (obj == null) - return null; - if (tk.hasMoreTokens()) { - if (obj instanceof HashMap) - map = (HashMap)obj; - else - return null; - } - else { - if (obj instanceof HashMap) - return null; - else { - if (((PdfObject)obj).isString()) - return ((PdfString)obj).toUnicodeString(); - else - return PdfName.decodeName(obj.toString()); - } - } - } - } - - /** Sets the field value as a name. - * @param field the fully qualified field name - * @param value the value - * @return true if the value was inserted, - * false if the name is incompatible with - * an existing field - */ - public boolean setFieldAsName(String field, String value) { - return setField(field, new PdfName(value)); - } - - /** Sets the field value as a string. - * @param field the fully qualified field name - * @param value the value - * @return true if the value was inserted, - * false if the name is incompatible with - * an existing field - */ - public boolean setFieldAsString(String field, String value) { - return setField(field, new PdfString(value, PdfObject.TEXT_UNICODE)); - } - - /** Sets all the fields from this FdfReader - * @param fdf the FdfReader - */ - public void setFields(FdfReader fdf) { - HashMap map = fdf.getFields(); - for (Iterator it = map.keySet().iterator(); it.hasNext();) { - String key = (String)it.next(); - PdfDictionary dic = (PdfDictionary)map.get(key); - PdfObject v = dic.get(PdfName.V); - if (v != null) { - setField(key, v); - } - } - } - - /** Sets all the fields from this PdfReader - * @param pdf the PdfReader - */ - public void setFields(PdfReader pdf) { - setFields(pdf.getAcroFields()); - } - - /** Sets all the fields from this AcroFields - * @param af the AcroFields - */ - public void setFields(AcroFields af) { - for (Iterator it = af.getFields().entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - String fn = (String)entry.getKey(); - AcroFields.Item item = (AcroFields.Item)entry.getValue(); - PdfDictionary dic = (PdfDictionary)item.merged.get(0); - PdfObject v = PdfReader.getPdfObjectRelease(dic.get(PdfName.V)); - if (v == null) - continue; - PdfObject ft = PdfReader.getPdfObjectRelease(dic.get(PdfName.FT)); - if (ft == null || PdfName.SIG.equals(ft)) - continue; - setField(fn, v); - } - } - - /** Gets the PDF file name associated with the FDF. - * @return the PDF file name associated with the FDF - */ - public String getFile() { - return this.file; - } - - /** Sets the PDF file name associated with the FDF. - * @param file the PDF file name associated with the FDF - * - */ - public void setFile(String file) { - this.file = file; - } - - static class Wrt extends PdfWriter { - private FdfWriter fdf; - - Wrt(OutputStream os, FdfWriter fdf) throws DocumentException, IOException { - super(new PdfDocument(), os); - this.fdf = fdf; - this.os.write(HEADER_FDF); - body = new PdfBody(this); - } - - void writeTo() throws DocumentException, IOException { - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.FIELDS, calculate(fdf.fields)); - if (fdf.file != null) - dic.put(PdfName.F, new PdfString(fdf.file, PdfObject.TEXT_UNICODE)); - PdfDictionary fd = new PdfDictionary(); - fd.put(PdfName.FDF, dic); - PdfIndirectReference ref = addToBody(fd).getIndirectReference(); - os.write(getISOBytes("trailer\n")); - PdfDictionary trailer = new PdfDictionary(); - trailer.put(PdfName.ROOT, ref); - trailer.toPdf(null, os); - os.write(getISOBytes("\n%%EOF\n")); - os.close(); - } - - - PdfArray calculate(HashMap map) throws IOException { - PdfArray ar = new PdfArray(); - for (Iterator it = map.keySet().iterator(); it.hasNext();) { - String key = (String)it.next(); - Object v = map.get(key); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.T, new PdfString(key, PdfObject.TEXT_UNICODE)); - if (v instanceof HashMap) { - dic.put(PdfName.KIDS, calculate((HashMap)v)); - } - else { - dic.put(PdfName.V, (PdfObject)v); - } - ar.add(dic); - } - return ar; - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/FontDetails.java b/src/main/java/com/lowagie/text/pdf/FontDetails.java deleted file mode 100644 index 6aa72e4..0000000 --- a/src/main/java/com/lowagie/text/pdf/FontDetails.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * $Id: FontDetails.java,v 1.46 2006/02/23 16:45:49 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import java.util.HashMap; -import java.io.UnsupportedEncodingException; -/** Each font in the document will have an instance of this class - * where the characters used will be represented. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -class FontDetails { - - /** The indirect reference to this font - */ - PdfIndirectReference indirectReference; - /** The font name that appears in the document body stream - */ - PdfName fontName; - /** The font - */ - BaseFont baseFont; - /** The font if its an instance of TrueTypeFontUnicode - */ - TrueTypeFontUnicode ttu; - - CJKFont cjkFont; - /** The array used with single byte encodings - */ - byte shortTag[]; - /** The map used with double byte encodings. The key is Integer(glyph) and the - * value is int[]{glyph, width, Unicode code} - */ - HashMap longTag; - - IntHashtable cjkTag; - /** The font type - */ - int fontType; - /** true if the font is symbolic - */ - boolean symbolic; - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. - */ - protected boolean subset = true; - /** Each font used in a document has an instance of this class. - * This class stores the characters used in the document and other - * specifics unique to the current working document. - * @param fontName the font name - * @param indirectReference the indirect reference to the font - * @param baseFont the BaseFont - */ - FontDetails(PdfName fontName, PdfIndirectReference indirectReference, BaseFont baseFont) { - this.fontName = fontName; - this.indirectReference = indirectReference; - this.baseFont = baseFont; - fontType = baseFont.getFontType(); - switch (fontType) { - case BaseFont.FONT_TYPE_T1: - case BaseFont.FONT_TYPE_TT: - shortTag = new byte[256]; - break; - case BaseFont.FONT_TYPE_CJK: - cjkTag = new IntHashtable(); - cjkFont = (CJKFont)baseFont; - break; - case BaseFont.FONT_TYPE_TTUNI: - longTag = new HashMap(); - ttu = (TrueTypeFontUnicode)baseFont; - symbolic = baseFont.isFontSpecific(); - break; - } - } - - /** Gets the indirect reference to this font. - * @return the indirect reference to this font - */ - PdfIndirectReference getIndirectReference() { - return indirectReference; - } - - /** Gets the font name as it appears in the document body. - * @return the font name - */ - PdfName getFontName() { - return fontName; - } - - /** Gets the BaseFont of this font. - * @return the BaseFont of this font - */ - BaseFont getBaseFont() { - return baseFont; - } - - /** Converts the text into bytes to be placed in the document. - * The conversion is done according to the font and the encoding and the characters - * used are stored. - * @param text the text to convert - * @return the conversion - */ - byte[] convertToBytes(String text) { - byte b[] = null; - switch (fontType) { - case BaseFont.FONT_TYPE_T3: - return baseFont.convertToBytes(text); - case BaseFont.FONT_TYPE_T1: - case BaseFont.FONT_TYPE_TT: { - b = baseFont.convertToBytes(text); - int len = b.length; - for (int k = 0; k < len; ++k) - shortTag[((int)b[k]) & 0xff] = 1; - break; - } - case BaseFont.FONT_TYPE_CJK: { - int len = text.length(); - for (int k = 0; k < len; ++k) - cjkTag.put(cjkFont.getCidCode(text.charAt(k)), 0); - b = baseFont.convertToBytes(text); - break; - } - case BaseFont.FONT_TYPE_DOCUMENT: { - b = baseFont.convertToBytes(text); - break; - } - case BaseFont.FONT_TYPE_TTUNI: { - try { - int len = text.length(); - int metrics[] = null; - char glyph[] = new char[len]; - int i = 0; - if (symbolic) { - b = PdfEncodings.convertToBytes(text, "symboltt"); - len = b.length; - for (int k = 0; k < len; ++k) { - metrics = ttu.getMetricsTT(b[k] & 0xff); - if (metrics == null) - continue; - longTag.put(new Integer(metrics[0]), new int[]{metrics[0], metrics[1], ttu.getUnicodeDifferences(b[k] & 0xff)}); - glyph[i++] = (char)metrics[0]; - } - } - else { - for (int k = 0; k < len; ++k) { - char c = text.charAt(k); - metrics = ttu.getMetricsTT(c); - if (metrics == null) - continue; - int m0 = metrics[0]; - Integer gl = new Integer(m0); - if (!longTag.containsKey(gl)) - longTag.put(gl, new int[]{m0, metrics[1], c}); - glyph[i++] = (char)m0; - } - } - String s = new String(glyph, 0, i); - b = s.getBytes(CJKFont.CJK_ENCODING); - } - catch (UnsupportedEncodingException e) { - throw new ExceptionConverter(e); - } - break; - } - } - return b; - } - - /** Writes the font definition to the document. - * @param writer the PdfWriter of this document - */ - void writeFont(PdfWriter writer) { - try { - switch (fontType) { - case BaseFont.FONT_TYPE_T3: - baseFont.writeFont(writer, indirectReference, null); - break; - case BaseFont.FONT_TYPE_T1: - case BaseFont.FONT_TYPE_TT: { - int firstChar; - int lastChar; - for (firstChar = 0; firstChar < 256; ++firstChar) { - if (shortTag[firstChar] != 0) - break; - } - for (lastChar = 255; lastChar >= firstChar; --lastChar) { - if (shortTag[lastChar] != 0) - break; - } - if (firstChar > 255) { - firstChar = 255; - lastChar = 255; - } - baseFont.writeFont(writer, indirectReference, new Object[]{new Integer(firstChar), new Integer(lastChar), shortTag, new Boolean(subset)}); - break; - } - case BaseFont.FONT_TYPE_CJK: - baseFont.writeFont(writer, indirectReference, new Object[]{cjkTag}); - break; - case BaseFont.FONT_TYPE_TTUNI: - baseFont.writeFont(writer, indirectReference, new Object[]{longTag, new Boolean(subset)}); - break; - } - } - catch(Exception e) { - throw new ExceptionConverter(e); - } - } - - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. - * @return false to include all the glyphs and widths. - */ - public boolean isSubset() { - return subset; - } - - /** Indicates if all the glyphs and widths for that particular - * encoding should be included in the document. Set to false - * to include all. - * @param subset new value of property subset - */ - public void setSubset(boolean subset) { - this.subset = subset; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/FontMapper.java b/src/main/java/com/lowagie/text/pdf/FontMapper.java deleted file mode 100644 index 331a3cb..0000000 --- a/src/main/java/com/lowagie/text/pdf/FontMapper.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002 by Jeremy Bowman . - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Font; - -/** - * A FontMapper implementation handles mappings between AWT Fonts and PDF - * fonts. An interface is used instead of a fixed class because there isn't - * an exact correlation between the font types, so each application is free - * to define a mapping which is appropriate for it. - */ - -public interface FontMapper { - - /** - * Returns a BaseFont which can be used to represent the given AWT Font - * - * @param font the font to be converted - * @return a BaseFont which has similar properties to the provided Font - */ - - public BaseFont awtToPdf(Font font); - - /** - * Returns an AWT Font which can be used to represent the given BaseFont - * - * @param font the font to be converted - * @param size the desired point size of the resulting font - * @return a Font which has similar properties to the provided BaseFont - */ - - public Font pdfToAwt(BaseFont font, int size); - -} diff --git a/src/main/java/com/lowagie/text/pdf/FontSelector.java b/src/main/java/com/lowagie/text/pdf/FontSelector.java deleted file mode 100644 index 628150f..0000000 --- a/src/main/java/com/lowagie/text/pdf/FontSelector.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import com.lowagie.text.*; - -/** Selects the appropriate fonts that contain the glyphs needed to - * render text correctly. The fonts are checked in order until the - * character is found. - *

- * The built in fonts "Symbol" and "ZapfDingbats", if used, have a special encoding - * to allow the characters to be referred by Unicode. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class FontSelector { - - protected ArrayList fonts = new ArrayList(); - - /** - * Adds a Font to be searched for valid characters. - * @param font the Font - */ - public void addFont(Font font) { - if (font.getBaseFont() != null) { - fonts.add(font); - return; - } - BaseFont bf = font.getCalculatedBaseFont(true); - Font f2 = new Font(bf, font.size(), font.getCalculatedStyle(), font.color()); - fonts.add(f2); - } - - /** - * Process the text so that it will render with a combination of fonts - * if needed. - * @param text the text - * @return a Phrase with one or more chunks - */ - public Phrase process(String text) { - int fsize = fonts.size(); - if (fsize == 0) - throw new IndexOutOfBoundsException("No font is defined."); - char cc[] = text.toCharArray(); - int len = cc.length; - StringBuffer sb = new StringBuffer(); - Font font = null; - int lastidx = -1; - Phrase ret = new Phrase(); - for (int k = 0; k < len; ++k) { - char c = cc[k]; - if (c == '\n' || c == '\r') { - sb.append(c); - continue; - } - for (int f = 0; f < fsize; ++f) { - font = (Font)fonts.get(f); - if (font.getBaseFont().charExists(c)) { - if (lastidx == f) - sb.append(c); - else { - if (sb.length() > 0 && lastidx != -1) { - Chunk ck = new Chunk(sb.toString(), (Font)fonts.get(lastidx)); - ret.add(ck); - sb.setLength(0); - } - sb.append(c); - lastidx = f; - } - break; - } - } - } - if (sb.length() > 0) { - Chunk ck = new Chunk(sb.toString(), (Font)fonts.get(lastidx)); - ret.add(ck); - } - return ret; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/GlyphList.java b/src/main/java/com/lowagie/text/pdf/GlyphList.java deleted file mode 100644 index 59a3dc1..0000000 --- a/src/main/java/com/lowagie/text/pdf/GlyphList.java +++ /dev/null @@ -1,2200 +0,0 @@ -/* - * $Id: GlyphList.java,v 1.52 2005/05/04 14:32:31 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.HashMap; - -public class GlyphList -{ - private static HashMap unicode2names = new HashMap(); - private static HashMap names2unicode = new HashMap(); - - private static final int unicode[] = - { - 0x0041, - 0x00C6, - 0x01FC, - 0xF7E6, - 0x00C1, - 0xF7E1, - 0x0102, - 0x00C2, - 0xF7E2, - 0xF6C9, - 0xF7B4, - 0x00C4, - 0xF7E4, - 0x00C0, - 0xF7E0, - 0x0391, - 0x0386, - 0x0100, - 0x0104, - 0x00C5, - 0x01FA, - 0xF7E5, - 0xF761, - 0x00C3, - 0xF7E3, - 0x0042, - 0x0392, - 0xF6F4, - 0xF762, - 0x0043, - 0x0106, - 0xF6CA, - 0xF6F5, - 0x010C, - 0x00C7, - 0xF7E7, - 0x0108, - 0x010A, - 0xF7B8, - 0x03A7, - 0xF6F6, - 0xF763, - 0x0044, - 0x010E, - 0x0110, - 0x2206, - 0x0394, - 0xF6CB, - 0xF6CC, - 0xF6CD, - 0xF7A8, - 0xF6F7, - 0xF764, - 0x0045, - 0x00C9, - 0xF7E9, - 0x0114, - 0x011A, - 0x00CA, - 0xF7EA, - 0x00CB, - 0xF7EB, - 0x0116, - 0x00C8, - 0xF7E8, - 0x0112, - 0x014A, - 0x0118, - 0x0395, - 0x0388, - 0xF765, - 0x0397, - 0x0389, - 0x00D0, - 0xF7F0, - 0x20AC, - 0x0046, - 0xF766, - 0x0047, - 0x0393, - 0x011E, - 0x01E6, - 0x011C, - 0x0122, - 0x0120, - 0xF6CE, - 0xF760, - 0xF767, - 0x0048, - 0x25CF, - 0x25AA, - 0x25AB, - 0x25A1, - 0x0126, - 0x0124, - 0xF768, - 0xF6CF, - 0xF6F8, - 0x0049, - 0x0132, - 0x00CD, - 0xF7ED, - 0x012C, - 0x00CE, - 0xF7EE, - 0x00CF, - 0xF7EF, - 0x0130, - 0x2111, - 0x00CC, - 0xF7EC, - 0x012A, - 0x012E, - 0x0399, - 0x03AA, - 0x038A, - 0xF769, - 0x0128, - 0x004A, - 0x0134, - 0xF76A, - 0x004B, - 0x039A, - 0x0136, - 0xF76B, - 0x004C, - 0xF6BF, - 0x0139, - 0x039B, - 0x013D, - 0x013B, - 0x013F, - 0x0141, - 0xF6F9, - 0xF76C, - 0x004D, - 0xF6D0, - 0xF7AF, - 0xF76D, - 0x039C, - 0x004E, - 0x0143, - 0x0147, - 0x0145, - 0xF76E, - 0x00D1, - 0xF7F1, - 0x039D, - 0x004F, - 0x0152, - 0xF6FA, - 0x00D3, - 0xF7F3, - 0x014E, - 0x00D4, - 0xF7F4, - 0x00D6, - 0xF7F6, - 0xF6FB, - 0x00D2, - 0xF7F2, - 0x01A0, - 0x0150, - 0x014C, - 0x2126, - 0x03A9, - 0x038F, - 0x039F, - 0x038C, - 0x00D8, - 0x01FE, - 0xF7F8, - 0xF76F, - 0x00D5, - 0xF7F5, - 0x0050, - 0x03A6, - 0x03A0, - 0x03A8, - 0xF770, - 0x0051, - 0xF771, - 0x0052, - 0x0154, - 0x0158, - 0x0156, - 0x211C, - 0x03A1, - 0xF6FC, - 0xF772, - 0x0053, - 0x250C, - 0x2514, - 0x2510, - 0x2518, - 0x253C, - 0x252C, - 0x2534, - 0x251C, - 0x2524, - 0x2500, - 0x2502, - 0x2561, - 0x2562, - 0x2556, - 0x2555, - 0x2563, - 0x2551, - 0x2557, - 0x255D, - 0x255C, - 0x255B, - 0x255E, - 0x255F, - 0x255A, - 0x2554, - 0x2569, - 0x2566, - 0x2560, - 0x2550, - 0x256C, - 0x2567, - 0x2568, - 0x2564, - 0x2565, - 0x2559, - 0x2558, - 0x2552, - 0x2553, - 0x256B, - 0x256A, - 0x015A, - 0x0160, - 0xF6FD, - 0x015E, - 0xF6C1, - 0x015C, - 0x0218, - 0x03A3, - 0xF773, - 0x0054, - 0x03A4, - 0x0166, - 0x0164, - 0x0162, - 0x021A, - 0x0398, - 0x00DE, - 0xF7FE, - 0xF6FE, - 0xF774, - 0x0055, - 0x00DA, - 0xF7FA, - 0x016C, - 0x00DB, - 0xF7FB, - 0x00DC, - 0xF7FC, - 0x00D9, - 0xF7F9, - 0x01AF, - 0x0170, - 0x016A, - 0x0172, - 0x03A5, - 0x03D2, - 0x03AB, - 0x038E, - 0x016E, - 0xF775, - 0x0168, - 0x0056, - 0xF776, - 0x0057, - 0x1E82, - 0x0174, - 0x1E84, - 0x1E80, - 0xF777, - 0x0058, - 0x039E, - 0xF778, - 0x0059, - 0x00DD, - 0xF7FD, - 0x0176, - 0x0178, - 0xF7FF, - 0x1EF2, - 0xF779, - 0x005A, - 0x0179, - 0x017D, - 0xF6FF, - 0x017B, - 0x0396, - 0xF77A, - 0x0061, - 0x00E1, - 0x0103, - 0x00E2, - 0x00B4, - 0x0301, - 0x00E4, - 0x00E6, - 0x01FD, - 0x2015, - 0x0410, - 0x0411, - 0x0412, - 0x0413, - 0x0414, - 0x0415, - 0x0401, - 0x0416, - 0x0417, - 0x0418, - 0x0419, - 0x041A, - 0x041B, - 0x041C, - 0x041D, - 0x041E, - 0x041F, - 0x0420, - 0x0421, - 0x0422, - 0x0423, - 0x0424, - 0x0425, - 0x0426, - 0x0427, - 0x0428, - 0x0429, - 0x042A, - 0x042B, - 0x042C, - 0x042D, - 0x042E, - 0x042F, - 0x0490, - 0x0402, - 0x0403, - 0x0404, - 0x0405, - 0x0406, - 0x0407, - 0x0408, - 0x0409, - 0x040A, - 0x040B, - 0x040C, - 0x040E, - 0xF6C4, - 0xF6C5, - 0x0430, - 0x0431, - 0x0432, - 0x0433, - 0x0434, - 0x0435, - 0x0451, - 0x0436, - 0x0437, - 0x0438, - 0x0439, - 0x043A, - 0x043B, - 0x043C, - 0x043D, - 0x043E, - 0x043F, - 0x0440, - 0x0441, - 0x0442, - 0x0443, - 0x0444, - 0x0445, - 0x0446, - 0x0447, - 0x0448, - 0x0449, - 0x044A, - 0x044B, - 0x044C, - 0x044D, - 0x044E, - 0x044F, - 0x0491, - 0x0452, - 0x0453, - 0x0454, - 0x0455, - 0x0456, - 0x0457, - 0x0458, - 0x0459, - 0x045A, - 0x045B, - 0x045C, - 0x045E, - 0x040F, - 0x0462, - 0x0472, - 0x0474, - 0xF6C6, - 0x045F, - 0x0463, - 0x0473, - 0x0475, - 0xF6C7, - 0xF6C8, - 0x04D9, - 0x200E, - 0x200F, - 0x200D, - 0x066A, - 0x060C, - 0x0660, - 0x0661, - 0x0662, - 0x0663, - 0x0664, - 0x0665, - 0x0666, - 0x0667, - 0x0668, - 0x0669, - 0x061B, - 0x061F, - 0x0621, - 0x0622, - 0x0623, - 0x0624, - 0x0625, - 0x0626, - 0x0627, - 0x0628, - 0x0629, - 0x062A, - 0x062B, - 0x062C, - 0x062D, - 0x062E, - 0x062F, - 0x0630, - 0x0631, - 0x0632, - 0x0633, - 0x0634, - 0x0635, - 0x0636, - 0x0637, - 0x0638, - 0x0639, - 0x063A, - 0x0640, - 0x0641, - 0x0642, - 0x0643, - 0x0644, - 0x0645, - 0x0646, - 0x0648, - 0x0649, - 0x064A, - 0x064B, - 0x064C, - 0x064D, - 0x064E, - 0x064F, - 0x0650, - 0x0651, - 0x0652, - 0x0647, - 0x06A4, - 0x067E, - 0x0686, - 0x0698, - 0x06AF, - 0x0679, - 0x0688, - 0x0691, - 0x06BA, - 0x06D2, - 0x06D5, - 0x20AA, - 0x05BE, - 0x05C3, - 0x05D0, - 0x05D1, - 0x05D2, - 0x05D3, - 0x05D4, - 0x05D5, - 0x05D6, - 0x05D7, - 0x05D8, - 0x05D9, - 0x05DA, - 0x05DB, - 0x05DC, - 0x05DD, - 0x05DE, - 0x05DF, - 0x05E0, - 0x05E1, - 0x05E2, - 0x05E3, - 0x05E4, - 0x05E5, - 0x05E6, - 0x05E7, - 0x05E8, - 0x05E9, - 0x05EA, - 0xFB2A, - 0xFB2B, - 0xFB4B, - 0xFB1F, - 0x05F0, - 0x05F1, - 0x05F2, - 0xFB35, - 0x05B4, - 0x05B5, - 0x05B6, - 0x05BB, - 0x05B8, - 0x05B7, - 0x05B0, - 0x05B2, - 0x05B1, - 0x05B3, - 0x05C2, - 0x05C1, - 0x05B9, - 0x05BC, - 0x05BD, - 0x05BF, - 0x05C0, - 0x02BC, - 0x2105, - 0x2113, - 0x2116, - 0x202C, - 0x202D, - 0x202E, - 0x200C, - 0x066D, - 0x02BD, - 0x00E0, - 0x2135, - 0x03B1, - 0x03AC, - 0x0101, - 0x0026, - 0xF726, - 0x2220, - 0x2329, - 0x232A, - 0x0387, - 0x0105, - 0x2248, - 0x00E5, - 0x01FB, - 0x2194, - 0x21D4, - 0x21D3, - 0x21D0, - 0x21D2, - 0x21D1, - 0x2193, - 0xF8E7, - 0x2190, - 0x2192, - 0x2191, - 0x2195, - 0x21A8, - 0xF8E6, - 0x005E, - 0x007E, - 0x002A, - 0x2217, - 0xF6E9, - 0x0040, - 0x00E3, - 0x0062, - 0x005C, - 0x007C, - 0x03B2, - 0x2588, - 0xF8F4, - 0x007B, - 0xF8F3, - 0xF8F2, - 0xF8F1, - 0x007D, - 0xF8FE, - 0xF8FD, - 0xF8FC, - 0x005B, - 0xF8F0, - 0xF8EF, - 0xF8EE, - 0x005D, - 0xF8FB, - 0xF8FA, - 0xF8F9, - 0x02D8, - 0x00A6, - 0xF6EA, - 0x2022, - 0x0063, - 0x0107, - 0x02C7, - 0x21B5, - 0x010D, - 0x00E7, - 0x0109, - 0x010B, - 0x00B8, - 0x00A2, - 0xF6DF, - 0xF7A2, - 0xF6E0, - 0x03C7, - 0x25CB, - 0x2297, - 0x2295, - 0x02C6, - 0x2663, - 0x003A, - 0x20A1, - 0x002C, - 0xF6C3, - 0xF6E1, - 0xF6E2, - 0x2245, - 0x00A9, - 0xF8E9, - 0xF6D9, - 0x00A4, - 0xF6D1, - 0xF6D2, - 0xF6D4, - 0xF6D5, - 0x0064, - 0x2020, - 0x2021, - 0xF6D3, - 0xF6D6, - 0x010F, - 0x0111, - 0x00B0, - 0x03B4, - 0x2666, - 0x00A8, - 0xF6D7, - 0xF6D8, - 0x0385, - 0x00F7, - 0x2593, - 0x2584, - 0x0024, - 0xF6E3, - 0xF724, - 0xF6E4, - 0x20AB, - 0x02D9, - 0x0323, - 0x0131, - 0xF6BE, - 0x22C5, - 0xF6EB, - 0x0065, - 0x00E9, - 0x0115, - 0x011B, - 0x00EA, - 0x00EB, - 0x0117, - 0x00E8, - 0x0038, - 0x2088, - 0xF738, - 0x2078, - 0x2208, - 0x2026, - 0x0113, - 0x2014, - 0x2205, - 0x2013, - 0x014B, - 0x0119, - 0x03B5, - 0x03AD, - 0x003D, - 0x2261, - 0x212E, - 0xF6EC, - 0x03B7, - 0x03AE, - 0x00F0, - 0x0021, - 0x203C, - 0x00A1, - 0xF7A1, - 0xF721, - 0x2203, - 0x0066, - 0x2640, - 0xFB00, - 0xFB03, - 0xFB04, - 0xFB01, - 0x2012, - 0x25A0, - 0x25AC, - 0x0035, - 0x215D, - 0x2085, - 0xF735, - 0x2075, - 0xFB02, - 0x0192, - 0x0034, - 0x2084, - 0xF734, - 0x2074, - 0x2044, - 0x2215, - 0x20A3, - 0x0067, - 0x03B3, - 0x011F, - 0x01E7, - 0x011D, - 0x0123, - 0x0121, - 0x00DF, - 0x2207, - 0x0060, - 0x0300, - 0x003E, - 0x2265, - 0x00AB, - 0x00BB, - 0x2039, - 0x203A, - 0x0068, - 0x0127, - 0x0125, - 0x2665, - 0x0309, - 0x2302, - 0x02DD, - 0x002D, - 0x00AD, - 0xF6E5, - 0xF6E6, - 0x0069, - 0x00ED, - 0x012D, - 0x00EE, - 0x00EF, - 0x00EC, - 0x0133, - 0x012B, - 0x221E, - 0x222B, - 0x2321, - 0xF8F5, - 0x2320, - 0x2229, - 0x25D8, - 0x25D9, - 0x263B, - 0x012F, - 0x03B9, - 0x03CA, - 0x0390, - 0x03AF, - 0xF6ED, - 0x0129, - 0x006A, - 0x0135, - 0x006B, - 0x03BA, - 0x0137, - 0x0138, - 0x006C, - 0x013A, - 0x03BB, - 0x013E, - 0x013C, - 0x0140, - 0x003C, - 0x2264, - 0x258C, - 0x20A4, - 0xF6C0, - 0x2227, - 0x00AC, - 0x2228, - 0x017F, - 0x25CA, - 0x0142, - 0xF6EE, - 0x2591, - 0x006D, - 0x00AF, - 0x02C9, - 0x2642, - 0x2212, - 0x2032, - 0xF6EF, - 0x00B5, - 0x03BC, - 0x00D7, - 0x266A, - 0x266B, - 0x006E, - 0x0144, - 0x0149, - 0x0148, - 0x0146, - 0x0039, - 0x2089, - 0xF739, - 0x2079, - 0x2209, - 0x2260, - 0x2284, - 0x207F, - 0x00F1, - 0x03BD, - 0x0023, - 0x006F, - 0x00F3, - 0x014F, - 0x00F4, - 0x00F6, - 0x0153, - 0x02DB, - 0x00F2, - 0x01A1, - 0x0151, - 0x014D, - 0x03C9, - 0x03D6, - 0x03CE, - 0x03BF, - 0x03CC, - 0x0031, - 0x2024, - 0x215B, - 0xF6DC, - 0x00BD, - 0x2081, - 0xF731, - 0x00BC, - 0x00B9, - 0x2153, - 0x25E6, - 0x00AA, - 0x00BA, - 0x221F, - 0x00F8, - 0x01FF, - 0xF6F0, - 0x00F5, - 0x0070, - 0x00B6, - 0x0028, - 0xF8ED, - 0xF8EC, - 0x208D, - 0x207D, - 0xF8EB, - 0x0029, - 0xF8F8, - 0xF8F7, - 0x208E, - 0x207E, - 0xF8F6, - 0x2202, - 0x0025, - 0x002E, - 0x00B7, - 0x2219, - 0xF6E7, - 0xF6E8, - 0x22A5, - 0x2030, - 0x20A7, - 0x03C6, - 0x03D5, - 0x03C0, - 0x002B, - 0x00B1, - 0x211E, - 0x220F, - 0x2282, - 0x2283, - 0x221D, - 0x03C8, - 0x0071, - 0x003F, - 0x00BF, - 0xF7BF, - 0xF73F, - 0x0022, - 0x201E, - 0x201C, - 0x201D, - 0x2018, - 0x201B, - 0x2019, - 0x201A, - 0x0027, - 0x0072, - 0x0155, - 0x221A, - 0xF8E5, - 0x0159, - 0x0157, - 0x2286, - 0x2287, - 0x00AE, - 0xF8E8, - 0xF6DA, - 0x2310, - 0x03C1, - 0x02DA, - 0xF6F1, - 0x2590, - 0xF6DD, - 0x0073, - 0x015B, - 0x0161, - 0x015F, - 0xF6C2, - 0x015D, - 0x0219, - 0x2033, - 0x00A7, - 0x003B, - 0x0037, - 0x215E, - 0x2087, - 0xF737, - 0x2077, - 0x2592, - 0x03C3, - 0x03C2, - 0x223C, - 0x0036, - 0x2086, - 0xF736, - 0x2076, - 0x002F, - 0x263A, - 0x0020, - 0x00A0, - 0x2660, - 0xF6F2, - 0x00A3, - 0x220B, - 0x2211, - 0x263C, - 0x0074, - 0x03C4, - 0x0167, - 0x0165, - 0x0163, - 0x021B, - 0x2234, - 0x03B8, - 0x03D1, - 0x00FE, - 0x0033, - 0x215C, - 0x2083, - 0xF733, - 0x00BE, - 0xF6DE, - 0x00B3, - 0x02DC, - 0x0303, - 0x0384, - 0x2122, - 0xF8EA, - 0xF6DB, - 0x25BC, - 0x25C4, - 0x25BA, - 0x25B2, - 0xF6F3, - 0x0032, - 0x2025, - 0x2082, - 0xF732, - 0x00B2, - 0x2154, - 0x0075, - 0x00FA, - 0x016D, - 0x00FB, - 0x00FC, - 0x00F9, - 0x01B0, - 0x0171, - 0x016B, - 0x005F, - 0x2017, - 0x222A, - 0x2200, - 0x0173, - 0x2580, - 0x03C5, - 0x03CB, - 0x03B0, - 0x03CD, - 0x016F, - 0x0169, - 0x0076, - 0x0077, - 0x1E83, - 0x0175, - 0x1E85, - 0x2118, - 0x1E81, - 0x0078, - 0x03BE, - 0x0079, - 0x00FD, - 0x0177, - 0x00FF, - 0x00A5, - 0x1EF3, - 0x007A, - 0x017A, - 0x017E, - 0x017C, - 0x0030, - 0x2080, - 0xF730, - 0x2070, - 0x03B6 - }; - - private static final String names[] = - { - "A", - "AE", - "AEacute", - "AEsmall", - "Aacute", - "Aacutesmall", - "Abreve", - "Acircumflex", - "Acircumflexsmall", - "Acute", - "Acutesmall", - "Adieresis", - "Adieresissmall", - "Agrave", - "Agravesmall", - "Alpha", - "Alphatonos", - "Amacron", - "Aogonek", - "Aring", - "Aringacute", - "Aringsmall", - "Asmall", - "Atilde", - "Atildesmall", - "B", - "Beta", - "Brevesmall", - "Bsmall", - "C", - "Cacute", - "Caron", - "Caronsmall", - "Ccaron", - "Ccedilla", - "Ccedillasmall", - "Ccircumflex", - "Cdotaccent", - "Cedillasmall", - "Chi", - "Circumflexsmall", - "Csmall", - "D", - "Dcaron", - "Dcroat", - "Delta", - "Delta", - "Dieresis", - "DieresisAcute", - "DieresisGrave", - "Dieresissmall", - "Dotaccentsmall", - "Dsmall", - "E", - "Eacute", - "Eacutesmall", - "Ebreve", - "Ecaron", - "Ecircumflex", - "Ecircumflexsmall", - "Edieresis", - "Edieresissmall", - "Edotaccent", - "Egrave", - "Egravesmall", - "Emacron", - "Eng", - "Eogonek", - "Epsilon", - "Epsilontonos", - "Esmall", - "Eta", - "Etatonos", - "Eth", - "Ethsmall", - "Euro", - "F", - "Fsmall", - "G", - "Gamma", - "Gbreve", - "Gcaron", - "Gcircumflex", - "Gcommaaccent", - "Gdotaccent", - "Grave", - "Gravesmall", - "Gsmall", - "H", - "H18533", - "H18543", - "H18551", - "H22073", - "Hbar", - "Hcircumflex", - "Hsmall", - "Hungarumlaut", - "Hungarumlautsmall", - "I", - "IJ", - "Iacute", - "Iacutesmall", - "Ibreve", - "Icircumflex", - "Icircumflexsmall", - "Idieresis", - "Idieresissmall", - "Idotaccent", - "Ifraktur", - "Igrave", - "Igravesmall", - "Imacron", - "Iogonek", - "Iota", - "Iotadieresis", - "Iotatonos", - "Ismall", - "Itilde", - "J", - "Jcircumflex", - "Jsmall", - "K", - "Kappa", - "Kcommaaccent", - "Ksmall", - "L", - "LL", - "Lacute", - "Lambda", - "Lcaron", - "Lcommaaccent", - "Ldot", - "Lslash", - "Lslashsmall", - "Lsmall", - "M", - "Macron", - "Macronsmall", - "Msmall", - "Mu", - "N", - "Nacute", - "Ncaron", - "Ncommaaccent", - "Nsmall", - "Ntilde", - "Ntildesmall", - "Nu", - "O", - "OE", - "OEsmall", - "Oacute", - "Oacutesmall", - "Obreve", - "Ocircumflex", - "Ocircumflexsmall", - "Odieresis", - "Odieresissmall", - "Ogoneksmall", - "Ograve", - "Ogravesmall", - "Ohorn", - "Ohungarumlaut", - "Omacron", - "Omega", - "Omega", - "Omegatonos", - "Omicron", - "Omicrontonos", - "Oslash", - "Oslashacute", - "Oslashsmall", - "Osmall", - "Otilde", - "Otildesmall", - "P", - "Phi", - "Pi", - "Psi", - "Psmall", - "Q", - "Qsmall", - "R", - "Racute", - "Rcaron", - "Rcommaaccent", - "Rfraktur", - "Rho", - "Ringsmall", - "Rsmall", - "S", - "SF010000", - "SF020000", - "SF030000", - "SF040000", - "SF050000", - "SF060000", - "SF070000", - "SF080000", - "SF090000", - "SF100000", - "SF110000", - "SF190000", - "SF200000", - "SF210000", - "SF220000", - "SF230000", - "SF240000", - "SF250000", - "SF260000", - "SF270000", - "SF280000", - "SF360000", - "SF370000", - "SF380000", - "SF390000", - "SF400000", - "SF410000", - "SF420000", - "SF430000", - "SF440000", - "SF450000", - "SF460000", - "SF470000", - "SF480000", - "SF490000", - "SF500000", - "SF510000", - "SF520000", - "SF530000", - "SF540000", - "Sacute", - "Scaron", - "Scaronsmall", - "Scedilla", - "Scedilla", - "Scircumflex", - "Scommaaccent", - "Sigma", - "Ssmall", - "T", - "Tau", - "Tbar", - "Tcaron", - "Tcommaaccent", - "Tcommaaccent", - "Theta", - "Thorn", - "Thornsmall", - "Tildesmall", - "Tsmall", - "U", - "Uacute", - "Uacutesmall", - "Ubreve", - "Ucircumflex", - "Ucircumflexsmall", - "Udieresis", - "Udieresissmall", - "Ugrave", - "Ugravesmall", - "Uhorn", - "Uhungarumlaut", - "Umacron", - "Uogonek", - "Upsilon", - "Upsilon1", - "Upsilondieresis", - "Upsilontonos", - "Uring", - "Usmall", - "Utilde", - "V", - "Vsmall", - "W", - "Wacute", - "Wcircumflex", - "Wdieresis", - "Wgrave", - "Wsmall", - "X", - "Xi", - "Xsmall", - "Y", - "Yacute", - "Yacutesmall", - "Ycircumflex", - "Ydieresis", - "Ydieresissmall", - "Ygrave", - "Ysmall", - "Z", - "Zacute", - "Zcaron", - "Zcaronsmall", - "Zdotaccent", - "Zeta", - "Zsmall", - "a", - "aacute", - "abreve", - "acircumflex", - "acute", - "acutecomb", - "adieresis", - "ae", - "aeacute", - "afii00208", - "afii10017", - "afii10018", - "afii10019", - "afii10020", - "afii10021", - "afii10022", - "afii10023", - "afii10024", - "afii10025", - "afii10026", - "afii10027", - "afii10028", - "afii10029", - "afii10030", - "afii10031", - "afii10032", - "afii10033", - "afii10034", - "afii10035", - "afii10036", - "afii10037", - "afii10038", - "afii10039", - "afii10040", - "afii10041", - "afii10042", - "afii10043", - "afii10044", - "afii10045", - "afii10046", - "afii10047", - "afii10048", - "afii10049", - "afii10050", - "afii10051", - "afii10052", - "afii10053", - "afii10054", - "afii10055", - "afii10056", - "afii10057", - "afii10058", - "afii10059", - "afii10060", - "afii10061", - "afii10062", - "afii10063", - "afii10064", - "afii10065", - "afii10066", - "afii10067", - "afii10068", - "afii10069", - "afii10070", - "afii10071", - "afii10072", - "afii10073", - "afii10074", - "afii10075", - "afii10076", - "afii10077", - "afii10078", - "afii10079", - "afii10080", - "afii10081", - "afii10082", - "afii10083", - "afii10084", - "afii10085", - "afii10086", - "afii10087", - "afii10088", - "afii10089", - "afii10090", - "afii10091", - "afii10092", - "afii10093", - "afii10094", - "afii10095", - "afii10096", - "afii10097", - "afii10098", - "afii10099", - "afii10100", - "afii10101", - "afii10102", - "afii10103", - "afii10104", - "afii10105", - "afii10106", - "afii10107", - "afii10108", - "afii10109", - "afii10110", - "afii10145", - "afii10146", - "afii10147", - "afii10148", - "afii10192", - "afii10193", - "afii10194", - "afii10195", - "afii10196", - "afii10831", - "afii10832", - "afii10846", - "afii299", - "afii300", - "afii301", - "afii57381", - "afii57388", - "afii57392", - "afii57393", - "afii57394", - "afii57395", - "afii57396", - "afii57397", - "afii57398", - "afii57399", - "afii57400", - "afii57401", - "afii57403", - "afii57407", - "afii57409", - "afii57410", - "afii57411", - "afii57412", - "afii57413", - "afii57414", - "afii57415", - "afii57416", - "afii57417", - "afii57418", - "afii57419", - "afii57420", - "afii57421", - "afii57422", - "afii57423", - "afii57424", - "afii57425", - "afii57426", - "afii57427", - "afii57428", - "afii57429", - "afii57430", - "afii57431", - "afii57432", - "afii57433", - "afii57434", - "afii57440", - "afii57441", - "afii57442", - "afii57443", - "afii57444", - "afii57445", - "afii57446", - "afii57448", - "afii57449", - "afii57450", - "afii57451", - "afii57452", - "afii57453", - "afii57454", - "afii57455", - "afii57456", - "afii57457", - "afii57458", - "afii57470", - "afii57505", - "afii57506", - "afii57507", - "afii57508", - "afii57509", - "afii57511", - "afii57512", - "afii57513", - "afii57514", - "afii57519", - "afii57534", - "afii57636", - "afii57645", - "afii57658", - "afii57664", - "afii57665", - "afii57666", - "afii57667", - "afii57668", - "afii57669", - "afii57670", - "afii57671", - "afii57672", - "afii57673", - "afii57674", - "afii57675", - "afii57676", - "afii57677", - "afii57678", - "afii57679", - "afii57680", - "afii57681", - "afii57682", - "afii57683", - "afii57684", - "afii57685", - "afii57686", - "afii57687", - "afii57688", - "afii57689", - "afii57690", - "afii57694", - "afii57695", - "afii57700", - "afii57705", - "afii57716", - "afii57717", - "afii57718", - "afii57723", - "afii57793", - "afii57794", - "afii57795", - "afii57796", - "afii57797", - "afii57798", - "afii57799", - "afii57800", - "afii57801", - "afii57802", - "afii57803", - "afii57804", - "afii57806", - "afii57807", - "afii57839", - "afii57841", - "afii57842", - "afii57929", - "afii61248", - "afii61289", - "afii61352", - "afii61573", - "afii61574", - "afii61575", - "afii61664", - "afii63167", - "afii64937", - "agrave", - "aleph", - "alpha", - "alphatonos", - "amacron", - "ampersand", - "ampersandsmall", - "angle", - "angleleft", - "angleright", - "anoteleia", - "aogonek", - "approxequal", - "aring", - "aringacute", - "arrowboth", - "arrowdblboth", - "arrowdbldown", - "arrowdblleft", - "arrowdblright", - "arrowdblup", - "arrowdown", - "arrowhorizex", - "arrowleft", - "arrowright", - "arrowup", - "arrowupdn", - "arrowupdnbse", - "arrowvertex", - "asciicircum", - "asciitilde", - "asterisk", - "asteriskmath", - "asuperior", - "at", - "atilde", - "b", - "backslash", - "bar", - "beta", - "block", - "braceex", - "braceleft", - "braceleftbt", - "braceleftmid", - "bracelefttp", - "braceright", - "bracerightbt", - "bracerightmid", - "bracerighttp", - "bracketleft", - "bracketleftbt", - "bracketleftex", - "bracketlefttp", - "bracketright", - "bracketrightbt", - "bracketrightex", - "bracketrighttp", - "breve", - "brokenbar", - "bsuperior", - "bullet", - "c", - "cacute", - "caron", - "carriagereturn", - "ccaron", - "ccedilla", - "ccircumflex", - "cdotaccent", - "cedilla", - "cent", - "centinferior", - "centoldstyle", - "centsuperior", - "chi", - "circle", - "circlemultiply", - "circleplus", - "circumflex", - "club", - "colon", - "colonmonetary", - "comma", - "commaaccent", - "commainferior", - "commasuperior", - "congruent", - "copyright", - "copyrightsans", - "copyrightserif", - "currency", - "cyrBreve", - "cyrFlex", - "cyrbreve", - "cyrflex", - "d", - "dagger", - "daggerdbl", - "dblGrave", - "dblgrave", - "dcaron", - "dcroat", - "degree", - "delta", - "diamond", - "dieresis", - "dieresisacute", - "dieresisgrave", - "dieresistonos", - "divide", - "dkshade", - "dnblock", - "dollar", - "dollarinferior", - "dollaroldstyle", - "dollarsuperior", - "dong", - "dotaccent", - "dotbelowcomb", - "dotlessi", - "dotlessj", - "dotmath", - "dsuperior", - "e", - "eacute", - "ebreve", - "ecaron", - "ecircumflex", - "edieresis", - "edotaccent", - "egrave", - "eight", - "eightinferior", - "eightoldstyle", - "eightsuperior", - "element", - "ellipsis", - "emacron", - "emdash", - "emptyset", - "endash", - "eng", - "eogonek", - "epsilon", - "epsilontonos", - "equal", - "equivalence", - "estimated", - "esuperior", - "eta", - "etatonos", - "eth", - "exclam", - "exclamdbl", - "exclamdown", - "exclamdownsmall", - "exclamsmall", - "existential", - "f", - "female", - "ff", - "ffi", - "ffl", - "fi", - "figuredash", - "filledbox", - "filledrect", - "five", - "fiveeighths", - "fiveinferior", - "fiveoldstyle", - "fivesuperior", - "fl", - "florin", - "four", - "fourinferior", - "fouroldstyle", - "foursuperior", - "fraction", - "fraction", - "franc", - "g", - "gamma", - "gbreve", - "gcaron", - "gcircumflex", - "gcommaaccent", - "gdotaccent", - "germandbls", - "gradient", - "grave", - "gravecomb", - "greater", - "greaterequal", - "guillemotleft", - "guillemotright", - "guilsinglleft", - "guilsinglright", - "h", - "hbar", - "hcircumflex", - "heart", - "hookabovecomb", - "house", - "hungarumlaut", - "hyphen", - "hyphen", - "hypheninferior", - "hyphensuperior", - "i", - "iacute", - "ibreve", - "icircumflex", - "idieresis", - "igrave", - "ij", - "imacron", - "infinity", - "integral", - "integralbt", - "integralex", - "integraltp", - "intersection", - "invbullet", - "invcircle", - "invsmileface", - "iogonek", - "iota", - "iotadieresis", - "iotadieresistonos", - "iotatonos", - "isuperior", - "itilde", - "j", - "jcircumflex", - "k", - "kappa", - "kcommaaccent", - "kgreenlandic", - "l", - "lacute", - "lambda", - "lcaron", - "lcommaaccent", - "ldot", - "less", - "lessequal", - "lfblock", - "lira", - "ll", - "logicaland", - "logicalnot", - "logicalor", - "longs", - "lozenge", - "lslash", - "lsuperior", - "ltshade", - "m", - "macron", - "macron", - "male", - "minus", - "minute", - "msuperior", - "mu", - "mu", - "multiply", - "musicalnote", - "musicalnotedbl", - "n", - "nacute", - "napostrophe", - "ncaron", - "ncommaaccent", - "nine", - "nineinferior", - "nineoldstyle", - "ninesuperior", - "notelement", - "notequal", - "notsubset", - "nsuperior", - "ntilde", - "nu", - "numbersign", - "o", - "oacute", - "obreve", - "ocircumflex", - "odieresis", - "oe", - "ogonek", - "ograve", - "ohorn", - "ohungarumlaut", - "omacron", - "omega", - "omega1", - "omegatonos", - "omicron", - "omicrontonos", - "one", - "onedotenleader", - "oneeighth", - "onefitted", - "onehalf", - "oneinferior", - "oneoldstyle", - "onequarter", - "onesuperior", - "onethird", - "openbullet", - "ordfeminine", - "ordmasculine", - "orthogonal", - "oslash", - "oslashacute", - "osuperior", - "otilde", - "p", - "paragraph", - "parenleft", - "parenleftbt", - "parenleftex", - "parenleftinferior", - "parenleftsuperior", - "parenlefttp", - "parenright", - "parenrightbt", - "parenrightex", - "parenrightinferior", - "parenrightsuperior", - "parenrighttp", - "partialdiff", - "percent", - "period", - "periodcentered", - "periodcentered", - "periodinferior", - "periodsuperior", - "perpendicular", - "perthousand", - "peseta", - "phi", - "phi1", - "pi", - "plus", - "plusminus", - "prescription", - "product", - "propersubset", - "propersuperset", - "proportional", - "psi", - "q", - "question", - "questiondown", - "questiondownsmall", - "questionsmall", - "quotedbl", - "quotedblbase", - "quotedblleft", - "quotedblright", - "quoteleft", - "quotereversed", - "quoteright", - "quotesinglbase", - "quotesingle", - "r", - "racute", - "radical", - "radicalex", - "rcaron", - "rcommaaccent", - "reflexsubset", - "reflexsuperset", - "registered", - "registersans", - "registerserif", - "revlogicalnot", - "rho", - "ring", - "rsuperior", - "rtblock", - "rupiah", - "s", - "sacute", - "scaron", - "scedilla", - "scedilla", - "scircumflex", - "scommaaccent", - "second", - "section", - "semicolon", - "seven", - "seveneighths", - "seveninferior", - "sevenoldstyle", - "sevensuperior", - "shade", - "sigma", - "sigma1", - "similar", - "six", - "sixinferior", - "sixoldstyle", - "sixsuperior", - "slash", - "smileface", - "space", - "space", - "spade", - "ssuperior", - "sterling", - "suchthat", - "summation", - "sun", - "t", - "tau", - "tbar", - "tcaron", - "tcommaaccent", - "tcommaaccent", - "therefore", - "theta", - "theta1", - "thorn", - "three", - "threeeighths", - "threeinferior", - "threeoldstyle", - "threequarters", - "threequartersemdash", - "threesuperior", - "tilde", - "tildecomb", - "tonos", - "trademark", - "trademarksans", - "trademarkserif", - "triagdn", - "triaglf", - "triagrt", - "triagup", - "tsuperior", - "two", - "twodotenleader", - "twoinferior", - "twooldstyle", - "twosuperior", - "twothirds", - "u", - "uacute", - "ubreve", - "ucircumflex", - "udieresis", - "ugrave", - "uhorn", - "uhungarumlaut", - "umacron", - "underscore", - "underscoredbl", - "union", - "universal", - "uogonek", - "upblock", - "upsilon", - "upsilondieresis", - "upsilondieresistonos", - "upsilontonos", - "uring", - "utilde", - "v", - "w", - "wacute", - "wcircumflex", - "wdieresis", - "weierstrass", - "wgrave", - "x", - "xi", - "y", - "yacute", - "ycircumflex", - "ydieresis", - "yen", - "ygrave", - "z", - "zacute", - "zcaron", - "zdotaccent", - "zero", - "zeroinferior", - "zerooldstyle", - "zerosuperior", - "zeta" - }; - - static - { - for (int k = 0; k < unicode.length; ++k) - { - Integer num = new Integer(unicode[k]); - unicode2names.put(num, names[k]); - int code[] = (int[])names2unicode.get(names[k]); - if (code == null) - { - names2unicode.put(names[k], new int[]{unicode[k]}); - } - else - { - int code2[] = new int[code.length + 1]; - System.arraycopy(code, 0, code2, 0, code.length); - code2[code.length] = unicode[k]; - names2unicode.put(names[k], code2); - } - } - } - - public static int[] nameToUnicode(String name) - { - return (int[])names2unicode.get(name); - } - - public static String unicodeToName(int num) - { - return (String)unicode2names.get(new Integer(num)); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/GrayColor.java b/src/main/java/com/lowagie/text/pdf/GrayColor.java deleted file mode 100644 index 4c14e79..0000000 --- a/src/main/java/com/lowagie/text/pdf/GrayColor.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * $Id: GrayColor.java,v 1.44 2006/02/22 10:53:08 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class GrayColor extends ExtendedColor { - - private float gray; - - public static final GrayColor GRAYBLACK = new GrayColor(0f); - public static final GrayColor GRAYWHITE = new GrayColor(1f); - - public GrayColor(int intGray) { - this((float)intGray / 255f); - } - - public GrayColor(float floatGray) { - super(TYPE_GRAY, floatGray, floatGray, floatGray); - gray = normalize(floatGray); - } - - public float getGray() { - return gray; - } - - public boolean equals(Object obj) { - return obj instanceof GrayColor && ((GrayColor)obj).gray == this.gray; - } - - public int hashCode() { - return Float.floatToIntBits(gray); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/HyphenationAuto.java b/src/main/java/com/lowagie/text/pdf/HyphenationAuto.java deleted file mode 100644 index 3e49d79..0000000 --- a/src/main/java/com/lowagie/text/pdf/HyphenationAuto.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.pdf.hyphenation.Hyphenator; -import com.lowagie.text.pdf.hyphenation.Hyphenation; - -/** Hyphenates words automatically accordingly to the language and country. - * The hyphenator engine was taken from FOP and uses the TEX patterns. If a language - * is not provided and a TEX pattern for it exists, it can be easily adapted. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class HyphenationAuto implements HyphenationEvent { - - /** The hyphenator engine. - */ - protected Hyphenator hyphenator; - /** The second part of the hyphenated word. - */ - protected String post; - - /** Creates a new hyphenation instance usable in Chunk. - * @param lang the language ("en" for english, for example) - * @param country the country ("GB" for Great-Britain or "none" for no country, for example) - * @param leftMin the minimun number of letters before the hyphen - * @param rightMin the minimun number of letters after the hyphen - */ - public HyphenationAuto(String lang, String country, int leftMin, int rightMin) { - hyphenator = new Hyphenator(lang, country, leftMin, rightMin); - } - - /** Gets the hyphen symbol. - * @return the hyphen symbol - */ - public String getHyphenSymbol() { - return "-"; - } - - /** Hyphenates a word and returns the first part of it. To get - * the second part of the hyphenated word call getHyphenatedWordPost(). - * @param word the word to hyphenate - * @param font the font used by this word - * @param fontSize the font size used by this word - * @param remainingWidth the width available to fit this word in - * @return the first part of the hyphenated word including - * the hyphen symbol, if any - */ - public String getHyphenatedWordPre(String word, BaseFont font, float fontSize, float remainingWidth) { - post = word; - String hyphen = getHyphenSymbol(); - float hyphenWidth = font.getWidthPoint(hyphen, fontSize); - if (hyphenWidth > remainingWidth) - return ""; - Hyphenation hyphenation = hyphenator.hyphenate(word); - if (hyphenation == null) { - return ""; - } - int len = hyphenation.length(); - int k; - for (k = 0; k < len; ++k) { - if (font.getWidthPoint(hyphenation.getPreHyphenText(k), fontSize) + hyphenWidth > remainingWidth) - break; - } - --k; - if (k < 0) - return ""; - post = hyphenation.getPostHyphenText(k); - return hyphenation.getPreHyphenText(k) + hyphen; - } - - /** Gets the second part of the hyphenated word. Must be called - * after getHyphenatedWordPre(). - * @return the second part of the hyphenated word - */ - public String getHyphenatedWordPost() { - return post; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/HyphenationEvent.java b/src/main/java/com/lowagie/text/pdf/HyphenationEvent.java deleted file mode 100644 index b465cea..0000000 --- a/src/main/java/com/lowagie/text/pdf/HyphenationEvent.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** Called by Chunk to hyphenate a word. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public interface HyphenationEvent { - - /** Gets the hyphen symbol. - * @return the hyphen symbol - */ - public String getHyphenSymbol(); - - /** Hyphenates a word and returns the first part of it. To get - * the second part of the hyphenated word call getHyphenatedWordPost(). - * @param word the word to hyphenate - * @param font the font used by this word - * @param fontSize the font size used by this word - * @param remainingWidth the width available to fit this word in - * @return the first part of the hyphenated word including - * the hyphen symbol, if any - */ - public String getHyphenatedWordPre(String word, BaseFont font, float fontSize, float remainingWidth); - - /** Gets the second part of the hyphenated word. Must be called - * after getHyphenatedWordPre(). - * @return the second part of the hyphenated word - */ - public String getHyphenatedWordPost(); -} - diff --git a/src/main/java/com/lowagie/text/pdf/IntHashtable.java b/src/main/java/com/lowagie/text/pdf/IntHashtable.java deleted file mode 100644 index 633439a..0000000 --- a/src/main/java/com/lowagie/text/pdf/IntHashtable.java +++ /dev/null @@ -1,338 +0,0 @@ -// IntHashtable - a Hashtable that uses ints as the keys -// -// This is 90% based on JavaSoft's java.util.Hashtable. -// -// Visit the ACME Labs Java page for up-to-date versions of this and other -// fine Java utilities: http://www.acme.com/java/ - -package com.lowagie.text.pdf; - -import java.util.Arrays; -import java.util.NoSuchElementException; -import java.util.Iterator; - -/// A Hashtable that uses ints as the keys. -//

-// Use just like java.util.Hashtable, except that the keys must be ints. -// This is much faster than creating a new Integer for each access. -//

-// Fetch the software.
-// Fetch the entire Acme package. -//

-// @see java.util.Hashtable - -public class IntHashtable implements Cloneable { - /// The hash table data. - private IntHashtableEntry table[]; - - /// The total number of entries in the hash table. - private int count; - - /// Rehashes the table when count exceeds this threshold. - private int threshold; - - /// The load factor for the hashtable. - private float loadFactor; - - /// Constructs a new, empty hashtable with the specified initial - // capacity and the specified load factor. - // @param initialCapacity the initial number of buckets - // @param loadFactor a number between 0.0 and 1.0, it defines - // the threshold for rehashing the hashtable into - // a bigger one. - // @exception IllegalArgumentException If the initial capacity - // is less than or equal to zero. - // @exception IllegalArgumentException If the load factor is - // less than or equal to zero. - public IntHashtable( int initialCapacity, float loadFactor ) { - if ( initialCapacity <= 0 || loadFactor <= 0.0 ) - throw new IllegalArgumentException(); - this.loadFactor = loadFactor; - table = new IntHashtableEntry[initialCapacity]; - threshold = (int) ( initialCapacity * loadFactor ); - } - - /// Constructs a new, empty hashtable with the specified initial - // capacity. - // @param initialCapacity the initial number of buckets - public IntHashtable( int initialCapacity ) { - this( initialCapacity, 0.75f ); - } - - /// Constructs a new, empty hashtable. A default capacity and load factor - // is used. Note that the hashtable will automatically grow when it gets - // full. - public IntHashtable() { - this( 101, 0.75f ); - } - - /// Returns the number of elements contained in the hashtable. - public int size() { - return count; - } - - /// Returns true if the hashtable contains no elements. - public boolean isEmpty() { - return count == 0; - } - - /// Returns true if the specified object is an element of the hashtable. - // This operation is more expensive than the containsKey() method. - // @param value the value that we are looking for - // @exception NullPointerException If the value being searched - // for is equal to null. - // @see IntHashtable#containsKey - public boolean contains( int value ) { - IntHashtableEntry tab[] = table; - for ( int i = tab.length ; i-- > 0 ; ) { - for ( IntHashtableEntry e = tab[i] ; e != null ; e = e.next ) { - if ( e.value == value ) - return true; - } - } - return false; - } - - /// Returns true if the collection contains an element for the key. - // @param key the key that we are looking for - // @see IntHashtable#contains - public boolean containsKey( int key ) { - IntHashtableEntry tab[] = table; - int hash = key; - int index = ( hash & 0x7FFFFFFF ) % tab.length; - for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) { - if ( e.hash == hash && e.key == key ) - return true; - } - return false; - } - - /// Gets the object associated with the specified key in the - // hashtable. - // @param key the specified key - // @returns the element for the key or null if the key - // is not defined in the hash table. - // @see IntHashtable#put - public int get( int key ) { - IntHashtableEntry tab[] = table; - int hash = key; - int index = ( hash & 0x7FFFFFFF ) % tab.length; - for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) { - if ( e.hash == hash && e.key == key ) - return e.value; - } - return 0; - } - - /// Rehashes the content of the table into a bigger table. - // This method is called automatically when the hashtable's - // size exceeds the threshold. - protected void rehash() { - int oldCapacity = table.length; - IntHashtableEntry oldTable[] = table; - - int newCapacity = oldCapacity * 2 + 1; - IntHashtableEntry newTable[] = new IntHashtableEntry[newCapacity]; - - threshold = (int) ( newCapacity * loadFactor ); - table = newTable; - - for ( int i = oldCapacity ; i-- > 0 ; ) { - for ( IntHashtableEntry old = oldTable[i] ; old != null ; ) { - IntHashtableEntry e = old; - old = old.next; - - int index = ( e.hash & 0x7FFFFFFF ) % newCapacity; - e.next = newTable[index]; - newTable[index] = e; - } - } - } - - /// Puts the specified element into the hashtable, using the specified - // key. The element may be retrieved by doing a get() with the same key. - // The key and the element cannot be null. - // @param key the specified key in the hashtable - // @param value the specified element - // @exception NullPointerException If the value of the element - // is equal to null. - // @see IntHashtable#get - // @return the old value of the key, or null if it did not have one. - public int put( int key, int value ) { - // Makes sure the key is not already in the hashtable. - IntHashtableEntry tab[] = table; - int hash = key; - int index = ( hash & 0x7FFFFFFF ) % tab.length; - for ( IntHashtableEntry e = tab[index] ; e != null ; e = e.next ) { - if ( e.hash == hash && e.key == key ) { - int old = e.value; - e.value = value; - return old; - } - } - - if ( count >= threshold ) { - // Rehash the table if the threshold is exceeded. - rehash(); - return put( key, value ); - } - - // Creates the new entry. - IntHashtableEntry e = new IntHashtableEntry(); - e.hash = hash; - e.key = key; - e.value = value; - e.next = tab[index]; - tab[index] = e; - ++count; - return 0; - } - - /// Removes the element corresponding to the key. Does nothing if the - // key is not present. - // @param key the key that needs to be removed - // @return the value of key, or null if the key was not found. - public int remove( int key ) { - IntHashtableEntry tab[] = table; - int hash = key; - int index = ( hash & 0x7FFFFFFF ) % tab.length; - for ( IntHashtableEntry e = tab[index], prev = null ; e != null ; prev = e, e = e.next ) { - if ( e.hash == hash && e.key == key ) { - if ( prev != null ) - prev.next = e.next; - else - tab[index] = e.next; - --count; - return e.value; - } - } - return 0; - } - - /// Clears the hash table so that it has no more elements in it. - public void clear() { - IntHashtableEntry tab[] = table; - for ( int index = tab.length; --index >= 0; ) - tab[index] = null; - count = 0; - } - - public Object clone() { - try { - IntHashtable t = (IntHashtable)super.clone(); - t.table = new IntHashtableEntry[table.length]; - for (int i = table.length ; i-- > 0 ; ) { - t.table[i] = (table[i] != null) - ? (IntHashtableEntry)table[i].clone() : null; - } - return t; - } catch (CloneNotSupportedException e) { - // this shouldn't happen, since we are Cloneable - throw new InternalError(); - } - } - - public int[] toOrderedKeys() { - int res[] = getKeys(); - Arrays.sort(res); - return res; - } - - public int[] getKeys() { - int res[] = new int[count]; - int ptr = 0; - int index = table.length; - IntHashtableEntry entry = null; - while (true) { - if (entry == null) - while ((index-- > 0) && ((entry = table[index]) == null)); - if (entry == null) - break; - IntHashtableEntry e = entry; - entry = e.next; - res[ptr++] = e.key; - } - return res; - } - - public int getOneKey() { - if (count == 0) - return 0; - int index = table.length; - IntHashtableEntry entry = null; - while ((index-- > 0) && ((entry = table[index]) == null)); - if (entry == null) - return 0; - return entry.key; - } - - static class IntHashtableEntry { - int hash; - int key; - int value; - IntHashtableEntry next; - - public int getKey() { - return key; - } - - public int getValue() { - return value; - } - - protected Object clone() { - IntHashtableEntry entry = new IntHashtableEntry(); - entry.hash = hash; - entry.key = key; - entry.value = value; - entry.next = (next != null) ? (IntHashtableEntry)next.clone() : null; - return entry; - } - } - - public Iterator getEntryIterator() { - return new IntHashtableIterator(table); - } - - static class IntHashtableIterator implements Iterator { - // boolean keys; - int index; - IntHashtableEntry table[]; - IntHashtableEntry entry; - - IntHashtableIterator(IntHashtableEntry table[] /* , boolean keys */) { - this.table = table; - // this.keys = keys; - this.index = table.length; - } - - public boolean hasNext() { - if (entry != null) { - return true; - } - while (index-- > 0) { - if ((entry = table[index]) != null) { - return true; - } - } - return false; - } - - public Object next() { - if (entry == null) { - while ((index-- > 0) && ((entry = table[index]) == null)); - } - if (entry != null) { - IntHashtableEntry e = entry; - entry = e.next; - return e; - } - throw new NoSuchElementException("IntHashtableIterator"); - } - - public void remove() { - throw new UnsupportedOperationException("remove() not supported."); - } - - } -} diff --git a/src/main/java/com/lowagie/text/pdf/LZWDecoder.java b/src/main/java/com/lowagie/text/pdf/LZWDecoder.java deleted file mode 100644 index b8bedcf..0000000 --- a/src/main/java/com/lowagie/text/pdf/LZWDecoder.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2001 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * -Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * -Redistribution in binary form must reproduct the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE - * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING - * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS - * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, - * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER - * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF - * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that Software is not designed,licensed or intended for use in - * the design, construction, operation or maintenance of any nuclear facility. - * - * Adapted from the JAI codecs TIFFLZWDecoder. - */ -package com.lowagie.text.pdf; -import java.io.OutputStream; -import java.io.IOException; -import com.lowagie.text.ExceptionConverter; -/** - * A class for performing LZW decoding. - * - * - */ -public class LZWDecoder { - - byte stringTable[][]; - byte data[] = null; - OutputStream uncompData; - int tableIndex, bitsToGet = 9; - int bytePointer, bitPointer; - int nextData = 0; - int nextBits = 0; - - int andTable[] = { - 511, - 1023, - 2047, - 4095 - }; - - public LZWDecoder() { - } - - /** - * Method to decode LZW compressed data. - * - * @param data The compressed data. - * @param uncompData Array to return the uncompressed data in. - */ - public void decode(byte data[], OutputStream uncompData) { - - if(data[0] == (byte)0x00 && data[1] == (byte)0x01) { - throw new RuntimeException("LZW flavour not supported."); - } - - initializeStringTable(); - - this.data = data; - this.uncompData = uncompData; - - // Initialize pointers - bytePointer = 0; - bitPointer = 0; - - nextData = 0; - nextBits = 0; - - int code, oldCode = 0; - byte string[]; - - while ((code = getNextCode()) != 257) { - - if (code == 256) { - - initializeStringTable(); - code = getNextCode(); - - if (code == 257) { - break; - } - - writeString(stringTable[code]); - oldCode = code; - - } else { - - if (code < tableIndex) { - - string = stringTable[code]; - - writeString(string); - addStringToTable(stringTable[oldCode], string[0]); - oldCode = code; - - } else { - - string = stringTable[oldCode]; - string = composeString(string, string[0]); - writeString(string); - addStringToTable(string); - oldCode = code; - } - } - } - } - - - /** - * Initialize the string table. - */ - public void initializeStringTable() { - - stringTable = new byte[8192][]; - - for (int i=0; i<256; i++) { - stringTable[i] = new byte[1]; - stringTable[i][0] = (byte)i; - } - - tableIndex = 258; - bitsToGet = 9; - } - - /** - * Write out the string just uncompressed. - */ - public void writeString(byte string[]) { - try { - uncompData.write(string); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** - * Add a new string to the string table. - */ - public void addStringToTable(byte oldString[], byte newString) { - int length = oldString.length; - byte string[] = new byte[length + 1]; - System.arraycopy(oldString, 0, string, 0, length); - string[length] = newString; - - // Add this new String to the table - stringTable[tableIndex++] = string; - - if (tableIndex == 511) { - bitsToGet = 10; - } else if (tableIndex == 1023) { - bitsToGet = 11; - } else if (tableIndex == 2047) { - bitsToGet = 12; - } - } - - /** - * Add a new string to the string table. - */ - public void addStringToTable(byte string[]) { - - // Add this new String to the table - stringTable[tableIndex++] = string; - - if (tableIndex == 511) { - bitsToGet = 10; - } else if (tableIndex == 1023) { - bitsToGet = 11; - } else if (tableIndex == 2047) { - bitsToGet = 12; - } - } - - /** - * Append newString to the end of oldString. - */ - public byte[] composeString(byte oldString[], byte newString) { - int length = oldString.length; - byte string[] = new byte[length + 1]; - System.arraycopy(oldString, 0, string, 0, length); - string[length] = newString; - - return string; - } - - // Returns the next 9, 10, 11 or 12 bits - public int getNextCode() { - // Attempt to get the next code. The exception is caught to make - // this robust to cases wherein the EndOfInformation code has been - // omitted from a strip. Examples of such cases have been observed - // in practice. - try { - nextData = (nextData << 8) | (data[bytePointer++] & 0xff); - nextBits += 8; - - if (nextBits < bitsToGet) { - nextData = (nextData << 8) | (data[bytePointer++] & 0xff); - nextBits += 8; - } - - int code = - (nextData >> (nextBits - bitsToGet)) & andTable[bitsToGet-9]; - nextBits -= bitsToGet; - - return code; - } catch(ArrayIndexOutOfBoundsException e) { - // Strip not terminated as expected: return EndOfInformation code. - return 257; - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/MultiColumnText.java b/src/main/java/com/lowagie/text/pdf/MultiColumnText.java deleted file mode 100644 index 4de2069..0000000 --- a/src/main/java/com/lowagie/text/pdf/MultiColumnText.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * $Id: MultiColumnText.java,v 1.19 2006/03/20 12:11:46 blowagie Exp $ - * $Name: $ - * - * Copyright 2004 Steve Appling - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.*; - -import java.util.ArrayList; - -/** - * Formats content into one or more columns bounded by a - * rectangle. The columns may be simple rectangles or - * more complicated shapes. Add all of the columns before - * adding content. Column continuation is supported. A MultiColumnText object may be added to - * a document using Document.add. - * @author Steve Appling - */ -public class MultiColumnText implements Element { - - /** special constant for automatic calculation of height */ - public static final float AUTOMATIC = -1f; - - /** - * total desiredHeight of columns. If AUTOMATIC, this means fill pages until done. - * This may be larger than one page - */ - private float desiredHeight; - - /** - * total height of element written out so far - */ - private float totalHeight; - - /** - * true if all the text could not be written out due to height restriction - */ - private boolean overflow; - - /** - * Top of the columns - y position on starting page. - * If AUTOMATIC, it means current y position when added to document - */ - private float top; - - /** - * used to store the y position of the bottom of the page - */ - private float pageBottom; - - /** - * ColumnText object used to do all the real work. This same object is used for all columns - */ - private ColumnText columnText; - - /** - * Array of ColumnDef objects used to define the columns - */ - private ArrayList columnDefs; - - /** - * true if all columns are simple (rectangular) - */ - private boolean simple = true; - - private int currentColumn = 0; - - private float nextY = AUTOMATIC; - - private boolean columnsRightToLeft = false; - - private PdfDocument document; - /** - * Default constructor. Sets height to AUTOMATIC. - * Columns will repeat on each page as necessary to accomodate content length. - */ - public MultiColumnText() { - this(AUTOMATIC); - } - - /** - * Construct a MultiColumnText container of the specified height. - * If height is AUTOMATIC, fill complete pages until done. - * If a specific height is used, it may span one or more pages. - * - * @param height - */ - public MultiColumnText(float height) { - columnDefs = new ArrayList(); - desiredHeight = height; - top = AUTOMATIC; - // canvas will be set later - columnText = new ColumnText(null); - totalHeight = 0f; - } - - /** - * Construct a MultiColumnText container of the specified height - * starting at the specified Y position. - * - * @param height - * @param top - */ - public MultiColumnText(float top, float height) { - columnDefs = new ArrayList(); - desiredHeight = height; - this.top = top; - nextY = top; - // canvas will be set later - columnText = new ColumnText(null); - totalHeight = 0f; - } - - /** - * Indicates that all of the text did not fit in the - * specified height. Note that isOverflow will return - * false before the MultiColumnText object has been - * added to the document. It will always be false if - * the height is AUTOMATIC. - * - * @return true if there is still space left in the column - */ - public boolean isOverflow() { - return overflow; - } - - /** - * Copy the parameters from the specified ColumnText to use - * when rendering. Parameters like setArabicOptions - * must be set in this way. - * - * @param sourceColumn - */ - public void useColumnParams(ColumnText sourceColumn) { - // note that canvas will be overwritten later - columnText.setSimpleVars(sourceColumn); - } - - /** - * Add a new column. The parameters are limits for each column - * wall in the format of a sequence of points (x1,y1,x2,y2,...). - * - * @param left limits for left column - * @param right limits for right column - */ - public void addColumn(float[] left, float[] right) { - ColumnDef nextDef = new ColumnDef(left, right); - simple = nextDef.isSimple(); - columnDefs.add(nextDef); - } - - /** - * Add a simple rectangular column with specified left - * and right x position boundaries. - * - * @param left left boundary - * @param right right boundary - */ - public void addSimpleColumn(float left, float right) { - ColumnDef newCol = new ColumnDef(left, right); - columnDefs.add(newCol); - } - - /** - * Add the specified number of evenly spaced rectangular columns. - * Columns will be seperated by the specified gutterWidth. - * - * @param left left boundary of first column - * @param right right boundary of last column - * @param gutterWidth width of gutter spacing between columns - * @param numColumns number of columns to add - */ - public void addRegularColumns(float left, float right, float gutterWidth, int numColumns) { - float currX = left; - float width = right - left; - float colWidth = (width - (gutterWidth * (numColumns - 1))) / numColumns; - for (int i = 0; i < numColumns; i++) { - addSimpleColumn(currX, currX + colWidth); - currX += colWidth + gutterWidth; - } - } - - /** - * Add an element to be rendered in a column. - * Note that you can only add a Phrase - * or a Chunk if the columns are - * not all simple. This is an underlying restriction in - * {@link com.lowagie.text.pdf.ColumnText} - * - * @param element element to add - * @throws DocumentException if element can't be added - */ - public void addElement(Element element) throws DocumentException { - if (simple) { - columnText.addElement(element); - } else if (element instanceof Phrase) { - columnText.addText((Phrase) element); - } else if (element instanceof Chunk) { - columnText.addText((Chunk) element); - } else { - throw new DocumentException("Can't add " + element.getClass() + " to MultiColumnText with complex columns"); - } - } - - - /** - * Write out the columns. After writing, use - * {@link #isOverflow()} to see if all text was written. - * @param canvas PdfContentByte to write with - * @param document document to write to (only used to get page limit info) - * @param documentY starting y position to begin writing at - * @return the current height (y position) after writing the columns - * @throws DocumentException on error - */ - public float write(PdfContentByte canvas, PdfDocument document, float documentY) throws DocumentException { - this.document = document; - columnText.setCanvas(canvas); - if (columnDefs.size() == 0) { - throw new DocumentException("MultiColumnText has no columns"); - } - overflow = false; - pageBottom = document.bottom(); - float currentHeight = 0; - boolean done = false; - try { - while (!done) { - if (nextY == AUTOMATIC) { - nextY = document.getVerticalPosition(true); // RS - 07/07/2005 - - Get current doc writing position for top of columns on new page. - } - if (top == AUTOMATIC) { - top = document.getVerticalPosition(true); // RS - 07/07/2005 - Get current doc writing position for top of columns on new page. - } - - ColumnDef currentDef = (ColumnDef) columnDefs.get(getCurrentColumn()); - columnText.setYLine(top); - - float[] left = currentDef.resolvePositions(Rectangle.LEFT); - float[] right = currentDef.resolvePositions(Rectangle.RIGHT); - if (document.isMarginMirroring() && document.getPageNumber() % 2 == 0){ - float delta = document.rightMargin() - document.left(); - left = (float[])left.clone(); - right = (float[])right.clone(); - for (int i = 0; i < left.length; i += 2) { - left[i] -= delta; - } - for (int i = 0; i < right.length; i += 2) { - right[i] -= delta; - } - } - - currentHeight = Math.max(currentHeight, getHeight(left, right)); - - if (currentDef.isSimple()) { - columnText.setSimpleColumn(left[2], left[3], right[0], right[1]); - } else { - columnText.setColumns(left, right); - } - - int result = columnText.go(); - if ((result & ColumnText.NO_MORE_TEXT) != 0) { - done = true; - top = columnText.getYLine(); - } else if (shiftCurrentColumn()) { - top = nextY; - } else { // check if we are done because of height - totalHeight += currentHeight; - if ((desiredHeight != AUTOMATIC) && (totalHeight >= desiredHeight)) { - overflow = true; - break; - } else { // need to start new page and reset the columns - documentY = nextY; - newPage(); - currentHeight = 0; - } - } - } - } catch (DocumentException ex) { - ex.printStackTrace(); - throw ex; - } - if (desiredHeight == AUTOMATIC && columnDefs.size() == 1) { - currentHeight = documentY - columnText.getYLine(); - } - return currentHeight; - } - - private void newPage() throws DocumentException { - resetCurrentColumn(); - if (desiredHeight == AUTOMATIC) { - top = nextY = AUTOMATIC; - } - else { - top = nextY; - } - totalHeight = 0; - if (document != null) { - document.newPage(); - } - } - - /** - * Figure out the height of a column from the border extents - * - * @param left left border - * @param right right border - * @return height - */ - private float getHeight(float[] left, float[] right) { - float max = Float.MIN_VALUE; - float min = Float.MAX_VALUE; - for (int i = 0; i < left.length; i += 2) { - min = Math.min(min, left[i + 1]); - max = Math.max(max, left[i + 1]); - } - for (int i = 0; i < right.length; i += 2) { - min = Math.min(min, right[i + 1]); - max = Math.max(max, right[i + 1]); - } - return max - min; - } - - - /** - * Processes the element by adding it to an - * ElementListener. - * - * @param listener an ElementListener - * @return true if the element was processed successfully - */ - public boolean process(ElementListener listener) { - try { - return listener.add(this); - } catch (DocumentException de) { - return false; - } - } - - /** - * Gets the type of the text element. - * - * @return a type - */ - - public int type() { - return Element.MULTI_COLUMN_TEXT; - } - - /** - * Returns null - not used - * - * @return null - */ - - public ArrayList getChunks() { - return null; - } - - /** - * Calculates the appropriate y position for the bottom - * of the columns on this page. - * - * @return the y position of the bottom of the columns - */ - private float getColumnBottom() { - if (desiredHeight == AUTOMATIC) { - return pageBottom; - } else { - return Math.max(top - (desiredHeight - totalHeight), pageBottom); - } - } - - /** - * Moves the text insertion point to the beginning of the next column, issuing a page break if - * needed. - * @throws DocumentException on error - */ - public void nextColumn() throws DocumentException { - currentColumn = (currentColumn + 1) % columnDefs.size(); - top = nextY; - if (currentColumn == 0) { - newPage(); - } - } - - /** - * Gets the current column. - * @return the current column - */ - public int getCurrentColumn() { - if (columnsRightToLeft) { - return (columnDefs.size() - currentColumn - 1); - } - return currentColumn; - } - - /** - * Resets the current column. - */ - public void resetCurrentColumn() { - currentColumn = 0; - } - - /** - * Shifts the current column. - * @return true if the currentcolumn has changed - */ - public boolean shiftCurrentColumn() { - if (currentColumn + 1 < columnDefs.size()) { - currentColumn++; - return true; - } - return false; - } - - /** - * Sets the direction of the columns. - * @param direction true = right2left; false = left2right - */ - public void setColumnsRightToLeft(boolean direction) { - columnsRightToLeft = direction; - } - - /** Sets the ratio between the extra word spacing and the extra character spacing - * when the text is fully justified. - * Extra word spacing will grow spaceCharRatio times more than extra character spacing. - * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the extra character spacing - * will be zero. - * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing - */ - public void setSpaceCharRatio(float spaceCharRatio) { - columnText.setSpaceCharRatio(spaceCharRatio); - } - - /** Sets the run direction. - * @param runDirection the run direction - */ - public void setRunDirection(int runDirection) { - columnText.setRunDirection(runDirection); - } - - /** Sets the arabic shaping options. The option can be AR_NOVOWEL, - * AR_COMPOSEDTASHKEEL and AR_LIG. - * @param arabicOptions the arabic shaping options - */ - public void setArabicOptions(int arabicOptions) { - columnText.setArabicOptions(arabicOptions); - } - - /** Sets the default alignment - * @param alignment the default alignment - */ - public void setAlignment(int alignment) { - columnText.setAlignment(alignment); - } - - /** - * Inner class used to define a column - */ - private class ColumnDef { - private float[] left; - private float[] right; - - ColumnDef(float[] newLeft, float[] newRight) { - left = newLeft; - right = newRight; - } - - ColumnDef(float leftPosition, float rightPosition) { - left = new float[4]; - left[0] = leftPosition; // x1 - left[1] = top; // y1 - left[2] = leftPosition; // x2 - if (desiredHeight == AUTOMATIC || top == AUTOMATIC) { - left[3] = AUTOMATIC; - } else { - left[3] = top - desiredHeight; - } - - right = new float[4]; - right[0] = rightPosition; // x1 - right[1] = top; // y1 - right[2] = rightPosition; // x2 - if (desiredHeight == AUTOMATIC || top == AUTOMATIC) { - right[3] = AUTOMATIC; - } else { - right[3] = top - desiredHeight; - } - } - - /** - * Resolves the positions for the specified side of the column - * into real numbers once the top of the column is known. - * - * @param side either Rectangle.LEFT - * or Rectangle.RIGHT - * @return the array of floats for the side - */ - float[] resolvePositions(int side) { - if (side == Rectangle.LEFT) { - return resolvePositions(left); - } else { - return resolvePositions(right); - } - } - - private float[] resolvePositions(float[] positions) { - if (!isSimple()) { - return positions; - } - if (top == AUTOMATIC) { - // this is bad - must be programmer error - throw new RuntimeException("resolvePositions called with top=AUTOMATIC (-1). " + - "Top position must be set befure lines can be resolved"); - } - positions[1] = top; - positions[3] = getColumnBottom(); - return positions; - } - - /** - * Checks if column definition is a simple rectangle - * @return true if it is a simple column - */ - private boolean isSimple() { - return (left.length == 4 && right.length == 4) && (left[0] == left[2] && right[0] == right[2]); - } - - } -} diff --git a/src/main/java/com/lowagie/text/pdf/OutputStreamCounter.java b/src/main/java/com/lowagie/text/pdf/OutputStreamCounter.java deleted file mode 100644 index bae72bc..0000000 --- a/src/main/java/com/lowagie/text/pdf/OutputStreamCounter.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; -import java.io.OutputStream; -import java.io.IOException; - -/** - * - * @author psoares - */ -public class OutputStreamCounter extends OutputStream { - - protected OutputStream out; - protected int counter = 0; - - /** Creates a new instance of OutputStreamCounter */ - public OutputStreamCounter(OutputStream out) { - this.out = out; - } - - /** Closes this output stream and releases any system resources - * associated with this stream. The general contract of close - * is that it closes the output stream. A closed stream cannot perform - * output operations and cannot be reopened. - *

- * The close method of OutputStream does nothing. - * - * @exception IOException if an I/O error occurs. - * - */ - public void close() throws IOException { - out.close(); - } - - /** Flushes this output stream and forces any buffered output bytes - * to be written out. The general contract of flush is - * that calling it is an indication that, if any bytes previously - * written have been buffered by the implementation of the output - * stream, such bytes should immediately be written to their - * intended destination. - *

- * The flush method of OutputStream does nothing. - * - * @exception IOException if an I/O error occurs. - * - */ - public void flush() throws IOException { - out.flush(); - } - - /** Writes b.length bytes from the specified byte array - * to this output stream. The general contract for write(b) - * is that it should have exactly the same effect as the call - * write(b, 0, b.length). - * - * @param b the data. - * @exception IOException if an I/O error occurs. - * @see java.io.OutputStream#write(byte[], int, int) - * - */ - public void write(byte[] b) throws IOException { - counter += b.length; - out.write(b); - } - - /** Writes the specified byte to this output stream. The general - * contract for write is that one byte is written - * to the output stream. The byte to be written is the eight - * low-order bits of the argument b. The 24 - * high-order bits of b are ignored. - *

- * Subclasses of OutputStream must provide an - * implementation for this method. - * - * @param b the byte. - * @exception IOException if an I/O error occurs. In particular, - * an IOException may be thrown if the - * output stream has been closed. - * - */ - public void write(int b) throws IOException { - ++counter; - out.write(b); - } - - /** Writes len bytes from the specified byte array - * starting at offset off to this output stream. - * The general contract for write(b, off, len) is that - * some of the bytes in the array b are written to the - * output stream in order; element b[off] is the first - * byte written and b[off+len-1] is the last byte written - * by this operation. - *

- * The write method of OutputStream calls - * the write method of one argument on each of the bytes to be - * written out. Subclasses are encouraged to override this method and - * provide a more efficient implementation. - *

- * If b is null, a - * NullPointerException is thrown. - *

- * If off is negative, or len is negative, or - * off+len is greater than the length of the array - * b, then an IndexOutOfBoundsException is thrown. - * - * @param b the data. - * @param off the start offset in the data. - * @param len the number of bytes to write. - * @exception IOException if an I/O error occurs. In particular, - * an IOException is thrown if the output - * stream is closed. - * - */ - public void write(byte[] b, int off, int len) throws IOException { - counter += len; - out.write(b, off, len); - } - - public int getCounter() { - return counter; - } - - public void resetCounter() { - counter = 0; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PRAcroForm.java b/src/main/java/com/lowagie/text/pdf/PRAcroForm.java deleted file mode 100644 index 986b2ab..0000000 --- a/src/main/java/com/lowagie/text/pdf/PRAcroForm.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * $Id: PRAcroForm.java,v 1.35 2005/05/04 14:31:42 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * This class written by Mark Thompson, Copyright (C) 2002 by Mark Thompson. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.HashMap; - -/** - * This class captures an AcroForm on input. Basically, it extends Dictionary - * by indexing the fields of an AcroForm - * @author Mark Thompson - */ - -public class PRAcroForm extends PdfDictionary { - - /** - * This class holds the information for a single field - */ - public static class FieldInformation { - String name; - PdfDictionary info; - PRIndirectReference ref; - - FieldInformation(String name, PdfDictionary info, PRIndirectReference ref) { - this.name = name; this.info = info; this.ref = ref; - } - public String getName() { return name; } - public PdfDictionary getInfo() { return info; } - public PRIndirectReference getRef() { return ref; } - }; - ArrayList fields; - ArrayList stack; - HashMap fieldByName; - PdfReader reader; - - /** - * Constructor - * @param reader reader of the input file - */ - public PRAcroForm(PdfReader reader) { - this.reader = reader; - fields = new ArrayList(); - fieldByName = new HashMap(); - stack = new ArrayList(); - } - /** - * Number of fields found - * @return size - */ - public int size() { - return fields.size(); - } - - public ArrayList getFields() { - return fields; - } - - public FieldInformation getField(String name) { - return (FieldInformation)fieldByName.get(name); - } - - /** - * Given the title (/T) of a reference, return the associated reference - * @param name a string containing the path - * @return a reference to the field, or null - */ - public PRIndirectReference getRefByName(String name) { - FieldInformation fi = (FieldInformation)fieldByName.get(name); - if (fi == null) return null; - return fi.getRef(); - } - /** - * Read, and comprehend the acroform - * @param root the docment root - */ - public void readAcroForm(PdfDictionary root) { - hashMap = root.hashMap; - pushAttrib(root); - PdfArray fieldlist = (PdfArray)PdfReader.getPdfObjectRelease(root.get(PdfName.FIELDS)); - iterateFields(fieldlist, null, null); - } - - /** - * After reading, we index all of the fields. Recursive. - * @param fieldlist An array of fields - * @param fieldDict the last field dictionary we encountered (recursively) - * @param title the pathname of the field, up to this point or null - */ - protected void iterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String title) { - for (Iterator it = fieldlist.getArrayList().iterator(); it.hasNext();) { - PRIndirectReference ref = (PRIndirectReference)it.next(); - PdfDictionary dict = (PdfDictionary) PdfReader.getPdfObjectRelease(ref); - - // if we are not a field dictionary, pass our parent's values - PRIndirectReference myFieldDict = fieldDict; - String myTitle = title; - PdfString tField = (PdfString)dict.get(PdfName.T); - boolean isFieldDict = tField != null; - - if (isFieldDict) { - myFieldDict = ref; - if (title == null) myTitle = tField.toString(); - else myTitle = title + '.' + tField.toString(); - } - - PdfArray kids = (PdfArray)dict.get(PdfName.KIDS); - if (kids != null) { - pushAttrib(dict); - iterateFields(kids, myFieldDict, myTitle); - stack.remove(stack.size() - 1); // pop - } - else { // leaf node - if (myFieldDict != null) { - PdfDictionary mergedDict = (PdfDictionary)stack.get(stack.size() - 1); - if (isFieldDict) - mergedDict = mergeAttrib(mergedDict, dict); - - mergedDict.put(PdfName.T, new PdfString(myTitle)); - FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict); - fields.add(fi); - fieldByName.put(myTitle, fi); - } - } - } - } - /** - * merge field attributes from two dictionaries - * @param parent one dictionary - * @param child the other dictionary - * @return a merged dictionary - */ - protected PdfDictionary mergeAttrib(PdfDictionary parent, PdfDictionary child) { - PdfDictionary targ = new PdfDictionary(); - if (parent != null) targ.putAll(parent); - - for (Iterator it = child.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName) it.next(); - if (key.equals(PdfName.DR) || key.equals(PdfName.DA) || - key.equals(PdfName.Q) || key.equals(PdfName.FF) || - key.equals(PdfName.DV) || key.equals(PdfName.V) - || key.equals(PdfName.FT) - || key.equals(PdfName.F)) { - targ.put(key,child.get(key)); - } - } - return targ; - } - /** - * stack a level of dictionary. Merge in a dictionary from this level - */ - protected void pushAttrib(PdfDictionary dict) { - PdfDictionary dic = null; - if (stack.size() != 0) { - dic = (PdfDictionary)stack.get(stack.size() - 1); - } - dic = mergeAttrib(dic, dict); - stack.add(dic); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PRIndirectReference.java b/src/main/java/com/lowagie/text/pdf/PRIndirectReference.java deleted file mode 100644 index 2ff852f..0000000 --- a/src/main/java/com/lowagie/text/pdf/PRIndirectReference.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * $Id: PRIndirectReference.java,v 1.46 2005/05/04 14:33:11 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.OutputStream; -import java.io.IOException; - -public class PRIndirectReference extends PdfIndirectReference { - - protected PdfReader reader; - // membervariables - - // constructors - -/** - * Constructs a PdfIndirectReference. - * - * @param reader a PdfReader - * @param number the object number. - * @param generation the generation number. - */ - - PRIndirectReference(PdfReader reader, int number, int generation) { - type = INDIRECT; - this.number = number; - this.generation = generation; - this.reader = reader; - } - -/** - * Constructs a PdfIndirectReference. - * - * @param reader a PdfReader - * @param number the object number. - */ - - PRIndirectReference(PdfReader reader, int number) { - this(reader, number, 0); - } - - // methods - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - int n = writer.getNewObjectNumber(reader, number, generation); - os.write(PdfEncodings.convertToBytes(new StringBuffer().append(n).append(" 0 R").toString(), null)); - } - - public PdfReader getReader() { - return reader; - } - - public void setNumber(int number, int generation) { - this.number = number; - this.generation = generation; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PRStream.java b/src/main/java/com/lowagie/text/pdf/PRStream.java deleted file mode 100644 index 272a45f..0000000 --- a/src/main/java/com/lowagie/text/pdf/PRStream.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * $Id: PRStream.java,v 1.46 2005/05/04 14:32:34 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.*; -import com.lowagie.text.ExceptionConverter; -import java.util.zip.DeflaterOutputStream; -import com.lowagie.text.Document; -import java.io.OutputStream; -import java.io.IOException; - -public class PRStream extends PdfStream { - - protected PdfReader reader; - protected int offset; - protected int length; - - //added by ujihara for decryption - protected int objNum = 0; - protected int objGen = 0; - - public PRStream(PRStream stream, PdfDictionary newDic) { - reader = stream.reader; - offset = stream.offset; - length = stream.length; - compressed = stream.compressed; - streamBytes = stream.streamBytes; - bytes = stream.bytes; - objNum = stream.objNum; - objGen = stream.objGen; - if (newDic != null) - putAll(newDic); - else - hashMap.putAll(stream.hashMap); - } - - public PRStream(PRStream stream, PdfDictionary newDic, PdfReader reader) { - this(stream, newDic); - this.reader = reader; - } - - public PRStream(PdfReader reader, int offset) { - this.reader = reader; - this.offset = offset; - } - - public PRStream(PdfReader reader, byte conts[]) { - this.reader = reader; - this.offset = -1; - if (Document.compress) { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - DeflaterOutputStream zip = new DeflaterOutputStream(stream); - zip.write(conts); - zip.close(); - bytes = stream.toByteArray(); - } - catch (IOException ioe) { - throw new ExceptionConverter(ioe); - } - put(PdfName.FILTER, PdfName.FLATEDECODE); - } - else - bytes = conts; - setLength(bytes.length); - } - - /**Sets the data associated with the stream - * @param data raw data, decrypted and uncompressed. - */ - public void setData(byte[] data) { - remove(PdfName.FILTER); - this.offset = -1; - if (Document.compress) { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - DeflaterOutputStream zip = new DeflaterOutputStream(stream); - zip.write(data); - zip.close(); - bytes = stream.toByteArray(); - } - catch (IOException ioe) { - throw new ExceptionConverter(ioe); - } - put(PdfName.FILTER, PdfName.FLATEDECODE); - } - else - bytes = data; - setLength(bytes.length); - } - - public void setLength(int length) { - this.length = length; - put(PdfName.LENGTH, new PdfNumber(length)); - } - - public int getOffset() { - return offset; - } - - public int getLength() { - return length; - } - - public PdfReader getReader() { - return reader; - } - - public byte[] getBytes() { - return bytes; - } - - public void setObjNum(int objNum, int objGen) { - this.objNum = objNum; - this.objGen = objGen; - } - - int getObjNum() { - return objNum; - } - - int getObjGen() { - return objGen; - } - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - superToPdf(writer, os); - os.write(STARTSTREAM); - if (length > 0) { - PdfEncryption crypto = null; - if (writer != null) - crypto = writer.getEncryption(); - if (offset < 0) { - if (crypto == null) - os.write(bytes); - else { - crypto.prepareKey(); - byte buf[] = new byte[length]; - System.arraycopy(bytes, 0, buf, 0, length); - crypto.encryptRC4(buf); - os.write(buf); - } - } - else { - byte buf[] = new byte[Math.min(length, 4092)]; - RandomAccessFileOrArray file = writer.getReaderFile(reader); - boolean isOpen = file.isOpen(); - try { - file.seek(offset); - int size = length; - - //added by ujihara for decryption - PdfEncryption decrypt = reader.getDecrypt(); - if (decrypt != null) { - decrypt.setHashKey(objNum, objGen); - decrypt.prepareKey(); - } - - if (crypto != null) - crypto.prepareKey(); - while (size > 0) { - int r = file.read(buf, 0, Math.min(size, buf.length)); - size -= r; - - if (decrypt != null) - decrypt.encryptRC4(buf, 0, r); //added by ujihara for decryption - - if (crypto != null) - crypto.encryptRC4(buf, 0, r); - os.write(buf, 0, r); - } - } - finally { - if (!isOpen) - try{file.close();}catch(Exception e){} - } - } - } - os.write(ENDSTREAM); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PRTokeniser.java b/src/main/java/com/lowagie/text/pdf/PRTokeniser.java deleted file mode 100644 index 9aaa881..0000000 --- a/src/main/java/com/lowagie/text/pdf/PRTokeniser.java +++ /dev/null @@ -1,585 +0,0 @@ -/* - * $Id: PRTokeniser.java,v 1.51 2005/12/22 18:29:21 psoares33 Exp $ - * - * Copyright 2001, 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.*; -/** - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PRTokeniser { - - public static final int TK_NUMBER = 1; - public static final int TK_STRING = 2; - public static final int TK_NAME = 3; - public static final int TK_COMMENT = 4; - public static final int TK_START_ARRAY = 5; - public static final int TK_END_ARRAY = 6; - public static final int TK_START_DIC = 7; - public static final int TK_END_DIC = 8; - public static final int TK_REF = 9; - public static final int TK_OTHER = 10; - public static final boolean delims[] = { - true, true, false, false, false, false, false, false, false, false, - true, true, false, true, true, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, true, false, false, false, false, true, false, - false, true, true, false, false, false, false, false, true, false, - false, false, false, false, false, false, false, false, false, false, - false, true, false, true, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, true, false, true, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false}; - - static final String EMPTY = ""; - - - protected RandomAccessFileOrArray file; - protected int type; - protected String stringValue; - protected int reference; - protected int generation; - protected boolean hexString; - - private static final int LINE_SEGMENT_SIZE = 256; - - public PRTokeniser(String filename) throws IOException { - file = new RandomAccessFileOrArray(filename); - } - - public PRTokeniser(byte pdfIn[]) { - file = new RandomAccessFileOrArray(pdfIn); - } - - public PRTokeniser(RandomAccessFileOrArray file) { - this.file = file; - } - - public void seek(int pos) throws IOException { - file.seek(pos); - } - - public int getFilePointer() throws IOException { - return file.getFilePointer(); - } - - public void close() throws IOException { - file.close(); - } - - public int length() throws IOException { - return file.length(); - } - - public int read() throws IOException { - return file.read(); - } - - public RandomAccessFileOrArray getSafeFile() { - return new RandomAccessFileOrArray(file); - } - - public RandomAccessFileOrArray getFile() { - return file; - } - - public String readString(int size) throws IOException { - StringBuffer buf = new StringBuffer(); - int ch; - while ((size--) > 0) { - ch = file.read(); - if (ch == -1) - break; - buf.append((char)ch); - } - return buf.toString(); - } - - public static final boolean isWhitespace(int ch) { - return (ch == 0 || ch == 9 || ch == 10 || ch == 12 || ch == 13 || ch == 32); - } - - public static final boolean isDelimiter(int ch) { - return (ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '/' || ch == '%'); - } - - public static final boolean isDelimiterWhitespace(int ch) { - return delims[ch + 1]; - } - - public int getTokenType() { - return type; - } - - public String getStringValue() { - return stringValue; - } - - public int getReference() { - return reference; - } - - public int getGeneration() { - return generation; - } - - public void backOnePosition(int ch) throws IOException { - if (ch != -1) - file.pushBack((byte)ch); - } - - public void throwError(String error) throws IOException { - throw new IOException(error + " at file pointer " + file.getFilePointer()); - } - - public char checkPdfHeader() throws IOException { - file.setStartOffset(0); - String str = readString(1024); - int idx = str.indexOf("%PDF-1."); - if (idx < 0) - throw new IOException("PDF header signature not found."); - file.setStartOffset(idx); - return str.charAt(idx + 7); - } - - public void checkFdfHeader() throws IOException { - file.setStartOffset(0); - String str = readString(1024); - int idx = str.indexOf("%FDF-1.2"); - if (idx < 0) - throw new IOException("FDF header signature not found."); - file.setStartOffset(idx); - } - - public int getStartxref() throws IOException { - int size = Math.min(1024, file.length()); - int pos = file.length() - size; - file.seek(pos); - String str = readString(1024); - int idx = str.lastIndexOf("startxref"); - if (idx < 0) - throw new IOException("PDF startxref not found."); - return pos + idx; - } - - public static int getHex(int v) { - if (v >= '0' && v <= '9') - return v - '0'; - if (v >= 'A' && v <= 'F') - return v - 'A' + 10; - if (v >= 'a' && v <= 'f') - return v - 'a' + 10; - return -1; - } - - public void nextValidToken() throws IOException { - int level = 0; - String n1 = null; - String n2 = null; - int ptr = 0; - while (nextToken()) { - if (type == TK_COMMENT) - continue; - switch (level) { - case 0: - { - if (type != TK_NUMBER) - return; - ptr = file.getFilePointer(); - n1 = stringValue; - ++level; - break; - } - case 1: - { - if (type != TK_NUMBER) { - file.seek(ptr); - type = TK_NUMBER; - stringValue = n1; - return; - } - n2 = stringValue; - ++level; - break; - } - default: - { - if (type != TK_OTHER || !stringValue.equals("R")) { - file.seek(ptr); - type = TK_NUMBER; - stringValue = n1; - return; - } - type = TK_REF; - reference = Integer.parseInt(n1); - generation = Integer.parseInt(n2); - return; - } - } - } - throwError("Unexpected end of file"); - } - - public boolean nextToken() throws IOException { - StringBuffer outBuf = null; - stringValue = EMPTY; - int ch = 0; - do { - ch = file.read(); - } while (ch != -1 && isWhitespace(ch)); - if (ch == -1) - return false; - switch (ch) { - case '[': - type = TK_START_ARRAY; - break; - case ']': - type = TK_END_ARRAY; - break; - case '/': - { - outBuf = new StringBuffer(); - type = TK_NAME; - while (true) { - ch = file.read(); - if (delims[ch + 1]) - break; - if (ch == '#') { - ch = (getHex(file.read()) << 4) + getHex(file.read()); - } - outBuf.append((char)ch); - } - backOnePosition(ch); - break; - } - case '>': - ch = file.read(); - if (ch != '>') - throwError("'>' not expected"); - type = TK_END_DIC; - break; - case '<': - { - int v1 = file.read(); - if (v1 == '<') { - type = TK_START_DIC; - break; - } - outBuf = new StringBuffer(); - type = TK_STRING; - hexString = true; - int v2 = 0; - while (true) { - while (isWhitespace(v1)) - v1 = file.read(); - if (v1 == '>') - break; - v1 = getHex(v1); - if (v1 < 0) - break; - v2 = file.read(); - while (isWhitespace(v2)) - v2 = file.read(); - if (v2 == '>') { - ch = v1 << 4; - outBuf.append((char)ch); - break; - } - v2 = getHex(v2); - if (v2 < 0) - break; - ch = (v1 << 4) + v2; - outBuf.append((char)ch); - v1 = file.read(); - } - if (v1 < 0 || v2 < 0) - throwError("Error reading string"); - break; - } - case '%': - type = TK_COMMENT; - do { - ch = file.read(); - } while (ch != -1 && ch != '\r' && ch != '\n'); - break; - case '(': - { - outBuf = new StringBuffer(); - type = TK_STRING; - hexString = false; - int nesting = 0; - while (true) { - ch = file.read(); - if (ch == -1) - break; - if (ch == '(') { - ++nesting; - } - else if (ch == ')') { - --nesting; - } - else if (ch == '\\') { - boolean lineBreak = false; - ch = file.read(); - switch (ch) { - case 'n': - ch = '\n'; - break; - case 'r': - ch = '\r'; - break; - case 't': - ch = '\t'; - break; - case 'b': - ch = '\b'; - break; - case 'f': - ch = '\f'; - break; - case '(': - case ')': - case '\\': - break; - case '\r': - lineBreak = true; - ch = file.read(); - if (ch != '\n') - backOnePosition(ch); - break; - case '\n': - lineBreak = true; - break; - default: - { - if (ch < '0' || ch > '7') { - break; - } - int octal = ch - '0'; - ch = file.read(); - if (ch < '0' || ch > '7') { - backOnePosition(ch); - ch = octal; - break; - } - octal = (octal << 3) + ch - '0'; - ch = file.read(); - if (ch < '0' || ch > '7') { - backOnePosition(ch); - ch = octal; - break; - } - octal = (octal << 3) + ch - '0'; - ch = octal & 0xff; - break; - } - } - if (lineBreak) - continue; - if (ch < 0) - break; - } - else if (ch == '\r') { - ch = file.read(); - if (ch < 0) - break; - if (ch != '\n') { - backOnePosition(ch); - ch = '\n'; - } - } - if (nesting == -1) - break; - outBuf.append((char)ch); - } - if (ch == -1) - throwError("Error reading string"); - break; - } - default: - { - outBuf = new StringBuffer(); - if (ch == '-' || ch == '+' || ch == '.' || (ch >= '0' && ch <= '9')) { - type = TK_NUMBER; - do { - outBuf.append((char)ch); - ch = file.read(); - } while (ch != -1 && ((ch >= '0' && ch <= '9') || ch == '.')); - } - else { - type = TK_OTHER; - do { - outBuf.append((char)ch); - ch = file.read(); - } while (!delims[ch + 1]); - } - backOnePosition(ch); - break; - } - } - if (outBuf != null) - stringValue = outBuf.toString(); - return true; - } - - public int intValue() { - return Integer.parseInt(stringValue); - } - - public boolean readLineSegment(byte input[]) throws IOException { - int c = -1; - boolean eol = false; - int ptr = 0; - int len = input.length; - // ssteward, pdftk-1.10, 040922: - // skip initial whitespace; added this because PdfReader.rebuildXref() - // assumes that line provided by readLineSegment does not have init. whitespace; - if ( ptr < len ) { - while ( isWhitespace( (c = read()) ) ); - } - while ( !eol && ptr < len ) { - switch (c) { - case -1: - case '\n': - eol = true; - break; - case '\r': - eol = true; - int cur = getFilePointer(); - if ((read()) != '\n') { - seek(cur); - } - break; - default: - input[ptr++] = (byte)c; - break; - } - - // break loop? do it before we read() again - if( eol || len <= ptr ) { - break; - } - else { - c = read(); - } - } - if (ptr >= len) { - eol = false; - while (!eol) { - switch (c = read()) { - case -1: - case '\n': - eol = true; - break; - case '\r': - eol = true; - int cur = getFilePointer(); - if ((read()) != '\n') { - seek(cur); - } - break; - } - } - } - - if ((c == -1) && (ptr == 0)) { - return false; - } - if (ptr + 2 <= len) { - input[ptr++] = (byte)' '; - input[ptr] = (byte)'X'; - } - return true; - } - - public static int[] checkObjectStart(byte line[]) { - try { - PRTokeniser tk = new PRTokeniser(line); - int num = 0; - int gen = 0; - if (!tk.nextToken() || tk.getTokenType() != TK_NUMBER) - return null; - num = tk.intValue(); - if (!tk.nextToken() || tk.getTokenType() != TK_NUMBER) - return null; - gen = tk.intValue(); - if (!tk.nextToken()) - return null; - if (!tk.getStringValue().equals("obj")) - return null; - return new int[]{num, gen}; - } - catch (Exception ioe) { - // empty on purpose - } - return null; - } - - public boolean isHexString() { - return this.hexString; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PageResources.java b/src/main/java/com/lowagie/text/pdf/PageResources.java deleted file mode 100644 index e065945..0000000 --- a/src/main/java/com/lowagie/text/pdf/PageResources.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * $Id: PageResources.java,v 1.14 2005/10/17 17:35:34 psoares33 Exp $ - * - * Copyright 2003-2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.HashMap; -import java.util.Iterator; - -class PageResources { - - protected PdfDictionary fontDictionary = new PdfDictionary(); - protected PdfDictionary xObjectDictionary = new PdfDictionary(); - protected PdfDictionary colorDictionary = new PdfDictionary(); - protected PdfDictionary patternDictionary = new PdfDictionary(); - protected PdfDictionary shadingDictionary = new PdfDictionary(); - protected PdfDictionary extGStateDictionary = new PdfDictionary(); - protected PdfDictionary propertyDictionary = new PdfDictionary(); - protected HashMap forbiddenNames; - protected PdfDictionary originalResources; - protected int namePtr[] = {0}; - protected HashMap usedNames; - - PageResources() { - } - - void setOriginalResources(PdfDictionary resources, int newNamePtr[]) { - if (newNamePtr != null) - namePtr = newNamePtr; - originalResources = resources; - forbiddenNames = new HashMap(); - usedNames = new HashMap(); - if (resources == null) - return; - for (Iterator i = resources.getKeys().iterator(); i.hasNext();) { - PdfObject sub = PdfReader.getPdfObject(resources.get((PdfName)i.next())); - if (sub.isDictionary()) { - PdfDictionary dic = (PdfDictionary)sub; - for (Iterator j = dic.getKeys().iterator(); j.hasNext();) { - forbiddenNames.put(j.next(), null); - } - } - } - } - - PdfName translateName(PdfName name) { - PdfName translated = name; - if (forbiddenNames != null) { - translated = (PdfName)usedNames.get(name); - if (translated == null) { - while (true) { - translated = new PdfName("Xi" + (namePtr[0]++)); - if (!forbiddenNames.containsKey(translated)) - break; - } - usedNames.put(name, translated); - } - } - return translated; - } - - PdfName addFont(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - fontDictionary.put(name, reference); - return name; - } - - PdfName addXObject(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - xObjectDictionary.put(name, reference); - return name; - } - - PdfName addColor(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - colorDictionary.put(name, reference); - return name; - } - - void addDefaultColor(PdfName name, PdfObject obj) { - if (obj == null || obj.isNull()) - colorDictionary.remove(name); - else - colorDictionary.put(name, obj); - } - - void addDefaultColor(PdfDictionary dic) { - colorDictionary.merge(dic); - } - - void addDefaultColorDiff(PdfDictionary dic) { - colorDictionary.mergeDifferent(dic); - } - - PdfName addShading(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - shadingDictionary.put(name, reference); - return name; - } - - PdfName addPattern(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - patternDictionary.put(name, reference); - return name; - } - - PdfName addExtGState(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - extGStateDictionary.put(name, reference); - return name; - } - - PdfName addProperty(PdfName name, PdfIndirectReference reference) { - name = translateName(name); - propertyDictionary.put(name, reference); - return name; - } - - PdfDictionary getResources() { - PdfResources resources = new PdfResources(); - if (originalResources != null) - resources.putAll(originalResources); - resources.put(PdfName.PROCSET, new PdfLiteral("[/PDF /Text /ImageB /ImageC /ImageI]")); - resources.add(PdfName.FONT, fontDictionary); - resources.add(PdfName.XOBJECT, xObjectDictionary); - resources.add(PdfName.COLORSPACE, colorDictionary); - resources.add(PdfName.PATTERN, patternDictionary); - resources.add(PdfName.SHADING, shadingDictionary); - resources.add(PdfName.EXTGSTATE, extGStateDictionary); - resources.add(PdfName.PROPERTIES, propertyDictionary); - return resources; - } - - boolean hasResources() { - return (fontDictionary.size() > 0 - || xObjectDictionary.size() > 0 - || colorDictionary.size() > 0 - || patternDictionary.size() > 0 - || shadingDictionary.size() > 0 - || extGStateDictionary.size() > 0 - || propertyDictionary.size() > 0); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PatternColor.java b/src/main/java/com/lowagie/text/pdf/PatternColor.java deleted file mode 100644 index 4268e1c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PatternColor.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** Represents a pattern. Can be used in high-level constructs (Paragraph, Cell, etc.). - */ -public class PatternColor extends ExtendedColor { - /** - * The actual pattern. - */ - PdfPatternPainter painter; - - /** Creates a color representing a pattern. - * @param painter the actual pattern - */ - public PatternColor(PdfPatternPainter painter) { - super(TYPE_PATTERN, .5f, .5f, .5f); - this.painter = painter; - } - - /** Gets the pattern. - * @return the pattern - */ - public PdfPatternPainter getPainter() { - return this.painter; - } - - public boolean equals(Object obj) { - return this == obj; - } - - public int hashCode() { - return painter.hashCode(); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfAcroForm.java b/src/main/java/com/lowagie/text/pdf/PdfAcroForm.java deleted file mode 100644 index 7893eb8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfAcroForm.java +++ /dev/null @@ -1,744 +0,0 @@ -/* - * $Id: PdfAcroForm.java,v 1.44 2005/03/30 10:10:58 blowagie Exp $ - * $Name: $ - * - * Copyright 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.Iterator; -import java.util.HashMap; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.ExceptionConverter; - -/** - * Each PDF document can contain maximum 1 AcroForm. - */ - -public class PdfAcroForm extends PdfDictionary { - - private PdfWriter writer; - - - /** This is a map containing FieldTemplates. */ - private HashMap fieldTemplates = new HashMap(); - - /** This is an array containing DocumentFields. */ - private PdfArray documentFields = new PdfArray(); - - /** This is an array containing the calculationorder of the fields. */ - private PdfArray calculationOrder = new PdfArray(); - - /** Contains the signature flags. */ - private int sigFlags = 0; - - /** Creates new PdfAcroForm - * @param writer*/ - PdfAcroForm(PdfWriter writer) { - super(); - this.writer = writer; - } - - /** - * Adds fieldTemplates. - * @param ft - */ - - void addFieldTemplates(HashMap ft) { - fieldTemplates.putAll(ft); - } - - /** - * Adds documentFields. - * @param ref - */ - - void addDocumentField(PdfIndirectReference ref) { - documentFields.add(ref); - } - - /** - * Checks if the Acroform is valid - * @return true if the Acroform is valid - */ - - boolean isValid() { - if (documentFields.size() == 0) return false; - put(PdfName.FIELDS, documentFields); - if (sigFlags != 0) - put(PdfName.SIGFLAGS, new PdfNumber(sigFlags)); - if (calculationOrder.size() > 0) - put(PdfName.CO, calculationOrder); - if (fieldTemplates.size() == 0) return true; - PdfDictionary dic = new PdfDictionary(); - for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) { - PdfTemplate template = (PdfTemplate)it.next(); - PdfFormField.mergeResources(dic, (PdfDictionary)template.getResources()); - } - put(PdfName.DR, dic); - PdfDictionary fonts = (PdfDictionary)dic.get(PdfName.FONT); - if (fonts != null) { - put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); - writer.eliminateFontSubset(fonts); - } - return true; - } - - /** - * Adds an object to the calculationOrder. - * @param formField - */ - - public void addCalculationOrder(PdfFormField formField) { - calculationOrder.add(formField.getIndirectReference()); - } - - /** - * Sets the signature flags. - * @param f - */ - - public void setSigFlags(int f) { - sigFlags |= f; - } - - /** - * Adds a formfield to the AcroForm. - * @param formField - */ - - public void addFormField(PdfFormField formField) { - writer.addAnnotation(formField); - } - - /** - * @param name - * @param caption - * @param value - * @param url - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addHtmlPostButton(String name, String caption, String value, String url, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT); - PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); - setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value); - drawButton(button, caption, font, fontSize, llx, lly, urx, ury); - addFormField(button); - return button; - } - - /** - * @param name - * @param caption - * @param value - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addResetButton(String name, String caption, String value, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfAction action = PdfAction.createResetForm(null, 0); - PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); - setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value); - drawButton(button, caption, font, fontSize, llx, lly, urx, ury); - addFormField(button); - return button; - } - - /** - * @param name - * @param value - * @param url - * @param appearance - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addMap(String name, String value, String url, PdfContentByte appearance, float llx, float lly, float urx, float ury) { - PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_COORDINATES); - PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action); - setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, null); - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance pa = cb.createAppearance(urx - llx, ury - lly); - pa.add(appearance); - button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa); - addFormField(button); - return button; - } - - /** - * @param button - * @param characteristics - * @param name - * @param value - */ - public void setButtonParams(PdfFormField button, int characteristics, String name, String value) { - button.setButton(characteristics); - button.setFlags(PdfAnnotation.FLAGS_PRINT); - button.setPage(); - button.setFieldName(name); - if (value != null) button.setValueAsString(value); - } - - /** - * @param button - * @param caption - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawButton(PdfFormField button, String caption, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance pa = cb.createAppearance(urx - llx, ury - lly); - pa.drawButton(0f, 0f, urx - llx, ury - lly, caption, font, fontSize); - button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa); - } - - /** - * @param name - * @param value - * @return a PdfFormField - */ - public PdfFormField addHiddenField(String name, String value) { - PdfFormField hidden = PdfFormField.createEmpty(writer); - hidden.setFieldName(name); - hidden.setValueAsName(value); - addFormField(hidden); - return hidden; - } - - /** - * @param name - * @param text - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addSingleLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PLAINTEXT, 0); - setTextFieldParams(field, text, name, llx, lly, urx, ury); - drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury); - addFormField(field); - return field; - } - - /** - * @param name - * @param text - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addMultiLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.MULTILINE, PdfFormField.PLAINTEXT, 0); - setTextFieldParams(field, text, name, llx, lly, urx, ury); - drawMultiLineOfText(field, text, font, fontSize, llx, lly, urx, ury); - addFormField(field); - return field; - } - - /** - * @param name - * @param text - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return PdfFormField - */ - public PdfFormField addSingleLinePasswordField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PASSWORD, 0); - setTextFieldParams(field, text, name, llx, lly, urx, ury); - drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury); - addFormField(field); - return field; - } - - /** - * @param field - * @param text - * @param name - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void setTextFieldParams(PdfFormField field, String text, String name, float llx, float lly, float urx, float ury) { - field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); - field.setValueAsString(text); - field.setDefaultValueAsString(text); - field.setFieldName(name); - field.setFlags(PdfAnnotation.FLAGS_PRINT); - field.setPage(); - } - - /** - * @param field - * @param text - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawSingleLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance tp = cb.createAppearance(urx - llx, ury - lly); - PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate(); - tp2.setFontAndSize(font, fontSize); - tp2.resetRGBColorFill(); - field.setDefaultAppearanceString(tp2); - tp.drawTextField(0f, 0f, urx - llx, ury - lly); - tp.beginVariableText(); - tp.saveState(); - tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f); - tp.clip(); - tp.newPath(); - tp.beginText(); - tp.setFontAndSize(font, fontSize); - tp.resetRGBColorFill(); - tp.setTextMatrix(4, (ury - lly) / 2 - (fontSize * 0.3f)); - tp.showText(text); - tp.endText(); - tp.restoreState(); - tp.endVariableText(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); - } - - /** - * @param field - * @param text - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawMultiLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance tp = cb.createAppearance(urx - llx, ury - lly); - PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate(); - tp2.setFontAndSize(font, fontSize); - tp2.resetRGBColorFill(); - field.setDefaultAppearanceString(tp2); - tp.drawTextField(0f, 0f, urx - llx, ury - lly); - tp.beginVariableText(); - tp.saveState(); - tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f); - tp.clip(); - tp.newPath(); - tp.beginText(); - tp.setFontAndSize(font, fontSize); - tp.resetRGBColorFill(); - tp.setTextMatrix(4, 5); - java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(text, "\n"); - float yPos = ury - lly; - while (tokenizer.hasMoreTokens()) { - yPos -= fontSize * 1.2f; - tp.showTextAligned(PdfContentByte.ALIGN_LEFT, tokenizer.nextToken(), 3, yPos, 0); - } - tp.endText(); - tp.restoreState(); - tp.endVariableText(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); - } - - /** - * @param name - * @param value - * @param status - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addCheckBox(String name, String value, boolean status, float llx, float lly, float urx, float ury) { - PdfFormField field = PdfFormField.createCheckBox(writer); - setCheckBoxParams(field, name, value, status, llx, lly, urx, ury); - drawCheckBoxAppearences(field, value, llx, lly, urx, ury); - addFormField(field); - return field; - } - - /** - * @param field - * @param name - * @param value - * @param status - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void setCheckBoxParams(PdfFormField field, String name, String value, boolean status, float llx, float lly, float urx, float ury) { - field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE); - field.setFieldName(name); - if (status) { - field.setValueAsName(value); - field.setAppearanceState(value); - } - else { - field.setValueAsName("Off"); - field.setAppearanceState("Off"); - } - field.setFlags(PdfAnnotation.FLAGS_PRINT); - field.setPage(); - field.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID)); - } - - /** - * @param field - * @param value - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawCheckBoxAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) { - BaseFont font = null; - try { - font = BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED); - } - catch(Exception e) { - throw new ExceptionConverter(e); - } - float size = (ury - lly); - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance tpOn = cb.createAppearance(urx - llx, ury - lly); - PdfAppearance tp2 = (PdfAppearance)tpOn.getDuplicate(); - tp2.setFontAndSize(font, size); - tp2.resetRGBColorFill(); - field.setDefaultAppearanceString(tp2); - tpOn.drawTextField(0f, 0f, urx - llx, ury - lly); - tpOn.saveState(); - tpOn.resetRGBColorFill(); - tpOn.beginText(); - tpOn.setFontAndSize(font, size); - tpOn.showTextAligned(PdfContentByte.ALIGN_CENTER, "4", (urx - llx) / 2, (ury - lly) / 2 - (size * 0.3f), 0); - tpOn.endText(); - tpOn.restoreState(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn); - PdfAppearance tpOff = cb.createAppearance(urx - llx, ury - lly); - tpOff.drawTextField(0f, 0f, urx - llx, ury - lly); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff); - } - - /** - * @param name - * @param defaultValue - * @param noToggleToOff - * @return a PdfFormField - */ - public PdfFormField getRadioGroup(String name, String defaultValue, boolean noToggleToOff) { - PdfFormField radio = PdfFormField.createRadioButton(writer, noToggleToOff); - radio.setFieldName(name); - radio.setValueAsName(defaultValue); - return radio; - } - - /** - * @param radiogroup - */ - public void addRadioGroup(PdfFormField radiogroup) { - addFormField(radiogroup); - } - - /** - * @param radiogroup - * @param value - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addRadioButton(PdfFormField radiogroup, String value, float llx, float lly, float urx, float ury) { - PdfFormField radio = PdfFormField.createEmpty(writer); - radio.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE); - String name = ((PdfName)radiogroup.get(PdfName.V)).toString().substring(1); - if (name.equals(value)) { - radio.setAppearanceState(value); - } - else { - radio.setAppearanceState("Off"); - } - drawRadioAppearences(radio, value, llx, lly, urx, ury); - radiogroup.addKid(radio); - return radio; - } - - /** - * @param field - * @param value - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawRadioAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) { - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance tpOn = cb.createAppearance(urx - llx, ury - lly); - tpOn.drawRadioField(0f, 0f, urx - llx, ury - lly, true); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn); - PdfAppearance tpOff = cb.createAppearance(urx - llx, ury - lly); - tpOff.drawRadioField(0f, 0f, urx - llx, ury - lly, false); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff); - } - - /** - * @param name - * @param options - * @param defaultValue - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addSelectList(String name, String[] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField choice = PdfFormField.createList(writer, options, 0); - setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); - StringBuffer text = new StringBuffer(); - for (int i = 0; i < options.length; i++) { - text.append(options[i]).append("\n"); - } - drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury); - addFormField(choice); - return choice; - } - - /** - * @param name - * @param options - * @param defaultValue - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addSelectList(String name, String[][] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField choice = PdfFormField.createList(writer, options, 0); - setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); - StringBuffer text = new StringBuffer(); - for (int i = 0; i < options.length; i++) { - text.append(options[i][1]).append("\n"); - } - drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury); - addFormField(choice); - return choice; - } - - /** - * @param name - * @param options - * @param defaultValue - * @param editable - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addComboBox(String name, String[] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0); - setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); - if (defaultValue == null) { - defaultValue = options[0]; - } - drawSingleLineOfText(choice, defaultValue, font, fontSize, llx, lly, urx, ury); - addFormField(choice); - return choice; - } - - /** - * @param name - * @param options - * @param defaultValue - * @param editable - * @param font - * @param fontSize - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addComboBox(String name, String[][] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) { - PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0); - setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury); - String value = null; - for (int i = 0; i < options.length; i++) { - if (options[i][0].equals(defaultValue)) { - value = options[i][1]; - break; - } - } - if (value == null) { - value = options[0][1]; - } - drawSingleLineOfText(choice, value, font, fontSize, llx, lly, urx, ury); - addFormField(choice); - return choice; - } - - /** - * @param field - * @param name - * @param defaultValue - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void setChoiceParams(PdfFormField field, String name, String defaultValue, float llx, float lly, float urx, float ury) { - field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); - if (defaultValue != null) { - field.setValueAsString(defaultValue); - field.setDefaultValueAsString(defaultValue); - } - field.setFieldName(name); - field.setFlags(PdfAnnotation.FLAGS_PRINT); - field.setPage(); - field.setBorderStyle(new PdfBorderDictionary(2, PdfBorderDictionary.STYLE_SOLID)); - } - - /** - * @param name - * @param llx - * @param lly - * @param urx - * @param ury - * @return a PdfFormField - */ - public PdfFormField addSignature(String name, - float llx, float lly, float urx, float ury) { - PdfFormField signature = PdfFormField.createSignature(writer); - setSignatureParams(signature, name, llx, lly, urx, ury); - drawSignatureAppearences(signature, llx, lly, urx, ury); - addFormField(signature); - return signature; - } - - /** - * @param field - * @param name - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void setSignatureParams(PdfFormField field, String name, - float llx, float lly, float urx, float ury) { - field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT); - field.setFieldName(name); - field.setFlags(PdfAnnotation.FLAGS_PRINT); - field.setPage(); - field.setMKBorderColor(java.awt.Color.black); - field.setMKBackgroundColor(java.awt.Color.white); - } - - /** - * @param field - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawSignatureAppearences(PdfFormField field, - float llx, float lly, float urx, float ury) { - PdfContentByte cb = writer.getDirectContent(); - PdfAppearance tp = cb.createAppearance(urx - llx, ury - lly); - tp.setGrayFill(1.0f); - tp.rectangle(0, 0, urx - llx, ury - lly); - tp.fill(); - tp.setGrayStroke(0); - tp.setLineWidth(1); - tp.rectangle(0.5f, 0.5f, urx - llx - 0.5f, ury - lly - 0.5f); - tp.closePathStroke(); - tp.saveState(); - tp.rectangle(1, 1, urx - llx - 2, ury - lly - 2); - tp.clip(); - tp.newPath(); - tp.restoreState(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfAction.java b/src/main/java/com/lowagie/text/pdf/PdfAction.java deleted file mode 100644 index 054fd30..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfAction.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * $Id: PdfAction.java,v 1.71 2006/05/18 09:38:35 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 by Bruno Lowagie. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.net.URL; -import com.lowagie.text.ExceptionConverter; -import java.io.IOException; -import java.util.ArrayList; - -/** - * A PdfAction defines an action that can be triggered from a PDF file. - * - * @see PdfDictionary - */ - -public class PdfAction extends PdfDictionary { - - /** A named action to go to the first page. - */ - public static final int FIRSTPAGE = 1; - /** A named action to go to the previous page. - */ - public static final int PREVPAGE = 2; - /** A named action to go to the next page. - */ - public static final int NEXTPAGE = 3; - /** A named action to go to the last page. - */ - public static final int LASTPAGE = 4; - - /** A named action to open a print dialog. - */ - public static final int PRINTDIALOG = 5; - - /** a possible submitvalue */ - public static final int SUBMIT_EXCLUDE = 1; - /** a possible submitvalue */ - public static final int SUBMIT_INCLUDE_NO_VALUE_FIELDS = 2; - /** a possible submitvalue */ - public static final int SUBMIT_HTML_FORMAT = 4; - /** a possible submitvalue */ - public static final int SUBMIT_HTML_GET = 8; - /** a possible submitvalue */ - public static final int SUBMIT_COORDINATES = 16; - /** a possible submitvalue */ - public static final int SUBMIT_XFDF = 32; - /** a possible submitvalue */ - public static final int SUBMIT_INCLUDE_APPEND_SAVES = 64; - /** a possible submitvalue */ - public static final int SUBMIT_INCLUDE_ANNOTATIONS = 128; - /** a possible submitvalue */ - public static final int SUBMIT_PDF = 256; - /** a possible submitvalue */ - public static final int SUBMIT_CANONICAL_FORMAT = 512; - /** a possible submitvalue */ - public static final int SUBMIT_EXCL_NON_USER_ANNOTS = 1024; - /** a possible submitvalue */ - public static final int SUBMIT_EXCL_F_KEY = 2048; - /** a possible submitvalue */ - public static final int SUBMIT_EMBED_FORM = 8196; - /** a possible submitvalue */ - public static final int RESET_EXCLUDE = 1; - - // constructors - - /** Create an empty action. - */ - public PdfAction() { - } - - /** - * Constructs a new PdfAction of Subtype URI. - * - * @param url the Url to go to - */ - - public PdfAction(URL url) { - this(url.toExternalForm()); - } - - /** - * Construct a new PdfAction of Subtype URI that accepts the x and y coordinate of the position that was clicked. - * @param url - * @param isMap - */ - public PdfAction(URL url, boolean isMap) { - this(url.toExternalForm(), isMap); - } - - /** - * Constructs a new PdfAction of Subtype URI. - * - * @param url the url to go to - */ - - public PdfAction(String url) { - this(url, false); - } - - /** - * Construct a new PdfAction of Subtype URI that accepts the x and y coordinate of the position that was clicked. - * @param url - * @param isMap - */ - - public PdfAction(String url, boolean isMap) { - put(PdfName.S, PdfName.URI); - put(PdfName.URI, new PdfString(url)); - if (isMap) - put(PdfName.ISMAP, PdfBoolean.PDFTRUE); - } - - /** - * Constructs a new PdfAction of Subtype GoTo. - * @param destination the destination to go to - */ - - PdfAction(PdfIndirectReference destination) { - put(PdfName.S, PdfName.GOTO); - put(PdfName.D, destination); - } - - /** - * Constructs a new PdfAction of Subtype GoToR. - * @param filename the file name to go to - * @param name the named destination to go to - */ - - public PdfAction(String filename, String name) { - put(PdfName.S, PdfName.GOTOR); - put(PdfName.F, new PdfString(filename)); - put(PdfName.D, new PdfString(name)); - } - - /** - * Constructs a new PdfAction of Subtype GoToR. - * @param filename the file name to go to - * @param page the page destination to go to - */ - - public PdfAction(String filename, int page) { - put(PdfName.S, PdfName.GOTOR); - put(PdfName.F, new PdfString(filename)); - put(PdfName.D, new PdfLiteral("[" + (page - 1) + " /FitH 10000]")); - } - - /** Implements name actions. The action can be FIRSTPAGE, LASTPAGE, - * NEXTPAGE, PREVPAGE and PRINTDIALOG. - * @param named the named action - */ - public PdfAction(int named) { - put(PdfName.S, PdfName.NAMED); - switch (named) { - case FIRSTPAGE: - put(PdfName.N, PdfName.FIRSTPAGE); - break; - case LASTPAGE: - put(PdfName.N, PdfName.LASTPAGE); - break; - case NEXTPAGE: - put(PdfName.N, PdfName.NEXTPAGE); - break; - case PREVPAGE: - put(PdfName.N, PdfName.PREVPAGE); - break; - case PRINTDIALOG: - put(PdfName.S, PdfName.JAVASCRIPT); - put(PdfName.JS, new PdfString("this.print(true);\r")); - break; - default: - throw new RuntimeException("Invalid named action."); - } - } - - /** Launchs an application or a document. - * @param application the application to be launched or the document to be opened or printed. - * @param parameters (Windows-specific) A parameter string to be passed to the application. - * It can be null. - * @param operation (Windows-specific) the operation to perform: "open" - Open a document, - * "print" - Print a document. - * It can be null. - * @param defaultDir (Windows-specific) the default directory in standard DOS syntax. - * It can be null. - */ - public PdfAction(String application, String parameters, String operation, String defaultDir) { - put(PdfName.S, PdfName.LAUNCH); - if (parameters == null && operation == null && defaultDir == null) - put(PdfName.F, new PdfString(application)); - else { - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.F, new PdfString(application)); - if (parameters != null) - dic.put(PdfName.P, new PdfString(parameters)); - if (operation != null) - dic.put(PdfName.O, new PdfString(operation)); - if (defaultDir != null) - dic.put(PdfName.D, new PdfString(defaultDir)); - put(PdfName.WIN, dic); - } - } - - /** Launchs an application or a document. - * @param application the application to be launched or the document to be opened or printed. - * @param parameters (Windows-specific) A parameter string to be passed to the application. - * It can be null. - * @param operation (Windows-specific) the operation to perform: "open" - Open a document, - * "print" - Print a document. - * It can be null. - * @param defaultDir (Windows-specific) the default directory in standard DOS syntax. - * It can be null. - * @return a Launch action - */ - public static PdfAction createLaunch(String application, String parameters, String operation, String defaultDir) { - return new PdfAction(application, parameters, operation, defaultDir); - } - - /**Creates a Rendition action - * @param file - * @param fs - * @param mimeType - * @param ref - * @return a Media Clip action - * @throws IOException - */ - public static PdfAction rendition(String file, PdfFileSpecification fs, String mimeType, PdfIndirectReference ref) throws IOException { - PdfAction js = new PdfAction(); - js.put(PdfName.S, PdfName.RENDITION); - js.put(PdfName.R, new PdfRendition(file, fs, mimeType)); - js.put(new PdfName("OP"), new PdfNumber(0)); - js.put(new PdfName("AN"), ref); - return js; - } - - /** Creates a JavaScript action. If the JavaScript is smaller than - * 50 characters it will be placed as a string, otherwise it will - * be placed as a compressed stream. - * @param code the JavaScript code - * @param writer the writer for this action - * @param unicode select JavaScript unicode. Note that the internal - * Acrobat JavaScript engine does not support unicode, - * so this may or may not work for you - * @return the JavaScript action - */ - public static PdfAction javaScript(String code, PdfWriter writer, boolean unicode) { - PdfAction js = new PdfAction(); - js.put(PdfName.S, PdfName.JAVASCRIPT); - if (unicode && code.length() < 50) { - js.put(PdfName.JS, new PdfString(code, PdfObject.TEXT_UNICODE)); - } - else if (!unicode && code.length() < 100) { - js.put(PdfName.JS, new PdfString(code)); - } - else { - try { - byte b[] = PdfEncodings.convertToBytes(code, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING); - PdfStream stream = new PdfStream(b); - stream.flateCompress(); - js.put(PdfName.JS, writer.addToBody(stream).getIndirectReference()); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - return js; - } - - /** Creates a JavaScript action. If the JavaScript is smaller than - * 50 characters it will be place as a string, otherwise it will - * be placed as a compressed stream. - * @param code the JavaScript code - * @param writer the writer for this action - * @return the JavaScript action - */ - public static PdfAction javaScript(String code, PdfWriter writer) { - return javaScript(code, writer, false); - } - - /** - * A Hide action hides or shows an object. - * @param obj object to hide or show - * @param hide true is hide, false is show - * @return a Hide Action - */ - static PdfAction createHide(PdfObject obj, boolean hide) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.HIDE); - action.put(PdfName.T, obj); - if (!hide) - action.put(PdfName.H, PdfBoolean.PDFFALSE); - return action; - } - - /** - * A Hide action hides or shows an annotation. - * @param annot - * @param hide - * @return A Hide Action - */ - public static PdfAction createHide(PdfAnnotation annot, boolean hide) { - return createHide(annot.getIndirectReference(), hide); - } - - /** - * A Hide action hides or shows an annotation. - * @param name - * @param hide - * @return A Hide Action - */ - public static PdfAction createHide(String name, boolean hide) { - return createHide(new PdfString(name), hide); - } - - static PdfArray buildArray(Object names[]) { - PdfArray array = new PdfArray(); - for (int k = 0; k < names.length; ++k) { - Object obj = names[k]; - if (obj instanceof String) - array.add(new PdfString((String)obj)); - else if (obj instanceof PdfAnnotation) - array.add(((PdfAnnotation)obj).getIndirectReference()); - else - throw new RuntimeException("The array must contain String or PdfAnnotation."); - } - return array; - } - - /** - * A Hide action hides or shows objects. - * @param names - * @param hide - * @return A Hide Action - */ - public static PdfAction createHide(Object names[], boolean hide) { - return createHide(buildArray(names), hide); - } - - /** - * Creates a submit form. - * @param file the URI to submit the form to - * @param names the objects to submit - * @param flags submit properties - * @return A PdfAction - */ - public static PdfAction createSubmitForm(String file, Object names[], int flags) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.SUBMITFORM); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.F, new PdfString(file)); - dic.put(PdfName.FS, PdfName.URL); - action.put(PdfName.F, dic); - if (names != null) - action.put(PdfName.FIELDS, buildArray(names)); - action.put(PdfName.FLAGS, new PdfNumber(flags)); - return action; - } - - /** - * Creates a resetform. - * @param names the objects to reset - * @param flags submit properties - * @return A PdfAction - */ - public static PdfAction createResetForm(Object names[], int flags) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.RESETFORM); - if (names != null) - action.put(PdfName.FIELDS, buildArray(names)); - action.put(PdfName.FLAGS, new PdfNumber(flags)); - return action; - } - - /** - * Creates an Import field. - * @param file - * @return A PdfAction - */ - public static PdfAction createImportData(String file) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.IMPORTDATA); - action.put(PdfName.F, new PdfString(file)); - return action; - } - - /** Add a chained action. - * @param na the next action - */ - public void next(PdfAction na) { - PdfObject nextAction = get(PdfName.NEXT); - if (nextAction == null) - put(PdfName.NEXT, na); - else if (nextAction.isDictionary()) { - PdfArray array = new PdfArray(nextAction); - array.add(na); - put(PdfName.NEXT, array); - } - else { - ((PdfArray)nextAction).add(na); - } - } - - /** Creates a GoTo action to an internal page. - * @param page the page to go. First page is 1 - * @param dest the destination for the page - * @param writer the writer for this action - * @return a GoTo action - */ - public static PdfAction gotoLocalPage(int page, PdfDestination dest, PdfWriter writer) { - PdfIndirectReference ref = writer.getPageReference(page); - dest.addPage(ref); - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.GOTO); - action.put(PdfName.D, dest); - return action; - } - - /** - * Creates a GoTo action to a named destination. - * @param dest the named destination - * @param isName if true sets the destination as a name, if false sets it as a String - * @return a GoTo action - */ - public static PdfAction gotoLocalPage(String dest, boolean isName) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.GOTO); - if (isName) - action.put(PdfName.D, new PdfName(dest)); - else - action.put(PdfName.D, new PdfString(dest, null)); - return action; - } - - /** - * Creates a GoToR action to a named destination. - * @param filename the file name to go to - * @param dest the destination name - * @param isName if true sets the destination as a name, if false sets it as a String - * @param newWindow open the document in a new window if true, if false the current document is replaced by the new document. - * @return a GoToR action - */ - public static PdfAction gotoRemotePage(String filename, String dest, boolean isName, boolean newWindow) { - PdfAction action = new PdfAction(); - action.put(PdfName.F, new PdfString(filename)); - action.put(PdfName.S, PdfName.GOTOR); - if (isName) - action.put(PdfName.D, new PdfName(dest)); - else - action.put(PdfName.D, new PdfString(dest, null)); - if (newWindow) - action.put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE); - return action; - } - - /** - * A set-OCG-state action (PDF 1.5) sets the state of one or more optional content - * groups. - * @param state an array consisting of any number of sequences beginning with a PdfName - * or String (ON, OFF, or Toggle) followed by one or more optional content group dictionaries - * PdfLayer or a PdfIndirectReference to a PdfLayer.
- * The array elements are processed from left to right; each name is applied - * to the subsequent groups until the next name is encountered: - *

- * @param preserveRB if true, indicates that radio-button state relationships between optional - * content groups (as specified by the RBGroups entry in the current configuration - * dictionary) should be preserved when the states in the - * state array are applied. That is, if a group is set to ON (either by ON or Toggle) during - * processing of the state array, any other groups belong to the same radio-button - * group are turned OFF. If a group is set to OFF, there is no effect on other groups.
- * If false, radio-button state relationships, if any, are ignored - * @return the action - */ - public static PdfAction setOCGstate(ArrayList state, boolean preserveRB) { - PdfAction action = new PdfAction(); - action.put(PdfName.S, PdfName.SETOCGSTATE); - PdfArray a = new PdfArray(); - for (int k = 0; k < state.size(); ++k) { - Object o = state.get(k); - if (o == null) - continue; - if (o instanceof PdfIndirectReference) - a.add((PdfIndirectReference)o); - else if (o instanceof PdfLayer) - a.add(((PdfLayer)o).getRef()); - else if (o instanceof PdfName) - a.add((PdfName)o); - else if (o instanceof String) { - PdfName name = null; - String s = (String)o; - if (s.equalsIgnoreCase("on")) - name = PdfName.ON; - else if (s.equalsIgnoreCase("off")) - name = PdfName.OFF; - else if (s.equalsIgnoreCase("toggle")) - name = PdfName.TOGGLE; - else - throw new IllegalArgumentException("A string '" + s + " was passed in state. Only 'ON', 'OFF' and 'Toggle' are allowed."); - a.add(name); - } - else - throw new IllegalArgumentException("Invalid type was passed in state: " + o.getClass().getName()); - } - action.put(PdfName.STATE, a); - if (!preserveRB) - action.put(PdfName.PRESERVERB, PdfBoolean.PDFFALSE); - return action; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfAnnotation.java b/src/main/java/com/lowagie/text/pdf/PdfAnnotation.java deleted file mode 100644 index 53deae7..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfAnnotation.java +++ /dev/null @@ -1,742 +0,0 @@ -/* - * $Id: PdfAnnotation.java,v 1.66 2006/06/04 22:23:39 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; -import java.util.HashMap; -import java.awt.Color; -import java.io.*; -/** - * A PdfAnnotation is a note that is associated with a page. - * - * @see PdfDictionary - */ - -public class PdfAnnotation extends PdfDictionary { - /** highlight attributename */ - public static final PdfName HIGHLIGHT_NONE = PdfName.N; - /** highlight attributename */ - public static final PdfName HIGHLIGHT_INVERT = PdfName.I; - /** highlight attributename */ - public static final PdfName HIGHLIGHT_OUTLINE = PdfName.O; - /** highlight attributename */ - public static final PdfName HIGHLIGHT_PUSH = PdfName.P; - /** highlight attributename */ - public static final PdfName HIGHLIGHT_TOGGLE = PdfName.T; - /** flagvalue */ - public static final int FLAGS_INVISIBLE = 1; - /** flagvalue */ - public static final int FLAGS_HIDDEN = 2; - /** flagvalue */ - public static final int FLAGS_PRINT = 4; - /** flagvalue */ - public static final int FLAGS_NOZOOM = 8; - /** flagvalue */ - public static final int FLAGS_NOROTATE = 16; - /** flagvalue */ - public static final int FLAGS_NOVIEW = 32; - /** flagvalue */ - public static final int FLAGS_READONLY = 64; - /** flagvalue */ - public static final int FLAGS_LOCKED = 128; - /** flagvalue */ - public static final int FLAGS_TOGGLENOVIEW = 256; - /** appearance attributename */ - public static final PdfName APPEARANCE_NORMAL = PdfName.N; - /** appearance attributename */ - public static final PdfName APPEARANCE_ROLLOVER = PdfName.R; - /** appearance attributename */ - public static final PdfName APPEARANCE_DOWN = PdfName.D; - /** attributevalue */ - public static final PdfName AA_ENTER = PdfName.E; - /** attributevalue */ - public static final PdfName AA_EXIT = PdfName.X; - /** attributevalue */ - public static final PdfName AA_DOWN = PdfName.D; - /** attributevalue */ - public static final PdfName AA_UP = PdfName.U; - /** attributevalue */ - public static final PdfName AA_FOCUS = PdfName.FO; - /** attributevalue */ - public static final PdfName AA_BLUR = PdfName.BL; - /** attributevalue */ - public static final PdfName AA_JS_KEY = PdfName.K; - /** attributevalue */ - public static final PdfName AA_JS_FORMAT = PdfName.F; - /** attributevalue */ - public static final PdfName AA_JS_CHANGE = PdfName.V; - /** attributevalue */ - public static final PdfName AA_JS_OTHER_CHANGE = PdfName.C; - /** attributevalue */ - public static final int MARKUP_HIGHLIGHT = 0; - /** attributevalue */ - public static final int MARKUP_UNDERLINE = 1; - /** attributevalue */ - public static final int MARKUP_STRIKEOUT = 2; - - protected PdfWriter writer; - protected PdfIndirectReference reference; - protected HashMap templates; - protected boolean form = false; - protected boolean annotation = true; - - /** Holds value of property used. */ - protected boolean used = false; - - /** Holds value of property placeInPage. */ - private int placeInPage = -1; - - // constructors - public PdfAnnotation(PdfWriter writer, Rectangle rect) { - this.writer = writer; - if (rect != null) - put(PdfName.RECT, new PdfRectangle(rect)); - } - -/** - * Constructs a new PdfAnnotation of subtype text. - * @param writer - * @param llx - * @param lly - * @param urx - * @param ury - * @param title - * @param content - */ - - PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfString title, PdfString content) { - this.writer = writer; - put(PdfName.SUBTYPE, PdfName.TEXT); - put(PdfName.T, title); - put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury)); - put(PdfName.CONTENTS, content); - } - -/** - * Constructs a new PdfAnnotation of subtype link (Action). - * @param writer - * @param llx - * @param lly - * @param urx - * @param ury - * @param action - */ - - public PdfAnnotation(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) { - this.writer = writer; - put(PdfName.SUBTYPE, PdfName.LINK); - put(PdfName.RECT, new PdfRectangle(llx, lly, urx, ury)); - put(PdfName.A, action); - put(PdfName.BORDER, new PdfBorderArray(0, 0, 0)); - put(PdfName.C, new PdfColor(0x00, 0x00, 0xFF)); - } - - /** - * Creates a screen PdfAnnotation - * @param writer - * @param rect - * @param clipTitle - * @param fs - * @param mimeType - * @param playOnDisplay - * @return a screen PdfAnnotation - * @throws IOException - */ - public static PdfAnnotation createScreen(PdfWriter writer, Rectangle rect, String clipTitle, PdfFileSpecification fs, - String mimeType, boolean playOnDisplay) throws IOException { - PdfAnnotation ann = new PdfAnnotation(writer, rect); - ann.put(PdfName.SUBTYPE, PdfName.SCREEN); - ann.put (PdfName.F, new PdfNumber(FLAGS_PRINT)); - ann.put(PdfName.TYPE, PdfName.ANNOT); - ann.setPage(); - PdfIndirectReference ref = ann.getIndirectReference(); - PdfAction action = PdfAction.rendition(clipTitle,fs,mimeType, ref); - PdfIndirectReference actionRef = writer.addToBody(action).getIndirectReference(); - // for play on display add trigger event - if (playOnDisplay) - { - PdfDictionary aa = new PdfDictionary(); - aa.put(new PdfName("PV"), actionRef); - ann.put(PdfName.AA, aa); - } - ann.put(PdfName.A, actionRef); - return ann; - } - - public PdfIndirectReference getIndirectReference() { - if (reference == null) { - reference = writer.getPdfIndirectReference(); - } - return reference; - } - - /** - * @param writer - * @param rect - * @param title - * @param contents - * @param open - * @param icon - * @return a PdfAnnotation - */ - public static PdfAnnotation createText(PdfWriter writer, Rectangle rect, String title, String contents, boolean open, String icon) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.TEXT); - if (title != null) - annot.put(PdfName.T, new PdfString(title, PdfObject.TEXT_UNICODE)); - if (contents != null) - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - if (open) - annot.put(PdfName.OPEN, PdfBoolean.PDFTRUE); - if (icon != null) { - annot.put(PdfName.NAME, new PdfName(icon)); - } - return annot; - } - - /** - * Creates a link. - * @param writer - * @param rect - * @param highlight - * @return A PdfAnnotation - */ - protected static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.LINK); - if (!highlight.equals(HIGHLIGHT_INVERT)) - annot.put(PdfName.H, highlight); - return annot; - } - - /** - * Creates an Annotation with an Action. - * @param writer - * @param rect - * @param highlight - * @param action - * @return A PdfAnnotation - */ - public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, PdfAction action) { - PdfAnnotation annot = createLink(writer, rect, highlight); - annot.putEx(PdfName.A, action); - return annot; - } - - /** - * Creates an Annotation with an local destination. - * @param writer - * @param rect - * @param highlight - * @param namedDestination - * @return A PdfAnnotation - */ - public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, String namedDestination) { - PdfAnnotation annot = createLink(writer, rect, highlight); - annot.put(PdfName.DEST, new PdfString(namedDestination)); - return annot; - } - - /** - * Creates an Annotation with a PdfDestination. - * @param writer - * @param rect - * @param highlight - * @param page - * @param dest - * @return A PdfAnnotation - */ - public static PdfAnnotation createLink(PdfWriter writer, Rectangle rect, PdfName highlight, int page, PdfDestination dest) { - PdfAnnotation annot = createLink(writer, rect, highlight); - PdfIndirectReference ref = writer.getPageReference(page); - dest.addPage(ref); - annot.put(PdfName.DEST, dest); - return annot; - } - - /** - * Add some free text to the document. - * @param writer - * @param rect - * @param contents - * @param defaultAppearance - * @return A PdfAnnotation - */ - public static PdfAnnotation createFreeText(PdfWriter writer, Rectangle rect, String contents, PdfContentByte defaultAppearance) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.FREETEXT); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - annot.setDefaultAppearanceString(defaultAppearance); - return annot; - } - - /** - * Adds a line to the document. Move over the line and a tooltip is shown. - * @param writer - * @param rect - * @param contents - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @return A PdfAnnotation - */ - public static PdfAnnotation createLine(PdfWriter writer, Rectangle rect, String contents, float x1, float y1, float x2, float y2) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.LINE); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - PdfArray array = new PdfArray(new PdfNumber(x1)); - array.add(new PdfNumber(y1)); - array.add(new PdfNumber(x2)); - array.add(new PdfNumber(y2)); - annot.put(PdfName.L, array); - return annot; - } - - /** - * Adds a circle or a square that shows a tooltip when you pass over it. - * @param writer - * @param rect - * @param contents The tooltip - * @param square true if you want a square, false if you want a circle - * @return A PdfAnnotation - */ - public static PdfAnnotation createSquareCircle(PdfWriter writer, Rectangle rect, String contents, boolean square) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - if (square) - annot.put(PdfName.SUBTYPE, PdfName.SQUARE); - else - annot.put(PdfName.SUBTYPE, PdfName.CIRCLE); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - return annot; - } - - public static PdfAnnotation createMarkup(PdfWriter writer, Rectangle rect, String contents, int type, float quadPoints[]) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - PdfName name = PdfName.HIGHLIGHT; - switch (type) { - case MARKUP_UNDERLINE: - name = PdfName.UNDERLINE; - break; - case MARKUP_STRIKEOUT: - name = PdfName.STRIKEOUT; - break; - } - annot.put(PdfName.SUBTYPE, name); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - PdfArray array = new PdfArray(); - for (int k = 0; k < quadPoints.length; ++k) - array.add(new PdfNumber(quadPoints[k])); - annot.put(PdfName.QUADPOINTS, array); - return annot; - } - - /** - * Adds a Stamp to your document. Move over the stamp and a tooltip is shown - * @param writer - * @param rect - * @param contents - * @param name - * @return A PdfAnnotation - */ - public static PdfAnnotation createStamp(PdfWriter writer, Rectangle rect, String contents, String name) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.STAMP); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - annot.put(PdfName.NAME, new PdfName(name)); - return annot; - } - - public static PdfAnnotation createInk(PdfWriter writer, Rectangle rect, String contents, float inkList[][]) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.INK); - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - PdfArray outer = new PdfArray(); - for (int k = 0; k < inkList.length; ++k) { - PdfArray inner = new PdfArray(); - float deep[] = inkList[k]; - for (int j = 0; j < deep.length; ++j) - inner.add(new PdfNumber(deep[j])); - outer.add(inner); - } - annot.put(PdfName.INKLIST, outer); - return annot; - } - - /** Creates a file attachment annotation. - * @param writer the PdfWriter - * @param rect the dimensions in the page of the annotation - * @param contents the file description - * @param fileStore an array with the file. If it's null - * the file will be read from the disk - * @param file the path to the file. It will only be used if - * fileStore is not null - * @param fileDisplay the actual file name stored in the pdf - * @throws IOException on error - * @return the annotation - */ - public static PdfAnnotation createFileAttachment(PdfWriter writer, Rectangle rect, String contents, byte fileStore[], String file, String fileDisplay) throws IOException { - return createFileAttachment(writer, rect, contents, PdfFileSpecification.fileEmbedded(writer, file, fileDisplay, fileStore)); - } - - /** Creates a file attachment annotation - * @param writer - * @param rect - * @param contents - * @param fs - * @return the annotation - * @throws IOException - */ - public static PdfAnnotation createFileAttachment(PdfWriter writer, Rectangle rect, String contents, PdfFileSpecification fs) throws IOException { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.FILEATTACHMENT); - if (contents != null) - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - annot.put(PdfName.FS, fs.getReference()); - return annot; - } - - /** - * Adds a popup to your document. - * @param writer - * @param rect - * @param contents - * @param open - * @return A PdfAnnotation - */ - public static PdfAnnotation createPopup(PdfWriter writer, Rectangle rect, String contents, boolean open) { - PdfAnnotation annot = new PdfAnnotation(writer, rect); - annot.put(PdfName.SUBTYPE, PdfName.POPUP); - if (contents != null) - annot.put(PdfName.CONTENTS, new PdfString(contents, PdfObject.TEXT_UNICODE)); - if (open) - annot.put(PdfName.OPEN, PdfBoolean.PDFTRUE); - return annot; - } - - public void setDefaultAppearanceString(PdfContentByte cb) { - byte b[] = cb.getInternalBuffer().toByteArray(); - int len = b.length; - for (int k = 0; k < len; ++k) { - if (b[k] == '\n') - b[k] = 32; - } - put(PdfName.DA, new PdfString(b)); - } - - public void setFlags(int flags) { - if (flags == 0) - remove(PdfName.F); - else - put(PdfName.F, new PdfNumber(flags)); - } - - public void setBorder(PdfBorderArray border) { - putDel(PdfName.BORDER, border); - } - - public void setBorderStyle(PdfBorderDictionary border) { - putDel(PdfName.BS, border); - } - - /** - * Sets the annotation's highlighting mode. The values can be - * HIGHLIGHT_NONE, HIGHLIGHT_INVERT, - * HIGHLIGHT_OUTLINE and HIGHLIGHT_PUSH; - * @param highlight the annotation's highlighting mode - */ - public void setHighlighting(PdfName highlight) { - if (highlight.equals(HIGHLIGHT_INVERT)) - remove(PdfName.H); - else - put(PdfName.H, highlight); - } - - public void setAppearance(PdfName ap, PdfTemplate template) { - PdfDictionary dic = (PdfDictionary)get(PdfName.AP); - if (dic == null) - dic = new PdfDictionary(); - dic.put(ap, template.getIndirectReference()); - put(PdfName.AP, dic); - if (!form) - return; - if (templates == null) - templates = new HashMap(); - templates.put(template, null); - } - - public void setAppearance(PdfName ap, String state, PdfTemplate template) { - PdfDictionary dicAp = (PdfDictionary)get(PdfName.AP); - if (dicAp == null) - dicAp = new PdfDictionary(); - - PdfDictionary dic; - PdfObject obj = dicAp.get(ap); - if (obj != null && obj.isDictionary()) - dic = (PdfDictionary)obj; - else - dic = new PdfDictionary(); - dic.put(new PdfName(state), template.getIndirectReference()); - dicAp.put(ap, dic); - put(PdfName.AP, dicAp); - if (!form) - return; - if (templates == null) - templates = new HashMap(); - templates.put(template, null); - } - - public void setAppearanceState(String state) { - if (state == null) { - remove(PdfName.AS); - return; - } - put(PdfName.AS, new PdfName(state)); - } - - public void setColor(Color color) { - putDel(PdfName.C, new PdfColor(color)); - } - - public void setTitle(String title) { - if (title == null) { - remove(PdfName.T); - return; - } - put(PdfName.T, new PdfString(title, PdfObject.TEXT_UNICODE)); - } - - public void setPopup(PdfAnnotation popup) { - put(PdfName.POPUP, popup.getIndirectReference()); - popup.put(PdfName.PARENT, getIndirectReference()); - } - - public void setAction(PdfAction action) { - putDel(PdfName.A, action); - } - - public void setAdditionalActions(PdfName key, PdfAction action) { - PdfDictionary dic; - PdfObject obj = get(PdfName.AA); - if (obj != null && obj.isDictionary()) - dic = (PdfDictionary)obj; - else - dic = new PdfDictionary(); - dic.put(key, action); - put(PdfName.AA, dic); - } - - /** Getter for property used. - * @return Value of property used. - */ - public boolean isUsed() { - return used; - } - - /** Setter for property used. - */ - void setUsed() { - used = true; - } - - HashMap getTemplates() { - return templates; - } - - /** Getter for property form. - * @return Value of property form. - */ - public boolean isForm() { - return form; - } - - /** Getter for property annotation. - * @return Value of property annotation. - */ - public boolean isAnnotation() { - return annotation; - } - - public void setPage(int page) { - put(PdfName.P, writer.getPageReference(page)); - } - - public void setPage() { - put(PdfName.P, writer.getCurrentPage()); - } - - /** Getter for property placeInPage. - * @return Value of property placeInPage. - */ - public int getPlaceInPage() { - return placeInPage; - } - - /** Places the annotation in a specified page that must be greater - * or equal to the current one. With PdfStamper the page - * can be any. The first page is 1. - * @param placeInPage New value of property placeInPage. - */ - public void setPlaceInPage(int placeInPage) { - this.placeInPage = placeInPage; - } - - public void setRotate(int v) { - put(PdfName.ROTATE, new PdfNumber(v)); - } - - PdfDictionary getMK() { - PdfDictionary mk = (PdfDictionary)get(PdfName.MK); - if (mk == null) { - mk = new PdfDictionary(); - put(PdfName.MK, mk); - } - return mk; - } - - public void setMKRotation(int rotation) { - getMK().put(PdfName.R, new PdfNumber(rotation)); - } - - public static PdfArray getMKColor(Color color) { - PdfArray array = new PdfArray(); - int type = ExtendedColor.getType(color); - switch (type) { - case ExtendedColor.TYPE_GRAY: { - array.add(new PdfNumber(((GrayColor)color).getGray())); - break; - } - case ExtendedColor.TYPE_CMYK: { - CMYKColor cmyk = (CMYKColor)color; - array.add(new PdfNumber(cmyk.getCyan())); - array.add(new PdfNumber(cmyk.getMagenta())); - array.add(new PdfNumber(cmyk.getYellow())); - array.add(new PdfNumber(cmyk.getBlack())); - break; - } - case ExtendedColor.TYPE_SEPARATION: - case ExtendedColor.TYPE_PATTERN: - case ExtendedColor.TYPE_SHADING: - throw new RuntimeException("Separations, patterns and shadings are not allowed in MK dictionary."); - default: - array.add(new PdfNumber(color.getRed() / 255f)); - array.add(new PdfNumber(color.getGreen() / 255f)); - array.add(new PdfNumber(color.getBlue() / 255f)); - } - return array; - } - - public void setMKBorderColor(Color color) { - if (color == null) - getMK().remove(PdfName.BC); - else - getMK().put(PdfName.BC, getMKColor(color)); - } - - public void setMKBackgroundColor(Color color) { - if (color == null) - getMK().remove(PdfName.BG); - else - getMK().put(PdfName.BG, getMKColor(color)); - } - - public void setMKNormalCaption(String caption) { - getMK().put(PdfName.CA, new PdfString(caption, PdfObject.TEXT_UNICODE)); - } - - public void setMKRolloverCaption(String caption) { - getMK().put(PdfName.RC, new PdfString(caption, PdfObject.TEXT_UNICODE)); - } - - public void setMKAlternateCaption(String caption) { - getMK().put(PdfName.AC, new PdfString(caption, PdfObject.TEXT_UNICODE)); - } - - public void setMKNormalIcon(PdfTemplate template) { - getMK().put(PdfName.I, template.getIndirectReference()); - } - - public void setMKRolloverIcon(PdfTemplate template) { - getMK().put(PdfName.RI, template.getIndirectReference()); - } - - public void setMKAlternateIcon(PdfTemplate template) { - getMK().put(PdfName.IX, template.getIndirectReference()); - } - - public void setMKIconFit(PdfName scale, PdfName scalingType, float leftoverLeft, float leftoverBottom, boolean fitInBounds) { - PdfDictionary dic = new PdfDictionary(); - if (!scale.equals(PdfName.A)) - dic.put(PdfName.SW, scale); - if (!scalingType.equals(PdfName.P)) - dic.put(PdfName.S, scalingType); - if (leftoverLeft != 0.5f || leftoverBottom != 0.5f) { - PdfArray array = new PdfArray(new PdfNumber(leftoverLeft)); - array.add(new PdfNumber(leftoverBottom)); - dic.put(PdfName.A, array); - } - if (fitInBounds) - dic.put(PdfName.FB, PdfBoolean.PDFTRUE); - getMK().put(PdfName.IF, dic); - } - - public void setMKTextPosition(int tp) { - getMK().put(PdfName.TP, new PdfNumber(tp)); - } - - /** - * Sets the layer this annotation belongs to. - * @param layer the layer this annotation belongs to - */ - public void setLayer(PdfOCG layer) { - put(PdfName.OC, layer.getRef()); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfAppearance.java b/src/main/java/com/lowagie/text/pdf/PdfAppearance.java deleted file mode 100644 index 2189762..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfAppearance.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.Rectangle; -import java.util.HashMap; - -/** - * Implements the appearance stream to be used with form fields.. - */ - -public class PdfAppearance extends PdfTemplate { - - public static final HashMap stdFieldFontNames = new HashMap(); - static { - stdFieldFontNames.put("Courier-BoldOblique", new PdfName("CoBO")); - stdFieldFontNames.put("Courier-Bold", new PdfName("CoBo")); - stdFieldFontNames.put("Courier-Oblique", new PdfName("CoOb")); - stdFieldFontNames.put("Courier", new PdfName("Cour")); - stdFieldFontNames.put("Helvetica-BoldOblique", new PdfName("HeBO")); - stdFieldFontNames.put("Helvetica-Bold", new PdfName("HeBo")); - stdFieldFontNames.put("Helvetica-Oblique", new PdfName("HeOb")); - stdFieldFontNames.put("Helvetica", new PdfName("Helv")); - stdFieldFontNames.put("Symbol", new PdfName("Symb")); - stdFieldFontNames.put("Times-BoldItalic", new PdfName("TiBI")); - stdFieldFontNames.put("Times-Bold", new PdfName("TiBo")); - stdFieldFontNames.put("Times-Italic", new PdfName("TiIt")); - stdFieldFontNames.put("Times-Roman", new PdfName("TiRo")); - stdFieldFontNames.put("ZapfDingbats", new PdfName("ZaDb")); - stdFieldFontNames.put("HYSMyeongJo-Medium", new PdfName("HySm")); - stdFieldFontNames.put("HYGoThic-Medium", new PdfName("HyGo")); - stdFieldFontNames.put("HeiseiKakuGo-W5", new PdfName("KaGo")); - stdFieldFontNames.put("HeiseiMin-W3", new PdfName("KaMi")); - stdFieldFontNames.put("MHei-Medium", new PdfName("MHei")); - stdFieldFontNames.put("MSung-Light", new PdfName("MSun")); - stdFieldFontNames.put("STSong-Light", new PdfName("STSo")); - stdFieldFontNames.put("MSungStd-Light", new PdfName("MSun")); - stdFieldFontNames.put("STSongStd-Light", new PdfName("STSo")); - stdFieldFontNames.put("HYSMyeongJoStd-Medium", new PdfName("HySm")); - stdFieldFontNames.put("KozMinPro-Regular", new PdfName("KaMi")); - } - - /** - *Creates a PdfAppearance. - */ - - PdfAppearance() { - super(); - separator = ' '; - } - - PdfAppearance(PdfIndirectReference iref) { - thisReference = iref; - } - - /** - * Creates new PdfTemplate - * - * @param wr the PdfWriter - */ - - PdfAppearance(PdfWriter wr) { - super(wr); - separator = ' '; - } - - /** - * Set the font and the size for the subsequent text writing. - * - * @param bf the font - * @param size the font size in points - */ - public void setFontAndSize(BaseFont bf, float size) { - checkWriter(); - state.size = size; - if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { - state.fontDetails = new FontDetails(null, ((DocumentFont)bf).getIndirectReference(), bf); - } - else - state.fontDetails = writer.addSimple(bf); - PdfName psn = (PdfName)stdFieldFontNames.get(bf.getPostscriptFontName()); - if (psn == null) { - if (bf.isSubset() && bf.getFontType() == BaseFont.FONT_TYPE_TTUNI) - psn = state.fontDetails.getFontName(); - else { - psn = new PdfName(bf.getPostscriptFontName()); - state.fontDetails.setSubset(false); - } - } - PageResources prs = getPageResources(); -// PdfName name = state.fontDetails.getFontName(); - prs.addFont(psn, state.fontDetails.getIndirectReference()); - content.append(psn.getBytes()).append(' ').append(size).append(" Tf").append_i(separator); - } - - public PdfContentByte getDuplicate() { - PdfAppearance tpl = new PdfAppearance(); - tpl.writer = writer; - tpl.pdf = pdf; - tpl.thisReference = thisReference; - tpl.pageResources = pageResources; - tpl.bBox = new Rectangle(bBox); - tpl.group = group; - tpl.layer = layer; - if (matrix != null) { - tpl.matrix = new PdfArray(matrix); - } - tpl.separator = separator; - return tpl; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfArray.java b/src/main/java/com/lowagie/text/pdf/PdfArray.java deleted file mode 100644 index 30be4ef..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfArray.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * $Id: PdfArray.java,v 1.62 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.ListIterator; - -/** - * PdfArray is the PDF Array object. - *

- * An array is a sequence of PDF objects. An array may contain a mixture of object types. - * An array is written as a left square bracket ([), followed by a sequence of objects, - * followed by a right square bracket (]).
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.6 (page 40). - * - * @see PdfObject - */ - -public class PdfArray extends PdfObject { - - // membervariables - -/** this is the actual array of PdfObjects */ - protected ArrayList arrayList; - - // constructors - -/** - * Constructs an empty PdfArray-object. - */ - - public PdfArray() { - super(ARRAY); - arrayList = new ArrayList(); - } - -/** - * Constructs an PdfArray-object, containing 1 PdfObject. - * - * @param object a PdfObject that has to be added to the array - */ - - public PdfArray(PdfObject object) { - super(ARRAY); - arrayList = new ArrayList(); - arrayList.add(object); - } - - public PdfArray(float values[]) { - super(ARRAY); - arrayList = new ArrayList(); - add(values); - } - - public PdfArray(int values[]) { - super(ARRAY); - arrayList = new ArrayList(); - add(values); - } - -/** - * Constructs an PdfArray-object, containing all the PdfObjects in a given PdfArray. - * - * @param array a PdfArray that has to be added to the array - */ - - public PdfArray(PdfArray array) { - super(ARRAY); - arrayList = new ArrayList(array.getArrayList()); - } - - // methods overriding some methods in PdfObject - -/** - * Returns the PDF representation of this PdfArray. - * - * @return an array of bytes - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - os.write('['); - - Iterator i = arrayList.iterator(); - PdfObject object; - int type = 0; - if (i.hasNext()) { - object = (PdfObject) i.next(); - object.toPdf(writer, os); - } - while (i.hasNext()) { - object = (PdfObject) i.next(); - type = object.type(); - if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) - os.write(' '); - object.toPdf(writer, os); - } - os.write(']'); - } - - // methods concerning the ArrayList-membervalue - -/** - * Returns an ArrayList containing PdfObjects. - * - * @return an ArrayList - */ - - public ArrayList getArrayList() { - return arrayList; - } - -/** - * Returns the number of entries in the array. - * - * @return the size of the ArrayList - */ - - public int size() { - return arrayList.size(); - } - -/** - * Adds a PdfObject to the PdfArray. - * - * @param object PdfObject to add - * @return true - */ - - public boolean add(PdfObject object) { - return arrayList.add(object); - } - - public boolean add(float values[]) { - for (int k = 0; k < values.length; ++k) - arrayList.add(new PdfNumber(values[k])); - return true; - } - - public boolean add(int values[]) { - for (int k = 0; k < values.length; ++k) - arrayList.add(new PdfNumber(values[k])); - return true; - } - -/** - * Adds a PdfObject to the PdfArray. - *

- * The newly added object will be the first element in the ArrayList. - * - * @param object PdfObject to add - */ - - public void addFirst(PdfObject object) { - arrayList.add(0, object); - } - -/** - * Checks if the PdfArray already contains a certain PdfObject. - * - * @param object PdfObject to check - * @return true - */ - - public boolean contains(PdfObject object) { - return arrayList.contains(object); - } - - public ListIterator listIterator() { - return arrayList.listIterator(); - } - - public String toString() { - return arrayList.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfBoolean.java b/src/main/java/com/lowagie/text/pdf/PdfBoolean.java deleted file mode 100644 index 1bd2fc8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfBoolean.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * $Id: PdfBoolean.java,v 1.55 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfBoolean is the boolean object represented by the keywords true or false. - *

- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.2 (page 37). - * - * @see PdfObject - * @see BadPdfFormatException - */ - -public class PdfBoolean extends PdfObject { - - // static membervariables (possible values of a boolean object) - public static final PdfBoolean PDFTRUE = new PdfBoolean(true); - public static final PdfBoolean PDFFALSE = new PdfBoolean(false); -/** A possible value of PdfBoolean */ - public static final String TRUE = "true"; - -/** A possible value of PdfBoolean */ - public static final String FALSE = "false"; - - // membervariables - -/** the boolean value of this object */ - private boolean value; - - // constructors - -/** - * Constructs a PdfBoolean-object. - * - * @param value the value of the new PdfObject - */ - - public PdfBoolean(boolean value) { - super(BOOLEAN); - if (value) { - setContent(TRUE); - } - else { - setContent(FALSE); - } - this.value = value; - } - -/** - * Constructs a PdfBoolean-object. - * - * @param value the value of the new PdfObject, represented as a String - * - * @throws BadPdfFormatException thrown if the value isn't 'true' or 'false' - */ - - public PdfBoolean(String value) throws BadPdfFormatException { - super(BOOLEAN, value); - if (value.equals(TRUE)) { - this.value = true; - } - else if (value.equals(FALSE)) { - this.value = false; - } - else { - throw new BadPdfFormatException("The value has to be 'true' of 'false', instead of '" + value + "'."); - } - } - - // methods returning the value of this object - -/** - * Returns the primitive value of the PdfBoolean-object. - * - * @return the actual value of the object. - */ - - public boolean booleanValue() { - return value; - } - - public String toString() { - return String.valueOf(value); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfBorderArray.java b/src/main/java/com/lowagie/text/pdf/PdfBorderArray.java deleted file mode 100644 index 170bb4c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfBorderArray.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * $Id: PdfBorderArray.java,v 1.55 2005/05/04 14:32:24 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * A PdfBorderArray defines the border of a PdfAnnotation. - * - * @see PdfArray - */ - -public class PdfBorderArray extends PdfArray { - - // constructors - -/** - * Constructs a new PdfBorderArray. - */ - - public PdfBorderArray(float hRadius, float vRadius, float width) { - this(hRadius, vRadius, width, null); - } - -/** - * Constructs a new PdfBorderArray. - */ - - public PdfBorderArray(float hRadius, float vRadius, float width, PdfDashPattern dash) { - super(new PdfNumber(hRadius)); - add(new PdfNumber(vRadius)); - add(new PdfNumber(width)); - if (dash != null) - add(dash); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfBorderDictionary.java b/src/main/java/com/lowagie/text/pdf/PdfBorderDictionary.java deleted file mode 100644 index 687b9b0..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfBorderDictionary.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * $Id: PdfBorderDictionary.java,v 1.54 2005/05/04 14:31:49 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * A PdfBorderDictionary define the appearance of a Border (Annotations). - * - * @see PdfDictionary - */ - -public class PdfBorderDictionary extends PdfDictionary { - - public static final int STYLE_SOLID = 0; - public static final int STYLE_DASHED = 1; - public static final int STYLE_BEVELED = 2; - public static final int STYLE_INSET = 3; - public static final int STYLE_UNDERLINE = 4; - // constructors - -/** - * Constructs a PdfBorderDictionary. - */ - - public PdfBorderDictionary(float borderWidth, int borderStyle, PdfDashPattern dashes) { - put(PdfName.W, new PdfNumber(borderWidth)); - switch (borderStyle) { - case STYLE_SOLID: - put(PdfName.S, PdfName.S); - break; - case STYLE_DASHED: - if (dashes != null) - put(PdfName.D, dashes); - put(PdfName.S, PdfName.D); - break; - case STYLE_BEVELED: - put(PdfName.S, PdfName.B); - break; - case STYLE_INSET: - put(PdfName.S, PdfName.I); - break; - case STYLE_UNDERLINE: - put(PdfName.S, PdfName.U); - break; - default: - throw new IllegalArgumentException("Invalid border style."); - } - } - - public PdfBorderDictionary(float borderWidth, int borderStyle) { - this(borderWidth, borderStyle, null); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfCell.java b/src/main/java/com/lowagie/text/pdf/PdfCell.java deleted file mode 100644 index 909b884..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfCell.java +++ /dev/null @@ -1,890 +0,0 @@ -/* - * $Id: PdfCell.java,v 1.98 2005/11/01 12:27:04 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.Iterator; - -import com.lowagie.text.*; - -/** - * A PdfCell is the PDF translation of a Cell. - *

- * A PdfCell is an ArrayList of PdfLines. - *

- * When using variable borders ({@link com.lowagie.text.Rectangle#isUseVariableBorders isUseVariableBorders()} == true), - * the borders are drawn completely inside the cell Rectangle - * so that adjacent cell borders will not overlap. - * Otherwise, the borders are drawn on top of the edges of the - * cell Rectangle and will overlap the borders of adjacent - * cells. - * - * @see com.lowagie.text.Rectangle - * @see com.lowagie.text.Cell - * @see PdfLine - * @see PdfTable - */ - -public class PdfCell extends Rectangle { - - // membervariables - - /** - * These are the PdfLines in the Cell. - */ - private ArrayList lines; - - /** - * These are the PdfLines in the Cell. - */ - private PdfLine line; - - /** - * These are the Images in the Cell. - */ - private ArrayList images; - - /** - * This is the leading of the lines. - */ - private float leading; - - /** - * This is the number of the row the cell is in. - */ - private int rownumber; - - /** - * This is the rowspan of the cell. - */ - private int rowspan; - - /** - * This is the cellspacing of the cell. - */ - private float cellspacing; - - /** - * This is the cellpadding of the cell. - */ - private float cellpadding; - - /** - * Indicates if this cell belongs to the header of a PdfTable - */ - private boolean header = false; - - /** - * This is the total height of the content of the cell. Note that the actual cell - * height may be larger due to another cell on the row * - */ - private float contentHeight = 0.0f; - - /** - * Indicates that the largest ascender height should be used to - * determine the height of the first line. Setting this to true can help - * with vertical alignment problems. */ - private boolean useAscender; - - /** - * Indicates that the largest descender height should be added to the height of - * the last line (so characters like y don't dip into the border). */ - private boolean useDescender; - - /** - * Adjusts the cell contents to compensate for border widths. - */ - private boolean useBorderPadding; - - private int verticalAlignment; - - private PdfLine firstLine; - private PdfLine lastLine; - - // constructors - - /** - * Constructs a PdfCell-object. - * - * @param cell the original Cell - * @param rownumber the number of the Row the Cell was in. - * @param left the left border of the PdfCell - * @param right the right border of the PdfCell - * @param top the top border of the PdfCell - * @param cellspacing the cellspacing of the Table - * @param cellpadding the cellpadding of the Table - */ - - public PdfCell(Cell cell, int rownumber, float left, float right, float top, float cellspacing, float cellpadding) { - // constructs a Rectangle (the bottomvalue will be changed afterwards) - super(left, top, right, top); - // copying the other Rectangle attributes from class Cell - cloneNonPositionParameters(cell); - this.cellpadding = cellpadding; - this.cellspacing = cellspacing; - this.verticalAlignment = cell.verticalAlignment(); - this.useAscender = cell.isUseAscender(); - this.useDescender = cell.isUseDescender(); - this.useBorderPadding = cell.isUseBorderPadding(); - - // initialisation of some parameters - PdfChunk chunk; - Element element; - PdfChunk overflow; - lines = new ArrayList(); - images = new ArrayList(); - leading = cell.leading(); - int alignment = cell.horizontalAlignment(); - left += cellspacing + cellpadding; - right -= cellspacing + cellpadding; - - left += getBorderWidthInside(LEFT); - right -= getBorderWidthInside(RIGHT); - - - contentHeight = 0; - - rowspan = cell.rowspan(); - - ArrayList allActions; - int aCounter; - // we loop over all the elements of the cell - for (Iterator i = cell.getElements(); i.hasNext();) { - element = (Element) i.next(); - switch (element.type()) { - case Element.JPEG: - case Element.IMGRAW: - case Element.IMGTEMPLATE: - addImage((Image) element, left, right, 0.4f * leading, alignment); // - break; - // if the element is a list - case Element.LIST: - if (line != null && line.size() > 0) { - line.resetAlignment(); - addLine(line); - } - allActions = new ArrayList(); - processActions(element, null, allActions); - aCounter = 0; - ListItem item; - // we loop over all the listitems - for (Iterator items = ((List) element).getItems().iterator(); items.hasNext();) { - item = (ListItem) items.next(); - line = new PdfLine(left + item.indentationLeft(), right, alignment, item.leading()); - line.setListItem(item); - for (Iterator j = item.getChunks().iterator(); j.hasNext();) { - chunk = new PdfChunk((Chunk) j.next(), (PdfAction) (allActions.get(aCounter++))); - while ((overflow = line.add(chunk)) != null) { - addLine(line); - line = new PdfLine(left + item.indentationLeft(), right, alignment, item.leading()); - chunk = overflow; - } - line.resetAlignment(); - addLine(line); - line = new PdfLine(left + item.indentationLeft(), right, alignment, leading); - } - } - line = new PdfLine(left, right, alignment, leading); - break; - // if the element is something else - default: - allActions = new ArrayList(); - processActions(element, null, allActions); - aCounter = 0; - - float currentLineLeading = leading; - float currentLeft = left; - float currentRight = right; - if (element instanceof Phrase) { - currentLineLeading = ((Phrase) element).leading(); - } - if (element instanceof Paragraph) { - Paragraph p = (Paragraph) element; - currentLeft += p.indentationLeft(); - currentRight -= p.indentationRight(); - } - if (line == null) { - line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); - } - // we loop over the chunks - ArrayList chunks = element.getChunks(); - if (chunks.isEmpty()) { - addLine(line); // add empty line - all cells need some lines even if they are empty - line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); - } - else { - for (Iterator j = chunks.iterator(); j.hasNext();) { - Chunk c = (Chunk) j.next(); - chunk = new PdfChunk(c, (PdfAction) (allActions.get(aCounter++))); - while ((overflow = line.add(chunk)) != null) { - addLine(line); - line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading); - chunk = overflow; - } - } - } - // if the element is a paragraph, section or chapter, we reset the alignment and add the line - switch (element.type()) { - case Element.PARAGRAPH: - case Element.SECTION: - case Element.CHAPTER: - line.resetAlignment(); - flushCurrentLine(); - } - } - } - flushCurrentLine(); - if (lines.size() > cell.getMaxLines()) { - while (lines.size() > cell.getMaxLines()) { - removeLine(lines.size() - 1); - } - if (cell.getMaxLines() > 0) { - String more = cell.getShowTruncation(); - if (more != null && more.length() > 0) { - // Denote that the content has been truncated - lastLine = (PdfLine) lines.get(lines.size() - 1); - if (lastLine.size() >= 0) { - PdfChunk lastChunk = lastLine.getChunk(lastLine.size() - 1); - float moreWidth = new PdfChunk(more, lastChunk).width(); - while (lastChunk.toString().length() > 0 && lastChunk.width() + moreWidth > right - left) { - // Remove characters to leave room for the 'more' indicator - lastChunk.setValue(lastChunk.toString().substring(0, lastChunk.length() - 1)); - } - lastChunk.setValue(lastChunk.toString() + more); - } else { - lastLine.add(new PdfChunk(new Chunk(more), null)); - } - } - } - } - // we set some additional parameters - if (useDescender && lastLine != null) { - contentHeight -= lastLine.getDescender(); - } - - // adjust first line height so that it touches the top - if (lines.size() > 0) { - firstLine = (PdfLine) lines.get(0); - float firstLineRealHeight = firstLineRealHeight(); - contentHeight -= firstLine.height(); - firstLine.height = firstLineRealHeight; - contentHeight += firstLineRealHeight; - } - - float newBottom = top - contentHeight - (2f * cellpadding()) - (2f * cellspacing()); - newBottom -= getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM); - setBottom(newBottom); - - this.rownumber = rownumber; - } - - - - - // overriding of the Rectangle methods - - - /** - * Sets the bottom of the Rectangle and determines the proper {link #verticalOffset} - * to appropriately align the contents vertically. - * @param value - */ - public void setBottom(float value) { - super.setBottom(value); - float firstLineRealHeight = firstLineRealHeight(); - - float totalHeight = ury - value; // can't use top (already compensates for cellspacing) - float nonContentHeight = (cellpadding() * 2f) + (cellspacing() * 2f); - nonContentHeight += getBorderWidthInside(TOP) + getBorderWidthInside(BOTTOM); - - float interiorHeight = totalHeight - nonContentHeight; - float extraHeight = 0.0f; - - switch (verticalAlignment) { - case Element.ALIGN_BOTTOM: - extraHeight = interiorHeight - contentHeight; - break; - case Element.ALIGN_MIDDLE: - extraHeight = (interiorHeight - contentHeight) / 2.0f; - break; - default: // ALIGN_TOP - extraHeight = 0f; - } - - extraHeight += cellpadding() + cellspacing(); - extraHeight += getBorderWidthInside(TOP); - if (firstLine != null) { - firstLine.height = firstLineRealHeight + extraHeight; - } - } - - /** - * Returns the lower left x-coordinaat. - * - * @return the lower left x-coordinaat - */ - - public float left() { - return super.left(cellspacing); - } - - /** - * Returns the upper right x-coordinate. - * - * @return the upper right x-coordinate - */ - - public float right() { - return super.right(cellspacing); - } - - /** - * Returns the upper right y-coordinate. - * - * @return the upper right y-coordinate - */ - - public float top() { - return super.top(cellspacing); - } - - /** - * Returns the lower left y-coordinate. - * - * @return the lower left y-coordinate - */ - - public float bottom() { - return super.bottom(cellspacing); - } - - // methods - - private void addLine(PdfLine line) { - lines.add(line); - contentHeight += line.height(); - lastLine = line; - this.line = null; - } - - private PdfLine removeLine(int index) { - PdfLine oldLine = (PdfLine) lines.remove(index); - contentHeight -= oldLine.height(); - if (index == 0) { - if (lines.size() > 0) { - firstLine = (PdfLine) lines.get(0); - float firstLineRealHeight = firstLineRealHeight(); - contentHeight -= firstLine.height(); - firstLine.height = firstLineRealHeight; - contentHeight += firstLineRealHeight; - } - } - return oldLine; - } - - private void flushCurrentLine() { - if (line != null && line.size() > 0) { - addLine(line); - } - } - - /** - * Calculates what the height of the first line should be so that the content will be - * flush with the top. For text, this is the height of the ascender. For an image, - * it is the actual height of the image. - * @return the real height of the first line - */ - private float firstLineRealHeight() { - float firstLineRealHeight = 0f; - if (firstLine != null) { - PdfChunk chunk = firstLine.getChunk(0); - if (chunk != null) { - Image image = chunk.getImage(); - if (image != null) { - firstLineRealHeight = firstLine.getChunk(0).getImage().scaledHeight(); - } else { - firstLineRealHeight = useAscender ? firstLine.getAscender() : leading; - } - } - } - return firstLineRealHeight; - } - - /** - * Gets the amount of the border for the specified side that is inside the Rectangle. - * For non-variable width borders this is only 1/2 the border width on that side. This - * always returns 0 if {@link #useBorderPadding} is false; - * @param side the side to check. One of the side constants in {@link com.lowagie.text.Rectangle} - * @return the borderwidth inside the cell - */ - private float getBorderWidthInside(int side) { - float width = 0f; - if (useBorderPadding) { - switch (side) { - case Rectangle.LEFT: - width = getBorderWidthLeft(); - break; - - case Rectangle.RIGHT: - width = getBorderWidthRight(); - break; - - case Rectangle.TOP: - width = getBorderWidthTop(); - break; - - default: // default and BOTTOM - width = getBorderWidthBottom(); - break; - } - // non-variable (original style) borders overlap the rectangle (only 1/2 counts) - if (!isUseVariableBorders()) { - width = width / 2f; - } - } - return width; - } - - - /** - * Adds an image to this Cell. - * - * @param i the image to add - * @param left the left border - * @param right the right border - * @param extraHeight extra height to add above image - * @param alignment horizontal alignment (constant from Element class) - * @return the height of the image - */ - - private float addImage(Image i, float left, float right, float extraHeight, int alignment) { - Image image = Image.getInstance(i); - if (image.scaledWidth() > right - left) { - image.scaleToFit(right - left, Float.MAX_VALUE); - } - flushCurrentLine(); - if (line == null) { - line = new PdfLine(left, right, alignment, leading); - } - PdfLine imageLine = line; - - // left and right in chunk is relative to the start of the line - right = right - left; - left = 0f; - - if ((image.alignment() & Image.RIGHT) == Image.RIGHT) { // fix Uwe Zimmerman - left = right - image.scaledWidth(); - } else if ((image.alignment() & Image.MIDDLE) == Image.MIDDLE) { - left = left + ((right - left - image.scaledWidth()) / 2f); - } - Chunk imageChunk = new Chunk(image, left, 0); - imageLine.add(new PdfChunk(imageChunk, null)); - addLine(imageLine); - return imageLine.height(); - } - - /** - * Gets the lines of a cell that can be drawn between certain limits. - *

- * Remark: all the lines that can be drawn are removed from the object! - * - * @param top the top of the part of the table that can be drawn - * @param bottom the bottom of the part of the table that can be drawn - * @return an ArrayList of PdfLines - */ - - public ArrayList getLines(float top, float bottom) { - float lineHeight; - float currentPosition = Math.min(top(), top); - setTop(currentPosition + cellspacing); - ArrayList result = new ArrayList(); - - // if the bottom of the page is higher than the top of the cell: do nothing - if (top() < bottom) { - return result; - } - - // we loop over the lines - int size = lines.size(); - boolean aboveBottom = true; - for (int i = 0; i < size && aboveBottom; i++) { - line = (PdfLine) lines.get(i); - lineHeight = line.height(); - currentPosition -= lineHeight; - // if the currentPosition is higher than the bottom, we add the line to the result - if (currentPosition > (bottom + cellpadding + getBorderWidthInside(BOTTOM))) { // bugfix by Tom Ring and Veerendra Namineni - result.add(line); - } else { - aboveBottom = false; - } - } - // if the bottom of the cell is higher than the bottom of the page, the cell is written, so we can remove all lines - float difference = 0f; - if (!header) { - if (aboveBottom) { - lines = new ArrayList(); - contentHeight = 0f; - } else { - size = result.size(); - for (int i = 0; i < size; i++) { - line = removeLine(0); - difference += line.height(); - } - } - } - if (difference > 0) { - Image image; - for (Iterator i = images.iterator(); i.hasNext();) { - image = (Image) i.next(); - image.setAbsolutePosition(image.absoluteX(), image.absoluteY() - difference - leading); - } - } - return result; - } - - /** - * Gets the images of a cell that can be drawn between certain limits. - *

- * Remark: all the lines that can be drawn are removed from the object! - * - * @param top the top of the part of the table that can be drawn - * @param bottom the bottom of the part of the table that can be drawn - * @return an ArrayList of Images - */ - - public ArrayList getImages(float top, float bottom) { - - // if the bottom of the page is higher than the top of the cell: do nothing - if (top() < bottom) { - return new ArrayList(); - } - top = Math.min(top(), top); - // initialisations - Image image; - float height; - ArrayList result = new ArrayList(); - // we loop over the images - for (Iterator i = images.iterator(); i.hasNext() && !header;) { - image = (Image) i.next(); - height = image.absoluteY(); - // if the currentPosition is higher than the bottom, we add the line to the result - if (top - height > (bottom + cellpadding)) { - image.setAbsolutePosition(image.absoluteX(), top - height); - result.add(image); - i.remove(); - } - } - return result; - } - - /** - * Checks if this cell belongs to the header of a PdfTable. - * - * @return void - */ - - boolean isHeader() { - return header; - } - - /** - * Indicates that this cell belongs to the header of a PdfTable. - */ - - void setHeader() { - header = true; - } - - /** - * Checks if the cell may be removed. - *

- * Headers may allways be removed, even if they are drawn only partially: - * they will be repeated on each following page anyway! - * - * @return true if all the lines are allready drawn; false otherwise. - */ - - boolean mayBeRemoved() { - return (header || (lines.size() == 0 && images.size() == 0)); - } - - /** - * Returns the number of lines in the cell. - * - * @return a value - */ - - public int size() { - return lines.size(); - } - - /** - * Returns the number of lines in the cell that are not empty. - * - * @return a value - */ - - public int remainingLines() { - if (lines.size() == 0) return 0; - int result = 0; - int size = lines.size(); - PdfLine line; - for (int i = 0; i < size; i++) { - line = (PdfLine) lines.get(i); - if (line.size() > 0) result++; - } - return result; - } - - /** - * Returns the height needed to draw the remaining text. - * - * @return a height - */ - - public float remainingHeight() { - float result = 0f; - for (Iterator i = images.iterator(); i.hasNext();) { - Image image = (Image) i.next(); - result += image.scaledHeight(); - } - return remainingLines() * leading + 2 * cellpadding + cellspacing + result + leading / 2.5f; - } - - // methods to retrieve membervariables - - /** - * Gets the leading of a cell. - * - * @return the leading of the lines is the cell. - */ - - public float leading() { - return leading; - } - - /** - * Gets the number of the row this cell is in.. - * - * @return a number - */ - - public int rownumber() { - return rownumber; - } - - /** - * Gets the rowspan of a cell. - * - * @return the rowspan of the cell - */ - - public int rowspan() { - return rowspan; - } - - /** - * Gets the cellspacing of a cell. - * - * @return a value - */ - - public float cellspacing() { - return cellspacing; - } - - /** - * Gets the cellpadding of a cell.. - * - * @return a value - */ - - public float cellpadding() { - return cellpadding; - } - - /** - * Processes all actions contained in the cell. - * @param element an element in the cell - * @param action an action that should be coupled to the cell - * @param allActions - */ - - protected void processActions(Element element, PdfAction action, ArrayList allActions) { - if (element.type() == Element.ANCHOR) { - String url = ((Anchor) element).reference(); - if (url != null) { - action = new PdfAction(url); - } - } - Iterator i; - switch (element.type()) { - case Element.PHRASE: - case Element.SECTION: - case Element.ANCHOR: - case Element.CHAPTER: - case Element.LISTITEM: - case Element.PARAGRAPH: - for (i = ((ArrayList) element).iterator(); i.hasNext();) { - processActions((Element) i.next(), action, allActions); - } - break; - case Element.CHUNK: - allActions.add(action); - break; - case Element.LIST: - for (i = ((List) element).getItems().iterator(); i.hasNext();) { - processActions((Element) i.next(), action, allActions); - } - break; - default: - int n = element.getChunks().size(); - while (n-- > 0) - allActions.add(action); - break; - } - } - - /** - * This is the number of the group the cell is in. - */ - private int groupNumber; - - /** - * Gets the number of the group this cell is in.. - * - * @return a number - */ - - public int getGroupNumber() { - return groupNumber; - } - - /** - * Sets the group number. - * @param number - */ - - void setGroupNumber(int number) { - groupNumber = number; - } - - /** - * Gets a Rectangle that is altered to fit on the page. - * - * @param top the top position - * @param bottom the bottom position - * @return a Rectangle - */ - - public Rectangle rectangle(float top, float bottom) { - Rectangle tmp = new Rectangle(left(), bottom(), right(), top()); - tmp.cloneNonPositionParameters(this); - if (top() > top) { - tmp.setTop(top); - tmp.setBorder(border - (border & TOP)); - } - if (bottom() < bottom) { - tmp.setBottom(bottom); - tmp.setBorder(border - (border & BOTTOM)); - } - return tmp; - } - - /** - * Sets the value of {@link #useAscender}. - * @param use use ascender height if true - */ - public void setUseAscender(boolean use) { - useAscender = use; - } - - /** - * Gets the value of {@link #useAscender} - * @return useAscender - */ - public boolean isUseAscender() { - return useAscender; - } - - /** - * Sets the value of {@link #useDescender}. - * @param use use descender height if true - */ - public void setUseDescender(boolean use) { - useDescender = use; - } - - /** - * gets the value of {@link #useDescender } - * @return useDescender - */ - public boolean isUseDescender() { - return useDescender; - } - - /** - * Sets the value of {@link #useBorderPadding}. - * @param use adjust layour for borders if true - */ - public void setUseBorderPadding(boolean use) { - useBorderPadding = use; - } - - /** - * Gets the value of {@link #useBorderPadding}. - * @return useBorderPadding - */ - public boolean isUseBorderPadding() { - return useBorderPadding; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfChunk.java b/src/main/java/com/lowagie/text/pdf/PdfChunk.java deleted file mode 100644 index 2906552..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfChunk.java +++ /dev/null @@ -1,781 +0,0 @@ -/* - * $Id: PdfChunk.java,v 1.71 2006/02/16 16:17:52 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; - -import com.lowagie.text.Chunk; -import com.lowagie.text.Font; -import com.lowagie.text.Image; -import com.lowagie.text.SplitCharacter; -import java.util.HashMap; -import java.util.Iterator; - -/** - * A PdfChunk is the PDF translation of a Chunk. - *

- * A PdfChunk is a PdfString in a certain - * PdfFont and Color. - * - * @see PdfString - * @see com.lowagie.text.Chunk - * @see com.lowagie.text.Font - */ - -public class PdfChunk implements SplitCharacter{ - - private static final char singleSpace[] = {' '}; - private static final PdfChunk thisChunk[] = new PdfChunk[1]; - private static final float ITALIC_ANGLE = 0.21256f; -/** The allowed attributes in variable attributes. */ - private static final HashMap keysAttributes = new HashMap(); - -/** The allowed attributes in variable noStroke. */ - private static final HashMap keysNoStroke = new HashMap(); - - static { - keysAttributes.put(Chunk.ACTION, null); - keysAttributes.put(Chunk.UNDERLINE, null); - keysAttributes.put(Chunk.REMOTEGOTO, null); - keysAttributes.put(Chunk.LOCALGOTO, null); - keysAttributes.put(Chunk.LOCALDESTINATION, null); - keysAttributes.put(Chunk.GENERICTAG, null); - keysAttributes.put(Chunk.NEWPAGE, null); - keysAttributes.put(Chunk.IMAGE, null); - keysAttributes.put(Chunk.BACKGROUND, null); - keysAttributes.put(Chunk.PDFANNOTATION, null); - keysAttributes.put(Chunk.SKEW, null); - keysAttributes.put(Chunk.HSCALE, null); - keysNoStroke.put(Chunk.SUBSUPSCRIPT, null); - keysNoStroke.put(Chunk.SPLITCHARACTER, null); - keysNoStroke.put(Chunk.HYPHENATION, null); - keysNoStroke.put(Chunk.TEXTRENDERMODE, null); - } - - // membervariables - - /** The value of this object. */ - protected String value = PdfObject.NOTHING; - - /** The encoding. */ - protected String encoding = BaseFont.WINANSI; - - -/** The font for this PdfChunk. */ - protected PdfFont font; - - protected BaseFont baseFont; - - protected SplitCharacter splitCharacter; -/** - * Metric attributes. - *

- * This attributes require the mesurement of characters widths when rendering - * such as underline. - */ - protected HashMap attributes = new HashMap(); - -/** - * Non metric attributes. - *

- * This attributes do not require the mesurement of characters widths when rendering - * such as Color. - */ - protected HashMap noStroke = new HashMap(); - -/** true if the chunk split was cause by a newline. */ - protected boolean newlineSplit; - -/** The image in this PdfChunk, if it has one */ - protected Image image; - -/** The offset in the x direction for the image */ - protected float offsetX; - -/** The offset in the y direction for the image */ - protected float offsetY; - -/** Indicates if the height and offset of the Image has to be taken into account */ - protected boolean changeLeading = false; - - // constructors - -/** - * Constructs a PdfChunk-object. - * - * @param string the content of the PdfChunk-object - * @param other Chunk with the same style you want for the new Chunk - */ - - PdfChunk(String string, PdfChunk other) { - thisChunk[0] = this; - value = string; - this.font = other.font; - this.attributes = other.attributes; - this.noStroke = other.noStroke; - this.baseFont = other.baseFont; - Object obj[] = (Object[])attributes.get(Chunk.IMAGE); - if (obj == null) - image = null; - else { - image = (Image)obj[0]; - offsetX = ((Float)obj[1]).floatValue(); - offsetY = ((Float)obj[2]).floatValue(); - changeLeading = ((Boolean)obj[3]).booleanValue(); - } - encoding = font.getFont().getEncoding(); - splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); - if (splitCharacter == null) - splitCharacter = this; - } - -/** - * Constructs a PdfChunk-object. - * - * @param chunk the original Chunk-object - * @param action the PdfAction if the Chunk comes from an Anchor - */ - - PdfChunk(Chunk chunk, PdfAction action) { - thisChunk[0] = this; - value = chunk.content(); - - Font f = chunk.font(); - float size = f.size(); - if (size == Font.UNDEFINED) - size = 12; - baseFont = f.getBaseFont(); - int style = f.style(); - if (style == Font.UNDEFINED) { - style = Font.NORMAL; - } - if (baseFont == null) { - // translation of the font-family to a PDF font-family - baseFont = f.getCalculatedBaseFont(false); - } - else { - // bold simulation - if ((style & Font.BOLD) != 0) - attributes.put(Chunk.TEXTRENDERMODE, new Object[]{new Integer(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), new Float(size / 30f), null}); - // italic simulation - if ((style & Font.ITALIC) != 0) - attributes.put(Chunk.SKEW, new float[]{0, ITALIC_ANGLE}); - } - font = new PdfFont(baseFont, size); - // other style possibilities - HashMap attr = chunk.getAttributes(); - if (attr != null) { - for (Iterator i = attr.keySet().iterator(); i.hasNext();) { - Object name = i.next(); - if (keysAttributes.containsKey(name)) { - attributes.put(name, attr.get(name)); - } - else if (keysNoStroke.containsKey(name)) { - noStroke.put(name, attr.get(name)); - } - } - if ("".equals(attr.get(Chunk.GENERICTAG))) { - attributes.put(Chunk.GENERICTAG, chunk.content()); - } - } - if (f.isUnderlined()) { - Object obj[] = {null, new float[]{0, 1f / 15, 0, -1f / 3, 0}}; - Object unders[][] = Chunk.addToArray((Object[][])attributes.get(Chunk.UNDERLINE), obj); - attributes.put(Chunk.UNDERLINE, unders); - } - if (f.isStrikethru()) { - Object obj[] = {null, new float[]{0, 1f / 15, 0, 1f / 3, 0}}; - Object unders[][] = Chunk.addToArray((Object[][])attributes.get(Chunk.UNDERLINE), obj); - attributes.put(Chunk.UNDERLINE, unders); - } - if (action != null) - attributes.put(Chunk.ACTION, action); - // the color can't be stored in a PdfFont - noStroke.put(Chunk.COLOR, f.color()); - noStroke.put(Chunk.ENCODING, font.getFont().getEncoding()); - Object obj[] = (Object[])attributes.get(Chunk.IMAGE); - if (obj == null) { - image = null; - } - else { - attributes.remove(Chunk.HSCALE); // images are scaled in other ways - image = (Image)obj[0]; - offsetX = ((Float)obj[1]).floatValue(); - offsetY = ((Float)obj[2]).floatValue(); - changeLeading = ((Boolean)obj[3]).booleanValue(); - } - font.setImage(image); - Float hs = (Float)attributes.get(Chunk.HSCALE); - if (hs != null) - font.setHorizontalScaling(hs.floatValue()); - encoding = font.getFont().getEncoding(); - splitCharacter = (SplitCharacter)noStroke.get(Chunk.SPLITCHARACTER); - if (splitCharacter == null) - splitCharacter = this; - } - - // methods - - /** Gets the Unicode equivalent to a CID. - * The (inexistent) CID is translated as '\n'. - * It has only meaning with CJK fonts with Identity encoding. - * @param c the CID code - * @return the Unicode equivalent - */ - public char getUnicodeEquivalent(char c) { - return baseFont.getUnicodeEquivalent(c); - } - - protected int getWord(String text, int start) { - int len = text.length(); - while (start < len) { - if (!Character.isLetter(text.charAt(start))) - break; - ++start; - } - return start; - } - -/** - * Splits this PdfChunk if it's too long for the given width. - *

- * Returns null if the PdfChunk wasn't truncated. - * - * @param width a given width - * @return the PdfChunk that doesn't fit into the width. - */ - - PdfChunk split(float width) { - newlineSplit = false; - if (image != null) { - if (image.scaledWidth() > width) { - PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this); - value = ""; - attributes = new HashMap(); - image = null; - font = PdfFont.getDefaultFont(); - return pc; - } - else - return null; - } - HyphenationEvent hyphenationEvent = (HyphenationEvent)noStroke.get(Chunk.HYPHENATION); - int currentPosition = 0; - int splitPosition = -1; - float currentWidth = 0; - - // loop over all the characters of a string - // or until the totalWidth is reached - int lastSpace = -1; - float lastSpaceWidth = 0; - int length = value.length(); - char valueArray[] = value.toCharArray(); - char character = 0; - BaseFont ft = font.getFont(); - if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { - while (currentPosition < length) { - // the width of every character is added to the currentWidth - char cidChar = valueArray[currentPosition]; - character = ft.getUnicodeEquivalent(cidChar); - // if a newLine or carriageReturn is encountered - if (character == '\n') { - newlineSplit = true; - String returnValue = value.substring(currentPosition + 1); - value = value.substring(0, currentPosition); - if (value.length() < 1) { - value = "\u0001"; - } - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - currentWidth += font.width(cidChar); - if (character == ' ') { - lastSpace = currentPosition + 1; - lastSpaceWidth = currentWidth; - } - if (currentWidth > width) - break; - // if a split-character is encountered, the splitPosition is altered - if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, thisChunk)) - splitPosition = currentPosition + 1; - currentPosition++; - } - } - else { - while (currentPosition < length) { - // the width of every character is added to the currentWidth - character = valueArray[currentPosition]; - // if a newLine or carriageReturn is encountered - if (character == '\r' || character == '\n') { - newlineSplit = true; - int inc = 1; - if (character == '\r' && currentPosition + 1 < length && valueArray[currentPosition + 1] == '\n') - inc = 2; - String returnValue = value.substring(currentPosition + inc); - value = value.substring(0, currentPosition); - if (value.length() < 1) { - value = " "; - } - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - currentWidth += font.width(character); - if (character == ' ') { - lastSpace = currentPosition + 1; - lastSpaceWidth = currentWidth; - } - if (currentWidth > width) - break; - // if a split-character is encountered, the splitPosition is altered - if (splitCharacter.isSplitCharacter(0, currentPosition, length, valueArray, null)) - splitPosition = currentPosition + 1; - currentPosition++; - } - } - - // if all the characters fit in the total width, null is returned (there is no overflow) - if (currentPosition == length) { - return null; - } - // otherwise, the string has to be truncated - if (splitPosition < 0) { - String returnValue = value; - value = ""; - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - if (lastSpace > splitPosition && splitCharacter.isSplitCharacter(0, 0, 1, singleSpace, null)) - splitPosition = lastSpace; - if (hyphenationEvent != null && lastSpace < currentPosition) { - int wordIdx = getWord(value, lastSpace); - if (wordIdx > lastSpace) { - String pre = hyphenationEvent.getHyphenatedWordPre(value.substring(lastSpace, wordIdx), font.getFont(), font.size(), width - lastSpaceWidth); - String post = hyphenationEvent.getHyphenatedWordPost(); - if (pre.length() > 0) { - String returnValue = post + value.substring(wordIdx); - value = trim(value.substring(0, lastSpace) + pre); - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - } - } - String returnValue = value.substring(splitPosition); - value = trim(value.substring(0, splitPosition)); - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - -/** - * Truncates this PdfChunk if it's too long for the given width. - *

- * Returns null if the PdfChunk wasn't truncated. - * - * @param width a given width - * @return the PdfChunk that doesn't fit into the width. - */ - - PdfChunk truncate(float width) { - if (image != null) { - if (image.scaledWidth() > width) { - PdfChunk pc = new PdfChunk("", this); - value = ""; - attributes.remove(Chunk.IMAGE); - image = null; - font = PdfFont.getDefaultFont(); - return pc; - } - else - return null; - } - - int currentPosition = 0; - float currentWidth = 0; - - // it's no use trying to split if there isn't even enough place for a space - if (width < font.width()) { - String returnValue = value.substring(1); - value = value.substring(0, 1); - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - - // loop over all the characters of a string - // or until the totalWidth is reached - int length = value.length(); - char character; - while (currentPosition < length) { - // the width of every character is added to the currentWidth - character = value.charAt(currentPosition); - currentWidth += font.width(character); - if (currentWidth > width) - break; - currentPosition++; - } - - // if all the characters fit in the total width, null is returned (there is no overflow) - if (currentPosition == length) { - return null; - } - - // otherwise, the string has to be truncated - //currentPosition -= 2; - // we have to chop off minimum 1 character from the chunk - if (currentPosition == 0) { - currentPosition = 1; - } - String returnValue = value.substring(currentPosition); - value = value.substring(0, currentPosition); - PdfChunk pc = new PdfChunk(returnValue, this); - return pc; - } - - // methods to retrieve the membervariables - -/** - * Returns the font of this Chunk. - * - * @return a PdfFont - */ - - PdfFont font() { - return font; - } - -/** - * Returns the color of this Chunk. - * - * @return a Color - */ - - Color color() { - return (Color)noStroke.get(Chunk.COLOR); - } - -/** - * Returns the width of this PdfChunk. - * - * @return a width - */ - - float width() { - return font.width(value); - } - -/** - * Checks if the PdfChunk split was caused by a newline. - * @return true if the PdfChunk split was caused by a newline. - */ - - public boolean isNewlineSplit() - { - return newlineSplit; - } - -/** - * Gets the width of the PdfChunk taking into account the - * extra character and word spacing. - * @param charSpacing the extra character spacing - * @param wordSpacing the extra word spacing - * @return the calculated width - */ - - public float getWidthCorrected(float charSpacing, float wordSpacing) - { - if (image != null) { - return image.scaledWidth() + charSpacing; - } - int numberOfSpaces = 0; - int idx = -1; - while ((idx = value.indexOf(' ', idx + 1)) >= 0) - ++numberOfSpaces; - return width() + (value.length() * charSpacing + numberOfSpaces * wordSpacing); - } - - /** - * Gets the text displacement relatiev to the baseline. - * @return a displacement in points - */ - public float getTextRise() { - Float f = (Float) getAttribute(Chunk.SUBSUPSCRIPT); - if (f != null) { - return f.floatValue(); - } - return 0.0f; - } - -/** - * Trims the last space. - * @return the width of the space trimmed, otherwise 0 - */ - - public float trimLastSpace() - { - BaseFont ft = font.getFont(); - if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { - if (value.length() > 1 && value.endsWith("\u0001")) { - value = value.substring(0, value.length() - 1); - return font.width('\u0001'); - } - } - else { - if (value.length() > 1 && value.endsWith(" ")) { - value = value.substring(0, value.length() - 1); - return font.width(' '); - } - } - return 0; - } - -/** - * Gets an attribute. The search is made in attributes - * and noStroke. - * @param name the attribute key - * @return the attribute value or null if not found - */ - - Object getAttribute(String name) - { - if (attributes.containsKey(name)) - return attributes.get(name); - return noStroke.get(name); - } - -/** - *Checks if the attribute exists. - * @param name the attribute key - * @return true if the attribute exists - */ - - boolean isAttribute(String name) - { - if (attributes.containsKey(name)) - return true; - return noStroke.containsKey(name); - } - -/** - * Checks if this PdfChunk needs some special metrics handling. - * @return true if this PdfChunk needs some special metrics handling. - */ - - boolean isStroked() - { - return (attributes.size() > 0); - } - -/** - * Checks if there is an image in the PdfChunk. - * @return true if an image is present - */ - - boolean isImage() - { - return image != null; - } - -/** - * Gets the image in the PdfChunk. - * @return the image or null - */ - - Image getImage() - { - return image; - } - -/** - * Sets the image offset in the x direction - * @param offsetX the image offset in the x direction - */ - - void setImageOffsetX(float offsetX) - { - this.offsetX = offsetX; - } - -/** - * Gets the image offset in the x direction - * @return the image offset in the x direction - */ - - float getImageOffsetX() - { - return offsetX; - } - -/** - * Sets the image offset in the y direction - * @param offsetY the image offset in the y direction - */ - - void setImageOffsetY(float offsetY) - { - this.offsetY = offsetY; - } - -/** - * Gets the image offset in the y direction - * @return Gets the image offset in the y direction - */ - - float getImageOffsetY() - { - return offsetY; - } - -/** - * sets the value. - * @param value content of the Chunk - */ - - void setValue(String value) - { - this.value = value; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - return value; - } - - /** - * Tells you if this string is in Chinese, Japanese, Korean or Identity-H. - * @return true if the Chunk has a special encoding - */ - - boolean isSpecialEncoding() { - return encoding.equals(CJKFont.CJK_ENCODING) || encoding.equals(BaseFont.IDENTITY_H); - } - - /** - * Gets the encoding of this string. - * - * @return a String - */ - - String getEncoding() { - return encoding; - } - - int length() { - return value.length(); - } -/** - * Checks if a character can be used to split a PdfString. - *

- * for the moment every character less than or equal to SPACE and the character '-' are 'splitCharacters'. - * - * @param start start position in the array - * @param current current position in the array - * @param end end position in the array - * @param cc the character array that has to be checked - * @param ck chunk array - * @return true if the character can be used to split a string, false otherwise - */ - public boolean isSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { - char c; - if (ck == null) - c = cc[current]; - else - c = ck[Math.min(current, ck.length - 1)].getUnicodeEquivalent(cc[current]); - if (c <= ' ' || c == '-') { - return true; - } - if (c < 0x2e80) - return false; - return ((c >= 0x2e80 && c < 0xd7a0) - || (c >= 0xf900 && c < 0xfb00) - || (c >= 0xfe30 && c < 0xfe50) - || (c >= 0xff61 && c < 0xffa0)); - } - - boolean isExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { - return splitCharacter.isSplitCharacter(start, current, end, cc, ck); - } - -/** - * Removes all the ' ' and '-'-characters on the right of a String. - *

- * @param string the String that has to be trimmed. - * @return the trimmed String - */ - String trim(String string) { - BaseFont ft = font.getFont(); - if (ft.getFontType() == BaseFont.FONT_TYPE_CJK && ft.getUnicodeEquivalent(' ') != ' ') { - while (string.endsWith("\u0001")) { - string = string.substring(0, string.length() - 1); - } - } - else { - while (string.endsWith(" ") || string.endsWith("\t")) { - string = string.substring(0, string.length() - 1); - } - } - return string; - } - - public boolean changeLeading() { - return changeLeading; - } - - float getCharWidth(char c) { - if (noPrint(c)) - return 0; - return font.width(c); - } - - public static boolean noPrint(char c) { - return ((c >= 0x200b && c <= 0x200f) || (c >= 0x202a && c <= 0x202e)); - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfColor.java b/src/main/java/com/lowagie/text/pdf/PdfColor.java deleted file mode 100644 index b07348d..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfColor.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * $Id: PdfColor.java,v 1.54 2005/05/04 14:31:42 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.awt.Color; -/** - * A PdfColor defines a Color (it's a PdfArray containing 3 values). - * - * @see PdfDictionary - */ - -class PdfColor extends PdfArray { - - // constructors - -/** - * Constructs a new PdfColor. - * - * @param red a value between 0 and 255 - * @param green a value between 0 and 255 - * @param blue a value between 0 and 255 - */ - - PdfColor(int red, int green, int blue) { - super(new PdfNumber((double)(red & 0xFF) / 0xFF)); - add(new PdfNumber((double)(green & 0xFF) / 0xFF)); - add(new PdfNumber((double)(blue & 0xFF) / 0xFF)); - } - - PdfColor(Color color) { - this(color.getRed(), color.getGreen(), color.getBlue()); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfContentByte.java b/src/main/java/com/lowagie/text/pdf/PdfContentByte.java deleted file mode 100644 index 07669cd..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfContentByte.java +++ /dev/null @@ -1,3053 +0,0 @@ -/* - * $Id: PdfContentByte.java,v 1.100 2006/05/18 09:39:28 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.awt.Color; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.awt.geom.AffineTransform; -import java.awt.print.PrinterJob; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.Element; -import com.lowagie.text.Image; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Annotation; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.pdf.ExtendedColor; - -/** - * PdfContentByte is an object containing the user positioned - * text and graphic contents of a page. It knows how to apply the proper - * font encoding. - */ - -public class PdfContentByte { - - /** - * This class keeps the graphic state of the current page - */ - - static class GraphicState { - - /** This is the font in use */ - FontDetails fontDetails; - - /** This is the color in use */ - ColorDetails colorDetails; - - /** This is the font size in use */ - float size; - - /** The x position of the text line matrix. */ - protected float xTLM = 0; - /** The y position of the text line matrix. */ - protected float yTLM = 0; - - /** The current text leading. */ - protected float leading = 0; - - /** The current horizontal scaling */ - protected float scale = 100; - - /** The current character spacing */ - protected float charSpace = 0; - - /** The current word spacing */ - protected float wordSpace = 0; - - GraphicState() { - } - - GraphicState(GraphicState cp) { - fontDetails = cp.fontDetails; - colorDetails = cp.colorDetails; - size = cp.size; - xTLM = cp.xTLM; - yTLM = cp.yTLM; - leading = cp.leading; - scale = cp.scale; - charSpace = cp.charSpace; - wordSpace = cp.wordSpace; - } - } - - /** The alignement is center */ - public static final int ALIGN_CENTER = Element.ALIGN_CENTER; - - /** The alignement is left */ - public static final int ALIGN_LEFT = Element.ALIGN_LEFT; - - /** The alignement is right */ - public static final int ALIGN_RIGHT = Element.ALIGN_RIGHT; - - /** A possible line cap value */ - public static final int LINE_CAP_BUTT = 0; - /** A possible line cap value */ - public static final int LINE_CAP_ROUND = 1; - /** A possible line cap value */ - public static final int LINE_CAP_PROJECTING_SQUARE = 2; - - /** A possible line join value */ - public static final int LINE_JOIN_MITER = 0; - /** A possible line join value */ - public static final int LINE_JOIN_ROUND = 1; - /** A possible line join value */ - public static final int LINE_JOIN_BEVEL = 2; - - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_FILL = 0; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_STROKE = 1; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_FILL_STROKE = 2; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_INVISIBLE = 3; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_FILL_CLIP = 4; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_STROKE_CLIP = 5; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_FILL_STROKE_CLIP = 6; - /** A possible text rendering value */ - public static final int TEXT_RENDER_MODE_CLIP = 7; - - private static final float[] unitRect = {0, 0, 0, 1, 1, 0, 1, 1}; - // membervariables - - /** This is the actual content */ - protected ByteBuffer content = new ByteBuffer(); - - /** This is the writer */ - protected PdfWriter writer; - - /** This is the PdfDocument */ - protected PdfDocument pdf; - - /** This is the GraphicState in use */ - protected GraphicState state = new GraphicState(); - - /** The list were we save/restore the state */ - protected ArrayList stateList = new ArrayList(); - - /** The list were we save/restore the layer depth */ - protected ArrayList layerDepth; - - /** The separator between commands. - */ - protected int separator = '\n'; - - private static HashMap abrev = new HashMap(); - - static { - abrev.put(PdfName.BITSPERCOMPONENT, "/BPC "); - abrev.put(PdfName.COLORSPACE, "/CS "); - abrev.put(PdfName.DECODE, "/D "); - abrev.put(PdfName.DECODEPARMS, "/DP "); - abrev.put(PdfName.FILTER, "/F "); - abrev.put(PdfName.HEIGHT, "/H "); - abrev.put(PdfName.IMAGEMASK, "/IM "); - abrev.put(PdfName.INTENT, "/Intent "); - abrev.put(PdfName.INTERPOLATE, "/I "); - abrev.put(PdfName.WIDTH, "/W "); - } - - // constructors - - /** - * Constructs a new PdfContentByte-object. - * - * @param wr the writer associated to this content - */ - - public PdfContentByte(PdfWriter wr) { - if (wr != null) { - writer = wr; - pdf = writer.getPdfDocument(); - } - } - - // methods to get the content of this object - - /** - * Returns the String representation of this PdfContentByte-object. - * - * @return a String - */ - - public String toString() { - return content.toString(); - } - - /** - * Gets the internal buffer. - * @return the internal buffer - */ - public ByteBuffer getInternalBuffer() { - return content; - } - - /** Returns the PDF representation of this PdfContentByte-object. - * - * @param writer the PdfWriter - * @return a byte array with the representation - */ - - public byte[] toPdf(PdfWriter writer) { - return content.toByteArray(); - } - - // methods to add graphical content - - /** - * Adds the content of another PdfContent-object to this object. - * - * @param other another PdfByteContent-object - */ - - public void add(PdfContentByte other) { - if (other.writer != null && writer != other.writer) - throw new RuntimeException("Inconsistent writers. Are you mixing two documents?"); - content.append(other.content); - } - - /** - * Gets the x position of the text line matrix. - * - * @return the x position of the text line matrix - */ - public float getXTLM() { - return state.xTLM; - } - - /** - * Gets the y position of the text line matrix. - * - * @return the y position of the text line matrix - */ - public float getYTLM() { - return state.yTLM; - } - - /** - * Gets the current text leading. - * - * @return the current text leading - */ - public float getLeading() { - return state.leading; - } - - /** - * Gets the current character spacing. - * - * @return the current character spacing - */ - public float getCharacterSpacing() { - return state.charSpace; - } - - /** - * Gets the current word spacing. - * - * @return the current word spacing - */ - public float getWordSpacing() { - return state.wordSpace; - } - - /** - * Gets the current character spacing. - * - * @return the current character spacing - */ - public float getHorizontalScaling() { - return state.scale; - } - - /** - * Changes the Flatness. - *

- * Flatness sets the maximum permitted distance in device pixels between the - * mathematically correct path and an approximation constructed from straight line segments.
- * - * @param flatness a value - */ - - public void setFlatness(float flatness) { - if (flatness >= 0 && flatness <= 100) { - content.append(flatness).append(" i").append_i(separator); - } - } - - /** - * Changes the Line cap style. - *

- * The line cap style specifies the shape to be used at the end of open subpaths - * when they are stroked.
- * Allowed values are LINE_CAP_BUTT, LINE_CAP_ROUND and LINE_CAP_PROJECTING_SQUARE.
- * - * @param style a value - */ - - public void setLineCap(int style) { - if (style >= 0 && style <= 2) { - content.append(style).append(" J").append_i(separator); - } - } - - /** - * Changes the value of the line dash pattern. - *

- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths. - * It is specified by an array and a phase. The array specifies the length - * of the alternating dashes and gaps. The phase specifies the distance into the dash - * pattern to start the dash.
- * - * @param phase the value of the phase - */ - - public void setLineDash(float phase) { - content.append("[] ").append(phase).append(" d").append_i(separator); - } - - /** - * Changes the value of the line dash pattern. - *

- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths. - * It is specified by an array and a phase. The array specifies the length - * of the alternating dashes and gaps. The phase specifies the distance into the dash - * pattern to start the dash.
- * - * @param phase the value of the phase - * @param unitsOn the number of units that must be 'on' (equals the number of units that must be 'off'). - */ - - public void setLineDash(float unitsOn, float phase) { - content.append("[").append(unitsOn).append("] ").append(phase).append(" d").append_i(separator); - } - - /** - * Changes the value of the line dash pattern. - *

- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths. - * It is specified by an array and a phase. The array specifies the length - * of the alternating dashes and gaps. The phase specifies the distance into the dash - * pattern to start the dash.
- * - * @param phase the value of the phase - * @param unitsOn the number of units that must be 'on' - * @param unitsOff the number of units that must be 'off' - */ - - public void setLineDash(float unitsOn, float unitsOff, float phase) { - content.append("[").append(unitsOn).append(' ').append(unitsOff).append("] ").append(phase).append(" d").append_i(separator); - } - - /** - * Changes the value of the line dash pattern. - *

- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths. - * It is specified by an array and a phase. The array specifies the length - * of the alternating dashes and gaps. The phase specifies the distance into the dash - * pattern to start the dash.
- * - * @param array length of the alternating dashes and gaps - * @param phase the value of the phase - */ - - public final void setLineDash(float[] array, float phase) { - content.append("["); - for (int i = 0; i < array.length; i++) { - content.append(array[i]); - if (i < array.length - 1) content.append(' '); - } - content.append("] ").append(phase).append(" d").append_i(separator); - } - - /** - * Changes the Line join style. - *

- * The line join style specifies the shape to be used at the corners of paths - * that are stroked.
- * Allowed values are LINE_JOIN_MITER (Miter joins), LINE_JOIN_ROUND (Round joins) and LINE_JOIN_BEVEL (Bevel joins).
- * - * @param style a value - */ - - public void setLineJoin(int style) { - if (style >= 0 && style <= 2) { - content.append(style).append(" j").append_i(separator); - } - } - - /** - * Changes the line width. - *

- * The line width specifies the thickness of the line used to stroke a path and is measured - * in user space units.
- * - * @param w a width - */ - - public void setLineWidth(float w) { - content.append(w).append(" w").append_i(separator); - } - - /** - * Changes the Miter limit. - *

- * When two line segments meet at a sharp angle and mitered joins have been specified as the - * line join style, it is possible for the miter to extend far beyond the thickness of the line - * stroking path. The miter limit imposes a maximum on the ratio of the miter length to the line - * witdh. When the limit is exceeded, the join is converted from a miter to a bevel.
- * - * @param miterLimit a miter limit - */ - - public void setMiterLimit(float miterLimit) { - if (miterLimit > 1) { - content.append(miterLimit).append(" M").append_i(separator); - } - } - - /** - * Modify the current clipping path by intersecting it with the current path, using the - * nonzero winding number rule to determine which regions lie inside the clipping - * path. - */ - - public void clip() { - content.append("W").append_i(separator); - } - - /** - * Modify the current clipping path by intersecting it with the current path, using the - * even-odd rule to determine which regions lie inside the clipping path. - */ - - public void eoClip() { - content.append("W*").append_i(separator); - } - - /** - * Changes the currentgray tint for filling paths (device dependent colors!). - *

- * Sets the color space to DeviceGray (or the DefaultGray color space), - * and sets the gray tint to use for filling paths.

- * - * @param gray a value between 0 (black) and 1 (white) - */ - - public void setGrayFill(float gray) { - content.append(gray).append(" g").append_i(separator); - } - - /** - * Changes the current gray tint for filling paths to black. - */ - - public void resetGrayFill() { - content.append("0 g").append_i(separator); - } - - /** - * Changes the currentgray tint for stroking paths (device dependent colors!). - *

- * Sets the color space to DeviceGray (or the DefaultGray color space), - * and sets the gray tint to use for stroking paths.

- * - * @param gray a value between 0 (black) and 1 (white) - */ - - public void setGrayStroke(float gray) { - content.append(gray).append(" G").append_i(separator); - } - - /** - * Changes the current gray tint for stroking paths to black. - */ - - public void resetGrayStroke() { - content.append("0 G").append_i(separator); - } - - /** - * Helper to validate and write the RGB color components - * @param red the intensity of red. A value between 0 and 1 - * @param green the intensity of green. A value between 0 and 1 - * @param blue the intensity of blue. A value between 0 and 1 - */ - private void HelperRGB(float red, float green, float blue) { - PdfWriter.checkPDFXConformance(writer, PdfWriter.PDFXKEY_RGB, null); - if (red < 0) - red = 0.0f; - else if (red > 1.0f) - red = 1.0f; - if (green < 0) - green = 0.0f; - else if (green > 1.0f) - green = 1.0f; - if (blue < 0) - blue = 0.0f; - else if (blue > 1.0f) - blue = 1.0f; - content.append(red).append(' ').append(green).append(' ').append(blue); - } - - /** - * Changes the current color for filling paths (device dependent colors!). - *

- * Sets the color space to DeviceRGB (or the DefaultRGB color space), - * and sets the color to use for filling paths.

- *

- * Following the PDF manual, each operand must be a number between 0 (minimum intensity) and - * 1 (maximum intensity).

- * - * @param red the intensity of red. A value between 0 and 1 - * @param green the intensity of green. A value between 0 and 1 - * @param blue the intensity of blue. A value between 0 and 1 - */ - - public void setRGBColorFillF(float red, float green, float blue) { - HelperRGB(red, green, blue); - content.append(" rg").append_i(separator); - } - - /** - * Changes the current color for filling paths to black. - */ - - public void resetRGBColorFill() { - content.append("0 g").append_i(separator); - } - - /** - * Changes the current color for stroking paths (device dependent colors!). - *

- * Sets the color space to DeviceRGB (or the DefaultRGB color space), - * and sets the color to use for stroking paths.

- *

- * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and - * 1 (maximum intensity). - * - * @param red the intensity of red. A value between 0 and 1 - * @param green the intensity of green. A value between 0 and 1 - * @param blue the intensity of blue. A value between 0 and 1 - */ - - public void setRGBColorStrokeF(float red, float green, float blue) { - HelperRGB(red, green, blue); - content.append(" RG").append_i(separator); - } - - /** - * Changes the current color for stroking paths to black. - * - */ - - public void resetRGBColorStroke() { - content.append("0 G").append_i(separator); - } - - /** - * Helper to validate and write the CMYK color components. - * - * @param cyan the intensity of cyan. A value between 0 and 1 - * @param magenta the intensity of magenta. A value between 0 and 1 - * @param yellow the intensity of yellow. A value between 0 and 1 - * @param black the intensity of black. A value between 0 and 1 - */ - private void HelperCMYK(float cyan, float magenta, float yellow, float black) { - if (cyan < 0) - cyan = 0.0f; - else if (cyan > 1.0f) - cyan = 1.0f; - if (magenta < 0) - magenta = 0.0f; - else if (magenta > 1.0f) - magenta = 1.0f; - if (yellow < 0) - yellow = 0.0f; - else if (yellow > 1.0f) - yellow = 1.0f; - if (black < 0) - black = 0.0f; - else if (black > 1.0f) - black = 1.0f; - content.append(cyan).append(' ').append(magenta).append(' ').append(yellow).append(' ').append(black); - } - - /** - * Changes the current color for filling paths (device dependent colors!). - *

- * Sets the color space to DeviceCMYK (or the DefaultCMYK color space), - * and sets the color to use for filling paths.

- *

- * Following the PDF manual, each operand must be a number between 0 (no ink) and - * 1 (maximum ink).

- * - * @param cyan the intensity of cyan. A value between 0 and 1 - * @param magenta the intensity of magenta. A value between 0 and 1 - * @param yellow the intensity of yellow. A value between 0 and 1 - * @param black the intensity of black. A value between 0 and 1 - */ - - public void setCMYKColorFillF(float cyan, float magenta, float yellow, float black) { - HelperCMYK(cyan, magenta, yellow, black); - content.append(" k").append_i(separator); - } - - /** - * Changes the current color for filling paths to black. - * - */ - - public void resetCMYKColorFill() { - content.append("0 0 0 1 k").append_i(separator); - } - - /** - * Changes the current color for stroking paths (device dependent colors!). - *

- * Sets the color space to DeviceCMYK (or the DefaultCMYK color space), - * and sets the color to use for stroking paths.

- *

- * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and - * 1 (maximum intensity). - * - * @param cyan the intensity of cyan. A value between 0 and 1 - * @param magenta the intensity of magenta. A value between 0 and 1 - * @param yellow the intensity of yellow. A value between 0 and 1 - * @param black the intensity of black. A value between 0 and 1 - */ - - public void setCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) { - HelperCMYK(cyan, magenta, yellow, black); - content.append(" K").append_i(separator); - } - - /** - * Changes the current color for stroking paths to black. - * - */ - - public void resetCMYKColorStroke() { - content.append("0 0 0 1 K").append_i(separator); - } - - /** - * Move the current point (x, y), omitting any connecting line segment. - * - * @param x new x-coordinate - * @param y new y-coordinate - */ - - public void moveTo(float x, float y) { - content.append(x).append(' ').append(y).append(" m").append_i(separator); - } - - /** - * Appends a straight line segment from the current point (x, y). The new current - * point is (x, y). - * - * @param x new x-coordinate - * @param y new y-coordinate - */ - - public void lineTo(float x, float y) { - content.append(x).append(' ').append(y).append(" l").append_i(separator); - } - - /** - * Appends a Bêzier curve to the path, starting from the current point. - * - * @param x1 x-coordinate of the first control point - * @param y1 y-coordinate of the first control point - * @param x2 x-coordinate of the second control point - * @param y2 y-coordinate of the second control point - * @param x3 x-coordinaat of the ending point (= new current point) - * @param y3 y-coordinaat of the ending point (= new current point) - */ - - public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) { - content.append(x1).append(' ').append(y1).append(' ').append(x2).append(' ').append(y2).append(' ').append(x3).append(' ').append(y3).append(" c").append_i(separator); - } - - /** - * Appends a Bêzier curve to the path, starting from the current point. - * - * @param x2 x-coordinate of the second control point - * @param y2 y-coordinate of the second control point - * @param x3 x-coordinaat of the ending point (= new current point) - * @param y3 y-coordinaat of the ending point (= new current point) - */ - - public void curveTo(float x2, float y2, float x3, float y3) { - content.append(x2).append(' ').append(y2).append(' ').append(x3).append(' ').append(y3).append(" v").append_i(separator); - } - - /** - * Appends a Bêzier curve to the path, starting from the current point. - * - * @param x1 x-coordinate of the first control point - * @param y1 y-coordinate of the first control point - * @param x3 x-coordinaat of the ending point (= new current point) - * @param y3 y-coordinaat of the ending point (= new current point) - */ - - public void curveFromTo(float x1, float y1, float x3, float y3) { - content.append(x1).append(' ').append(y1).append(' ').append(x3).append(' ').append(y3).append(" y").append_i(separator); - } - - /** Draws a circle. The endpoint will (x+r, y). - * - * @param x x center of circle - * @param y y center of circle - * @param r radius of circle - */ - public void circle(float x, float y, float r) { - float b = 0.5523f; - moveTo(x + r, y); - curveTo(x + r, y + r * b, x + r * b, y + r, x, y + r); - curveTo(x - r * b, y + r, x - r, y + r * b, x - r, y); - curveTo(x - r, y - r * b, x - r * b, y - r, x, y - r); - curveTo(x + r * b, y - r, x + r, y - r * b, x + r, y); - } - - - - /** - * Adds a rectangle to the current path. - * - * @param x x-coordinate of the starting point - * @param y y-coordinate of the starting point - * @param w width - * @param h height - */ - - public void rectangle(float x, float y, float w, float h) { - content.append(x).append(' ').append(y).append(' ').append(w).append(' ').append(h).append(" re").append_i(separator); - } - - private boolean compareColors(Color c1, Color c2) { - if (c1 == null && c2 == null) - return true; - if (c1 == null || c2 == null) - return false; - if (c1 instanceof ExtendedColor) - return c1.equals(c2); - return c2.equals(c1); - } - - /** - * Adds a variable width border to the current path. - * Only use if {@link com.lowagie.text.Rectangle#isUseVariableBorders() Rectangle.isUseVariableBorders} - * = true. - * @param rect a Rectangle - */ - public void variableRectangle(Rectangle rect) { - float t = rect.top(); - float b = rect.bottom(); - float r = rect.right(); - float l = rect.left(); - float wt = rect.getBorderWidthTop(); - float wb = rect.getBorderWidthBottom(); - float wr = rect.getBorderWidthRight(); - float wl = rect.getBorderWidthLeft(); - Color ct = rect.getBorderColorTop(); - Color cb = rect.getBorderColorBottom(); - Color cr = rect.getBorderColorRight(); - Color cl = rect.getBorderColorLeft(); - saveState(); - setLineCap(PdfContentByte.LINE_CAP_BUTT); - setLineJoin(PdfContentByte.LINE_JOIN_MITER); - float clw = 0; - boolean cdef = false; - Color ccol = null; - boolean cdefi = false; - Color cfil = null; - // draw top - if (wt > 0) { - setLineWidth(clw = wt); - cdef = true; - if (ct == null) - resetRGBColorStroke(); - else - setColorStroke(ct); - ccol = ct; - moveTo(l, t - wt / 2f); - lineTo(r, t - wt / 2f); - stroke(); - } - - // Draw bottom - if (wb > 0) { - if (wb != clw) - setLineWidth(clw = wb); - if (!cdef || !compareColors(ccol, cb)) { - cdef = true; - if (cb == null) - resetRGBColorStroke(); - else - setColorStroke(cb); - ccol = cb; - } - moveTo(r, b + wb / 2f); - lineTo(l, b + wb / 2f); - stroke(); - } - - // Draw right - if (wr > 0) { - if (wr != clw) - setLineWidth(clw = wr); - if (!cdef || !compareColors(ccol, cr)) { - cdef = true; - if (cr == null) - resetRGBColorStroke(); - else - setColorStroke(cr); - ccol = cr; - } - boolean bt = compareColors(ct, cr); - boolean bb = compareColors(cb, cr); - moveTo(r - wr / 2f, bt ? t : t - wt); - lineTo(r - wr / 2f, bb ? b : b + wb); - stroke(); - if (!bt || !bb) { - cdefi = true; - if (cr == null) - resetRGBColorFill(); - else - setColorFill(cr); - cfil = cr; - if (!bt) { - moveTo(r, t); - lineTo(r, t - wt); - lineTo(r - wr, t - wt); - fill(); - } - if (!bb) { - moveTo(r, b); - lineTo(r, b + wb); - lineTo(r - wr, b + wb); - fill(); - } - } - } - - // Draw Left - if (wl > 0) { - if (wl != clw) - setLineWidth(wl); - if (!cdef || !compareColors(ccol, cl)) { - if (cl == null) - resetRGBColorStroke(); - else - setColorStroke(cl); - } - boolean bt = compareColors(ct, cl); - boolean bb = compareColors(cb, cl); - moveTo(l + wl / 2f, bt ? t : t - wt); - lineTo(l + wl / 2f, bb ? b : b + wb); - stroke(); - if (!bt || !bb) { - if (!cdefi || !compareColors(cfil, cl)) { - if (cl == null) - resetRGBColorFill(); - else - setColorFill(cl); - } - if (!bt) { - moveTo(l, t); - lineTo(l, t - wt); - lineTo(l + wl, t - wt); - fill(); - } - if (!bb) { - moveTo(l, b); - lineTo(l, b + wb); - lineTo(l + wl, b + wb); - fill(); - } - } - } - restoreState(); - } - - /** - * Adds a border (complete or partially) to the current path.. - * - * @param rectangle a Rectangle - */ - - public void rectangle(Rectangle rectangle) { - // the coordinates of the border are retrieved - float x1 = rectangle.left(); - float y1 = rectangle.bottom(); - float x2 = rectangle.right(); - float y2 = rectangle.top(); - - // the backgroundcolor is set - Color background = rectangle.backgroundColor(); - if (background != null) { - setColorFill(background); - rectangle(x1, y1, x2 - x1, y2 - y1); - fill(); - resetRGBColorFill(); - } - - // if the element hasn't got any borders, nothing is added - if (! rectangle.hasBorders()) { - return; - } - - // if any of the individual border colors are set - // we draw the borders all around using the - // different colors - if (rectangle.isUseVariableBorders()) { - variableRectangle(rectangle); - } - else { - // the width is set to the width of the element - if (rectangle.borderWidth() != Rectangle.UNDEFINED) { - setLineWidth(rectangle.borderWidth()); - } - - // the color is set to the color of the element - Color color = rectangle.borderColor(); - if (color != null) { - setColorStroke(color); - } - - // if the box is a rectangle, it is added as a rectangle - if (rectangle.hasBorder(Rectangle.BOX)) { - rectangle(x1, y1, x2 - x1, y2 - y1); - } - // if the border isn't a rectangle, the different sides are added apart - else { - if (rectangle.hasBorder(Rectangle.RIGHT)) { - moveTo(x2, y1); - lineTo(x2, y2); - } - if (rectangle.hasBorder(Rectangle.LEFT)) { - moveTo(x1, y1); - lineTo(x1, y2); - } - if (rectangle.hasBorder(Rectangle.BOTTOM)) { - moveTo(x1, y1); - lineTo(x2, y1); - } - if (rectangle.hasBorder(Rectangle.TOP)) { - moveTo(x1, y2); - lineTo(x2, y2); - } - } - - stroke(); - - if (color != null) { - resetRGBColorStroke(); - } - } - } - - /** - * Closes the current subpath by appending a straight line segment from the current point - * to the starting point of the subpath. - */ - - public void closePath() { - content.append("h").append_i(separator); - } - - /** - * Ends the path without filling or stroking it. - */ - - public void newPath() { - content.append("n").append_i(separator); - } - - /** - * Strokes the path. - */ - - public void stroke() { - content.append("S").append_i(separator); - } - - /** - * Closes the path and strokes it. - */ - - public void closePathStroke() { - content.append("s").append_i(separator); - } - - /** - * Fills the path, using the non-zero winding number rule to determine the region to fill. - */ - - public void fill() { - content.append("f").append_i(separator); - } - - /** - * Fills the path, using the even-odd rule to determine the region to fill. - */ - - public void eoFill() { - content.append("f*").append_i(separator); - } - - /** - * Fills the path using the non-zero winding number rule to determine the region to fill and strokes it. - */ - - public void fillStroke() { - content.append("B").append_i(separator); - } - - /** - * Closes the path, fills it using the non-zero winding number rule to determine the region to fill and strokes it. - */ - - public void closePathFillStroke() { - content.append("b").append_i(separator); - } - - /** - * Fills the path, using the even-odd rule to determine the region to fill and strokes it. - */ - - public void eoFillStroke() { - content.append("B*").append_i(separator); - } - - /** - * Closes the path, fills it using the even-odd rule to determine the region to fill and strokes it. - */ - - public void closePathEoFillStroke() { - content.append("b*").append_i(separator); - } - - /** - * Adds an Image to the page. The Image must have - * absolute positioning. - * @param image the Image object - * @throws DocumentException if the Image does not have absolute positioning - */ - public void addImage(Image image) throws DocumentException { - addImage(image, false); - } - - /** - * Adds an Image to the page. The Image must have - * absolute positioning. The image can be placed inline. - * @param image the Image object - * @param inlineImage true to place this image inline, false otherwise - * @throws DocumentException if the Image does not have absolute positioning - */ - public void addImage(Image image, boolean inlineImage) throws DocumentException { - if (!image.hasAbsolutePosition()) - throw new DocumentException("The image must have absolute positioning."); - float matrix[] = image.matrix(); - matrix[Image.CX] = image.absoluteX() - matrix[Image.CX]; - matrix[Image.CY] = image.absoluteY() - matrix[Image.CY]; - addImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], inlineImage); - } - - /** - * Adds an Image to the page. The positioning of the Image - * is done with the transformation matrix. To position an image at (x,y) - * use addImage(image, image_width, 0, 0, image_height, x, y). - * @param image the Image object - * @param a an element of the transformation matrix - * @param b an element of the transformation matrix - * @param c an element of the transformation matrix - * @param d an element of the transformation matrix - * @param e an element of the transformation matrix - * @param f an element of the transformation matrix - * @throws DocumentException on error - */ - public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { - addImage(image, a, b, c, d, e, f, false); - } - - /** - * Adds an Image to the page. The positioning of the Image - * is done with the transformation matrix. To position an image at (x,y) - * use addImage(image, image_width, 0, 0, image_height, x, y). The image can be placed inline. - * @param image the Image object - * @param a an element of the transformation matrix - * @param b an element of the transformation matrix - * @param c an element of the transformation matrix - * @param d an element of the transformation matrix - * @param e an element of the transformation matrix - * @param f an element of the transformation matrix - * @param inlineImage true to place this image inline, false otherwise - * @throws DocumentException on error - */ - public void addImage(Image image, float a, float b, float c, float d, float e, float f, boolean inlineImage) throws DocumentException { - try { - if (image.getLayer() != null) - beginLayer(image.getLayer()); - if (image.isImgTemplate()) { - writer.addDirectImageSimple(image); - PdfTemplate template = image.templateData(); - float w = template.getWidth(); - float h = template.getHeight(); - addTemplate(template, a / w, b / w, c / h, d / h, e, f); - } - else { - content.append("q "); - content.append(a).append(' '); - content.append(b).append(' '); - content.append(c).append(' '); - content.append(d).append(' '); - content.append(e).append(' '); - content.append(f).append(" cm"); - if (inlineImage) { - content.append("\nBI\n"); - PdfImage pimage = new PdfImage(image, "", null); - for (Iterator it = pimage.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - PdfObject value = pimage.get(key); - String s = (String)abrev.get(key); - if (s == null) - continue; - content.append(s); - boolean check = true; - if (key.equals(PdfName.COLORSPACE) && value.isArray()) { - ArrayList ar = ((PdfArray)value).getArrayList(); - if (ar.size() == 4 - && PdfName.INDEXED.equals(ar.get(0)) - && ((PdfObject)ar.get(1)).isName() - && ((PdfObject)ar.get(2)).isNumber() - && ((PdfObject)ar.get(3)).isString() - ) { - check = false; - } - - } - if (check && key.equals(PdfName.COLORSPACE) && !value.isName()) { - PdfName cs = writer.getColorspaceName(); - PageResources prs = getPageResources(); - prs.addColor(cs, writer.addToBody(value).getIndirectReference()); - value = cs; - } - value.toPdf(null, content); - content.append('\n'); - } - content.append("ID\n"); - pimage.writeContent(content); - content.append("\nEI\nQ").append_i(separator); - } - else { - PdfName name; - PageResources prs = getPageResources(); - Image maskImage = image.getImageMask(); - if (maskImage != null) { - name = writer.addDirectImageSimple(maskImage); - prs.addXObject(name, writer.getImageReference(name)); - } - name = writer.addDirectImageSimple(image); - name = prs.addXObject(name, writer.getImageReference(name)); - content.append(' ').append(name.getBytes()).append(" Do Q").append_i(separator); - } - } - if (image.hasBorders()) { - saveState(); - float w = image.width(); - float h = image.height(); - concatCTM(a / w, b / w, c / h, d / h, e, f); - rectangle(image); - restoreState(); - } - if (image.getLayer() != null) - endLayer(); - Annotation annot = image.annotation(); - if (annot == null) - return; - float[] r = new float[unitRect.length]; - for (int k = 0; k < unitRect.length; k += 2) { - r[k] = a * unitRect[k] + c * unitRect[k + 1] + e; - r[k + 1] = b * unitRect[k] + d * unitRect[k + 1] + f; - } - float llx = r[0]; - float lly = r[1]; - float urx = llx; - float ury = lly; - for (int k = 2; k < r.length; k += 2) { - llx = Math.min(llx, r[k]); - lly = Math.min(lly, r[k + 1]); - urx = Math.max(urx, r[k]); - ury = Math.max(ury, r[k + 1]); - } - annot = new Annotation(annot); - annot.setDimensions(llx, lly, urx, ury); - PdfAnnotation an = PdfDocument.convertAnnotation(writer, annot); - if (an == null) - return; - addAnnotation(an); - } - catch (Exception ee) { - throw new DocumentException(ee); - } - } - - /** - * Makes this PdfContentByte empty. - */ - public void reset() { - content.reset(); - stateList.clear(); - state = new GraphicState(); - } - - /** - * Starts the writing of text. - */ - public void beginText() { - state.xTLM = 0; - state.yTLM = 0; - content.append("BT").append_i(separator); - } - - /** - * Ends the writing of text and makes the current font invalid. - */ - public void endText() { - content.append("ET").append_i(separator); - } - - /** - * Saves the graphic state. saveState and - * restoreState must be balanced. - */ - public void saveState() { - content.append("q").append_i(separator); - stateList.add(new GraphicState(state)); - } - - /** - * Restores the graphic state. saveState and - * restoreState must be balanced. - */ - public void restoreState() { - content.append("Q").append_i(separator); - int idx = stateList.size() - 1; - if (idx < 0) - throw new RuntimeException("Unbalanced save/restore state operators."); - state = (GraphicState)stateList.get(idx); - stateList.remove(idx); - } - - /** - * Sets the character spacing parameter. - * - * @param charSpace a parameter - */ - public void setCharacterSpacing(float charSpace) { - state.charSpace = charSpace; - content.append(charSpace).append(" Tc").append_i(separator); - } - - /** - * Sets the word spacing parameter. - * - * @param wordSpace a parameter - */ - public void setWordSpacing(float wordSpace) { - state.wordSpace = wordSpace; - content.append(wordSpace).append(" Tw").append_i(separator); - } - - /** - * Sets the horizontal scaling parameter. - * - * @param scale a parameter - */ - public void setHorizontalScaling(float scale) { - state.scale = scale; - content.append(scale).append(" Tz").append_i(separator); - } - - /** - * Sets the text leading parameter. - *

- * The leading parameter is measured in text space units. It specifies the vertical distance - * between the baselines of adjacent lines of text.

- * - * @param leading the new leading - */ - public void setLeading(float leading) { - state.leading = leading; - content.append(leading).append(" TL").append_i(separator); - } - - /** - * Set the font and the size for the subsequent text writing. - * - * @param bf the font - * @param size the font size in points - */ - public void setFontAndSize(BaseFont bf, float size) { - checkWriter(); - state.size = size; - state.fontDetails = writer.addSimple(bf); - PageResources prs = getPageResources(); - PdfName name = state.fontDetails.getFontName(); - name = prs.addFont(name, state.fontDetails.getIndirectReference()); - content.append(name.getBytes()).append(' ').append(size).append(" Tf").append_i(separator); - } - - /** - * Sets the text rendering parameter. - * - * @param rendering a parameter - */ - public void setTextRenderingMode(int rendering) { - content.append(rendering).append(" Tr").append_i(separator); - } - - /** - * Sets the text rise parameter. - *

- * This allows to write text in subscript or superscript mode.

- * - * @param rise a parameter - */ - public void setTextRise(float rise) { - content.append(rise).append(" Ts").append_i(separator); - } - - /** - * A helper to insert into the content stream the text - * converted to bytes according to the font's encoding. - * - * @param text the text to write - */ - private void showText2(String text) { - if (state.fontDetails == null) - throw new NullPointerException("Font and size must be set before writing any text"); - byte b[] = state.fontDetails.convertToBytes(text); - escapeString(b, content); - } - - /** - * Shows the text. - * - * @param text the text to write - */ - public void showText(String text) { - showText2(text); - content.append("Tj").append_i(separator); - } - - /** - * Constructs a kern array for a text in a certain font - * @param text the text - * @param font the font - * @return a PdfTextArray - */ - public static PdfTextArray getKernArray(String text, BaseFont font) { - PdfTextArray pa = new PdfTextArray(); - StringBuffer acc = new StringBuffer(); - int len = text.length() - 1; - char c[] = text.toCharArray(); - if (len >= 0) - acc.append(c, 0, 1); - for (int k = 0; k < len; ++k) { - char c2 = c[k + 1]; - int kern = font.getKerning(c[k], c2); - if (kern == 0) { - acc.append(c2); - } - else { - pa.add(acc.toString()); - acc.setLength(0); - acc.append(c, k + 1, 1); - pa.add(-kern); - } - } - pa.add(acc.toString()); - return pa; - } - - /** - * Shows the text kerned. - * - * @param text the text to write - */ - public void showTextKerned(String text) { - if (state.fontDetails == null) - throw new NullPointerException("Font and size must be set before writing any text"); - BaseFont bf = state.fontDetails.getBaseFont(); - if (bf.hasKernPairs()) - showText(getKernArray(text, bf)); - else - showText(text); - } - - /** - * Moves to the next line and shows text. - * - * @param text the text to write - */ - public void newlineShowText(String text) { - state.yTLM -= state.leading; - showText2(text); - content.append("'").append_i(separator); - } - - /** - * Moves to the next line and shows text string, using the given values of the character and word spacing parameters. - * - * @param wordSpacing a parameter - * @param charSpacing a parameter - * @param text the text to write - */ - public void newlineShowText(float wordSpacing, float charSpacing, String text) { - state.yTLM -= state.leading; - content.append(wordSpacing).append(' ').append(charSpacing); - showText2(text); - content.append("\"").append_i(separator); - - // The " operator sets charSpace and wordSpace into graphics state - // (cfr PDF reference v1.6, table 5.6) - state.charSpace = charSpacing; - state.wordSpace = wordSpacing; - } - - /** - * Changes the text matrix. - *

- * Remark: this operation also initializes the current point position.

- * - * @param a operand 1,1 in the matrix - * @param b operand 1,2 in the matrix - * @param c operand 2,1 in the matrix - * @param d operand 2,2 in the matrix - * @param x operand 3,1 in the matrix - * @param y operand 3,2 in the matrix - */ - public void setTextMatrix(float a, float b, float c, float d, float x, float y) { - state.xTLM = x; - state.yTLM = y; - content.append(a).append(' ').append(b).append_i(' ') - .append(c).append_i(' ').append(d).append_i(' ') - .append(x).append_i(' ').append(y).append(" Tm").append_i(separator); - } - - /** - * Changes the text matrix. The first four parameters are {1,0,0,1}. - *

- * Remark: this operation also initializes the current point position.

- * - * @param x operand 3,1 in the matrix - * @param y operand 3,2 in the matrix - */ - public void setTextMatrix(float x, float y) { - setTextMatrix(1, 0, 0, 1, x, y); - } - - /** - * Moves to the start of the next line, offset from the start of the current line. - * - * @param x x-coordinate of the new current point - * @param y y-coordinate of the new current point - */ - public void moveText(float x, float y) { - state.xTLM += x; - state.yTLM += y; - content.append(x).append(' ').append(y).append(" Td").append_i(separator); - } - - /** - * Moves to the start of the next line, offset from the start of the current line. - *

- * As a side effect, this sets the leading parameter in the text state.

- * - * @param x offset of the new current point - * @param y y-coordinate of the new current point - */ - public void moveTextWithLeading(float x, float y) { - state.xTLM += x; - state.yTLM += y; - state.leading = -y; - content.append(x).append(' ').append(y).append(" TD").append_i(separator); - } - - /** - * Moves to the start of the next line. - */ - public void newlineText() { - state.yTLM -= state.leading; - content.append("T*").append_i(separator); - } - - /** - * Gets the size of this content. - * - * @return the size of the content - */ - int size() { - return content.size(); - } - - /** - * Escapes a byte array according to the PDF conventions. - * - * @param b the byte array to escape - * @return an escaped byte array - */ - static byte[] escapeString(byte b[]) { - ByteBuffer content = new ByteBuffer(); - escapeString(b, content); - return content.toByteArray(); - } - - /** - * Escapes a byte array according to the PDF conventions. - * - * @param b the byte array to escape - * @param content the content - */ - static void escapeString(byte b[], ByteBuffer content) { - content.append_i('('); - for (int k = 0; k < b.length; ++k) { - byte c = b[k]; - switch ((int)c) { - case '\r': - content.append("\\r"); - break; - case '\n': - content.append("\\n"); - break; - case '\t': - content.append("\\t"); - break; - case '\b': - content.append("\\b"); - break; - case '\f': - content.append("\\f"); - break; - case '(': - case ')': - case '\\': - content.append_i('\\').append_i(c); - break; - default: - content.append_i(c); - } - } - content.append(")"); - } - - /** - * Adds an outline to the document. - * - * @param outline the outline - * @deprecated not needed anymore. The outlines are extracted - * from the root outline - */ - public void addOutline(PdfOutline outline) { - // for compatibility - } - /** - * Adds a named outline to the document. - * - * @param outline the outline - * @param name the name for the local destination - */ - public void addOutline(PdfOutline outline, String name) { - checkWriter(); - pdf.addOutline(outline, name); - } - /** - * Gets the root outline. - * - * @return the root outline - */ - public PdfOutline getRootOutline() { - checkWriter(); - return pdf.getRootOutline(); - } - - /** - * Computes the width of the given string taking in account - * the current values of "Character spacing", "Word Spacing" - * and "Horizontal Scaling". - * The additional spacing is not computed for the last character - * of the string. - * @param text the string to get width of - * @param kerned the kerning option - * @return the width - */ - - public float getEffectiveStringWidth(String text, boolean kerned) { - BaseFont bf = state.fontDetails.getBaseFont(); - - float w; - if (kerned) - w = bf.getWidthPointKerned(text, state.size); - else - w = bf.getWidthPoint(text, state.size); - - if (state.charSpace != 0.0f && text.length() > 1) { - w += state.charSpace * (text.length() -1); - } - - int ft = bf.getFontType(); - if (state.wordSpace != 0.0f && (ft == BaseFont.FONT_TYPE_T1 || ft == BaseFont.FONT_TYPE_TT || ft == BaseFont.FONT_TYPE_T3)) { - for (int i = 0; i < (text.length() -1); i++) { - if (text.charAt(i) == ' ') - w += state.wordSpace; - } - } - if (state.scale != 100.0) - w = (w * state.scale) / 100.0f; - - //System.out.println("String width = " + Float.toString(w)); - return w; - } - - /** - * Shows text right, left or center aligned with rotation. - * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT - * @param text the text to show - * @param x the x pivot position - * @param y the y pivot position - * @param rotation the rotation to be applied in degrees counterclockwise - */ - public void showTextAligned(int alignment, String text, float x, float y, float rotation) { - showTextAligned(alignment, text, x, y, rotation, false); - } - - private void showTextAligned(int alignment, String text, float x, float y, float rotation, boolean kerned) { - if (state.fontDetails == null) - throw new NullPointerException("Font and size must be set before writing any text"); - if (rotation == 0) { - switch (alignment) { - case ALIGN_CENTER: - x -= getEffectiveStringWidth(text, kerned) / 2; - break; - case ALIGN_RIGHT: - x -= getEffectiveStringWidth(text, kerned); - break; - } - setTextMatrix(x, y); - if (kerned) - showTextKerned(text); - else - showText(text); - } - else { - double alpha = rotation * Math.PI / 180.0; - float cos = (float)Math.cos(alpha); - float sin = (float)Math.sin(alpha); - float len; - switch (alignment) { - case ALIGN_CENTER: - len = getEffectiveStringWidth(text, kerned) / 2; - x -= len * cos; - y -= len * sin; - break; - case ALIGN_RIGHT: - len = getEffectiveStringWidth(text, kerned); - x -= len * cos; - y -= len * sin; - break; - } - setTextMatrix(cos, sin, -sin, cos, x, y); - if (kerned) - showTextKerned(text); - else - showText(text); - setTextMatrix(0f, 0f); - } - } - - /** - * Shows text kerned right, left or center aligned with rotation. - * @param alignment the alignment can be ALIGN_CENTER, ALIGN_RIGHT or ALIGN_LEFT - * @param text the text to show - * @param x the x pivot position - * @param y the y pivot position - * @param rotation the rotation to be applied in degrees counterclockwise - */ - public void showTextAlignedKerned(int alignment, String text, float x, float y, float rotation) { - showTextAligned(alignment, text, x, y, rotation, true); - } - - /** - * Concatenate a matrix to the current transformation matrix. - * @param a an element of the transformation matrix - * @param b an element of the transformation matrix - * @param c an element of the transformation matrix - * @param d an element of the transformation matrix - * @param e an element of the transformation matrix - * @param f an element of the transformation matrix - **/ - public void concatCTM(float a, float b, float c, float d, float e, float f) { - content.append(a).append(' ').append(b).append(' ').append(c).append(' '); - content.append(d).append(' ').append(e).append(' ').append(f).append(" cm").append_i(separator); - } - - /** - * Generates an array of bezier curves to draw an arc. - *

- * (x1, y1) and (x2, y2) are the corners of the enclosing rectangle. - * Angles, measured in degrees, start with 0 to the right (the positive X - * axis) and increase counter-clockwise. The arc extends from startAng - * to startAng+extent. I.e. startAng=0 and extent=180 yields an openside-down - * semi-circle. - *

- * The resulting coordinates are of the form float[]{x1,y1,x2,y2,x3,y3, x4,y4} - * such that the curve goes from (x1, y1) to (x4, y4) with (x2, y2) and - * (x3, y3) as their respective Bezier control points. - *

- * Note: this code was taken from ReportLab (www.reportlab.com), an excelent - * PDF generator for Python. - * - * @param x1 a corner of the enclosing rectangle - * @param y1 a corner of the enclosing rectangle - * @param x2 a corner of the enclosing rectangle - * @param y2 a corner of the enclosing rectangle - * @param startAng starting angle in degrees - * @param extent angle extent in degrees - * @return a list of float[] with the bezier curves - */ - public static ArrayList bezierArc(float x1, float y1, float x2, float y2, float startAng, float extent) { - float tmp; - if (x1 > x2) { - tmp = x1; - x1 = x2; - x2 = tmp; - } - if (y2 > y1) { - tmp = y1; - y1 = y2; - y2 = tmp; - } - - float fragAngle; - int Nfrag; - if (Math.abs(extent) <= 90f) { - fragAngle = extent; - Nfrag = 1; - } - else { - Nfrag = (int)(Math.ceil(Math.abs(extent)/90f)); - fragAngle = extent / Nfrag; - } - float x_cen = (x1+x2)/2f; - float y_cen = (y1+y2)/2f; - float rx = (x2-x1)/2f; - float ry = (y2-y1)/2f; - float halfAng = (float)(fragAngle * Math.PI / 360.); - float kappa = (float)(Math.abs(4. / 3. * (1. - Math.cos(halfAng)) / Math.sin(halfAng))); - ArrayList pointList = new ArrayList(); - for (int i = 0; i < Nfrag; ++i) { - float theta0 = (float)((startAng + i*fragAngle) * Math.PI / 180.); - float theta1 = (float)((startAng + (i+1)*fragAngle) * Math.PI / 180.); - float cos0 = (float)Math.cos(theta0); - float cos1 = (float)Math.cos(theta1); - float sin0 = (float)Math.sin(theta0); - float sin1 = (float)Math.sin(theta1); - if (fragAngle > 0f) { - pointList.add(new float[]{x_cen + rx * cos0, - y_cen - ry * sin0, - x_cen + rx * (cos0 - kappa * sin0), - y_cen - ry * (sin0 + kappa * cos0), - x_cen + rx * (cos1 + kappa * sin1), - y_cen - ry * (sin1 - kappa * cos1), - x_cen + rx * cos1, - y_cen - ry * sin1}); - } - else { - pointList.add(new float[]{x_cen + rx * cos0, - y_cen - ry * sin0, - x_cen + rx * (cos0 + kappa * sin0), - y_cen - ry * (sin0 - kappa * cos0), - x_cen + rx * (cos1 - kappa * sin1), - y_cen - ry * (sin1 + kappa * cos1), - x_cen + rx * cos1, - y_cen - ry * sin1}); - } - } - return pointList; - } - - /** - * Draws a partial ellipse inscribed within the rectangle x1,y1,x2,y2, - * starting at startAng degrees and covering extent degrees. Angles - * start with 0 to the right (+x) and increase counter-clockwise. - * - * @param x1 a corner of the enclosing rectangle - * @param y1 a corner of the enclosing rectangle - * @param x2 a corner of the enclosing rectangle - * @param y2 a corner of the enclosing rectangle - * @param startAng starting angle in degrees - * @param extent angle extent in degrees - */ - public void arc(float x1, float y1, float x2, float y2, float startAng, float extent) { - ArrayList ar = bezierArc(x1, y1, x2, y2, startAng, extent); - if (ar.size() == 0) - return; - float pt[] = (float [])ar.get(0); - moveTo(pt[0], pt[1]); - for (int k = 0; k < ar.size(); ++k) { - pt = (float [])ar.get(k); - curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]); - } - } - - /** - * Draws an ellipse inscribed within the rectangle x1,y1,x2,y2. - * - * @param x1 a corner of the enclosing rectangle - * @param y1 a corner of the enclosing rectangle - * @param x2 a corner of the enclosing rectangle - * @param y2 a corner of the enclosing rectangle - */ - public void ellipse(float x1, float y1, float x2, float y2) { - arc(x1, y1, x2, y2, 0f, 360f); - } - - /** - * Create a new colored tiling pattern. - * - * @param width the width of the pattern - * @param height the height of the pattern - * @param xstep the desired horizontal spacing between pattern cells. - * May be either positive or negative, but not zero. - * @param ystep the desired vertical spacing between pattern cells. - * May be either positive or negative, but not zero. - * @return the PdfPatternPainter where the pattern will be created - */ - public PdfPatternPainter createPattern(float width, float height, float xstep, float ystep) { - checkWriter(); - if ( xstep == 0.0f || ystep == 0.0f ) - throw new RuntimeException("XStep or YStep can not be ZERO."); - PdfPatternPainter painter = new PdfPatternPainter(writer); - painter.setWidth(width); - painter.setHeight(height); - painter.setXStep(xstep); - painter.setYStep(ystep); - writer.addSimplePattern(painter); - return painter; - } - - /** - * Create a new colored tiling pattern. Variables xstep and ystep are set to the same values - * of width and height. - * @param width the width of the pattern - * @param height the height of the pattern - * @return the PdfPatternPainter where the pattern will be created - */ - public PdfPatternPainter createPattern(float width, float height) { - return createPattern(width, height, width, height); - } - - /** - * Create a new uncolored tiling pattern. - * - * @param width the width of the pattern - * @param height the height of the pattern - * @param xstep the desired horizontal spacing between pattern cells. - * May be either positive or negative, but not zero. - * @param ystep the desired vertical spacing between pattern cells. - * May be either positive or negative, but not zero. - * @param color the default color. Can be null - * @return the PdfPatternPainter where the pattern will be created - */ - public PdfPatternPainter createPattern(float width, float height, float xstep, float ystep, Color color) { - checkWriter(); - if ( xstep == 0.0f || ystep == 0.0f ) - throw new RuntimeException("XStep or YStep can not be ZERO."); - PdfPatternPainter painter = new PdfPatternPainter(writer, color); - painter.setWidth(width); - painter.setHeight(height); - painter.setXStep(xstep); - painter.setYStep(ystep); - writer.addSimplePattern(painter); - return painter; - } - - /** - * Create a new uncolored tiling pattern. - * Variables xstep and ystep are set to the same values - * of width and height. - * @param width the width of the pattern - * @param height the height of the pattern - * @param color the default color. Can be null - * @return the PdfPatternPainter where the pattern will be created - */ - public PdfPatternPainter createPattern(float width, float height, Color color) { - return createPattern(width, height, width, height, color); - } - - /** - * Creates a new template. - *

- * Creates a new template that is nothing more than a form XObject. This template can be included - * in this PdfContentByte or in another template. Templates are only written - * to the output when the document is closed permitting things like showing text in the first page - * that is only defined in the last page. - * - * @param width the bounding box width - * @param height the bounding box height - * @return the templated created - */ - public PdfTemplate createTemplate(float width, float height) { - return createTemplate(width, height, null); - } - - PdfTemplate createTemplate(float width, float height, PdfName forcedName) { - checkWriter(); - PdfTemplate template = new PdfTemplate(writer); - template.setWidth(width); - template.setHeight(height); - writer.addDirectTemplateSimple(template, forcedName); - return template; - } - - /** - * Creates a new appearance to be used with form fields. - * - * @param width the bounding box width - * @param height the bounding box height - * @return the appearance created - */ - public PdfAppearance createAppearance(float width, float height) { - return createAppearance(width, height, null); - } - - PdfAppearance createAppearance(float width, float height, PdfName forcedName) { - checkWriter(); - PdfAppearance template = new PdfAppearance(writer); - template.setWidth(width); - template.setHeight(height); - writer.addDirectTemplateSimple(template, forcedName); - return template; - } - - /** - * Adds a PostScript XObject to this content. - * - * @param psobject the object - */ - public void addPSXObject(PdfPSXObject psobject) { - checkWriter(); - PdfName name = writer.addDirectTemplateSimple(psobject, null); - PageResources prs = getPageResources(); - name = prs.addXObject(name, psobject.getIndirectReference()); - content.append(name.getBytes()).append(" Do").append_i(separator); - } - - /** - * Adds a template to this content. - * - * @param template the template - * @param a an element of the transformation matrix - * @param b an element of the transformation matrix - * @param c an element of the transformation matrix - * @param d an element of the transformation matrix - * @param e an element of the transformation matrix - * @param f an element of the transformation matrix - */ - public void addTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) { - checkWriter(); - checkNoPattern(template); - PdfName name = writer.addDirectTemplateSimple(template, null); - PageResources prs = getPageResources(); - name = prs.addXObject(name, template.getIndirectReference()); - content.append("q "); - content.append(a).append(' '); - content.append(b).append(' '); - content.append(c).append(' '); - content.append(d).append(' '); - content.append(e).append(' '); - content.append(f).append(" cm "); - content.append(name.getBytes()).append(" Do Q").append_i(separator); - } - - /** - * Adds a template to this content. - * - * @param template the template - * @param x the x location of this template - * @param y the y location of this template - */ - public void addTemplate(PdfTemplate template, float x, float y) { - addTemplate(template, 1, 0, 0, 1, x, y); - } - - /** - * Changes the current color for filling paths (device dependent colors!). - *

- * Sets the color space to DeviceCMYK (or the DefaultCMYK color space), - * and sets the color to use for filling paths.

- *

- * This method is described in the 'Portable Document Format Reference Manual version 1.3' - * section 8.5.2.1 (page 331).

- *

- * Following the PDF manual, each operand must be a number between 0 (no ink) and - * 1 (maximum ink). This method however accepts only integers between 0x00 and 0xFF.

- * - * @param cyan the intensity of cyan - * @param magenta the intensity of magenta - * @param yellow the intensity of yellow - * @param black the intensity of black - */ - - public void setCMYKColorFill(int cyan, int magenta, int yellow, int black) { - content.append((float)(cyan & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(magenta & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(yellow & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(black & 0xFF) / 0xFF); - content.append(" k").append_i(separator); - } - /** - * Changes the current color for stroking paths (device dependent colors!). - *

- * Sets the color space to DeviceCMYK (or the DefaultCMYK color space), - * and sets the color to use for stroking paths.

- *

- * This method is described in the 'Portable Document Format Reference Manual version 1.3' - * section 8.5.2.1 (page 331).

- * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and - * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF. - * - * @param cyan the intensity of red - * @param magenta the intensity of green - * @param yellow the intensity of blue - * @param black the intensity of black - */ - - public void setCMYKColorStroke(int cyan, int magenta, int yellow, int black) { - content.append((float)(cyan & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(magenta & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(yellow & 0xFF) / 0xFF); - content.append(' '); - content.append((float)(black & 0xFF) / 0xFF); - content.append(" K").append_i(separator); - } - - /** - * Changes the current color for filling paths (device dependent colors!). - *

- * Sets the color space to DeviceRGB (or the DefaultRGB color space), - * and sets the color to use for filling paths.

- *

- * This method is described in the 'Portable Document Format Reference Manual version 1.3' - * section 8.5.2.1 (page 331).

- *

- * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and - * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF.

- * - * @param red the intensity of red - * @param green the intensity of green - * @param blue the intensity of blue - */ - - public void setRGBColorFill(int red, int green, int blue) { - HelperRGB((float)(red & 0xFF) / 0xFF, (float)(green & 0xFF) / 0xFF, (float)(blue & 0xFF) / 0xFF); - content.append(" rg").append_i(separator); - } - - /** - * Changes the current color for stroking paths (device dependent colors!). - *

- * Sets the color space to DeviceRGB (or the DefaultRGB color space), - * and sets the color to use for stroking paths.

- *

- * This method is described in the 'Portable Document Format Reference Manual version 1.3' - * section 8.5.2.1 (page 331).

- * Following the PDF manual, each operand must be a number between 0 (miniumum intensity) and - * 1 (maximum intensity). This method however accepts only integers between 0x00 and 0xFF. - * - * @param red the intensity of red - * @param green the intensity of green - * @param blue the intensity of blue - */ - - public void setRGBColorStroke(int red, int green, int blue) { - HelperRGB((float)(red & 0xFF) / 0xFF, (float)(green & 0xFF) / 0xFF, (float)(blue & 0xFF) / 0xFF); - content.append(" RG").append_i(separator); - } - - /** Sets the stroke color. color can be an - * ExtendedColor. - * @param color the color - */ - public void setColorStroke(Color color) { - PdfWriter.checkPDFXConformance(writer, PdfWriter.PDFXKEY_COLOR, color); - int type = ExtendedColor.getType(color); - switch (type) { - case ExtendedColor.TYPE_GRAY: { - setGrayStroke(((GrayColor)color).getGray()); - break; - } - case ExtendedColor.TYPE_CMYK: { - CMYKColor cmyk = (CMYKColor)color; - setCMYKColorStrokeF(cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()); - break; - } - case ExtendedColor.TYPE_SEPARATION: { - SpotColor spot = (SpotColor)color; - setColorStroke(spot.getPdfSpotColor(), spot.getTint()); - break; - } - case ExtendedColor.TYPE_PATTERN: { - PatternColor pat = (PatternColor) color; - setPatternStroke(pat.getPainter()); - break; - } - case ExtendedColor.TYPE_SHADING: { - ShadingColor shading = (ShadingColor) color; - setShadingStroke(shading.getPdfShadingPattern()); - break; - } - default: - setRGBColorStroke(color.getRed(), color.getGreen(), color.getBlue()); - } - } - - /** Sets the fill color. color can be an - * ExtendedColor. - * @param color the color - */ - public void setColorFill(Color color) { - PdfWriter.checkPDFXConformance(writer, PdfWriter.PDFXKEY_COLOR, color); - int type = ExtendedColor.getType(color); - switch (type) { - case ExtendedColor.TYPE_GRAY: { - setGrayFill(((GrayColor)color).getGray()); - break; - } - case ExtendedColor.TYPE_CMYK: { - CMYKColor cmyk = (CMYKColor)color; - setCMYKColorFillF(cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()); - break; - } - case ExtendedColor.TYPE_SEPARATION: { - SpotColor spot = (SpotColor)color; - setColorFill(spot.getPdfSpotColor(), spot.getTint()); - break; - } - case ExtendedColor.TYPE_PATTERN: { - PatternColor pat = (PatternColor) color; - setPatternFill(pat.getPainter()); - break; - } - case ExtendedColor.TYPE_SHADING: { - ShadingColor shading = (ShadingColor) color; - setShadingFill(shading.getPdfShadingPattern()); - break; - } - default: - setRGBColorFill(color.getRed(), color.getGreen(), color.getBlue()); - } - } - - /** Sets the fill color to a spot color. - * @param sp the spot color - * @param tint the tint for the spot color. 0 is no color and 1 - * is 100% color - */ - public void setColorFill(PdfSpotColor sp, float tint) { - checkWriter(); - state.colorDetails = writer.addSimple(sp); - PageResources prs = getPageResources(); - PdfName name = state.colorDetails.getColorName(); - name = prs.addColor(name, state.colorDetails.getIndirectReference()); - content.append(name.getBytes()).append(" cs ").append(tint).append(" scn").append_i(separator); - } - - /** Sets the stroke color to a spot color. - * @param sp the spot color - * @param tint the tint for the spot color. 0 is no color and 1 - * is 100% color - */ - public void setColorStroke(PdfSpotColor sp, float tint) { - checkWriter(); - state.colorDetails = writer.addSimple(sp); - PageResources prs = getPageResources(); - PdfName name = state.colorDetails.getColorName(); - name = prs.addColor(name, state.colorDetails.getIndirectReference()); - content.append(name.getBytes()).append(" CS ").append(tint).append(" SCN").append_i(separator); - } - - /** Sets the fill color to a pattern. The pattern can be - * colored or uncolored. - * @param p the pattern - */ - public void setPatternFill(PdfPatternPainter p) { - if (p.isStencil()) { - setPatternFill(p, p.getDefaultColor()); - return; - } - checkWriter(); - PageResources prs = getPageResources(); - PdfName name = writer.addSimplePattern(p); - name = prs.addPattern(name, p.getIndirectReference()); - content.append(PdfName.PATTERN.getBytes()).append(" cs ").append(name.getBytes()).append(" scn").append_i(separator); - } - - /** Outputs the color values to the content. - * @param color The color - * @param tint the tint if it is a spot color, ignored otherwise - */ - void outputColorNumbers(Color color, float tint) { - PdfWriter.checkPDFXConformance(writer, PdfWriter.PDFXKEY_COLOR, color); - int type = ExtendedColor.getType(color); - switch (type) { - case ExtendedColor.TYPE_RGB: - content.append((float)(color.getRed()) / 0xFF); - content.append(' '); - content.append((float)(color.getGreen()) / 0xFF); - content.append(' '); - content.append((float)(color.getBlue()) / 0xFF); - break; - case ExtendedColor.TYPE_GRAY: - content.append(((GrayColor)color).getGray()); - break; - case ExtendedColor.TYPE_CMYK: { - CMYKColor cmyk = (CMYKColor)color; - content.append(cmyk.getCyan()).append(' ').append(cmyk.getMagenta()); - content.append(' ').append(cmyk.getYellow()).append(' ').append(cmyk.getBlack()); - break; - } - case ExtendedColor.TYPE_SEPARATION: - content.append(tint); - break; - default: - throw new RuntimeException("Invalid color type."); - } - } - - /** Sets the fill color to an uncolored pattern. - * @param p the pattern - * @param color the color of the pattern - */ - public void setPatternFill(PdfPatternPainter p, Color color) { - if (ExtendedColor.getType(color) == ExtendedColor.TYPE_SEPARATION) - setPatternFill(p, color, ((SpotColor)color).getTint()); - else - setPatternFill(p, color, 0); - } - - /** Sets the fill color to an uncolored pattern. - * @param p the pattern - * @param color the color of the pattern - * @param tint the tint if the color is a spot color, ignored otherwise - */ - public void setPatternFill(PdfPatternPainter p, Color color, float tint) { - checkWriter(); - if (!p.isStencil()) - throw new RuntimeException("An uncolored pattern was expected."); - PageResources prs = getPageResources(); - PdfName name = writer.addSimplePattern(p); - name = prs.addPattern(name, p.getIndirectReference()); - ColorDetails csDetail = writer.addSimplePatternColorspace(color); - PdfName cName = prs.addColor(csDetail.getColorName(), csDetail.getIndirectReference()); - content.append(cName.getBytes()).append(" cs").append_i(separator); - outputColorNumbers(color, tint); - content.append(' ').append(name.getBytes()).append(" scn").append_i(separator); - } - - /** Sets the stroke color to an uncolored pattern. - * @param p the pattern - * @param color the color of the pattern - */ - public void setPatternStroke(PdfPatternPainter p, Color color) { - if (ExtendedColor.getType(color) == ExtendedColor.TYPE_SEPARATION) - setPatternStroke(p, color, ((SpotColor)color).getTint()); - else - setPatternStroke(p, color, 0); - } - - /** Sets the stroke color to an uncolored pattern. - * @param p the pattern - * @param color the color of the pattern - * @param tint the tint if the color is a spot color, ignored otherwise - */ - public void setPatternStroke(PdfPatternPainter p, Color color, float tint) { - checkWriter(); - if (!p.isStencil()) - throw new RuntimeException("An uncolored pattern was expected."); - PageResources prs = getPageResources(); - PdfName name = writer.addSimplePattern(p); - name = prs.addPattern(name, p.getIndirectReference()); - ColorDetails csDetail = writer.addSimplePatternColorspace(color); - PdfName cName = prs.addColor(csDetail.getColorName(), csDetail.getIndirectReference()); - content.append(cName.getBytes()).append(" CS").append_i(separator); - outputColorNumbers(color, tint); - content.append(' ').append(name.getBytes()).append(" SCN").append_i(separator); - } - - /** Sets the stroke color to a pattern. The pattern can be - * colored or uncolored. - * @param p the pattern - */ - public void setPatternStroke(PdfPatternPainter p) { - if (p.isStencil()) { - setPatternStroke(p, p.getDefaultColor()); - return; - } - checkWriter(); - PageResources prs = getPageResources(); - PdfName name = writer.addSimplePattern(p); - name = prs.addPattern(name, p.getIndirectReference()); - content.append(PdfName.PATTERN.getBytes()).append(" CS ").append(name.getBytes()).append(" SCN").append_i(separator); - } - - /** - * Paints using a shading object. - * @param shading the shading object - */ - public void paintShading(PdfShading shading) { - writer.addSimpleShading(shading); - PageResources prs = getPageResources(); - PdfName name = prs.addShading(shading.getShadingName(), shading.getShadingReference()); - content.append(name.getBytes()).append(" sh").append_i(separator); - ColorDetails details = shading.getColorDetails(); - if (details != null) - prs.addColor(details.getColorName(), details.getIndirectReference()); - } - - /** - * Paints using a shading pattern. - * @param shading the shading pattern - */ - public void paintShading(PdfShadingPattern shading) { - paintShading(shading.getShading()); - } - - /** - * Sets the shading fill pattern. - * @param shading the shading pattern - */ - public void setShadingFill(PdfShadingPattern shading) { - writer.addSimpleShadingPattern(shading); - PageResources prs = getPageResources(); - PdfName name = prs.addPattern(shading.getPatternName(), shading.getPatternReference()); - content.append(PdfName.PATTERN.getBytes()).append(" cs ").append(name.getBytes()).append(" scn").append_i(separator); - ColorDetails details = shading.getColorDetails(); - if (details != null) - prs.addColor(details.getColorName(), details.getIndirectReference()); - } - - /** - * Sets the shading stroke pattern - * @param shading the shading pattern - */ - public void setShadingStroke(PdfShadingPattern shading) { - writer.addSimpleShadingPattern(shading); - PageResources prs = getPageResources(); - PdfName name = prs.addPattern(shading.getPatternName(), shading.getPatternReference()); - content.append(PdfName.PATTERN.getBytes()).append(" CS ").append(name.getBytes()).append(" SCN").append_i(separator); - ColorDetails details = shading.getColorDetails(); - if (details != null) - prs.addColor(details.getColorName(), details.getIndirectReference()); - } - - /** Check if we have a valid PdfWriter. - * - */ - protected void checkWriter() { - if (writer == null) - throw new NullPointerException("The writer in PdfContentByte is null."); - } - - /** - * Show an array of text. - * @param text array of text - */ - public void showText(PdfTextArray text) { - if (state.fontDetails == null) - throw new NullPointerException("Font and size must be set before writing any text"); - content.append("["); - ArrayList arrayList = text.getArrayList(); - boolean lastWasNumber = false; - for (int k = 0; k < arrayList.size(); ++k) { - Object obj = arrayList.get(k); - if (obj instanceof String) { - showText2((String)obj); - lastWasNumber = false; - } - else { - if (lastWasNumber) - content.append(' '); - else - lastWasNumber = true; - content.append(((Float)obj).floatValue()); - } - } - content.append("]TJ").append_i(separator); - } - - /** - * Gets the PdfWriter in use by this object. - * @return the PdfWriter in use by this object - */ - public PdfWriter getPdfWriter() { - return writer; - } - - /** - * Gets the PdfDocument in use by this object. - * @return the PdfDocument in use by this object - */ - public PdfDocument getPdfDocument() { - return pdf; - } - - /** - * Implements a link to other part of the document. The jump will - * be made to a local destination with the same name, that must exist. - * @param name the name for this link - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - public void localGoto(String name, float llx, float lly, float urx, float ury) { - pdf.localGoto(name, llx, lly, urx, ury); - } - - /** - * The local destination to where a local goto with the same - * name will jump. - * @param name the name of this local destination - * @param destination the PdfDestination with the jump coordinates - * @return true if the local destination was added, - * false if a local destination with the same name - * already exists - */ - public boolean localDestination(String name, PdfDestination destination) { - return pdf.localDestination(name, destination); - } - - /** - * Gets a duplicate of this PdfContentByte. All - * the members are copied by reference but the buffer stays different. - * - * @return a copy of this PdfContentByte - */ - public PdfContentByte getDuplicate() { - return new PdfContentByte(writer); - } - - /** - * Implements a link to another document. - * @param filename the filename for the remote document - * @param name the name to jump to - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - public void remoteGoto(String filename, String name, float llx, float lly, float urx, float ury) { - pdf.remoteGoto(filename, name, llx, lly, urx, ury); - } - - /** - * Implements a link to another document. - * @param filename the filename for the remote document - * @param page the page to jump to - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - public void remoteGoto(String filename, int page, float llx, float lly, float urx, float ury) { - pdf.remoteGoto(filename, page, llx, lly, urx, ury); - } - /** - * Adds a round rectangle to the current path. - * - * @param x x-coordinate of the starting point - * @param y y-coordinate of the starting point - * @param w width - * @param h height - * @param r radius of the arc corner - */ - public void roundRectangle(float x, float y, float w, float h, float r) { - if (w < 0) { - x += w; - w = -w; - } - if (h < 0) { - y += h; - h = -h; - } - if (r < 0) - r = -r; - float b = 0.4477f; - moveTo(x + r, y); - lineTo(x + w - r, y); - curveTo(x + w - r * b, y, x + w, y + r * b, x + w, y + r); - lineTo(x + w, y + h - r); - curveTo(x + w, y + h - r * b, x + w - r * b, y + h, x + w - r, y + h); - lineTo(x + r, y + h); - curveTo(x + r * b, y + h, x, y + h - r * b, x, y + h - r); - lineTo(x, y + r); - curveTo(x, y + r * b, x + r * b, y, x + r, y); - } - - /** Implements an action in an area. - * @param action the PdfAction - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - public void setAction(PdfAction action, float llx, float lly, float urx, float ury) { - pdf.setAction(action, llx, lly, urx, ury); - } - - /** Outputs a String directly to the content. - * @param s the String - */ - public void setLiteral(String s) { - content.append(s); - } - - /** Outputs a char directly to the content. - * @param c the char - */ - public void setLiteral(char c) { - content.append(c); - } - - /** Outputs a float directly to the content. - * @param n the float - */ - public void setLiteral(float n) { - content.append(n); - } - - /** Throws an error if it is a pattern. - * @param t the object to check - */ - void checkNoPattern(PdfTemplate t) { - if (t.getType() == PdfTemplate.TYPE_PATTERN) - throw new RuntimeException("Invalid use of a pattern. A template was expected."); - } - - /** - * Draws a TextField. - * @param llx - * @param lly - * @param urx - * @param ury - * @param on - */ - public void drawRadioField(float llx, float lly, float urx, float ury, boolean on) { - if (llx > urx) { float x = llx; llx = urx; urx = x; } - if (lly > ury) { float y = lly; lly = ury; ury = y; } - // silver circle - setLineWidth(1); - setLineCap(1); - setColorStroke(new Color(0xC0, 0xC0, 0xC0)); - arc(llx + 1f, lly + 1f, urx - 1f, ury - 1f, 0f, 360f); - stroke(); - // gray circle-segment - setLineWidth(1); - setLineCap(1); - setColorStroke(new Color(0xA0, 0xA0, 0xA0)); - arc(llx + 0.5f, lly + 0.5f, urx - 0.5f, ury - 0.5f, 45, 180); - stroke(); - // black circle-segment - setLineWidth(1); - setLineCap(1); - setColorStroke(new Color(0x00, 0x00, 0x00)); - arc(llx + 1.5f, lly + 1.5f, urx - 1.5f, ury - 1.5f, 45, 180); - stroke(); - if (on) { - // gray circle - setLineWidth(1); - setLineCap(1); - setColorFill(new Color(0x00, 0x00, 0x00)); - arc(llx + 4f, lly + 4f, urx - 4f, ury - 4f, 0, 360); - fill(); - } - } - - /** - * Draws a TextField. - * @param llx - * @param lly - * @param urx - * @param ury - */ - public void drawTextField(float llx, float lly, float urx, float ury) { - if (llx > urx) { float x = llx; llx = urx; urx = x; } - if (lly > ury) { float y = lly; lly = ury; ury = y; } - // silver rectangle not filled - setColorStroke(new Color(0xC0, 0xC0, 0xC0)); - setLineWidth(1); - setLineCap(0); - rectangle(llx, lly, urx - llx, ury - lly); - stroke(); - // white rectangle filled - setLineWidth(1); - setLineCap(0); - setColorFill(new Color(0xFF, 0xFF, 0xFF)); - rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f); - fill(); - // silver lines - setColorStroke(new Color(0xC0, 0xC0, 0xC0)); - setLineWidth(1); - setLineCap(0); - moveTo(llx + 1f, lly + 1.5f); - lineTo(urx - 1.5f, lly + 1.5f); - lineTo(urx - 1.5f, ury - 1f); - stroke(); - // gray lines - setColorStroke(new Color(0xA0, 0xA0, 0xA0)); - setLineWidth(1); - setLineCap(0); - moveTo(llx + 1f, lly + 1); - lineTo(llx + 1f, ury - 1f); - lineTo(urx - 1f, ury - 1f); - stroke(); - // black lines - setColorStroke(new Color(0x00, 0x00, 0x00)); - setLineWidth(1); - setLineCap(0); - moveTo(llx + 2f, lly + 2f); - lineTo(llx + 2f, ury - 2f); - lineTo(urx - 2f, ury - 2f); - stroke(); - } - - /** - * Draws a button. - * @param llx - * @param lly - * @param urx - * @param ury - * @param text - * @param bf - * @param size - */ - public void drawButton(float llx, float lly, float urx, float ury, String text, BaseFont bf, float size) { - if (llx > urx) { float x = llx; llx = urx; urx = x; } - if (lly > ury) { float y = lly; lly = ury; ury = y; } - // black rectangle not filled - setColorStroke(new Color(0x00, 0x00, 0x00)); - setLineWidth(1); - setLineCap(0); - rectangle(llx, lly, urx - llx, ury - lly); - stroke(); - // silver rectangle filled - setLineWidth(1); - setLineCap(0); - setColorFill(new Color(0xC0, 0xC0, 0xC0)); - rectangle(llx + 0.5f, lly + 0.5f, urx - llx - 1f, ury -lly - 1f); - fill(); - // white lines - setColorStroke(new Color(0xFF, 0xFF, 0xFF)); - setLineWidth(1); - setLineCap(0); - moveTo(llx + 1f, lly + 1f); - lineTo(llx + 1f, ury - 1f); - lineTo(urx - 1f, ury - 1f); - stroke(); - // dark grey lines - setColorStroke(new Color(0xA0, 0xA0, 0xA0)); - setLineWidth(1); - setLineCap(0); - moveTo(llx + 1f, lly + 1f); - lineTo(urx - 1f, lly + 1f); - lineTo(urx - 1f, ury - 1f); - stroke(); - // text - resetRGBColorFill(); - beginText(); - setFontAndSize(bf, size); - showTextAligned(PdfContentByte.ALIGN_CENTER, text, llx + (urx - llx) / 2, lly + (ury - lly - size) / 2, 0); - endText(); - } - - /** Gets a Graphics2D to write on. The graphics - * are translated to PDF commands as shapes. No PDF fonts will appear. - * @param width the width of the panel - * @param height the height of the panel - * @return a Graphics2D - */ - public java.awt.Graphics2D createGraphicsShapes(float width, float height) { - return new PdfGraphics2D(this, width, height, null, true, false, 0); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands as shapes. No PDF fonts will appear. - * @param width the width of the panel - * @param height the height of the panel - * @param printerJob a printer job - * @return a Graphics2D - */ - public java.awt.Graphics2D createPrinterGraphicsShapes(float width, float height, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, null, true, false, 0, printerJob); - } - - /** Gets a Graphics2D to write on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @return a Graphics2D - */ - public java.awt.Graphics2D createGraphics(float width, float height) { - return new PdfGraphics2D(this, width, height, null, false, false, 0); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param printerJob - * @return a Graphics2D - */ - public java.awt.Graphics2D createPrinterGraphics(float width, float height, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, null, false, false, 0, printerJob); - } - - /** Gets a Graphics2D to write on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param convertImagesToJPEG - * @param quality - * @return a Graphics2D - */ - public java.awt.Graphics2D createGraphics(float width, float height, boolean convertImagesToJPEG, float quality) { - return new PdfGraphics2D(this, width, height, null, false, convertImagesToJPEG, quality); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param convertImagesToJPEG - * @param quality - * @param printerJob - * @return a Graphics2D - */ - public java.awt.Graphics2D createPrinterGraphics(float width, float height, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, null, false, convertImagesToJPEG, quality, printerJob); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width - * @param height - * @param convertImagesToJPEG - * @param quality - * @return A Graphics2D object - */ - public java.awt.Graphics2D createGraphicsShapes(float width, float height, boolean convertImagesToJPEG, float quality) { - return new PdfGraphics2D(this, width, height, null, true, convertImagesToJPEG, quality); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width - * @param height - * @param convertImagesToJPEG - * @param quality - * @param printerJob - * @return a Graphics2D object - */ - public java.awt.Graphics2D createPrinterGraphicsShapes(float width, float height, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, null, true, convertImagesToJPEG, quality, printerJob); - } - - /** Gets a Graphics2D to write on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param fontMapper the mapping from awt fonts to BaseFont - * @return a Graphics2D - */ - public java.awt.Graphics2D createGraphics(float width, float height, FontMapper fontMapper) { - return new PdfGraphics2D(this, width, height, fontMapper, false, false, 0); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param fontMapper the mapping from awt fonts to BaseFont - * @param printerJob a printer job - * @return a Graphics2D - */ - public java.awt.Graphics2D createPrinterGraphics(float width, float height, FontMapper fontMapper, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, fontMapper, false, false, 0, printerJob); - } - - /** Gets a Graphics2D to write on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param fontMapper the mapping from awt fonts to BaseFont - * @param convertImagesToJPEG converts awt images to jpeg before inserting in pdf - * @param quality the quality of the jpeg - * @return a Graphics2D - */ - public java.awt.Graphics2D createGraphics(float width, float height, FontMapper fontMapper, boolean convertImagesToJPEG, float quality) { - return new PdfGraphics2D(this, width, height, fontMapper, false, convertImagesToJPEG, quality); - } - - /** Gets a Graphics2D to print on. The graphics - * are translated to PDF commands. - * @param width the width of the panel - * @param height the height of the panel - * @param fontMapper the mapping from awt fonts to BaseFont - * @param convertImagesToJPEG converts awt images to jpeg before inserting in pdf - * @param quality the quality of the jpeg - * @param printerJob a printer job - * @return a Graphics2D - */ - public java.awt.Graphics2D createPrinterGraphics(float width, float height, FontMapper fontMapper, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { - return new PdfPrinterGraphics2D(this, width, height, fontMapper, false, convertImagesToJPEG, quality, printerJob); - } - - PageResources getPageResources() { - return pdf.getPageResources(); - } - - /** Sets the graphic state - * @param gstate the graphic state - */ - public void setGState(PdfGState gstate) { - PdfObject obj[] = writer.addSimpleExtGState(gstate); - PageResources prs = getPageResources(); - PdfName name = prs.addExtGState((PdfName)obj[0], (PdfIndirectReference)obj[1]); - content.append(name.getBytes()).append(" gs").append_i(separator); - } - - /** - * Begins a graphic block whose visibility is controled by the layer. - * Blocks can be nested. Each block must be terminated by an {@link #endLayer()}.

- * Note that nested layers with {@link PdfLayer#addChild(PdfLayer)} only require a single - * call to this method and a single call to {@link #endLayer()}; all the nesting control - * is built in. - * @param layer the layer - */ - public void beginLayer(PdfOCG layer) { - if ((layer instanceof PdfLayer) && ((PdfLayer)layer).getTitle() != null) - throw new IllegalArgumentException("A title is not a layer"); - if (layerDepth == null) - layerDepth = new ArrayList(); - if (layer instanceof PdfLayerMembership) { - layerDepth.add(new Integer(1)); - beginLayer2(layer); - return; - } - int n = 0; - PdfLayer la = (PdfLayer)layer; - while (la != null) { - if (la.getTitle() == null) { - beginLayer2(la); - ++n; - } - la = la.getParent(); - } - layerDepth.add(new Integer(n)); - } - - private void beginLayer2(PdfOCG layer) { - PdfName name = (PdfName)writer.addSimpleProperty(layer, layer.getRef())[0]; - PageResources prs = getPageResources(); - name = prs.addProperty(name, layer.getRef()); - content.append("/OC ").append(name.getBytes()).append(" BDC").append_i(separator); - } - - /** - * Ends a layer controled graphic block. It will end the most recent open block. - */ - public void endLayer() { - int n = 1; - if (layerDepth != null && layerDepth.size() > 0) { - n = ((Integer)layerDepth.get(layerDepth.size() - 1)).intValue(); - layerDepth.remove(layerDepth.size() - 1); - } - while (n-- > 0) - content.append("EMC").append_i(separator); - } - - /** Concatenates a transformation to the current transformation - * matrix. - * @param af the transformation - */ - public void transform(AffineTransform af) { - double arr[] = new double[6]; - af.getMatrix(arr); - content.append(arr[0]).append(' ').append(arr[1]).append(' ').append(arr[2]).append(' '); - content.append(arr[3]).append(' ').append(arr[4]).append(' ').append(arr[5]).append(" cm").append_i(separator); - } - - void addAnnotation(PdfAnnotation annot) { - writer.addAnnotation(annot); - } - - /** - * Sets the default colorspace. - * @param name the name of the colorspace. It can be PdfName.DEFAULTGRAY, PdfName.DEFAULTRGB - * or PdfName.DEFAULTCMYK - * @param obj the colorspace. A null or PdfNull removes any colorspace with the same name - */ - public void setDefaultColorspace(PdfName name, PdfObject obj) { - PageResources prs = getPageResources(); - prs.addDefaultColor(name, obj); - } - - /** - * Begins a marked content sequence. This sequence will be tagged with the structure struc. - * The same structure can be used several times to connect text that belongs to the same logical segment - * but is in a different location, like the same paragraph crossing to another page, for example. - * @param struc the tagging structure - */ - public void beginMarkedContentSequence(PdfStructureElement struc) { - PdfObject obj = struc.get(PdfName.K); - int mark = pdf.getMarkPoint(); - if (obj != null) { - PdfArray ar = null; - if (obj.isNumber()) { - ar = new PdfArray(); - ar.add(obj); - struc.put(PdfName.K, ar); - } - else if (obj.isArray()) { - ar = (PdfArray)obj; - if (!((PdfObject)ar.getArrayList().get(0)).isNumber()) - throw new IllegalArgumentException("The structure has kids."); - } - else - throw new IllegalArgumentException("Unknown object at /K " + obj.getClass().toString()); - PdfDictionary dic = new PdfDictionary(PdfName.MCR); - dic.put(PdfName.PG, writer.getCurrentPage()); - dic.put(PdfName.MCID, new PdfNumber(mark)); - ar.add(dic); - struc.setPageMark(writer.getPageNumber() - 1, -1); - } - else { - struc.setPageMark(writer.getPageNumber() - 1, mark); - struc.put(PdfName.PG, writer.getCurrentPage()); - } - pdf.incMarkPoint(); - content.append(struc.get(PdfName.S).getBytes()).append(" <> BDC").append_i(separator); - } - - /** - * Ends a marked content sequence - */ - public void endMarkedContentSequence() { - content.append("EMC").append_i(separator); - } - - /** - * Begins a marked content sequence. If property is null the mark will be of the type - * BMC otherwise it will be BDC. - * @param tag the tag - * @param property the property - * @param inline true to include the property in the content or false - * to include the property in the resource dictionary with the possibility of reusing - */ - public void beginMarkedContentSequence(PdfName tag, PdfDictionary property, boolean inline) { - if (property == null) { - content.append(tag.getBytes()).append(" BMC").append_i(separator); - return; - } - content.append(tag.getBytes()).append(' '); - if (inline) - try { - property.toPdf(writer, content); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - else { - PdfObject[] objs; - if (writer.propertyExists(property)) - objs = writer.addSimpleProperty(property, null); - else - objs = writer.addSimpleProperty(property, writer.getPdfIndirectReference()); - PdfName name = (PdfName)objs[0]; - PageResources prs = getPageResources(); - name = prs.addProperty(name, (PdfIndirectReference)objs[1]); - content.append(name.getBytes()); - } - content.append(" BDC").append_i(separator); - } - - /** - * This is just a shorthand to beginMarkedContentSequence(tag, null, false). - * @param tag the tag - */ - public void beginMarkedContentSequence(PdfName tag) { - beginMarkedContentSequence(tag, null, false); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfContentParser.java b/src/main/java/com/lowagie/text/pdf/PdfContentParser.java deleted file mode 100644 index af731bc..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfContentParser.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * $Id: PdfContentParser.java,v 1.4 2006/05/27 11:11:54 psoares33 Exp $ - * - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.util.ArrayList; -/** - * Parses the page or template content. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfContentParser { - - /** - * Commands have this type. - */ - public static final int COMMAND_TYPE = 200; - /** - * Holds value of property tokeniser. - */ - private PRTokeniser tokeniser; - - /** - * Creates a new instance of PdfContentParser - * @param tokeniser the tokeniser with the content - */ - public PdfContentParser(PRTokeniser tokeniser) { - this.tokeniser = tokeniser; - } - - /** - * Parses a single command from the content. Each command is output as an array of arguments - * having the command itself as the last element. The returned array will be empty if the - * end of content was reached. - * @param ls an ArrayList to use. It will be cleared before using. If it's - * null will create a new ArrayList - * @return the same ArrayList given as argument or a new one - * @throws IOException on error - */ - public ArrayList parse(ArrayList ls) throws IOException { - if (ls == null) - ls = new ArrayList(); - else - ls.clear(); - PdfObject ob = null; - while ((ob = readPRObject()) != null) { - ls.add(ob); - if (ob.type() == COMMAND_TYPE) - break; - } - return ls; - } - - /** - * Gets the tokeniser. - * @return the tokeniser. - */ - public PRTokeniser getTokeniser() { - return this.tokeniser; - } - - /** - * Sets the tokeniser. - * @param tokeniser the tokeniser - */ - public void setTokeniser(PRTokeniser tokeniser) { - this.tokeniser = tokeniser; - } - - /** - * Reads a dictionary. The tokeniser must be positioned past the "<<" token. - * @return the dictionary - * @throws IOException on error - */ - public PdfDictionary readDictionary() throws IOException { - PdfDictionary dic = new PdfDictionary(); - while (true) { - if (!nextValidToken()) - throw new IOException("Unexpected end of file.");; - if (tokeniser.getTokenType() == PRTokeniser.TK_END_DIC) - break; - if (tokeniser.getTokenType() != PRTokeniser.TK_NAME) - throw new IOException("Dictionary key is not a name."); - PdfName name = new PdfName(tokeniser.getStringValue(), false); - PdfObject obj = readPRObject(); - int type = obj.type(); - if (-type == PRTokeniser.TK_END_DIC) - throw new IOException("Unexpected '>>'"); - if (-type == PRTokeniser.TK_END_ARRAY) - throw new IOException("Unexpected ']'"); - dic.put(name, obj); - } - return dic; - } - - /** - * Reads an array. The tokeniser must be positioned past the "[" token. - * @return an array - * @throws IOException on error - */ - public PdfArray readArray() throws IOException { - PdfArray array = new PdfArray(); - while (true) { - PdfObject obj = readPRObject(); - int type = obj.type(); - if (-type == PRTokeniser.TK_END_ARRAY) - break; - if (-type == PRTokeniser.TK_END_DIC) - throw new IOException("Unexpected '>>'"); - array.add(obj); - } - return array; - } - - /** - * Reads a pdf object. - * @return the pdf object - * @throws IOException on error - */ - public PdfObject readPRObject() throws IOException { - if (!nextValidToken()) - return null; - int type = tokeniser.getTokenType(); - switch (type) { - case PRTokeniser.TK_START_DIC: { - PdfDictionary dic = readDictionary(); - return dic; - } - case PRTokeniser.TK_START_ARRAY: - return readArray(); - case PRTokeniser.TK_STRING: - PdfString str = new PdfString(tokeniser.getStringValue(), null).setHexWriting(tokeniser.isHexString()); - return str; - case PRTokeniser.TK_NAME: - return new PdfName(tokeniser.getStringValue(), false); - case PRTokeniser.TK_NUMBER: - return new PdfNumber(tokeniser.getStringValue()); - case PRTokeniser.TK_OTHER: - return new PdfLiteral(COMMAND_TYPE, tokeniser.getStringValue()); - default: - return new PdfLiteral(-type, tokeniser.getStringValue()); - } - } - - /** - * Reads the next token skipping over the comments. - * @return true if a token was read, false if the end of content was reached - * @throws IOException on error - */ - public boolean nextValidToken() throws IOException { - while (tokeniser.nextToken()) { - if (tokeniser.getTokenType() == PRTokeniser.TK_COMMENT) - continue; - return true; - } - return false; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfContents.java b/src/main/java/com/lowagie/text/pdf/PdfContents.java deleted file mode 100644 index 786da2f..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfContents.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * $Id: PdfContents.java,v 1.58 2005/05/04 14:31:50 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.DocWriter; -import com.lowagie.text.Document; -import com.lowagie.text.Rectangle; -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.util.zip.DeflaterOutputStream; - -/** - * PdfContents is a PdfStream containing the contents (text + graphics) of a PdfPage. - */ - -class PdfContents extends PdfStream { - - static final byte SAVESTATE[] = DocWriter.getISOBytes("q\n"); - static final byte RESTORESTATE[] = DocWriter.getISOBytes("Q\n"); - static final byte ROTATE90[] = DocWriter.getISOBytes("0 1 -1 0 "); - static final byte ROTATE180[] = DocWriter.getISOBytes("-1 0 0 -1 "); - static final byte ROTATE270[] = DocWriter.getISOBytes("0 -1 1 0 "); - static final byte ROTATEFINAL[] = DocWriter.getISOBytes(" cm\n"); - // constructor - -/** - * Constructs a PdfContents-object, containing text and general graphics. - * - * @param under the direct content that is under all others - * @param content the graphics in a page - * @param text the text in a page - * @param secondContent the direct content that is over all others - * @throws BadPdfFormatException on error - */ - - PdfContents(PdfContentByte under, PdfContentByte content, PdfContentByte text, PdfContentByte secondContent, Rectangle page) throws BadPdfFormatException { - super(); - try { - OutputStream out = null; - streamBytes = new ByteArrayOutputStream(); - if (Document.compress) - { - compressed = true; - out = new DeflaterOutputStream(streamBytes); - } - else - out = streamBytes; - int rotation = page.getRotation(); - switch (rotation) { - case 90: - out.write(ROTATE90); - out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.top()))); - out.write(' '); - out.write('0'); - out.write(ROTATEFINAL); - break; - case 180: - out.write(ROTATE180); - out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.right()))); - out.write(' '); - out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.top()))); - out.write(ROTATEFINAL); - break; - case 270: - out.write(ROTATE270); - out.write('0'); - out.write(' '); - out.write(DocWriter.getISOBytes(ByteBuffer.formatDouble(page.right()))); - out.write(ROTATEFINAL); - break; - } - if (under.size() > 0) { - out.write(SAVESTATE); - under.getInternalBuffer().writeTo(out); - out.write(RESTORESTATE); - } - if (content.size() > 0) { - out.write(SAVESTATE); - content.getInternalBuffer().writeTo(out); - out.write(RESTORESTATE); - } - if (text != null) { - out.write(SAVESTATE); - text.getInternalBuffer().writeTo(out); - out.write(RESTORESTATE); - } - if (secondContent.size() > 0) { - secondContent.getInternalBuffer().writeTo(out); - } - out.close(); - } - catch (Exception e) { - throw new BadPdfFormatException(e.getMessage()); - } - put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); - if (compressed) - put(PdfName.FILTER, PdfName.FLATEDECODE); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfCopy.java b/src/main/java/com/lowagie/text/pdf/PdfCopy.java deleted file mode 100644 index 0dcdc70..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfCopy.java +++ /dev/null @@ -1,474 +0,0 @@ -/* - * $Id: PdfCopy.java,v 1.42 2006/05/06 14:19:51 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * This module by Mark Thompson. Copyright (C) 2002 Mark Thompson - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.HashMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Iterator; -import java.io.*; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; - -/** - * Make copies of PDF documents. Documents can be edited after reading and - * before writing them out. - * @author Mark Thompson - */ - -public class PdfCopy extends PdfWriter { - /** - * This class holds information about indirect references, since they are - * renumbered by iText. - */ - static class IndirectReferences { - PdfIndirectReference theRef; - boolean hasCopied; - IndirectReferences(PdfIndirectReference ref) { - theRef = ref; - hasCopied = false; - } - void setCopied() { hasCopied = true; } - boolean getCopied() { return hasCopied; } - PdfIndirectReference getRef() { return theRef; } - }; - protected HashMap indirects; - protected HashMap indirectMap; - protected int currentObjectNum = 1; - protected PdfReader reader; - protected PdfIndirectReference acroForm; - protected PdfIndirectReference topPageParent; - protected ArrayList pageNumbersToRefs = new ArrayList(); - protected List newBookmarks; - - /** - * A key to allow us to hash indirect references - */ - protected static class RefKey { - int num; - int gen; - RefKey(int num, int gen) { - this.num = num; - this.gen = gen; - } - RefKey(PdfIndirectReference ref) { - num = ref.getNumber(); - gen = ref.getGeneration(); - } - RefKey(PRIndirectReference ref) { - num = ref.getNumber(); - gen = ref.getGeneration(); - } - public int hashCode() { - return (gen<<16)+num; - } - public boolean equals(Object o) { - RefKey other = (RefKey)o; - return this.gen == other.gen && this.num == other.num; - } - public String toString() { - return "" + num + " " + gen; - } - } - - /** - * Constructor - * @param document - * @param os outputstream - */ - public PdfCopy(Document document, OutputStream os) throws DocumentException { - super(new PdfDocument(), os); - document.addDocListener(pdf); - pdf.addWriter(this); - indirectMap = new HashMap(); - } - public void open() { - super.open(); - topPageParent = getPdfIndirectReference(); - root.setLinearMode(topPageParent); - } - - /** - * Grabs a page from the input document - * @param reader the reader of the document - * @param pageNumber which page to get - * @return the page - */ - public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { - if (currentPdfReaderInstance != null) { - if (currentPdfReaderInstance.getReader() != reader) { - try { - currentPdfReaderInstance.getReader().close(); - currentPdfReaderInstance.getReaderFile().close(); - } - catch (IOException ioe) { - // empty on purpose - } - currentPdfReaderInstance = reader.getPdfReaderInstance(this); - } - } - else { - currentPdfReaderInstance = reader.getPdfReaderInstance(this); - } - return currentPdfReaderInstance.getImportedPage(pageNumber); - } - - - /** - * Translate a PRIndirectReference to a PdfIndirectReference - * In addition, translates the object numbers, and copies the - * referenced object to the output file. - * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what - * file they came from, because each file has its own namespace. The translation - * we do from their namespace to ours is *at best* heuristic, and guaranteed to - * fail under some circumstances. - */ - protected PdfIndirectReference copyIndirect(PRIndirectReference in) throws IOException, BadPdfFormatException { - PdfIndirectReference theRef; - RefKey key = new RefKey(in); - IndirectReferences iRef = (IndirectReferences)indirects.get(key); - if (iRef != null) { - theRef = iRef.getRef(); - if (iRef.getCopied()) { - // System.out.println(">>> Value is " + theRef.toString()); - return theRef; - } - // System.out.println(">>> Fill in " + theRef.toString()); - } - else { - theRef = body.getPdfIndirectReference(); - iRef = new IndirectReferences(theRef); - indirects.put(key, iRef); - } - iRef.setCopied(); - PdfObject obj = copyObject(PdfReader.getPdfObjectRelease(in)); - addToBody(obj, theRef); - return theRef; - } - - /** - * Translate a PRDictionary to a PdfDictionary. Also translate all of the - * objects contained in it. - */ - protected PdfDictionary copyDictionary(PdfDictionary in) - throws IOException, BadPdfFormatException { - PdfDictionary out = new PdfDictionary(); - PdfName type = (PdfName)in.get(PdfName.TYPE); - - for (Iterator it = in.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - PdfObject value = in.get(key); - // System.out.println("Copy " + key); - if (type != null && PdfName.PAGE.equals(type)) { - if (key.equals(PdfName.PARENT)) - out.put(PdfName.PARENT, topPageParent); - else if (!key.equals(PdfName.B)) - out.put(key, copyObject(value)); - } - else - out.put(key, copyObject(value)); - } - return out; - } - - /** - * Translate a PRStream to a PdfStream. The data part copies itself. - */ - protected PdfStream copyStream(PRStream in) throws IOException, BadPdfFormatException { - PRStream out = new PRStream(in, null); - - for (Iterator it = in.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName) it.next(); - PdfObject value = in.get(key); - out.put(key, copyObject(value)); - } - - return out; - } - - - /** - * Translate a PRArray to a PdfArray. Also translate all of the objects contained - * in it - */ - protected PdfArray copyArray(PdfArray in) throws IOException, BadPdfFormatException { - PdfArray out = new PdfArray(); - - for (Iterator i = in.getArrayList().iterator(); i.hasNext();) { - PdfObject value = (PdfObject)i.next(); - out.add(copyObject(value)); - } - return out; - } - - /** - * Translate a PR-object to a Pdf-object - */ - protected PdfObject copyObject(PdfObject in) throws IOException,BadPdfFormatException { - switch (in.type) { - case PdfObject.DICTIONARY: - // System.out.println("Dictionary: " + in.toString()); - return copyDictionary((PdfDictionary)in); - case PdfObject.INDIRECT: - return copyIndirect((PRIndirectReference)in); - case PdfObject.ARRAY: - return copyArray((PdfArray)in); - case PdfObject.NUMBER: - case PdfObject.NAME: - case PdfObject.STRING: - case PdfObject.NULL: - case PdfObject.BOOLEAN: - return in; - case PdfObject.STREAM: - return copyStream((PRStream)in); - // return in; - default: - if (in.type < 0) { - String lit = ((PdfLiteral)in).toString(); - if (lit.equals("true") || lit.equals("false")) { - return new PdfBoolean(lit); - } - return new PdfLiteral(lit); - } - System.out.println("CANNOT COPY type " + in.type); - return null; - } - } - - /** - * convenience method. Given an importedpage, set our "globals" - */ - protected int setFromIPage(PdfImportedPage iPage) { - int pageNum = iPage.getPageNumber(); - PdfReaderInstance inst = currentPdfReaderInstance = iPage.getPdfReaderInstance(); - reader = inst.getReader(); - setFromReader(reader); - return pageNum; - } - - /** - * convenience method. Given a reader, set our "globals" - */ - protected void setFromReader(PdfReader reader) { - this.reader = reader; - indirects = (HashMap)indirectMap.get(reader); - if (indirects == null) { - indirects = new HashMap(); - indirectMap.put(reader,indirects); - PdfDictionary catalog = reader.getCatalog(); - PRIndirectReference ref = (PRIndirectReference)catalog.get(PdfName.PAGES); - indirects.put(new RefKey(ref), new IndirectReferences(topPageParent)); - ref = null; - PdfObject o = catalog.get(PdfName.ACROFORM); - if (o == null || o.type() != PdfObject.INDIRECT) - return; - ref = (PRIndirectReference)o; - if (acroForm == null) acroForm = body.getPdfIndirectReference(); - indirects.put(new RefKey(ref), new IndirectReferences(acroForm)); - } - } - /** - * Add an imported page to our output - * @param iPage an imported page - * @throws IOException, BadPdfFormatException - */ - public void addPage(PdfImportedPage iPage) throws IOException, BadPdfFormatException { - int pageNum = setFromIPage(iPage); - - PdfDictionary thePage = reader.getPageN(pageNum); - PRIndirectReference origRef = reader.getPageOrigRef(pageNum); - reader.releasePage(pageNum); - RefKey key = new RefKey(origRef); - PdfIndirectReference pageRef; - IndirectReferences iRef = (IndirectReferences)indirects.get(key); - // if we already have an iref for the page (we got here by another link) - if (iRef != null) { - pageRef = iRef.getRef(); - } - else { - pageRef = body.getPdfIndirectReference(); - iRef = new IndirectReferences(pageRef); - indirects.put(key, iRef); - } - pageReferences.add(pageRef); - ++currentPageNumber; - if (! iRef.getCopied()) { - iRef.setCopied(); - PdfDictionary newPage = copyDictionary(thePage); - newPage.put(PdfName.PARENT, topPageParent); - addToBody(newPage, pageRef); - } - root.addPage(pageRef); - pageNumbersToRefs.add(pageRef); - } - - public PdfIndirectReference getPageReference(int page) { - if (page < 0 || page > pageNumbersToRefs.size()) - throw new IllegalArgumentException("Invalid page number " + page); - return (PdfIndirectReference)pageNumbersToRefs.get(page - 1); - } - - /** - * Copy the acroform for an input document. Note that you can only have one, - * we make no effort to merge them. - * @param reader The reader of the input file that is being copied - * @throws IOException, BadPdfFormatException - */ - public void copyAcroForm(PdfReader reader) throws IOException, BadPdfFormatException { - setFromReader(reader); - - PdfDictionary catalog = reader.getCatalog(); - PRIndirectReference hisRef = null; - PdfObject o = catalog.get(PdfName.ACROFORM); - if (o != null && o.type() == PdfObject.INDIRECT) - hisRef = (PRIndirectReference)o; - if (hisRef == null) return; // bugfix by John Englar - RefKey key = new RefKey(hisRef); - PdfIndirectReference myRef; - IndirectReferences iRef = (IndirectReferences)indirects.get(key); - if (iRef != null) { - acroForm = myRef = iRef.getRef(); - } - else { - acroForm = myRef = body.getPdfIndirectReference(); - iRef = new IndirectReferences(myRef); - indirects.put(key, iRef); - } - if (! iRef.getCopied()) { - iRef.setCopied(); - PdfDictionary theForm = copyDictionary((PdfDictionary)PdfReader.getPdfObject(hisRef)); - addToBody(theForm, myRef); - } - } - - /* - * the getCatalog method is part of PdfWriter. - * we wrap this so that we can extend it - */ - protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { - try { - PdfDictionary theCat = ((PdfDocument)document).getCatalog(rootObj); - if (acroForm != null) theCat.put(PdfName.ACROFORM, acroForm); - if (newBookmarks == null || newBookmarks.size() == 0) - return theCat; - PdfDictionary top = new PdfDictionary(); - PdfIndirectReference topRef = getPdfIndirectReference(); - Object kids[] = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, false); - top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); - top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); - top.put(PdfName.COUNT, new PdfNumber(((Integer)kids[2]).intValue())); - addToBody(top, topRef); - theCat.put(PdfName.OUTLINES, topRef); - return theCat; - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** - * Sets the bookmarks. The list structure is defined in - * SimpleBookmark#. - * @param outlines the bookmarks or null to remove any - */ - public void setOutlines(List outlines) { - newBookmarks = outlines; - } - - /** - * Signals that the Document was closed and that no other - * Elements will be added. - *

- * The pages-tree is built and written to the outputstream. - * A Catalog is constructed, as well as an Info-object, - * the referencetable is composed and everything is written - * to the outputstream embedded in a Trailer. - */ - - public synchronized void close() { - if (open) { - PdfReaderInstance ri = currentPdfReaderInstance; - pdf.close(); - super.close(); - if (ri != null) { - try { - ri.getReader().close(); - ri.getReaderFile().close(); - } - catch (IOException ioe) { - // empty on purpose - } - } - } - } - PdfIndirectReference add(PdfImage pdfImage, PdfIndirectReference fixedRef) throws PdfException { return null; } - public PdfIndirectReference add(PdfOutline outline) { return null; } - public void addAnnotation(PdfAnnotation annot) { } - PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { return null; } - - public void freeReader(PdfReader reader) throws IOException { - indirectMap.remove(reader); - if (currentPdfReaderInstance != null) { - if (currentPdfReaderInstance.getReader() == reader) { - try { - currentPdfReaderInstance.getReader().close(); - currentPdfReaderInstance.getReaderFile().close(); - } - catch (IOException ioe) { - // empty on purpose - } - currentPdfReaderInstance = null; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfCopyFields.java b/src/main/java/com/lowagie/text/pdf/PdfCopyFields.java deleted file mode 100644 index ec08329..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfCopyFields.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.DocWriter; -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; - -/** - * Concatenates PDF documents including form fields. The rules for the form field - * concatenation are the same as in Acrobat. All the documents are kept in memory unlike - * PdfCopy. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfCopyFields { - - private PdfCopyFieldsImp fc; - - /** - * Creates a new instance. - * @param os the output stream - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfCopyFields(OutputStream os) throws DocumentException, IOException { - fc = new PdfCopyFieldsImp(os); - } - - /** - * Creates a new instance. - * @param os the output stream - * @param pdfVersion the pdf version the output will have - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfCopyFields(OutputStream os, char pdfVersion) throws DocumentException, IOException { - fc = new PdfCopyFieldsImp(os, pdfVersion); - } - - /** - * Concatenates a PDF document. - * @param reader the PDF document - * @throws DocumentException on error - */ - public void addDocument(PdfReader reader) throws DocumentException { - fc.addDocument(reader); - } - - /** - * Concatenates a PDF document selecting the pages to keep. The pages are described as a - * List of Integer. The page ordering can be changed but - * no page repetitions are allowed. - * @param reader the PDF document - * @param pagesToKeep the pages to keep - * @throws DocumentException on error - */ - public void addDocument(PdfReader reader, List pagesToKeep) throws DocumentException { - fc.addDocument(reader, pagesToKeep); - } - - /** - * Concatenates a PDF document selecting the pages to keep. The pages are described as - * ranges. The page ordering can be changed but - * no page repetitions are allowed. - * @param reader the PDF document - * @param ranges the comma separated ranges as described in {@link SequenceList} - * @throws DocumentException on error - */ - public void addDocument(PdfReader reader, String ranges) throws DocumentException { - fc.addDocument(reader, SequenceList.expand(ranges, reader.getNumberOfPages())); - } - - /** Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param strength128Bits true for 128 bit key length, false for 40 bit key length - * @throws DocumentException if the document is already open - */ - public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { - fc.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); - } - - /** - * Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param strength true for 128 bit key length. false for 40 bit key length - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @throws DocumentException if the document is already open - */ - public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { - setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength); - } - - /** - * Closes the output document. - */ - public void close() { - fc.close(); - } - - /** - * Opens the document. This is usually not needed as addDocument() will do it - * automatically. - */ - public void open() { - fc.openDoc(); - } - - /** - * Adds JavaScript to the global document - * @param js the JavaScript - */ - public void addJavaScript(String js) { - fc.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js)); - } - - /** - * Sets the bookmarks. The list structure is defined in - * SimpleBookmark#. - * @param outlines the bookmarks or null to remove any - */ - public void setOutlines(List outlines) { - fc.setOutlines(outlines); - } - - /** Gets the underlying PdfWriter. - * @return the underlying PdfWriter - */ - public PdfWriter getWriter() { - return fc; - } - - /** - * Gets the 1.5 compression status. - * @return true if the 1.5 compression is on - */ - public boolean isFullCompression() { - return fc.isFullCompression(); - } - - /** - * Sets the document's compression to the new 1.5 mode with object streams and xref - * streams. It can be set at any time but once set it can't be unset. - *

- * If set before opening the document it will also set the pdf version to 1.5. - */ - public void setFullCompression() { - fc.setFullCompression(); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfCopyFieldsImp.java b/src/main/java/com/lowagie/text/pdf/PdfCopyFieldsImp.java deleted file mode 100644 index ac9b3d5..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfCopyFieldsImp.java +++ /dev/null @@ -1,639 +0,0 @@ -/* - * $Id: PdfCopyFieldsImp.java,v 1.13 2006/02/11 09:44:10 psoares33 Exp $ - * $Name: $ - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Document; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.HashMap; -import java.util.List; -import java.util.StringTokenizer; - -/** - * - * @author psoares - */ -class PdfCopyFieldsImp extends PdfWriter { - - private static final PdfName iTextTag = new PdfName("_iTextTag_"); - private static final Integer zero = new Integer(0); - ArrayList readers = new ArrayList(); - HashMap readers2intrefs = new HashMap(); - HashMap pages2intrefs = new HashMap(); - HashMap visited = new HashMap(); - ArrayList fields = new ArrayList(); - RandomAccessFileOrArray file; - HashMap fieldTree = new HashMap(); - ArrayList pageRefs = new ArrayList(); - ArrayList pageDics = new ArrayList(); - PdfDictionary resources = new PdfDictionary(); - PdfDictionary form; - protected List newBookmarks; - boolean closing = false; - Document nd; - private HashMap tabOrder; - private ArrayList calculationOrder = new ArrayList(); - private ArrayList calculationOrderRefs; - - PdfCopyFieldsImp(OutputStream os) throws DocumentException, IOException { - this(os, '\0'); - } - - PdfCopyFieldsImp(OutputStream os, char pdfVersion) throws DocumentException, IOException { - super(new PdfDocument(), os); - pdf.addWriter(this); - if (pdfVersion != 0) - super.setPdfVersion(pdfVersion); - nd = new Document(); - nd.addDocListener(pdf); - } - - void addDocument(PdfReader reader, List pagesToKeep) throws DocumentException { - if (!readers2intrefs.containsKey(reader) && reader.isTampered()) - throw new DocumentException("The document was reused."); - reader = new PdfReader(reader); - reader.selectPages(pagesToKeep); - if (reader.getNumberOfPages() == 0) - return; - reader.setTampered(false); - addDocument(reader); - } - - void addDocument(PdfReader reader) throws DocumentException { - openDoc(); - if (readers2intrefs.containsKey(reader)) { - reader = new PdfReader(reader); - } - else { - if (reader.isTampered()) - throw new DocumentException("The document was reused."); - reader.consolidateNamedDestinations(); - reader.setTampered(true); - } - reader.shuffleSubsetNames(); - readers2intrefs.put(reader, new IntHashtable()); - readers.add(reader); - int len = reader.getNumberOfPages(); - IntHashtable refs = new IntHashtable(); - for (int p = 1; p <= len; ++p) { - refs.put(reader.getPageOrigRef(p).getNumber(), 1); - reader.releasePage(p); - } - pages2intrefs.put(reader, refs); - visited.put(reader, new IntHashtable()); - fields.add(reader.getAcroFields()); - updateCalculationOrder(reader); - } - - private static String getCOName(PdfReader reader, PRIndirectReference ref) { - String name = ""; - while (ref != null) { - PdfObject obj = PdfReader.getPdfObject(ref); - if (obj == null || obj.type() != PdfObject.DICTIONARY) - break; - PdfDictionary dic = (PdfDictionary)obj; - PdfString t = (PdfString)PdfReader.getPdfObject(dic.get(PdfName.T)); - if (t != null) { - name = t.toUnicodeString()+ "." + name; - } - ref = (PRIndirectReference)dic.get(PdfName.PARENT); - } - if (name.endsWith(".")) - name = name.substring(0, name.length() - 1); - return name; - } - - private void updateCalculationOrder(PdfReader reader) { - PdfDictionary catalog = reader.getCatalog(); - PdfDictionary acro = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM)); - if (acro == null) - return; - PdfArray co = (PdfArray)PdfReader.getPdfObject(acro.get(PdfName.CO)); - if (co == null || co.size() == 0) - return; - AcroFields af = reader.getAcroFields(); - ArrayList coa = co.getArrayList(); - for (int k = 0; k < coa.size(); ++k) { - PdfObject obj = (PdfObject)coa.get(k); - if (obj == null || !obj.isIndirect()) - continue; - String name = getCOName(reader, (PRIndirectReference)obj); - if (af.getFieldItem(name) == null) - continue; - name = "." + name; - if (calculationOrder.contains(name)) - continue; - calculationOrder.add(name); - } - } - - void propagate(PdfObject obj, PdfIndirectReference refo, boolean restricted) throws IOException { - if (obj == null) - return; -// if (refo != null) -// addToBody(obj, refo); - if (obj instanceof PdfIndirectReference) - return; - switch (obj.type()) { - case PdfObject.DICTIONARY: - case PdfObject.STREAM: { - PdfDictionary dic = (PdfDictionary)obj; - for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - if (restricted && (key.equals(PdfName.PARENT) || key.equals(PdfName.KIDS))) - continue; - PdfObject ob = dic.get(key); - if (ob != null && ob.isIndirect()) { - PRIndirectReference ind = (PRIndirectReference)ob; - if (!setVisited(ind) && !isPage(ind)) { - PdfIndirectReference ref = getNewReference(ind); - propagate(PdfReader.getPdfObjectRelease(ind), ref, restricted); - } - } - else - propagate(ob, null, restricted); - } - break; - } - case PdfObject.ARRAY: { - ArrayList list = ((PdfArray)obj).getArrayList(); - //PdfArray arr = new PdfArray(); - for (Iterator it = list.iterator(); it.hasNext();) { - PdfObject ob = (PdfObject)it.next(); - if (ob != null && ob.isIndirect()) { - PRIndirectReference ind = (PRIndirectReference)ob; - if (!isVisited(ind) && !isPage(ind)) { - PdfIndirectReference ref = getNewReference(ind); - propagate(PdfReader.getPdfObjectRelease(ind), ref, restricted); - } - } - else - propagate(ob, null, restricted); - } - break; - } - case PdfObject.INDIRECT: { - throw new RuntimeException("Reference pointing to reference."); - } - } - } - - private void adjustTabOrder(PdfArray annots, PdfIndirectReference ind, PdfNumber nn) { - int v = nn.intValue(); - ArrayList t = (ArrayList)tabOrder.get(annots); - if (t == null) { - t = new ArrayList(); - int size = annots.size() - 1; - for (int k = 0; k < size; ++k) { - t.add(zero); - } - t.add(new Integer(v)); - tabOrder.put(annots, t); - annots.add(ind); - } - else { - int size = t.size() - 1; - for (int k = size; k >= 0; --k) { - if (((Integer)t.get(k)).intValue() <= v) { - t.add(k + 1, new Integer(v)); - annots.getArrayList().add(k + 1, ind); - size = -2; - break; - } - } - if (size != -2) { - t.add(0, new Integer(v)); - annots.getArrayList().add(0, ind); - } - } - } - - protected PdfArray branchForm(HashMap level, PdfIndirectReference parent, String fname) throws IOException { - PdfArray arr = new PdfArray(); - for (Iterator it = level.keySet().iterator(); it.hasNext();) { - String name = (String)it.next(); - Object obj = level.get(name); - PdfIndirectReference ind = getPdfIndirectReference(); - PdfDictionary dic = new PdfDictionary(); - if (parent != null) - dic.put(PdfName.PARENT, parent); - dic.put(PdfName.T, new PdfString(name, PdfObject.TEXT_UNICODE)); - String fname2 = fname + "." + name; - int coidx = calculationOrder.indexOf(fname2); - if (coidx >= 0) - calculationOrderRefs.set(coidx, ind); - if (obj instanceof HashMap) { - dic.put(PdfName.KIDS, branchForm((HashMap)obj, ind, fname2)); - arr.add(ind); - addToBody(dic, ind); - } - else { - ArrayList list = (ArrayList)obj; - dic.mergeDifferent((PdfDictionary)list.get(0)); - if (list.size() == 3) { - dic.mergeDifferent((PdfDictionary)list.get(2)); - int page = ((Integer)list.get(1)).intValue(); - PdfDictionary pageDic = (PdfDictionary)pageDics.get(page - 1); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS)); - if (annots == null) { - annots = new PdfArray(); - pageDic.put(PdfName.ANNOTS, annots); - } - PdfNumber nn = (PdfNumber)dic.get(iTextTag); - dic.remove(iTextTag); - adjustTabOrder(annots, ind, nn); - } - else { - PdfArray kids = new PdfArray(); - for (int k = 1; k < list.size(); k += 2) { - int page = ((Integer)list.get(k)).intValue(); - PdfDictionary pageDic = (PdfDictionary)pageDics.get(page - 1); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS)); - if (annots == null) { - annots = new PdfArray(); - pageDic.put(PdfName.ANNOTS, annots); - } - PdfDictionary widget = new PdfDictionary(); - widget.merge((PdfDictionary)list.get(k + 1)); - widget.put(PdfName.PARENT, ind); - PdfNumber nn = (PdfNumber)widget.get(iTextTag); - widget.remove(iTextTag); - PdfIndirectReference wref = addToBody(widget).getIndirectReference(); - adjustTabOrder(annots, wref, nn); - kids.add(wref); - propagate(widget, null, false); - } - dic.put(PdfName.KIDS, kids); - } - arr.add(ind); - addToBody(dic, ind); - propagate(dic, null, false); - } - } - return arr; - } - - protected void createAcroForms() throws IOException { - if (fieldTree.size() == 0) - return; - form = new PdfDictionary(); - form.put(PdfName.DR, resources); - propagate(resources, null, false); - form.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); - tabOrder = new HashMap(); - calculationOrderRefs = new ArrayList(calculationOrder); - form.put(PdfName.FIELDS, branchForm(fieldTree, null, "")); - PdfArray co = new PdfArray(); - for (int k = 0; k < calculationOrderRefs.size(); ++k) { - Object obj = calculationOrderRefs.get(k); - if (obj instanceof PdfIndirectReference) - co.add((PdfIndirectReference)obj); - } - if (co.size() > 0) - form.put(PdfName.CO, co); - } - - public void close() { - if (closing) { - super.close(); - return; - } - closing = true; - try { - closeIt(); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - protected void closeIt() throws DocumentException, IOException { - for (int k = 0; k < readers.size(); ++k) { - ((PdfReader)readers.get(k)).removeFields(); - } - for (int r = 0; r < readers.size(); ++r) { - PdfReader reader = (PdfReader)readers.get(r); - for (int page = 1; page <= reader.getNumberOfPages(); ++page) { - pageRefs.add(getNewReference(reader.getPageOrigRef(page))); - pageDics.add(reader.getPageN(page)); - } - } - mergeFields(); - createAcroForms(); - for (int r = 0; r < readers.size(); ++r) { - PdfReader reader = (PdfReader)readers.get(r); - for (int page = 1; page <= reader.getNumberOfPages(); ++page) { - PdfDictionary dic = reader.getPageN(page); - PdfIndirectReference pageRef = getNewReference(reader.getPageOrigRef(page)); - PdfIndirectReference parent = root.addPageRef(pageRef); - dic.put(PdfName.PARENT, parent); - propagate(dic, pageRef, false); - } - } - for (Iterator it = readers2intrefs.keySet().iterator(); it.hasNext();) { - PdfReader reader = (PdfReader)it.next(); - try { - file = reader.getSafeFile(); - file.reOpen(); - IntHashtable t = (IntHashtable)readers2intrefs.get(reader); - int keys[] = t.toOrderedKeys(); - for (int k = 0; k < keys.length; ++k) { - PRIndirectReference ref = new PRIndirectReference(reader, keys[k]); - addToBody(PdfReader.getPdfObjectRelease(ref), t.get(keys[k])); - } - } - finally { - try { - file.close(); - reader.close(); - } - catch (Exception e) { - // empty on purpose - } - } - } - pdf.close(); - } - - void addPageOffsetToField(HashMap fd, int pageOffset) { - if (pageOffset == 0) - return; - for (Iterator it = fd.values().iterator(); it.hasNext();) { - ArrayList page = ((AcroFields.Item)it.next()).page; - for (int k = 0; k < page.size(); ++k) - page.set(k, new Integer(((Integer)page.get(k)).intValue() + pageOffset)); - } - } - - void createWidgets(ArrayList list, AcroFields.Item item) { - for (int k = 0; k < item.merged.size(); ++k) { - list.add(item.page.get(k)); - PdfDictionary merged = (PdfDictionary)item.merged.get(k); - PdfObject dr = merged.get(PdfName.DR); - if (dr != null) - PdfFormField.mergeResources(resources, (PdfDictionary)PdfReader.getPdfObject(dr)); - PdfDictionary widget = new PdfDictionary(); - for (Iterator it = merged.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - if (widgetKeys.containsKey(key)) - widget.put(key, merged.get(key)); - } - widget.put(iTextTag, new PdfNumber(((Integer)item.tabOrder.get(k)).intValue() + 1)); - list.add(widget); - } - } - - void mergeField(String name, AcroFields.Item item) { - HashMap map = fieldTree; - StringTokenizer tk = new StringTokenizer(name, "."); - if (!tk.hasMoreTokens()) - return; - while (true) { - String s = tk.nextToken(); - Object obj = map.get(s); - if (tk.hasMoreTokens()) { - if (obj == null) { - obj = new HashMap(); - map.put(s, obj); - map = (HashMap)obj; - continue; - } - else if (obj instanceof HashMap) - map = (HashMap)obj; - else - return; - } - else { - if (obj instanceof HashMap) - return; - PdfDictionary merged = (PdfDictionary)item.merged.get(0); - if (obj == null) { - PdfDictionary field = new PdfDictionary(); - for (Iterator it = merged.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - if (fieldKeys.containsKey(key)) - field.put(key, merged.get(key)); - } - ArrayList list = new ArrayList(); - list.add(field); - createWidgets(list, item); - map.put(s, list); - } - else { - ArrayList list = (ArrayList)obj; - PdfDictionary field = (PdfDictionary)list.get(0); - PdfName type1 = (PdfName)field.get(PdfName.FT); - PdfName type2 = (PdfName)merged.get(PdfName.FT); - if (type1 == null || !type1.equals(type2)) - return; - int flag1 = 0; - PdfObject f1 = field.get(PdfName.FF); - if (f1 != null && f1.isNumber()) - flag1 = ((PdfNumber)f1).intValue(); - int flag2 = 0; - PdfObject f2 = merged.get(PdfName.FF); - if (f2 != null && f2.isNumber()) - flag2 = ((PdfNumber)f2).intValue(); - if (type1.equals(PdfName.BTN)) { - if (((flag1 ^ flag2) & PdfFormField.FF_PUSHBUTTON) != 0) - return; - if ((flag1 & PdfFormField.FF_PUSHBUTTON) == 0 && ((flag1 ^ flag2) & PdfFormField.FF_RADIO) != 0) - return; - } - else if (type1.equals(PdfName.CH)) { - if (((flag1 ^ flag2) & PdfFormField.FF_COMBO) != 0) - return; - } - createWidgets(list, item); - } - return; - } - } - } - - void mergeWithMaster(HashMap fd) { - for (Iterator it = fd.keySet().iterator(); it.hasNext();) { - String name = (String)it.next(); - mergeField(name, (AcroFields.Item)fd.get(name)); - } - } - - void mergeFields() { - int pageOffset = 0; - for (int k = 0; k < fields.size(); ++k) { - HashMap fd = ((AcroFields)fields.get(k)).getFields(); - addPageOffsetToField(fd, pageOffset); - mergeWithMaster(fd); - pageOffset += ((PdfReader)readers.get(k)).getNumberOfPages(); - } - } - - public PdfIndirectReference getPageReference(int page) { - return (PdfIndirectReference)pageRefs.get(page - 1); - } - - protected PdfDictionary getCatalog(PdfIndirectReference rootObj) { - try { - PdfDictionary cat = ((PdfDocument)document).getCatalog(rootObj); - if (form != null) { - PdfIndirectReference ref = addToBody(form).getIndirectReference(); - cat.put(PdfName.ACROFORM, ref); - } - if (newBookmarks == null || newBookmarks.size() == 0) - return cat; - PdfDictionary top = new PdfDictionary(); - PdfIndirectReference topRef = getPdfIndirectReference(); - Object kids[] = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, false); - top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); - top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); - top.put(PdfName.COUNT, new PdfNumber(((Integer)kids[2]).intValue())); - addToBody(top, topRef); - cat.put(PdfName.OUTLINES, topRef); - return cat; - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - protected PdfIndirectReference getNewReference(PRIndirectReference ref) { - return new PdfIndirectReference(0, getNewObjectNumber(ref.getReader(), ref.getNumber(), 0)); - } - - protected int getNewObjectNumber(PdfReader reader, int number, int generation) { - IntHashtable refs = (IntHashtable)readers2intrefs.get(reader); - int n = refs.get(number); - if (n == 0) { - n = getIndirectReferenceNumber(); - refs.put(number, n); - } - return n; - } - - protected boolean isVisited(PdfReader reader, int number, int generation) { - IntHashtable refs = (IntHashtable)readers2intrefs.get(reader); - return refs.containsKey(number); - } - - protected boolean isVisited(PRIndirectReference ref) { - IntHashtable refs = (IntHashtable)visited.get(ref.getReader()); - return refs.containsKey(ref.getNumber()); - } - - protected boolean setVisited(PRIndirectReference ref) { - IntHashtable refs = (IntHashtable)visited.get(ref.getReader()); - return (refs.put(ref.getNumber(), 1) != 0); - } - - protected boolean isPage(PRIndirectReference ref) { - IntHashtable refs = (IntHashtable)pages2intrefs.get(ref.getReader()); - return refs.containsKey(ref.getNumber()); - } - - RandomAccessFileOrArray getReaderFile(PdfReader reader) { - return file; - } - - /** - * Sets the bookmarks. The list structure is defined in - * SimpleBookmark#. - * @param outlines the bookmarks or null to remove any - */ - public void setOutlines(List outlines) { - newBookmarks = outlines; - } - - public void openDoc() { - if (!nd.isOpen()) - nd.open(); - } - - protected static final HashMap widgetKeys = new HashMap(); - protected static final HashMap fieldKeys = new HashMap(); - static { - Integer one = new Integer(1); - widgetKeys.put(PdfName.SUBTYPE, one); - widgetKeys.put(PdfName.CONTENTS, one); - widgetKeys.put(PdfName.RECT, one); - widgetKeys.put(PdfName.NM, one); - widgetKeys.put(PdfName.M, one); - widgetKeys.put(PdfName.F, one); - widgetKeys.put(PdfName.BS, one); - widgetKeys.put(PdfName.BORDER, one); - widgetKeys.put(PdfName.AP, one); - widgetKeys.put(PdfName.AS, one); - widgetKeys.put(PdfName.C, one); - widgetKeys.put(PdfName.A, one); - widgetKeys.put(PdfName.STRUCTPARENT, one); - widgetKeys.put(PdfName.OC, one); - widgetKeys.put(PdfName.H, one); - widgetKeys.put(PdfName.MK, one); - widgetKeys.put(PdfName.DA, one); - widgetKeys.put(PdfName.Q, one); - fieldKeys.put(PdfName.AA, one); - fieldKeys.put(PdfName.FT, one); - fieldKeys.put(PdfName.TU, one); - fieldKeys.put(PdfName.TM, one); - fieldKeys.put(PdfName.FF, one); - fieldKeys.put(PdfName.V, one); - fieldKeys.put(PdfName.DV, one); - fieldKeys.put(PdfName.DS, one); - fieldKeys.put(PdfName.RV, one); - fieldKeys.put(PdfName.OPT, one); - fieldKeys.put(PdfName.MAXLEN, one); - fieldKeys.put(PdfName.TI, one); - fieldKeys.put(PdfName.I, one); - fieldKeys.put(PdfName.LOCK, one); - fieldKeys.put(PdfName.SV, one); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfDashPattern.java b/src/main/java/com/lowagie/text/pdf/PdfDashPattern.java deleted file mode 100644 index f5f00f9..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfDashPattern.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * $Id: PdfDashPattern.java,v 1.57 2005/05/04 14:33:09 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * A PdfDashPattern defines a dash pattern as described in - * the PDF Reference Manual version 1.3 p 325 (section 8.4.3). - * - * @see PdfArray - */ - -public class PdfDashPattern extends PdfArray { - - // membervariables - -/** This is the length of a dash. */ - private float dash = -1; - -/** This is the length of a gap. */ - private float gap = -1; - -/** This is the phase. */ - private float phase = -1; - - // constructors - -/** - * Constructs a new PdfDashPattern. - */ - - public PdfDashPattern() { - super(); - } - -/** - * Constructs a new PdfDashPattern. - */ - - public PdfDashPattern(float dash) { - super(new PdfNumber(dash)); - this.dash = dash; - } - -/** - * Constructs a new PdfDashPattern. - */ - - public PdfDashPattern(float dash, float gap) { - super(new PdfNumber(dash)); - add(new PdfNumber(gap)); - this.dash = dash; - this.gap = gap; - } - -/** - * Constructs a new PdfDashPattern. - */ - - public PdfDashPattern(float dash, float gap, float phase) { - super(new PdfNumber(dash)); - add(new PdfNumber(gap)); - this.dash = dash; - this.gap = gap; - this.phase = phase; - } - - public void add(float n) { - add(new PdfNumber(n)); - } - -/** - * Returns the PDF representation of this PdfArray. - * - * @return an array of bytes - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - os.write('['); - - if (dash >= 0) { - new PdfNumber(dash).toPdf(writer, os); - if (gap >= 0) { - os.write(' '); - new PdfNumber(gap).toPdf(writer, os); - } - } - os.write(']'); - if (phase >=0) { - os.write(' '); - new PdfNumber(phase).toPdf(writer, os); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfDate.java b/src/main/java/com/lowagie/text/pdf/PdfDate.java deleted file mode 100644 index 5c26880..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfDate.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * $Id: PdfDate.java,v 1.63 2005/09/04 16:20:01 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.text.SimpleDateFormat; -import java.util.GregorianCalendar; -import java.util.Calendar; -import java.util.SimpleTimeZone; - -/** - * PdfDate is the PDF date object. - *

- * PDF defines a standard date format. The PDF date format closely follows the format - * defined by the international standard ASN.1 (Abstract Syntax Notation One, defined - * in CCITT X.208 or ISO/IEC 8824). A date is a PdfString of the form: - *

- * (D: YYYYMMDDHHmmSSOHH'mm') - *

- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 7.2 (page 183-184) - * - * @see PdfString - * @see java.util.GregorianCalendar - */ - -public class PdfDate extends PdfString { - - private static final int dateSpace[] = {Calendar.YEAR, 4, 0, Calendar.MONTH, 2, -1, Calendar.DAY_OF_MONTH, 2, 0, - Calendar.HOUR_OF_DAY, 2, 0, Calendar.MINUTE, 2, 0, Calendar.SECOND, 2, 0}; - - // constructors - -/** - * Constructs a PdfDate-object. - * - * @param d the date that has to be turned into a PdfDate-object - */ - - public PdfDate(Calendar d) { - super(); - StringBuffer date = new StringBuffer("D:"); - date.append(setLength(d.get(Calendar.YEAR), 4)); - date.append(setLength(d.get(Calendar.MONTH) + 1, 2)); - date.append(setLength(d.get(Calendar.DATE), 2)); - date.append(setLength(d.get(Calendar.HOUR_OF_DAY), 2)); - date.append(setLength(d.get(Calendar.MINUTE), 2)); - date.append(setLength(d.get(Calendar.SECOND), 2)); - int timezone = (d.get(Calendar.ZONE_OFFSET) + d.get(Calendar.DST_OFFSET)) / (60 * 60 * 1000); - if (timezone == 0) { - date.append("Z"); - } - else if (timezone < 0) { - date.append("-"); - timezone = -timezone; - } - else { - date.append("+"); - } - if (timezone != 0) { - date.append(setLength(timezone, 2)).append("'"); - int zone = Math.abs((d.get(Calendar.ZONE_OFFSET) + d.get(Calendar.DST_OFFSET)) / (60 * 1000)) - (timezone * 60); - date.append(setLength(zone, 2)).append("'"); - } - value = date.toString(); - } - -/** - * Constructs a PdfDate-object, representing the current day and time. - */ - - public PdfDate() { - this(new GregorianCalendar()); - } - -/** - * Adds a number of leading zeros to a given String in order to get a String - * of a certain length. - * - * @param i a given number - * @param length the length of the resulting String - * @return the resulting String - */ - - private String setLength(int i, int length) { // 1.3-1.4 problem fixed by Finn Bock - StringBuffer tmp = new StringBuffer(); - tmp.append(i); - while (tmp.length() < length) { - tmp.insert(0, "0"); - } - tmp.setLength(length); - return tmp.toString(); - } - - /** - * Gives the W3C format of the PdfDate. - * @return a formatted date - */ - public String getW3CDate() { - return getW3CDate(value); - } - - /** - * Gives the W3C format of the PdfDate. - * @param d - * @return a formatted date - */ - public static String getW3CDate(String d) { - SimpleDateFormat w3c = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - Calendar c = decode(d); - return w3c.format(c.getTime()); - } - - /** - * Converts a PDF string representing a date into a Calendar. - * @param s the PDF string representing a date - * @return a Calendar representing the date or null if the string - * was not a date - */ - public static Calendar decode(String s) { - try { - if (s.startsWith("D:")) - s = s.substring(2); - GregorianCalendar calendar; - int slen = s.length(); - int idx = s.indexOf('Z'); - if (idx >= 0) { - slen = idx; - calendar = new GregorianCalendar(new SimpleTimeZone(0, "ZPDF")); - } - else { - int sign = 1; - idx = s.indexOf('+'); - if (idx < 0) { - idx = s.indexOf('-'); - if (idx >= 0) - sign = -1; - } - if (idx < 0) - calendar = new GregorianCalendar(); - else { - int offset = Integer.parseInt(s.substring(idx + 1, idx + 3)) * 60; - if (idx + 5 < s.length()) - offset += Integer.parseInt(s.substring(idx + 4, idx + 6)); - calendar = new GregorianCalendar(new SimpleTimeZone(offset * sign * 60000, "ZPDF")); - slen = idx; - } - } - calendar.clear(); - idx = 0; - for (int k = 0; k < dateSpace.length; k += 3) { - if (idx >= slen) - break; - calendar.set(dateSpace[k], Integer.parseInt(s.substring(idx, idx + dateSpace[k + 1])) + dateSpace[k + 2]); - idx += dateSpace[k + 1]; - } - return calendar; - } - catch (Exception e) { - return null; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfDestination.java b/src/main/java/com/lowagie/text/pdf/PdfDestination.java deleted file mode 100644 index 6ab6598..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfDestination.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * $Id: PdfDestination.java,v 1.54 2005/05/04 14:33:11 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * A PdfColor defines a Color (it's a PdfArray containing 3 values). - * - * @see PdfDictionary - */ - -public class PdfDestination extends PdfArray { - - // public static final member-variables - -/** This is a possible destination type */ - public static final int XYZ = 0; - -/** This is a possible destination type */ - public static final int FIT = 1; - -/** This is a possible destination type */ - public static final int FITH = 2; - -/** This is a possible destination type */ - public static final int FITV = 3; - -/** This is a possible destination type */ - public static final int FITR = 4; - -/** This is a possible destination type */ - public static final int FITB = 5; - -/** This is a possible destination type */ - public static final int FITBH = 6; - -/** This is a possible destination type */ - public static final int FITBV = 7; - - // member variables - -/** Is the indirect reference to a page already added? */ - private boolean status = false; - - // constructors - -/** - * Constructs a new PdfDestination. - *

- * If type equals FITB, the bounding box of a page - * will fit the window of the Reader. Otherwise the type will be set to - * FIT so that the entire page will fit to the window. - * - * @param type The destination type - */ - - public PdfDestination(int type) { - super(); - if (type == FITB) { - add(PdfName.FITB); - } - else { - add(PdfName.FIT); - } - } - -/** - * Constructs a new PdfDestination. - *

- * If type equals FITBH / FITBV, - * the width / height of the bounding box of a page will fit the window - * of the Reader. The parameter will specify the y / x coordinate of the - * top / left edge of the window. If the type equals FITH - * or FITV the width / height of the entire page will fit - * the window and the parameter will specify the y / x coordinate of the - * top / left edge. In all other cases the type will be set to FITH. - * - * @param type the destination type - * @param parameter a parameter to combined with the destination type - */ - - public PdfDestination(int type, float parameter) { - super(new PdfNumber(parameter)); - switch(type) { - default: - addFirst(PdfName.FITH); - break; - case FITV: - addFirst(PdfName.FITV); - break; - case FITBH: - addFirst(PdfName.FITBH); - break; - case FITBV: - addFirst(PdfName.FITBV); - } - } - -/** Constructs a new PdfDestination. - *

- * Display the page, with the coordinates (left, top) positioned - * at the top-left corner of the window and the contents of the page magnified - * by the factor zoom. A negative value for any of the parameters left or top, or a - * zoom value of 0 specifies that the current value of that parameter is to be retained unchanged. - * @param type must be a PdfDestination.XYZ - * @param left the left value. Negative to place a null - * @param top the top value. Negative to place a null - * @param zoom The zoom factor. A value of 0 keeps the current value - */ - - public PdfDestination(int type, float left, float top, float zoom) { - super(PdfName.XYZ); - if (left < 0) - add(PdfNull.PDFNULL); - else - add(new PdfNumber(left)); - if (top < 0) - add(PdfNull.PDFNULL); - else - add(new PdfNumber(top)); - add(new PdfNumber(zoom)); - } - -/** Constructs a new PdfDestination. - *

- * Display the page, with its contents magnified just enough - * to fit the rectangle specified by the coordinates left, bottom, right, and top - * entirely within the window both horizontally and vertically. If the required - * horizontal and vertical magnification factors are different, use the smaller of - * the two, centering the rectangle within the window in the other dimension. - * - * @param type must be PdfDestination.FITR - * @param left a parameter - * @param bottom a parameter - * @param right a parameter - * @param top a parameter - * @since iText0.38 - */ - - public PdfDestination(int type, float left, float bottom, float right, float top) { - super(PdfName.FITR); - add(new PdfNumber(left)); - add(new PdfNumber(bottom)); - add(new PdfNumber(right)); - add(new PdfNumber(top)); - } - - // methods - -/** - * Checks if an indirect reference to a page has been added. - * - * @return true or false - */ - - public boolean hasPage() { - return status; - } - -/** Adds the indirect reference of the destination page. - * - * @param page an indirect reference - * @return true if the page reference was added - */ - - public boolean addPage(PdfIndirectReference page) { - if (!status) { - addFirst(page); - status = true; - return true; - } - return false; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfDictionary.java b/src/main/java/com/lowagie/text/pdf/PdfDictionary.java deleted file mode 100644 index acf84d5..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfDictionary.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * $Id: PdfDictionary.java,v 1.62 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.HashMap; -import java.util.List; -import java.util.Set; - -/** - * PdfDictionary is the Pdf dictionary object. - *

- * A dictionary is an associative table containing pairs of objects. The first element - * of each pair is called the key and the second element is called the value. - * Unlike dictionaries in the PostScript language, a key must be a PdfName. - * A value can be any kind of PdfObject, including a dictionary. A dictionary is - * generally used to collect and tie together the attributes of a complex object, with each - * key-value pair specifying the name and value of an attribute.
- * A dictionary is represented by two left angle brackets (<<), followed by a sequence of - * key-value pairs, followed by two right angle brackets (>>).
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.7 (page 40-41). - *

- * - * @see PdfObject - * @see PdfName - * @see BadPdfFormatException - */ - -public class PdfDictionary extends PdfObject { - - // static membervariables (types of dictionary's) - -/** This is a possible type of dictionary */ - public static final PdfName FONT = PdfName.FONT; - -/** This is a possible type of dictionary */ - public static final PdfName OUTLINES = PdfName.OUTLINES; - -/** This is a possible type of dictionary */ - public static final PdfName PAGE = PdfName.PAGE; - -/** This is a possible type of dictionary */ - public static final PdfName PAGES = PdfName.PAGES; - -/** This is a possible type of dictionary */ - public static final PdfName CATALOG = PdfName.CATALOG; - - // membervariables - -/** This is the type of this dictionary */ - private PdfName dictionaryType = null; - -/** This is the hashmap that contains all the values and keys of the dictionary */ - protected HashMap hashMap; - - - // EGIZ various modifications - /** - * This list preserves the order of the elements. - * - *

- * If an element to be added to the list already exists in the list, - * it sould not be added as the contents of this new element - * overwrites the contents of the old element in the hash map. - *

- */ - protected List list; - - - // constructors - -/** - * Constructs an empty PdfDictionary-object. - */ - - public PdfDictionary() { - super(DICTIONARY); - hashMap = new HashMap(); - list = new ArrayList(); - } - -/** - * Constructs a PdfDictionary-object of a certain type. - * - * @param type a PdfName - */ - - public PdfDictionary(PdfName type) { - this(); - dictionaryType = type; - put(PdfName.TYPE, dictionaryType); - } - - // methods overriding some methods in PdfObject - -/** - * Returns the PDF representation of this PdfDictionary. - * - * @return an array of byte - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - os.write('<'); - os.write('<'); - - // loop over all the object-pairs in the HashMap - PdfName key; - PdfObject value; - int type = 0; - for (Iterator i = list.iterator(); //hashMap.keySet().iterator(); - i.hasNext(); ) { - key = (PdfName) i.next(); - value = (PdfObject) hashMap.get(key); - key.toPdf(writer, os); - type = value.type(); - if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) - os.write(' '); - value.toPdf(writer, os); - } - os.write('>'); - os.write('>'); - } - - // methods concerning the HashMap member value - -/** - * Adds a PdfObject and its key to the PdfDictionary. - * - * @param key key of the entry (a PdfName) - * @param value value of the entry (a PdfObject) - * @return the previous
PdfObject
corresponding with the key - */ - - public void put(PdfName key, PdfObject value) { - if (!hashMap.containsKey(key)) - { - // If the key is new, add it to the ordered list. - // If not, it already has a position in the list. - list.add(key); - } - hashMap.put(key, value); - } - -/** - * Adds a PdfObject and its key to the PdfDictionary. - * If the value is null it does nothing. - * - * @param key key of the entry (a PdfName) - * @param value value of the entry (a PdfObject) - * @return the previous PdfObject corresponding with the key - */ - public void putEx(PdfName key, PdfObject value) { - if (value == null) - return; - hashMap.put(key, value); - list.add(key); - } - -/** - * Adds a PdfObject and its key to the PdfDictionary. - * If the value is null the key is deleted. - * - * @param key key of the entry (a PdfName) - * @param value value of the entry (a PdfObject) - * @return the previous PdfObject corresponding with the key - */ - public void putDel(PdfName key, PdfObject value) { - if (value == null) { - hashMap.remove(key); - list.remove(key); - return; - } - hashMap.put(key, value); - list.add(key); - } - -/** - * Removes a PdfObject and its key from the PdfDictionary. - * - * @param key key of the entry (a PdfName) - * @return the previous PdfObject corresponding with the key - */ - - public void remove(PdfName key) { - hashMap.remove(key); - list.remove(key); - } - -/** - * Gets a PdfObject with a certain key from the PdfDictionary. - * - * @param key key of the entry (a PdfName) - * @return the previous PdfObject corresponding with the key - */ - - public PdfObject get(PdfName key) { - return (PdfObject) hashMap.get(key); - } - - // methods concerning the type of Dictionary - -/** - * Checks if a PdfDictionary is of a certain type. - * - * @param type a type of dictionary - * @return true of false - * - * @deprecated - */ - - public boolean isDictionaryType(PdfName type) { - return dictionaryType.compareTo(type) == 0; - } - -/** - * Checks if a Dictionary is of the type FONT. - * - * @return true if it is, false if it isn't. - */ - - public boolean isFont() { - return dictionaryType.compareTo(FONT) == 0; - } - -/** - * Checks if a Dictionary is of the type PAGE. - * - * @return true if it is, false if it isn't. - */ - - public boolean isPage() { - return dictionaryType.compareTo(PAGE) == 0; - } - -/** - * Checks if a Dictionary is of the type PAGES. - * - * @return true if it is, false if it isn't. - */ - - public boolean isPages() { - return dictionaryType.compareTo(PAGES) == 0; - } - -/** - * Checks if a Dictionary is of the type CATALOG. - * - * @return true if it is, false if it isn't. - */ - - public boolean isCatalog() { - return dictionaryType.compareTo(CATALOG) == 0; - } - -/** - * Checks if a Dictionary is of the type OUTLINES. - * - * @return true if it is, false if it isn't. - */ - - public boolean isOutlineTree() { - return dictionaryType.compareTo(OUTLINES) == 0; - } - - public void merge(PdfDictionary other) { - hashMap.putAll(other.hashMap); - list.addAll(other.list); - } - - public void mergeDifferent(PdfDictionary other) { - for (Iterator i = other.list.iterator(); //other.hashMap.keySet().iterator(); - i.hasNext();) { - Object key = i.next(); - if (!hashMap.containsKey(key)) { - hashMap.put(key, other.hashMap.get(key)); - list.add(key); - } - } - } - - public Set getKeys() { - return hashMap.keySet(); - } - - public void putAll(PdfDictionary dic) { - hashMap.putAll(dic.hashMap); - list.addAll(dic.list); - } - - public int size() { - return hashMap.size(); - } - - public boolean contains(PdfName key) { - return hashMap.containsKey(key); - } - - public String toString() { - return "Dictionary of type: " + get(PdfName.TYPE); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfDocument.java b/src/main/java/com/lowagie/text/pdf/PdfDocument.java deleted file mode 100644 index cafc637..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfDocument.java +++ /dev/null @@ -1,3279 +0,0 @@ -/* - * $Name: $ - * $Id: PdfDocument.java,v 1.229 2006/06/04 22:23:34 psoares33 Exp $ - * - * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import com.lowagie.text.Anchor; -import com.lowagie.text.Annotation; -import com.lowagie.text.BadElementException; -import com.lowagie.text.Cell; -import com.lowagie.text.Chunk; -import com.lowagie.text.DocListener; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Element; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Graphic; -import com.lowagie.text.HeaderFooter; -import com.lowagie.text.Image; -import com.lowagie.text.List; -import com.lowagie.text.ListItem; -import com.lowagie.text.Meta; -import com.lowagie.text.Paragraph; -import com.lowagie.text.Phrase; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Section; -import com.lowagie.text.SimpleTable; -import com.lowagie.text.StringCompare; -import com.lowagie.text.Table; -import com.lowagie.text.Watermark; -import com.lowagie.text.xml.xmp.XmpWriter; - -/** - * PdfDocument is the class that is used by PdfWriter - * to translate a Document into a PDF with different pages. - *

- * A PdfDocument always listens to a Document - * and adds the Pdf representation of every Element that is - * added to the Document. - * - * @see com.lowagie.text.Document - * @see com.lowagie.text.DocListener - * @see PdfWriter - */ - -class PdfDocument extends Document implements DocListener { - - /** - * PdfInfo is the PDF InfoDictionary. - *

- * A document's trailer may contain a reference to an Info dictionary that provides information - * about the document. This optional dictionary may contain one or more keys, whose values - * should be strings.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 6.10 (page 120-121) - */ - - public static class PdfInfo extends PdfDictionary { - - // constructors - - /** - * Construct a PdfInfo-object. - */ - - PdfInfo() { - super(); - addProducer(); - addCreationDate(); - } - - /** - * Constructs a PdfInfo-object. - * - * @param author name of the author of the document - * @param title title of the document - * @param subject subject of the document - */ - - PdfInfo(String author, String title, String subject) { - this(); - addTitle(title); - addSubject(subject); - addAuthor(author); - } - - /** - * Adds the title of the document. - * - * @param title the title of the document - */ - - void addTitle(String title) { - put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); - } - - /** - * Adds the subject to the document. - * - * @param subject the subject of the document - */ - - void addSubject(String subject) { - put(PdfName.SUBJECT, new PdfString(subject, PdfObject.TEXT_UNICODE)); - } - - /** - * Adds some keywords to the document. - * - * @param keywords the keywords of the document - */ - - void addKeywords(String keywords) { - put(PdfName.KEYWORDS, new PdfString(keywords, PdfObject.TEXT_UNICODE)); - } - - /** - * Adds the name of the author to the document. - * - * @param author the name of the author - */ - - void addAuthor(String author) { - put(PdfName.AUTHOR, new PdfString(author, PdfObject.TEXT_UNICODE)); - } - - /** - * Adds the name of the creator to the document. - * - * @param creator the name of the creator - */ - - void addCreator(String creator) { - put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE)); - } - - /** - * Adds the name of the producer to the document. - */ - - void addProducer() { - // This line may only be changed by Bruno Lowagie or Paulo Soares - put(PdfName.PRODUCER, new PdfString(getVersion())); - // Do not edit the line above! - } - - /** - * Adds the date of creation to the document. - */ - - void addCreationDate() { - PdfString date = new PdfDate(); - put(PdfName.CREATIONDATE, date); - put(PdfName.MODDATE, date); - } - - void addkey(String key, String value) { - if (key.equals("Producer") || key.equals("CreationDate")) - return; - put(new PdfName(key), new PdfString(value, PdfObject.TEXT_UNICODE)); - } - } - - /** - * PdfCatalog is the PDF Catalog-object. - *

- * The Catalog is a dictionary that is the root node of the document. It contains a reference - * to the tree of pages contained in the document, a reference to the tree of objects representing - * the document's outline, a reference to the document's article threads, and the list of named - * destinations. In addition, the Catalog indicates whether the document's outline or thumbnail - * page images should be displayed automatically when the document is viewed and wether some location - * other than the first page should be shown when the document is opened.
- * In this class however, only the reference to the tree of pages is implemented.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 6.2 (page 67-71) - */ - - static class PdfCatalog extends PdfDictionary { - - PdfWriter writer; - // constructors - - /** - * Constructs a PdfCatalog. - * - * @param pages an indirect reference to the root of the document's Pages tree. - * @param writer the writer the catalog applies to - */ - - PdfCatalog(PdfIndirectReference pages, PdfWriter writer) { - super(CATALOG); - this.writer = writer; - put(PdfName.PAGES, pages); - } - - /** - * Constructs a PdfCatalog. - * - * @param pages an indirect reference to the root of the document's Pages tree. - * @param outlines an indirect reference to the outline tree. - * @param writer the writer the catalog applies to - */ - - PdfCatalog(PdfIndirectReference pages, PdfIndirectReference outlines, PdfWriter writer) { - super(CATALOG); - this.writer = writer; - put(PdfName.PAGES, pages); - put(PdfName.PAGEMODE, PdfName.USEOUTLINES); - put(PdfName.OUTLINES, outlines); - } - - /** - * Adds the names of the named destinations to the catalog. - * @param localDestinations the local destinations - * @param documentJavaScript the javascript used in the document - * @param writer the writer the catalog applies to - */ - void addNames(TreeMap localDestinations, ArrayList documentJavaScript, HashMap documentFileAttachment, PdfWriter writer) { - if (localDestinations.size() == 0 && documentJavaScript.size() == 0 && documentFileAttachment.size() == 0) - return; - try { - PdfDictionary names = new PdfDictionary(); - if (localDestinations.size() > 0) { - PdfArray ar = new PdfArray(); - for (Iterator i = localDestinations.keySet().iterator(); i.hasNext();) { - String name = (String)i.next(); - Object obj[] = (Object[])localDestinations.get(name); - PdfIndirectReference ref = (PdfIndirectReference)obj[1]; - ar.add(new PdfString(name)); - ar.add(ref); - } - PdfDictionary dests = new PdfDictionary(); - dests.put(PdfName.NAMES, ar); - names.put(PdfName.DESTS, writer.addToBody(dests).getIndirectReference()); - } - if (documentJavaScript.size() > 0) { - String s[] = new String[documentJavaScript.size()]; - for (int k = 0; k < s.length; ++k) - s[k] = Integer.toHexString(k); - Arrays.sort(s, new StringCompare()); - PdfArray ar = new PdfArray(); - for (int k = 0; k < s.length; ++k) { - ar.add(new PdfString(s[k])); - ar.add((PdfIndirectReference)documentJavaScript.get(k)); - } - PdfDictionary js = new PdfDictionary(); - js.put(PdfName.NAMES, ar); - names.put(PdfName.JAVASCRIPT, writer.addToBody(js).getIndirectReference()); - } - if (documentFileAttachment.size() > 0) { - names.put(PdfName.EMBEDDEDFILES, writer.addToBody(PdfNameTree.writeTree(documentFileAttachment, writer)).getIndirectReference()); - } - put(PdfName.NAMES, writer.addToBody(names).getIndirectReference()); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** Sets the viewer preferences as the sum of several constants. - * @param preferences the viewer preferences - * @see PdfWriter#setViewerPreferences - */ - - void setViewerPreferences(int preferences) { - PdfReader.setViewerPreferences(preferences, this); - } - - void setOpenAction(PdfAction action) { - put(PdfName.OPENACTION, action); - } - - - /** Sets the document level additional actions. - * @param actions dictionary of actions - */ - void setAdditionalActions(PdfDictionary actions) { - try { - put(PdfName.AA, writer.addToBody(actions).getIndirectReference()); - } catch (Exception e) { - new ExceptionConverter(e); - } - } - - - void setPageLabels(PdfPageLabels pageLabels) { - put(PdfName.PAGELABELS, pageLabels.getDictionary()); - } - - void setAcroForm(PdfObject fields) { - put(PdfName.ACROFORM, fields); - } - } - - // membervariables - private PdfIndirectReference thumb; - - /** The characters to be applied the hanging ponctuation. */ - static final String hangingPunctuation = ".,;:'"; - - /** The PdfWriter. */ - private PdfWriter writer; - - /** some meta information about the Document. */ - private PdfInfo info = new PdfInfo(); - - /** Signals that OnOpenDocument should be called. */ - private boolean firstPageEvent = true; - - /** Signals that onParagraph is valid. */ - private boolean isParagraph = true; - - // Horizontal line - - /** The line that is currently being written. */ - private PdfLine line = null; - - /** This represents the current indentation of the PDF Elements on the left side. */ - private float indentLeft = 0; - - /** This represents the current indentation of the PDF Elements on the right side. */ - private float indentRight = 0; - - /** This represents the current indentation of the PDF Elements on the left side. */ - private float listIndentLeft = 0; - - /** This represents the current alignment of the PDF Elements. */ - private int alignment = Element.ALIGN_LEFT; - - // Vertical lines - - /** This is the PdfContentByte object, containing the text. */ - private PdfContentByte text; - - /** This is the PdfContentByte object, containing the borders and other Graphics. */ - private PdfContentByte graphics; - - /** The lines that are written until now. */ - private ArrayList lines = new ArrayList(); - - /** This represents the leading of the lines. */ - private float leading = 0; - - /** This is the current height of the document. */ - private float currentHeight = 0; - - /** This represents the current indentation of the PDF Elements on the top side. */ - private float indentTop = 0; - - /** This represents the current indentation of the PDF Elements on the bottom side. */ - private float indentBottom = 0; - - /** This checks if the page is empty. */ - private boolean pageEmpty = true; - - private int textEmptySize; - // resources - - /** This is the size of the next page. */ - protected Rectangle nextPageSize = null; - - /** This is the size of the several boxes of the current Page. */ - protected HashMap thisBoxSize = new HashMap(); - - /** This is the size of the several boxes that will be used in - * the next page. */ - protected HashMap boxSize = new HashMap(); - - /** This are the page resources of the current Page. */ - protected PageResources pageResources; - - // images - - /** This is the image that could not be shown on a previous page. */ - private Image imageWait = null; - - /** This is the position where the image ends. */ - private float imageEnd = -1; - - /** This is the indentation caused by an image on the left. */ - private float imageIndentLeft = 0; - - /** This is the indentation caused by an image on the right. */ - private float imageIndentRight = 0; - - // annotations and outlines - - /** This is the array containing the references to the annotations. */ - private ArrayList annotations; - - /** This is an array containg references to some delayed annotations. */ - private ArrayList delayedAnnotations = new ArrayList(); - - /** This is the AcroForm object. */ - PdfAcroForm acroForm; - - /** This is the root outline of the document. */ - private PdfOutline rootOutline; - - /** This is the current PdfOutline in the hierarchy of outlines. */ - private PdfOutline currentOutline; - - /** The current active PdfAction when processing an Anchor. */ - private PdfAction currentAction = null; - - /** - * Stores the destinations keyed by name. Value is - * Object[]{PdfAction,PdfIndirectReference,PdfDestintion}. - */ - private TreeMap localDestinations = new TreeMap(new StringCompare()); - - private ArrayList documentJavaScript = new ArrayList(); - - private HashMap documentFileAttachment = new HashMap(); - - /** these are the viewerpreferences of the document */ - private int viewerPreferences = 0; - - private String openActionName; - private PdfAction openActionAction; - private PdfDictionary additionalActions; - private PdfPageLabels pageLabels; - - //add by Jin-Hsia Yang - private boolean isNewpage = false; - - private float paraIndent = 0; - //end add by Jin-Hsia Yang - - /** margin in x direction starting from the left. Will be valid in the next page */ - protected float nextMarginLeft; - - /** margin in x direction starting from the right. Will be valid in the next page */ - protected float nextMarginRight; - - /** margin in y direction starting from the top. Will be valid in the next page */ - protected float nextMarginTop; - - /** margin in y direction starting from the bottom. Will be valid in the next page */ - protected float nextMarginBottom; - -/** The duration of the page */ - protected int duration=-1; // negative values will indicate no duration - -/** The page transition */ - protected PdfTransition transition=null; - - protected PdfDictionary pageAA = null; - - /** Holds value of property strictImageSequence. */ - private boolean strictImageSequence = false; - - /** Holds the type of the last element, that has been added to the document. */ - private int lastElementType = -1; - - private boolean isNewPagePending; - - protected int markPoint; - - // constructors - - /** - * Constructs a new PDF document. - * @throws DocumentException on error - */ - - public PdfDocument() throws DocumentException { - super(); - addProducer(); - addCreationDate(); - } - - // listener methods - - /** - * Adds a PdfWriter to the PdfDocument. - * - * @param writer the PdfWriter that writes everything - * what is added to this document to an outputstream. - * @throws DocumentException on error - */ - - public void addWriter(PdfWriter writer) throws DocumentException { - if (this.writer == null) { - this.writer = writer; - acroForm = new PdfAcroForm(writer); - return; - } - throw new DocumentException("You can only add a writer to a PdfDocument once."); - } - - /** - * Sets the pagesize. - * - * @param pageSize the new pagesize - * @return true if the page size was set - */ - - public boolean setPageSize(Rectangle pageSize) { - if (writer != null && writer.isPaused()) { - return false; - } - nextPageSize = new Rectangle(pageSize); - return true; - } - - /** - * Changes the header of this document. - * - * @param header the new header - */ - - public void setHeader(HeaderFooter header) { - if (writer != null && writer.isPaused()) { - return; - } - super.setHeader(header); - } - - /** - * Resets the header of this document. - */ - - public void resetHeader() { - if (writer != null && writer.isPaused()) { - return; - } - super.resetHeader(); - } - - /** - * Changes the footer of this document. - * - * @param footer the new footer - */ - - public void setFooter(HeaderFooter footer) { - if (writer != null && writer.isPaused()) { - return; - } - super.setFooter(footer); - } - - /** - * Resets the footer of this document. - */ - - public void resetFooter() { - if (writer != null && writer.isPaused()) { - return; - } - super.resetFooter(); - } - - /** - * Sets the page number to 0. - */ - - public void resetPageCount() { - if (writer != null && writer.isPaused()) { - return; - } - super.resetPageCount(); - } - - /** - * Sets the page number. - * - * @param pageN the new page number - */ - - public void setPageCount(int pageN) { - if (writer != null && writer.isPaused()) { - return; - } - super.setPageCount(pageN); - } - - /** - * Sets the Watermark. - * - * @param watermark the watermark to add - * @return true if the element was added, false if not. - */ - - public boolean add(Watermark watermark) { - if (writer != null && writer.isPaused()) { - return false; - } - this.watermark = watermark; - return true; - } - - /** - * Removes the Watermark. - */ - - public void removeWatermark() { - if (writer != null && writer.isPaused()) { - return; - } - this.watermark = null; - } - - /** - * Sets the margins. - * - * @param marginLeft the margin on the left - * @param marginRight the margin on the right - * @param marginTop the margin on the top - * @param marginBottom the margin on the bottom - * @return a boolean - */ - - public boolean setMargins(float marginLeft, float marginRight, float marginTop, float marginBottom) { - if (writer != null && writer.isPaused()) { - return false; - } - nextMarginLeft = marginLeft; - nextMarginRight = marginRight; - nextMarginTop = marginTop; - nextMarginBottom = marginBottom; - return true; - } - - protected PdfArray rotateAnnotations() { - PdfArray array = new PdfArray(); - int rotation = pageSize.getRotation() % 360; - int currentPage = writer.getCurrentPageNumber(); - for (int k = 0; k < annotations.size(); ++k) { - PdfAnnotation dic = (PdfAnnotation)annotations.get(k); - int page = dic.getPlaceInPage(); - if (page > currentPage) { - delayedAnnotations.add(dic); - continue; - } - if (dic.isForm()) { - if (!dic.isUsed()) { - HashMap templates = dic.getTemplates(); - if (templates != null) - acroForm.addFieldTemplates(templates); - } - PdfFormField field = (PdfFormField)dic; - if (field.getParent() == null) - acroForm.addDocumentField(field.getIndirectReference()); - } - if (dic.isAnnotation()) { - array.add(dic.getIndirectReference()); - if (!dic.isUsed()) { - PdfRectangle rect = (PdfRectangle)dic.get(PdfName.RECT); - if (rect != null) { - switch (rotation) { - case 90: - dic.put(PdfName.RECT, new PdfRectangle( - pageSize.top() - rect.bottom(), - rect.left(), - pageSize.top() - rect.top(), - rect.right())); - break; - case 180: - dic.put(PdfName.RECT, new PdfRectangle( - pageSize.right() - rect.left(), - pageSize.top() - rect.bottom(), - pageSize.right() - rect.right(), - pageSize.top() - rect.top())); - break; - case 270: - dic.put(PdfName.RECT, new PdfRectangle( - rect.bottom(), - pageSize.right() - rect.left(), - rect.top(), - pageSize.right() - rect.right())); - break; - } - } - } - } - if (!dic.isUsed()) { - dic.setUsed(); - try { - writer.addToBody(dic, dic.getIndirectReference()); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - } - return array; - } - - /** - * Makes a new page and sends it to the PdfWriter. - * - * @return a boolean - * @throws DocumentException on error - */ - - public boolean newPage() throws DocumentException { - lastElementType = -1; - //add by Jin-Hsia Yang - isNewpage = true; - //end add by Jin-Hsia Yang - if (writer.getDirectContent().size() == 0 && writer.getDirectContentUnder().size() == 0 && (pageEmpty || (writer != null && writer.isPaused()))) { - return false; - } - PdfPageEvent pageEvent = writer.getPageEvent(); - if (pageEvent != null) - pageEvent.onEndPage(writer, this); - - //Added to inform any listeners that we are moving to a new page (added by David Freels) - super.newPage(); - - // the following 2 lines were added by Pelikan Stephan - imageIndentLeft = 0; - imageIndentRight = 0; - - // we flush the arraylist with recently written lines - flushLines(); - // we assemble the resources of this pages - pageResources.addDefaultColorDiff(writer.getDefaultColorspace()); - PdfDictionary resources = pageResources.getResources(); - // we make a new page and add it to the document - if (writer.getPDFXConformance() != PdfWriter.PDFXNONE) { - if (thisBoxSize.containsKey("art") && thisBoxSize.containsKey("trim")) - throw new PdfXConformanceException("Only one of ArtBox or TrimBox can exist in the page."); - if (!thisBoxSize.containsKey("art") && !thisBoxSize.containsKey("trim")) { - if (thisBoxSize.containsKey("crop")) - thisBoxSize.put("trim", thisBoxSize.get("crop")); - else - thisBoxSize.put("trim", new PdfRectangle(pageSize, pageSize.getRotation())); - } - } - PdfPage page; - int rotation = pageSize.getRotation(); - page = new PdfPage(new PdfRectangle(pageSize, rotation), thisBoxSize, resources, rotation); - // we add tag info - if (writer.isTagged()) - page.put(PdfName.STRUCTPARENTS, new PdfNumber(writer.getCurrentPageNumber() - 1)); -// we add the transitions - if (this.transition!=null) { - page.put(PdfName.TRANS, this.transition.getTransitionDictionary()); - transition = null; - } - if (this.duration>0) { - page.put(PdfName.DUR,new PdfNumber(this.duration)); - duration = 0; - } - // we add the page object additional actions - if (pageAA != null) { - try { - page.put(PdfName.AA, writer.addToBody(pageAA).getIndirectReference()); - } - catch (IOException ioe) { - throw new ExceptionConverter(ioe); - } - pageAA = null; - } - // we check if the userunit is defined - if (writer.getUserunit() > 0f) { - page.put(PdfName.USERUNIT, new PdfNumber(writer.getUserunit())); - } - // we add the annotations - if (annotations.size() > 0) { - PdfArray array = rotateAnnotations(); - if (array.size() != 0) - page.put(PdfName.ANNOTS, array); - } - // we add the thumbs - if (thumb != null) { - page.put(PdfName.THUMB, thumb); - thumb = null; - } - if (!open || close) { - throw new PdfException("The document isn't open."); - } - if (text.size() > textEmptySize) - text.endText(); - else - text = null; - writer.add(page, new PdfContents(writer.getDirectContentUnder(), graphics, text, writer.getDirectContent(), pageSize)); - // we initialize the new page - initPage(); - - //add by Jin-Hsia Yang - isNewpage = false; - //end add by Jin-Hsia Yang - - return true; - } - - // methods to open and close a document - - /** - * Opens the document. - *

- * You have to open the document before you can begin to add content - * to the body of the document. - */ - - public void open() { - if (!open) { - super.open(); - writer.open(); - rootOutline = new PdfOutline(writer); - currentOutline = rootOutline; - } - try { - initPage(); - } - catch(DocumentException de) { - throw new ExceptionConverter(de); - } - } - - void outlineTree(PdfOutline outline) throws IOException { - outline.setIndirectReference(writer.getPdfIndirectReference()); - if (outline.parent() != null) - outline.put(PdfName.PARENT, outline.parent().indirectReference()); - ArrayList kids = outline.getKids(); - int size = kids.size(); - for (int k = 0; k < size; ++k) - outlineTree((PdfOutline)kids.get(k)); - for (int k = 0; k < size; ++k) { - if (k > 0) - ((PdfOutline)kids.get(k)).put(PdfName.PREV, ((PdfOutline)kids.get(k - 1)).indirectReference()); - if (k < size - 1) - ((PdfOutline)kids.get(k)).put(PdfName.NEXT, ((PdfOutline)kids.get(k + 1)).indirectReference()); - } - if (size > 0) { - outline.put(PdfName.FIRST, ((PdfOutline)kids.get(0)).indirectReference()); - outline.put(PdfName.LAST, ((PdfOutline)kids.get(size - 1)).indirectReference()); - } - for (int k = 0; k < size; ++k) { - PdfOutline kid = (PdfOutline)kids.get(k); - writer.addToBody(kid, kid.indirectReference()); - } - } - - void writeOutlines() throws IOException { - if (rootOutline.getKids().size() == 0) - return; - outlineTree(rootOutline); - writer.addToBody(rootOutline, rootOutline.indirectReference()); - } - - void traverseOutlineCount(PdfOutline outline) { - ArrayList kids = outline.getKids(); - PdfOutline parent = outline.parent(); - if (kids.size() == 0) { - if (parent != null) { - parent.setCount(parent.getCount() + 1); - } - } - else { - for (int k = 0; k < kids.size(); ++k) { - traverseOutlineCount((PdfOutline)kids.get(k)); - } - if (parent != null) { - if (outline.isOpen()) { - parent.setCount(outline.getCount() + parent.getCount() + 1); - } - else { - parent.setCount(parent.getCount() + 1); - outline.setCount(-outline.getCount()); - } - } - } - } - - void calculateOutlineCount() { - if (rootOutline.getKids().size() == 0) - return; - traverseOutlineCount(rootOutline); - } - /** - * Closes the document. - * - * Once all the content has been written in the body, you have to close - * the body. After that nothing can be written to the body anymore. - */ - - public void close() { - if (close) { - return; - } - try { - boolean wasImage = (imageWait != null); - newPage(); - if (imageWait != null || wasImage) newPage(); - if (annotations.size() > 0) - throw new RuntimeException(annotations.size() + " annotations had invalid placement pages."); - PdfPageEvent pageEvent = writer.getPageEvent(); - if (pageEvent != null) - pageEvent.onCloseDocument(writer, this); - super.close(); - - writer.addLocalDestinations(localDestinations); - calculateOutlineCount(); - writeOutlines(); - } - catch(Exception e) { - throw new ExceptionConverter(e); - } - - writer.close(); - } - - PageResources getPageResources() { - return pageResources; - } - - /** Adds a PdfPTable to the document. - * @param ptable the PdfPTable to be added to the document. - * @throws DocumentException on error - */ - void addPTable(PdfPTable ptable) throws DocumentException { - ColumnText ct = new ColumnText(writer.getDirectContent()); - if (currentHeight > 0) { - Paragraph p = new Paragraph(); - p.setLeading(0); - ct.addElement(p); - // if the table prefers to be on a single page, and it wouldn't - //fit on the current page, start a new page. - if (ptable.getKeepTogether() && !fitsPage(ptable, 0f)) - newPage(); - } - ct.addElement(ptable); - boolean he = ptable.isHeadersInEvent(); - ptable.setHeadersInEvent(true); - int loop = 0; - while (true) { - ct.setSimpleColumn(indentLeft(), indentBottom(), indentRight(), indentTop() - currentHeight); - int status = ct.go(); - if ((status & ColumnText.NO_MORE_TEXT) != 0) { - text.moveText(0, ct.getYLine() - indentTop() + currentHeight); - currentHeight = indentTop() - ct.getYLine(); - break; - } - if (indentTop() - currentHeight == ct.getYLine()) - ++loop; - else - loop = 0; - if (loop == 3) { - add(new Paragraph("ERROR: Infinite table loop")); - break; - } - newPage(); - } - ptable.setHeadersInEvent(he); - } - - /** - * Gets a PdfTable object - * (contributed by dperezcar@fcc.es) - * @param table a high level table object - * @param supportRowAdditions - * @return returns a PdfTable object - * @see PdfWriter#getPdfTable(Table) - */ - - PdfTable getPdfTable(Table table, boolean supportRowAdditions) { - return new PdfTable(table, indentLeft(), indentRight(), indentTop() - currentHeight, supportRowAdditions); - } - - /** - * @see PdfWriter#breakTableIfDoesntFit(PdfTable) - * (contributed by dperezcar@fcc.es) - * @param table Table to add - * @return true if the table will be broken - * @throws DocumentException - */ - - boolean breakTableIfDoesntFit(PdfTable table) throws DocumentException { - table.updateRowAdditions(); - // Do we have any full page available? - if (!table.hasToFitPageTable() && table.bottom() <= indentBottom) { - // Then output that page - add(table, true); - return true; - } - return false; - } - - private static class RenderingContext { - int countPageBreaks = 0; - float pagetop = -1; - float oldHeight = -1; - - PdfContentByte cellGraphics = null; - - float lostTableBottom; - - float maxCellBottom; - float maxCellHeight; - - Map rowspanMap; - Map pageMap = new HashMap(); - /** - * A PdfPTable - */ - public PdfTable table; - - /** - * Consumes the rowspan - * @param c - * @return a rowspan. - */ - public int consumeRowspan(PdfCell c) { - if (c.rowspan() == 1) { - return 1; - } - - Integer i = (Integer) rowspanMap.get(c); - if (i == null) { - i = new Integer(c.rowspan()); - } - - i = new Integer(i.intValue() - 1); - rowspanMap.put(c, i); - - if (i.intValue() < 1) { - return 1; - } - return i.intValue(); - } - - /** - * Looks at the current rowspan. - * @param c - * @return the current rowspan - */ - public int currentRowspan(PdfCell c) { - Integer i = (Integer) rowspanMap.get(c); - if (i == null) { - return c.rowspan(); - } else { - return i.intValue(); - } - } - - public int cellRendered(PdfCell cell, int pageNumber) { - Integer i = (Integer) pageMap.get(cell); - if (i == null) { - i = new Integer(1); - } else { - i = new Integer(i.intValue() + 1); - } - pageMap.put(cell, i); - - Integer pageInteger = new Integer(pageNumber); - Set set = (Set) pageMap.get(pageInteger); - - if (set == null) { - set = new HashSet(); - pageMap.put(pageInteger, set); - } - - set.add(cell); - - return i.intValue(); - } - - public int numCellRendered(PdfCell cell) { - Integer i = (Integer) pageMap.get(cell); - if (i == null) { - i = new Integer(0); - } - return i.intValue(); - } - - public boolean isCellRenderedOnPage(PdfCell cell, int pageNumber) { - Integer pageInteger = new Integer(pageNumber); - Set set = (Set) pageMap.get(pageInteger); - - if (set != null) { - return set.contains(cell); - } - - return false; - } - }; - - private void analyzeRow(ArrayList rows, RenderingContext ctx) { - ctx.maxCellBottom = indentBottom(); - - // determine whether row(index) is in a rowspan - int rowIndex = 0; - - ArrayList row = (ArrayList) rows.get(rowIndex); - int maxRowspan = 1; - Iterator iterator = row.iterator(); - while (iterator.hasNext()) { - PdfCell cell = (PdfCell) iterator.next(); - maxRowspan = Math.max(ctx.currentRowspan(cell), maxRowspan); - } - rowIndex += maxRowspan; - - boolean useTop = true; - if (rowIndex == rows.size()) { - rowIndex = rows.size() - 1; - useTop = false; - } - - if (rowIndex < 0 || rowIndex >= rows.size()) return; - - row = (ArrayList) rows.get(rowIndex); - iterator = row.iterator(); - while (iterator.hasNext()) { - PdfCell cell = (PdfCell) iterator.next(); - Rectangle cellRect = cell.rectangle(ctx.pagetop, indentBottom()); - if (useTop) { - ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.top()); - } else { - if (ctx.currentRowspan(cell) == 1) { - ctx.maxCellBottom = Math.max(ctx.maxCellBottom, cellRect.bottom()); - } - } - } - } - - /** - * Adds a new table to - * @param table Table to add. Rendered rows will be deleted after processing. - * @param onlyFirstPage Render only the first full page - * @throws DocumentException - */ - private void add(PdfTable table, boolean onlyFirstPage) throws DocumentException { - // before every table, we flush all lines - flushLines(); - - RenderingContext ctx = new RenderingContext(); - ctx.pagetop = indentTop(); - ctx.oldHeight = currentHeight; - ctx.cellGraphics = new PdfContentByte(writer); - ctx.rowspanMap = new HashMap(); - ctx.table = table; - - // initialisation of parameters - PdfCell cell; - - boolean tableHasToFit = - table.hasToFitPageTable() ? (table.bottom() < indentBottom() && table.height() < (top() - bottom())) : false; - if (pageEmpty) - tableHasToFit = false; - boolean cellsHaveToFit = table.hasToFitPageCells(); - - // drawing the table - ArrayList dataCells = table.getCells(); - - ArrayList headercells = table.getHeaderCells(); - // Check if we have removed header cells in a previous call - if (headercells.size() > 0 && (dataCells.size() == 0 || dataCells.get(0) != headercells.get(0))) { - ArrayList allCells = new ArrayList(dataCells.size()+headercells.size()); - allCells.addAll(headercells); - allCells.addAll(dataCells); - dataCells = allCells; - } - - ArrayList cells = dataCells; - ArrayList rows = extractRows(cells, ctx); - boolean isContinue = false; - while (!cells.isEmpty()) { - // initialisation of some extra parameters; - ctx.lostTableBottom = 0; - - // loop over the cells - boolean cellsShown = false; - int currentGroupNumber = 0; - boolean headerChecked = false; - - float headerHeight = 0; - - // draw the cells (line by line) - Iterator iterator = rows.iterator(); - - boolean atLeastOneFits = false; - while (iterator.hasNext()) { - ArrayList row = (ArrayList) iterator.next(); - analyzeRow(rows, ctx); - renderCells(ctx, row, table.hasToFitPageCells() & atLeastOneFits); - - if (!mayBeRemoved(row)) { - break; - } - consumeRowspan(row, ctx); - iterator.remove(); - atLeastOneFits = true; - } - -// compose cells array list for subsequent code - cells.clear(); - Set opt = new HashSet(); - iterator = rows.iterator(); - while (iterator.hasNext()) { - ArrayList row = (ArrayList) iterator.next(); - - Iterator cellIterator = row.iterator(); - while (cellIterator.hasNext()) { - cell = (PdfCell) cellIterator.next(); - - if (!opt.contains(cell)) { - cells.add(cell); - opt.add(cell); - } - } - } - - tableHasToFit = false; - - // we paint the graphics of the table after looping through all the cells - Rectangle tablerec = new Rectangle(table); - tablerec.setBorder(table.border()); - tablerec.setBorderWidth(table.borderWidth()); - tablerec.setBorderColor(table.borderColor()); - tablerec.setBackgroundColor(table.backgroundColor()); - PdfContentByte under = writer.getDirectContentUnder(); - under.rectangle(tablerec.rectangle(top(), indentBottom())); - under.add(ctx.cellGraphics); - // bugfix by Gerald Fehringer: now again add the border for the table - // since it might have been covered by cell backgrounds - tablerec.setBackgroundColor(null); - tablerec = tablerec.rectangle(top(), indentBottom()); - tablerec.setBorder(table.border()); - under.rectangle(tablerec); - // end bugfix - - ctx.cellGraphics = new PdfContentByte(null); - // if the table continues on the next page - - if (!rows.isEmpty()) { - isContinue = true; - graphics.setLineWidth(table.borderWidth()); - if (cellsShown && (table.border() & Rectangle.BOTTOM) == Rectangle.BOTTOM) { - // Draw the bottom line - - // the color is set to the color of the element - Color tColor = table.borderColor(); - if (tColor != null) { - graphics.setColorStroke(tColor); - } - graphics.moveTo(table.left(), Math.max(table.bottom(), indentBottom())); - graphics.lineTo(table.right(), Math.max(table.bottom(), indentBottom())); - graphics.stroke(); - if (tColor != null) { - graphics.resetRGBColorStroke(); - } - } - - // old page - pageEmpty = false; - float difference = ctx.lostTableBottom; - - // new page - newPage(); - - ctx.countPageBreaks++; - - // G.F.: if something added in page event i.e. currentHeight > 0 - float heightCorrection = 0; - boolean somethingAdded = false; - if (currentHeight > 0) { - heightCorrection = 6; - currentHeight += heightCorrection; - somethingAdded = true; - newLine(); - flushLines(); - indentTop = currentHeight - leading; - currentHeight = 0; - } - else { - flushLines(); - } - - // this part repeats the table headers (if any) - int size = headercells.size(); - if (size > 0) { - // this is the top of the headersection - cell = (PdfCell) headercells.get(0); - float oldTop = cell.top(0); - // loop over all the cells of the table header - for (int i = 0; i < size; i++) { - cell = (PdfCell) headercells.get(i); - // calculation of the new cellpositions - cell.setTop(indentTop() - oldTop + cell.top(0)); - cell.setBottom(indentTop() - oldTop + cell.bottom(0)); - ctx.pagetop = cell.bottom(); - // we paint the borders of the cell - ctx.cellGraphics.rectangle(cell.rectangle(indentTop(), indentBottom())); - // we write the text of the cell - ArrayList images = cell.getImages(indentTop(), indentBottom()); - for (Iterator im = images.iterator(); im.hasNext();) { - cellsShown = true; - Image image = (Image) im.next(); - graphics.addImage(image); - } - lines = cell.getLines(indentTop(), indentBottom()); - float cellTop = cell.top(indentTop()); - text.moveText(0, cellTop-heightCorrection); - float cellDisplacement = flushLines() - cellTop+heightCorrection; - text.moveText(0, cellDisplacement); - } - - currentHeight = indentTop() - ctx.pagetop + table.cellspacing(); - text.moveText(0, ctx.pagetop - indentTop() - currentHeight); - } - else { - if (somethingAdded) { - ctx.pagetop = indentTop(); - text.moveText(0, -table.cellspacing()); - } - } - ctx.oldHeight = currentHeight - heightCorrection; - - // calculating the new positions of the table and the cells - size = Math.min(cells.size(), table.columns()); - int i = 0; - while (i < size) { - cell = (PdfCell) cells.get(i); - if (cell.top(-table.cellspacing()) > ctx.lostTableBottom) { - float newBottom = ctx.pagetop - difference + cell.bottom(); - float neededHeight = cell.remainingHeight(); - if (newBottom > ctx.pagetop - neededHeight) { - difference += newBottom - (ctx.pagetop - neededHeight); - } - } - i++; - } - size = cells.size(); - table.setTop(indentTop()); - table.setBottom(ctx.pagetop - difference + table.bottom(table.cellspacing())); - for (i = 0; i < size; i++) { - cell = (PdfCell) cells.get(i); - float newBottom = ctx.pagetop - difference + cell.bottom(); - float newTop = ctx.pagetop - difference + cell.top(-table.cellspacing()); - if (newTop > indentTop() - currentHeight) { - newTop = indentTop() - currentHeight; - } - - cell.setTop(newTop ); - cell.setBottom(newBottom ); - } - if (onlyFirstPage) { - break; - } - } - } - - float tableHeight = table.top() - table.bottom(); - // bugfix by Adauto Martins when have more than two tables and more than one page - // If continuation of table in other page (bug report #1460051) - if (isContinue) { - currentHeight = tableHeight; - text.moveText(0, -(tableHeight - (ctx.oldHeight * 2))); - } else { - currentHeight = ctx.oldHeight + tableHeight; - text.moveText(0, -tableHeight); - } - // end bugfix - pageEmpty = false; - - if (ctx.countPageBreaks > 0) { - // in case of tables covering more that one page have to have - // a newPage followed to reset some internal state. Otherwise - // subsequent tables are rendered incorrectly. - isNewPagePending = true; - } - } - - private boolean mayBeRemoved(ArrayList row) { - Iterator iterator = row.iterator(); - boolean mayBeRemoved = true; - while (iterator.hasNext()) { - PdfCell cell = (PdfCell) iterator.next(); - - mayBeRemoved &= cell.mayBeRemoved(); - } - return mayBeRemoved; - } - - private void consumeRowspan(ArrayList row, RenderingContext ctx) { - Iterator iterator = row.iterator(); - while (iterator.hasNext()) { - PdfCell c = (PdfCell) iterator.next(); - ctx.consumeRowspan(c); - } - } - - private ArrayList extractRows(ArrayList cells, RenderingContext ctx) { - PdfCell cell; - PdfCell previousCell = null; - ArrayList rows = new ArrayList(); - java.util.List rowCells = new ArrayList(); - - Iterator iterator = cells.iterator(); - while (iterator.hasNext()) { - cell = (PdfCell) iterator.next(); - - boolean isAdded = false; - - boolean isEndOfRow = !iterator.hasNext(); - boolean isCurrentCellPartOfRow = !iterator.hasNext(); - - if (previousCell != null) { - if (cell.left() <= previousCell.left()) { - isEndOfRow = true; - isCurrentCellPartOfRow = false; - } - } - - if (isCurrentCellPartOfRow) { - rowCells.add(cell); - isAdded = true; - } - - if (isEndOfRow) { - if (!rowCells.isEmpty()) { - // add to rowlist - rows.add(rowCells); - } - - // start a new list for next line - rowCells = new ArrayList(); - } - - if (!isAdded) { - rowCells.add(cell); - } - - previousCell = cell; - } - - if (!rowCells.isEmpty()) { - rows.add(rowCells); - } - - // fill row information with rowspan cells to get complete "scan lines" - for (int i = rows.size() - 1; i >= 0; i--) { - ArrayList row = (ArrayList) rows.get(i); - // iterator through row - for (int j = 0; j < row.size(); j++) { - PdfCell c = (PdfCell) row.get(j); - int rowspan = c.rowspan(); - // fill in missing rowspan cells to complete "scan line" - for (int k = 1; k < rowspan; k++) { - ArrayList spannedRow = ((ArrayList) rows.get(i + k)); - if (spannedRow.size() > j) - spannedRow.add(j, c); - } - } - } - - return rows; - } - - private void renderCells(RenderingContext ctx, java.util.List cells, boolean hasToFit) throws DocumentException { - PdfCell cell; - Iterator iterator; - if (hasToFit) { - iterator = cells.iterator(); - while (iterator.hasNext()) { - cell = (PdfCell) iterator.next(); - if (!cell.isHeader()) { - if (cell.bottom() < indentBottom()) return; - } - } - } - iterator = cells.iterator(); - - while (iterator.hasNext()) { - cell = (PdfCell) iterator.next(); - if (!ctx.isCellRenderedOnPage(cell, getPageNumber())) { - - float correction = 0; - if (ctx.numCellRendered(cell) >= 1) { - correction = 1.0f; - } - - lines = cell.getLines(ctx.pagetop, indentBottom() - correction); - - // if there is still text to render we render it - if (lines != null && lines.size() > 0) { - - // we write the text - float cellTop = cell.top(ctx.pagetop - ctx.oldHeight); - text.moveText(0, cellTop); - float cellDisplacement = flushLines() - cellTop; - - text.moveText(0, cellDisplacement); - if (ctx.oldHeight + cellDisplacement > currentHeight) { - currentHeight = ctx.oldHeight + cellDisplacement; - } - - ctx.cellRendered(cell, getPageNumber()); - } - float indentBottom = Math.max(cell.bottom(), indentBottom()); - Rectangle tableRect = ctx.table.rectangle(ctx.pagetop, indentBottom()); - indentBottom = Math.max(tableRect.bottom(), indentBottom); - - // we paint the borders of the cells - Rectangle cellRect = cell.rectangle(tableRect.top(), indentBottom); - //cellRect.setBottom(cellRect.bottom()); - if (cellRect.height() > 0) { - ctx.lostTableBottom = indentBottom; - ctx.cellGraphics.rectangle(cellRect); - } - - // and additional graphics - ArrayList images = cell.getImages(ctx.pagetop, indentBottom()); - for (Iterator i = images.iterator(); i.hasNext();) { - Image image = (Image) i.next(); - graphics.addImage(image); - } - - } - } - - } - - - /** - * Signals that an Element was added to the Document. - * - * @param element the element to add - * @return true if the element was added, false if not. - * @throws DocumentException when a document isn't open yet, or has been closed - */ - - public boolean add(Element element) throws DocumentException { - if (writer != null && writer.isPaused()) { - return false; - } - try { -// resolves problem described in add(PdfTable) - if (isNewPagePending) { - isNewPagePending = false; - newPage(); - } - switch(element.type()) { - - // Information (headers) - case Element.HEADER: - info.addkey(((Meta)element).name(), ((Meta)element).content()); - break; - case Element.TITLE: - info.addTitle(((Meta)element).content()); - break; - case Element.SUBJECT: - info.addSubject(((Meta)element).content()); - break; - case Element.KEYWORDS: - info.addKeywords(((Meta)element).content()); - break; - case Element.AUTHOR: - info.addAuthor(((Meta)element).content()); - break; - case Element.CREATOR: - info.addCreator(((Meta)element).content()); - break; - case Element.PRODUCER: - // you can not change the name of the producer - info.addProducer(); - break; - case Element.CREATIONDATE: - // you can not set the creation date, only reset it - info.addCreationDate(); - break; - - // content (text) - case Element.CHUNK: { - // if there isn't a current line available, we make one - if (line == null) { - carriageReturn(); - } - - // we cast the element to a chunk - PdfChunk chunk = new PdfChunk((Chunk) element, currentAction); - // we try to add the chunk to the line, until we succeed - { - PdfChunk overflow; - while ((overflow = line.add(chunk)) != null) { - carriageReturn(); - chunk = overflow; - } - } - pageEmpty = false; - if (chunk.isAttribute(Chunk.NEWPAGE)) { - newPage(); - } - break; - } - case Element.ANCHOR: { - Anchor anchor = (Anchor) element; - String url = anchor.reference(); - leading = anchor.leading(); - if (url != null) { - currentAction = new PdfAction(url); - } - - // we process the element - element.process(this); - currentAction = null; - break; - } - case Element.ANNOTATION: { - if (line == null) { - carriageReturn(); - } - Annotation annot = (Annotation) element; - PdfAnnotation an = convertAnnotation(writer, annot); - annotations.add(an); - pageEmpty = false; - break; - } - case Element.PHRASE: { - // we cast the element to a phrase and set the leading of the document - leading = ((Phrase) element).leading(); - // we process the element - element.process(this); - break; - } - case Element.PARAGRAPH: { - // we cast the element to a paragraph - Paragraph paragraph = (Paragraph) element; - - float spacingBefore = paragraph.spacingBefore(); - if (spacingBefore != 0) { - leading = spacingBefore; - carriageReturn(); - if (!pageEmpty) { - /* - * Don't add spacing before a paragraph if it's the first - * on the page - */ - Chunk space = new Chunk(" "); - space.process(this); - carriageReturn(); - } - } - - // we adjust the parameters of the document - alignment = paragraph.alignment(); - leading = paragraph.leading(); - - carriageReturn(); - // we don't want to make orphans/widows - if (currentHeight + line.height() + leading > indentTop() - indentBottom()) { - newPage(); - } - - // Begin added: Bonf (Marc Schneider) 2003-07-29 - //carriageReturn(); - // End added: Bonf (Marc Schneider) 2003-07-29 - - indentLeft += paragraph.indentationLeft(); - indentRight += paragraph.indentationRight(); - - // Begin removed: Bonf (Marc Schneider) 2003-07-29 - carriageReturn(); - // End removed: Bonf (Marc Schneider) 2003-07-29 - - - //add by Jin-Hsia Yang - - paraIndent += paragraph.indentationLeft(); - //end add by Jin-Hsia Yang - - PdfPageEvent pageEvent = writer.getPageEvent(); - if (pageEvent != null && isParagraph) - pageEvent.onParagraph(writer, this, indentTop() - currentHeight); - - // if a paragraph has to be kept together, we wrap it in a table object - if (paragraph.getKeepTogether()) { - Table table = new Table(1, 1); - table.setOffset(0f); - table.setBorder(Table.NO_BORDER); - table.setWidth(100f); - table.setTableFitsPage(true); - Cell cell = new Cell(paragraph); - cell.setBorder(Table.NO_BORDER); - //patch by Matt Benson 11/01/2002 - 14:32:00 - cell.setHorizontalAlignment(paragraph.alignment()); - //end patch by Matt Benson - table.addCell(cell); - this.add(table); - break; - } - else - // we process the paragraph - element.process(this); - - //add by Jin-Hsia Yang and blowagie - paraIndent -= paragraph.indentationLeft(); - //end add by Jin-Hsia Yang and blowagie - - // Begin removed: Bonf (Marc Schneider) 2003-07-29 - // carriageReturn(); - // End removed: Bonf (Marc Schneider) 2003-07-29 - - float spacingAfter = paragraph.spacingAfter(); - if (spacingAfter != 0) { - leading = spacingAfter; - carriageReturn(); - if (currentHeight + line.height() + leading < indentTop() - indentBottom()) { - /* - * Only add spacing after a paragraph if the extra - * spacing fits on the page. - */ - Chunk space = new Chunk(" "); - space.process(this); - carriageReturn(); - } - leading = paragraph.leading(); // restore original leading - } - - if (pageEvent != null && isParagraph) - pageEvent.onParagraphEnd(writer, this, indentTop() - currentHeight); - - alignment = Element.ALIGN_LEFT; - indentLeft -= paragraph.indentationLeft(); - indentRight -= paragraph.indentationRight(); - - // Begin added: Bonf (Marc Schneider) 2003-07-29 - carriageReturn(); - // End added: Bonf (Marc Schneider) 2003-07-29 - - //add by Jin-Hsia Yang - - //end add by Jin-Hsia Yang - - break; - } - case Element.SECTION: - case Element.CHAPTER: { - // Chapters and Sections only differ in their constructor - // so we cast both to a Section - Section section = (Section) element; - - boolean hasTitle = section.title() != null; - - // if the section is a chapter, we begin a new page - if (section.isChapter()) { - newPage(); - } - // otherwise, we begin a new line - else { - newLine(); - } - - if (hasTitle) { - float fith = indentTop() - currentHeight; - int rotation = pageSize.getRotation(); - if (rotation == 90 || rotation == 180) - fith = pageSize.height() - fith; - PdfDestination destination = new PdfDestination(PdfDestination.FITH, fith); - while (currentOutline.level() >= section.depth()) { - currentOutline = currentOutline.parent(); - } - PdfOutline outline = new PdfOutline(currentOutline, destination, section.getBookmarkTitle(), section.isBookmarkOpen()); - currentOutline = outline; - } - - // some values are set - carriageReturn(); - indentLeft += section.indentationLeft(); - indentRight += section.indentationRight(); - - PdfPageEvent pageEvent = writer.getPageEvent(); - if (pageEvent != null) - if (element.type() == Element.CHAPTER) - pageEvent.onChapter(writer, this, indentTop() - currentHeight, section.title()); - else - pageEvent.onSection(writer, this, indentTop() - currentHeight, section.depth(), section.title()); - - // the title of the section (if any has to be printed) - if (hasTitle) { - isParagraph = false; - add(section.title()); - isParagraph = true; - } - indentLeft += section.indentation(); - // we process the section - element.process(this); - // some parameters are set back to normal again - indentLeft -= section.indentationLeft() + section.indentation(); - indentRight -= section.indentationRight(); - - if (pageEvent != null) - if (element.type() == Element.CHAPTER) - pageEvent.onChapterEnd(writer, this, indentTop() - currentHeight); - else - pageEvent.onSectionEnd(writer, this, indentTop() - currentHeight); - - break; - } - case Element.LIST: { - // we cast the element to a List - List list = (List) element; - // we adjust the document - listIndentLeft += list.indentationLeft(); - indentRight += list.indentationRight(); - // we process the items in the list - element.process(this); - // some parameters are set back to normal again - listIndentLeft -= list.indentationLeft(); - indentRight -= list.indentationRight(); - break; - } - case Element.LISTITEM: { - // we cast the element to a ListItem - ListItem listItem = (ListItem) element; - - float spacingBefore = listItem.spacingBefore(); - if (spacingBefore != 0) { - leading = spacingBefore; - carriageReturn(); - if (!pageEmpty) { - /* - * Don't add spacing before a paragraph if it's the first - * on the page - */ - Chunk space = new Chunk(" "); - space.process(this); - carriageReturn(); - } - } - - // we adjust the document - alignment = listItem.alignment(); - listIndentLeft += listItem.indentationLeft(); - indentRight += listItem.indentationRight(); - leading = listItem.leading(); - carriageReturn(); - // we prepare the current line to be able to show us the listsymbol - line.setListItem(listItem); - // we process the item - element.process(this); - - float spacingAfter = listItem.spacingAfter(); - if (spacingAfter != 0) { - leading = spacingAfter; - carriageReturn(); - if (currentHeight + line.height() + leading < indentTop() - indentBottom()) { - /* - * Only add spacing after a paragraph if the extra - * spacing fits on the page. - */ - Chunk space = new Chunk(" "); - space.process(this); - carriageReturn(); - } - leading = listItem.leading(); // restore original leading - } - - // if the last line is justified, it should be aligned to the left - // if (line.hasToBeJustified()) { - // line.resetAlignment(); - // } - // some parameters are set back to normal again - carriageReturn(); - listIndentLeft -= listItem.indentationLeft(); - indentRight -= listItem.indentationRight(); - break; - } - case Element.RECTANGLE: { - Rectangle rectangle = (Rectangle) element; - graphics.rectangle(rectangle); - pageEmpty = false; - break; - } - case Element.PTABLE: { - PdfPTable ptable = (PdfPTable)element; - if (ptable.size() <= ptable.getHeaderRows()) - break; //nothing to do - - // before every table, we add a new line and flush all lines - ensureNewLine(); - flushLines(); - addPTable(ptable); - pageEmpty = false; - break; - } - case Element.MULTI_COLUMN_TEXT: { - ensureNewLine(); - flushLines(); - MultiColumnText multiText = (MultiColumnText) element; - float height = multiText.write(writer.getDirectContent(), this, indentTop() - currentHeight); - currentHeight += height; - text.moveText(0, -1f* height); - pageEmpty = false; - break; - } - case Element.TABLE : { - - /** - * This is a list of people who worked on the Table functionality. - * To see who did what, please check the CVS repository: - * - * Leslie Baski - * Matt Benson - * Francesco De Milato - * David Freels - * Bruno Lowagie - * Veerendra Namineni - * Geert Poels - * Tom Ring - * Paulo Soares - * Gerald Fehringer - * Steve Appling - * Karsten Klein - */ - - PdfTable table; - if (element instanceof PdfTable) { - // Already pre-rendered - table = (PdfTable)element; - table.updateRowAdditions(); - } else if (element instanceof SimpleTable) { - PdfPTable ptable = ((SimpleTable)element).createPdfPTable(); - if (ptable.size() <= ptable.getHeaderRows()) - break; //nothing to do - - // before every table, we add a new line and flush all lines - ensureNewLine(); - flushLines(); - addPTable(ptable); - pageEmpty = false; - break; - } else if (element instanceof Table) { - try { - PdfPTable ptable = ((Table)element).createPdfPTable(); - if (ptable.size() <= ptable.getHeaderRows()) - break; //nothing to do - - // before every table, we add a new line and flush all lines - ensureNewLine(); - flushLines(); - addPTable(ptable); - pageEmpty = false; - break; - } - catch(BadElementException bee) { - // constructing the PdfTable - // Before the table, add a blank line using offset or default leading - float offset = ((Table)element).getOffset(); - if (Float.isNaN(offset)) - offset = leading; - carriageReturn(); - lines.add(new PdfLine(indentLeft(), indentRight(), alignment, offset)); - currentHeight += offset; - table = getPdfTable((Table)element, false); - } - } else { - return false; - } - add(table, false); - break; - } - case Element.JPEG: - case Element.IMGRAW: - case Element.IMGTEMPLATE: { - //carriageReturn(); suggestion by Marc Campforts - add((Image) element); - break; - } - case Element.GRAPHIC: { - Graphic graphic = (Graphic) element; - graphic.processAttributes(indentLeft(), indentBottom(), indentRight(), indentTop(), indentTop() - currentHeight); - graphics.add(graphic); - pageEmpty = false; - break; - } - default: - return false; - } - lastElementType = element.type(); - return true; - } - catch(Exception e) { - throw new DocumentException(e); - } - } - - // methods to add Content - - /** - * Adds an image to the document. - * @param image the Image to add - * @throws PdfException on error - * @throws DocumentException on error - */ - - private void add(Image image) throws PdfException, DocumentException { - - if (image.hasAbsolutePosition()) { - graphics.addImage(image); - pageEmpty = false; - return; - } - - // if there isn't enough room for the image on this page, save it for the next page - if (currentHeight != 0 && indentTop() - currentHeight - image.scaledHeight() < indentBottom()) { - if (!strictImageSequence && imageWait == null) { - imageWait = image; - return; - } - newPage(); - if (currentHeight != 0 && indentTop() - currentHeight - image.scaledHeight() < indentBottom()) { - imageWait = image; - return; - } - } - pageEmpty = false; - // avoid endless loops - if (image == imageWait) - imageWait = null; - boolean textwrap = (image.alignment() & Image.TEXTWRAP) == Image.TEXTWRAP - && !((image.alignment() & Image.MIDDLE) == Image.MIDDLE); - boolean underlying = (image.alignment() & Image.UNDERLYING) == Image.UNDERLYING; - float diff = leading / 2; - if (textwrap) { - diff += leading; - } - float lowerleft = indentTop() - currentHeight - image.scaledHeight() -diff; - float mt[] = image.matrix(); - float startPosition = indentLeft() - mt[4]; - if ((image.alignment() & Image.RIGHT) == Image.RIGHT) startPosition = indentRight() - image.scaledWidth() - mt[4]; - if ((image.alignment() & Image.MIDDLE) == Image.MIDDLE) startPosition = indentLeft() + ((indentRight() - indentLeft() - image.scaledWidth()) / 2) - mt[4]; - if (image.hasAbsoluteX()) startPosition = image.absoluteX(); - if (textwrap) { - if (imageEnd < 0 || imageEnd < currentHeight + image.scaledHeight() + diff) { - imageEnd = currentHeight + image.scaledHeight() + diff; - } - if ((image.alignment() & Image.RIGHT) == Image.RIGHT) { - // indentation suggested by Pelikan Stephan - imageIndentRight += image.scaledWidth() + image.indentationLeft(); - } - else { - // indentation suggested by Pelikan Stephan - imageIndentLeft += image.scaledWidth() + image.indentationRight(); - } - } - else { - if ((image.alignment() & Image.RIGHT) == Image.RIGHT) startPosition -= image.indentationRight(); - else if ((image.alignment() & Image.LEFT) == Image.LEFT) startPosition += image.indentationLeft(); - else if ((image.alignment() & Image.MIDDLE) == Image.MIDDLE) startPosition += image.indentationLeft() - image.indentationRight(); - } - graphics.addImage(image, mt[0], mt[1], mt[2], mt[3], startPosition, lowerleft - mt[5]); - if (!(textwrap || underlying)) { - currentHeight += image.scaledHeight() + diff; - flushLines(); - text.moveText(0, - (image.scaledHeight() + diff)); - newLine(); - } - } - - /** - * Initializes a page. - *

- * If the footer/header is set, it is printed. - * @throws DocumentException on error - */ - - private void initPage() throws DocumentException { - - // initialisation of some page objects - markPoint = 0; - annotations = delayedAnnotations; - delayedAnnotations = new ArrayList(); - pageResources = new PageResources(); - writer.resetContent(); - - // the pagenumber is incremented - pageN++; - - // graphics and text are initialized - float oldleading = leading; - int oldAlignment = alignment; - - if (marginMirroring && (getPageNumber() & 1) == 0) { - marginRight = nextMarginLeft; - marginLeft = nextMarginRight; - } - else { - marginLeft = nextMarginLeft; - marginRight = nextMarginRight; - } - marginTop = nextMarginTop; - marginBottom = nextMarginBottom; - imageEnd = -1; - imageIndentRight = 0; - imageIndentLeft = 0; - graphics = new PdfContentByte(writer); - text = new PdfContentByte(writer); - text.beginText(); - text.moveText(left(), top()); - textEmptySize = text.size(); - text.reset(); - text.beginText(); - leading = 16; - indentBottom = 0; - indentTop = 0; - currentHeight = 0; - - // backgroundcolors, etc... - pageSize = nextPageSize; - thisBoxSize = new HashMap(boxSize); - if (pageSize.backgroundColor() != null - || pageSize.hasBorders() - || pageSize.borderColor() != null) { - add(pageSize); - } - - // if there is a watermark, the watermark is added - if (watermark != null) { - float mt[] = watermark.matrix(); - graphics.addImage(watermark, mt[0], mt[1], mt[2], mt[3], watermark.offsetX() - mt[4], watermark.offsetY() - mt[5]); - } - - // if there is a footer, the footer is added - if (footer != null) { - /* - Added by Edgar Leonardo Prieto Perilla - */ - // Avoid footer identation - float tmpIndentLeft = indentLeft; - float tmpIndentRight = indentRight; - // Begin added: Bonf (Marc Schneider) 2003-07-29 - float tmpListIndentLeft = listIndentLeft; - float tmpImageIndentLeft = imageIndentLeft; - float tmpImageIndentRight = imageIndentRight; - // End added: Bonf (Marc Schneider) 2003-07-29 - - indentLeft = indentRight = 0; - // Begin added: Bonf (Marc Schneider) 2003-07-29 - listIndentLeft = 0; - imageIndentLeft = 0; - imageIndentRight = 0; - // End added: Bonf (Marc Schneider) 2003-07-29 - /* - End Added by Edgar Leonardo Prieto Perilla - */ - - footer.setPageNumber(pageN); - leading = footer.paragraph().leading(); - add(footer.paragraph()); - // adding the footer limits the height - indentBottom = currentHeight; - text.moveText(left(), indentBottom()); - flushLines(); - text.moveText(-left(), -bottom()); - footer.setTop(bottom(currentHeight)); - footer.setBottom(bottom() - (0.75f * leading)); - footer.setLeft(left()); - footer.setRight(right()); - graphics.rectangle(footer); - indentBottom = currentHeight + leading * 2; - currentHeight = 0; - - /* - Added by Edgar Leonardo Prieto Perilla - */ - indentLeft = tmpIndentLeft; - indentRight = tmpIndentRight; - // Begin added: Bonf (Marc Schneider) 2003-07-29 - listIndentLeft = tmpListIndentLeft; - imageIndentLeft = tmpImageIndentLeft; - imageIndentRight = tmpImageIndentRight; - // End added: Bonf (Marc Schneider) 2003-07-29 - /* - End Added by Edgar Leonardo Prieto Perilla - */ - } - - // we move to the left/top position of the page - text.moveText(left(), top()); - - // if there is a header, the header = added - if (header != null) { - /* - Added by Edgar Leonardo Prieto Perilla - */ - // Avoid header identation - float tmpIndentLeft = indentLeft; - float tmpIndentRight = indentRight; - // Begin added: Bonf (Marc Schneider) 2003-07-29 - float tmpListIndentLeft = listIndentLeft; - float tmpImageIndentLeft = imageIndentLeft; - float tmpImageIndentRight = imageIndentRight; - // End added: Bonf (Marc Schneider) 2003-07-29 - - indentLeft = indentRight = 0; - // Added: Bonf - listIndentLeft = 0; - imageIndentLeft = 0; - imageIndentRight = 0; - // End added: Bonf - /* - End Added by Edgar Leonardo Prieto Perilla - */ - - header.setPageNumber(pageN); - leading = header.paragraph().leading(); - text.moveText(0, leading); - add(header.paragraph()); - newLine(); - indentTop = currentHeight - leading; - header.setTop(top() + leading); - header.setBottom(indentTop() + leading * 2 / 3); - header.setLeft(left()); - header.setRight(right()); - graphics.rectangle(header); - flushLines(); - currentHeight = 0; - - /* - Added by Edgar Leonardo Prieto Perilla - */ - // Restore identation - indentLeft = tmpIndentLeft; - indentRight = tmpIndentRight; - // Begin added: Bonf (Marc Schneider) 2003-07-29 - listIndentLeft = tmpListIndentLeft; - imageIndentLeft = tmpImageIndentLeft; - imageIndentRight = tmpImageIndentRight; - // End added: Bonf (Marc Schneider) 2003-07-29 - /* - End Added by Edgar Leonardo Prieto Perilla - */ - } - - pageEmpty = true; - - // if there is an image waiting to be drawn, draw it - try { - if (imageWait != null) { - add(imageWait); - imageWait = null; - } - } - catch(Exception e) { - throw new ExceptionConverter(e); - } - - leading = oldleading; - alignment = oldAlignment; - carriageReturn(); - PdfPageEvent pageEvent = writer.getPageEvent(); - if (pageEvent != null) { - if (firstPageEvent) { - pageEvent.onOpenDocument(writer, this); - } - pageEvent.onStartPage(writer, this); - } - firstPageEvent = false; - } - - /** - * If the current line is not empty or null, it is added to the arraylist - * of lines and a new empty line is added. - * @throws DocumentException on error - */ - - private void carriageReturn() throws DocumentException { - // the arraylist with lines may not be null - if (lines == null) { - lines = new ArrayList(); - } - // If the current line is not null - if (line != null) { - // we check if the end of the page is reached (bugfix by Francois Gravel) - if (currentHeight + line.height() + leading < indentTop() - indentBottom()) { - // if so nonempty lines are added and the heigt is augmented - if (line.size() > 0) { - currentHeight += line.height(); - lines.add(line); - pageEmpty = false; - } - } - // if the end of the line is reached, we start a new page - else { - newPage(); - } - } - if (imageEnd > -1 && currentHeight > imageEnd) { - imageEnd = -1; - imageIndentRight = 0; - imageIndentLeft = 0; - } - // a new current line is constructed - line = new PdfLine(indentLeft(), indentRight(), alignment, leading); - } - - /** - * Adds the current line to the list of lines and also adds an empty line. - * @throws DocumentException on error - */ - - private void newLine() throws DocumentException { - lastElementType = -1; - carriageReturn(); - if (lines != null && lines.size() > 0) { - lines.add(line); - currentHeight += line.height(); - } - line = new PdfLine(indentLeft(), indentRight(), alignment, leading); - } - - /** - * Writes all the lines to the text-object. - * - * @return the displacement that was caused - * @throws DocumentException on error - */ - - private float flushLines() throws DocumentException { - - // checks if the ArrayList with the lines is not null - if (lines == null) { - return 0; - } - - //add by Jin-Hsia Yang - boolean newline=false; - //end add by Jin-Hsia Yang - - // checks if a new Line has to be made. - if (line != null && line.size() > 0) { - lines.add(line); - line = new PdfLine(indentLeft(), indentRight(), alignment, leading); - - //add by Jin-Hsia Yang - newline=true; - //end add by Jin-Hsia Yang - - } - - // checks if the ArrayList with the lines is empty - if (lines.size() == 0) { - return 0; - } - - // initialisation of some parameters - Object currentValues[] = new Object[2]; - PdfFont currentFont = null; - float displacement = 0; - PdfLine l; - Float lastBaseFactor = new Float(0); - currentValues[1] = lastBaseFactor; - // looping over all the lines - for (Iterator i = lines.iterator(); i.hasNext(); ) { - - // this is a line in the loop - l = (PdfLine) i.next(); - - if(isNewpage && newline) { // fix Ken@PDI - newline=false; - text.moveText(l.indentLeft() - indentLeft() + listIndentLeft + paraIndent,-l.height()); - } - else { - text.moveText(l.indentLeft() - indentLeft() + listIndentLeft, -l.height()); - } - - // is the line preceeded by a symbol? - if (l.listSymbol() != null) { - ColumnText.showTextAligned(graphics, Element.ALIGN_LEFT, new Phrase(l.listSymbol()), text.getXTLM() - l.listIndent(), text.getYTLM(), 0); - } - - currentValues[0] = currentFont; - - writeLineToContent(l, text, graphics, currentValues, writer.getSpaceCharRatio()); - - currentFont = (PdfFont)currentValues[0]; - - displacement += l.height(); - if (indentLeft() - listIndentLeft != l.indentLeft()) { - text.moveText(indentLeft() - l.indentLeft() - listIndentLeft, 0); - } - - } - lines = new ArrayList(); - return displacement; - } - - // methods to retrieve information - - /** - * Gets the PdfInfo-object. - * - * @return PdfInfo - */ - - PdfInfo getInfo() { - return info; - } - - /** - * Gets the PdfCatalog-object. - * - * @param pages an indirect reference to this document pages - * @return PdfCatalog - */ - - PdfCatalog getCatalog(PdfIndirectReference pages) { - PdfCatalog catalog; - if (rootOutline.getKids().size() > 0) { - catalog = new PdfCatalog(pages, rootOutline.indirectReference(), writer); - } - else - catalog = new PdfCatalog(pages, writer); - if (openActionName != null) { - PdfAction action = getLocalGotoAction(openActionName); - catalog.setOpenAction(action); - } - else if (openActionAction != null) - catalog.setOpenAction(openActionAction); - - if (additionalActions != null) { - catalog.setAdditionalActions(additionalActions); - } - - if (pageLabels != null) - catalog.setPageLabels(pageLabels); - catalog.addNames(localDestinations, documentJavaScript, documentFileAttachment, writer); - catalog.setViewerPreferences(viewerPreferences); - if (acroForm.isValid()) { - try { - catalog.setAcroForm(writer.addToBody(acroForm).getIndirectReference()); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - return catalog; - } - - // methods concerning the layout - - /** - * Returns the bottomvalue of a Table if it were added to this document. - * - * @param table the table that may or may not be added to this document - * @return a bottom value - */ - - float bottom(Table table) { -// where will the table begin? - float h = (currentHeight > 0) ? indentTop() - currentHeight - 2f * leading : indentTop(); - // constructing a PdfTable - PdfTable tmp = getPdfTable(table, false); - return tmp.bottom(); - } - - /** - * Checks if a PdfPTable fits the current page of the PdfDocument. - * - * @param table the table that has to be checked - * @param margin a certain margin - * @return true if the PdfPTable fits the page, false otherwise. - */ - - boolean fitsPage(PdfPTable table, float margin) { - if (!table.isLockedWidth()) { - float totalWidth = (indentRight() - indentLeft()) * table.getWidthPercentage() / 100; - table.setTotalWidth(totalWidth); - } - // ensuring that a new line has been started. - ensureNewLine(); - return table.getTotalHeight() <= indentTop() - currentHeight - indentBottom() - margin; - } - - - /** - * Gets the current vertical page position. - * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects - * for elements that do not terminate the lines they've started because those lines will get - * terminated. - * @return The current vertical page position. - */ - public float getVerticalPosition(boolean ensureNewLine) { - // ensuring that a new line has been started. - if (ensureNewLine) { - ensureNewLine(); - } - return top() - currentHeight - indentTop; - } - - /** - * Ensures that a new line has been started. - */ - private void ensureNewLine() { - try { - if ((lastElementType == Element.PHRASE) || - (lastElementType == Element.CHUNK)) { - newLine(); - flushLines(); - } - } catch (DocumentException ex) { - throw new ExceptionConverter(ex); - } - } - - /** - * Gets the indentation on the left side. - * - * @return a margin - */ - - private float indentLeft() { - return left(indentLeft + listIndentLeft + imageIndentLeft); - } - - /** - * Gets the indentation on the right side. - * - * @return a margin - */ - - private float indentRight() { - return right(indentRight + imageIndentRight); - } - - /** - * Gets the indentation on the top side. - * - * @return a margin - */ - - private float indentTop() { - return top(indentTop); - } - - /** - * Gets the indentation on the bottom side. - * - * @return a margin - */ - - float indentBottom() { - return bottom(indentBottom); - } - - /** - * Adds a named outline to the document . - * @param outline the outline to be added - * @param name the name of this local destination - */ - void addOutline(PdfOutline outline, String name) { - localDestination(name, outline.getPdfDestination()); - } - - /** - * Gets the AcroForm object. - * @return the PdfAcroform object of the PdfDocument - */ - - public PdfAcroForm getAcroForm() { - return acroForm; - } - - /** - * Gets the root outline. All the outlines must be created with a parent. - * The first level is created with this outline. - * @return the root outline - */ - public PdfOutline getRootOutline() { - return rootOutline; - } - - /** - * Writes a text line to the document. It takes care of all the attributes. - *

- * Before entering the line position must have been established and the - * text argument must be in text object scope (beginText()). - * @param line the line to be written - * @param text the PdfContentByte where the text will be written to - * @param graphics the PdfContentByte where the graphics will be written to - * @param currentValues the current font and extra spacing values - * @param ratio - * @throws DocumentException on error - */ - void writeLineToContent(PdfLine line, PdfContentByte text, PdfContentByte graphics, Object currentValues[], float ratio) throws DocumentException { - PdfFont currentFont = (PdfFont)(currentValues[0]); - float lastBaseFactor = ((Float)(currentValues[1])).floatValue(); - PdfChunk chunk; - int numberOfSpaces; - int lineLen; - boolean isJustified; - float hangingCorrection = 0; - float hScale = 1; - float lastHScale = Float.NaN; - float baseWordSpacing = 0; - float baseCharacterSpacing = 0; - - numberOfSpaces = line.numberOfSpaces(); - lineLen = line.toString().length(); - // does the line need to be justified? - isJustified = line.hasToBeJustified() && (numberOfSpaces != 0 || lineLen > 1); - if (isJustified) { - if (line.isNewlineSplit() && line.widthLeft() >= (lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1))) { - if (line.isRTL()) { - text.moveText(line.widthLeft() - lastBaseFactor * (ratio * numberOfSpaces + lineLen - 1), 0); - } - baseWordSpacing = ratio * lastBaseFactor; - baseCharacterSpacing = lastBaseFactor; - } - else { - float width = line.widthLeft(); - PdfChunk last = line.getChunk(line.size() - 1); - if (last != null) { - String s = last.toString(); - char c; - if (s.length() > 0 && hangingPunctuation.indexOf((c = s.charAt(s.length() - 1))) >= 0) { - float oldWidth = width; - width += last.font().width(c) * 0.4f; - hangingCorrection = width - oldWidth; - } - } - float baseFactor = width / (ratio * numberOfSpaces + lineLen - 1); - baseWordSpacing = ratio * baseFactor; - baseCharacterSpacing = baseFactor; - lastBaseFactor = baseFactor; - } - } - - int lastChunkStroke = line.getLastStrokeChunk(); - int chunkStrokeIdx = 0; - float xMarker = text.getXTLM(); - float baseXMarker = xMarker; - float yMarker = text.getYTLM(); - boolean adjustMatrix = false; - - // looping over all the chunks in 1 line - for (Iterator j = line.iterator(); j.hasNext(); ) { - chunk = (PdfChunk) j.next(); - Color color = chunk.color(); - hScale = 1; - - if (chunkStrokeIdx <= lastChunkStroke) { - float width; - if (isJustified) { - width = chunk.getWidthCorrected(baseCharacterSpacing, baseWordSpacing); - } - else - width = chunk.width(); - if (chunk.isStroked()) { - PdfChunk nextChunk = line.getChunk(chunkStrokeIdx + 1); - if (chunk.isAttribute(Chunk.BACKGROUND)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.BACKGROUND)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - float fontSize = chunk.font().size(); - float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); - float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); - Object bgr[] = (Object[])chunk.getAttribute(Chunk.BACKGROUND); - graphics.setColorFill((Color)bgr[0]); - float extra[] = (float[])bgr[1]; - graphics.rectangle(xMarker - extra[0], - yMarker + descender - extra[1] + chunk.getTextRise(), - width - subtract + extra[0] + extra[2], - ascender - descender + extra[1] + extra[3]); - graphics.fill(); - graphics.setGrayFill(0); - } - if (chunk.isAttribute(Chunk.UNDERLINE)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.UNDERLINE)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - Object unders[][] = (Object[][])chunk.getAttribute(Chunk.UNDERLINE); - Color scolor = null; - for (int k = 0; k < unders.length; ++k) { - Object obj[] = unders[k]; - scolor = (Color)obj[0]; - float ps[] = (float[])obj[1]; - if (scolor == null) - scolor = color; - if (scolor != null) - graphics.setColorStroke(scolor); - float fsize = chunk.font().size(); - graphics.setLineWidth(ps[0] + fsize * ps[1]); - float shift = ps[2] + fsize * ps[3]; - int cap2 = (int)ps[4]; - if (cap2 != 0) - graphics.setLineCap(cap2); - graphics.moveTo(xMarker, yMarker + shift); - graphics.lineTo(xMarker + width - subtract, yMarker + shift); - graphics.stroke(); - if (scolor != null) - graphics.resetGrayStroke(); - if (cap2 != 0) - graphics.setLineCap(0); - } - graphics.setLineWidth(1); - } - if (chunk.isAttribute(Chunk.ACTION)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.ACTION)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - text.addAnnotation(new PdfAnnotation(writer, xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size(), (PdfAction)chunk.getAttribute(Chunk.ACTION))); - } - if (chunk.isAttribute(Chunk.REMOTEGOTO)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.REMOTEGOTO)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - Object obj[] = (Object[])chunk.getAttribute(Chunk.REMOTEGOTO); - String filename = (String)obj[0]; - if (obj[1] instanceof String) - remoteGoto(filename, (String)obj[1], xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); - else - remoteGoto(filename, ((Integer)obj[1]).intValue(), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); - } - if (chunk.isAttribute(Chunk.LOCALGOTO)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALGOTO)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - localGoto((String)chunk.getAttribute(Chunk.LOCALGOTO), xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); - } - if (chunk.isAttribute(Chunk.LOCALDESTINATION)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALDESTINATION)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - localDestination((String)chunk.getAttribute(Chunk.LOCALDESTINATION), new PdfDestination(PdfDestination.XYZ, xMarker, yMarker + chunk.font().size(), 0)); - } - if (chunk.isAttribute(Chunk.GENERICTAG)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.GENERICTAG)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - Rectangle rect = new Rectangle(xMarker, yMarker, xMarker + width - subtract, yMarker + chunk.font().size()); - PdfPageEvent pev = writer.getPageEvent(); - if (pev != null) - pev.onGenericTag(writer, this, rect, (String)chunk.getAttribute(Chunk.GENERICTAG)); - } - if (chunk.isAttribute(Chunk.PDFANNOTATION)) { - float subtract = lastBaseFactor; - if (nextChunk != null && nextChunk.isAttribute(Chunk.PDFANNOTATION)) - subtract = 0; - if (nextChunk == null) - subtract += hangingCorrection; - float fontSize = chunk.font().size(); - float ascender = chunk.font().getFont().getFontDescriptor(BaseFont.ASCENT, fontSize); - float descender = chunk.font().getFont().getFontDescriptor(BaseFont.DESCENT, fontSize); - PdfAnnotation annot = PdfFormField.shallowDuplicate((PdfAnnotation)chunk.getAttribute(Chunk.PDFANNOTATION)); - annot.put(PdfName.RECT, new PdfRectangle(xMarker, yMarker + descender, xMarker + width - subtract, yMarker + ascender)); - text.addAnnotation(annot); - } - float params[] = (float[])chunk.getAttribute(Chunk.SKEW); - Float hs = (Float)chunk.getAttribute(Chunk.HSCALE); - if (params != null || hs != null) { - float b = 0, c = 0; - if (params != null) { - b = params[0]; - c = params[1]; - } - if (hs != null) - hScale = hs.floatValue(); - text.setTextMatrix(hScale, b, c, 1, xMarker, yMarker); - } - if (chunk.isImage()) { - Image image = chunk.getImage(); - float matrix[] = image.matrix(); - matrix[Image.CX] = xMarker + chunk.getImageOffsetX() - matrix[Image.CX]; - matrix[Image.CY] = yMarker + chunk.getImageOffsetY() - matrix[Image.CY]; - graphics.addImage(image, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); - text.moveText(xMarker + lastBaseFactor + image.scaledWidth() - text.getXTLM(), 0); - } - } - xMarker += width; - ++chunkStrokeIdx; - } - - if (chunk.font().compareTo(currentFont) != 0) { - currentFont = chunk.font(); - text.setFontAndSize(currentFont.getFont(), currentFont.size()); - } - float rise = 0; - Object textRender[] = (Object[])chunk.getAttribute(Chunk.TEXTRENDERMODE); - int tr = 0; - float strokeWidth = 1; - Color strokeColor = null; - Float fr = (Float)chunk.getAttribute(Chunk.SUBSUPSCRIPT); - if (textRender != null) { - tr = ((Integer)textRender[0]).intValue() & 3; - if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL) - text.setTextRenderingMode(tr); - if (tr == PdfContentByte.TEXT_RENDER_MODE_STROKE || tr == PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE) { - strokeWidth = ((Float)textRender[1]).floatValue(); - if (strokeWidth != 1) - text.setLineWidth(strokeWidth); - strokeColor = (Color)textRender[2]; - if (strokeColor == null) - strokeColor = color; - if (strokeColor != null) - text.setColorStroke(strokeColor); - } - } - if (fr != null) - rise = fr.floatValue(); - if (color != null) - text.setColorFill(color); - if (rise != 0) - text.setTextRise(rise); - if (chunk.isImage()) { - adjustMatrix = true; - } - // If it is a CJK chunk or Unicode TTF we will have to simulate the - // space adjustment. - else if (isJustified && numberOfSpaces > 0 && chunk.isSpecialEncoding()) { - if (hScale != lastHScale) { - lastHScale = hScale; - text.setWordSpacing(baseWordSpacing / hScale); - text.setCharacterSpacing(baseCharacterSpacing / hScale); - } - String s = chunk.toString(); - int idx = s.indexOf(' '); - if (idx < 0) - text.showText(chunk.toString()); - else { - float spaceCorrection = - baseWordSpacing * 1000f / chunk.font.size() / hScale; - PdfTextArray textArray = new PdfTextArray(s.substring(0, idx)); - int lastIdx = idx; - while ((idx = s.indexOf(' ', lastIdx + 1)) >= 0) { - textArray.add(spaceCorrection); - textArray.add(s.substring(lastIdx, idx)); - lastIdx = idx; - } - textArray.add(spaceCorrection); - textArray.add(s.substring(lastIdx)); - text.showText(textArray); - } - } - else { - if (isJustified && hScale != lastHScale) { - lastHScale = hScale; - text.setWordSpacing(baseWordSpacing / hScale); - text.setCharacterSpacing(baseCharacterSpacing / hScale); - } - text.showText(chunk.toString()); - } - - if (rise != 0) - text.setTextRise(0); - if (color != null) - text.resetRGBColorFill(); - if (tr != PdfContentByte.TEXT_RENDER_MODE_FILL) - text.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL); - if (strokeColor != null) - text.resetRGBColorStroke(); - if (strokeWidth != 1) - text.setLineWidth(1); - if (chunk.isAttribute(Chunk.SKEW) || chunk.isAttribute(Chunk.HSCALE)) { - adjustMatrix = true; - text.setTextMatrix(xMarker, yMarker); - } - } - if (isJustified) { - text.setWordSpacing(0); - text.setCharacterSpacing(0); - if (line.isNewlineSplit()) - lastBaseFactor = 0; - } - if (adjustMatrix) - text.moveText(baseXMarker - text.getXTLM(), 0); - currentValues[0] = currentFont; - currentValues[1] = new Float(lastBaseFactor); - } - - /** - * Implements a link to other part of the document. The jump will - * be made to a local destination with the same name, that must exist. - * @param name the name for this link - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - void localGoto(String name, float llx, float lly, float urx, float ury) { - PdfAction action = getLocalGotoAction(name); - annotations.add(new PdfAnnotation(writer, llx, lly, urx, ury, action)); - } - - PdfAction getLocalGotoAction(String name) { - PdfAction action; - Object obj[] = (Object[])localDestinations.get(name); - if (obj == null) - obj = new Object[3]; - if (obj[0] == null) { - if (obj[1] == null) { - obj[1] = writer.getPdfIndirectReference(); - } - action = new PdfAction((PdfIndirectReference)obj[1]); - obj[0] = action; - localDestinations.put(name, obj); - } - else { - action = (PdfAction)obj[0]; - } - return action; - } - - /** - * The local destination to where a local goto with the same - * name will jump to. - * @param name the name of this local destination - * @param destination the PdfDestination with the jump coordinates - * @return true if the local destination was added, - * false if a local destination with the same name - * already existed - */ - boolean localDestination(String name, PdfDestination destination) { - Object obj[] = (Object[])localDestinations.get(name); - if (obj == null) - obj = new Object[3]; - if (obj[2] != null) - return false; - obj[2] = destination; - localDestinations.put(name, obj); - destination.addPage(writer.getCurrentPage()); - return true; - } - - /** - * Implements a link to another document. - * @param filename the filename for the remote document - * @param name the name to jump to - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - void remoteGoto(String filename, String name, float llx, float lly, float urx, float ury) { - annotations.add(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, name))); - } - - /** - * Implements a link to another document. - * @param filename the filename for the remote document - * @param page the page to jump to - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - void remoteGoto(String filename, int page, float llx, float lly, float urx, float ury) { - writer.addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, new PdfAction(filename, page))); - } - - /** Sets the viewer preferences as the sum of several constants. - * @param preferences the viewer preferences - * @see PdfWriter#setViewerPreferences - */ - - public void setViewerPreferences(int preferences) { - viewerPreferences |= preferences; - } - - /** Implements an action in an area. - * @param action the PdfAction - * @param llx the lower left x corner of the activation area - * @param lly the lower left y corner of the activation area - * @param urx the upper right x corner of the activation area - * @param ury the upper right y corner of the activation area - */ - void setAction(PdfAction action, float llx, float lly, float urx, float ury) { - writer.addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action)); - } - - void setOpenAction(String name) { - openActionName = name; - openActionAction = null; - } - - void setOpenAction(PdfAction action) { - openActionAction = action; - openActionName = null; - } - - void addAdditionalAction(PdfName actionType, PdfAction action) { - if (additionalActions == null) { - additionalActions = new PdfDictionary(); - } - if (action == null) - additionalActions.remove(actionType); - else - additionalActions.put(actionType, action); - if (additionalActions.size() == 0) - additionalActions = null; - } - - void setPageLabels(PdfPageLabels pageLabels) { - this.pageLabels = pageLabels; - } - - void addJavaScript(PdfAction js) { - if (js.get(PdfName.JS) == null) - throw new RuntimeException("Only JavaScript actions are allowed."); - try { - documentJavaScript.add(writer.addToBody(js).getIndirectReference()); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - void setCropBoxSize(Rectangle crop) { - setBoxSize("crop", crop); - } - - void setBoxSize(String boxName, Rectangle size) { - if (size == null) - boxSize.remove(boxName); - else - boxSize.put(boxName, new PdfRectangle(size)); - } - - void addCalculationOrder(PdfFormField formField) { - acroForm.addCalculationOrder(formField); - } - - /** - * Gives the size of a trim, art, crop or bleed box, or null if not defined. - * @param boxName crop, trim, art or bleed - */ - Rectangle getBoxSize(String boxName) { - PdfRectangle r = (PdfRectangle)thisBoxSize.get(boxName); - if (r != null) return r.getRectangle(); - return null; - } - - void setSigFlags(int f) { - acroForm.setSigFlags(f); - } - - void addFormFieldRaw(PdfFormField field) { - annotations.add(field); - ArrayList kids = field.getKids(); - if (kids != null) { - for (int k = 0; k < kids.size(); ++k) - addFormFieldRaw((PdfFormField)kids.get(k)); - } - } - - void addAnnotation(PdfAnnotation annot) { - pageEmpty = false; - if (annot.isForm()) { - PdfFormField field = (PdfFormField)annot; - if (field.getParent() == null) - addFormFieldRaw(field); - } - else - annotations.add(annot); - } - - /** - * Sets the display duration for the page (for presentations) - * @param seconds the number of seconds to display the page - */ - void setDuration(int seconds) { - if (seconds > 0) - this.duration=seconds; - else - this.duration=-1; - } - - /** - * Sets the transition for the page - * @param transition the PdfTransition object - */ - void setTransition(PdfTransition transition) { - this.transition=transition; - } - - void setPageAction(PdfName actionType, PdfAction action) { - if (pageAA == null) { - pageAA = new PdfDictionary(); - } - pageAA.put(actionType, action); - } - - /** Getter for property strictImageSequence. - * @return Value of property strictImageSequence. - * - */ - boolean isStrictImageSequence() { - return this.strictImageSequence; - } - - /** Setter for property strictImageSequence. - * @param strictImageSequence New value of property strictImageSequence. - * - */ - void setStrictImageSequence(boolean strictImageSequence) { - this.strictImageSequence = strictImageSequence; - } - - void setPageEmpty(boolean pageEmpty) { - this.pageEmpty = pageEmpty; - } - /** - * Method added by Pelikan Stephan - * @see com.lowagie.text.DocListener#clearTextWrap() - */ - public void clearTextWrap() throws DocumentException { - super.clearTextWrap(); - float tmpHeight = imageEnd - currentHeight; - if (line != null) { - tmpHeight += line.height(); - } - if ((imageEnd > -1) && (tmpHeight > 0)) { - carriageReturn(); - currentHeight += tmpHeight; - } - } - - ArrayList getDocumentJavaScript() { - return documentJavaScript; - } - - /** - * @see com.lowagie.text.DocListener#setMarginMirroring(boolean) - */ - public boolean setMarginMirroring(boolean MarginMirroring) { - if (writer != null && writer.isPaused()) { - return false; - } - return super.setMarginMirroring(MarginMirroring); - } - - void setThumbnail(Image image) throws PdfException, DocumentException { - thumb = writer.getImageReference(writer.addDirectImageSimple(image)); - } - - void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { - if (description == null) - description = ""; - fs.put(PdfName.DESC, new PdfString(description, PdfObject.TEXT_UNICODE)); - if (description.length() == 0) - description = "Unnamed"; - String fn = PdfEncodings.convertToString(new PdfString(description, PdfObject.TEXT_UNICODE).getBytes(), null); - int k = 0; - while (documentFileAttachment.containsKey(fn)) { - ++k; - fn = PdfEncodings.convertToString(new PdfString(description + " " + k, PdfObject.TEXT_UNICODE).getBytes(), null); - } - documentFileAttachment.put(fn, fs.getReference()); - } - - HashMap getDocumentFileAttachment() { - return documentFileAttachment; - } - - static PdfAnnotation convertAnnotation(PdfWriter writer, Annotation annot) throws IOException { - switch(annot.annotationType()) { - case Annotation.URL_NET: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((URL) annot.attributes().get(Annotation.URL))); - case Annotation.URL_AS_STRING: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE))); - case Annotation.FILE_DEST: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE), (String) annot.attributes().get(Annotation.DESTINATION))); - case Annotation.SCREEN: - boolean sparams[] = (boolean[])annot.attributes().get(Annotation.PARAMETERS); - String fname = (String) annot.attributes().get(Annotation.FILE); - String mimetype = (String) annot.attributes().get(Annotation.MIMETYPE); - PdfFileSpecification fs; - if (sparams[0]) - fs = PdfFileSpecification.fileEmbedded(writer, fname, fname, null); - else - fs = PdfFileSpecification.fileExtern(writer, fname); - PdfAnnotation ann = PdfAnnotation.createScreen(writer, new Rectangle(annot.llx(), annot.lly(), annot.urx(), annot.ury()), - fname, fs, mimetype, sparams[1]); - return ann; - case Annotation.FILE_PAGE: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.FILE), ((Integer) annot.attributes().get(Annotation.PAGE)).intValue())); - case Annotation.NAMED_DEST: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction(((Integer) annot.attributes().get(Annotation.NAMED)).intValue())); - case Annotation.LAUNCH: - return new PdfAnnotation(writer, annot.llx(), annot.lly(), annot.urx(), annot.ury(), new PdfAction((String) annot.attributes().get(Annotation.APPLICATION),(String) annot.attributes().get(Annotation.PARAMETERS),(String) annot.attributes().get(Annotation.OPERATION),(String) annot.attributes().get(Annotation.DEFAULTDIR))); - default: - PdfDocument doc = writer.getPdfDocument(); - if (doc.line == null) - return null; - PdfAnnotation an = new PdfAnnotation(writer, annot.llx(doc.indentRight() - doc.line.widthLeft()), annot.lly(doc.indentTop() - doc.currentHeight), annot.urx(doc.indentRight() - doc.line.widthLeft() + 20), annot.ury(doc.indentTop() - doc.currentHeight - 20), new PdfString(annot.title()), new PdfString(annot.content())); - return an; - } - } - /** - * @return an XmpMetadata byte array - */ - public byte[] createXmpMetadata() { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - XmpWriter xmp = new XmpWriter(baos, getInfo()); - xmp.close(); - } - catch(IOException ioe) { - ioe.printStackTrace(); - } - return baos.toByteArray(); - } - - int getMarkPoint() { - return markPoint; - } - - void incMarkPoint() { - ++markPoint; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfEncodings.java b/src/main/java/com/lowagie/text/pdf/PdfEncodings.java deleted file mode 100644 index ab9c468..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfEncodings.java +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.ExceptionConverter; -import java.io.UnsupportedEncodingException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.BufferedReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.StringTokenizer; -/** Supports fast encodings for winansi and PDFDocEncoding. - * Supports conversions from CJK encodings to CID. - * Supports custom encodings. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfEncodings { - protected static final int CIDNONE = 0; - protected static final int CIDRANGE = 1; - protected static final int CIDCHAR = 2; - - static final char winansiByteToChar[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 8364, 65533, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 65533, 381, 65533, - 65533, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 65533, 382, 376, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; - - static final char pdfEncodingByteToChar[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018, - 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 65533, - 0x20ac, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; - - static final IntHashtable winansi = new IntHashtable(); - - static final IntHashtable pdfEncoding = new IntHashtable(); - - static final HashMap extraEncodings = new HashMap(); - - static { - for (int k = 128; k < 160; ++k) { - char c = winansiByteToChar[k]; - if (c != 65533) - winansi.put(c, k); - } - - for (int k = 128; k < 161; ++k) { - char c = pdfEncodingByteToChar[k]; - if (c != 65533) - pdfEncoding.put(c, k); - } - - addExtraEncoding("Wingdings", new WingdingsConversion()); - addExtraEncoding("Symbol", new SymbolConversion(true)); - addExtraEncoding("ZapfDingbats", new SymbolConversion(false)); - addExtraEncoding("SymbolTT", new SymbolTTConversion()); - addExtraEncoding("Cp437", new Cp437Conversion()); - } - - /** Converts a String to a byte array according - * to the font's encoding. - * @return an array of byte representing the conversion according to the font's encoding - * @param encoding the encoding - * @param text the String to be converted - */ - public static final byte[] convertToBytes(String text, String encoding) { - if (text == null) - return new byte[0]; - if (encoding == null || encoding.length() == 0) { - int len = text.length(); - byte b[] = new byte[len]; - for (int k = 0; k < len; ++k) - b[k] = (byte)text.charAt(k); - return b; - } - ExtraEncoding extra = null; - synchronized (extraEncodings) { - extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase()); - } - if (extra != null) { - byte b[] = extra.charToByte(text, encoding); - if (b != null) - return b; - } - IntHashtable hash = null; - if (encoding.equals(BaseFont.WINANSI)) - hash = winansi; - else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING)) - hash = pdfEncoding; - if (hash != null) { - char cc[] = text.toCharArray(); - int len = cc.length; - int ptr = 0; - byte b[] = new byte[len]; - int c = 0; - for (int k = 0; k < len; ++k) { - char char1 = cc[k]; - if (char1 < 128 || (char1 >= 160 && char1 <= 255)) - c = char1; - else - c = hash.get(char1); - if (c != 0) - b[ptr++] = (byte)c; - } - if (ptr == len) - return b; - byte b2[] = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - if (encoding.equals(PdfObject.TEXT_UNICODE)) { - // workaround for jdk 1.2.2 bug - char cc[] = text.toCharArray(); - int len = cc.length; - byte b[] = new byte[cc.length * 2 + 2]; - b[0] = -2; - b[1] = -1; - int bptr = 2; - for (int k = 0; k < len; ++k) { - char c = cc[k]; - b[bptr++] = (byte)(c >> 8); - b[bptr++] = (byte)(c & 0xff); - } - return b; - } - try { - return text.getBytes(encoding); - } - catch (UnsupportedEncodingException e) { - throw new ExceptionConverter(e); - } - } - - /** Converts a byte array to a String according - * to the some encoding. - * @param bytes the bytes to convert - * @param encoding the encoding - * @return the converted String - */ - public static final String convertToString(byte bytes[], String encoding) { - if (bytes == null) - return PdfObject.NOTHING; - if (encoding == null || encoding.length() == 0) { - char c[] = new char[bytes.length]; - for (int k = 0; k < bytes.length; ++k) - c[k] = (char)(bytes[k] & 0xff); - return new String(c); - } - ExtraEncoding extra = null; - synchronized (extraEncodings) { - extra = (ExtraEncoding)extraEncodings.get(encoding.toLowerCase()); - } - if (extra != null) { - String text = extra.byteToChar(bytes, encoding); - if (text != null) - return text; - } - char ch[] = null; - if (encoding.equals(BaseFont.WINANSI)) - ch = winansiByteToChar; - else if (encoding.equals(PdfObject.TEXT_PDFDOCENCODING)) - ch = pdfEncodingByteToChar; - if (ch != null) { - int len = bytes.length; - char c[] = new char[len]; - for (int k = 0; k < len; ++k) { - c[k] = ch[bytes[k] & 0xff]; - } - return new String(c); - } - try { - return new String(bytes, encoding); - } - catch (UnsupportedEncodingException e) { - throw new ExceptionConverter(e); - } - } - - /** Checks is text only has PdfDocEncoding characters. - * @param text the String to test - * @return true if only PdfDocEncoding characters are present - */ - public static boolean isPdfDocEncoding(String text) { - if (text == null) - return true; - int len = text.length(); - for (int k = 0; k < len; ++k) { - char char1 = text.charAt(k); - if (char1 < 128 || (char1 >= 160 && char1 <= 255)) - continue; - if (!pdfEncoding.containsKey(char1)) - return false; - } - return true; - } - - static final HashMap cmaps = new HashMap(); - /** Assumes that '\\n' and '\\r\\n' are the newline sequences. It may not work for - * all CJK encodings. To be used with loadCmap(). - */ - public static final byte CRLF_CID_NEWLINE[][] = new byte[][]{{(byte)'\n'}, {(byte)'\r', (byte)'\n'}}; - - /** Clears the CJK cmaps from the cache. If name is the - * empty string then all the cache is cleared. Calling this method - * has no consequences other than the need to reload the cmap - * if needed. - * @param name the name of the cmap to clear or all the cmaps if the empty string - */ - public static void clearCmap(String name) { - synchronized (cmaps) { - if (name.length() == 0) - cmaps.clear(); - else - cmaps.remove(name); - } - } - - /** Loads a CJK cmap to the cache with the option of associating - * sequences to the newline. - * @param name the CJK cmap name - * @param newline the sequences to be replaced bi a newline in the resulting CID. See CRLF_CID_NEWLINE - */ - public static void loadCmap(String name, byte newline[][]) { - try { - char planes[][] = null; - synchronized (cmaps) { - planes = (char[][])cmaps.get(name); - } - if (planes == null) { - planes = readCmap(name, newline); - synchronized (cmaps) { - cmaps.put(name, planes); - } - } - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** Converts a byte array encoded as name - * to a CID string. This is needed to reach some CJK characters - * that don't exist in 16 bit Unicode.

- * The font to use this result must use the encoding "Identity-H" - * or "Identity-V".

- * See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/. - * @param name the CJK encoding name - * @param seq the byte array to be decoded - * @return the CID string - */ - public static String convertCmap(String name, byte seq[]) { - return convertCmap(name, seq, 0, seq.length); - } - - /** Converts a byte array encoded as name - * to a CID string. This is needed to reach some CJK characters - * that don't exist in 16 bit Unicode.

- * The font to use this result must use the encoding "Identity-H" - * or "Identity-V".

- * See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/. - * @param name the CJK encoding name - * @param start the start offset in the data - * @param length the number of bytes to convert - * @param seq the byte array to be decoded - * @return the CID string - */ - public static String convertCmap(String name, byte seq[], int start, int length) { - try { - char planes[][] = null; - synchronized (cmaps) { - planes = (char[][])cmaps.get(name); - } - if (planes == null) { - planes = readCmap(name, (byte[][])null); - synchronized (cmaps) { - cmaps.put(name, planes); - } - } - return decodeSequence(seq, start, length, planes); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - static String decodeSequence(byte seq[], int start, int length, char planes[][]) { - StringBuffer buf = new StringBuffer(); - int end = start + length; - int currentPlane = 0; - for (int k = start; k < end; ++k) { - int one = (int)seq[k] & 0xff; - char plane[] = planes[currentPlane]; - int cid = plane[one]; - if ((cid & 0x8000) == 0) { - buf.append((char)cid); - currentPlane = 0; - } - else - currentPlane = cid & 0x7fff; - } - return buf.toString(); - } - - static char[][] readCmap(String name, byte newline[][]) throws IOException { - ArrayList planes = new ArrayList(); - planes.add(new char[256]); - readCmap(name, planes); - if (newline != null) { - for (int k = 0; k < newline.length; ++k) - encodeSequence(newline[k].length, newline[k], BaseFont.CID_NEWLINE, planes); - } - char ret[][] = new char[planes.size()][]; - return (char[][])planes.toArray(ret); - } - - static void readCmap(String name, ArrayList planes) throws IOException { - String fullName = BaseFont.RESOURCE_PATH + "cmaps/" + name; - InputStream in = BaseFont.getResourceStream(fullName); - if (in == null) - throw new IOException("The Cmap " + name + " was not found."); - encodeStream(in, planes); - in.close(); - } - - static void encodeStream(InputStream in, ArrayList planes) throws IOException { - BufferedReader rd = new BufferedReader(new InputStreamReader(in, "iso-8859-1")); - String line = null; - int state = CIDNONE; - byte seqs[] = new byte[7]; - while ((line = rd.readLine()) != null) { - if (line.length() < 6) - continue; - switch (state) { - case CIDNONE: { - if (line.indexOf("begincidrange") >= 0) - state = CIDRANGE; - else if (line.indexOf("begincidchar") >= 0) - state = CIDCHAR; - else if (line.indexOf("usecmap") >= 0) { - StringTokenizer tk = new StringTokenizer(line); - String t = tk.nextToken(); - readCmap(t.substring(1), planes); - } - break; - } - case CIDRANGE: { - if (line.indexOf("endcidrange") >= 0) { - state = CIDNONE; - break; - } - StringTokenizer tk = new StringTokenizer(line); - String t = tk.nextToken(); - int size = t.length() / 2 - 1; - long start = Long.parseLong(t.substring(1, t.length() - 1), 16); - t = tk.nextToken(); - long end = Long.parseLong(t.substring(1, t.length() - 1), 16); - t = tk.nextToken(); - int cid = Integer.parseInt(t); - for (long k = start; k <= end; ++k) { - breakLong(k, size, seqs); - encodeSequence(size, seqs, (char)cid, planes); - ++cid; - } - break; - } - case CIDCHAR: { - if (line.indexOf("endcidchar") >= 0) { - state = CIDNONE; - break; - } - StringTokenizer tk = new StringTokenizer(line); - String t = tk.nextToken(); - int size = t.length() / 2 - 1; - long start = Long.parseLong(t.substring(1, t.length() - 1), 16); - t = tk.nextToken(); - int cid = Integer.parseInt(t); - breakLong(start, size, seqs); - encodeSequence(size, seqs, (char)cid, planes); - break; - } - } - } - } - - static void breakLong(long n, int size, byte seqs[]) { - for (int k = 0; k < size; ++k) { - seqs[k] = (byte)(n >> ((size - 1 - k) * 8)); - } - } - - static void encodeSequence(int size, byte seqs[], char cid, ArrayList planes) { - --size; - int nextPlane = 0; - for (int idx = 0; idx < size; ++idx) { - char plane[] = (char[])planes.get(nextPlane); - int one = (int)seqs[idx] & 0xff; - char c = plane[one]; - if (c != 0 && (c & 0x8000) == 0) - throw new RuntimeException("Inconsistent mapping."); - if (c == 0) { - planes.add(new char[256]); - c = (char)((planes.size() - 1) | 0x8000); - plane[one] = c; - } - nextPlane = c & 0x7fff; - } - char plane[] = (char[])planes.get(nextPlane); - int one = (int)seqs[size] & 0xff; - char c = plane[one]; - if ((c & 0x8000) != 0) - throw new RuntimeException("Inconsistent mapping."); - plane[one] = cid; - } - - /** Adds an extra encoding. - * @param name the name of the encoding. The encoding recognition is case insensitive - * @param enc the conversion class - */ - public static void addExtraEncoding(String name, ExtraEncoding enc) { - synchronized (extraEncodings) { - extraEncodings.put(name.toLowerCase(), enc); - } - } - - private static class WingdingsConversion implements ExtraEncoding { - - public byte[] charToByte(String text, String encoding) { - char cc[] = text.toCharArray(); - byte b[] = new byte[cc.length]; - int ptr = 0; - int len = cc.length; - for (int k = 0; k < len; ++k) { - char c = cc[k]; - if (c == ' ') - b[ptr++] = (byte)c; - else if (c >= '\u2701' && c <= '\u27BE') { - byte v = table[c - 0x2700]; - if (v != 0) - b[ptr++] = v; - } - } - if (ptr == len) - return b; - byte b2[] = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - - public String byteToChar(byte[] b, String encoding) { - return null; - } - - private final static byte table[] = { - 0, 35, 34, 0, 0, 0, 41, 62, 81, 42, - 0, 0, 65, 63, 0, 0, 0, 0, 0, -4, - 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, - 86, 0, 88, 89, 0, 0, 0, 0, 0, 0, - 0, 0, -75, 0, 0, 0, 0, 0, -74, 0, - 0, 0, -83, -81, -84, 0, 0, 0, 0, 0, - 0, 0, 0, 124, 123, 0, 0, 0, 84, 0, - 0, 0, 0, 0, 0, 0, 0, -90, 0, 0, - 0, 113, 114, 0, 0, 0, 117, 0, 0, 0, - 0, 0, 0, 125, 126, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -116, -115, - -114, -113, -112, -111, -110, -109, -108, -107, -127, -126, - -125, -124, -123, -122, -121, -120, -119, -118, -116, -115, - -114, -113, -112, -111, -110, -109, -108, -107, -24, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -24, -40, 0, 0, -60, -58, 0, 0, -16, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -36, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 - }; - } - - private static class Cp437Conversion implements ExtraEncoding { - private static IntHashtable c2b = new IntHashtable(); - - public byte[] charToByte(String text, String encoding) { - char cc[] = text.toCharArray(); - byte b[] = new byte[cc.length]; - int ptr = 0; - int len = cc.length; - for (int k = 0; k < len; ++k) { - char c = cc[k]; - if (c < ' ') - continue; - if (c < 128) - b[ptr++] = (byte)c; - else { - byte v = (byte)c2b.get(c); - if (v != 0) - b[ptr++] = v; - } - } - if (ptr == len) - return b; - byte b2[] = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - - public String byteToChar(byte[] b, String encoding) { - int len = b.length; - char cc[] = new char[len]; - int ptr = 0; - for (int k = 0; k < len; ++k) { - int c = b[k] & 0xff; - if (c < ' ') - continue; - if (c < 128) - cc[ptr++] = (char)c; - else { - char v = table[c - 128]; - cc[ptr++] = v; - } - } - return new String(cc, 0, ptr); - } - - private final static char table[] = { - '\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', - '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', '\u00FF', '\u00D6', '\u00DC', '\u00A2', '\u00A3', '\u00A5', '\u20A7', '\u0192', - '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', '\u00AA', '\u00BA', '\u00BF', '\u2310', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', - '\u2591', '\u2592', '\u2593', '\u2502', '\u2524', '\u2561', '\u2562', '\u2556', '\u2555', '\u2563', '\u2551', '\u2557', '\u255D', '\u255C', '\u255B', '\u2510', - '\u2514', '\u2534', '\u252C', '\u251C', '\u2500', '\u253C', '\u255E', '\u255F', '\u255A', '\u2554', '\u2569', '\u2566', '\u2560', '\u2550', '\u256C', '\u2567', - '\u2568', '\u2564', '\u2565', '\u2559', '\u2558', '\u2552', '\u2553', '\u256B', '\u256A', '\u2518', '\u250C', '\u2588', '\u2584', '\u258C', '\u2590', '\u2580', - '\u03B1', '\u00DF', '\u0393', '\u03C0', '\u03A3', '\u03C3', '\u00B5', '\u03C4', '\u03A6', '\u0398', '\u03A9', '\u03B4', '\u221E', '\u03C6', '\u03B5', '\u2229', - '\u2261', '\u00B1', '\u2265', '\u2264', '\u2320', '\u2321', '\u00F7', '\u2248', '\u00B0', '\u2219', '\u00B7', '\u221A', '\u207F', '\u00B2', '\u25A0', '\u00A0' - }; - - static { - for (int k = 0; k < table.length; ++k) - c2b.put(table[k], k + 128); - } - } - - private static class SymbolConversion implements ExtraEncoding { - - private static final IntHashtable t1 = new IntHashtable(); - private static final IntHashtable t2 = new IntHashtable(); - private IntHashtable translation; - - SymbolConversion(boolean symbol) { - if (symbol) - translation = t1; - else - translation = t2; - } - - public byte[] charToByte(String text, String encoding) { - char cc[] = text.toCharArray(); - byte b[] = new byte[cc.length]; - int ptr = 0; - int len = cc.length; - for (int k = 0; k < len; ++k) { - char c = cc[k]; - byte v = (byte)translation.get((int)c); - if (v != 0) - b[ptr++] = v; - } - if (ptr == len) - return b; - byte b2[] = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - - public String byteToChar(byte[] b, String encoding) { - return null; - } - - private final static char table1[] = { - ' ','!','\u2200','#','\u2203','%','&','\u220b','(',')','*','+',',','-','.','/', - '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', - '\u2245','\u0391','\u0392','\u03a7','\u0394','\u0395','\u03a6','\u0393','\u0397','\u0399','\u03d1','\u039a','\u039b','\u039c','\u039d','\u039f', - '\u03a0','\u0398','\u03a1','\u03a3','\u03a4','\u03a5','\u03c2','\u03a9','\u039e','\u03a8','\u0396','[','\u2234',']','\u22a5','_', - '\u0305','\u03b1','\u03b2','\u03c7','\u03b4','\u03b5','\u03d5','\u03b3','\u03b7','\u03b9','\u03c6','\u03ba','\u03bb','\u03bc','\u03bd','\u03bf', - '\u03c0','\u03b8','\u03c1','\u03c3','\u03c4','\u03c5','\u03d6','\u03c9','\u03be','\u03c8','\u03b6','{','|','}','~','\0', - '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', - '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', - '\u20ac','\u03d2','\u2032','\u2264','\u2044','\u221e','\u0192','\u2663','\u2666','\u2665','\u2660','\u2194','\u2190','\u2191','\u2192','\u2193', - '\u00b0','\u00b1','\u2033','\u2265','\u00d7','\u221d','\u2202','\u2022','\u00f7','\u2260','\u2261','\u2248','\u2026','\u2502','\u2500','\u21b5', - '\u2135','\u2111','\u211c','\u2118','\u2297','\u2295','\u2205','\u2229','\u222a','\u2283','\u2287','\u2284','\u2282','\u2286','\u2208','\u2209', - '\u2220','\u2207','\u00ae','\u00a9','\u2122','\u220f','\u221a','\u2022','\u00ac','\u2227','\u2228','\u21d4','\u21d0','\u21d1','\u21d2','\u21d3', - '\u25ca','\u2329','\0','\0','\0','\u2211','\u239b','\u239c','\u239d','\u23a1','\u23a2','\u23a3','\u23a7','\u23a8','\u23a9','\u23aa', - '\0','\u232a','\u222b','\u2320','\u23ae','\u2321','\u239e','\u239f','\u23a0','\u23a4','\u23a5','\u23a6','\u23ab','\u23ac','\u23ad','\0' - }; - - private final static char table2[] = { - '\u0020','\u2701','\u2702','\u2703','\u2704','\u260e','\u2706','\u2707','\u2708','\u2709','\u261b','\u261e','\u270C','\u270D','\u270E','\u270F', - '\u2710','\u2711','\u2712','\u2713','\u2714','\u2715','\u2716','\u2717','\u2718','\u2719','\u271A','\u271B','\u271C','\u271D','\u271E','\u271F', - '\u2720','\u2721','\u2722','\u2723','\u2724','\u2725','\u2726','\u2727','\u2605','\u2729','\u272A','\u272B','\u272C','\u272D','\u272E','\u272F', - '\u2730','\u2731','\u2732','\u2733','\u2734','\u2735','\u2736','\u2737','\u2738','\u2739','\u273A','\u273B','\u273C','\u273D','\u273E','\u273F', - '\u2740','\u2741','\u2742','\u2743','\u2744','\u2745','\u2746','\u2747','\u2748','\u2749','\u274A','\u274B','\u25cf','\u274D','\u25a0','\u274F', - '\u2750','\u2751','\u2752','\u25b2','\u25bc','\u25c6','\u2756','\u25d7','\u2758','\u2759','\u275A','\u275B','\u275C','\u275D','\u275E','\u0000', - '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', - '\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0','\0', - '\u0000','\u2761','\u2762','\u2763','\u2764','\u2765','\u2766','\u2767','\u2663','\u2666','\u2665','\u2660','\u2460','\u2461','\u2462','\u2463', - '\u2464','\u2465','\u2466','\u2467','\u2468','\u2469','\u2776','\u2777','\u2778','\u2779','\u277A','\u277B','\u277C','\u277D','\u277E','\u277F', - '\u2780','\u2781','\u2782','\u2783','\u2784','\u2785','\u2786','\u2787','\u2788','\u2789','\u278A','\u278B','\u278C','\u278D','\u278E','\u278F', - '\u2790','\u2791','\u2792','\u2793','\u2794','\u2192','\u2194','\u2195','\u2798','\u2799','\u279A','\u279B','\u279C','\u279D','\u279E','\u279F', - '\u27A0','\u27A1','\u27A2','\u27A3','\u27A4','\u27A5','\u27A6','\u27A7','\u27A8','\u27A9','\u27AA','\u27AB','\u27AC','\u27AD','\u27AE','\u27AF', - '\u0000','\u27B1','\u27B2','\u27B3','\u27B4','\u27B5','\u27B6','\u27B7','\u27B8','\u27B9','\u27BA','\u27BB','\u27BC','\u27BD','\u27BE','\u0000' - }; - - static { - for (int k = 0; k < table1.length; ++k) { - int v = (int)table1[k]; - if (v != 0) - t1.put(v, k + 32); - } - for (int k = 0; k < table2.length; ++k) { - int v = (int)table2[k]; - if (v != 0) - t2.put(v, k + 32); - } - } - } - - private static class SymbolTTConversion implements ExtraEncoding { - - public byte[] charToByte(String text, String encoding) { - char ch[] = text.toCharArray(); - byte b[] = new byte[ch.length]; - int ptr = 0; - int len = ch.length; - for (int k = 0; k < len; ++k) { - char c = ch[k]; - if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000) - b[ptr++] = (byte)c; - } - if (ptr == len) - return b; - byte b2[] = new byte[ptr]; - System.arraycopy(b, 0, b2, 0, ptr); - return b2; - } - - public String byteToChar(byte[] b, String encoding) { - return null; - } - - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfEncryption.java b/src/main/java/com/lowagie/text/pdf/PdfEncryption.java deleted file mode 100644 index 18046a8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfEncryption.java +++ /dev/null @@ -1,390 +0,0 @@ -/* - * $Id: PdfEncryption.java,v 1.54 2006/05/03 11:35:12 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.security.MessageDigest; -import com.lowagie.text.ExceptionConverter; - -/** - * - * @author Paulo Soares (psoares@consiste.pt) - * @author Kazuya Ujihara - */ -public class PdfEncryption { - - static final byte pad[] = { - (byte)0x28, (byte)0xBF, (byte)0x4E, (byte)0x5E, (byte)0x4E, (byte)0x75, - (byte)0x8A, (byte)0x41, (byte)0x64, (byte)0x00, (byte)0x4E, (byte)0x56, - (byte)0xFF, (byte)0xFA, (byte)0x01, (byte)0x08, (byte)0x2E, (byte)0x2E, - (byte)0x00, (byte)0xB6, (byte)0xD0, (byte)0x68, (byte)0x3E, (byte)0x80, - (byte)0x2F, (byte)0x0C, (byte)0xA9, (byte)0xFE, (byte)0x64, (byte)0x53, - (byte)0x69, (byte)0x7A}; - - byte state[] = new byte[256]; - int x; - int y; - /** The encryption key for a particular object/generation */ - byte key[]; - /** The encryption key length for a particular object/generation */ - int keySize; - /** The global encryption key */ - byte mkey[]; - /** Work area to prepare the object/generation bytes */ - byte extra[] = new byte[5]; - /** The message digest algorithm MD5 */ - MessageDigest md5; - /** The encryption key for the owner */ - byte ownerKey[] = new byte[32]; - /** The encryption key for the user */ - byte userKey[] = new byte[32]; - int permissions; - byte documentID[]; - static long seq = System.currentTimeMillis(); - - public PdfEncryption() { - try { - md5 = MessageDigest.getInstance("MD5"); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - public PdfEncryption(PdfEncryption enc) { - this(); - mkey = (byte[])enc.mkey.clone(); - ownerKey = (byte[])enc.ownerKey.clone(); - userKey = (byte[])enc.userKey.clone(); - permissions = enc.permissions; - if (enc.documentID != null) - documentID = (byte[])enc.documentID.clone(); - } - - /** - */ - private byte[] padPassword(byte userPassword[]) { - byte userPad[] = new byte[32]; - if (userPassword == null) { - System.arraycopy(pad, 0, userPad, 0, 32); - } - else { - System.arraycopy(userPassword, 0, userPad, 0, Math.min(userPassword.length, 32)); - if (userPassword.length < 32) - System.arraycopy(pad, 0, userPad, userPassword.length, 32 - userPassword.length); - } - - return userPad; - } - - /** - */ - private byte[] computeOwnerKey(byte userPad[], byte ownerPad[], int keylength, int revision) { - byte ownerKey[] = new byte[32]; - - byte digest[] = md5.digest(ownerPad); - if (revision == 3) { - byte mkey[] = new byte[keylength/8]; - // only use for the input as many bit as the key consists of - for (int k = 0; k < 50; ++k) - System.arraycopy(md5.digest(), 0, digest, 0, mkey.length); - System.arraycopy(userPad, 0, ownerKey, 0, 32); - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < mkey.length ; ++j) - mkey[j] = (byte)(digest[j] ^ i); - prepareRC4Key(mkey); - encryptRC4(ownerKey); - } - } - else { - prepareRC4Key(digest, 0, 5); - encryptRC4(userPad, ownerKey); - } - - return ownerKey; - } - - /** - * - * ownerKey, documentID must be setuped - */ - private void setupGlobalEncryptionKey(byte[] documentID, byte userPad[], byte ownerKey[], int permissions, int keylength, int revision) { - this.documentID = documentID; - this.ownerKey = ownerKey; - this.permissions = permissions; - // use variable keylength - mkey = new byte[keylength/8]; - - //fixed by ujihara in order to follow PDF refrence - md5.reset(); - md5.update(userPad); - md5.update(ownerKey); - - byte ext[] = new byte[4]; - ext[0] = (byte)permissions; - ext[1] = (byte)(permissions >> 8); - ext[2] = (byte)(permissions >> 16); - ext[3] = (byte)(permissions >> 24); - md5.update(ext, 0, 4); - if (documentID != null) md5.update(documentID); - - byte digest[] = new byte[mkey.length]; - System.arraycopy(md5.digest(), 0, digest, 0, mkey.length); - - // only use the really needed bits as input for the hash - if (revision == 3){ - for (int k = 0; k < 50; ++k) - System.arraycopy(md5.digest(digest), 0, digest, 0, mkey.length); - } - - - System.arraycopy(digest, 0, mkey, 0, mkey.length); - } - - /** - * - * mkey must be setuped - */ - // use the revision to choose the setup method - private void setupUserKey(int revision) { - if (revision == 3) { - md5.update(pad); - byte digest[] = md5.digest(documentID); - System.arraycopy(digest, 0, userKey, 0, 16); - for (int k = 16; k < 32; ++k) - userKey[k] = 0; - for (int i = 0; i < 20; ++i) { - for (int j = 0; j < mkey.length; ++j) - digest[j] = (byte)(mkey[j] ^ i); - prepareRC4Key(digest, 0, mkey.length); - encryptRC4(userKey, 0, 16); - } - } - else { - prepareRC4Key(mkey); - encryptRC4(pad, userKey); - } - } - - // gets keylength and revision and uses revison to choose the initial values for permissions - public void setupAllKeys(byte userPassword[], byte ownerPassword[], int permissions, int keylength, int revision) { - if (ownerPassword == null || ownerPassword.length == 0) - ownerPassword = md5.digest(createDocumentId()); - permissions |= revision==3 ? 0xfffff0c0 : 0xffffffc0; - permissions &= 0xfffffffc; - //PDF refrence 3.5.2 Standard Security Handler, Algorithum 3.3-1 - //If there is no owner password, use the user password instead. - byte userPad[] = padPassword(userPassword); - byte ownerPad[] = padPassword(ownerPassword); - - this.ownerKey = computeOwnerKey(userPad, ownerPad, keylength, revision); - documentID = createDocumentId(); - setupByUserPad(this.documentID, userPad, this.ownerKey, permissions, keylength, revision); - } - - // calls the setupAllKeys function with default values to keep the old behavior and signature - public void setupAllKeys(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) { - setupAllKeys(userPassword, ownerPassword, permissions, strength128Bits?128:40, strength128Bits?3:2); - } - - public static byte[] createDocumentId() { - MessageDigest md5; - try { - md5 = MessageDigest.getInstance("MD5"); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - long time = System.currentTimeMillis(); - long mem = Runtime.getRuntime().freeMemory(); - String s = time + "+" + mem + "+" + (seq++); - return md5.digest(s.getBytes()); - } - - /** - */ - // the following functions use the new parameters for the call of the functions - // resp. they map the call of the old functions to the changed in order to keep the - // old behaviour and signatures - public void setupByUserPassword(byte[] documentID, byte userPassword[], byte ownerKey[], int permissions, boolean strength128Bits) { - setupByUserPassword(documentID, userPassword, ownerKey, permissions, strength128Bits?128:40, strength128Bits?3:2); - } - - /** - */ - public void setupByUserPassword(byte[] documentID, byte userPassword[], byte ownerKey[], int permissions, int keylength, int revision) { - setupByUserPad(documentID, padPassword(userPassword), ownerKey, permissions, keylength, revision); - } - - /** - */ - private void setupByUserPad(byte[] documentID, byte userPad[], byte ownerKey[], int permissions, int keylength, int revision) { - setupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions, keylength, revision); - setupUserKey(revision); - } - - /** - */ - public void setupByOwnerPassword(byte[] documentID, byte ownerPassword[], byte userKey[], byte ownerKey[], int permissions, boolean strength128Bits) { - setupByOwnerPassword(documentID, ownerPassword, userKey, ownerKey, permissions, strength128Bits?128:40, strength128Bits?3:2); - } - - /** - */ - public void setupByOwnerPassword(byte[] documentID, byte ownerPassword[], byte userKey[], byte ownerKey[], int permissions, int keylength, int revision) { - setupByOwnerPad(documentID, padPassword(ownerPassword), userKey, ownerKey, permissions, keylength, revision); - } - - private void setupByOwnerPad(byte[] documentID, byte ownerPad[], byte userKey[], byte ownerKey[], int permissions, int keylength, int revision) { - byte userPad[] = computeOwnerKey(ownerKey, ownerPad, keylength, revision); //userPad will be set in this.ownerKey - setupGlobalEncryptionKey(documentID, userPad, ownerKey, permissions, keylength, revision); //step 3 - setupUserKey(revision); - } - - public void prepareKey() { - prepareRC4Key(key, 0, keySize); - } - - public void setHashKey(int number, int generation) { - md5.reset(); //added by ujihara - extra[0] = (byte)number; - extra[1] = (byte)(number >> 8); - extra[2] = (byte)(number >> 16); - extra[3] = (byte)generation; - extra[4] = (byte)(generation >> 8); - md5.update(mkey); - key = md5.digest(extra); - keySize = mkey.length + 5; - if (keySize > 16) - keySize = 16; - } - - public static PdfObject createInfoId(byte id[]) { - ByteBuffer buf = new ByteBuffer(90); - buf.append('[').append('<'); - for (int k = 0; k < 16; ++k) - buf.appendHex(id[k]); - buf.append('>').append('<'); - id = createDocumentId(); - for (int k = 0; k < 16; ++k) - buf.appendHex(id[k]); - buf.append('>').append(']'); - return new PdfLiteral(buf.toByteArray()); - } - - public PdfDictionary getEncryptionDictionary() { - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.FILTER, PdfName.STANDARD); - dic.put(PdfName.O, new PdfLiteral(PdfContentByte.escapeString(ownerKey))); - dic.put(PdfName.U, new PdfLiteral(PdfContentByte.escapeString(userKey))); - dic.put(PdfName.P, new PdfNumber(permissions)); - if (mkey.length > 5) { - dic.put(PdfName.V, new PdfNumber(2)); - dic.put(PdfName.R, new PdfNumber(3)); - dic.put(PdfName.LENGTH, new PdfNumber(128)); - } - else { - dic.put(PdfName.V, new PdfNumber(1)); - dic.put(PdfName.R, new PdfNumber(2)); - } - return dic; - } - - public void prepareRC4Key(byte key[]) { - prepareRC4Key(key, 0, key.length); - } - - public void prepareRC4Key(byte key[], int off, int len) { - int index1 = 0; - int index2 = 0; - for (int k = 0; k < 256; ++k) - state[k] = (byte)k; - x = 0; - y = 0; - byte tmp; - for (int k = 0; k < 256; ++k) { - index2 = (key[index1 + off] + state[k] + index2) & 255; - tmp = state[k]; - state[k] = state[index2]; - state[index2] = tmp; - index1 = (index1 + 1) % len; - } - } - - public void encryptRC4(byte dataIn[], int off, int len, byte dataOut[]) { - int length = len + off; - byte tmp; - for (int k = off; k < length; ++k) { - x = (x + 1) & 255; - y = (state[x] + y) & 255; - tmp = state[x]; - state[x] = state[y]; - state[y] = tmp; - dataOut[k] = (byte)(dataIn[k] ^ state[(state[x] + state[y]) & 255]); - } - } - - public void encryptRC4(byte data[], int off, int len) { - encryptRC4(data, off, len, data); - } - - public void encryptRC4(byte dataIn[], byte dataOut[]) { - encryptRC4(dataIn, 0, dataIn.length, dataOut); - } - - public void encryptRC4(byte data[]) { - encryptRC4(data, 0, data.length, data); - } - - public PdfObject getFileID() { - return createInfoId(documentID); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfEncryptionStream.java b/src/main/java/com/lowagie/text/pdf/PdfEncryptionStream.java deleted file mode 100644 index 99170ca..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfEncryptionStream.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * $Id: PdfEncryptionStream.java,v 1.3 2005/02/17 09:20:54 blowagie Exp $ - * $Name: $ - * - * Copyright 2004 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.FilterOutputStream; -import java.io.OutputStream; -import java.io.IOException; - -public class PdfEncryptionStream extends FilterOutputStream { - - protected PdfEncryption enc; - private byte buf[] = new byte[1]; - - public PdfEncryptionStream(OutputStream out, PdfEncryption enc) { - super(out); - this.enc = enc; - } - - public void write(byte[] b, int off, int len) throws IOException { - if ((off | len | (b.length - (len + off)) | (off + len)) < 0) - throw new IndexOutOfBoundsException(); - enc.encryptRC4(b, off, len); - out.write(b, off, len); - } - - public void close() throws IOException { - } - - public void write(int b) throws IOException { - buf[0] = (byte)b; - write(buf); - } - - public void flush() throws IOException { - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfEncryptor.java b/src/main/java/com/lowagie/text/pdf/PdfEncryptor.java deleted file mode 100644 index 7bea4d5..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfEncryptor.java +++ /dev/null @@ -1,176 +0,0 @@ -/* -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.OutputStream; -import java.io.IOException; -import com.lowagie.text.DocumentException; -import java.util.HashMap; - -/** This class takes any PDF and returns exactly the same but - * encrypted. All the content, links, outlines, etc, are kept. - * It is also possible to change the info dictionary. - */ -public class PdfEncryptor { - - private PdfEncryptor(){ - } - - /** Entry point to encrypt a PDF document. The encryption parameters are the same as in - * PdfWriter. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param reader the read PDF - * @param os the output destination - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param strength128Bits true for 128 bit key length, false for 40 bit key length - * @throws DocumentException on error - * @throws IOException on error */ - public static void encrypt(PdfReader reader, OutputStream os, byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException, IOException { - PdfStamper stamper = new PdfStamper(reader, os); - stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); - stamper.close(); - } - - /** Entry point to encrypt a PDF document. The encryption parameters are the same as in - * PdfWriter. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param reader the read PDF - * @param os the output destination - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param strength128Bits true for 128 bit key length, false for 40 bit key length - * @param newInfo an optional String map to add or change - * the info dictionary. Entries with null - * values delete the key in the original info dictionary - * @throws DocumentException on error - * @throws IOException on error - */ - public static void encrypt(PdfReader reader, OutputStream os, byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits, HashMap newInfo) throws DocumentException, IOException { - PdfStamper stamper = new PdfStamper(reader, os); - stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); - stamper.setMoreInfo(newInfo); - stamper.close(); - } - - /** Entry point to encrypt a PDF document. The encryption parameters are the same as in - * PdfWriter. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param reader the read PDF - * @param os the output destination - * @param strength true for 128 bit key length, false for 40 bit key length - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @throws DocumentException on error - * @throws IOException on error */ - public static void encrypt(PdfReader reader, OutputStream os, boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException, IOException { - PdfStamper stamper = new PdfStamper(reader, os); - stamper.setEncryption(strength, userPassword, ownerPassword, permissions); - stamper.close(); - } - - /** Entry point to encrypt a PDF document. The encryption parameters are the same as in - * PdfWriter. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param reader the read PDF - * @param os the output destination - * @param strength true for 128 bit key length, false for 40 bit key length - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param newInfo an optional String map to add or change - * the info dictionary. Entries with null - * values delete the key in the original info dictionary - * @throws DocumentException on error - * @throws IOException on error - */ - public static void encrypt(PdfReader reader, OutputStream os, boolean strength, String userPassword, String ownerPassword, int permissions, HashMap newInfo) throws DocumentException, IOException { - PdfStamper stamper = new PdfStamper(reader, os); - stamper.setEncryption(strength, userPassword, ownerPassword, permissions); - stamper.setMoreInfo(newInfo); - stamper.close(); - } - - /** - * Give you a verbose analysis of the permissions. - * @param permissions the permissions value of a PDF file - * @return a String that explains the meaning of the permissions value - */ - public static String getPermissionsVerbose(int permissions) { - StringBuffer buf = new StringBuffer("Allowed:"); - if ((PdfWriter.AllowPrinting & permissions) == PdfWriter.AllowPrinting) buf.append(" Printing"); - if ((PdfWriter.AllowModifyContents & permissions) == PdfWriter.AllowModifyContents) buf.append(" Modify contents"); - if ((PdfWriter.AllowCopy & permissions) == PdfWriter.AllowCopy) buf.append(" Copy"); - if ((PdfWriter.AllowModifyAnnotations & permissions) == PdfWriter.AllowModifyAnnotations) buf.append(" Modify annotations"); - if ((PdfWriter.AllowFillIn & permissions) == PdfWriter.AllowFillIn) buf.append(" Fill in"); - if ((PdfWriter.AllowScreenReaders & permissions) == PdfWriter.AllowScreenReaders) buf.append(" Screen readers"); - if ((PdfWriter.AllowAssembly & permissions) == PdfWriter.AllowAssembly) buf.append(" Assembly"); - if ((PdfWriter.AllowDegradedPrinting & permissions) == PdfWriter.AllowDegradedPrinting) buf.append(" Degraded printing"); - return buf.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfException.java b/src/main/java/com/lowagie/text/pdf/PdfException.java deleted file mode 100644 index 486ece0..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfException.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * $Id: PdfException.java,v 1.54 2005/05/04 14:31:43 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.DocumentException; - -/** - * Signals that an unspecified problem while constructing a PDF document. - * - * @see BadPdfFormatException - */ - -public class PdfException extends DocumentException { - - // constructors - - public PdfException(Exception ex) { - super(ex); - } - - /** - * Constructs a PdfException whithout a message. - */ - - PdfException() { - super(); - } - -/** - * Constructs a PdfException with a message. - * - * @param message a message describing the exception - */ - - PdfException(String message) { - super(message); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfFileSpecification.java b/src/main/java/com/lowagie/text/pdf/PdfFileSpecification.java deleted file mode 100644 index cec2b20..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfFileSpecification.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.*; -import java.net.URL; -/** Specifies a file or an URL. The file can be extern or embedded. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfFileSpecification extends PdfDictionary { - protected PdfWriter writer; - protected PdfIndirectReference ref; - - /** Creates a new instance of PdfFileSpecification. The static methods are preferred. */ - public PdfFileSpecification() { - super(PdfName.FILESPEC); - } - - /** - * Creates a file specification of type URL. - * @param writer the PdfWriter - * @param url the URL - * @return the file specification - */ - public static PdfFileSpecification url(PdfWriter writer, String url) { - PdfFileSpecification fs = new PdfFileSpecification(); - fs.writer = writer; - fs.put(PdfName.FS, PdfName.URL); - fs.put(PdfName.F, new PdfString(url)); - return fs; - } - - /** - * Creates a file specification with the file embedded. The file may - * come from the file system or from a byte array. The data is flate compressed. - * @param writer the PdfWriter - * @param filePath the file path - * @param fileDisplay the file information that is presented to the user - * @param fileStore the byte array with the file. If it is not null - * it takes precedence over filePath - * @throws IOException on error - * @return the file specification - */ - public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[]) throws IOException { - return fileEmbedded(writer, filePath, fileDisplay, fileStore, true); - } - - - /** - * Creates a file specification with the file embedded. The file may - * come from the file system or from a byte array. - * @param writer the PdfWriter - * @param filePath the file path - * @param fileDisplay the file information that is presented to the user - * @param fileStore the byte array with the file. If it is not null - * it takes precedence over filePath - * @param compress sets the compression on the data. Multimedia content will benefit little - * from compression - * @throws IOException on error - * @return the file specification - */ - public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], boolean compress) throws IOException { - PdfFileSpecification fs = new PdfFileSpecification(); - fs.writer = writer; - fs.put(PdfName.F, new PdfString(fileDisplay)); - PdfStream stream; - InputStream in = null; - PdfIndirectReference ref; - PdfIndirectReference refFileLength; - try { - refFileLength = writer.getPdfIndirectReference(); - if (fileStore == null) { - File file = new File(filePath); - if (file.canRead()) { - in = new FileInputStream(filePath); - } - else { - if (filePath.startsWith("file:/") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("jar:")) { - in = new URL(filePath).openStream(); - } - else { - in = BaseFont.getResourceStream(filePath); - if (in == null) - throw new IOException(filePath + " not found as file or resource."); - } - } - stream = new PdfStream(in, writer); - } - else - stream = new PdfStream(fileStore); - stream.put(PdfName.TYPE, PdfName.EMBEDDEDFILE); - if (compress) - stream.flateCompress(); - stream.put(PdfName.PARAMS, refFileLength); - ref = writer.addToBody(stream).getIndirectReference(); - if (fileStore == null) { - stream.writeLength(); - } - PdfDictionary params = new PdfDictionary(); - params.put(PdfName.SIZE, new PdfNumber(stream.getRawLength())); - writer.addToBody(params, refFileLength); - } - finally { - if (in != null) - try{in.close();}catch(Exception e){} - } - PdfDictionary f = new PdfDictionary(); - f.put(PdfName.F, ref); - fs.put(PdfName.EF, f); - return fs; - } - - /** - * Creates a file specification for an external file. - * @param writer the PdfWriter - * @param filePath the file path - * @return the file specification - */ - public static PdfFileSpecification fileExtern(PdfWriter writer, String filePath) { - PdfFileSpecification fs = new PdfFileSpecification(); - fs.writer = writer; - fs.put(PdfName.F, new PdfString(filePath)); - return fs; - } - - /** - * Gets the indirect reference to this file specification. - * Multiple invocations will retrieve the same value. - * @throws IOException on error - * @return the indirect reference - */ - public PdfIndirectReference getReference() throws IOException { - if (ref != null) - return ref; - ref = writer.addToBody(this).getIndirectReference(); - return ref; - } - - /** - * Sets the file name (the key /F) string as an hex representation - * to support multi byte file names. The name must heve th slash and - * backslash escaped according to the file specification rules - * @param fileName the file name as a byte array - */ - public void setMultiByteFileName(byte fileName[]) { - put(PdfName.F, new PdfString(fileName).setHexWriting(true)); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfFont.java b/src/main/java/com/lowagie/text/pdf/PdfFont.java deleted file mode 100644 index 0f8e3c8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfFont.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * $Id: PdfFont.java,v 1.64 2005/05/04 14:32:21 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Image; -import com.lowagie.text.ExceptionConverter; - -/** - * PdfFont is the Pdf Font object. - *

- * Limitation: in this class only base 14 Type 1 fonts (courier, courier bold, courier oblique, - * courier boldoblique, helvetica, helvetica bold, helvetica oblique, helvetica boldoblique, - * symbol, times roman, times bold, times italic, times bolditalic, zapfdingbats) and their - * standard encoding (standard, MacRoman, (MacExpert,) WinAnsi) are supported.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 7.7 (page 198-203). - * - * @see PdfName - * @see PdfDictionary - * @see BadPdfFormatException - */ - -class PdfFont implements Comparable { - - - /** the font metrics. */ - private BaseFont font; - - /** the size. */ - private float size; - - /** an image. */ - protected Image image; - - protected float hScale = 1; - - // constructors - - PdfFont(BaseFont bf, float size) { - this.size = size; - font = bf; - } - - // methods - - /** - * Compares this PdfFont with another - * - * @param object the other PdfFont - * @return a value - */ - - public int compareTo(Object object) { - if (image != null) - return 0; - if (object == null) { - return -1; - } - PdfFont pdfFont; - try { - pdfFont = (PdfFont) object; - if (font != pdfFont.font) { - return 1; - } - if (this.size() != pdfFont.size()) { - return 2; - } - return 0; - } - catch(ClassCastException cce) { - return -2; - } - } - - /** - * Returns the size of this font. - * - * @return a size - */ - - float size() { - if (image == null) - return size; - else { - return image.scaledHeight(); - } - } - - /** - * Returns the approximative width of 1 character of this font. - * - * @return a width in Text Space - */ - - float width() { - return width(' '); - } - - /** - * Returns the width of a certain character of this font. - * - * @param character a certain character - * @return a width in Text Space - */ - - float width(char character) { - if (image == null) - return font.getWidthPoint(character, size) * hScale; - else - return image.scaledWidth(); - } - - float width(String s) { - if (image == null) - return font.getWidthPoint(s, size) * hScale; - else - return image.scaledWidth(); - } - - BaseFont getFont() { - return font; - } - - void setImage(Image image) { - this.image = image; - } - - static PdfFont getDefaultFont() { - try { - BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, false); - return new PdfFont(bf, 12); - } - catch (Exception ee) { - throw new ExceptionConverter(ee); - } - } - void setHorizontalScaling(float hScale) { - this.hScale = hScale; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfFormField.java b/src/main/java/com/lowagie/text/pdf/PdfFormField.java deleted file mode 100644 index bd13ddc..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfFormField.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.Rectangle; -import java.util.ArrayList; -import java.util.Iterator; - -/** Implements form fields. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfFormField extends PdfAnnotation { - - public static final int FF_READ_ONLY = 1; - public static final int FF_REQUIRED = 2; - public static final int FF_NO_EXPORT = 4; - public static final int FF_NO_TOGGLE_TO_OFF = 16384; - public static final int FF_RADIO = 32768; - public static final int FF_PUSHBUTTON = 65536; - public static final int FF_MULTILINE = 4096; - public static final int FF_PASSWORD = 8192; - public static final int FF_COMBO = 131072; - public static final int FF_EDIT = 262144; - public static final int FF_FILESELECT = 1048576; - public static final int FF_MULTISELECT = 2097152; - public static final int FF_DONOTSPELLCHECK = 4194304; - public static final int FF_DONOTSCROLL = 8388608; - public static final int FF_COMB = 16777216; - public static final int FF_RADIOSINUNISON = 1 << 25; - public static final int Q_LEFT = 0; - public static final int Q_CENTER = 1; - public static final int Q_RIGHT = 2; - public static final int MK_NO_ICON = 0; - public static final int MK_NO_CAPTION = 1; - public static final int MK_CAPTION_BELOW = 2; - public static final int MK_CAPTION_ABOVE = 3; - public static final int MK_CAPTION_RIGHT = 4; - public static final int MK_CAPTION_LEFT = 5; - public static final int MK_CAPTION_OVERLAID = 6; - public static final PdfName IF_SCALE_ALWAYS = PdfName.A; - public static final PdfName IF_SCALE_BIGGER = PdfName.B; - public static final PdfName IF_SCALE_SMALLER = PdfName.S; - public static final PdfName IF_SCALE_NEVER = PdfName.N; - public static final PdfName IF_SCALE_ANAMORPHIC = PdfName.A; - public static final PdfName IF_SCALE_PROPORTIONAL = PdfName.P; - public static final boolean MULTILINE = true; - public static final boolean SINGLELINE = false; - public static final boolean PLAINTEXT = false; - public static final boolean PASSWORD = true; - static PdfName mergeTarget[] = {PdfName.FONT, PdfName.XOBJECT, PdfName.COLORSPACE, PdfName.PATTERN}; - - /** Holds value of property parent. */ - protected PdfFormField parent; - - protected ArrayList kids; - -/** - * Constructs a new PdfAnnotation of subtype link (Action). - */ - - public PdfFormField(PdfWriter writer, float llx, float lly, float urx, float ury, PdfAction action) { - super(writer, llx, lly, urx, ury, action); - put(PdfName.TYPE, PdfName.ANNOT); - put(PdfName.SUBTYPE, PdfName.WIDGET); - annotation = true; - } - - /** Creates new PdfFormField */ - protected PdfFormField(PdfWriter writer) { - super(writer, null); - form = true; - annotation = false; - } - - public void setWidget(Rectangle rect, PdfName highlight) { - put(PdfName.TYPE, PdfName.ANNOT); - put(PdfName.SUBTYPE, PdfName.WIDGET); - put(PdfName.RECT, new PdfRectangle(rect)); - annotation = true; - if (highlight != null && !highlight.equals(HIGHLIGHT_INVERT)) - put(PdfName.H, highlight); - } - - public static PdfFormField createEmpty(PdfWriter writer) { - PdfFormField field = new PdfFormField(writer); - return field; - } - - public void setButton(int flags) { - put(PdfName.FT, PdfName.BTN); - if (flags != 0) - put(PdfName.FF, new PdfNumber(flags)); - } - - protected static PdfFormField createButton(PdfWriter writer, int flags) { - PdfFormField field = new PdfFormField(writer); - field.setButton(flags); - return field; - } - - public static PdfFormField createPushButton(PdfWriter writer) { - return createButton(writer, FF_PUSHBUTTON); - } - - public static PdfFormField createCheckBox(PdfWriter writer) { - return createButton(writer, 0); - } - - public static PdfFormField createRadioButton(PdfWriter writer, boolean noToggleToOff) { - return createButton(writer, FF_RADIO + (noToggleToOff ? FF_NO_TOGGLE_TO_OFF : 0)); - } - - public static PdfFormField createTextField(PdfWriter writer, boolean multiline, boolean password, int maxLen) { - PdfFormField field = new PdfFormField(writer); - field.put(PdfName.FT, PdfName.TX); - int flags = (multiline ? FF_MULTILINE : 0); - flags += (password ? FF_PASSWORD : 0); - field.put(PdfName.FF, new PdfNumber(flags)); - if (maxLen > 0) - field.put(PdfName.MAXLEN, new PdfNumber(maxLen)); - return field; - } - - protected static PdfFormField createChoice(PdfWriter writer, int flags, PdfArray options, int topIndex) { - PdfFormField field = new PdfFormField(writer); - field.put(PdfName.FT, PdfName.CH); - field.put(PdfName.FF, new PdfNumber(flags)); - field.put(PdfName.OPT, options); - if (topIndex > 0) - field.put(PdfName.TI, new PdfNumber(topIndex)); - return field; - } - - public static PdfFormField createList(PdfWriter writer, String options[], int topIndex) { - return createChoice(writer, 0, processOptions(options), topIndex); - } - - public static PdfFormField createList(PdfWriter writer, String options[][], int topIndex) { - return createChoice(writer, 0, processOptions(options), topIndex); - } - - public static PdfFormField createCombo(PdfWriter writer, boolean edit, String options[], int topIndex) { - return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), processOptions(options), topIndex); - } - - public static PdfFormField createCombo(PdfWriter writer, boolean edit, String options[][], int topIndex) { - return createChoice(writer, FF_COMBO + (edit ? FF_EDIT : 0), processOptions(options), topIndex); - } - - protected static PdfArray processOptions(String options[]) { - PdfArray array = new PdfArray(); - for (int k = 0; k < options.length; ++k) { - array.add(new PdfString(options[k], PdfObject.TEXT_UNICODE)); - } - return array; - } - - protected static PdfArray processOptions(String options[][]) { - PdfArray array = new PdfArray(); - for (int k = 0; k < options.length; ++k) { - String subOption[] = options[k]; - PdfArray ar2 = new PdfArray(new PdfString(subOption[0], PdfObject.TEXT_UNICODE)); - ar2.add(new PdfString(subOption[1], PdfObject.TEXT_UNICODE)); - array.add(ar2); - } - return array; - } - - public static PdfFormField createSignature(PdfWriter writer) { - PdfFormField field = new PdfFormField(writer); - field.put(PdfName.FT, PdfName.SIG); - return field; - } - - /** Getter for property parent. - * @return Value of property parent. - */ - public PdfFormField getParent() { - return parent; - } - - public void addKid(PdfFormField field) { - field.parent = this; - if (kids == null) - kids = new ArrayList(); - kids.add(field); - } - - ArrayList getKids() { - return kids; - } - - public int setFieldFlags(int flags) { - PdfNumber obj = (PdfNumber)get(PdfName.FF); - int old; - if (obj == null) - old = 0; - else - old = obj.intValue(); - int v = old | flags; - put(PdfName.FF, new PdfNumber(v)); - return old; - } - - public void setValueAsString(String s) { - put(PdfName.V, new PdfString(s, PdfObject.TEXT_UNICODE)); - } - - public void setValueAsName(String s) { - put(PdfName.V, new PdfName(s)); - } - - public void setValue(PdfSignature sig) { - put(PdfName.V, sig); - } - - public void setDefaultValueAsString(String s) { - put(PdfName.DV, new PdfString(s, PdfObject.TEXT_UNICODE)); - } - - public void setDefaultValueAsName(String s) { - put(PdfName.DV, new PdfName(s)); - } - - public void setFieldName(String s) { - if (s != null) - put(PdfName.T, new PdfString(s, PdfObject.TEXT_UNICODE)); - } - - public void setUserName(String s) { - put(PdfName.TU, new PdfString(s, PdfObject.TEXT_UNICODE)); - } - - public void setMappingName(String s) { - put(PdfName.TM, new PdfString(s, PdfObject.TEXT_UNICODE)); - } - - public void setQuadding(int v) { - put(PdfName.Q, new PdfNumber(v)); - } - - static void mergeResources(PdfDictionary result, PdfDictionary source, PdfStamperImp writer) { - PdfDictionary dic = null; - PdfDictionary res = null; - PdfName target = null; - for (int k = 0; k < mergeTarget.length; ++k) { - target = mergeTarget[k]; - PdfDictionary pdfDict = (PdfDictionary)PdfReader.getPdfObject(source.get(target)); - if ((dic = pdfDict) != null) { - if ((res = (PdfDictionary)PdfReader.getPdfObject(result.get(target), result)) == null) { - res = new PdfDictionary(); - } - res.mergeDifferent(dic); - result.put(target, res); - if (writer != null) - writer.markUsed(res); - } - } - } - - static void mergeResources(PdfDictionary result, PdfDictionary source) { - mergeResources(result, source, null); - } - - void setUsed() { - used = true; - if (parent != null) - put(PdfName.PARENT, parent.getIndirectReference()); - if (kids != null) { - PdfArray array = new PdfArray(); - for (int k = 0; k < kids.size(); ++k) - array.add(((PdfFormField)kids.get(k)).getIndirectReference()); - put(PdfName.KIDS, array); - } - if (templates == null) - return; - PdfDictionary dic = new PdfDictionary(); - for (Iterator it = templates.keySet().iterator(); it.hasNext();) { - PdfTemplate template = (PdfTemplate)it.next(); - mergeResources(dic, (PdfDictionary)template.getResources()); - } - put(PdfName.DR, dic); - } - - public static PdfAnnotation shallowDuplicate(PdfAnnotation annot) { - PdfAnnotation dup; - if (annot.isForm()) { - dup = new PdfFormField(annot.writer); - PdfFormField dupField = (PdfFormField)dup; - PdfFormField srcField = (PdfFormField)annot; - dupField.parent = srcField.parent; - dupField.kids = srcField.kids; - } - else - dup = new PdfAnnotation(annot.writer, null); - dup.merge(annot); - dup.form = annot.form; - dup.annotation = annot.annotation; - dup.templates = annot.templates; - return dup; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfFormXObject.java b/src/main/java/com/lowagie/text/pdf/PdfFormXObject.java deleted file mode 100644 index 15f0041..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfFormXObject.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * $Id: PdfFormXObject.java,v 1.58 2005/07/16 16:49:22 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfFormObject is a type of XObject containing a template-object. - */ - -public class PdfFormXObject extends PdfStream { - - // public static final variables - -/** This is a PdfNumber representing 0. */ - public static final PdfNumber ZERO = new PdfNumber(0); - -/** This is a PdfNumber representing 1. */ - public static final PdfNumber ONE = new PdfNumber(1); - -/** This is the 1 - matrix. */ - public static final PdfLiteral MATRIX = new PdfLiteral("[1 0 0 1 0 0]"); - - // membervariables - - - // constructor - -/** - * Constructs a PdfFormXObject-object. - * - * @param template the template - */ - - PdfFormXObject(PdfTemplate template) // throws BadPdfFormatException - { - super(); - put(PdfName.TYPE, PdfName.XOBJECT); - put(PdfName.SUBTYPE, PdfName.FORM); - put(PdfName.RESOURCES, template.getResources()); - put(PdfName.BBOX, new PdfRectangle(template.getBoundingBox())); - put(PdfName.FORMTYPE, ONE); - if (template.getLayer() != null) - put(PdfName.OC, template.getLayer().getRef()); - if (template.getGroup() != null) - put(PdfName.GROUP, template.getGroup()); - PdfArray matrix = template.getMatrix(); - if (matrix == null) - put(PdfName.MATRIX, MATRIX); - else - put(PdfName.MATRIX, matrix); - bytes = template.toPdf(null); - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - flateCompress(); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfFunction.java b/src/main/java/com/lowagie/text/pdf/PdfFunction.java deleted file mode 100644 index 1460ba8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfFunction.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import java.io.IOException; -/** Implements PDF functions. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfFunction { - - protected PdfWriter writer; - - protected PdfIndirectReference reference; - - protected PdfDictionary dictionary; - - /** Creates new PdfFunction */ - protected PdfFunction(PdfWriter writer) { - this.writer = writer; - } - - PdfIndirectReference getReference() { - try { - if (reference == null) { - reference = writer.addToBody(dictionary).getIndirectReference(); - } - } - catch (IOException ioe) { - throw new ExceptionConverter(ioe); - } - return reference; - } - - public static PdfFunction type0(PdfWriter writer, float domain[], float range[], int size[], - int bitsPerSample, int order, float encode[], float decode[], byte stream[]) { - PdfFunction func = new PdfFunction(writer); - func.dictionary = new PdfStream(stream); - ((PdfStream)func.dictionary).flateCompress(); - func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(0)); - func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); - func.dictionary.put(PdfName.RANGE, new PdfArray(range)); - func.dictionary.put(PdfName.SIZE, new PdfArray(size)); - func.dictionary.put(PdfName.BITSPERSAMPLE, new PdfNumber(bitsPerSample)); - if (order != 1) - func.dictionary.put(PdfName.ORDER, new PdfNumber(order)); - if (encode != null) - func.dictionary.put(PdfName.ENCODE, new PdfArray(encode)); - if (decode != null) - func.dictionary.put(PdfName.DECODE, new PdfArray(decode)); - return func; - } - - public static PdfFunction type2(PdfWriter writer, float domain[], float range[], float c0[], float c1[], float n) { - PdfFunction func = new PdfFunction(writer); - func.dictionary = new PdfDictionary(); - func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(2)); - func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); - if (range != null) - func.dictionary.put(PdfName.RANGE, new PdfArray(range)); - if (c0 != null) - func.dictionary.put(PdfName.C0, new PdfArray(c0)); - if (c1 != null) - func.dictionary.put(PdfName.C1, new PdfArray(c1)); - func.dictionary.put(PdfName.N, new PdfNumber(n)); - return func; - } - - public static PdfFunction type3(PdfWriter writer, float domain[], float range[], PdfFunction functions[], float bounds[], float encode[]) { - PdfFunction func = new PdfFunction(writer); - func.dictionary = new PdfDictionary(); - func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(3)); - func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); - if (range != null) - func.dictionary.put(PdfName.RANGE, new PdfArray(range)); - PdfArray array = new PdfArray(); - for (int k = 0; k < functions.length; ++k) - array.add(functions[k].getReference()); - func.dictionary.put(PdfName.FUNCTIONS, array); - func.dictionary.put(PdfName.BOUNDS, new PdfArray(bounds)); - func.dictionary.put(PdfName.ENCODE, new PdfArray(encode)); - return func; - } - - public static PdfFunction type4(PdfWriter writer, float domain[], float range[], String postscript) { - byte b[] = new byte[postscript.length()]; - for (int k = 0; k < b.length; ++k) - b[k] = (byte)postscript.charAt(k); - PdfFunction func = new PdfFunction(writer); - func.dictionary = new PdfStream(b); - ((PdfStream)func.dictionary).flateCompress(); - func.dictionary.put(PdfName.FUNCTIONTYPE, new PdfNumber(4)); - func.dictionary.put(PdfName.DOMAIN, new PdfArray(domain)); - func.dictionary.put(PdfName.RANGE, new PdfArray(range)); - return func; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfGState.java b/src/main/java/com/lowagie/text/pdf/PdfGState.java deleted file mode 100644 index 6ea1ebc..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfGState.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** The graphic state dictionary. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfGState extends PdfDictionary { - /** A possible blend mode */ - public static final PdfName BM_NORMAL = new PdfName("Normal"); - /** A possible blend mode */ - public static final PdfName BM_COMPATIBLE = new PdfName("Compatible"); - /** A possible blend mode */ - public static final PdfName BM_MULTIPLY = new PdfName("Multiply"); - /** A possible blend mode */ - public static final PdfName BM_SCREEN = new PdfName("Screen"); - /** A possible blend mode */ - public static final PdfName BM_OVERLAY = new PdfName("Overlay"); - /** A possible blend mode */ - public static final PdfName BM_DARKEN = new PdfName("Darken"); - /** A possible blend mode */ - public static final PdfName BM_LIGHTEN = new PdfName("Lighten"); - /** A possible blend mode */ - public static final PdfName BM_COLORDODGE = new PdfName("ColorDodge"); - /** A possible blend mode */ - public static final PdfName BM_COLORBURN = new PdfName("ColorBurn"); - /** A possible blend mode */ - public static final PdfName BM_HARDLIGHT = new PdfName("HardLight"); - /** A possible blend mode */ - public static final PdfName BM_SOFTLIGHT = new PdfName("SoftLight"); - /** A possible blend mode */ - public static final PdfName BM_DIFFERENCE = new PdfName("Difference"); - /** A possible blend mode */ - public static final PdfName BM_EXCLUSION = new PdfName("Exclusion"); - - /** - * Sets the flag whether to apply overprint for stroking. - * @param ov - */ - public void setOverPrintStroking(boolean ov) { - put(PdfName.OP, ov ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - } - - /** - * Sets the flag whether to apply overprint for non stroking painting operations. - * @param ov - */ - public void setOverPrintNonStroking(boolean ov) { - put(PdfName.op, ov ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - } - - /** - * Sets the current stroking alpha constant, specifying the constant shape or - * constant opacity value to be used for stroking operations in the transparent - * imaging model. - * @param n - */ - public void setStrokeOpacity(float n) { - put(PdfName.CA, new PdfNumber(n)); - } - - /** - * Sets the current stroking alpha constant, specifying the constant shape or - * constant opacity value to be used for nonstroking operations in the transparent - * imaging model. - * @param n - */ - public void setFillOpacity(float n) { - put(PdfName.ca, new PdfNumber(n)); - } - - /** - * The alpha source flag specifying whether the current soft mask - * and alpha constant are to be interpreted as shape values (true) - * or opacity values (false). - * @param v - */ - public void setAlphaIsShape(boolean v) { - put(PdfName.AIS, v ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - } - - /** - * Determines the behaviour of overlapping glyphs within a text object - * in the transparent imaging model. - * @param v - */ - public void setTextKnockout(boolean v) { - put(PdfName.TK, v ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - } - - /** - * The current blend mode to be used in the transparent imaging model. - * @param bm - */ - public void setBlendMode(PdfName bm) { - put(PdfName.BM, bm); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfGraphics2D.java b/src/main/java/com/lowagie/text/pdf/PdfGraphics2D.java deleted file mode 100644 index 962b502..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfGraphics2D.java +++ /dev/null @@ -1,1450 +0,0 @@ -/* - * Copyright 2002 by Jim Moore . - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Component; -import java.awt.Composite; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GraphicsConfiguration; -import java.awt.Image; -import java.awt.Paint; -import java.awt.GradientPaint; -import java.awt.TexturePaint; -import java.awt.MediaTracker; -import java.awt.Polygon; -import java.awt.Rectangle; -import java.awt.RenderingHints; -import java.awt.Shape; -import java.awt.Stroke; -import java.awt.Transparency; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.TextLayout; -import java.awt.geom.AffineTransform; -import java.awt.geom.Arc2D; -import java.awt.geom.Area; -import java.awt.geom.Ellipse2D; -import java.awt.geom.Line2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Rectangle2D; -import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.BufferedImageOp; -import java.awt.image.ColorModel; -import java.awt.image.ImageObserver; -import java.awt.image.RenderedImage; -import java.awt.image.WritableRaster; -import java.awt.image.renderable.RenderableImage; -import java.awt.RenderingHints.Key; -import java.awt.geom.NoninvertibleTransformException; -import java.awt.geom.Point2D; -import java.text.AttributedCharacterIterator; -import java.util.Map; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.ArrayList; -import java.io.ByteArrayOutputStream; -// -import java.util.Set; -import java.util.Iterator; -import java.awt.font.TextAttribute; - -public class PdfGraphics2D extends Graphics2D { - - private static final int FILL = 1; - private static final int STROKE = 2; - private static final int CLIP = 3; - private BasicStroke strokeOne = new BasicStroke(1); - - private static AffineTransform IDENTITY = new AffineTransform(); - - private Font font; - private BaseFont baseFont; - private float fontSize; - private AffineTransform transform; - private Paint paint; - private Color background; - private float width; - private float height; - - private Area clip; - - private RenderingHints rhints = new RenderingHints(null); - - private Stroke stroke; - private Stroke originalStroke; - - private PdfContentByte cb; - - /** Storage for BaseFont objects created. */ - private HashMap baseFonts; - - private boolean disposeCalled = false; - - private FontMapper fontMapper; - - private ArrayList kids; - - private boolean kid = false; - - private Graphics2D dg2 = new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB).createGraphics(); - - private boolean onlyShapes = false; - - private Stroke oldStroke; - private Paint paintFill; - private Paint paintStroke; - - private MediaTracker mediaTracker; - - // Added by Jurij Bilas - protected boolean underline; // indicates if the font style is underlined - - protected PdfGState fillGState[] = new PdfGState[256]; - protected PdfGState strokeGState[] = new PdfGState[256]; - protected int currentFillGState = 255; - protected int currentStrokeGState = 255; - - public static int AFM_DIVISOR = 1000; // used to calculate coordinates - - private boolean convertImagesToJPEG = false; - private float jpegQuality = .95f; - - private PdfGraphics2D() { - dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - } - - /** - * Constructor for PDFGraphics2D. - * - */ - PdfGraphics2D(PdfContentByte cb, float width, float height, FontMapper fontMapper, boolean onlyShapes, boolean convertImagesToJPEG, float quality) { - super(); - dg2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); - try { - Class.forName("com.sun.image.codec.jpeg.JPEGCodec"); - } - catch (Throwable t) { - convertImagesToJPEG = false; - } - this.convertImagesToJPEG = convertImagesToJPEG; - this.jpegQuality = quality; - this.onlyShapes = onlyShapes; - this.transform = new AffineTransform(); - this.baseFonts = new HashMap(); - if (!onlyShapes) { - this.fontMapper = fontMapper; - if (this.fontMapper == null) - this.fontMapper = new DefaultFontMapper(); - } - this.kids = new ArrayList(); - paint = Color.black; - background = Color.white; - setFont(new Font("sanserif", Font.PLAIN, 12)); - this.cb = cb; - cb.saveState(); - this.width = width; - this.height = height; - clip = new Area(new Rectangle2D.Float(0, 0, width, height)); - clip(clip); - originalStroke = stroke = oldStroke = strokeOne; - setStrokeDiff(stroke, null); - cb.saveState(); - } - - /** - * @see Graphics2D#draw(Shape) - */ - public void draw(Shape s) { - followPath(s, STROKE); - } - - /** - * @see Graphics2D#drawImage(Image, AffineTransform, ImageObserver) - */ - public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - return drawImage(img, null, xform, null, obs); - } - - /** - * @see Graphics2D#drawImage(BufferedImage, BufferedImageOp, int, int) - */ - public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) { - BufferedImage result = img; - if (op != null) { - result = op.createCompatibleDestImage(img, img.getColorModel()); - result = op.filter(img, result); - } - drawImage(result, x, y, null); - } - - /** - * @see Graphics2D#drawRenderedImage(RenderedImage, AffineTransform) - */ - public void drawRenderedImage(RenderedImage img, AffineTransform xform) { - BufferedImage image = null; - if (img instanceof BufferedImage) { - image = (BufferedImage)img; - } else { - ColorModel cm = img.getColorModel(); - int width = img.getWidth(); - int height = img.getHeight(); - WritableRaster raster = cm.createCompatibleWritableRaster(width, height); - boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); - Hashtable properties = new Hashtable(); - String[] keys = img.getPropertyNames(); - if (keys!=null) { - for (int i = 0; i < keys.length; i++) { - properties.put(keys[i], img.getProperty(keys[i])); - } - } - BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties); - img.copyData(raster); - image=result; - } - drawImage(image, xform, null); - } - - /** - * @see Graphics2D#drawRenderableImage(RenderableImage, AffineTransform) - */ - public void drawRenderableImage(RenderableImage img, AffineTransform xform) { - drawRenderedImage(img.createDefaultRendering(), xform); - } - - /** - * @see Graphics#drawString(String, int, int) - */ - public void drawString(String s, int x, int y) { - drawString(s, (float)x, (float)y); - } - - /** - * Calculates position and/or stroke thickness depending on the font size - * @param d value to be converted - * @param i font size - * @return position and/or stroke thickness depending on the font size - */ - public static double asPoints(double d, int i) { - return (d * (double)i) / (double)AFM_DIVISOR; - } - /** - * This routine goes through the attributes and sets the font - * before calling the actual string drawing routine - * @param iter - */ - protected void doAttributes(AttributedCharacterIterator iter) { - underline = false; - Set set = iter.getAttributes().keySet(); - for(Iterator iterator = set.iterator(); iterator.hasNext();) { - AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute)iterator.next(); - if (!(attribute instanceof TextAttribute)) - continue; - TextAttribute textattribute = (TextAttribute)attribute; - if(textattribute.equals(TextAttribute.FONT)) { - Font font = (Font)iter.getAttributes().get(textattribute); - setFont(font); - } - else if(textattribute.equals(TextAttribute.UNDERLINE)) { - if(iter.getAttributes().get(textattribute) == TextAttribute.UNDERLINE_ON) - underline = true; - } - else if(textattribute.equals(TextAttribute.SUPERSCRIPT)) { - throw new RuntimeException("TextAttribute.SUPERSCRIPT not supported"); - /* - iter.getAttributes().get(textattribute); - Integer _tmp = TextAttribute.SUPERSCRIPT_SUPER; - subscript = true; - */ - } - else if(textattribute.equals(TextAttribute.SIZE)) { - Object obj = iter.getAttributes().get(textattribute); - Font font1 = null; - if(obj instanceof Integer) { - int i = ((Integer)obj).intValue(); - font1 = getFont().deriveFont(getFont().getStyle(), i); - } - else if(obj instanceof Float) { - float f = ((Float)obj).floatValue(); - font1 = getFont().deriveFont(getFont().getStyle(), f); - } - else { - throw new RuntimeException("Unknown type " + obj.getClass() + " for attribute SIZE"); - } - setFont(font1); - } - else if(textattribute.equals(TextAttribute.FOREGROUND)) { - setColor((Color) iter.getAttributes().get(textattribute)); - } - else if(textattribute.equals(TextAttribute.BACKGROUND)) { - throw new RuntimeException("Background color not supported"); - } - else { - throw new RuntimeException("Unknown TextAttribute: " + textattribute); - } - } - } - - /** - * @see Graphics2D#drawString(String, float, float) - */ - public void drawString(String s, float x, float y) { - if (s.length() == 0) - return; - setFillPaint(); - if (onlyShapes) { -// TextLayout tl = new TextLayout(s, this.font, new FontRenderContext(new AffineTransform(), false, true)); -// tl.draw(this, x, y); - drawGlyphVector(this.font.layoutGlyphVector(new FontRenderContext(new AffineTransform(), true, false), s.toCharArray(), 0, s.length(), java.awt.Font.LAYOUT_LEFT_TO_RIGHT), x, y); -// Use the following line to compile in JDK 1.3 -// drawGlyphVector(this.font.createGlyphVector(new FontRenderContext(new AffineTransform(), true, false), s), x, y); - } - else { - AffineTransform at = getTransform(); - AffineTransform at2 = getTransform(); - at2.translate(x, y); - at2.concatenate(font.getTransform()); - setTransform(at2); - AffineTransform inverse = this.normalizeMatrix(); - AffineTransform flipper = AffineTransform.getScaleInstance(1,-1); - inverse.concatenate(flipper); - double[] mx = new double[6]; - inverse.getMatrix(mx); - cb.beginText(); - cb.setFontAndSize(baseFont, fontSize); - cb.setTextMatrix((float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]); - double width = 0; - if (font.getSize2D() > 0) { - float scale = 1000 / font.getSize2D(); - width = font.deriveFont(AffineTransform.getScaleInstance(scale, scale)).getStringBounds(s, getFontRenderContext()).getWidth() / scale; - } - if (s.length() > 1) { - float adv = ((float)width - baseFont.getWidthPoint(s, fontSize)) / (s.length() - 1); - cb.setCharacterSpacing(adv); - } - cb.showText(s); - if (s.length() > 1) { - cb.setCharacterSpacing(0); - } - cb.endText(); - setTransform(at); - if(underline) - { - // These two are supposed to be taken from the .AFM file - //int UnderlinePosition = -100; - int UnderlineThickness = 50; - // - double d = asPoints((double)UnderlineThickness, (int)fontSize); - setStroke(new BasicStroke((float)d)); - y = (float)((double)(y) + asPoints((double)(UnderlineThickness), (int)fontSize)); - Line2D line = new Line2D.Double((double)x, (double)y, (double)(width+x), (double)y); - draw(line); - } - } - } - - /** - * @see Graphics#drawString(AttributedCharacterIterator, int, int) - */ - public void drawString(AttributedCharacterIterator iterator, int x, int y) { - drawString(iterator, (float)x, (float)y); - } - - /** - * @see Graphics2D#drawString(AttributedCharacterIterator, float, float) - */ - public void drawString(AttributedCharacterIterator iter, float x, float y) { -/* - StringBuffer sb = new StringBuffer(); - for(char c = iter.first(); c != AttributedCharacterIterator.DONE; c = iter.next()) { - sb.append(c); - } - drawString(sb.toString(),x,y); -*/ - StringBuffer stringbuffer = new StringBuffer(iter.getEndIndex()); - for(char c = iter.first(); c != '\uFFFF'; c = iter.next()) - { - if(iter.getIndex() == iter.getRunStart()) - { - if(stringbuffer.length() > 0) - { - drawString(stringbuffer.toString(), x, y); - FontMetrics fontmetrics = getFontMetrics(); - x = (float)((double)x + fontmetrics.getStringBounds(stringbuffer.toString(), this).getWidth()); - stringbuffer.delete(0, stringbuffer.length()); - } - doAttributes(iter); - } - stringbuffer.append(c); - } - - drawString(stringbuffer.toString(), x, y); - underline = false; - } - - /** - * @see Graphics2D#drawGlyphVector(GlyphVector, float, float) - */ - public void drawGlyphVector(GlyphVector g, float x, float y) { - Shape s = g.getOutline(x, y); - fill(s); - } - - /** - * @see Graphics2D#fill(Shape) - */ - public void fill(Shape s) { - followPath(s, FILL); - } - - /** - * @see Graphics2D#hit(Rectangle, Shape, boolean) - */ - public boolean hit(Rectangle rect, Shape s, boolean onStroke) { - if (onStroke) { - s = stroke.createStrokedShape(s); - } - s = transform.createTransformedShape(s); - Area area = new Area(s); - if (clip != null) - area.intersect(clip); - return area.intersects(rect.x, rect.y, rect.width, rect.height); - } - - /** - * @see Graphics2D#getDeviceConfiguration() - */ - public GraphicsConfiguration getDeviceConfiguration() { - return dg2.getDeviceConfiguration(); - } - - /** - * @see Graphics2D#setComposite(Composite) - */ - public void setComposite(Composite comp) { - - } - - /** - * @see Graphics2D#setPaint(Paint) - */ - public void setPaint(Paint paint) { - if (paint == null) - return; - this.paint = paint; -// setPaint(paint, false, 0, 0); - } - - private Stroke transformStroke(Stroke stroke) { - if (!(stroke instanceof BasicStroke)) - return stroke; - BasicStroke st = (BasicStroke)stroke; - float scale = (float)Math.sqrt(Math.abs(transform.getDeterminant())); - float dash[] = st.getDashArray(); - if (dash != null) { - for (int k = 0; k < dash.length; ++k) - dash[k] *= scale; - } - return new BasicStroke(st.getLineWidth() * scale, st.getEndCap(), st.getLineJoin(), st.getMiterLimit(), dash, st.getDashPhase() * scale); - } - - private void setStrokeDiff(Stroke newStroke, Stroke oldStroke) { - if (newStroke == oldStroke) - return; - if (!(newStroke instanceof BasicStroke)) - return; - BasicStroke nStroke = (BasicStroke)newStroke; - boolean oldOk = (oldStroke instanceof BasicStroke); - BasicStroke oStroke = null; - if (oldOk) - oStroke = (BasicStroke)oldStroke; - if (!oldOk || nStroke.getLineWidth() != oStroke.getLineWidth()) - cb.setLineWidth(nStroke.getLineWidth()); - if (!oldOk || nStroke.getEndCap() != oStroke.getEndCap()) { - switch (nStroke.getEndCap()) { - case BasicStroke.CAP_BUTT: - cb.setLineCap(0); - break; - case BasicStroke.CAP_SQUARE: - cb.setLineCap(2); - break; - default: - cb.setLineCap(1); - } - } - if (!oldOk || nStroke.getLineJoin() != oStroke.getLineJoin()) { - switch (nStroke.getLineJoin()) { - case BasicStroke.JOIN_MITER: - cb.setLineJoin(0); - break; - case BasicStroke.JOIN_BEVEL: - cb.setLineJoin(2); - break; - default: - cb.setLineJoin(1); - } - } - if (!oldOk || nStroke.getMiterLimit() != oStroke.getMiterLimit()) - cb.setMiterLimit(nStroke.getMiterLimit()); - boolean makeDash; - if (oldOk) { - if (nStroke.getDashArray() != null) { - if (nStroke.getDashPhase() != oStroke.getDashPhase()) { - makeDash = true; - } - else if (!java.util.Arrays.equals(nStroke.getDashArray(), oStroke.getDashArray())) { - makeDash = true; - } - else - makeDash = false; - } - else if (oStroke.getDashArray() != null) { - makeDash = true; - } - else - makeDash = false; - } - else { - makeDash = true; - } - if (makeDash) { - float dash[] = nStroke.getDashArray(); - if (dash == null) - cb.setLiteral("[]0 d\n"); - else { - cb.setLiteral('['); - int lim = dash.length; - for (int k = 0; k < lim; ++k) { - cb.setLiteral(dash[k]); - cb.setLiteral(' '); - } - cb.setLiteral(']'); - cb.setLiteral(nStroke.getDashPhase()); - cb.setLiteral(" d\n"); - } - } - } - - /** - * @see Graphics2D#setStroke(Stroke) - */ - public void setStroke(Stroke s) { - originalStroke = s; - this.stroke = transformStroke(s); - } - - - /** - * Sets a rendering hint - * @param arg0 - * @param arg1 - */ - public void setRenderingHint(Key arg0, Object arg1) { - rhints.put(arg0, arg1); - } - - /** - * @param arg0 a key - * @return the rendering hint - */ - public Object getRenderingHint(Key arg0) { - return rhints.get(arg0); - } - - /** - * @see Graphics2D#setRenderingHints(Map) - */ - public void setRenderingHints(Map hints) { - rhints.clear(); - rhints.putAll(hints); - } - - /** - * @see Graphics2D#addRenderingHints(Map) - */ - public void addRenderingHints(Map hints) { - rhints.putAll(hints); - } - - /** - * @see Graphics2D#getRenderingHints() - */ - public RenderingHints getRenderingHints() { - return rhints; - } - - /** - * @see Graphics#translate(int, int) - */ - public void translate(int x, int y) { - translate((double)x, (double)y); - } - - /** - * @see Graphics2D#translate(double, double) - */ - public void translate(double tx, double ty) { - transform.translate(tx,ty); - } - - /** - * @see Graphics2D#rotate(double) - */ - public void rotate(double theta) { - transform.rotate(theta); - } - - /** - * @see Graphics2D#rotate(double, double, double) - */ - public void rotate(double theta, double x, double y) { - transform.rotate(theta, x, y); - } - - /** - * @see Graphics2D#scale(double, double) - */ - public void scale(double sx, double sy) { - transform.scale(sx, sy); - this.stroke = transformStroke(originalStroke); - } - - /** - * @see Graphics2D#shear(double, double) - */ - public void shear(double shx, double shy) { - transform.shear(shx, shy); - } - - /** - * @see Graphics2D#transform(AffineTransform) - */ - public void transform(AffineTransform tx) { - transform.concatenate(tx); - this.stroke = transformStroke(originalStroke); - } - - /** - * @see Graphics2D#setTransform(AffineTransform) - */ - public void setTransform(AffineTransform t) { - transform = new AffineTransform(t); - this.stroke = transformStroke(originalStroke); - } - - /** - * @see Graphics2D#getTransform() - */ - public AffineTransform getTransform() { - return new AffineTransform(transform); - } - - /** - * @see Graphics2D#getPaint() - */ - public Paint getPaint() { - return paint; - } - - /** - * @see Graphics2D#getComposite() - */ - public Composite getComposite() { - return null; - } - - /** - * @see Graphics2D#setBackground(Color) - */ - public void setBackground(Color color) { - background = color; - } - - /** - * @see Graphics2D#getBackground() - */ - public Color getBackground() { - return background; - } - - /** - * @see Graphics2D#getStroke() - */ - public Stroke getStroke() { - return originalStroke; - } - - - /** - * @see Graphics2D#getFontRenderContext() - */ - public FontRenderContext getFontRenderContext() { - return new FontRenderContext(null, true, true); - } - - /** - * @see Graphics#create() - */ - public Graphics create() { - PdfGraphics2D g2 = new PdfGraphics2D(); - g2.onlyShapes = this.onlyShapes; - g2.transform = new AffineTransform(this.transform); - g2.baseFonts = this.baseFonts; - g2.fontMapper = this.fontMapper; - g2.kids = this.kids; - g2.paint = this.paint; - g2.fillGState = this.fillGState; - g2.strokeGState = this.strokeGState; - g2.background = this.background; - g2.mediaTracker = this.mediaTracker; - g2.convertImagesToJPEG = this.convertImagesToJPEG; - g2.jpegQuality = this.jpegQuality; - g2.setFont(this.font); - g2.cb = this.cb.getDuplicate(); - g2.cb.saveState(); - g2.width = this.width; - g2.height = this.height; - g2.followPath(new Area(new Rectangle2D.Float(0, 0, width, height)), CLIP); - if (this.clip != null) - g2.clip = new Area(this.clip); - g2.stroke = stroke; - g2.originalStroke = originalStroke; - g2.strokeOne = (BasicStroke)g2.transformStroke(g2.strokeOne); - g2.oldStroke = g2.strokeOne; - g2.setStrokeDiff(g2.oldStroke, null); - g2.cb.saveState(); - if (g2.clip != null) - g2.followPath(g2.clip, CLIP); - g2.kid = true; - synchronized (kids) { - kids.add(g2); - } - return g2; - } - - public PdfContentByte getContent() { - return this.cb; - } - /** - * @see Graphics#getColor() - */ - public Color getColor() { - if (paint instanceof Color) { - return (Color)paint; - } else { - return Color.black; - } - } - - /** - * @see Graphics#setColor(Color) - */ - public void setColor(Color color) { - setPaint(color); - } - - /** - * @see Graphics#setPaintMode() - */ - public void setPaintMode() {} - - /** - * @see Graphics#setXORMode(Color) - */ - public void setXORMode(Color c1) { - - } - - /** - * @see Graphics#getFont() - */ - public Font getFont() { - return font; - } - - /** - * @see Graphics#setFont(Font) - */ - /** - * Sets the current font. - */ - public void setFont(Font f) { - if (f == null) - return; - if (onlyShapes) { - font = f; - return; - } - if (f == font) - return; - font = f; - fontSize = f.getSize2D(); - baseFont = getCachedBaseFont(f); - } - - private BaseFont getCachedBaseFont(Font f) { - synchronized (baseFonts) { - BaseFont bf = (BaseFont)baseFonts.get(f.getFontName()); - if (bf == null) { - bf = fontMapper.awtToPdf(f); - baseFonts.put(f.getFontName(), bf); - } - return bf; - } - } - - /** - * @see Graphics#getFontMetrics(Font) - */ - public FontMetrics getFontMetrics(Font f) { - return dg2.getFontMetrics(f); - } - - /** - * @see Graphics#getClipBounds() - */ - public Rectangle getClipBounds() { - if (clip == null) - return null; - return getClip().getBounds(); - } - - /** - * @see Graphics#clipRect(int, int, int, int) - */ - public void clipRect(int x, int y, int width, int height) { - Rectangle2D rect = new Rectangle2D.Double(x,y,width,height); - clip(rect); - } - - /** - * @see Graphics#setClip(int, int, int, int) - */ - public void setClip(int x, int y, int width, int height) { - Rectangle2D rect = new Rectangle2D.Double(x,y,width,height); - setClip(rect); - } - - /** - * @see Graphics2D#clip(Shape) - */ - public void clip(Shape s) { - if (s != null) - s = transform.createTransformedShape(s); - if (clip == null) - clip = new Area(s); - else - clip.intersect(new Area(s)); - followPath(s, CLIP); - } - - /** - * @see Graphics#getClip() - */ - public Shape getClip() { - try { - return transform.createInverse().createTransformedShape(clip); - } - catch (NoninvertibleTransformException e) { - return null; - } - } - - /** - * @see Graphics#setClip(Shape) - */ - public void setClip(Shape s) { - cb.restoreState(); - cb.saveState(); - if (s != null) - s = transform.createTransformedShape(s); - if (s == null) { - clip = null; - } - else { - clip = new Area(s); - followPath(s, CLIP); - } - paintFill = paintStroke = null; - currentFillGState = currentStrokeGState = 255; - oldStroke = strokeOne; - } - - /** - * @see Graphics#copyArea(int, int, int, int, int, int) - */ - public void copyArea(int x, int y, int width, int height, int dx, int dy) { - - } - - /** - * @see Graphics#drawLine(int, int, int, int) - */ - public void drawLine(int x1, int y1, int x2, int y2) { - Line2D line = new Line2D.Double((double)x1, (double)y1, (double)x2, (double)y2); - draw(line); - } - - /** - * @see Graphics#fillRect(int, int, int, int) - */ - public void drawRect(int x, int y, int width, int height) { - draw(new Rectangle(x, y, width, height)); - } - - /** - * @see Graphics#fillRect(int, int, int, int) - */ - public void fillRect(int x, int y, int width, int height) { - fill(new Rectangle(x,y,width,height)); - } - - /** - * @see Graphics#clearRect(int, int, int, int) - */ - public void clearRect(int x, int y, int width, int height) { - Paint temp = paint; - setPaint(background); - fillRect(x,y,width,height); - setPaint(temp); - } - - /** - * @see Graphics#drawRoundRect(int, int, int, int, int, int) - */ - public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - RoundRectangle2D rect = new RoundRectangle2D.Double(x,y,width,height,arcWidth, arcHeight); - draw(rect); - } - - /** - * @see Graphics#fillRoundRect(int, int, int, int, int, int) - */ - public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) { - RoundRectangle2D rect = new RoundRectangle2D.Double(x,y,width,height,arcWidth, arcHeight); - fill(rect); - } - - /** - * @see Graphics#drawOval(int, int, int, int) - */ - public void drawOval(int x, int y, int width, int height) { - Ellipse2D oval = new Ellipse2D.Float((float)x, (float)y, (float)width, (float)height); - draw(oval); - } - - /** - * @see Graphics#fillOval(int, int, int, int) - */ - public void fillOval(int x, int y, int width, int height) { - Ellipse2D oval = new Ellipse2D.Float((float)x, (float)y, (float)width, (float)height); - fill(oval); - } - - /** - * @see Graphics#drawArc(int, int, int, int, int, int) - */ - public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - Arc2D arc = new Arc2D.Double(x,y,width,height,startAngle, arcAngle, Arc2D.OPEN); - draw(arc); - - } - - /** - * @see Graphics#fillArc(int, int, int, int, int, int) - */ - public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - Arc2D arc = new Arc2D.Double(x,y,width,height,startAngle, arcAngle, Arc2D.PIE); - fill(arc); - } - - /** - * @see Graphics#drawPolyline(int[], int[], int) - */ - public void drawPolyline(int[] x, int[] y, int nPoints) { - Line2D line = new Line2D.Double(x[0],y[0],x[0],y[0]); - for (int i = 1; i < nPoints; i++) { - line.setLine(line.getX2(), line.getY2(), x[i], y[i]); - draw(line); - } - } - - /** - * @see Graphics#drawPolygon(int[], int[], int) - */ - public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) { - Polygon poly = new Polygon(); - for (int i = 0; i < nPoints; i++) { - poly.addPoint(xPoints[i], yPoints[i]); - } - draw(poly); - } - - /** - * @see Graphics#fillPolygon(int[], int[], int) - */ - public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { - Polygon poly = new Polygon(); - for (int i = 0; i < nPoints; i++) { - poly.addPoint(xPoints[i], yPoints[i]); - } - fill(poly); - } - - /** - * @see Graphics#drawImage(Image, int, int, ImageObserver) - */ - public boolean drawImage(Image img, int x, int y, ImageObserver observer) { - return drawImage(img, x, y, null, observer); - } - - /** - * @see Graphics#drawImage(Image, int, int, int, int, ImageObserver) - */ - public boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) { - return drawImage(img, x, y, width, height, null, observer); - } - - /** - * @see Graphics#drawImage(Image, int, int, Color, ImageObserver) - */ - public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) { - waitForImage(img); - return drawImage(img, x, y, img.getWidth(observer), img.getHeight(observer), bgcolor, observer); - } - - /** - * @see Graphics#drawImage(Image, int, int, int, int, Color, ImageObserver) - */ - public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) { - waitForImage(img); - double scalex = width/(double)img.getWidth(observer); - double scaley = height/(double)img.getHeight(observer); - AffineTransform tx = AffineTransform.getTranslateInstance(x,y); - tx.scale(scalex,scaley); - return drawImage(img, null, tx, bgcolor, observer); - } - - /** - * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, ImageObserver) - */ - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) { - return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, observer); - } - - /** - * @see Graphics#drawImage(Image, int, int, int, int, int, int, int, int, Color, ImageObserver) - */ - public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) { - waitForImage(img); - double dwidth = (double)dx2-dx1; - double dheight = (double)dy2-dy1; - double swidth = (double)sx2-sx1; - double sheight = (double)sy2-sy1; - - //if either width or height is 0, then there is nothing to draw - if (dwidth == 0 || dheight == 0 || swidth == 0 || sheight == 0) return true; - - double scalex = dwidth/swidth; - double scaley = dheight/sheight; - - double transx = sx1*scalex; - double transy = sy1*scaley; - AffineTransform tx = AffineTransform.getTranslateInstance(dx1-transx,dy1-transy); - tx.scale(scalex,scaley); - - BufferedImage mask = new BufferedImage(img.getWidth(observer), img.getHeight(observer), BufferedImage.TYPE_BYTE_BINARY); - Graphics g = mask.getGraphics(); - g.fillRect(sx1,sy1, (int)swidth, (int)sheight); - drawImage(img, mask, tx, null, observer); - g.dispose(); - return true; - } - - /** - * @see Graphics#dispose() - */ - public void dispose() { - if (kid) - return; - if (!disposeCalled) { - disposeCalled = true; - cb.restoreState(); - cb.restoreState(); - for (int k = 0; k < kids.size(); ++k) { - PdfGraphics2D g2 = (PdfGraphics2D)kids.get(k); - g2.cb.restoreState(); - g2.cb.restoreState(); - cb.add(g2.cb); - g2.dg2.dispose(); - g2.dg2 = null; - } - dg2.dispose(); - dg2 = null; - } - } - - /////////////////////////////////////////////// - // - // - // implementation specific methods - // - // - - - private void followPath(Shape s, int drawType) { - if (s==null) return; - if (drawType==STROKE) { - if (!(stroke instanceof BasicStroke)) { - s = stroke.createStrokedShape(s); - followPath(s, FILL); - return; - } - } - if (drawType==STROKE) { - setStrokeDiff(stroke, oldStroke); - oldStroke = stroke; - setStrokePaint(); - } - else if (drawType==FILL) - setFillPaint(); - PathIterator points; - int traces = 0; - if (drawType == CLIP) - points = s.getPathIterator(IDENTITY); - else - points = s.getPathIterator(transform); - float[] coords = new float[6]; - while(!points.isDone()) { - ++traces; - int segtype = points.currentSegment(coords); - normalizeY(coords); - switch(segtype) { - case PathIterator.SEG_CLOSE: - cb.closePath(); - break; - - case PathIterator.SEG_CUBICTO: - cb.curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]); - break; - - case PathIterator.SEG_LINETO: - cb.lineTo(coords[0], coords[1]); - break; - - case PathIterator.SEG_MOVETO: - cb.moveTo(coords[0], coords[1]); - break; - - case PathIterator.SEG_QUADTO: - cb.curveTo(coords[0], coords[1], coords[2], coords[3]); - break; - } - points.next(); - } - switch (drawType) { - case FILL: - if (traces > 0) { - if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) - cb.eoFill(); - else - cb.fill(); - } - break; - case STROKE: - if (traces > 0) - cb.stroke(); - break; - default: //drawType==CLIP - if (traces == 0) - cb.rectangle(0, 0, 0, 0); - if (points.getWindingRule() == PathIterator.WIND_EVEN_ODD) - cb.eoClip(); - else - cb.clip(); - cb.newPath(); - } - } - - private float normalizeY(float y) { - return this.height - y; - } - - private void normalizeY(float[] coords) { - coords[1] = normalizeY(coords[1]); - coords[3] = normalizeY(coords[3]); - coords[5] = normalizeY(coords[5]); - } - - private AffineTransform normalizeMatrix() { - double[] mx = new double[6]; - AffineTransform result = AffineTransform.getTranslateInstance(0,0); - result.getMatrix(mx); - mx[3]=-1; - mx[5]=height; - result = new AffineTransform(mx); - result.concatenate(transform); - return result; - } - - private boolean drawImage(Image img, Image mask, AffineTransform xform, Color bgColor, ImageObserver obs) { - if (xform==null) return true; - - xform.translate(0, img.getHeight(obs)); - xform.scale(img.getWidth(obs), img.getHeight(obs)); - - AffineTransform inverse = this.normalizeMatrix(); - AffineTransform flipper = AffineTransform.getScaleInstance(1,-1); - inverse.concatenate(xform); - inverse.concatenate(flipper); - - double[] mx = new double[6]; - inverse.getMatrix(mx); - if (currentFillGState != 255) { - PdfGState gs = fillGState[255]; - if (gs == null) { - gs = new PdfGState(); - gs.setFillOpacity(1); - fillGState[255] = gs; - } - cb.setGState(gs); - } - - try { - com.lowagie.text.Image image = null; - if(!convertImagesToJPEG){ - image = com.lowagie.text.Image.getInstance(img, bgColor); - } - else{ - BufferedImage scaled = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); - Graphics2D g3 = scaled.createGraphics(); - g3.drawImage(img, 0, 0, img.getWidth(null), img.getHeight(null), null); - g3.dispose(); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - com.sun.image.codec.jpeg.JPEGImageEncoder encoder = com.sun.image.codec.jpeg.JPEGCodec.createJPEGEncoder(baos); - com.sun.image.codec.jpeg.JPEGEncodeParam param = com.sun.image.codec.jpeg.JPEGCodec.getDefaultJPEGEncodeParam(scaled); - param.setQuality(jpegQuality, true); - encoder.encode(scaled, param); - scaled.flush(); - scaled = null; - image = com.lowagie.text.Image.getInstance(baos.toByteArray()); - - } - if (mask!=null) { - com.lowagie.text.Image msk = com.lowagie.text.Image.getInstance(mask, null, true); - msk.makeMask(); - msk.setInvertMask(true); - image.setImageMask(msk); - } - cb.addImage(image, (float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]); - } catch (Exception ex) { - throw new IllegalArgumentException(); - } - if (currentFillGState != 255) { - PdfGState gs = fillGState[currentFillGState]; - cb.setGState(gs); - } - return true; - } - - private boolean checkNewPaint(Paint oldPaint) { - if (paint == oldPaint) - return false; - return !((paint instanceof Color) && paint.equals(oldPaint)); - } - - private void setFillPaint() { - if (checkNewPaint(paintFill)) { - paintFill = paint; - setPaint(false, 0, 0, true); - } - } - - private void setStrokePaint() { - if (checkNewPaint(paintStroke)) { - paintStroke = paint; - setPaint(false, 0, 0, false); - } - } - - private void setPaint(boolean invert, double xoffset, double yoffset, boolean fill) { - if (paint instanceof Color) { - Color color = (Color)paint; - int alpha = color.getAlpha(); - if (fill) { - if (alpha != currentFillGState) { - currentFillGState = alpha; - PdfGState gs = fillGState[alpha]; - if (gs == null) { - gs = new PdfGState(); - gs.setFillOpacity((float)alpha / 255f); - fillGState[alpha] = gs; - } - cb.setGState(gs); - } - cb.setColorFill(color); - } - else { - if (alpha != currentStrokeGState) { - currentStrokeGState = alpha; - PdfGState gs = strokeGState[alpha]; - if (gs == null) { - gs = new PdfGState(); - gs.setStrokeOpacity((float)alpha / 255f); - strokeGState[alpha] = gs; - } - cb.setGState(gs); - } - cb.setColorStroke(color); - } - } - else if (paint instanceof GradientPaint) { - GradientPaint gp = (GradientPaint)paint; - Point2D p1 = gp.getPoint1(); - transform.transform(p1, p1); - Point2D p2 = gp.getPoint2(); - transform.transform(p2, p2); - Color c1 = gp.getColor1(); - Color c2 = gp.getColor2(); - PdfShading shading = PdfShading.simpleAxial(cb.getPdfWriter(), (float)p1.getX(), normalizeY((float)p1.getY()), (float)p2.getX(), normalizeY((float)p2.getY()), c1, c2); - PdfShadingPattern pat = new PdfShadingPattern(shading); - if (fill) - cb.setShadingFill(pat); - else - cb.setShadingStroke(pat); - } - else if (paint instanceof TexturePaint) { - try { - TexturePaint tp = (TexturePaint)paint; - BufferedImage img = tp.getImage(); - Rectangle2D rect = tp.getAnchorRect(); - com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null); - PdfPatternPainter pattern = cb.createPattern(image.width(), image.height()); - AffineTransform inverse = this.normalizeMatrix(); - inverse.translate(rect.getX(), rect.getY()); - inverse.scale(rect.getWidth() / image.width(), -rect.getHeight() / image.height()); - double[] mx = new double[6]; - inverse.getMatrix(mx); - pattern.setPatternMatrix((float)mx[0], (float)mx[1], (float)mx[2], (float)mx[3], (float)mx[4], (float)mx[5]) ; - image.setAbsolutePosition(0,0); - pattern.addImage(image); - if (fill) - cb.setPatternFill(pattern); - else - cb.setPatternStroke(pattern); - } catch (Exception ex) { - if (fill) - cb.setColorFill(Color.gray); - else - cb.setColorStroke(Color.gray); - } - } - else { - try { - BufferedImage img = null; - int type = BufferedImage.TYPE_4BYTE_ABGR; - if (paint.getTransparency() == Transparency.OPAQUE) { - type = BufferedImage.TYPE_3BYTE_BGR; - } - img = new BufferedImage((int)width, (int)height, type); - Graphics2D g = (Graphics2D)img.getGraphics(); - g.transform(transform); - AffineTransform inv = transform.createInverse(); - Shape fillRect = new Rectangle2D.Double(0,0,img.getWidth(),img.getHeight()); - fillRect = inv.createTransformedShape(fillRect); - g.setPaint(paint); - g.fill(fillRect); - if (invert) { - AffineTransform tx = new AffineTransform(); - tx.scale(1,-1); - tx.translate(-xoffset,-yoffset); - g.drawImage(img,tx,null); - } - g.dispose(); - g = null; - com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(img, null); - PdfPatternPainter pattern = cb.createPattern(width, height); - image.setAbsolutePosition(0,0); - pattern.addImage(image); - if (fill) - cb.setPatternFill(pattern); - else - cb.setPatternStroke(pattern); - } catch (Exception ex) { - if (fill) - cb.setColorFill(Color.gray); - else - cb.setColorStroke(Color.gray); - } - } - } - - private synchronized void waitForImage(java.awt.Image image) { - if (mediaTracker == null) - mediaTracker = new MediaTracker(new PdfGraphics2D.fakeComponent()); - mediaTracker.addImage(image, 0); - try { - mediaTracker.waitForID(0); - } - catch (InterruptedException e) { - // empty on purpose - } - mediaTracker.removeImage(image); - } - - static private class fakeComponent extends Component { - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfICCBased.java b/src/main/java/com/lowagie/text/pdf/PdfICCBased.java deleted file mode 100644 index d5afe92..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfICCBased.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.awt.color.ICC_Profile; - -import com.lowagie.text.ExceptionConverter; - -/** - * A PdfICCBased defines a ColorSpace - * - * @see PdfStream - */ - -class PdfICCBased extends PdfStream { - - protected int NumberOfComponents; - - PdfICCBased(ICC_Profile profile) { - super(); - try { - NumberOfComponents = profile.getNumComponents(); - switch (NumberOfComponents) { - case 1: - put(PdfName.ALTERNATE, PdfName.DEVICEGRAY); - break; - case 3: - put(PdfName.ALTERNATE, PdfName.DEVICERGB); - break; - case 4: - put(PdfName.ALTERNATE, PdfName.DEVICECMYK); - break; - default: - throw new PdfException(NumberOfComponents + " component(s) is not supported in PDF1.4"); - } - put(PdfName.N, new PdfNumber(NumberOfComponents)); - bytes = profile.getData(); - flateCompress(); - } catch (Exception e) { - throw new ExceptionConverter(e); - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfImage.java b/src/main/java/com/lowagie/text/pdf/PdfImage.java deleted file mode 100644 index 46d737f..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfImage.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * $Id: PdfImage.java,v 1.66 2005/11/01 12:27:05 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - * - * REMARK: - * LZW/GIF is covered by a software patent which is owned by Unisys Corporation. - * Unisys refuses to license this patent for PDF-related use in software - * even when this software is released for free and may be freely distributed. - * HOWEVER: - * This library doesn't compress or decompress data using the LZW - * algorithm, nor does it create or visualize GIF-images in any way; - * it only copies parts of an existing GIF file into a PDF file. - * - * More information about the GIF format can be found in the following documents: - * * GRAPHICS INTERCHANGE FORMAT(sm) Version 89a - * (c)1987,1988,1989,1990 Copyright CompuServe Incorporated. Columbus, Ohio - * * LZW and GIF explained - * Steve Blackstock - * * http://mistress.informatik.unibw-muenchen.de/ - * very special thanks to klee@informatik.unibw-muenchen.de for the algorithm - * to extract the LZW data from a GIF. - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Image; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.IOException; - -/** - * PdfImage is a PdfStream containing an image-Dictionary and -stream. - */ - -class PdfImage extends PdfStream { - - static final int TRANSFERSIZE = 4096; - // membervariables - - /** This is the PdfName of the image. */ - protected PdfName name = null; - - // constructor - - /** - * Constructs a PdfImage-object. - * - * @param image the Image-object - * @param name the PdfName for this image - * @throws BadPdfFormatException on error - */ - - public PdfImage(Image image, String name, PdfIndirectReference maskRef) throws BadPdfFormatException { - super(); - this.name = new PdfName(name); - put(PdfName.TYPE, PdfName.XOBJECT); - put(PdfName.SUBTYPE, PdfName.IMAGE); - put(PdfName.WIDTH, new PdfNumber(image.width())); - put(PdfName.HEIGHT, new PdfNumber(image.height())); - if (image.getLayer() != null) - put(PdfName.OC, image.getLayer().getRef()); - if (image.isMask() && (image.bpc() == 1 || image.bpc() > 0xff)) - put(PdfName.IMAGEMASK, PdfBoolean.PDFTRUE); - if (maskRef != null) { - if (image.isSmask()) - put(PdfName.SMASK, maskRef); - else - put(PdfName.MASK, maskRef); - } - if (image.isMask() && image.isInvertMask()) - put(PdfName.DECODE, new PdfLiteral("[1 0]")); - if (image.isInterpolation()) - put(PdfName.INTERPOLATE, PdfBoolean.PDFTRUE); - InputStream is = null; - try { - - // Raw Image data - if (image.isImgRaw()) { - // will also have the CCITT parameters - int colorspace = image.colorspace(); - int transparency[] = image.getTransparency(); - if (transparency != null && !image.isMask() && maskRef == null) { - String s = "["; - for (int k = 0; k < transparency.length; ++k) - s += transparency[k] + " "; - s += "]"; - put(PdfName.MASK, new PdfLiteral(s)); - } - bytes = image.rawData(); - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - int bpc = image.bpc(); - if (bpc > 0xff) { - if (!image.isMask()) - put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); - put(PdfName.BITSPERCOMPONENT, new PdfNumber(1)); - put(PdfName.FILTER, PdfName.CCITTFAXDECODE); - int k = bpc - Image.CCITTG3_1D; - PdfDictionary decodeparms = new PdfDictionary(); - if (k != 0) - decodeparms.put(PdfName.K, new PdfNumber(k)); - if ((colorspace & Image.CCITT_BLACKIS1) != 0) - decodeparms.put(PdfName.BLACKIS1, PdfBoolean.PDFTRUE); - if ((colorspace & Image.CCITT_ENCODEDBYTEALIGN) != 0) - decodeparms.put(PdfName.ENCODEDBYTEALIGN, PdfBoolean.PDFTRUE); - if ((colorspace & Image.CCITT_ENDOFLINE) != 0) - decodeparms.put(PdfName.ENDOFLINE, PdfBoolean.PDFTRUE); - if ((colorspace & Image.CCITT_ENDOFBLOCK) != 0) - decodeparms.put(PdfName.ENDOFBLOCK, PdfBoolean.PDFFALSE); - decodeparms.put(PdfName.COLUMNS, new PdfNumber(image.width())); - decodeparms.put(PdfName.ROWS, new PdfNumber(image.height())); - put(PdfName.DECODEPARMS, decodeparms); - } - else { - switch(colorspace) { - case 1: - put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); - if (image.isInverted()) - put(PdfName.DECODE, new PdfLiteral("[1 0]")); - break; - case 3: - put(PdfName.COLORSPACE, PdfName.DEVICERGB); - if (image.isInverted()) - put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0]")); - break; - case 4: - default: - put(PdfName.COLORSPACE, PdfName.DEVICECMYK); - if (image.isInverted()) - put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]")); - } - PdfDictionary additional = image.getAdditional(); - if (additional != null) - putAll(additional); - if (image.isMask() && (image.bpc() == 1 || image.bpc() > 8)) - remove(PdfName.COLORSPACE); - put(PdfName.BITSPERCOMPONENT, new PdfNumber(image.bpc())); - if (image.isDeflated()) - put(PdfName.FILTER, PdfName.FLATEDECODE); - else { - flateCompress(); - } - } - return; - } - - // GIF, JPEG or PNG - String errorID; - if (image.rawData() == null){ - is = image.url().openStream(); - errorID = image.url().toString(); - } - else{ - is = new java.io.ByteArrayInputStream(image.rawData()); - errorID = "Byte array"; - } - switch(image.type()) { - case Image.JPEG: - put(PdfName.FILTER, PdfName.DCTDECODE); - switch(image.colorspace()) { - case 1: - put(PdfName.COLORSPACE, PdfName.DEVICEGRAY); - break; - case 3: - put(PdfName.COLORSPACE, PdfName.DEVICERGB); - break; - default: - put(PdfName.COLORSPACE, PdfName.DEVICECMYK); - if (image.isInverted()) { - put(PdfName.DECODE, new PdfLiteral("[1 0 1 0 1 0 1 0]")); - } - } - put(PdfName.BITSPERCOMPONENT, new PdfNumber(8)); - if (image.rawData() != null){ - bytes = image.rawData(); - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - return; - } - streamBytes = new ByteArrayOutputStream(); - transferBytes(is, streamBytes, -1); - break; - default: - throw new BadPdfFormatException(errorID + " is an unknown Image format."); - } - put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); - } - catch(IOException ioe) { - throw new BadPdfFormatException(ioe.getMessage()); - } - finally { - if (is != null) { - try{ - is.close(); - } - catch (Exception ee) { - // empty on purpose - } - } - } - } - - /** - * Returns the PdfName of the image. - * - * @return the name - */ - - public PdfName name() { - return name; - } - - static void transferBytes(InputStream in, OutputStream out, int len) throws IOException { - byte buffer[] = new byte[TRANSFERSIZE]; - if (len < 0) - len = 0x7ffffff; - int size; - while (len != 0) { - size = in.read(buffer, 0, Math.min(len, TRANSFERSIZE)); - if (size < 0) - return; - out.write(buffer, 0, size); - len -= size; - } - } - - protected void importAll(PdfImage dup) { - name = dup.name; - compressed = dup.compressed; - streamBytes = dup.streamBytes; - bytes = dup.bytes; - hashMap = dup.hashMap; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfImportedPage.java b/src/main/java/com/lowagie/text/pdf/PdfImportedPage.java deleted file mode 100644 index 7e6566e..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfImportedPage.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * $Id: PdfImportedPage.java,v 1.48 2005/05/04 14:32:39 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Image; -import java.io.IOException; - -/** Represents an imported page. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfImportedPage extends com.lowagie.text.pdf.PdfTemplate { - - PdfReaderInstance readerInstance; - int pageNumber; - - PdfImportedPage(PdfReaderInstance readerInstance, PdfWriter writer, int pageNumber) { - this.readerInstance = readerInstance; - this.pageNumber = pageNumber; - thisReference = writer.getPdfIndirectReference(); - bBox = readerInstance.getReader().getPageSize(pageNumber); - type = TYPE_IMPORTED; - } - - /** Reads the content from this PdfImportedPage-object from a reader. - * - * @return self - * - */ - public PdfImportedPage getFromReader() { - return this; - } - - public int getPageNumber() { - return pageNumber; - } - - - /** Always throws an error. This operation is not allowed. - * @param image dummy - * @param a dummy - * @param b dummy - * @param c dummy - * @param d dummy - * @param e dummy - * @param f dummy - * @throws DocumentException dummy */ - public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { - throwError(); - } - - /** Always throws an error. This operation is not allowed. - * @param template dummy - * @param a dummy - * @param b dummy - * @param c dummy - * @param d dummy - * @param e dummy - * @param f dummy */ - public void addTemplate(PdfTemplate template, float a, float b, float c, float d, float e, float f) { - throwError(); - } - - /** Always throws an error. This operation is not allowed. - * @return dummy */ - public PdfContentByte getDuplicate() { - throwError(); - return null; - } - - PdfStream getFormXObject() throws IOException { - return readerInstance.getFormXObject(pageNumber); - } - - public void setColorFill(PdfSpotColor sp, float tint) { - throwError(); - } - - public void setColorStroke(PdfSpotColor sp, float tint) { - throwError(); - } - - PdfObject getResources() { - return readerInstance.getResources(pageNumber); - } - - /** Always throws an error. This operation is not allowed. - * @param bf dummy - * @param size dummy */ - public void setFontAndSize(BaseFont bf, float size) { - throwError(); - } - - void throwError() { - throw new RuntimeException("Content can not be added to a PdfImportedPage."); - } - - PdfReaderInstance getPdfReaderInstance() { - return readerInstance; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfIndirectObject.java b/src/main/java/com/lowagie/text/pdf/PdfIndirectObject.java deleted file mode 100644 index 81ef485..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfIndirectObject.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * $Id: PdfIndirectObject.java,v 1.60 2005/05/04 14:31:40 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; - -import com.lowagie.text.DocWriter; - -/** - * PdfIndirectObject is the Pdf indirect object. - *

- * An indirect object is an object that has been labeled so that it can be referenced by - * other objects. Any type of PdfObject may be labeled as an indirect object.
- * An indirect object consists of an object identifier, a direct object, and the endobj - * keyword. The object identifier consists of an integer object number, an integer - * generation number, and the obj keyword.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.10 (page 53). - * - * @see PdfObject - * @see PdfIndirectReference - */ - -public class PdfIndirectObject { - - // membervariables - -/** The object number */ - protected int number; - -/** the generation number */ - protected int generation = 0; - - static final byte STARTOBJ[] = DocWriter.getISOBytes(" obj"); - static final byte ENDOBJ[] = DocWriter.getISOBytes("\nendobj\n"); - static final int SIZEOBJ = STARTOBJ.length + ENDOBJ.length; - PdfObject object; - PdfWriter writer; - - // constructors - -/** - * Constructs a PdfIndirectObject. - * - * @param number the object number - * @param object the direct object - */ - - PdfIndirectObject(int number, PdfObject object, PdfWriter writer) { - this(number, 0, object, writer); - } - - PdfIndirectObject(PdfIndirectReference ref, PdfObject object, PdfWriter writer) { - this(ref.getNumber(),ref.getGeneration(),object,writer); - } -/** - * Constructs a PdfIndirectObject. - * - * @param number the object number - * @param generation the generation number - * @param object the direct object - */ - - PdfIndirectObject(int number, int generation, PdfObject object, PdfWriter writer) { - this.writer = writer; - this.number = number; - this.generation = generation; - this.object = object; - PdfEncryption crypto = null; - if (writer != null) - crypto = writer.getEncryption(); - if (crypto != null) { - crypto.setHashKey(number, generation); - } - } - - // methods - -/** - * Return the length of this PdfIndirectObject. - * - * @return the length of the PDF-representation of this indirect object. - */ - -// public int length() { -// if (isStream) -// return bytes.size() + SIZEOBJ + stream.getStreamLength(writer); -// else -// return bytes.size(); -// } - - -/** - * Returns a PdfIndirectReference to this PdfIndirectObject. - * - * @return a PdfIndirectReference - */ - - public PdfIndirectReference getIndirectReference() { - return new PdfIndirectReference(object.type(), number, generation); - } - -/** - * Writes eficiently to a stream - * - * @param os the stream to write to - * @throws IOException on write error - */ - void writeTo(OutputStream os) throws IOException - { - os.write(DocWriter.getISOBytes(String.valueOf(number))); - os.write(' '); - os.write(DocWriter.getISOBytes(String.valueOf(generation))); - os.write(STARTOBJ); - int type = object.type(); - if (type != PdfObject.ARRAY && type != PdfObject.DICTIONARY && type != PdfObject.NAME && type != PdfObject.STRING) - os.write(' '); - object.toPdf(writer, os); - os.write(ENDOBJ); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfIndirectReference.java b/src/main/java/com/lowagie/text/pdf/PdfIndirectReference.java deleted file mode 100644 index 3b0e89c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfIndirectReference.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * $Id: PdfIndirectReference.java,v 1.55 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfIndirectReference contains a reference to a PdfIndirectObject. - *

- * Any object used as an element of an array or as a value in a dictionary may be specified - * by either a direct object of an indirect reference. An indirect reference is a reference - * to an indirect object, and consists of the indirect object's object number, generation number - * and the R keyword.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.11 (page 54). - * - * @see PdfObject - * @see PdfIndirectObject - */ - -public class PdfIndirectReference extends PdfObject { - - // membervariables - -/** the object number */ - protected int number; - -/** the generation number */ - protected int generation = 0; - - // constructors - - protected PdfIndirectReference() { - super(0); - } - -/** - * Constructs a PdfIndirectReference. - * - * @param type the type of the PdfObject that is referenced to - * @param number the object number. - * @param generation the generation number. - */ - - PdfIndirectReference(int type, int number, int generation) { - super(0, new StringBuffer().append(number).append(" ").append(generation).append(" R").toString()); - this.number = number; - this.generation = generation; - } - -/** - * Constructs a PdfIndirectReference. - * - * @param type the type of the PdfObject that is referenced to - * @param number the object number. - */ - - PdfIndirectReference(int type, int number) { - this(type, number, 0); - } - - // methods - -/** - * Returns the number of the object. - * - * @return a number. - */ - - public int getNumber() { - return number; - } - -/** - * Returns the generation of the object. - * - * @return a number. - */ - - public int getGeneration() { - return generation; - } - - public String toString() { - return new StringBuffer().append(number).append(" ").append(generation).append(" R").toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfLayer.java b/src/main/java/com/lowagie/text/pdf/PdfLayer.java deleted file mode 100644 index bf53904..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfLayer.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -/** - * An optional content group is a dictionary representing a collection of graphics - * that can be made visible or invisible dynamically by users of viewer applications. - * In iText they are referenced as layers. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfLayer extends PdfDictionary implements PdfOCG { - protected PdfIndirectReference ref; - protected ArrayList children; - protected PdfLayer parent; - protected String title; - - /** - * Holds value of property on. - */ - private boolean on = true; - - /** - * Holds value of property onPanel. - */ - private boolean onPanel = true; - - PdfLayer(String title) { - this.title = title; - } - - /** - * Creates a title layer. A title layer is not really a layer but a collection of layers - * under the same title heading. - * @param title the title text - * @param writer the PdfWriter - * @return the title layer - */ - public static PdfLayer createTitle(String title, PdfWriter writer) { - if (title == null) - throw new NullPointerException("Title cannot be null."); - PdfLayer layer = new PdfLayer(title); - writer.registerLayer(layer); - return layer; - } - /** - * Creates a new layer. - * @param name the name of the layer - * @param writer the writer - */ - public PdfLayer(String name, PdfWriter writer) { - super(PdfName.OCG); - setName(name); - ref = writer.getPdfIndirectReference(); - writer.registerLayer(this); - } - - String getTitle() { - return title; - } - - /** - * Adds a child layer. Nested layers can only have one parent. - * @param child the child layer - */ - public void addChild(PdfLayer child) { - if (child.parent != null) - throw new IllegalArgumentException("The layer '" + ((PdfString)child.get(PdfName.NAME)).toUnicodeString() + "' already has a parent."); - child.parent = this; - if (children == null) - children = new ArrayList(); - children.add(child); - } - - - /** - * Gets the parent layer. - * @return the parent layer or null if the layer has no parent - */ - public PdfLayer getParent() { - return parent; - } - - /** - * Gets the children layers. - * @return the children layers or null if the layer has no children - */ - public ArrayList getChildren() { - return children; - } - - /** - * Gets the PdfIndirectReference that represents this layer. - * @return the PdfIndirectReference that represents this layer - */ - public PdfIndirectReference getRef() { - return ref; - } - - /** - * Sets the name of this layer. - * @param name the name of this layer - */ - public void setName(String name) { - put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); - } - - /** - * Gets the dictionary representing the layer. It just returns this. - * @return the dictionary representing the layer - */ - public PdfObject getPdfObject() { - return this; - } - - /** - * Gets the initial visibility of the layer. - * @return the initial visibility of the layer - */ - public boolean isOn() { - return this.on; - } - - /** - * Sets the initial visibility of the layer. - * @param on the initial visibility of the layer - */ - public void setOn(boolean on) { - this.on = on; - } - - private PdfDictionary getUsage() { - PdfDictionary usage = (PdfDictionary)get(PdfName.USAGE); - if (usage == null) { - usage = new PdfDictionary(); - put(PdfName.USAGE, usage); - } - return usage; - } - - /** - * Used by the creating application to store application-specific - * data associated with this optional content group. - * @param creator a text string specifying the application that created the group - * @param subtype a string defining the type of content controlled by the group. Suggested - * values include but are not limited to Artwork, for graphic-design or publishing - * applications, and Technical, for technical designs such as building plans or - * schematics - */ - public void setCreatorInfo(String creator, String subtype) { - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.CREATOR, new PdfString(creator, PdfObject.TEXT_UNICODE)); - dic.put(PdfName.SUBTYPE, new PdfName(subtype)); - usage.put(PdfName.CREATORINFO, dic); - } - - /** - * Specifies the language of the content controlled by this - * optional content group - * @param lang a language string which specifies a language and possibly a locale - * (for example, es-MX represents Mexican Spanish) - * @param preferred used by viewer applications when there is a partial match but no exact - * match between the system language and the language strings in all usage dictionaries - */ - public void setLanguage(String lang, boolean preferred) { - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.LANG, new PdfString(lang, PdfObject.TEXT_UNICODE)); - if (preferred) - dic.put(PdfName.PREFERRED, PdfName.ON); - usage.put(PdfName.LANGUAGE, dic); - } - - /** - * Specifies the recommended state for content in this - * group when the document (or part of it) is saved by a viewer application to a format - * that does not support optional content (for example, an earlier version of - * PDF or a raster image format). - * @param export the export state - */ - public void setExport(boolean export) { - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.EXPORTSTATE, export ? PdfName.ON : PdfName.OFF); - usage.put(PdfName.EXPORT, dic); - } - - /** - * Specifies a range of magnifications at which the content - * in this optional content group is best viewed. - * @param min the minimum recommended magnification factors at which the group - * should be ON. A negative value will set the default to 0 - * @param max the maximum recommended magnification factor at which the group - * should be ON. A negative value will set the largest possible magnification supported by the - * viewer application - */ - public void setZoom(float min, float max) { - if (min <= 0 && max < 0) - return; - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - if (min > 0) - dic.put(PdfName.MIN, new PdfNumber(min)); - if (max >= 0) - dic.put(PdfName.MAX, new PdfNumber(max)); - usage.put(PdfName.ZOOM, dic); - } - - /** - * Specifies that the content in this group is intended for - * use in printing - * @param subtype a name specifying the kind of content controlled by the group; - * for example, Trapping, PrintersMarks and Watermark - * @param printstate indicates that the group should be - * set to that state when the document is printed from a viewer application - */ - public void setPrint(String subtype, boolean printstate) { - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.SUBTYPE, new PdfName(subtype)); - dic.put(PdfName.PRINTSTATE, printstate ? PdfName.ON : PdfName.OFF); - usage.put(PdfName.PRINT, dic); - } - - /** - * Indicates that the group should be set to that state when the - * document is opened in a viewer application. - * @param view the view state - */ - public void setView(boolean view) { - PdfDictionary usage = getUsage(); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.VIEWSTATE, view ? PdfName.ON : PdfName.OFF); - usage.put(PdfName.VIEW, dic); - } - - /** - * Gets the layer visibility in Acrobat's layer panel - * @return the layer visibility in Acrobat's layer panel - */ - public boolean isOnPanel() { - return this.onPanel; - } - - /** - * Sets the visibility of the layer in Acrobat's layer panel. If false - * the layer cannot be directly manipulated by the user. Note that any children layers will - * also be absent from the panel. - * @param onPanel the visibility of the layer in Acrobat's layer panel - */ - public void setOnPanel(boolean onPanel) { - this.onPanel = onPanel; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfLayerMembership.java b/src/main/java/com/lowagie/text/pdf/PdfLayerMembership.java deleted file mode 100644 index 3a5be50..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfLayerMembership.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.HashSet; -import java.util.Collection; - -/** - * Content typically belongs to a single optional content group, - * and is visible when the group is ON and invisible when it is OFF. To express more - * complex visibility policies, content should not declare itself to belong to an optional - * content group directly, but rather to an optional content membership dictionary - * represented by this class. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfLayerMembership extends PdfDictionary implements PdfOCG { - - /** - * Visible only if all of the entries are ON. - */ - public static PdfName ALLON = new PdfName("AllOn"); - /** - * Visible if any of the entries are ON. - */ - public static PdfName ANYON = new PdfName("AnyOn"); - /** - * Visible if any of the entries are OFF. - */ - public static PdfName ANYOFF = new PdfName("AnyOff"); - /** - * Visible only if all of the entries are OFF. - */ - public static PdfName ALLOFF = new PdfName("AllOff"); - - PdfIndirectReference ref; - PdfArray members = new PdfArray(); - HashSet layers = new HashSet(); - - /** - * Creates a new, empty, membership layer. - * @param writer the writer - */ - public PdfLayerMembership(PdfWriter writer) { - super(PdfName.OCMD); - put(PdfName.OCGS, members); - ref = writer.getPdfIndirectReference(); - } - - /** - * Gets the PdfIndirectReference that represents this membership layer. - * @return the PdfIndirectReference that represents this layer - */ - public PdfIndirectReference getRef() { - return ref; - } - - /** - * Adds a new member to the layer. - * @param layer the new member to the layer - */ - public void addMember(PdfLayer layer) { - if (!layers.contains(layer)) { - members.add(layer.getRef()); - layers.add(layer); - } - } - - /** - * Gets the member layers. - * @return the member layers - */ - public Collection getLayers() { - return layers; - } - - /** - * Sets the visibility policy for content belonging to this - * membership dictionary. Possible values are ALLON, ANYON, ANYOFF and ALLOFF. - * The default value is ANYON. - * @param type the visibility policy - */ - public void setVisibilityPolicy(PdfName type) { - put(PdfName.P, type); - } - - /** - * Gets the dictionary representing the membership layer. It just returns this. - * @return the dictionary representing the layer - */ - public PdfObject getPdfObject() { - return this; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfLine.java b/src/main/java/com/lowagie/text/pdf/PdfLine.java deleted file mode 100644 index 8ccd84a..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfLine.java +++ /dev/null @@ -1,477 +0,0 @@ -/* - * $Id: PdfLine.java,v 1.66 2006/01/18 20:35:48 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.Iterator; - -import com.lowagie.text.Element; -import com.lowagie.text.ListItem; -import com.lowagie.text.Chunk; - -/** - * PdfLine defines an array with PdfChunk-objects - * that fit into 1 line. - */ - -public class PdfLine { - - // membervariables - - /** The arraylist containing the chunks. */ - protected ArrayList line; - - /** The left indentation of the line. */ - protected float left; - - /** The width of the line. */ - protected float width; - - /** The alignment of the line. */ - protected int alignment; - - /** The heigth of the line. */ - protected float height; - - /** The listsymbol (if necessary). */ - protected Chunk listSymbol = null; - - /** The listsymbol (if necessary). */ - protected float symbolIndent; - - /** true if the chunk splitting was caused by a newline. */ - protected boolean newlineSplit = false; - - /** The original width. */ - protected float originalWidth; - - protected boolean isRTL = false; - - // constructors - - /** - * Constructs a new PdfLine-object. - * - * @param left the limit of the line at the left - * @param right the limit of the line at the right - * @param alignment the alignment of the line - * @param height the height of the line - */ - - PdfLine(float left, float right, int alignment, float height) { - this.left = left; - this.width = right - left; - this.originalWidth = this.width; - this.alignment = alignment; - this.height = height; - this.line = new ArrayList(); - } - - PdfLine(float left, float remainingWidth, int alignment, boolean newlineSplit, ArrayList line, boolean isRTL) { - this.left = left; - this.width = remainingWidth; - this.alignment = alignment; - this.line = line; - this.newlineSplit = newlineSplit; - this.isRTL = isRTL; - } - - // methods - - /** - * Adds a PdfChunk to the PdfLine. - * - * @param chunk the PdfChunk to add - * @return null if the chunk could be added completely; if not - * a PdfChunk containing the part of the chunk that could - * not be added is returned - */ - - PdfChunk add(PdfChunk chunk) { - // nothing happens if the chunk is null. - if (chunk == null || chunk.toString().equals("")) { - return null; - } - - // we split the chunk to be added - PdfChunk overflow = chunk.split(width); - newlineSplit = (chunk.isNewlineSplit() || overflow == null); - // if (chunk.isNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED) - // alignment = Element.ALIGN_LEFT; - - - // if the length of the chunk > 0 we add it to the line - if (chunk.length() > 0) { - if (overflow != null) - chunk.trimLastSpace(); - width -= chunk.width(); - line.add(chunk); - } - - // if the length == 0 and there were no other chunks added to the line yet, - // we risk to end up in an endless loop trying endlessly to add the same chunk - else if (line.size() < 1) { - chunk = overflow; - overflow = chunk.truncate(width); - width -= chunk.width(); - if (chunk.length() > 0) { - line.add(chunk); - return overflow; - } - // if the chunck couldn't even be truncated, we add everything, so be it - else { - if (overflow != null) - line.add(overflow); - return null; - } - } - else { - width += ((PdfChunk)(line.get(line.size() - 1))).trimLastSpace(); - } - return overflow; - } - - // methods to retrieve information - - /** - * Returns the number of chunks in the line. - * - * @return a value - */ - - public int size() { - return line.size(); - } - - /** - * Returns an iterator of PdfChunks. - * - * @return an Iterator - */ - - public Iterator iterator() { - return line.iterator(); - } - - /** - * Returns the height of the line. - * - * @return a value - */ - - float height() { - return height; - } - - /** - * Returns the left indentation of the line taking the alignment of the line into account. - * - * @return a value - */ - - float indentLeft() { - if (isRTL) { - switch (alignment) { - case Element.ALIGN_LEFT: - return left + width; - case Element.ALIGN_CENTER: - return left + (width / 2f); - default: - return left; - } - } - else { - switch (alignment) { - case Element.ALIGN_RIGHT: - return left + width; - case Element.ALIGN_CENTER: - return left + (width / 2f); - default: - return left; - } - } - } - - /** - * Checks if this line has to be justified. - * - * @return true if the alignment equals ALIGN_JUSTIFIED and there is some width left. - */ - - public boolean hasToBeJustified() { - return ((alignment == Element.ALIGN_JUSTIFIED || alignment == Element.ALIGN_JUSTIFIED_ALL) && width != 0); - } - - /** - * Resets the alignment of this line. - *

- * The alignment of the last line of for instance a Paragraph - * that has to be justified, has to be reset to ALIGN_LEFT. - */ - - public void resetAlignment() { - if (alignment == Element.ALIGN_JUSTIFIED) { - alignment = Element.ALIGN_LEFT; - } - } - - /** - * Returns the width that is left, after a maximum of characters is added to the line. - * - * @return a value - */ - - float widthLeft() { - return width; - } - - /** - * Returns the number of space-characters in this line. - * - * @return a value - */ - - int numberOfSpaces() { - String string = toString(); - int length = string.length(); - int numberOfSpaces = 0; - for (int i = 0; i < length; i++) { - if (string.charAt(i) == ' ') { - numberOfSpaces++; - } - } - return numberOfSpaces; - } - - /** - * Sets the listsymbol of this line. - *

- * This is only necessary for the first line of a ListItem. - * - * @param listItem the list symbol - */ - - public void setListItem(ListItem listItem) { - this.listSymbol = listItem.listSymbol(); - this.symbolIndent = listItem.indentationLeft(); - } - - /** - * Returns the listsymbol of this line. - * - * @return a PdfChunk if the line has a listsymbol; null otherwise - */ - - public Chunk listSymbol() { - return listSymbol; - } - - /** - * Return the indentation needed to show the listsymbol. - * - * @return a value - */ - - public float listIndent() { - return symbolIndent; - } - - /** - * Get the string representation of what is in this line. - * - * @return a String - */ - - public String toString() { - StringBuffer tmp = new StringBuffer(); - for (Iterator i = line.iterator(); i.hasNext(); ) { - tmp.append(((PdfChunk) i.next()).toString()); - } - return tmp.toString(); - } - - /** - * Checks if a newline caused the line split. - * @return true if a newline caused the line split - */ - public boolean isNewlineSplit() { - return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL); - } - - /** - * Gets the index of the last PdfChunk with metric attributes - * @return the last PdfChunk with metric attributes - */ - public int getLastStrokeChunk() { - int lastIdx = line.size() - 1; - for (; lastIdx >= 0; --lastIdx) { - PdfChunk chunk = (PdfChunk)line.get(lastIdx); - if (chunk.isStroked()) - break; - } - return lastIdx; - } - - /** - * Gets a PdfChunk by index. - * @param idx the index - * @return the PdfChunk or null if beyond the array - */ - public PdfChunk getChunk(int idx) { - if (idx < 0 || idx >= line.size()) - return null; - return (PdfChunk)line.get(idx); - } - - /** - * Gets the original width of the line. - * @return the original width of the line - */ - public float getOriginalWidth() { - return originalWidth; - } - - /** - * Gets the maximum size of all the fonts used in this line - * including images (if there are images in the line and if - * the leading has to be changed). - * @return maximum size of all the fonts used in this line - */ - float getMaxSize() { - float maxSize = 0; - for (int k = 0; k < line.size(); ++k) { - PdfChunk chunk = (PdfChunk)line.get(k); - if (!chunk.isImage() || !chunk.changeLeading()) { - maxSize = Math.max(chunk.font().size(), maxSize); - } - else { - maxSize = Math.max(chunk.getImage().scaledHeight() + chunk.getImageOffsetY() , maxSize); - } - } - return maxSize; - } - - /** - * Gets the maximum size of all the fonts used in this line - * including images. - * @return maximum size of all the fonts used in this line - */ - float getMaxSizeSimple() { - float maxSize = 0; - for (int k = 0; k < line.size(); ++k) { - PdfChunk chunk = (PdfChunk)line.get(k); - if (!chunk.isImage()) { - maxSize = Math.max(chunk.font().size(), maxSize); - } - else { - maxSize = Math.max(chunk.getImage().scaledHeight() + chunk.getImageOffsetY() , maxSize); - } - } - return maxSize; - } - - boolean isRTL() { - return isRTL; - } - - /** - * Gets a width corrected with a charSpacing and wordSpacing. - * @param charSpacing - * @param wordSpacing - * @return a corrected width - */ - public float getWidthCorrected(float charSpacing, float wordSpacing) { - float total = 0; - for (int k = 0; k < line.size(); ++k) { - PdfChunk ck = (PdfChunk)line.get(k); - total += ck.getWidthCorrected(charSpacing, wordSpacing); - } - return total; - } - -/** - * Gets the maximum size of the ascender for all the fonts used - * in this line. - * @return maximum size of all the ascenders used in this line - */ - public float getAscender() { - float ascender = 0; - for (int k = 0; k < line.size(); ++k) { - PdfChunk ck = (PdfChunk)line.get(k); - if (ck.isImage()) - ascender = Math.max(ascender, ck.getImage().scaledHeight() + ck.getImageOffsetY()); - else { - PdfFont font = ck.font(); - ascender = Math.max(ascender, font.getFont().getFontDescriptor(BaseFont.ASCENT, font.size())); - } - } - return ascender; - } - -/** - * Gets the biggest descender for all the fonts used - * in this line. Note that this is a negative number. - * @return maximum size of all the ascenders used in this line - */ - public float getDescender() { - float descender = 0; - for (int k = 0; k < line.size(); ++k) { - PdfChunk ck = (PdfChunk)line.get(k); - if (ck.isImage()) - descender = Math.min(descender, ck.getImageOffsetY()); - else { - PdfFont font = ck.font(); - descender = Math.min(descender, font.getFont().getFontDescriptor(BaseFont.DESCENT, font.size())); - } - } - return descender; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfLister.java b/src/main/java/com/lowagie/text/pdf/PdfLister.java deleted file mode 100644 index c3ecf63..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfLister.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * $Id: PdfLister.java,v 1.34 2005/11/01 12:27:05 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * This class by Mark Thompson. Copyright (C) 2002 Mark Thompson - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - - package com.lowagie.text.pdf; - -import java.io.*; -import java.util.Iterator; -/** - * List a PDF file in human-readable form (for debugging reasons mostly) - * @author Mark Thompson - */ - -public class PdfLister { - - /** the printStream you want to write the output to. */ - PrintStream out; - - /** - * Create a new lister object. - * @param out - */ - public PdfLister(PrintStream out) { - this.out = out; - } - - /** - * Visualizes a PDF object. - * @param object a com.lowagie.text.pdf object - */ - public void listAnyObject(PdfObject object) - { - switch (object.type()) { - case PdfObject.ARRAY: - listArray((PdfArray)object); - break; - case PdfObject.DICTIONARY: - listDict((PdfDictionary) object); - break; - case PdfObject.STRING: - out.println("(" + object.toString() + ")"); - break; - default: - out.println(object.toString()); - break; - } - } - /** - * Visualizes a PdfDictionary object. - * @param dictionary a com.lowagie.text.pdf.PdfDictionary object - */ - public void listDict(PdfDictionary dictionary) - { - out.println("<<"); - PdfName key; - PdfObject value; - for (Iterator i = dictionary.getKeys().iterator(); i.hasNext(); ) { - key = (PdfName) i.next(); - value = dictionary.get(key); - out.print(key.toString()); - out.print(' '); - listAnyObject(value); - } - out.println(">>"); - } - - /** - * Visualizes a PdfArray object. - * @param array a com.lowagie.text.pdf.PdfArray object - */ - public void listArray(PdfArray array) - { - out.println('['); - for (Iterator i = array.getArrayList().iterator(); i.hasNext(); ) { - PdfObject item = (PdfObject)i.next(); - listAnyObject(item); - } - out.println(']'); - } - /** - * Visualizes a Stream. - * @param stream - * @param reader - */ - public void listStream(PRStream stream, PdfReaderInstance reader) - { - try { - listDict(stream); - out.println("startstream"); - byte[] b = PdfReader.getStreamBytes(stream); -// byte buf[] = new byte[Math.min(stream.getLength(), 4096)]; -// int r = 0; -// stream.openStream(reader); -// for (;;) { -// r = stream.readStream(buf, 0, buf.length); -// if (r == 0) break; -// out.write(buf, 0, r); -// } -// stream.closeStream(); - int len = b.length - 1; - for (int k = 0; k < len; ++k) { - if (b[k] == '\r' && b[k + 1] != '\n') - b[k] = (byte)'\n'; - } - out.println(new String(b)); - out.println("endstream"); - } catch (IOException e) { - System.err.println("I/O exception: " + e); -// } catch (java.util.zip.DataFormatException e) { -// System.err.println("Data Format Exception: " + e); - } - } - /** - * Visualizes an imported page - * @param iPage - */ - public void listPage(PdfImportedPage iPage) - { - int pageNum = iPage.getPageNumber(); - PdfReaderInstance readerInst = iPage.getPdfReaderInstance(); - PdfReader reader = readerInst.getReader(); - - PdfDictionary page = reader.getPageN(pageNum); - listDict(page); - PdfObject obj = PdfReader.getPdfObject(page.get(PdfName.CONTENTS)); - switch (obj.type) { - case PdfObject.STREAM: - listStream((PRStream)obj, readerInst); - break; - case PdfObject.ARRAY: - for (Iterator i = ((PdfArray)obj).getArrayList().iterator(); i.hasNext();) { - PdfObject o = PdfReader.getPdfObject((PdfObject)i.next()); - listStream((PRStream)o, readerInst); - out.println("-----------"); - } - break; - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfLiteral.java b/src/main/java/com/lowagie/text/pdf/PdfLiteral.java deleted file mode 100644 index bf71bc6..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfLiteral.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * $Id: PdfLiteral.java,v 1.53 2005/05/04 14:31:48 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * a Literal - */ - -public class PdfLiteral extends PdfObject { - - /** - * Holds value of property position. - */ - private int position; - - public PdfLiteral(String text) { - super(0, text); - } - - public PdfLiteral(byte b[]) { - super(0, b); - } - - public PdfLiteral(int size) { - super(0, (byte[])null); - bytes = new byte[size]; - java.util.Arrays.fill(bytes, (byte)32); - } - - public PdfLiteral(int type, String text) { - super(type, text); - } - - public PdfLiteral(int type, byte b[]) { - super(type, b); - } - - public void toPdf(PdfWriter writer, java.io.OutputStream os) throws java.io.IOException { - if (os instanceof OutputStreamCounter) - position = ((OutputStreamCounter)os).getCounter(); - super.toPdf(writer, os); - } - - /** - * Getter for property position. - * @return Value of property position. - */ - public int getPosition() { - return this.position; - } - - /** - * Getter for property posLength. - * @return Value of property posLength. - */ - public int getPosLength() { - if (bytes != null) - return bytes.length; - else - return 0; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfMediaClipData.java b/src/main/java/com/lowagie/text/pdf/PdfMediaClipData.java deleted file mode 100644 index de17355..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfMediaClipData.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2003 Galo Gimenez - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; - -public class PdfMediaClipData extends PdfDictionary { - - PdfMediaClipData(String file, PdfFileSpecification fs, String mimeType) throws IOException { - put(PdfName.TYPE,new PdfName("MediaClip")); - put(PdfName.S, new PdfName("MCD")); - put(PdfName.N, new PdfString("Media clip for "+file)); - put(new PdfName("CT"), new PdfString(mimeType)); - PdfDictionary dic = new PdfDictionary(); - dic.put(new PdfName("TF"), new PdfString("TEMPACCESS")); - put(new PdfName("P"), dic); - put(PdfName.D, fs.getReference()); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfName.java b/src/main/java/com/lowagie/text/pdf/PdfName.java deleted file mode 100644 index ccfbd01..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfName.java +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * $Id: PdfName.java,v 1.83 2006/06/04 22:23:38 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999-2006 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfName is an object that can be used as a name in a PDF-file. - *

- * A name, like a string, is a sequence of characters. It must begin with a slash - * followed by a sequence of ASCII characters in the range 32 through 136 except - * %, (, ), [, ], <, >, {, }, / and #. Any character except 0x00 may be included - * in a name by writing its twocharacter hex code, preceded by #. The maximum number - * of characters in a name is 127.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.5 (page 39-40). - *

- * - * @see PdfObject - * @see PdfDictionary - * @see BadPdfFormatException - */ - -public class PdfName extends PdfObject implements Comparable{ - - // static membervariables (a variety of standard names used in PDF) - - /** A name */ - public static final PdfName A = new PdfName("A"); - /** A name */ - public static final PdfName AA = new PdfName("AA"); - /** A name */ - public static final PdfName ABSOLUTECALORIMETRIC = new PdfName("AbsoluteColorimetric"); - /** A name */ - public static final PdfName AC = new PdfName("AC"); - /** A name */ - public static final PdfName ACROFORM = new PdfName("AcroForm"); - /** A name */ - public static final PdfName ACTION = new PdfName("Action"); - /** A name */ - public static final PdfName ADBE_PKCS7_DETACHED = new PdfName("adbe.pkcs7.detached"); - /** A name */ - public static final PdfName ADBE_PKCS7_SHA1 = new PdfName("adbe.pkcs7.sha1"); - /** A name */ - public static final PdfName ADBE_X509_RSA_SHA1 = new PdfName("adbe.x509.rsa_sha1"); - /** A name */ - public static final PdfName ADOBE_PPKLITE = new PdfName("Adobe.PPKLite"); - /** A name */ - public static final PdfName ADOBE_PPKMS = new PdfName("Adobe.PPKMS"); - /** A name */ - public static final PdfName AIS = new PdfName("AIS"); - /** A name */ - public static final PdfName ALLPAGES = new PdfName("AllPages"); - /** A name */ - public static final PdfName ALTERNATE = new PdfName("Alternate"); - /** A name */ - public static final PdfName ANNOT = new PdfName("Annot"); - /** A name */ - public static final PdfName ANTIALIAS = new PdfName("AntiAlias"); - /** A name */ - public static final PdfName ANNOTS = new PdfName("Annots"); - /** A name */ - public static final PdfName AP = new PdfName("AP"); - /** A name */ - public static final PdfName ARTBOX = new PdfName("ArtBox"); - /** A name */ - public static final PdfName ASCENT = new PdfName("Ascent"); - /** A name */ - public static final PdfName AS = new PdfName("AS"); - /** A name */ - public static final PdfName ASCII85DECODE = new PdfName("ASCII85Decode"); - /** A name */ - public static final PdfName ASCIIHEXDECODE = new PdfName("ASCIIHexDecode"); - /** A name */ - public static final PdfName AUTHOR = new PdfName("Author"); - /** A name */ - public static final PdfName B = new PdfName("B"); - /** A name */ - public static final PdfName BASEENCODING = new PdfName("BaseEncoding"); - /** A name */ - public static final PdfName BASEFONT = new PdfName("BaseFont"); - /** A name */ - public static final PdfName BBOX = new PdfName("BBox"); - /** A name */ - public static final PdfName BC = new PdfName("BC"); - /** A name */ - public static final PdfName BG = new PdfName("BG"); - /** A name */ - public static final PdfName BIGFIVE = new PdfName("BigFive"); - /** A name */ - public static final PdfName BITSPERCOMPONENT = new PdfName("BitsPerComponent"); - /** A name */ - public static final PdfName BITSPERSAMPLE = new PdfName("BitsPerSample"); - /** A name */ - public static final PdfName BL = new PdfName("Bl"); - /** A name */ - public static final PdfName BLACKIS1 = new PdfName("BlackIs1"); - /** A name */ - public static final PdfName BLACKPOINT = new PdfName("BlackPoint"); - /** A name */ - public static final PdfName BLEEDBOX = new PdfName("BleedBox"); - /** A name */ - public static final PdfName BLINDS = new PdfName("Blinds"); - /** A name */ - public static final PdfName BM = new PdfName("BM"); - /** A name */ - public static final PdfName BORDER = new PdfName("Border"); - /** A name */ - public static final PdfName BOUNDS = new PdfName("Bounds"); - /** A name */ - public static final PdfName BOX = new PdfName("Box"); - /** A name */ - public static final PdfName BS = new PdfName("BS"); - /** A name */ - public static final PdfName BTN = new PdfName("Btn"); - /** A name */ - public static final PdfName BYTERANGE = new PdfName("ByteRange"); - /** A name */ - public static final PdfName C = new PdfName("C"); - /** A name */ - public static final PdfName C0 = new PdfName("C0"); - /** A name */ - public static final PdfName C1 = new PdfName("C1"); - /** A name */ - public static final PdfName CA = new PdfName("CA"); - /** A name */ - public static final PdfName ca = new PdfName("ca"); - /** A name */ - public static final PdfName CALGRAY = new PdfName("CalGray"); - /** A name */ - public static final PdfName CALRGB = new PdfName("CalRGB"); - /** A name */ - public static final PdfName CAPHEIGHT = new PdfName("CapHeight"); - /** A name */ - public static final PdfName CATALOG = new PdfName("Catalog"); - /** A name */ - public static final PdfName CATEGORY = new PdfName("Category"); - /** A name */ - public static final PdfName CCITTFAXDECODE = new PdfName("CCITTFaxDecode"); - /** A name */ - public static final PdfName CENTERWINDOW = new PdfName("CenterWindow"); - /** A name */ - public static final PdfName CERT = new PdfName("Cert"); - /** A name */ - public static final PdfName CH = new PdfName("Ch"); - /** A name */ - public static final PdfName CHARPROCS = new PdfName("CharProcs"); - /** A name */ - public static final PdfName CIDFONTTYPE0 = new PdfName("CIDFontType0"); - /** A name */ - public static final PdfName CIDFONTTYPE2 = new PdfName("CIDFontType2"); - /** A name */ - public static final PdfName CIDSYSTEMINFO = new PdfName("CIDSystemInfo"); - /** A name */ - public static final PdfName CIDTOGIDMAP = new PdfName("CIDToGIDMap"); - /** A name */ - public static final PdfName CIRCLE = new PdfName("Circle"); - /** A name */ - public static final PdfName CO = new PdfName("CO"); - /** A name */ - public static final PdfName COLORS = new PdfName("Colors"); - /** A name */ - public static final PdfName COLORSPACE = new PdfName("ColorSpace"); - /** A name */ - public static final PdfName COLUMNS = new PdfName("Columns"); - /** A name */ - public static final PdfName CONTACTINFO = new PdfName("ContactInfo"); - /** A name */ - public static final PdfName CONTENT = new PdfName("Content"); - /** A name */ - public static final PdfName CONTENTS = new PdfName("Contents"); - /** A name */ - public static final PdfName COORDS = new PdfName("Coords"); - /** A name */ - public static final PdfName COUNT = new PdfName("Count"); - /** A name of a base 14 type 1 font */ - public static final PdfName COURIER = new PdfName("Courier"); - /** A name of a base 14 type 1 font */ - public static final PdfName COURIER_BOLD = new PdfName("Courier-Bold"); - /** A name of a base 14 type 1 font */ - public static final PdfName COURIER_OBLIQUE = new PdfName("Courier-Oblique"); - /** A name of a base 14 type 1 font */ - public static final PdfName COURIER_BOLDOBLIQUE = new PdfName("Courier-BoldOblique"); - /** A name */ - public static final PdfName CREATIONDATE = new PdfName("CreationDate"); - /** A name */ - public static final PdfName CREATOR = new PdfName("Creator"); - /** A name */ - public static final PdfName CREATORINFO = new PdfName("CreatorInfo"); - /** A name */ - public static final PdfName CROPBOX = new PdfName("CropBox"); - /** A name */ - public static final PdfName CS = new PdfName("CS"); - /** A name */ - public static final PdfName D = new PdfName("D"); - /** A name */ - public static final PdfName DA = new PdfName("DA"); - /** A name */ - public static final PdfName DC = new PdfName("DC"); - /** A name */ - public static final PdfName DCTDECODE = new PdfName("DCTDecode"); - /** A name */ - public static final PdfName DECODE = new PdfName("Decode"); - /** A name */ - public static final PdfName DECODEPARMS = new PdfName("DecodeParms"); - /** A name */ - public static final PdfName DEFAULTCMYK = new PdfName("DefaultCMYK"); - /** A name */ - public static final PdfName DEFAULTGRAY = new PdfName("DefaultGray"); - /** A name */ - public static final PdfName DEFAULTRGB = new PdfName("DefaultRGB"); - /** A name */ - public static final PdfName DESC = new PdfName("Desc"); - /** A name */ - public static final PdfName DESCENDANTFONTS = new PdfName("DescendantFonts"); - /** A name */ - public static final PdfName DESCENT = new PdfName("Descent"); - /** A name */ - public static final PdfName DEST = new PdfName("Dest"); - /** A name */ - public static final PdfName DESTOUTPUTPROFILE = new PdfName("DestOutputProfile"); - /** A name */ - public static final PdfName DESTS = new PdfName("Dests"); - /** A name */ - public static final PdfName DEVICEGRAY = new PdfName("DeviceGray"); - /** A name */ - public static final PdfName DEVICERGB = new PdfName("DeviceRGB"); - /** A name */ - public static final PdfName DEVICECMYK = new PdfName("DeviceCMYK"); - /** A name */ - public static final PdfName DI = new PdfName("Di"); - /** A name */ - public static final PdfName DIFFERENCES = new PdfName("Differences"); - /** A name */ - public static final PdfName DISSOLVE = new PdfName("Dissolve"); - /** A name */ - public static final PdfName DIRECTION = new PdfName("Direction"); - /** A name */ - public static final PdfName DISPLAYDOCTITLE = new PdfName("DisplayDocTitle"); - /** A name */ - public static final PdfName DM = new PdfName("Dm"); - /** A name */ - public static final PdfName DOMAIN = new PdfName("Domain"); - /** A name */ - public static final PdfName DP = new PdfName("DP"); - /** A name */ - public static final PdfName DR = new PdfName("DR"); - /** A name */ - public static final PdfName DS = new PdfName("DS"); - /** A name */ - public static final PdfName DUR = new PdfName("Dur"); - /** A name */ - public static final PdfName DV = new PdfName("DV"); - /** A name */ - public static final PdfName DW = new PdfName("DW"); - /** A name */ - public static final PdfName E = new PdfName("E"); - /** A name */ - public static final PdfName EARLYCHANGE = new PdfName("EarlyChange"); - /** A name */ - public static final PdfName EF = new PdfName("EF"); - /** A name */ - public static final PdfName EMBEDDEDFILE = new PdfName("EmbeddedFile"); - /** A name */ - public static final PdfName EMBEDDEDFILES = new PdfName("EmbeddedFiles"); - /** A name */ - public static final PdfName ENCODE = new PdfName("Encode"); - /** A name */ - public static final PdfName ENCODEDBYTEALIGN = new PdfName("EncodedByteAlign"); - /** A name */ - public static final PdfName ENCODING = new PdfName("Encoding"); - /** A name */ - public static final PdfName ENCRYPT = new PdfName("Encrypt"); - /** A name */ - public static final PdfName ENDOFBLOCK = new PdfName("EndOfBlock"); - /** A name */ - public static final PdfName ENDOFLINE = new PdfName("EndOfLine"); - /** A name */ - public static final PdfName EXTEND = new PdfName("Extend"); - /** A name */ - public static final PdfName EXTGSTATE = new PdfName("ExtGState"); - /** A name */ - public static final PdfName EXPORT = new PdfName("Export"); - /** A name */ - public static final PdfName EXPORTSTATE = new PdfName("ExportState"); - /** A name */ - public static final PdfName EVENT = new PdfName("Event"); - /** A name */ - public static final PdfName F = new PdfName("F"); - /** A name */ - public static final PdfName FB = new PdfName("FB"); - /** A name */ - public static final PdfName FDECODEPARMS = new PdfName("FDecodeParms"); - /** A name */ - public static final PdfName FDF = new PdfName("FDF"); - /** A name */ - public static final PdfName FF = new PdfName("Ff"); - /** A name */ - public static final PdfName FFILTER = new PdfName("FFilter"); - /** A name */ - public static final PdfName FIELDS = new PdfName("Fields"); - /** A name */ - public static final PdfName FILEATTACHMENT = new PdfName("FileAttachment"); - /** A name */ - public static final PdfName FILESPEC = new PdfName("Filespec"); - /** A name */ - public static final PdfName FILTER = new PdfName("Filter"); - /** A name */ - public static final PdfName FIRST = new PdfName("First"); - /** A name */ - public static final PdfName FIRSTCHAR = new PdfName("FirstChar"); - /** A name */ - public static final PdfName FIRSTPAGE = new PdfName("FirstPage"); - /** A name */ - public static final PdfName FIT = new PdfName("Fit"); - /** A name */ - public static final PdfName FITH = new PdfName("FitH"); - /** A name */ - public static final PdfName FITV = new PdfName("FitV"); - /** A name */ - public static final PdfName FITR = new PdfName("FitR"); - /** A name */ - public static final PdfName FITB = new PdfName("FitB"); - /** A name */ - public static final PdfName FITBH = new PdfName("FitBH"); - /** A name */ - public static final PdfName FITBV = new PdfName("FitBV"); - /** A name */ - public static final PdfName FITWINDOW = new PdfName("FitWindow"); - /** A name */ - public static final PdfName FLAGS = new PdfName("Flags"); - /** A name */ - public static final PdfName FLATEDECODE = new PdfName("FlateDecode"); - /** A name */ - public static final PdfName FO = new PdfName("Fo"); - /** A name */ - public static final PdfName FONT = new PdfName("Font"); - /** A name */ - public static final PdfName FONTBBOX = new PdfName("FontBBox"); - /** A name */ - public static final PdfName FONTDESCRIPTOR = new PdfName("FontDescriptor"); - /** A name */ - public static final PdfName FONTFILE = new PdfName("FontFile"); - /** A name */ - public static final PdfName FONTFILE2 = new PdfName("FontFile2"); - /** A name */ - public static final PdfName FONTFILE3 = new PdfName("FontFile3"); - /** A name */ - public static final PdfName FONTMATRIX = new PdfName("FontMatrix"); - /** A name */ - public static final PdfName FONTNAME = new PdfName("FontName"); - /** A name */ - public static final PdfName FORM = new PdfName("Form"); - /** A name */ - public static final PdfName FORMTYPE = new PdfName("FormType"); - /** A name */ - public static final PdfName FREETEXT = new PdfName("FreeText"); - /** A name */ - public static final PdfName FRM = new PdfName("FRM"); - /** A name */ - public static final PdfName FS = new PdfName("FS"); - /** A name */ - public static final PdfName FT = new PdfName("FT"); - /** A name */ - public static final PdfName FULLSCREEN = new PdfName("FullScreen"); - /** A name */ - public static final PdfName FUNCTION = new PdfName("Function"); - /** A name */ - public static final PdfName FUNCTIONS = new PdfName("Functions"); - /** A name */ - public static final PdfName FUNCTIONTYPE = new PdfName("FunctionType"); - /** A name of an attribute. */ - public static final PdfName GAMMA = new PdfName("Gamma"); - /** A name of an attribute. */ - public static final PdfName GBK = new PdfName("GBK"); - /** A name of an attribute. */ - public static final PdfName GLITTER = new PdfName("Glitter"); - /** A name of an attribute. */ - public static final PdfName GOTO = new PdfName("GoTo"); - /** A name of an attribute. */ - public static final PdfName GOTOR = new PdfName("GoToR"); - /** A name of an attribute. */ - public static final PdfName GROUP = new PdfName("Group"); - /** A name of an attribute. */ - public static final PdfName GTS_PDFX = new PdfName("GTS_PDFX"); - /** A name of an attribute. */ - public static final PdfName GTS_PDFXVERSION = new PdfName("GTS_PDFXVersion"); - /** A name of an attribute. */ - public static final PdfName H = new PdfName("H"); - /** A name of an attribute. */ - public static final PdfName HEIGHT = new PdfName("Height"); - /** A name of a base 14 type 1 font */ - public static final PdfName HELVETICA = new PdfName("Helvetica"); - /** A name of a base 14 type 1 font */ - public static final PdfName HELVETICA_BOLD = new PdfName("Helvetica-Bold"); - /** This is a static PdfName PdfName of a base 14 type 1 font */ - public static final PdfName HELVETICA_OBLIQUE = new PdfName("Helvetica-Oblique"); - /** This is a static PdfName PdfName of a base 14 type 1 font */ - public static final PdfName HELVETICA_BOLDOBLIQUE = new PdfName("Helvetica-BoldOblique"); - /** A name */ - public static final PdfName HID = new PdfName("Hid"); - /** A name */ - public static final PdfName HIDE = new PdfName("Hide"); - /** A name */ - public static final PdfName HIDEMENUBAR = new PdfName("HideMenubar"); - /** A name */ - public static final PdfName HIDETOOLBAR = new PdfName("HideToolbar"); - /** A name */ - public static final PdfName HIDEWINDOWUI = new PdfName("HideWindowUI"); - /** A name */ - public static final PdfName HIGHLIGHT = new PdfName("Highlight"); - /** A name */ - public static final PdfName I = new PdfName("I"); - /** A name */ - public static final PdfName ICCBASED = new PdfName("ICCBased"); - /** A name */ - public static final PdfName ID = new PdfName("ID"); - /** A name */ - public static final PdfName IDENTITY = new PdfName("Identity"); - /** A name */ - public static final PdfName IF = new PdfName("IF"); - /** A name */ - public static final PdfName IMAGE = new PdfName("Image"); - /** A name */ - public static final PdfName IMAGEB = new PdfName("ImageB"); - /** A name */ - public static final PdfName IMAGEC = new PdfName("ImageC"); - /** A name */ - public static final PdfName IMAGEI = new PdfName("ImageI"); - /** A name */ - public static final PdfName IMAGEMASK = new PdfName("ImageMask"); - /** A name */ - public static final PdfName INDEX = new PdfName("Index"); - /** A name */ - public static final PdfName INDEXED = new PdfName("Indexed"); - /** A name */ - public static final PdfName INFO = new PdfName("Info"); - /** A name */ - public static final PdfName INK = new PdfName("Ink"); - /** A name */ - public static final PdfName INKLIST = new PdfName("InkList"); - /** A name */ - public static final PdfName IMPORTDATA = new PdfName("ImportData"); - /** A name */ - public static final PdfName INTENT = new PdfName("Intent"); - /** A name */ - public static final PdfName INTERPOLATE = new PdfName("Interpolate"); - /** A name */ - public static final PdfName ISMAP = new PdfName("IsMap"); - /** A name */ - public static final PdfName IRT = new PdfName("IRT"); - /** A name */ - public static final PdfName ITALICANGLE = new PdfName("ItalicAngle"); - /** A name */ - public static final PdfName IX = new PdfName("IX"); - /** A name */ - public static final PdfName JAVASCRIPT = new PdfName("JavaScript"); - /** A name */ - public static final PdfName JS = new PdfName("JS"); - /** A name */ - public static final PdfName K = new PdfName("K"); - /** A name */ - public static final PdfName KEYWORDS = new PdfName("Keywords"); - /** A name */ - public static final PdfName KIDS = new PdfName("Kids"); - /** A name */ - public static final PdfName L = new PdfName("L"); - /** A name */ - public static final PdfName L2R = new PdfName("L2R"); - /** A name */ - public static final PdfName LANG = new PdfName("Lang"); - /** A name */ - public static final PdfName LANGUAGE = new PdfName("Language"); - /** A name */ - public static final PdfName LAST = new PdfName("Last"); - /** A name */ - public static final PdfName LASTCHAR = new PdfName("LastChar"); - /** A name */ - public static final PdfName LASTPAGE = new PdfName("LastPage"); - /** A name */ - public static final PdfName LAUNCH = new PdfName("Launch"); - /** A name */ - public static final PdfName LENGTH = new PdfName("Length"); - /** A name */ - public static final PdfName LENGTH1 = new PdfName("Length1"); - /** A name */ - public static final PdfName LIMITS = new PdfName("Limits"); - /** A name */ - public static final PdfName LINE = new PdfName("Line"); - /** A name */ - public static final PdfName LINK = new PdfName("Link"); - /** A name */ - public static final PdfName LISTMODE = new PdfName("ListMode"); - /** A name */ - public static final PdfName LOCATION = new PdfName("Location"); - /** A name */ - public static final PdfName LOCK = new PdfName("Lock"); - /** A name */ - public static final PdfName LZWDECODE = new PdfName("LZWDecode"); - /** A name */ - public static final PdfName M = new PdfName("M"); - /** A name */ - public static final PdfName MATRIX = new PdfName("Matrix"); - /** A name of an encoding */ - public static final PdfName MAC_EXPERT_ENCODING = new PdfName("MacExpertEncoding"); - /** A name of an encoding */ - public static final PdfName MAC_ROMAN_ENCODING = new PdfName("MacRomanEncoding"); - /** A name */ - public static final PdfName MARKED = new PdfName("Marked"); - /** A name */ - public static final PdfName MARKINFO = new PdfName("MarkInfo"); - /** A name */ - public static final PdfName MASK = new PdfName("Mask"); - /** A name */ - public static final PdfName MAX = new PdfName("max"); - /** A name */ - public static final PdfName MAXLEN = new PdfName("MaxLen"); - /** A name */ - public static final PdfName MEDIABOX = new PdfName("MediaBox"); - /** A name */ - public static final PdfName MCID = new PdfName("MCID"); - /** A name */ - public static final PdfName MCR = new PdfName("MCR"); - /** A name */ - public static final PdfName METADATA = new PdfName("Metadata"); - /** A name */ - public static final PdfName MIN = new PdfName("min"); - /** A name */ - public static final PdfName MK = new PdfName("MK"); - /** A name */ - public static final PdfName MMTYPE1 = new PdfName("MMType1"); - /** A name */ - public static final PdfName MODDATE = new PdfName("ModDate"); - /** A name */ - public static final PdfName N = new PdfName("N"); - /** A name */ - public static final PdfName N0 = new PdfName("n0"); - /** A name */ - public static final PdfName N1 = new PdfName("n1"); - /** A name */ - public static final PdfName N2 = new PdfName("n2"); - /** A name */ - public static final PdfName N3 = new PdfName("n3"); - /** A name */ - public static final PdfName N4 = new PdfName("n4"); - /** A name */ - public static final PdfName NAME = new PdfName("Name"); - /** A name */ - public static final PdfName NAMED = new PdfName("Named"); - /** A name */ - public static final PdfName NAMES = new PdfName("Names"); - /** A name */ - public static final PdfName NEEDAPPEARANCES = new PdfName("NeedAppearances"); - /** A name */ - public static final PdfName NEWWINDOW = new PdfName("NewWindow"); - /** A name */ - public static final PdfName NEXT = new PdfName("Next"); - /** A name */ - public static final PdfName NEXTPAGE = new PdfName("NextPage"); - /** A name */ - public static final PdfName NM = new PdfName("NM"); - /** A name */ - public static final PdfName NONE = new PdfName("None"); - /** A name */ - public static final PdfName NONFULLSCREENPAGEMODE = new PdfName("NonFullScreenPageMode"); - /** A name */ - public static final PdfName NUMS = new PdfName("Nums"); - /** A name */ - public static final PdfName O = new PdfName("O"); - /** A name */ - public static final PdfName OBJSTM = new PdfName("ObjStm"); - /** A name */ - public static final PdfName OC = new PdfName("OC"); - /** A name */ - public static final PdfName OCG = new PdfName("OCG"); - /** A name */ - public static final PdfName OCGS = new PdfName("OCGs"); - /** A name */ - public static final PdfName OCMD = new PdfName("OCMD"); - /** A name */ - public static final PdfName OCPROPERTIES = new PdfName("OCProperties"); - /** A name */ - public static final PdfName Off = new PdfName("Off"); - /** A name */ - public static final PdfName OFF = new PdfName("OFF"); - /** A name */ - public static final PdfName ON = new PdfName("ON"); - /** A name */ - public static final PdfName ONECOLUMN = new PdfName("OneColumn"); - /** A name */ - public static final PdfName OPEN = new PdfName("Open"); - /** A name */ - public static final PdfName OPENACTION = new PdfName("OpenAction"); - /** A name */ - public static final PdfName OP = new PdfName("OP"); - /** A name */ - public static final PdfName op = new PdfName("op"); - /** A name */ - public static final PdfName OPM = new PdfName("OPM"); - /** A name */ - public static final PdfName OPT = new PdfName("Opt"); - /** A name */ - public static final PdfName ORDER = new PdfName("Order"); - /** A name */ - public static final PdfName ORDERING = new PdfName("Ordering"); - /** A name */ - public static final PdfName OUTLINES = new PdfName("Outlines"); - /** A name */ - public static final PdfName OUTPUTCONDITION = new PdfName("OutputCondition"); - /** A name */ - public static final PdfName OUTPUTCONDITIONIDENTIFIER = new PdfName("OutputConditionIdentifier"); - /** A name */ - public static final PdfName OUTPUTINTENT = new PdfName("OutputIntent"); - /** A name */ - public static final PdfName OUTPUTINTENTS = new PdfName("OutputIntents"); - /** A name */ - public static final PdfName P = new PdfName("P"); - /** A name */ - public static final PdfName PAGE = new PdfName("Page"); - /** A name */ - public static final PdfName PAGELABELS = new PdfName("PageLabels"); - /** A name */ - public static final PdfName PAGELAYOUT = new PdfName("PageLayout"); - /** A name */ - public static final PdfName PAGEMODE = new PdfName("PageMode"); - /** A name */ - public static final PdfName PAGES = new PdfName("Pages"); - /** A name */ - public static final PdfName PAINTTYPE = new PdfName("PaintType"); - /** A name */ - public static final PdfName PANOSE = new PdfName("Panose"); - /** A name */ - public static final PdfName PARAMS = new PdfName("Params"); - /** A name */ - public static final PdfName PARENT = new PdfName("Parent"); - /** A name */ - public static final PdfName PARENTTREE = new PdfName("ParentTree"); - /** A name */ - public static final PdfName PATTERN = new PdfName("Pattern"); - /** A name */ - public static final PdfName PATTERNTYPE = new PdfName("PatternType"); - /** A name */ - public static final PdfName PDF = new PdfName("PDF"); - /** A name */ - public static final PdfName PERCEPTUAL = new PdfName("Perceptual"); - /** A name */ - public static final PdfName PG = new PdfName("Pg"); - /** A name */ - public static final PdfName POPUP = new PdfName("Popup"); - /** A name */ - public static final PdfName PREDICTOR = new PdfName("Predictor"); - /** A name */ - public static final PdfName PREFERRED = new PdfName("Preferred"); - /** A name */ - public static final PdfName PRESERVERB = new PdfName("PreserveRB"); - /** A name */ - public static final PdfName PREV = new PdfName("Prev"); - /** A name */ - public static final PdfName PREVPAGE = new PdfName("PrevPage"); - /** A name */ - public static final PdfName PRINT = new PdfName("Print"); - /** A name */ - public static final PdfName PRINTSCALING = new PdfName("PrintScaling"); - /** A name */ - public static final PdfName PRINTSTATE = new PdfName("PrintState"); - /** A name */ - public static final PdfName PROCSET = new PdfName("ProcSet"); - /** A name */ - public static final PdfName PRODUCER = new PdfName("Producer"); - /** A name */ - public static final PdfName PROPERTIES = new PdfName("Properties"); - /** A name */ - public static final PdfName PS = new PdfName("PS"); - /** A name */ - public static final PdfName Q = new PdfName("Q"); - /** A name */ - public static final PdfName QUADPOINTS = new PdfName("QuadPoints"); - /** A name */ - public static final PdfName R = new PdfName("R"); - /** A name */ - public static final PdfName R2L = new PdfName("R2L"); - /** A name */ - public static final PdfName RANGE = new PdfName("Range"); - /** A name */ - public static final PdfName RC = new PdfName("RC"); - /** A name */ - public static final PdfName RBGROUPS = new PdfName("RBGroups"); - /** A name */ - public static final PdfName REASON = new PdfName("Reason"); - /** A name */ - public static final PdfName RECT = new PdfName("Rect"); - /** A name */ - public static final PdfName REGISTRY = new PdfName("Registry"); - /** A name */ - public static final PdfName REGISTRYNAME = new PdfName("RegistryName"); - /** A name */ - public static final PdfName RELATIVECALORIMETRIC = new PdfName("RelativeColorimetric"); - /** A name */ - public static final PdfName RENDITION = new PdfName("Rendition"); - /** A name */ - public static final PdfName RESETFORM = new PdfName("ResetForm"); - /** A name */ - public static final PdfName RESOURCES = new PdfName("Resources"); - /** A name */ - public static final PdfName RI = new PdfName("RI"); - /** A name */ - public static final PdfName ROLEMAP = new PdfName("RoleMap"); - /** A name */ - public static final PdfName ROOT = new PdfName("Root"); - /** A name */ - public static final PdfName ROTATE = new PdfName("Rotate"); - /** A name */ - public static final PdfName ROWS = new PdfName("Rows"); - /** A name */ - public static final PdfName RUNLENGTHDECODE = new PdfName("RunLengthDecode"); - /** A name */ - public static final PdfName RV = new PdfName("RV"); - /** A name */ - public static final PdfName S = new PdfName("S"); - /** A name */ - public static final PdfName SATURATION = new PdfName("Saturation"); - /** A name */ - public static final PdfName SCREEN = new PdfName("Screen"); - /** A name */ - public static final PdfName SEPARATION = new PdfName("Separation"); - /** A name */ - public static final PdfName SETOCGSTATE = new PdfName("SetOCGState"); - /** A name */ - public static final PdfName SHADING = new PdfName("Shading"); - /** A name */ - public static final PdfName SHADINGTYPE = new PdfName("ShadingType"); - /** A name */ - public static final PdfName SHIFT_JIS = new PdfName("Shift-JIS"); - /** A name */ - public static final PdfName SIG = new PdfName("Sig"); - /** A name */ - public static final PdfName SIGFLAGS = new PdfName("SigFlags"); - /** A name */ - public static final PdfName SINGLEPAGE = new PdfName("SinglePage"); - /** A name */ - public static final PdfName SIZE = new PdfName("Size"); - /** A name */ - public static final PdfName SMASK = new PdfName("SMask"); - /** A name */ - public static final PdfName SPLIT = new PdfName("Split"); - /** A name */ - public static final PdfName SQUARE = new PdfName("Square"); - /** A name */ - public static final PdfName ST = new PdfName("St"); - /** A name */ - public static final PdfName STAMP = new PdfName("Stamp"); - /** A name */ - public static final PdfName STANDARD = new PdfName("Standard"); - /** A name */ - public static final PdfName STATE = new PdfName("State"); - /** A name */ - public static final PdfName STRIKEOUT = new PdfName("StrikeOut"); - /** A name */ - public static final PdfName STRUCTPARENT = new PdfName("StructParent"); - /** A name */ - public static final PdfName STRUCTPARENTS = new PdfName("StructParents"); - /** A name */ - public static final PdfName STRUCTTREEROOT = new PdfName("StructTreeRoot"); - /** A name */ - public static final PdfName STYLE = new PdfName("Style"); - /** A name */ - public static final PdfName STEMV = new PdfName("StemV"); - /** A name */ - public static final PdfName SUBFILTER = new PdfName("SubFilter"); - /** A name */ - public static final PdfName SUBJECT = new PdfName("Subject"); - /** A name */ - public static final PdfName SUBMITFORM = new PdfName("SubmitForm"); - /** A name */ - public static final PdfName SUBTYPE = new PdfName("Subtype"); - /** A name */ - public static final PdfName SUPPLEMENT = new PdfName("Supplement"); - /** A name */ - public static final PdfName SV = new PdfName("SV"); - /** A name */ - public static final PdfName SW = new PdfName("SW"); - /** A name of a base 14 type 1 font */ - public static final PdfName SYMBOL = new PdfName("Symbol"); - /** A name */ - public static final PdfName T = new PdfName("T"); - /** A name */ - public static final PdfName TEXT = new PdfName("Text"); - /** A name */ - public static final PdfName THUMB = new PdfName("Thumb"); - /** A name */ - public static final PdfName THREADS = new PdfName("Threads"); - /** A name */ - public static final PdfName TI = new PdfName("TI"); - /** A name */ - public static final PdfName TILINGTYPE = new PdfName("TilingType"); - /** A name of a base 14 type 1 font */ - public static final PdfName TIMES_ROMAN = new PdfName("Times-Roman"); - /** A name of a base 14 type 1 font */ - public static final PdfName TIMES_BOLD = new PdfName("Times-Bold"); - /** A name of a base 14 type 1 font */ - public static final PdfName TIMES_ITALIC = new PdfName("Times-Italic"); - /** A name of a base 14 type 1 font */ - public static final PdfName TIMES_BOLDITALIC = new PdfName("Times-BoldItalic"); - /** A name */ - public static final PdfName TITLE = new PdfName("Title"); - /** A name */ - public static final PdfName TK = new PdfName("TK"); - /** A name */ - public static final PdfName TM = new PdfName("TM"); - /** A name */ - public static final PdfName TOGGLE = new PdfName("Toggle"); - /** A name */ - public static final PdfName TOUNICODE = new PdfName("ToUnicode"); - /** A name */ - public static final PdfName TP = new PdfName("TP"); - /** A name */ - public static final PdfName TRANS = new PdfName("Trans"); - /** A name */ - public static final PdfName TRANSPARENCY = new PdfName("Transparency"); - /** A name */ - public static final PdfName TRAPPED = new PdfName("Trapped"); - /** A name */ - public static final PdfName TRIMBOX = new PdfName("TrimBox"); - /** A name */ - public static final PdfName TRUETYPE = new PdfName("TrueType"); - /** A name */ - public static final PdfName TU = new PdfName("TU"); - /** A name */ - public static final PdfName TWOCOLUMNLEFT = new PdfName("TwoColumnLeft"); - /** A name */ - public static final PdfName TWOCOLUMNRIGHT = new PdfName("TwoColumnRight"); - /** A name */ - public static final PdfName TWOPAGELEFT = new PdfName("TwoPageLeft"); - /** A name */ - public static final PdfName TWOPAGERIGHT = new PdfName("TwoPageRight"); - /** A name */ - public static final PdfName TX = new PdfName("Tx"); - /** A name */ - public static final PdfName TYPE = new PdfName("Type"); - /** A name */ - public static final PdfName TYPE0 = new PdfName("Type0"); - /** A name */ - public static final PdfName TYPE1 = new PdfName("Type1"); - /** A name of an attribute. */ - public static final PdfName TYPE3 = new PdfName("Type3"); - /** A name of an attribute. */ - public static final PdfName U = new PdfName("U"); - /** A name of an attribute. */ - public static final PdfName UHC = new PdfName("UHC"); - /** A name of an attribute. */ - public static final PdfName UNDERLINE = new PdfName("Underline"); - /** A name */ - public static final PdfName URI = new PdfName("URI"); - /** A name */ - public static final PdfName URL = new PdfName("URL"); - /** A name */ - public static final PdfName USAGE = new PdfName("Usage"); - /** A name */ - public static final PdfName USEATTACHMENTS = new PdfName("UseAttachments"); - /** A name */ - public static final PdfName USENONE = new PdfName("UseNone"); - /** A name */ - public static final PdfName USEOC = new PdfName("UseOC"); - /** A name */ - public static final PdfName USEOUTLINES = new PdfName("UseOutlines"); - /** A name */ - public static final PdfName USER = new PdfName("User"); - /** A name */ - public static final PdfName USERUNIT = new PdfName("UserUnit"); - /** A name */ - public static final PdfName USETHUMBS = new PdfName("UseThumbs"); - /** A name */ - public static final PdfName V = new PdfName("V"); - /** A name */ - public static final PdfName VERISIGN_PPKVS = new PdfName("VeriSign.PPKVS"); - /** A name */ - public static final PdfName VIEW = new PdfName("View"); - /** A name */ - public static final PdfName VIEWERPREFERENCES = new PdfName("ViewerPreferences"); - /** A name */ - public static final PdfName VIEWSTATE = new PdfName("ViewState"); - /** A name */ - public static final PdfName VISIBLEPAGES = new PdfName("VisiblePages"); - /** A name of an attribute. */ - public static final PdfName W = new PdfName("W"); - /** A name of an attribute. */ - public static final PdfName W2 = new PdfName("W2"); - /** A name of an attribute. */ - public static final PdfName WC = new PdfName("WC"); - /** A name of an attribute. */ - public static final PdfName WIDGET = new PdfName("Widget"); - /** A name of an attribute. */ - public static final PdfName WIDTH = new PdfName("Width"); - /** A name */ - public static final PdfName WIDTHS = new PdfName("Widths"); - /** A name of an encoding */ - public static final PdfName WIN = new PdfName("Win"); - /** A name of an encoding */ - public static final PdfName WIN_ANSI_ENCODING = new PdfName("WinAnsiEncoding"); - /** A name of an encoding */ - public static final PdfName WIPE = new PdfName("Wipe"); - /** A name */ - public static final PdfName WHITEPOINT = new PdfName("WhitePoint"); - /** A name */ - public static final PdfName WP = new PdfName("WP"); - /** A name of an encoding */ - public static final PdfName WS = new PdfName("WS"); - /** A name */ - public static final PdfName X = new PdfName("X"); - /** A name */ - public static final PdfName XFA = new PdfName("XFA"); - /** A name */ - public static final PdfName XML = new PdfName("XML"); - /** A name */ - public static final PdfName XOBJECT = new PdfName("XObject"); - /** A name */ - public static final PdfName XSTEP = new PdfName("XStep"); - /** A name */ - public static final PdfName XREF = new PdfName("XRef"); - /** A name */ - public static final PdfName XREFSTM = new PdfName("XRefStm"); - /** A name */ - public static final PdfName XYZ = new PdfName("XYZ"); - /** A name */ - public static final PdfName YSTEP = new PdfName("YStep"); - /** A name of a base 14 type 1 font */ - public static final PdfName ZAPFDINGBATS = new PdfName("ZapfDingbats"); - /** A name */ - public static final PdfName ZOOM = new PdfName("Zoom"); - - private int hash = 0; - - // constructors - - - /** - * Constructs a new PdfName. The name length will be checked. - * @param name the new name - */ - public PdfName(String name) { - this(name, true); - } - - /** - * Constructs a new PdfName. - * @param name the new name - * @param lengthCheck if true check the lenght validity, if false the name can - * have any length - */ - - public PdfName(String name, boolean lengthCheck) { - super(PdfObject.NAME); - // The minimum number of characters in a name is 0, the maximum is 127 (the '/' not included) - int length = name.length(); - if (lengthCheck && length > 127) { - throw new IllegalArgumentException("The name '" + name + "' is too long (" + length + " characters)."); - } - // The name has to be checked for illegal characters - // every special character has to be substituted - ByteBuffer pdfName = new ByteBuffer(length + 20); - pdfName.append('/'); - char character; - char chars[] = name.toCharArray(); - // loop over all the characters - for (int index = 0; index < length; index++) { - character = (char)(chars[index] & 0xff); - // special characters are escaped (reference manual p.39) - switch (character) { - case ' ': - case '%': - case '(': - case ')': - case '<': - case '>': - case '[': - case ']': - case '{': - case '}': - case '/': - case '#': - pdfName.append('#'); - pdfName.append(Integer.toString((int) character, 16)); - break; - default: - if (character > 126 || character < 32) { - pdfName.append('#'); - if (character < 16) - pdfName.append('0'); - pdfName.append(Integer.toString((int) character, 16)); - } - else - pdfName.append(character); - break; - } - } - bytes = pdfName.toByteArray(); - } - - /** - * Constructs a PdfName. - * @param bytes the byte representation of the name - */ - public PdfName(byte bytes[]) { - super(PdfObject.NAME, bytes); - } - // methods - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer as this object is less - * than, equal to, or greater than the specified object.

- * @param object the Object to be compared. - * @return a negative integer, zero, or a positive integer as this object - * is less than, equal to, or greater than the specified object. - * @throws ClassCastException if the specified object's type prevents it - * from being compared to this Object. - */ - public int compareTo(Object object) { - PdfName name = (PdfName) object; - - byte myBytes[] = bytes; - byte objBytes[] = name.bytes; - int len = Math.min(myBytes.length, objBytes.length); - for(int i=0; i objBytes[i]) - return 1; - - if(myBytes[i] < objBytes[i]) - return -1; - } - if (myBytes.length < objBytes.length) - return -1; - if (myBytes.length > objBytes.length) - return 1; - return 0; - } - - /** - * Indicates whether some other object is "equal to" this one. - * - * @param obj the reference object with which to compare. - * @return true if this object is the same as the obj - * argument; false otherwise. - */ - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj instanceof PdfName) - return compareTo(obj) == 0; - return false; - } - - /** - * Returns a hash code value for the object. This method is - * supported for the benefit of hashtables such as those provided by - * java.util.Hashtable. - * - * @return a hash code value for this object. - */ - public int hashCode() { - int h = hash; - if (h == 0) { - int ptr = 0; - int len = bytes.length; - - for (int i = 0; i < len; i++) - h = 31*h + (bytes[ptr++] & 0xff); - hash = h; - } - return h; - } - - /** Decodes an escaped name in the form "/AB#20CD" into "AB CD". - * @param name the name to decode - * @return the decoded name - */ - public static String decodeName(String name) { - StringBuffer buf = new StringBuffer(); - try { - int len = name.length(); - for (int k = 1; k < len; ++k) { - char c = name.charAt(k); - if (c == '#') { - c = (char)((PRTokeniser.getHex(name.charAt(k + 1)) << 4) + PRTokeniser.getHex(name.charAt(k + 2))); - k += 2; - } - buf.append(c); - } - } - catch (IndexOutOfBoundsException e) { - // empty on purpose - } - return buf.toString(); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfNameTree.java b/src/main/java/com/lowagie/text/pdf/PdfNameTree.java deleted file mode 100644 index 999fca8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfNameTree.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.HashMap; -import java.util.Arrays; -import java.util.ArrayList; -import java.io.IOException; -import com.lowagie.text.StringCompare; - -/** - * Creates a name tree. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfNameTree { - - private static final int leafSize = 64; - private static final StringCompare stringCompare = new StringCompare(); - - /** - * Creates a name tree. - * @param items the item of the name tree. The key is a String - * and the value is a PdfObject. Note that although the - * keys are strings only the lower byte is used and no check is made for chars - * with the same lower byte and different upper byte. This will generate a wrong - * tree name. - * @param writer the writer - * @throws IOException on error - * @return the dictionary with the name tree. This dictionary is the one - * generally pointed to by the key /Dests, for example - */ - public static PdfDictionary writeTree(HashMap items, PdfWriter writer) throws IOException { - if (items.size() == 0) - return null; - String names[] = new String[items.size()]; - names = (String[])items.keySet().toArray(names); - Arrays.sort(names, stringCompare); - if (names.length <= leafSize) { - PdfDictionary dic = new PdfDictionary(); - PdfArray ar = new PdfArray(); - for (int k = 0; k < names.length; ++k) { - ar.add(new PdfString(names[k], null)); - ar.add((PdfObject)items.get(names[k])); - } - dic.put(PdfName.NAMES, ar); - return dic; - } - int skip = leafSize; - PdfIndirectReference kids[] = new PdfIndirectReference[(names.length + leafSize - 1) / leafSize]; - for (int k = 0; k < kids.length; ++k) { - int offset = k * leafSize; - int end = Math.min(offset + leafSize, names.length); - PdfDictionary dic = new PdfDictionary(); - PdfArray arr = new PdfArray(); - arr.add(new PdfString(names[offset], null)); - arr.add(new PdfString(names[end - 1], null)); - dic.put(PdfName.LIMITS, arr); - arr = new PdfArray(); - for (; offset < end; ++offset) { - arr.add(new PdfString(names[offset], null)); - arr.add((PdfObject)items.get(names[offset])); - } - dic.put(PdfName.NAMES, arr); - kids[k] = writer.addToBody(dic).getIndirectReference(); - } - int top = kids.length; - while (true) { - if (top <= leafSize) { - PdfArray arr = new PdfArray(); - for (int k = 0; k < top; ++k) - arr.add(kids[k]); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.KIDS, arr); - return dic; - } - skip *= leafSize; - int tt = (names.length + skip - 1 )/ skip; - for (int k = 0; k < tt; ++k) { - int offset = k * leafSize; - int end = Math.min(offset + leafSize, top); - PdfDictionary dic = new PdfDictionary(); - PdfArray arr = new PdfArray(); - arr.add(new PdfString(names[k * skip], null)); - arr.add(new PdfString(names[Math.min((k + 1) * skip, names.length) - 1], null)); - dic.put(PdfName.LIMITS, arr); - arr = new PdfArray(); - for (; offset < end; ++offset) { - arr.add(kids[offset]); - } - dic.put(PdfName.KIDS, arr); - kids[k] = writer.addToBody(dic).getIndirectReference(); - } - top = tt; - } - } - - private static void iterateItems(PdfDictionary dic, HashMap items) { - PdfArray nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.NAMES)); - if (nn != null) { - ArrayList arr = nn.getArrayList(); - for (int k = 0; k < arr.size(); ++k) { - PdfString s = (PdfString)PdfReader.getPdfObjectRelease((PdfObject)arr.get(k++)); - items.put(PdfEncodings.convertToString(s.getBytes(), null), arr.get(k)); - } - } - else if ((nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.KIDS))) != null) { - ArrayList arr = nn.getArrayList(); - for (int k = 0; k < arr.size(); ++k) { - PdfDictionary kid = (PdfDictionary)PdfReader.getPdfObjectRelease((PdfObject)arr.get(k)); - iterateItems(kid, items); - } - } - } - - public static HashMap readTree(PdfDictionary dic) { - HashMap items = new HashMap(); - if (dic != null) - iterateItems(dic, items); - return items; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfNull.java b/src/main/java/com/lowagie/text/pdf/PdfNull.java deleted file mode 100644 index ab40b32..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfNull.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * $Id: PdfNull.java,v 1.55 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfNull is the Null object represented by the keyword null. - *

- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.9 (page 53). - * - * @see PdfObject - */ - -public class PdfNull extends PdfObject { - - // static membervariables - -/** This is an instance of the PdfNull-object. */ - public static final PdfNull PDFNULL = new PdfNull(); - -/** This is the content of a PdfNull-object. */ - private static final String CONTENT = "null"; - - // constructors - -/** - * Constructs a PdfNull-object. - *

- * You never need to do this yourself, you can always use the static final object PDFNULL. - */ - - public PdfNull() { - super(NULL, CONTENT); - } - - public String toString() { - return "null"; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfNumber.java b/src/main/java/com/lowagie/text/pdf/PdfNumber.java deleted file mode 100644 index 07faf07..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfNumber.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * $Id: PdfNumber.java,v 1.56 2005/05/04 14:32:42 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfNumber provides two types of numbers, integer and real. - *

- * Integers may be specified by signed or unsigned constants. Reals may only be - * in decimal format.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.3 (page 37). - * - * @see PdfObject - * @see BadPdfFormatException - */ - -public class PdfNumber extends PdfObject { - -/** actual value of this PdfNumber, represented as a double */ - private double value; - - // constructors - -/** - * Constructs a PdfNumber-object. - * - * @param content value of the new PdfNumber-object - */ - - public PdfNumber(String content) { - super(NUMBER); - try { - value = Double.valueOf(content.trim()).doubleValue(); - setContent(content); - } - catch (NumberFormatException nfe){ - throw new RuntimeException(content + " is not a valid number - " + nfe.toString()); - } - } - -/** - * Constructs a new INTEGER PdfNumber-object. - * - * @param value value of the new PdfNumber-object - */ - - public PdfNumber(int value) { - super(NUMBER); - this.value = value; - setContent(String.valueOf(value)); - } - -/** - * Constructs a new REAL PdfNumber-object. - * - * @param value value of the new PdfNumber-object - */ - - public PdfNumber(double value) { - super(NUMBER); - this.value = value; - setContent(ByteBuffer.formatDouble(value)); - } - -/** - * Constructs a new REAL PdfNumber-object. - * - * @param value value of the new PdfNumber-object - */ - - public PdfNumber(float value) { - this((double)value); - } - - // methods returning the value of this object - -/** - * Returns the primitive int value of this object. - * - * @return a value - */ - - public int intValue() { - return (int) value; - } - -/** - * Returns the primitive double value of this object. - * - * @return a value - */ - - public double doubleValue() { - return value; - } - - public float floatValue() { - return (float)value; - } - - // other methods - -/** - * Increments the value of the PdfNumber-object with 1. - */ - - public void increment() { - value += 1.0; - setContent(ByteBuffer.formatDouble(value)); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfNumberTree.java b/src/main/java/com/lowagie/text/pdf/PdfNumberTree.java deleted file mode 100644 index 8e39c1d..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfNumberTree.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.HashMap; -import java.util.Arrays; -import java.util.ArrayList; -import java.io.IOException; - -/** - * Creates a number tree. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfNumberTree { - - private static final int leafSize = 64; - - /** - * Creates a number tree. - * @param items the item of the number tree. The key is an Integer - * and the value is a PdfObject. - * @param writer the writer - * @throws IOException on error - * @return the dictionary with the number tree. - */ - public static PdfDictionary writeTree(HashMap items, PdfWriter writer) throws IOException { - if (items.size() == 0) - return null; - Integer numbers[] = new Integer[items.size()]; - numbers = (Integer[])items.keySet().toArray(numbers); - Arrays.sort(numbers); - if (numbers.length <= leafSize) { - PdfDictionary dic = new PdfDictionary(); - PdfArray ar = new PdfArray(); - for (int k = 0; k < numbers.length; ++k) { - ar.add(new PdfNumber(numbers[k].intValue())); - ar.add((PdfObject)items.get(numbers[k])); - } - dic.put(PdfName.NUMS, ar); - return dic; - } - int skip = leafSize; - PdfIndirectReference kids[] = new PdfIndirectReference[(numbers.length + leafSize - 1) / leafSize]; - for (int k = 0; k < kids.length; ++k) { - int offset = k * leafSize; - int end = Math.min(offset + leafSize, numbers.length); - PdfDictionary dic = new PdfDictionary(); - PdfArray arr = new PdfArray(); - arr.add(new PdfNumber(numbers[offset].intValue())); - arr.add(new PdfNumber(numbers[end - 1].intValue())); - dic.put(PdfName.LIMITS, arr); - arr = new PdfArray(); - for (; offset < end; ++offset) { - arr.add(new PdfNumber(numbers[offset].intValue())); - arr.add((PdfObject)items.get(numbers[offset])); - } - dic.put(PdfName.NUMS, arr); - kids[k] = writer.addToBody(dic).getIndirectReference(); - } - int top = kids.length; - while (true) { - if (top <= leafSize) { - PdfArray arr = new PdfArray(); - for (int k = 0; k < top; ++k) - arr.add(kids[k]); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.KIDS, arr); - return dic; - } - skip *= leafSize; - int tt = (numbers.length + skip - 1 )/ skip; - for (int k = 0; k < tt; ++k) { - int offset = k * leafSize; - int end = Math.min(offset + leafSize, top); - PdfDictionary dic = new PdfDictionary(); - PdfArray arr = new PdfArray(); - arr.add(new PdfNumber(numbers[k * skip].intValue())); - arr.add(new PdfNumber(numbers[Math.min((k + 1) * skip, numbers.length) - 1].intValue())); - dic.put(PdfName.LIMITS, arr); - arr = new PdfArray(); - for (; offset < end; ++offset) { - arr.add(kids[offset]); - } - dic.put(PdfName.KIDS, arr); - kids[k] = writer.addToBody(dic).getIndirectReference(); - } - top = tt; - } - } - - private static void iterateItems(PdfDictionary dic, HashMap items) { - PdfArray nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.NUMS)); - if (nn != null) { - ArrayList arr = nn.getArrayList(); - for (int k = 0; k < arr.size(); ++k) { - PdfNumber s = (PdfNumber)PdfReader.getPdfObjectRelease((PdfObject)arr.get(k++)); - items.put(new Integer(s.intValue()), arr.get(k)); - } - } - else if ((nn = (PdfArray)PdfReader.getPdfObjectRelease(dic.get(PdfName.KIDS))) != null) { - ArrayList arr = nn.getArrayList(); - for (int k = 0; k < arr.size(); ++k) { - PdfDictionary kid = (PdfDictionary)PdfReader.getPdfObjectRelease((PdfObject)arr.get(k)); - iterateItems(kid, items); - } - } - } - - public static HashMap readTree(PdfDictionary dic) { - HashMap items = new HashMap(); - if (dic != null) - iterateItems(dic, items); - return items; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfOCG.java b/src/main/java/com/lowagie/text/pdf/PdfOCG.java deleted file mode 100644 index 18809f8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfOCG.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** - * The interface common to all layer types. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public interface PdfOCG { - - /** - * Gets the PdfIndirectReference that represents this layer. - * @return the PdfIndirectReference that represents this layer - */ - public PdfIndirectReference getRef(); - - /** - * Gets the object representing the layer. - * @return the object representing the layer - */ - public PdfObject getPdfObject(); -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfOCProperties.java b/src/main/java/com/lowagie/text/pdf/PdfOCProperties.java deleted file mode 100644 index a4d0caa..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfOCProperties.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** - * This class represents the /OCProperties entry in the document catalog - * and holds the optional content properties dictionary, which contains - * a list of all the optional content groups in the document, as well as information - * about the default and alternate configurations for optional content. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfOCProperties extends PdfDictionary { - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfObject.java b/src/main/java/com/lowagie/text/pdf/PdfObject.java deleted file mode 100644 index 5b92bb4..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfObject.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * $Id: PdfObject.java,v 1.60 2005/11/29 21:05:02 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.OutputStream; -import java.io.IOException; - -/** - * PdfObject is the abstract superclass of all PDF objects. - *

- * PDF supports seven basic types of objects: Booleans, numbers, strings, names, - * arrays, dictionaries and streams. In addition, PDF provides a null object. - * Objects may be labeled so that they can be referred to by other objects.
- * All these basic PDF objects are described in the 'Portable Document Format - * Reference Manual version 1.3' Chapter 4 (pages 37-54). - * - * @see PdfNull - * @see PdfBoolean - * @see PdfNumber - * @see PdfString - * @see PdfName - * @see PdfArray - * @see PdfDictionary - * @see PdfStream - * @see PdfIndirectReference - */ - -public abstract class PdfObject { - - // static membervariables (all the possible types of a PdfObject) - -/** a possible type of PdfObject */ - public static final int BOOLEAN = 1; - -/** a possible type of PdfObject */ - public static final int NUMBER = 2; - -/** a possible type of PdfObject */ - public static final int STRING = 3; - -/** a possible type of PdfObject */ - public static final int NAME = 4; - -/** a possible type of PdfObject */ - public static final int ARRAY = 5; - -/** a possible type of PdfObject */ - public static final int DICTIONARY = 6; - -/** a possible type of PdfObject */ - public static final int STREAM = 7; - -/** a possible type of PdfObject */ - public static final int NULL = 8; - - /** a possible type of PdfObject */ - public static final int INDIRECT = 10; - -/** This is an empty string used for the PdfNull-object and for an empty PdfString-object. */ - public static final String NOTHING = ""; - -/** This is the default encoding to be used for converting Strings into bytes and vice versa. - * The default encoding is PdfDocEncoding. - */ - public static final String TEXT_PDFDOCENCODING = "PDF"; - -/** This is the encoding to be used to output text in Unicode. */ - public static final String TEXT_UNICODE = "UnicodeBig"; - - // membervariables - -/** the content of this PdfObject */ - protected byte[] bytes; - -/** the type of this PdfObject */ - protected int type; - - /** - * Holds value of property indRef. - */ - protected PRIndirectReference indRef; - - // constructors - -/** - * Constructs a PdfObject of a certain type without any content. - * - * @param type type of the new PdfObject - */ - - protected PdfObject(int type) { - this.type = type; - } - -/** - * Constructs a PdfObject of a certain type with a certain content. - * - * @param type type of the new PdfObject - * @param content content of the new PdfObject as a String. - */ - - protected PdfObject(int type, String content) { - this.type = type; - bytes = PdfEncodings.convertToBytes(content, null); - } - -/** - * Constructs a PdfObject of a certain type with a certain content. - * - * @param type type of the new PdfObject - * @param bytes content of the new PdfObject as an array of byte. - */ - - protected PdfObject(int type, byte[] bytes) { - this.bytes = bytes; - this.type = type; - } - - // methods dealing with the content of this object - -/** - * Writes the PDF representation of this PdfObject as an array of bytes to the writer. - * @param writer for backwards compatibility - * @param os the outputstream to write the bytes to. - * @throws IOException - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - if (bytes != null) - os.write(bytes); - } - - /** - * Gets the presentation of this object in a byte array - * @return a byte array - */ - public byte[] getBytes() { - return bytes; - } - - /** - * Can this object be in an object stream? - * @return true if this object can be in an object stream. - */ - public boolean canBeInObjStm() { - return (type >= 1 && type <= 6) || type == 8; - } - -/** - * Returns the length of the PDF representation of the PdfObject. - *

- * In some cases, namely for PdfString and PdfStream, - * this method differs from the method length because length - * returns the length of the actual content of the PdfObject.

- *

- * Remark: the actual content of an object is in most cases identical to its representation. - * The following statement is always true: length() >= pdfLength().

- * - * @return a length - */ - -// public int pdfLength() { -// return toPdf(null).length; -// } - -/** - * Returns the String-representation of this PdfObject. - * - * @return a String - */ - - public String toString() { - if (bytes == null) - return super.toString(); - else - return PdfEncodings.convertToString(bytes, null); - } - -/** - * Returns the length of the actual content of the PdfObject. - *

- * In some cases, namely for PdfString and PdfStream, - * this method differs from the method pdfLength because pdfLength - * returns the length of the PDF representation of the object, not of the actual content - * as does the method length.

- *

- * Remark: the actual content of an object is in some cases identical to its representation. - * The following statement is always true: length() >= pdfLength().

- * - * @return a length - */ - - public int length() { - return toString().length(); - } - -/** - * Changes the content of this PdfObject. - * - * @param content the new content of this PdfObject - */ - - protected void setContent(String content) { - bytes = PdfEncodings.convertToBytes(content, null); - } - - // methods dealing with the type of this object - -/** - * Returns the type of this PdfObject. - * - * @return a type - */ - - public int type() { - return type; - } - -/** - * Checks if this PdfObject is of the type PdfNull. - * - * @return true or false - */ - - public boolean isNull() { - return (this.type == NULL); - } - -/** - * Checks if this PdfObject is of the type PdfBoolean. - * - * @return true or false - */ - - public boolean isBoolean() { - return (this.type == BOOLEAN); - } - -/** - * Checks if this PdfObject is of the type PdfNumber. - * - * @return true or false - */ - - public boolean isNumber() { - return (this.type == NUMBER); - } - -/** - * Checks if this PdfObject is of the type PdfString. - * - * @return true or false - */ - - public boolean isString() { - return (this.type == STRING); - } - -/** - * Checks if this PdfObject is of the type PdfName. - * - * @return true or false - */ - - public boolean isName() { - return (this.type == NAME); - } - -/** - * Checks if this PdfObject is of the type PdfArray. - * - * @return true or false - */ - - public boolean isArray() { - return (this.type == ARRAY); - } - -/** - * Checks if this PdfObject is of the type PdfDictionary. - * - * @return true or false - */ - - public boolean isDictionary() { - return (this.type == DICTIONARY); - } - -/** - * Checks if this PdfObject is of the type PdfStream. - * - * @return true or false - */ - - public boolean isStream() { - return (this.type == STREAM); - } - - /** - * Checks if this is an indirect object. - * @return true if this is an indirect object - */ - public boolean isIndirect() { - return (this.type == INDIRECT); - } - - /** - * Getter for property indRef. - * @return Value of property indRef. - */ - public PRIndirectReference getIndRef() { - return this.indRef; - } - - /** - * Setter for property indRef. - * @param indRef New value of property indRef. - */ - public void setIndRef(PRIndirectReference indRef) { - this.indRef = indRef; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfOutline.java b/src/main/java/com/lowagie/text/pdf/PdfOutline.java deleted file mode 100644 index 687006c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfOutline.java +++ /dev/null @@ -1,542 +0,0 @@ -/* - * $Id: PdfOutline.java,v 1.52 2005/11/29 17:31:34 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.Iterator; - -import com.lowagie.text.Chunk; -import com.lowagie.text.Paragraph; -import java.util.ArrayList; -import java.awt.Color; -import com.lowagie.text.Font; -import java.io.OutputStream; -import java.io.IOException; - -/** - * PdfOutline is an object that represents a PDF outline entry. - *

- * An outline allows a user to access views of a document by name.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 6.7 (page 104-106) - * - * @see PdfDictionary - */ - -public class PdfOutline extends PdfDictionary { - - // membervariables - - /** the PdfIndirectReference of this object */ - private PdfIndirectReference reference; - - /** value of the Count-key */ - private int count = 0; - - /** value of the Parent-key */ - private PdfOutline parent; - - /** value of the Destination-key */ - private PdfDestination destination; - - /** The PdfAction for this outline. - */ - private PdfAction action; - - protected ArrayList kids = new ArrayList(); - - protected PdfWriter writer; - - /** Holds value of property tag. */ - private String tag; - - /** Holds value of property open. */ - private boolean open; - - /** Holds value of property color. */ - private Color color; - - /** Holds value of property style. */ - private int style = 0; - - // constructors - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for the outlines object. - * - * @param writer The PdfWriter you are adding the outline to - */ - - PdfOutline(PdfWriter writer) { - super(OUTLINES); - open = true; - parent = null; - this.writer = writer; - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - */ - - public PdfOutline(PdfOutline parent, PdfAction action, String title) { - this(parent, action, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfAction action, String title, boolean open) { - super(); - this.action = action; - initOutline(parent, title, open); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - */ - - public PdfOutline(PdfOutline parent, PdfDestination destination, String title) { - this(parent, destination, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfDestination destination, String title, boolean open) { - super(); - this.destination = destination; - initOutline(parent, title, open); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - */ - public PdfOutline(PdfOutline parent, PdfAction action, PdfString title) { - this(parent, action, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfAction action, PdfString title, boolean open) { - this(parent, action, title.toString(), open); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - */ - - public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title) { - this(parent, destination, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title, boolean open) { - this(parent, destination, title.toString(), true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - */ - - public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title) { - this(parent, action, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param action the PdfAction for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfAction action, Paragraph title, boolean open) { - super(); - StringBuffer buf = new StringBuffer(); - for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) { - Chunk chunk = (Chunk) i.next(); - buf.append(chunk.content()); - } - this.action = action; - initOutline(parent, buf.toString(), open); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. The open mode is - * true. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - */ - - public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title) { - this(parent, destination, title, true); - } - - /** - * Constructs a PdfOutline. - *

- * This is the constructor for an outline entry. - * - * @param parent the parent of this outline item - * @param destination the destination for this outline item - * @param title the title of this outline item - * @param open true if the children are visible - */ - public PdfOutline(PdfOutline parent, PdfDestination destination, Paragraph title, boolean open) { - super(); - StringBuffer buf = new StringBuffer(); - for (Iterator i = title.getChunks().iterator(); i.hasNext(); ) { - Chunk chunk = (Chunk) i.next(); - buf.append(chunk.content()); - } - this.destination = destination; - initOutline(parent, buf.toString(), open); - } - - - // methods - - /** Helper for the constructors. - * @param parent the parent outline - * @param title the title for this outline - * @param open true if the children are visible - */ - void initOutline(PdfOutline parent, String title, boolean open) { - this.open = open; - this.parent = parent; - writer = parent.writer; - put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); - parent.addKid(this); - if (destination != null && !destination.hasPage()) // bugfix Finn Bock - setDestinationPage(writer.getCurrentPage()); - } - - /** - * Sets the indirect reference of this PdfOutline. - * - * @param reference the PdfIndirectReference to this outline. - */ - - public void setIndirectReference(PdfIndirectReference reference) { - this.reference = reference; - } - - /** - * Gets the indirect reference of this PdfOutline. - * - * @return the PdfIndirectReference to this outline. - */ - - public PdfIndirectReference indirectReference() { - return reference; - } - - /** - * Gets the parent of this PdfOutline. - * - * @return the PdfOutline that is the parent of this outline. - */ - - public PdfOutline parent() { - return parent; - } - - /** - * Set the page of the PdfDestination-object. - * - * @param pageReference indirect reference to the page - * @return true if this page was set as the PdfDestination-page. - */ - - public boolean setDestinationPage(PdfIndirectReference pageReference) { - if (destination == null) { - return false; - } - return destination.addPage(pageReference); - } - - /** - * Gets the destination for this outline. - * @return the destination - */ - public PdfDestination getPdfDestination() { - return destination; - } - - int getCount() { - return count; - } - - void setCount(int count) { - this.count = count; - } - - /** - * returns the level of this outline. - * - * @return a level - */ - - public int level() { - if (parent == null) { - return 0; - } - return (parent.level() + 1); - } - - /** - * Returns the PDF representation of this PdfOutline. - * - * @param writer the encryption information - * @param os - * @throws IOException - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - if (color != null && !color.equals(Color.black)) { - put(PdfName.C, new PdfArray(new float[]{color.getRed()/255f,color.getGreen()/255f,color.getBlue()/255f})); - } - int flag = 0; - if ((style & Font.BOLD) != 0) - flag |= 2; - if ((style & Font.ITALIC) != 0) - flag |= 1; - if (flag != 0) - put(PdfName.F, new PdfNumber(flag)); - if (parent != null) { - put(PdfName.PARENT, parent.indirectReference()); - } - if (destination != null && destination.hasPage()) { - put(PdfName.DEST, destination); - } - if (action != null) - put(PdfName.A, action); - if (count != 0) { - put(PdfName.COUNT, new PdfNumber(count)); - } - super.toPdf(writer, os); - } - - /** - * Adds a kid to the outline - * @param outline - */ - public void addKid(PdfOutline outline) { - kids.add(outline); - } - - /** - * Returns the kids of this outline - * @return an ArrayList with PdfOutlines - */ - public ArrayList getKids() { - return kids; - } - - /** - * Sets the kids of this outline - * @param kids - */ - public void setKids(ArrayList kids) { - this.kids = kids; - } - - /** Getter for property tag. - * @return Value of property tag. - */ - public String getTag() { - return tag; - } - - /** Setter for property tag. - * @param tag New value of property tag. - */ - public void setTag(String tag) { - this.tag = tag; - } - - /** - * Gets the title of this outline - * @return the title as a String - */ - public String getTitle() { - PdfString title = (PdfString)get(PdfName.TITLE); - return title.toString(); - } - - /** - * Sets the title of this outline - * @param title - */ - public void setTitle(String title) { - put(PdfName.TITLE, new PdfString(title, PdfObject.TEXT_UNICODE)); - } - - /** Getter for property open. - * @return Value of property open. - */ - public boolean isOpen() { - return open; - } - - /** Setter for property open. - * @param open New value of property open. - */ - public void setOpen(boolean open) { - this.open = open; - } - - /** Getter for property color. - * @return Value of property color. - * - */ - public Color getColor() { - return this.color; - } - - /** Setter for property color. - * @param color New value of property color. - * - */ - public void setColor(Color color) { - this.color = color; - } - - /** Getter for property style. - * @return Value of property style. - * - */ - public int getStyle() { - return this.style; - } - - /** Setter for property style. - * @param style New value of property style. - * - */ - public void setStyle(int style) { - this.style = style; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPCell.java b/src/main/java/com/lowagie/text/pdf/PdfPCell.java deleted file mode 100644 index 79d1f83..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPCell.java +++ /dev/null @@ -1,735 +0,0 @@ -/* - * $Id: PdfPCell.java,v 1.59 2006/02/16 16:17:49 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Element; -import com.lowagie.text.Phrase; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Image; -import com.lowagie.text.Chunk; -import com.lowagie.text.pdf.events.PdfPCellEventForwarder; - -/** A cell in a PdfPTable. - */ - -public class PdfPCell extends Rectangle{ - - private ColumnText column = new ColumnText(null); - - /** Holds value of property verticalAlignment. */ - private int verticalAlignment = Element.ALIGN_TOP; - - /** Holds value of property paddingLeft. */ - private float paddingLeft = 2; - - /** Holds value of property paddingLeft. */ - private float paddingRight = 2; - - /** Holds value of property paddingTop. */ - private float paddingTop = 2; - - /** Holds value of property paddingBottom. */ - private float paddingBottom = 2; - - /** Holds value of property fixedHeight. */ - private float fixedHeight = 0; - - /** Holds value of property noWrap. */ - private boolean noWrap = false; - - /** Holds value of property table. */ - private PdfPTable table; - - /** Holds value of property minimumHeight. */ - private float minimumHeight; - - /** Holds value of property colspan. */ - private int colspan = 1; - - /** Holds value of property image. */ - private Image image; - - /** Holds value of property cellEvent. */ - private PdfPCellEvent cellEvent; - - /** Holds value of property useDescender. */ - private boolean useDescender; - - /** Increases padding to include border if true */ - private boolean useBorderPadding = false; - - - /** The text in the cell. */ - protected Phrase phrase; - - /** Constructs an empty PdfPCell. - * The default padding is 2. - */ - public PdfPCell() { - super(0, 0, 0, 0); - borderWidth = 0.5f; - border = BOX; - column.setLeading(0, 1); - } - - /** Constructs a PdfPCell with a Phrase. - * The default padding is 2. - * @param phrase the text - */ - public PdfPCell(Phrase phrase) { - super(0, 0, 0, 0); - borderWidth = 0.5f; - border = BOX; - column.addText(this.phrase = phrase); - column.setLeading(0, 1); - } - - /** Constructs a PdfPCell with an Image. - * The default padding is 0. - * @param image the Image - */ - public PdfPCell(Image image) { - super(0, 0, 0, 0); - borderWidth = 0.5f; - border = BOX; - column.addText(this.phrase = new Phrase(new Chunk(image, 0, 0))); - column.setLeading(0, 1); - setPadding(0); - } - - /** Constructs a PdfPCell with an Image. - * The default padding is 0.25 for a border width of 0.5. - * @param image the Image - * @param fit true to fit the image to the cell - */ - public PdfPCell(Image image, boolean fit) { - super(0, 0, 0, 0); - if (fit) { - borderWidth = 0.5f; - border = BOX; - this.image = image; - column.setLeading(0, 1); - setPadding(borderWidth / 2); - } - else { - borderWidth = 0.5f; - border = BOX; - column.addText(this.phrase = new Phrase(new Chunk(image, 0, 0))); - column.setLeading(0, 1); - setPadding(0); - } - } - - /** Constructs a PdfPCell with a PdfPtable. - * This constructor allows nested tables. - * The default padding is 0. - * @param table The PdfPTable - */ - public PdfPCell(PdfPTable table) { - super(0, 0, 0, 0); - borderWidth = 0.5f; - border = BOX; - column.setLeading(0, 1); - setPadding(0); - this.table = table; - table.setWidthPercentage(100); - table.setExtendLastRow(true); - column.addElement(table); - } - - /** Constructs a deep copy of a PdfPCell. - * @param cell the PdfPCell to duplicate - */ - public PdfPCell(PdfPCell cell) { - super(cell.llx, cell.lly, cell.urx, cell.ury); - cloneNonPositionParameters(cell); - verticalAlignment = cell.verticalAlignment; - paddingLeft = cell.paddingLeft; - paddingRight = cell.paddingRight; - paddingTop = cell.paddingTop; - paddingBottom = cell.paddingBottom; - phrase = cell.phrase; - fixedHeight = cell.fixedHeight; - minimumHeight = cell.minimumHeight; - noWrap = cell.noWrap; - colspan = cell.colspan; - if (cell.table != null) - table = new PdfPTable(cell.table); - image = Image.getInstance(cell.image); - cellEvent = cell.cellEvent; - useDescender = cell.useDescender; - column = ColumnText.duplicate(cell.column); - useBorderPadding = cell.useBorderPadding; - rotation = cell.rotation; - } - - /** - * Adds an iText element to the cell. - * @param element - */ - public void addElement(Element element) { - if (table != null) { - table = null; - column.setText(null); - } - column.addElement(element); - } - - /** Gets the Phrase from this cell. - * @return the Phrase - */ - public Phrase getPhrase() { - return phrase; - } - - /** Sets the Phrase for this cell. - * @param phrase the Phrase - */ - public void setPhrase(Phrase phrase) { - table = null; - image = null; - column.setText(this.phrase = phrase); - } - - /** Gets the horizontal alignment for the cell. - * @return the horizontal alignment for the cell - */ - public int getHorizontalAlignment() { - return column.getAlignment(); - } - - /** Sets the horizontal alignment for the cell. It could be - * Element.ALIGN_CENTER for example. - * @param horizontalAlignment The horizontal alignment - */ - public void setHorizontalAlignment(int horizontalAlignment) { - column.setAlignment(horizontalAlignment); - } - - /** Gets the vertical alignment for the cell. - * @return the vertical alignment for the cell - */ - public int getVerticalAlignment() { - return verticalAlignment; - } - - /** Sets the vertical alignment for the cell. It could be - * Element.ALIGN_MIDDLE for example. - * @param verticalAlignment The vertical alignment - */ - public void setVerticalAlignment(int verticalAlignment) { - if (table != null) - table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); - this.verticalAlignment = verticalAlignment; - } - - /** Gets the effective left padding. This will include - * the left border width if {@link #isUseBorderPadding()} is true. - * @return effective value of property paddingLeft. - */ - public float getEffectivePaddingLeft() { - return paddingLeft + (isUseBorderPadding() ? (getBorderWidthLeft()/(isUseVariableBorders()?1f:2f)) : 0); - } - - /** - * @return Value of property paddingLeft. - */ - public float getPaddingLeft() { - return paddingLeft; - } - - /** - * Setter for property paddingLeft. - * @param paddingLeft New value of property paddingLeft. - */ - public void setPaddingLeft(float paddingLeft) { - this.paddingLeft = paddingLeft; - } - - /** Gets the effective right padding. This will include - * the right border width if {@link #isUseBorderPadding()} is true. - * @return effective value of property paddingRight. - */ - public float getEffectivePaddingRight() { - return paddingRight + (isUseBorderPadding() ? (getBorderWidthRight()/(isUseVariableBorders()?1f:2f)) : 0); - } - - /** - * Getter for property paddingRight. - * @return Value of property paddingRight. - */ - public float getPaddingRight() { - return paddingRight; - } - - /** - * Setter for property paddingRight. - * @param paddingRight New value of property paddingRight. - */ - public void setPaddingRight(float paddingRight) { - this.paddingRight = paddingRight; - } - - /** Gets the effective top padding. This will include - * the top border width if {@link #isUseBorderPadding()} is true. - * @return effective value of property paddingTop. - */ - public float getEffectivePaddingTop() { - return paddingTop + (isUseBorderPadding() ? (getBorderWidthTop()/(isUseVariableBorders()?1f:2f)) : 0); - } - - /** - * Getter for property paddingTop. - * @return Value of property paddingTop. - */ - public float getPaddingTop() { - return paddingTop; - } - - /** - * Setter for property paddingTop. - * @param paddingTop New value of property paddingTop. - */ - public void setPaddingTop(float paddingTop) { - this.paddingTop = paddingTop; - } - - /** Gets the effective bottom padding. This will include - * the bottom border width if {@link #isUseBorderPadding()} is true. - * @return effective value of property paddingBottom. - */ - public float getEffectivePaddingBottom() { - return paddingBottom + (isUseBorderPadding() ? (getBorderWidthBottom()/(isUseVariableBorders()?1f:2f)) : 0); - } - - /** - * Getter for property paddingBottom. - * @return Value of property paddingBottom. - */ - public float getPaddingBottom() { - return paddingBottom; - } - - /** - * Setter for property paddingBottom. - * @param paddingBottom New value of property paddingBottom. - */ - public void setPaddingBottom(float paddingBottom) { - this.paddingBottom = paddingBottom; - } - - /** - * Sets the padding of the contents in the cell (space between content and border). - * @param padding - */ - public void setPadding(float padding) { - paddingBottom = padding; - paddingTop = padding; - paddingLeft = padding; - paddingRight = padding; - } - - /** - * If true, then effective padding will include border widths - * @return true if effective padding includes border widths - */ - public boolean isUseBorderPadding() { - return useBorderPadding; - } - - /** - * Adjusts effective padding to include border widths. - * @param use adjust effective padding if true - */ - public void setUseBorderPadding(boolean use) { - useBorderPadding = use; - } - - /** - * Sets the leading fixed and variable. The resultant leading will be - * fixedLeading+multipliedLeading*maxFontSize where maxFontSize is the - * size of the bigest font in the line. - * @param fixedLeading the fixed leading - * @param multipliedLeading the variable leading - */ - public void setLeading(float fixedLeading, float multipliedLeading) { - column.setLeading(fixedLeading, multipliedLeading); - } - - /** - * Gets the fixed leading - * @return the leading - */ - public float getLeading() { - return column.getLeading(); - } - - /** - * Gets the variable leading - * @return the leading - */ - public float getMultipliedLeading() { - return column.getMultipliedLeading(); - } - - /** - * Sets the first paragraph line indent. - * @param indent the indent - */ - public void setIndent(float indent) { - column.setIndent(indent); - } - - /** - * Gets the first paragraph line indent. - * @return the indent - */ - public float getIndent() { - return column.getIndent(); - } - - /** - * Gets the extra space between paragraphs. - * @return the extra space between paragraphs - */ - public float getExtraParagraphSpace() { - return column.getExtraParagraphSpace(); - } - - /** - * Sets the extra space between paragraphs. - * @param extraParagraphSpace the extra space between paragraphs - */ - public void setExtraParagraphSpace(float extraParagraphSpace) { - column.setExtraParagraphSpace(extraParagraphSpace); - } - - /** - * Getter for property fixedHeight. - * @return Value of property fixedHeight. - */ - public float getFixedHeight() { - return fixedHeight; - } - - /** - * Setter for property fixedHeight. - * @param fixedHeight New value of property fixedHeight. - */ - public void setFixedHeight(float fixedHeight) { - this.fixedHeight = fixedHeight; - minimumHeight = 0; - } - - /** - * Getter for property noWrap. - * @return Value of property noWrap. - */ - public boolean isNoWrap() { - return noWrap; - } - - /** - * Setter for property noWrap. - * @param noWrap New value of property noWrap. - */ - public void setNoWrap(boolean noWrap) { - this.noWrap = noWrap; - } - - /** - * Getter for property table. - * @return Value of property table. - */ - PdfPTable getTable() { - return table; - } - - void setTable(PdfPTable table) { - this.table = table; - column.setText(null); - image = null; - if (table != null) { - table.setExtendLastRow(verticalAlignment == Element.ALIGN_TOP); - column.addElement(table); - table.setWidthPercentage(100); - } - } - - /** Getter for property minimumHeight. - * @return Value of property minimumHeight. - */ - public float getMinimumHeight() { - return minimumHeight; - } - - /** Setter for property minimumHeight. - * @param minimumHeight New value of property minimumHeight. - */ - public void setMinimumHeight(float minimumHeight) { - this.minimumHeight = minimumHeight; - fixedHeight = 0; - } - - /** Getter for property colspan. - * @return Value of property colspan. - */ - public int getColspan() { - return colspan; - } - - /** Setter for property colspan. - * @param colspan New value of property colspan. - */ - public void setColspan(int colspan) { - this.colspan = colspan; - } - - /** - * Sets the following paragraph lines indent. - * @param indent the indent - */ - public void setFollowingIndent(float indent) { - column.setFollowingIndent(indent); - } - - /** - * Gets the following paragraph lines indent. - * @return the indent - */ - public float getFollowingIndent() { - return column.getFollowingIndent(); - } - - /** - * Sets the right paragraph lines indent. - * @param indent the indent - */ - public void setRightIndent(float indent) { - column.setRightIndent(indent); - } - - /** - * Gets the right paragraph lines indent. - * @return the indent - */ - public float getRightIndent() { - return column.getRightIndent(); - } - - /** Gets the space/character extra spacing ratio for - * fully justified text. - * @return the space/character extra spacing ratio - */ - public float getSpaceCharRatio() { - return column.getSpaceCharRatio(); - } - - /** Sets the ratio between the extra word spacing and the extra character spacing - * when the text is fully justified. - * Extra word spacing will grow spaceCharRatio times more than extra character spacing. - * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the extra character spacing - * will be zero. - * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing - */ - public void setSpaceCharRatio(float spaceCharRatio) { - column.setSpaceCharRatio(spaceCharRatio); - } - - /** - * Sets the run direction of the text content in the cell (PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL). - * @param runDirection - */ - public void setRunDirection(int runDirection) { - column.setRunDirection(runDirection); - } - - /** - * Gets the run direction of the text content in the cell - * @return One of the following values: PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. - */ - public int getRunDirection() { - return column.getRunDirection(); - } - - /** Getter for property image. - * @return Value of property image. - * - */ - public Image getImage() { - return this.image; - } - - /** Setter for property image. - * @param image New value of property image. - * - */ - public void setImage(Image image) { - column.setText(null); - table = null; - this.image = image; - } - - /** Gets the cell event for this cell. - * @return the cell event - * - */ - public PdfPCellEvent getCellEvent() { - return this.cellEvent; - } - - /** Sets the cell event for this cell. - * @param event the cell event - * - */ - public void setCellEvent(PdfPCellEvent event) { - if (event == null) this.cellEvent = null; - else if (this.cellEvent == null) this.cellEvent = event; - else if (this.cellEvent instanceof PdfPCellEventForwarder) ((PdfPCellEventForwarder)this.cellEvent).addCellEvent(event); - else { - PdfPCellEventForwarder forward = new PdfPCellEventForwarder(); - forward.addCellEvent(this.cellEvent); - forward.addCellEvent(event); - this.cellEvent = forward; - } - } - - /** Gets the arabic shaping options. - * @return the arabic shaping options - */ - public int getArabicOptions() { - return column.getArabicOptions(); - } - - /** Sets the arabic shaping options. The option can be AR_NOVOWEL, - * AR_COMPOSEDTASHKEEL and AR_LIG. - * @param arabicOptions the arabic shaping options - */ - public void setArabicOptions(int arabicOptions) { - column.setArabicOptions(arabicOptions); - } - - /** Gets state of first line height based on max ascender - * @return true if an ascender is to be used. - */ - public boolean isUseAscender() { - return column.isUseAscender(); - } - - /** Enables/ Disables adjustment of first line height based on max ascender. - * - * @param use adjust height if true - */ - public void setUseAscender(boolean use) { - column.setUseAscender(use); - } - - - /** Getter for property useDescender. - * @return Value of property useDescender. - * - */ - public boolean isUseDescender() { - return this.useDescender; - } - - /** Setter for property useDescender. - * @param useDescender New value of property useDescender. - * - */ - public void setUseDescender(boolean useDescender) { - this.useDescender = useDescender; - } - - /** - * Gets the ColumnText with the content of the cell. - * @return a columntext object - */ - public ColumnText getColumn() { - return column; - } - - /** - * Sets the columntext in the cell. - * @param column - */ - public void setColumn(ColumnText column) { - this.column = column; - } - - /** - * The rotation of the cell. Possible values are - * 0, 90, 180 and 270. - */ - private int rotation; - - /** - * Gets the rotation of the cell. - * @return the rotation of the cell. - */ - public int getRotation() { - return this.rotation; - } - - /** - * Sets the rotation of the cell. Possible values are - * 0, 90, 180 and 270. - * @param rotation the rotation of the cell - */ - public void setRotation(int rotation) { - rotation %= 360; - if (rotation < 0) - rotation += 360; - if ((rotation % 90) != 0) - throw new IllegalArgumentException("Rotation must be a multiple of 90."); - this.rotation = rotation; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPCellEvent.java b/src/main/java/com/lowagie/text/pdf/PdfPCellEvent.java deleted file mode 100644 index 94b7573..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPCellEvent.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; - -/** An event called for a single cell. - * @author Paulo Soares (psoares@consiste.pt) - */ -public interface PdfPCellEvent { - /** This method is called at the end of the cell rendering. The text or graphics are added to - * one of the 4 PdfContentByte contained in - * canvases.
- * The indexes to canvases are:

- *

- * The layers are placed in sequence on top of each other. - *

- * @param cell the cell - * @param position the coordinates of the cell - * @param canvases an array of PdfContentByte - */ - public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases); -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java b/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java deleted file mode 100644 index d9f3473..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java +++ /dev/null @@ -1,1276 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.FileInputStream; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.MessageDigest; -import java.security.SignatureException; -import java.security.cert.CRL; -import java.security.cert.CRLException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509CRL; -import java.security.cert.X509Certificate; -import java.security.KeyStore; -import java.io.File; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; -import java.util.Calendar; -import java.util.GregorianCalendar; -import com.lowagie.text.ExceptionConverter; - -import com.lowagie.bc.asn1.ASN1InputStream; -import com.lowagie.bc.asn1.DERObject; -import com.lowagie.bc.asn1.ASN1Sequence; -import com.lowagie.bc.asn1.ASN1Set; -import com.lowagie.bc.asn1.DERObjectIdentifier; -import com.lowagie.bc.asn1.DEROctetString; -import com.lowagie.bc.asn1.DERTaggedObject; -import com.lowagie.bc.asn1.DERInteger; -import com.lowagie.bc.asn1.ASN1TaggedObject; -import com.lowagie.bc.asn1.DERConstructedSet; -import com.lowagie.bc.asn1.DERSequence; -import com.lowagie.bc.asn1.DERNull; -import com.lowagie.bc.asn1.ASN1EncodableVector; -import com.lowagie.bc.asn1.DERSet; -import com.lowagie.bc.asn1.DERString; -import com.lowagie.bc.asn1.DERUTCTime; -import com.lowagie.bc.asn1.ASN1OutputStream; - -/** - * This class does all the processing related to signing and verifying a PKCS#7 - * signature. - *

- * It's based in code found at org.bouncycastle. - */ -public class PdfPKCS7 { - - private byte sigAttr[]; - private byte digestAttr[]; - private int version, signerversion; - private Set digestalgos; - private Collection certs, crls; - private X509Certificate signCert; - private byte[] digest; - private MessageDigest messageDigest; - private String digestAlgorithm, digestEncryptionAlgorithm; - private Signature sig; - private transient PrivateKey privKey; - private byte RSAdata[]; - private boolean verified; - private boolean verifyResult; - private byte externalDigest[]; - private byte externalRSAdata[]; - - private static final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1"; - private static final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2"; - private static final String ID_MD5 = "1.2.840.113549.2.5"; - private static final String ID_MD2 = "1.2.840.113549.2.2"; - private static final String ID_SHA1 = "1.3.14.3.2.26"; - private static final String ID_RSA = "1.2.840.113549.1.1.1"; - private static final String ID_DSA = "1.2.840.10040.4.1"; - private static final String ID_CONTENT_TYPE = "1.2.840.113549.1.9.3"; - private static final String ID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4"; - private static final String ID_SIGNING_TIME = "1.2.840.113549.1.9.5"; - private static final String ID_MD2RSA = "1.2.840.113549.1.1.2"; - private static final String ID_MD5RSA = "1.2.840.113549.1.1.4"; - private static final String ID_SHA1RSA = "1.2.840.113549.1.1.5"; - /** - * Holds value of property reason. - */ - private String reason; - - /** - * Holds value of property location. - */ - private String location; - - /** - * Holds value of property signDate. - */ - private Calendar signDate; - - /** - * Holds value of property signName. - */ - private String signName; - - /** - * Verifies a signature using the sub-filter adbe.x509.rsa_sha1. - * @param contentsKey the /Contents key - * @param certsKey the /Cert key - * @param provider the provider or null for the default provider - * @throws SecurityException on error - * @throws CRLException on error - * @throws InvalidKeyException on error - * @throws CertificateException on error - * @throws NoSuchProviderException on error - * @throws NoSuchAlgorithmException on error - * @throws IOException on error - */ - public PdfPKCS7(byte[] contentsKey, byte[] certsKey, String provider) throws SecurityException, CRLException, InvalidKeyException, CertificateException, NoSuchProviderException, NoSuchAlgorithmException, IOException { - CertificateFactory cf; - if (provider == null) - cf = CertificateFactory.getInstance("X.509"); - else - cf = CertificateFactory.getInstance("X.509", provider); - if (provider == null) - certs = cf.generateCertificates(new ByteArrayInputStream(certsKey)); - signCert = (X509Certificate)certs.iterator().next(); - crls = new ArrayList(); - ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); - digest = ((DEROctetString)in.readObject()).getOctets(); - if (provider == null) - sig = Signature.getInstance("SHA1withRSA"); - else - sig = Signature.getInstance("SHA1withRSA", provider); - sig.initVerify(signCert.getPublicKey()); - } - - /** - * Verifies a signature using the sub-filter adbe.pkcs7.detached or - * adbe.pkcs7.sha1. - * @param contentsKey the /Contents key - * @param provider the provider or null for the default provider - * @throws SecurityException on error - * @throws CRLException on error - * @throws InvalidKeyException on error - * @throws CertificateException on error - * @throws NoSuchProviderException on error - * @throws NoSuchAlgorithmException on error - */ - public PdfPKCS7(byte[] contentsKey, String provider) throws SecurityException, CRLException, InvalidKeyException, CertificateException, NoSuchProviderException, NoSuchAlgorithmException { - ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); - - // - // Basic checks to make sure it's a PKCS#7 SignedData Object - // - DERObject pkcs; - - try { - pkcs = din.readObject(); - } - catch (IOException e) { - throw new SecurityException("can't decode PKCS7SignedData object"); - } - if (!(pkcs instanceof ASN1Sequence)) { - throw new SecurityException("Not a valid PKCS#7 object - not a sequence"); - } - ASN1Sequence signedData = (ASN1Sequence)pkcs; - DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); - if (!objId.getId().equals(ID_PKCS7_SIGNED_DATA)) - throw new SecurityException("Not a valid PKCS#7 object - not signed data"); - ASN1Sequence content = (ASN1Sequence)((DERTaggedObject)signedData.getObjectAt(1)).getObject(); - // the positions that we care are: - // 0 - version - // 1 - digestAlgorithms - // 2 - possible ID_PKCS7_DATA - // (the certificates and crls are taken out by other means) - // last - signerInfos - - // the version - version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); - - // the digestAlgorithms - digestalgos = new HashSet(); - Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence s = (ASN1Sequence)e.nextElement(); - DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); - digestalgos.add(o.getId()); - } - - // the certificates and crls - CertificateFactory cf; - if (provider == null) - cf = CertificateFactory.getInstance("X.509"); - else - cf = CertificateFactory.getInstance("X.509", provider); - certs = cf.generateCertificates(new ByteArrayInputStream(contentsKey)); - crls = cf.generateCRLs(new ByteArrayInputStream(contentsKey)); - - // the possible ID_PKCS7_DATA - ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2); - if (rsaData.size() > 1) { - DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject(); - RSAdata = rsaDataContent.getOctets(); - } - - // the signerInfos - int next = 3; - while (content.getObjectAt(next) instanceof DERTaggedObject) - ++next; - ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next); - if (signerInfos.size() != 1) - throw new SecurityException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); - ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0); - // the positions that we care are - // 0 - version - // 1 - the signing certificate serial number - // 2 - the digest algorithm - // 3 or 4 - digestEncryptionAlgorithm - // 4 or 5 - encryptedDigest - signerversion = ((DERInteger)signerInfo.getObjectAt(0)).getValue().intValue(); - // Get the signing certificate - ASN1Sequence issuerAndSerialNumber = (ASN1Sequence)signerInfo.getObjectAt(1); - BigInteger serialNumber = ((DERInteger)issuerAndSerialNumber.getObjectAt(1)).getValue(); - for (Iterator i = certs.iterator(); i.hasNext();) { - X509Certificate cert = (X509Certificate)i.next(); - if (serialNumber.equals(cert.getSerialNumber())) { - signCert = cert; - break; - } - } - if (signCert == null) { - throw new SecurityException("Can't find signing certificate with serial " + serialNumber.toString(16)); - } - digestAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId(); - next = 3; - if (signerInfo.getObjectAt(next) instanceof ASN1TaggedObject) { - ASN1TaggedObject tagsig = (ASN1TaggedObject)signerInfo.getObjectAt(next); - ASN1Sequence sseq = (ASN1Sequence)tagsig.getObject(); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - ASN1OutputStream dout = new ASN1OutputStream(bOut); - try { - ASN1EncodableVector attribute = new ASN1EncodableVector(); - for (int k = 0; k < sseq.size(); ++k) { - attribute.add(sseq.getObjectAt(k)); - } - dout.writeObject(new DERSet(attribute)); - dout.close(); - } - catch (IOException ioe){} - sigAttr = bOut.toByteArray(); - - for (int k = 0; k < sseq.size(); ++k) { - ASN1Sequence seq2 = (ASN1Sequence)sseq.getObjectAt(k); - if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { - ASN1Set set = (ASN1Set)seq2.getObjectAt(1); - digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); - break; - } - } - if (digestAttr == null) - throw new SecurityException("Authenticated attribute is missing the digest."); - ++next; - } - digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); - digest = ((DEROctetString)signerInfo.getObjectAt(next)).getOctets(); - if (RSAdata != null || digestAttr != null) { - if (provider == null || provider.startsWith("SunPKCS11")) - messageDigest = MessageDigest.getInstance(getHashAlgorithm()); - else - messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); - } - if (provider == null) - sig = Signature.getInstance(getDigestAlgorithm()); - else - sig = Signature.getInstance(getDigestAlgorithm(), provider); - sig.initVerify(signCert.getPublicKey()); - } - - /** - * Generates a signature. - * @param privKey the private key - * @param certChain the certificate chain - * @param crlList the certificate revocation list - * @param hashAlgorithm the hash algorithm - * @param provider the provider or null for the default provider - * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 - * @throws SecurityException on error - * @throws InvalidKeyException on error - * @throws NoSuchProviderException on error - * @throws NoSuchAlgorithmException on error - */ - public PdfPKCS7(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, - String hashAlgorithm, String provider, boolean hasRSAdata) - throws SecurityException, InvalidKeyException, NoSuchProviderException, - NoSuchAlgorithmException - { - this.privKey = privKey; - - if (hashAlgorithm.equals("MD5")) { - digestAlgorithm = ID_MD5; - } - else if (hashAlgorithm.equals("MD2")) { - digestAlgorithm = ID_MD2; - } - else if (hashAlgorithm.equals("SHA")) { - digestAlgorithm = ID_SHA1; - } - else if (hashAlgorithm.equals("SHA1")) { - digestAlgorithm = ID_SHA1; - } - else { - throw new NoSuchAlgorithmException("Unknown Hash Algorithm "+hashAlgorithm); - } - - version = signerversion = 1; - certs = new ArrayList(); - crls = new ArrayList(); - digestalgos = new HashSet(); - digestalgos.add(digestAlgorithm); - - // - // Copy in the certificates and crls used to sign the private key. - // - signCert = (X509Certificate)certChain[0]; - for (int i = 0;i < certChain.length;i++) { - certs.add(certChain[i]); - } - - if (crlList != null) { - for (int i = 0;i < crlList.length;i++) { - crls.add(crlList[i]); - } - } - - if (privKey != null) { - // - // Now we have private key, find out what the digestEncryptionAlgorithm is. - // - digestEncryptionAlgorithm = privKey.getAlgorithm(); - if (digestEncryptionAlgorithm.equals("RSA")) { - digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { - digestEncryptionAlgorithm = ID_DSA; - } - else { - throw new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm); - } - } - if (hasRSAdata) { - RSAdata = new byte[0]; - if (provider == null || provider.startsWith("SunPKCS11")) - messageDigest = MessageDigest.getInstance(getHashAlgorithm()); - else - messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); - } - - if (privKey != null) { - if (provider == null) - sig = Signature.getInstance(getDigestAlgorithm()); - else - sig = Signature.getInstance(getDigestAlgorithm(), provider); - - sig.initSign(privKey); - } - } - - /** - * Update the digest with the specified bytes. This method is used both for signing and verifying - * @param buf the data buffer - * @param off the offset in the data buffer - * @param len the data length - * @throws SignatureException on error - */ - public void update(byte[] buf, int off, int len) throws SignatureException { - if (RSAdata != null || digestAttr != null) - messageDigest.update(buf, off, len); - else - sig.update(buf, off, len); - } - - /** - * Verify the digest. - * @throws SignatureException on error - * @return true if the signature checks out, false otherwise - */ - public boolean verify() throws SignatureException { - if (verified) - return verifyResult; - if (sigAttr != null) { - sig.update(sigAttr); - if (RSAdata != null) { - byte msd[] = messageDigest.digest(); - messageDigest.update(msd); - } - verifyResult = (Arrays.equals(messageDigest.digest(), digestAttr) && sig.verify(digest)); - } - else { - if (RSAdata != null) - sig.update(messageDigest.digest()); - verifyResult = sig.verify(digest); - } - verified = true; - return verifyResult; - } - - /** - * Get the X.509 certificates associated with this PKCS#7 object - * @return the X.509 certificates associated with this PKCS#7 object - */ - public Certificate[] getCertificates() { - return (X509Certificate[])certs.toArray(new X509Certificate[0]); - } - - /** - * Get the X.509 certificate revocation lists associated with this PKCS#7 object - * @return the X.509 certificate revocation lists associated with this PKCS#7 object - */ - public Collection getCRLs() { - return crls; - } - - /** - * Get the X.509 certificate actually used to sign the digest. - * @return the X.509 certificate actually used to sign the digest - */ - public X509Certificate getSigningCertificate() { - return signCert; - } - - /** - * Get the version of the PKCS#7 object. Always 1 - * @return the version of the PKCS#7 object. Always 1 - */ - public int getVersion() { - return version; - } - - /** - * Get the version of the PKCS#7 "SignerInfo" object. Always 1 - * @return the version of the PKCS#7 "SignerInfo" object. Always 1 - */ - public int getSigningInfoVersion() { - return signerversion; - } - - /** - * Get the algorithm used to calculate the message digest - * @return the algorithm used to calculate the message digest - */ - public String getDigestAlgorithm() { - String dea = digestEncryptionAlgorithm; - - if (digestEncryptionAlgorithm.equals(ID_RSA)) { - dea = "RSA"; - } - else if (digestEncryptionAlgorithm.equals(ID_DSA)) { - dea = "DSA"; - } - - return getHashAlgorithm() + "with" + dea; - } - - /** - * Returns the algorithm. - * @return the digest algorithm - */ - public String getHashAlgorithm() { - String da = digestAlgorithm; - - if (digestAlgorithm.equals(ID_MD5) || digestAlgorithm.equals(ID_MD5RSA)) { - da = "MD5"; - } - else if (digestAlgorithm.equals(ID_MD2) || digestAlgorithm.equals(ID_MD2RSA)) { - da = "MD2"; - } - else if (digestAlgorithm.equals(ID_SHA1) || digestAlgorithm.equals(ID_SHA1RSA)) { - da = "SHA1"; - } - return da; - } - - /** - * Loads the default root certificates at <java.home>/lib/security/cacerts - * with the default provider. - * @return a KeyStore - */ - public static KeyStore loadCacertsKeyStore() { - return loadCacertsKeyStore(null); - } - - /** - * Loads the default root certificates at <java.home>/lib/security/cacerts. - * @param provider the provider or null for the default provider - * @return a KeyStore - */ - public static KeyStore loadCacertsKeyStore(String provider) { - File file = new File(System.getProperty("java.home"), "lib"); - file = new File(file, "security"); - file = new File(file, "cacerts"); - FileInputStream fin = null; - try { - fin = new FileInputStream(file); - KeyStore k; - if (provider == null) - k = KeyStore.getInstance("JKS"); - else - k = KeyStore.getInstance("JKS", provider); - k.load(fin, null); - return k; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - finally { - try{fin.close();}catch(Exception ex){} - } - } - - /** - * Verifies a single certificate. - * @param cert the certificate to verify - * @param crls the certificate revocation list or null - * @param calendar the date or null for the current date - * @return a String with the error description or null - * if no error - */ - public static String verifyCertificate(X509Certificate cert, Collection crls, Calendar calendar) { - if (calendar == null) - calendar = new GregorianCalendar(); - if (cert.hasUnsupportedCriticalExtension()) - return "Has unsupported critical extension"; - try { - cert.checkValidity(calendar.getTime()); - } - catch (Exception e) { - return e.getMessage(); - } - if (crls != null) { - for (Iterator it = crls.iterator(); it.hasNext();) { - if (((CRL)it.next()).isRevoked(cert)) - return "Certificate revoked"; - } - } - return null; - } - - /** - * Verifies a certificate chain against a KeyStore. - * @param certs the certificate chain - * @param keystore the KeyStore - * @param crls the certificate revocation list or null - * @param calendar the date or null for the current date - * @return null if the certificate chain could be validade or a - * Object[]{cert,error} where cert is the - * failed certificate and error is the error message - */ - public static Object[] verifyCertificates(Certificate certs[], KeyStore keystore, Collection crls, Calendar calendar) { - if (calendar == null) - calendar = new GregorianCalendar(); - for (int k = 0; k < certs.length; ++k) { - X509Certificate cert = (X509Certificate)certs[k]; - String err = verifyCertificate(cert, crls, calendar); - if (err != null) - return new Object[]{cert, err}; - try { - for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { - try { - String alias = (String)aliases.nextElement(); - if (!keystore.isCertificateEntry(alias)) - continue; - X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); - if (verifyCertificate(certStoreX509, crls, calendar) != null) - continue; - try { - cert.verify(certStoreX509.getPublicKey()); - return null; - } - catch (Exception e) { - continue; - } - } - catch (Exception ex) { - } - } - } - catch (Exception e) { - } - int j; - for (j = 0; j < certs.length; ++j) { - if (j == k) - continue; - X509Certificate certNext = (X509Certificate)certs[j]; - try { - cert.verify(certNext.getPublicKey()); - break; - } - catch (Exception e) { - } - } - if (j == certs.length) - return new Object[]{cert, "Cannot be verified against the KeyStore or the certificate chain"}; - } - return new Object[]{null, "Invalid state. Possible circular certificate chain"}; - } - - /** - * Get the "issuer" from the TBSCertificate bytes that are passed in - * @param enc a TBSCertificate in a byte array - * @return a DERObject - */ - private static DERObject getIssuer(byte[] enc) { - try { - ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** - * Get the "subject" from the TBSCertificate bytes that are passed in - * @param enc A TBSCertificate in a byte array - * @return a DERObject - */ - private static DERObject getSubject(byte[] enc) { - try { - ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - /** - * Get the issuer fields from an X509 Certificate - * @param cert an X509Certificate - * @return an X509Name - */ - public static X509Name getIssuerFields(X509Certificate cert) { - try { - return new X509Name((ASN1Sequence)getIssuer(cert.getTBSCertificate())); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Get the subject fields from an X509 Certificate - * @param cert an X509Certificate - * @return an X509Name - */ - public static X509Name getSubjectFields(X509Certificate cert) { - try { - return new X509Name((ASN1Sequence)getSubject(cert.getTBSCertificate())); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Gets the bytes for the PKCS#1 object. - * @return a byte array - */ - public byte[] getEncodedPKCS1() { - try { - if (externalDigest != null) - digest = externalDigest; - else - digest = sig.sign(); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - ASN1OutputStream dout = new ASN1OutputStream(bOut); - dout.writeObject(new DEROctetString(digest)); - dout.close(); - - return bOut.toByteArray(); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Sets the digest/signature to an external calculated value. - * @param digest the digest. This is the actual signature - * @param RSAdata the extra data that goes into the data tag in PKCS#7 - * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest - * is also null. If the digest is not null - * then it may be "RSA" or "DSA" - */ - public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { - externalDigest = digest; - externalRSAdata = RSAdata; - if (digestEncryptionAlgorithm != null) { - if (digestEncryptionAlgorithm.equals("RSA")) { - this.digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { - this.digestEncryptionAlgorithm = ID_DSA; - } - else - throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm)); - } - } - - /** - * Gets the bytes for the PKCS7SignedData object. - * @return the bytes for the PKCS7SignedData object - */ - public byte[] getEncodedPKCS7() { - return getEncodedPKCS7(null, null); - } - - /** - * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes - * in the signerInfo can also be set. If either of the parameters is null, none will be used. - * @param secondDigest the digest in the authenticatedAttributes - * @param signingTime the signing time in the authenticatedAttributes - * @return the bytes for the PKCS7SignedData object - */ - public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime) { - try { - if (externalDigest != null) { - digest = externalDigest; - if (RSAdata != null) - RSAdata = externalRSAdata; - } - else if (externalRSAdata != null && RSAdata != null) { - RSAdata = externalRSAdata; - sig.update(RSAdata); - digest = sig.sign(); - } - else { - if (RSAdata != null) { - RSAdata = messageDigest.digest(); - sig.update(RSAdata); - } - digest = sig.sign(); - } - - // Create the set of Hash algorithms - DERConstructedSet digestAlgorithms = new DERConstructedSet(); - for(Iterator it = digestalgos.iterator(); it.hasNext();) { - ASN1EncodableVector algos = new ASN1EncodableVector(); - algos.add(new DERObjectIdentifier((String)it.next())); - algos.add(new DERNull()); - digestAlgorithms.addObject(new DERSequence(algos)); - } - - // Create the contentInfo. - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_PKCS7_DATA)); - if (RSAdata != null) - v.add(new DERTaggedObject(0, new DEROctetString(RSAdata))); - DERSequence contentinfo = new DERSequence(v); - - // Get all the certificates - // - v = new ASN1EncodableVector(); - for (Iterator i = certs.iterator(); i.hasNext();) { - ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate)i.next()).getEncoded())); - v.add(tempstream.readObject()); - } - - DERSet dercertificates = new DERSet(v); - - // Create signerinfo structure. - // - ASN1EncodableVector signerinfo = new ASN1EncodableVector(); - - // Add the signerInfo version - // - signerinfo.add(new DERInteger(signerversion)); - - v = new ASN1EncodableVector(); - v.add(getIssuer(signCert.getTBSCertificate())); - v.add(new DERInteger(signCert.getSerialNumber())); - signerinfo.add(new DERSequence(v)); - - // Add the digestAlgorithm - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(digestAlgorithm)); - v.add(new DERNull()); - signerinfo.add(new DERSequence(v)); - - // add the authenticated attribute if present - if (secondDigest != null && signingTime != null) { - ASN1EncodableVector attribute = new ASN1EncodableVector(); - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); - v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); - attribute.add(new DERSequence(v)); - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); - v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); - attribute.add(new DERSequence(v)); - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); - v.add(new DERSet(new DEROctetString(secondDigest))); - attribute.add(new DERSequence(v)); - signerinfo.add(new DERTaggedObject(false, 0, new DERSet(attribute))); - } - // Add the digestEncryptionAlgorithm - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(digestEncryptionAlgorithm)); - v.add(new DERNull()); - signerinfo.add(new DERSequence(v)); - - // Add the digest - signerinfo.add(new DEROctetString(digest)); - - - // Finally build the body out of all the components above - ASN1EncodableVector body = new ASN1EncodableVector(); - body.add(new DERInteger(version)); - body.add(digestAlgorithms); - body.add(contentinfo); - body.add(new DERTaggedObject(false, 0, dercertificates)); - - if (crls.size() > 0) { - v = new ASN1EncodableVector(); - for (Iterator i = crls.iterator();i.hasNext();) { - ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream((((X509CRL)i.next()).getEncoded()))); - v.add(t.readObject()); - } - DERSet dercrls = new DERSet(v); - body.add(new DERTaggedObject(false, 1, dercrls)); - } - - // Only allow one signerInfo - body.add(new DERSet(new DERSequence(signerinfo))); - - // Now we have the body, wrap it in it's PKCS7Signed shell - // and return it - // - ASN1EncodableVector whole = new ASN1EncodableVector(); - whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA)); - whole.add(new DERTaggedObject(0, new DERSequence(body))); - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - ASN1OutputStream dout = new ASN1OutputStream(bOut); - dout.writeObject(new DERSequence(whole)); - dout.close(); - - return bOut.toByteArray(); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - - /** - * When using authenticatedAttributes the authentication process is different. - * The document digest is generated and put inside the attribute. The signing is done over the DER encoded - * authenticatedAttributes. This method provides that encoding and the parameters must be - * exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}. - *

- * A simple example: - *

- *

-     * Calendar cal = Calendar.getInstance();
-     * PdfPKCS7 pk7 = new PdfPKCS7(key, chain, null, "SHA1", null, false);
-     * MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
-     * byte buf[] = new byte[8192];
-     * int n;
-     * InputStream inp = sap.getRangeStream();
-     * while ((n = inp.read(buf)) > 0) {
-     *    messageDigest.update(buf, 0, n);
-     * }
-     * byte hash[] = messageDigest.digest();
-     * byte sh[] = pk7.getAuthenticatedAttributeBytes(hash, cal);
-     * pk7.update(sh, 0, sh.length);
-     * byte sg[] = pk7.getEncodedPKCS7(hash, cal);
-     * 
- * @param secondDigest the content digest - * @param signingTime the signing time - * @return the byte array representation of the authenticatedAttributes ready to be signed - */ - public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime) { - try { - ASN1EncodableVector attribute = new ASN1EncodableVector(); - ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); - v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); - attribute.add(new DERSequence(v)); - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); - v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); - attribute.add(new DERSequence(v)); - v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); - v.add(new DERSet(new DEROctetString(secondDigest))); - attribute.add(new DERSequence(v)); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - ASN1OutputStream dout = new ASN1OutputStream(bOut); - dout.writeObject(new DERSet(attribute)); - dout.close(); - - return bOut.toByteArray(); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - /** - * Getter for property reason. - * @return Value of property reason. - */ - public String getReason() { - return this.reason; - } - - /** - * Setter for property reason. - * @param reason New value of property reason. - */ - public void setReason(String reason) { - this.reason = reason; - } - - /** - * Getter for property location. - * @return Value of property location. - */ - public String getLocation() { - return this.location; - } - - /** - * Setter for property location. - * @param location New value of property location. - */ - public void setLocation(String location) { - this.location = location; - } - - /** - * Getter for property signDate. - * @return Value of property signDate. - */ - public Calendar getSignDate() { - return this.signDate; - } - - /** - * Setter for property signDate. - * @param signDate New value of property signDate. - */ - public void setSignDate(Calendar signDate) { - this.signDate = signDate; - } - - /** - * Getter for property sigName. - * @return Value of property sigName. - */ - public String getSignName() { - return this.signName; - } - - /** - * Setter for property sigName. - * @param signName New value of property sigName. - */ - public void setSignName(String signName) { - this.signName = signName; - } - - /** - * a class that holds an X509 name - */ - public static class X509Name { - /** - * country code - StringType(SIZE(2)) - */ - public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6"); - - /** - * organization - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10"); - - /** - * organizational unit name - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11"); - - /** - * Title - */ - public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12"); - - /** - * common name - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3"); - - /** - * device serial number name - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5"); - - /** - * locality name - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7"); - - /** - * state, or province name - StringType(SIZE(1..64)) - */ - public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8"); - - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45"); - - /** - * Email address (RSA PKCS#9 extension) - IA5String. - *

Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. - */ - public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1"); - - /** - * email address in Verisign certificates - */ - public static final DERObjectIdentifier E = EmailAddress; - - /** object identifier */ - public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25"); - - /** LDAP User id. */ - public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1"); - - /** A HashMap with default symbols */ - public static HashMap DefaultSymbols = new HashMap(); - - static { - DefaultSymbols.put(C, "C"); - DefaultSymbols.put(O, "O"); - DefaultSymbols.put(T, "T"); - DefaultSymbols.put(OU, "OU"); - DefaultSymbols.put(CN, "CN"); - DefaultSymbols.put(L, "L"); - DefaultSymbols.put(ST, "ST"); - DefaultSymbols.put(SN, "SN"); - DefaultSymbols.put(EmailAddress, "E"); - DefaultSymbols.put(DC, "DC"); - DefaultSymbols.put(UID, "UID"); - DefaultSymbols.put(SURNAME, "SURNAME"); - DefaultSymbols.put(GIVENNAME, "GIVENNAME"); - DefaultSymbols.put(INITIALS, "INITIALS"); - DefaultSymbols.put(GENERATION, "GENERATION"); - } - /** A HashMap with values */ - public HashMap values = new HashMap(); - - /** - * Constructs an X509 name - * @param seq an ASN1 Sequence - */ - public X509Name(ASN1Sequence seq) { - Enumeration e = seq.getObjects(); - - while (e.hasMoreElements()) { - ASN1Set set = (ASN1Set)e.nextElement(); - - for (int i = 0; i < set.size(); i++) { - ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); - String id = (String)DefaultSymbols.get(s.getObjectAt(0)); - if (id == null) - continue; - ArrayList vs = (ArrayList)values.get(id); - if (vs == null) { - vs = new ArrayList(); - values.put(id, vs); - } - vs.add(((DERString)s.getObjectAt(1)).getString()); - } - } - } - /** - * Constructs an X509 name - * @param dirName a directory name - */ - public X509Name(String dirName) { - X509NameTokenizer nTok = new X509NameTokenizer(dirName); - - while (nTok.hasMoreTokens()) { - String token = nTok.nextToken(); - int index = token.indexOf('='); - - if (index == -1) { - throw new IllegalArgumentException("badly formated directory string"); - } - - String id = token.substring(0, index).toUpperCase(); - String value = token.substring(index + 1); - ArrayList vs = (ArrayList)values.get(id); - if (vs == null) { - vs = new ArrayList(); - values.put(id, vs); - } - vs.add(value); - } - - } - - public String getField(String name) { - ArrayList vs = (ArrayList)values.get(name); - return vs == null ? null : (String)vs.get(0); - } - - /** - * gets a field array from the values Hashmap - * @param name - * @return an ArrayList - */ - public ArrayList getFieldArray(String name) { - ArrayList vs = (ArrayList)values.get(name); - return vs == null ? null : vs; - } - - /** - * getter for values - * @return a HashMap with the fields of the X509 name - */ - public HashMap getFields() { - return values; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - return values.toString(); - } - } - - /** - * class for breaking up an X500 Name into it's component tokens, ala - * java.util.StringTokenizer. We need this class as some of the - * lightweight Java environment don't support classes like - * StringTokenizer. - */ - public static class X509NameTokenizer { - private String oid; - private int index; - private StringBuffer buf = new StringBuffer(); - - public X509NameTokenizer( - String oid) { - this.oid = oid; - this.index = -1; - } - - public boolean hasMoreTokens() { - return (index != oid.length()); - } - - public String nextToken() { - if (index == oid.length()) { - return null; - } - - int end = index + 1; - boolean quoted = false; - boolean escaped = false; - - buf.setLength(0); - - while (end != oid.length()) { - char c = oid.charAt(end); - - if (c == '"') { - if (!escaped) { - quoted = !quoted; - } - else { - buf.append(c); - } - escaped = false; - } - else { - if (escaped || quoted) { - buf.append(c); - escaped = false; - } - else if (c == '\\') { - escaped = true; - } - else if (c == ',') { - break; - } - else { - buf.append(c); - } - } - end++; - } - - index = end; - return buf.toString().trim(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPRow.java b/src/main/java/com/lowagie/text/pdf/PdfPRow.java deleted file mode 100644 index 31f7cd9..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPRow.java +++ /dev/null @@ -1,659 +0,0 @@ -/* - * $Id: PdfPRow.java,v 1.72 2006/02/12 18:23:29 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.DocumentException; -import com.lowagie.text.Element; -import com.lowagie.text.Image; -import com.lowagie.text.Rectangle; -import java.awt.Color; - -/** - * A row in a PdfPTable. - * - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class PdfPRow { - - /** the bottom limit (bottom right y) */ - public static final float BOTTOM_LIMIT = -(1 << 30); - - protected PdfPCell cells[]; - - protected float widths[]; - - protected float maxHeight = 0; - - protected boolean calculated = false; - - private int[] canvasesPos; - - /** - * Constructs a new PdfPRow with the cells in the array that was passed as a parameter. - * @param cells - */ - public PdfPRow(PdfPCell cells[]) { - this.cells = cells; - widths = new float[cells.length]; - } - - /** - * Makes a copy of an existing row. - * @param row - */ - public PdfPRow(PdfPRow row) { - maxHeight = row.maxHeight; - calculated = row.calculated; - cells = new PdfPCell[row.cells.length]; - for (int k = 0; k < cells.length; ++k) { - if (row.cells[k] != null) - cells[k] = new PdfPCell(row.cells[k]); - } - widths = new float[cells.length]; - System.arraycopy(row.widths, 0, widths, 0, cells.length); - } - - /** - * Sets the widths of the columns in the row. - * @param widths - * @return true if everything went right - */ - public boolean setWidths(float widths[]) { - if (widths.length != cells.length) - return false; - System.arraycopy(widths, 0, this.widths, 0, cells.length); - float total = 0; - calculated = false; - for (int k = 0; k < widths.length; ++k) { - PdfPCell cell = cells[k]; - cell.setLeft(total); - int last = k + cell.getColspan(); - for (; k < last; ++k) - total += widths[k]; - --k; - cell.setRight(total); - cell.setTop(0); - } - return true; - } - - /** - * Calculates the heights of each cell in the row. - * @return the maximum height of the row. - */ - public float calculateHeights() { - maxHeight = 0; - for (int k = 0; k < cells.length; ++k) { - PdfPCell cell = cells[k]; - if (cell == null) - continue; - Image img = cell.getImage(); - if (img != null) { - img.scalePercent(100); - float refWidth = img.scaledWidth(); - if (cell.getRotation() == 90 || cell.getRotation() == 270) { - refWidth = img.scaledHeight(); - } - float scale = (cell.right() - cell.getEffectivePaddingRight() - - cell.getEffectivePaddingLeft() - cell.left()) - / refWidth; - img.scalePercent(scale * 100); - float refHeight = img.scaledHeight(); - if (cell.getRotation() == 90 || cell.getRotation() == 270) { - refHeight = img.scaledWidth(); - } - cell.setBottom(cell.top() - cell.getEffectivePaddingTop() - - cell.getEffectivePaddingBottom() - - refHeight); - } else { - if (cell.getRotation() == 0 || cell.getRotation() == 180) { - float rightLimit = cell.isNoWrap() ? 20000 : cell.right() - - cell.getEffectivePaddingRight(); - float bry = (cell.getFixedHeight() > 0) ? cell.top() - - cell.getEffectivePaddingTop() - + cell.getEffectivePaddingBottom() - - cell.getFixedHeight() : BOTTOM_LIMIT; - ColumnText ct = ColumnText.duplicate(cell.getColumn()); - ct.setSimpleColumn( - cell.left() + cell.getEffectivePaddingLeft(), bry, - rightLimit, cell.top() - cell.getEffectivePaddingTop()); - try { - ct.go(true); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } - float yLine = ct.getYLine(); - if (cell.isUseDescender()) - yLine += ct.getDescender(); - cell.setBottom(yLine - cell.getEffectivePaddingBottom()); - } - else { - if (cell.getFixedHeight() > 0) { - cell.setBottom(cell.top() - cell.getFixedHeight()); - } - else { - ColumnText ct = ColumnText.duplicate(cell.getColumn()); - ct.setSimpleColumn(0, cell.left() + cell.getEffectivePaddingLeft(), - 20000, cell.right() - cell.getEffectivePaddingRight()); - try { - ct.go(true); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } - cell.setBottom(cell.top() - cell.getEffectivePaddingTop() - - cell.getEffectivePaddingBottom() - ct.getFilledWidth()); - } - } - } - float height = cell.getFixedHeight(); - if (height <= 0) - height = cell.height(); - if (height < cell.getFixedHeight()) - height = cell.getFixedHeight(); - else if (height < cell.getMinimumHeight()) - height = cell.getMinimumHeight(); - if (height > maxHeight) - maxHeight = height; - } - calculated = true; - return maxHeight; - } - - /** - * Writes the border and background of one cell in the row. - * @param xPos - * @param yPos - * @param cell - * @param canvases - */ - public void writeBorderAndBackground(float xPos, float yPos, PdfPCell cell, - PdfContentByte[] canvases) { - PdfContentByte lines = canvases[PdfPTable.LINECANVAS]; - PdfContentByte backgr = canvases[PdfPTable.BACKGROUNDCANVAS]; - // the coordinates of the border are retrieved - float x1 = cell.left() + xPos; - float y2 = cell.top() + yPos; - float x2 = cell.right() + xPos; - float y1 = y2 - maxHeight; - - // the backgroundcolor is set - Color background = cell.backgroundColor(); - if (background != null) { - backgr.setColorFill(background); - backgr.rectangle(x1, y1, x2 - x1, y2 - y1); - backgr.fill(); - } - // if the element hasn't got any borders, nothing is added - if (cell.hasBorders()) { - if (cell.isUseVariableBorders()) { - Rectangle borderRect = new Rectangle(cell.left() + xPos, cell - .top() - - maxHeight + yPos, cell.right() + xPos, cell.top() - + yPos); - borderRect.cloneNonPositionParameters(cell); - borderRect.setBackgroundColor(null); - lines.rectangle(borderRect); - } else { - // the width is set to the width of the element - if (cell.borderWidth() != Rectangle.UNDEFINED) { - lines.setLineWidth(cell.borderWidth()); - } - // the color is set to the color of the element - Color color = cell.borderColor(); - if (color != null) { - lines.setColorStroke(color); - } - - // if the box is a rectangle, it is added as a rectangle - if (cell.hasBorder(Rectangle.BOX)) { - lines.rectangle(x1, y1, x2 - x1, y2 - y1); - } - // if the border isn't a rectangle, the different sides are - // added apart - else { - if (cell.hasBorder(Rectangle.RIGHT)) { - lines.moveTo(x2, y1); - lines.lineTo(x2, y2); - } - if (cell.hasBorder(Rectangle.LEFT)) { - lines.moveTo(x1, y1); - lines.lineTo(x1, y2); - } - if (cell.hasBorder(Rectangle.BOTTOM)) { - lines.moveTo(x1, y1); - lines.lineTo(x2, y1); - } - if (cell.hasBorder(Rectangle.TOP)) { - lines.moveTo(x1, y2); - lines.lineTo(x2, y2); - } - } - lines.stroke(); - if (color != null) { - lines.resetRGBColorStroke(); - } - } - } - } - - private void saveAndRotateCanvases(PdfContentByte[] canvases, float a, float b, float c, float d, float e, float f) { - int last = PdfPTable.TEXTCANVAS + 1; - if (canvasesPos == null) { - canvasesPos = new int[last * 2]; - } - for (int k = 0; k < last; ++k) { - ByteBuffer bb = canvases[k].getInternalBuffer(); - canvasesPos[k * 2] = bb.size(); - canvases[k].saveState(); - canvases[k].concatCTM(a, b, c, d, e, f); - canvasesPos[k * 2 + 1] = bb.size(); - } - } - - private void restoreCanvases(PdfContentByte[] canvases) { - int last = PdfPTable.TEXTCANVAS + 1; - for (int k = 0; k < last; ++k) { - ByteBuffer bb = canvases[k].getInternalBuffer(); - int p1 = bb.size(); - canvases[k].restoreState(); - if (p1 == canvasesPos[k * 2 + 1]) - bb.setSize(canvasesPos[k * 2]); - } - } - - /** - * Writes a number of cells (not necessarily all cells). - * @param colStart - * @param colEnd - * @param xPos - * @param yPos - * @param canvases - */ - public void writeCells(int colStart, int colEnd, float xPos, float yPos, - PdfContentByte[] canvases) { - if (!calculated) - calculateHeights(); - if (colEnd < 0) - colEnd = cells.length; - colEnd = Math.min(colEnd, cells.length); - if (colStart < 0) - colStart = 0; - if (colStart >= colEnd) - return; - int newStart; - for (newStart = colStart; newStart >= 0; --newStart) { - if (cells[newStart] != null) - break; - xPos -= widths[newStart - 1]; - } - xPos -= cells[newStart].left(); - for (int k = newStart; k < colEnd; ++k) { - PdfPCell cell = cells[k]; - if (cell == null) - continue; - writeBorderAndBackground(xPos, yPos, cell, canvases); - Image img = cell.getImage(); - float tly = 0; - switch (cell.getVerticalAlignment()) { - case Element.ALIGN_BOTTOM: - tly = cell.top() + yPos - maxHeight + cell.height() - - cell.getEffectivePaddingTop(); - break; - case Element.ALIGN_MIDDLE: - tly = cell.top() + yPos + (cell.height() - maxHeight) / 2 - - cell.getEffectivePaddingTop(); - break; - default: - tly = cell.top() + yPos - cell.getEffectivePaddingTop(); - break; - } - if (img != null) { - if (cell.getRotation() != 0) { - img = Image.getInstance(img); - img.setRotation(img.getImageRotation() + (float)(cell.getRotation() * Math.PI / 180.0)); - } - boolean vf = false; - if (cell.height() > maxHeight) { - img.scalePercent(100); - float scale = (maxHeight - cell.getEffectivePaddingTop() - cell - .getEffectivePaddingBottom()) - / img.scaledHeight(); - img.scalePercent(scale * 100); - vf = true; - } - float left = cell.left() + xPos - + cell.getEffectivePaddingLeft(); - if (vf) { - switch (cell.getHorizontalAlignment()) { - case Element.ALIGN_CENTER: - left = xPos - + (cell.left() + cell.getEffectivePaddingLeft() - + cell.right() - - cell.getEffectivePaddingRight() - img - .scaledWidth()) / 2; - break; - case Element.ALIGN_RIGHT: - left = xPos + cell.right() - - cell.getEffectivePaddingRight() - - img.scaledWidth(); - break; - default: - break; - } - tly = cell.top() + yPos - cell.getEffectivePaddingTop(); - } - img.setAbsolutePosition(left, tly - img.scaledHeight()); - try { - canvases[PdfPTable.TEXTCANVAS].addImage(img); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } - } else { - // rotation sponsored by Connection GmbH - if (cell.getRotation() == 90 || cell.getRotation() == 270) { - float netWidth = maxHeight - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom(); - float netHeight = cell.width() - cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight(); - ColumnText ct = ColumnText.duplicate(cell.getColumn()); - ct.setCanvases(canvases); - ct.setSimpleColumn(0, 0, netWidth + 0.001f, -netHeight); - try { - ct.go(true); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } - float calcHeight = -ct.getYLine(); - if (calcHeight > 0) { - if (cell.isUseDescender()) - calcHeight -= ct.getDescender(); - ct = ColumnText.duplicate(cell.getColumn()); - ct.setCanvases(canvases); - ct.setSimpleColumn(0, -0.001f, netWidth + 0.001f, calcHeight); - float pivotX; - float pivotY; - if (cell.getRotation() == 90) { - pivotY = cell.top() + yPos - maxHeight + cell.getEffectivePaddingBottom(); - switch (cell.getVerticalAlignment()) { - case Element.ALIGN_BOTTOM: - pivotX = cell.left() + xPos + cell.width() - cell.getEffectivePaddingRight(); - break; - case Element.ALIGN_MIDDLE: - pivotX = cell.left() + xPos + (cell.width() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() + calcHeight) / 2; - break; - default: //top - pivotX = cell.left() + xPos + cell.getEffectivePaddingLeft() + calcHeight; - break; - } - saveAndRotateCanvases(canvases, 0,1,-1,0,pivotX,pivotY); - } - else { - pivotY = cell.top() + yPos - cell.getEffectivePaddingTop(); - switch (cell.getVerticalAlignment()) { - case Element.ALIGN_BOTTOM: - pivotX = cell.left() + xPos + cell.getEffectivePaddingLeft(); - break; - case Element.ALIGN_MIDDLE: - pivotX = cell.left() + xPos + (cell.width() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() - calcHeight) / 2; - break; - default: //top - pivotX = cell.left() + xPos + cell.width() - cell.getEffectivePaddingRight() - calcHeight; - break; - } - saveAndRotateCanvases(canvases, 0,-1,1,0,pivotX,pivotY); - } - try { - ct.go(); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } finally { - restoreCanvases(canvases); - } - } - } - else { - float fixedHeight = cell.getFixedHeight(); - float rightLimit = cell.right() + xPos - - cell.getEffectivePaddingRight(); - float leftLimit = cell.left() + xPos - + cell.getEffectivePaddingLeft(); - if (cell.isNoWrap()) { - switch (cell.getHorizontalAlignment()) { - case Element.ALIGN_CENTER: - rightLimit += 10000; - leftLimit -= 10000; - break; - case Element.ALIGN_RIGHT: - leftLimit -= 20000; - break; - default: - rightLimit += 20000; - break; - } - } - ColumnText ct = ColumnText.duplicate(cell.getColumn()); - ct.setCanvases(canvases); - float bry = tly - - (maxHeight /* cell.height() */ - - cell.getEffectivePaddingTop() - cell.getEffectivePaddingBottom()); - if (fixedHeight > 0) { - if (cell.height() > maxHeight) { - tly = cell.top() + yPos - cell.getEffectivePaddingTop(); - bry = cell.top() + yPos - maxHeight + cell.getEffectivePaddingBottom(); - } - } - if ((tly > bry || ct.zeroHeightElement()) && leftLimit < rightLimit) { - ct.setSimpleColumn(leftLimit, bry - 0.001f, rightLimit, tly); - if (cell.getRotation() == 180) { - float shx = leftLimit + rightLimit; - float shy = bry - 0.001f + tly; - saveAndRotateCanvases(canvases, -1,0,0,-1,shx,shy); - } - try { - ct.go(); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } finally { - if (cell.getRotation() == 180) { - restoreCanvases(canvases); - } - } - } - } - } - PdfPCellEvent evt = cell.getCellEvent(); - if (evt != null) { - Rectangle rect = new Rectangle(cell.left() + xPos, cell.top() - + yPos - maxHeight, cell.right() + xPos, cell.top() - + yPos); - evt.cellLayout(cell, rect, canvases); - } - } - } - - /** - * Checks if the dimensions of the columns were calculated. - * @return true if the dimensions of the columns were calculated - */ - public boolean isCalculated() { - return calculated; - } - - /** - * Gets the maximum height of the row (i.e. of the 'highest' cell). - * @return the maximum height of the row - */ - public float getMaxHeights() { - if (calculated) - return maxHeight; - else - return calculateHeights(); - } - - /** - * Changes the maximum height of the row (to make it higher). - * (added by Jin-Hsia Yang) - * @param maxHeight the new maximum height - */ - public void setMaxHeights(float maxHeight) { - this.maxHeight = maxHeight; - } - - //end add - - float[] getEventWidth(float xPos) { - int n = 0; - for (int k = 0; k < cells.length; ++k) { - if (cells[k] != null) - ++n; - } - float width[] = new float[n + 1]; - n = 0; - width[n++] = xPos; - for (int k = 0; k < cells.length; ++k) { - if (cells[k] != null) { - width[n] = width[n - 1] + cells[k].width(); - ++n; - } - } - return width; - } - - /** - * Splits a row to newHeight. The returned row is the remainder. It will - * return null if the newHeight was so small that only an empty row would - * result. - * - * @param newHeight - * the new height - * @return the remainder row or null if the newHeight was so small that only - * an empty row would result - */ - public PdfPRow splitRow(float newHeight) { - PdfPCell newCells[] = new PdfPCell[cells.length]; - float fh[] = new float[cells.length * 2]; - boolean allEmpty = true; - for (int k = 0; k < cells.length; ++k) { - PdfPCell cell = cells[k]; - if (cell == null) - continue; - fh[k * 2] = cell.getFixedHeight(); - fh[k * 2 + 1] = cell.getMinimumHeight(); - Image img = cell.getImage(); - PdfPCell c2 = new PdfPCell(cell); - if (img != null) { - if (newHeight > cell.getEffectivePaddingBottom() - + cell.getEffectivePaddingTop() + 2) { - c2.setPhrase(null); - allEmpty = false; - } - } else { - int status; - float y; - ColumnText ct = ColumnText.duplicate(cell.getColumn()); - if (cell.getRotation() == 90 || cell.getRotation() == 270) { - ct.setSimpleColumn( - cell.top() - newHeight + cell.getEffectivePaddingBottom(), - cell.left() + cell.getEffectivePaddingLeft(), - cell.top() - cell.getEffectivePaddingTop(), - y = cell.right() - cell.getEffectivePaddingRight()); - } - else { - float rightLimit = cell.isNoWrap() ? 20000 : cell.right() - - cell.getEffectivePaddingRight(); - float y1 = cell.top() - newHeight - + cell.getEffectivePaddingBottom(); - float y2 = cell.top() - cell.getEffectivePaddingTop(); - y = Math.max(y1, y2); - ct.setSimpleColumn( - cell.left() + cell.getEffectivePaddingLeft(), y1, - rightLimit, y2); - } - try { - status = ct.go(true); - } catch (DocumentException e) { - throw new ExceptionConverter(e); - } - boolean thisEmpty = (ct.getYLine() == y); - if (thisEmpty) - ct = ColumnText.duplicate(cell.getColumn()); - allEmpty = (allEmpty && thisEmpty); - if ((status & ColumnText.NO_MORE_TEXT) == 0 || thisEmpty) { - c2.setColumn(ct); - ct.setFilledWidth(0); - } else { - c2.setPhrase(null); - } - } - newCells[k] = c2; - cell.setFixedHeight(newHeight); - } - if (allEmpty) { - for (int k = 0; k < cells.length; ++k) { - PdfPCell cell = cells[k]; - if (cell == null) - continue; - float f = fh[k * 2]; - float m = fh[k * 2 + 1]; - if (f <= 0) - cell.setMinimumHeight(m); - else - cell.setFixedHeight(f); - } - return null; - } - calculateHeights(); - PdfPRow split = new PdfPRow(newCells); - split.widths = (float[]) widths.clone(); - split.calculateHeights(); - return split; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPSXObject.java b/src/main/java/com/lowagie/text/pdf/PdfPSXObject.java deleted file mode 100644 index 434a848..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPSXObject.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2005 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; - -/** - * Implements the PostScript XObject. - */ -public class PdfPSXObject extends PdfTemplate { - - /** Creates a new instance of PdfPSXObject */ - protected PdfPSXObject() { - super(); - } - - /** - * Constructs a PSXObject - * @param wr - */ - public PdfPSXObject(PdfWriter wr) { - super(wr); - } - - /** - * Gets the stream representing this object. - * - * @return the stream representing this object - * @throws IOException - */ - - PdfStream getFormXObject() throws IOException { - PdfStream s = new PdfStream(content.toByteArray()); - s.put(PdfName.TYPE, PdfName.XOBJECT); - s.put(PdfName.SUBTYPE, PdfName.PS); - s.flateCompress(); - return s; - } - - /** - * Gets a duplicate of this PdfPSXObject. All - * the members are copied by reference but the buffer stays different. - * @return a copy of this PdfPSXObject - */ - - public PdfContentByte getDuplicate() { - PdfPSXObject tpl = new PdfPSXObject(); - tpl.writer = writer; - tpl.pdf = pdf; - tpl.thisReference = thisReference; - tpl.pageResources = pageResources; - tpl.separator = separator; - return tpl; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPTable.java b/src/main/java/com/lowagie/text/pdf/PdfPTable.java deleted file mode 100644 index 280bcf0..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPTable.java +++ /dev/null @@ -1,1081 +0,0 @@ -/* - * $Id: PdfPTable.java,v 1.66 2005/11/19 18:17:51 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import com.lowagie.text.Phrase; -import com.lowagie.text.Element; -import com.lowagie.text.Image; -import com.lowagie.text.Rectangle; -import com.lowagie.text.ElementListener; -import com.lowagie.text.DocumentException; -import com.lowagie.text.pdf.events.PdfPTableEventForwarder; - -/** This is a table that can be put at an absolute position but can also - * be added to the document as the class Table. - * In the last case when crossing pages the table always break at full rows; if a - * row is bigger than the page it is dropped silently to avoid infinite loops. - *

- * A PdfPTableEvent can be associated to the table to do custom drawing - * when the table is rendered. - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class PdfPTable implements Element{ - - /** The index of the original PdfcontentByte. - */ - public static final int BASECANVAS = 0; - /** The index of the duplicate PdfContentByte where the background will be drawn. - */ - public static final int BACKGROUNDCANVAS = 1; - /** The index of the duplicate PdfContentByte where the border lines will be drawn. - */ - public static final int LINECANVAS = 2; - /** The index of the duplicate PdfContentByte where the text will be drawn. - */ - public static final int TEXTCANVAS = 3; - - protected ArrayList rows = new ArrayList(); - protected float totalHeight = 0; - protected PdfPCell currentRow[]; - protected int currentRowIdx = 0; - protected PdfPCell defaultCell = new PdfPCell((Phrase)null); - protected float totalWidth = 0; - protected float relativeWidths[]; - protected float absoluteWidths[]; - protected PdfPTableEvent tableEvent; - -/** Holds value of property headerRows. */ - protected int headerRows; - -/** Holds value of property widthPercentage. */ - protected float widthPercentage = 80; - -/** Holds value of property horizontalAlignment. */ - private int horizontalAlignment = Element.ALIGN_CENTER; - -/** Holds value of property skipFirstHeader. */ - private boolean skipFirstHeader = false; - - protected boolean isColspan = false; - - protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT; - - /** - * Holds value of property lockedWidth. - */ - private boolean lockedWidth = false; - - /** - * Holds value of property splitRows. - */ - private boolean splitRows = true; - -/** The spacing before the table. */ - protected float spacingBefore; - -/** The spacing after the table. */ - protected float spacingAfter; - - /** - * Holds value of property extendLastRow. - */ - private boolean extendLastRow; - - /** - * Holds value of property headersInEvent. - */ - private boolean headersInEvent; - - /** - * Holds value of property splitLate. - */ - private boolean splitLate = true; - - /** - * Defines if the table should be kept - * on one page if possible - */ - private boolean keepTogether; - - /** - * Holds value of property footerRows. - */ - private int footerRows; - - protected PdfPTable() { - } - - /** Constructs a PdfPTable with the relative column widths. - * @param relativeWidths the relative column widths - */ - public PdfPTable(float relativeWidths[]) { - if (relativeWidths == null) - throw new NullPointerException("The widths array in PdfPTable constructor can not be null."); - if (relativeWidths.length == 0) - throw new IllegalArgumentException("The widths array in PdfPTable constructor can not have zero length."); - this.relativeWidths = new float[relativeWidths.length]; - System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); - absoluteWidths = new float[relativeWidths.length]; - calculateWidths(); - currentRow = new PdfPCell[absoluteWidths.length]; - keepTogether = false; - } - - /** Constructs a PdfPTable with numColumns columns. - * @param numColumns the number of columns - */ - public PdfPTable(int numColumns) { - if (numColumns <= 0) - throw new IllegalArgumentException("The number of columns in PdfPTable constructor must be greater than zero."); - relativeWidths = new float[numColumns]; - for (int k = 0; k < numColumns; ++k) - relativeWidths[k] = 1; - absoluteWidths = new float[relativeWidths.length]; - calculateWidths(); - currentRow = new PdfPCell[absoluteWidths.length]; - keepTogether = false; - } - - /** Constructs a copy of a PdfPTable. - * @param table the PdfPTable to be copied - */ - public PdfPTable(PdfPTable table) { - copyFormat(table); - for (int k = 0; k < currentRow.length; ++k) { - if (table.currentRow[k] == null) - break; - currentRow[k] = new PdfPCell(table.currentRow[k]); - } - for (int k = 0; k < table.rows.size(); ++k) { - PdfPRow row = (PdfPRow)(table.rows.get(k)); - if (row != null) - row = new PdfPRow(row); - rows.add(row); - } - } - - /** - * Makes a shallow copy of a table (format without content). - * @param table - * @return a shallow copy of the table - */ - public static PdfPTable shallowCopy(PdfPTable table) { - PdfPTable nt = new PdfPTable(); - nt.copyFormat(table); - return nt; - } - - /** - * Copies the format of the sourceTable without copying the content. - * @param sourceTable - */ - private void copyFormat(PdfPTable sourceTable) { - relativeWidths = new float[sourceTable.relativeWidths.length]; - absoluteWidths = new float[sourceTable.relativeWidths.length]; - System.arraycopy(sourceTable.relativeWidths, 0, relativeWidths, 0, relativeWidths.length); - System.arraycopy(sourceTable.absoluteWidths, 0, absoluteWidths, 0, relativeWidths.length); - totalWidth = sourceTable.totalWidth; - totalHeight = sourceTable.totalHeight; - currentRowIdx = 0; - tableEvent = sourceTable.tableEvent; - runDirection = sourceTable.runDirection; - defaultCell = new PdfPCell(sourceTable.defaultCell); - currentRow = new PdfPCell[sourceTable.currentRow.length]; - isColspan = sourceTable.isColspan; - splitRows = sourceTable.splitRows; - spacingAfter = sourceTable.spacingAfter; - spacingBefore = sourceTable.spacingBefore; - headerRows = sourceTable.headerRows; - footerRows = sourceTable.footerRows; - lockedWidth = sourceTable.lockedWidth; - extendLastRow = sourceTable.extendLastRow; - headersInEvent = sourceTable.headersInEvent; - widthPercentage = sourceTable.widthPercentage; - splitLate = sourceTable.splitLate; - skipFirstHeader = sourceTable.skipFirstHeader; - horizontalAlignment = sourceTable.horizontalAlignment; - keepTogether = sourceTable.keepTogether; - } - - /** Sets the relative widths of the table. - * @param relativeWidths the relative widths of the table. - * @throws DocumentException if the number of widths is different than the number - * of columns - */ - public void setWidths(float relativeWidths[]) throws DocumentException { - if (relativeWidths.length != this.relativeWidths.length) - throw new DocumentException("Wrong number of columns."); - this.relativeWidths = new float[relativeWidths.length]; - System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); - absoluteWidths = new float[relativeWidths.length]; - totalHeight = 0; - calculateWidths(); - calculateHeights(); - } - - /** Sets the relative widths of the table. - * @param relativeWidths the relative widths of the table. - * @throws DocumentException if the number of widths is different than the number - * of columns - */ - public void setWidths(int relativeWidths[]) throws DocumentException { - float tb[] = new float[relativeWidths.length]; - for (int k = 0; k < relativeWidths.length; ++k) - tb[k] = relativeWidths[k]; - setWidths(tb); - } - - private void calculateWidths() { - if (totalWidth <= 0) - return; - float total = 0; - for (int k = 0; k < absoluteWidths.length; ++k) { - total += relativeWidths[k]; - } - for (int k = 0; k < absoluteWidths.length; ++k) { - absoluteWidths[k] = totalWidth * relativeWidths[k] / total; - } - } - - /** Sets the full width of the table. - * @param totalWidth the full width of the table. - */ - public void setTotalWidth(float totalWidth) { - if (this.totalWidth == totalWidth) - return; - this.totalWidth = totalWidth; - totalHeight = 0; - calculateWidths(); - calculateHeights(); - } - - /** Sets the full width of the table from the absolute column width. - * @param columnWidth the absolute width of each column - * @throws DocumentException if the number of widths is different than the number - * of columns - */ - public void setTotalWidth(float columnWidth[]) throws DocumentException { - if (columnWidth.length != this.relativeWidths.length) - throw new DocumentException("Wrong number of columns."); - totalWidth = 0; - for (int k = 0; k < columnWidth.length; ++k) - totalWidth += columnWidth[k]; - setWidths(columnWidth); - } - - /** Sets the percentage width of the table from the absolute column width. - * @param columnWidth the absolute width of each column - * @param pageSize the page size - * @throws DocumentException - */ - public void setWidthPercentage(float columnWidth[], Rectangle pageSize) throws DocumentException { - if (columnWidth.length != this.relativeWidths.length) - throw new IllegalArgumentException("Wrong number of columns."); - float totalWidth = 0; - for (int k = 0; k < columnWidth.length; ++k) - totalWidth += columnWidth[k]; - widthPercentage = totalWidth / (pageSize.right() - pageSize.left()) * 100f; - setWidths(columnWidth); - } - - /** Gets the full width of the table. - * @return the full width of the table - */ - public float getTotalWidth() { - return totalWidth; - } - - void calculateHeights() { - if (totalWidth <= 0) - return; - totalHeight = 0; - for (int k = 0; k < rows.size(); ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - if (row != null) { - row.setWidths(absoluteWidths); - totalHeight += row.getMaxHeights(); - } - } - } - - /** - * Calculates the heights of the table. - */ - public void calculateHeightsFast() { - if (totalWidth <= 0) - return; - totalHeight = 0; - for (int k = 0; k < rows.size(); ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - if (row != null) - totalHeight += row.getMaxHeights(); - } - } - - /** Gets the default PdfPCell that will be used as - * reference for all the addCell methods except - * addCell(PdfPCell). - * @return default PdfPCell - */ - public PdfPCell getDefaultCell() { - return defaultCell; - } - - /** Adds a cell element. - * @param cell the cell element - */ - public void addCell(PdfPCell cell) { - PdfPCell ncell = new PdfPCell(cell); - int colspan = ncell.getColspan(); - colspan = Math.max(colspan, 1); - colspan = Math.min(colspan, currentRow.length - currentRowIdx); - ncell.setColspan(colspan); - if (colspan != 1) - isColspan = true; - int rdir = ncell.getRunDirection(); - if (rdir == PdfWriter.RUN_DIRECTION_DEFAULT) - ncell.setRunDirection(runDirection); - currentRow[currentRowIdx] = ncell; - currentRowIdx += colspan; - if (currentRowIdx >= currentRow.length) { - if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { - PdfPCell rtlRow[] = new PdfPCell[absoluteWidths.length]; - int rev = currentRow.length; - for (int k = 0; k < currentRow.length; ++k) { - PdfPCell rcell = currentRow[k]; - int cspan = rcell.getColspan(); - rev -= cspan; - rtlRow[rev] = rcell; - k += cspan - 1; - } - currentRow = rtlRow; - } - PdfPRow row = new PdfPRow(currentRow); - if (totalWidth > 0) { - row.setWidths(absoluteWidths); - totalHeight += row.getMaxHeights(); - } - rows.add(row); - currentRow = new PdfPCell[absoluteWidths.length]; - currentRowIdx = 0; - } - } - - /** Adds a cell element. - * @param text the text for the cell - */ - public void addCell(String text) { - addCell(new Phrase(text)); - } - - /** - * Adds a nested table. - * @param table the table to be added to the cell - */ - public void addCell(PdfPTable table) { - defaultCell.setTable(table); - addCell(defaultCell); - defaultCell.setTable(null); - } - - /** - * Adds an Image as Cell. - * @param image the Image to add to the table. This image will fit in the cell - */ - public void addCell(Image image) { - defaultCell.setImage(image); - addCell(defaultCell); - defaultCell.setImage(null); - } - - /** - * Adds a cell element. - * @param phrase the Phrase to be added to the cell - */ - public void addCell(Phrase phrase) { - defaultCell.setPhrase(phrase); - addCell(defaultCell); - defaultCell.setPhrase(null); - } - - /** - * Writes the selected rows to the document. - *

- * canvases is obtained from beginWritingRows(). - * @param rowStart the first row to be written, zero index - * @param rowEnd the last row to be written + 1. If it is -1 all the - * rows to the end are written - * @param xPos the x write coodinate - * @param yPos the y write coodinate - * @param canvases an array of 4 PdfContentByte obtained from - * beginWrittingRows() - * @return the y coordinate position of the bottom of the last row - * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte) - */ - public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { - return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvases); - } - - /** Writes the selected rows and columns to the document. - * This method does not clip the columns; this is only important - * if there are columns with colspan at boundaries. - *

- * canvases is obtained from beginWritingRows(). - *

- * The table event is only fired for complete rows. - * @param colStart the first column to be written, zero index - * @param colEnd the last column to be written + 1. If it is -1 all the - * columns to the end are written - * @param rowStart the first row to be written, zero index - * @param rowEnd the last row to be written + 1. If it is -1 all the - * rows to the end are written - * @param xPos the x write coodinate - * @param yPos the y write coodinate - * @param canvases an array of 4 PdfContentByte obtained from - * beginWrittingRows() - * @return the y coordinate position of the bottom of the last row - * @see #beginWritingRows(com.lowagie.text.pdf.PdfContentByte) - */ - public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { - if (totalWidth <= 0) - throw new RuntimeException("The table width must be greater than zero."); - int size = rows.size(); - if (rowEnd < 0) - rowEnd = size; - rowEnd = Math.min(rowEnd, size); - if (rowStart < 0) - rowStart = 0; - if (rowStart >= rowEnd) - return yPos; - if (colEnd < 0) - colEnd = absoluteWidths.length; - colEnd = Math.min(colEnd, absoluteWidths.length); - if (colStart < 0) - colStart = 0; - colStart = Math.min(colStart, absoluteWidths.length); - float yPosStart = yPos; - for (int k = rowStart; k < rowEnd; ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - if (row != null) { - row.writeCells(colStart, colEnd, xPos, yPos, canvases); - yPos -= row.getMaxHeights(); - } - } - if (tableEvent != null && colStart == 0 && colEnd == absoluteWidths.length) { - float heights[] = new float[rowEnd - rowStart + 1]; - heights[0] = yPosStart; - for (int k = rowStart; k < rowEnd; ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - float hr = 0; - if (row != null) - hr = row.getMaxHeights(); - heights[k - rowStart + 1] = heights[k - rowStart] - hr; - } - tableEvent.tableLayout(this, getEventWidths(xPos, rowStart, rowEnd, headersInEvent), heights, headersInEvent ? headerRows : 0, rowStart, canvases); - } - return yPos; - } - - /** - * Writes the selected rows to the document. - * - * @param rowStart the first row to be written, zero index - * @param rowEnd the last row to be written + 1. If it is -1 all the - * rows to the end are written - * @param xPos the x write coodinate - * @param yPos the y write coodinate - * @param canvas the PdfContentByte where the rows will - * be written to - * @return the y coordinate position of the bottom of the last row - */ - public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { - return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvas); - } - - /** - * Writes the selected rows to the document. - * This method clips the columns; this is only important - * if there are columns with colspan at boundaries. - *

- * The table event is only fired for complete rows. - * - * @param colStart the first column to be written, zero index - * @param colEnd the last column to be written + 1. If it is -1 all the - * @param rowStart the first row to be written, zero index - * @param rowEnd the last row to be written + 1. If it is -1 all the - * rows to the end are written - * @param xPos the x write coodinate - * @param yPos the y write coodinate - * @param canvas the PdfContentByte where the rows will - * be written to - * @return the y coordinate position of the bottom of the last row - */ - public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { - if (colEnd < 0) - colEnd = absoluteWidths.length; - colEnd = Math.min(colEnd, absoluteWidths.length); - if (colStart < 0) - colStart = 0; - colStart = Math.min(colStart, absoluteWidths.length); - if (colStart != 0 || colEnd != absoluteWidths.length) { - float w = 0; - for (int k = colStart; k < colEnd; ++k) - w += absoluteWidths[k]; - canvas.saveState(); - float lx = 0; - float rx = 0; - if (colStart == 0) - lx = 10000; - if (colEnd == absoluteWidths.length) - rx = 10000; - canvas.rectangle(xPos - lx, -10000, w + lx + rx, 20000); - canvas.clip(); - canvas.newPath(); - } - PdfContentByte[] canvases = beginWritingRows(canvas); - float y = writeSelectedRows(colStart, colEnd, rowStart, rowEnd, xPos, yPos, canvases); - endWritingRows(canvases); - if (colStart != 0 || colEnd != absoluteWidths.length) - canvas.restoreState(); - return y; - } - - /** Gets and initializes the 4 layers where the table is written to. The text or graphics are added to - * one of the 4 PdfContentByte returned with the following order:

- *

- * The layers are placed in sequence on top of each other. - * @param canvas the PdfContentByte where the rows will - * be written to - * @return an array of 4 PdfContentByte - * @see #writeSelectedRows(int, int, float, float, PdfContentByte[]) - */ - public static PdfContentByte[] beginWritingRows(PdfContentByte canvas) { - return new PdfContentByte[]{ - canvas, - canvas.getDuplicate(), - canvas.getDuplicate(), - canvas.getDuplicate(), - }; - } - - /** Finishes writing the table. - * @param canvases the array returned by beginWritingRows() - */ - public static void endWritingRows(PdfContentByte[] canvases) { - PdfContentByte canvas = canvases[BASECANVAS]; - canvas.saveState(); - canvas.add(canvases[BACKGROUNDCANVAS]); - canvas.restoreState(); - canvas.saveState(); - canvas.setLineCap(2); - canvas.resetRGBColorStroke(); - canvas.add(canvases[LINECANVAS]); - canvas.restoreState(); - canvas.add(canvases[TEXTCANVAS]); - } - - /** Gets the number of rows in this table. - * @return the number of rows in this table - */ - public int size() { - return rows.size(); - } - - /** Gets the total height of the table. - * @return the total height of the table - */ - public float getTotalHeight() { - return totalHeight; - } - - /** Gets the height of a particular row. - * @param idx the row index (starts at 0) - * @return the height of a particular row - */ - public float getRowHeight(int idx) { - if (totalWidth <= 0 || idx < 0 || idx >= rows.size()) - return 0; - PdfPRow row = (PdfPRow)rows.get(idx); - if (row == null) - return 0; - return row.getMaxHeights(); - } - - /** Gets the height of the rows that constitute the header as defined by - * setHeaderRows(). - * @return the height of the rows that constitute the header - */ - public float getHeaderHeight() { - float total = 0; - int size = Math.min(rows.size(), headerRows); - for (int k = 0; k < size; ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - if (row != null) - total += row.getMaxHeights(); - } - return total; - } - - /** Deletes a row from the table. - * @param rowNumber the row to be deleted - * @return true if the row was deleted - */ - public boolean deleteRow(int rowNumber) { - if (rowNumber < 0 || rowNumber >= rows.size()) { - return false; - } - if (totalWidth > 0) { - PdfPRow row = (PdfPRow)rows.get(rowNumber); - if (row != null) - totalHeight -= row.getMaxHeights(); - } - rows.remove(rowNumber); - return true; - } - - /** Deletes the last row in the table. - * @return true if the last row was deleted - */ - public boolean deleteLastRow() { - return deleteRow(rows.size() - 1); - } - - /** - * Removes all of the rows except headers - */ - public void deleteBodyRows() { - ArrayList rows2 = new ArrayList(); - for (int k = 0; k < headerRows; ++k) - rows2.add(rows.get(k)); - rows = rows2; - totalHeight = 0; - if (totalWidth > 0) - totalHeight = getHeaderHeight(); - } - - /** Gets the number of the rows that constitute the header. - * @return the number of the rows that constitute the header - */ - public int getHeaderRows() { - return headerRows; - } - - /** Sets the number of the top rows that constitute the header. - * This header has only meaning if the table is added to Document - * and the table crosses pages. - * @param headerRows the number of the top rows that constitute the header - */ - public void setHeaderRows(int headerRows) { - if (headerRows < 0) - headerRows = 0; - this.headerRows = headerRows; - } - - /** - * Gets all the chunks in this element. - * - * @return an ArrayList - */ - public ArrayList getChunks() { - return new ArrayList(); - } - - /** - * Gets the type of the text element. - * - * @return a type - */ - public int type() { - return Element.PTABLE; - } - - /** - * Processes the element by adding it (or the different parts) to an - * ElementListener. - * - * @param listener an ElementListener - * @return true if the element was processed successfully - */ - public boolean process(ElementListener listener) { - try { - return listener.add(this); - } - catch(DocumentException de) { - return false; - } - } - - /** Gets the width percentage that the table will occupy in the page. - * @return the width percentage that the table will occupy in the page - */ - public float getWidthPercentage() { - return widthPercentage; - } - - /** Sets the width percentage that the table will occupy in the page. - * @param widthPercentage the width percentage that the table will occupy in the page - */ - public void setWidthPercentage(float widthPercentage) { - this.widthPercentage = widthPercentage; - } - - /** Gets the horizontal alignment of the table relative to the page. - * @return the horizontal alignment of the table relative to the page - */ - public int getHorizontalAlignment() { - return horizontalAlignment; - } - - /** Sets the horizontal alignment of the table relative to the page. - * It only has meaning if the width percentage is less than - * 100%. - * @param horizontalAlignment the horizontal alignment of the table relative to the page - */ - public void setHorizontalAlignment(int horizontalAlignment) { - this.horizontalAlignment = horizontalAlignment; - } - - /** - * Gets a row with a given index - * (added by Jin-Hsia Yang). - * @param idx - * @return the row at position idx - */ - public PdfPRow getRow(int idx) { - return (PdfPRow)rows.get(idx); - } - - /** - * Gets an arraylist with all the rows in the table. - * @return an arraylist - */ - public ArrayList getRows() { - return rows; - } - - /** Sets the table event for this table. - * @param event the table event for this table - */ - public void setTableEvent(PdfPTableEvent event) { - if (event == null) this.tableEvent = null; - else if (this.tableEvent == null) this.tableEvent = event; - else if (this.tableEvent instanceof PdfPTableEventForwarder) ((PdfPTableEventForwarder)this.tableEvent).addTableEvent(event); - else { - PdfPTableEventForwarder forward = new PdfPTableEventForwarder(); - forward.addTableEvent(this.tableEvent); - forward.addTableEvent(event); - this.tableEvent = forward; - } - } - - /** Gets the table event for this page. - * @return the table event for this page - */ - public PdfPTableEvent getTableEvent() { - return tableEvent; - } - - /** Gets the absolute sizes of each column width. - * @return he absolute sizes of each column width - */ - public float[] getAbsoluteWidths() { - return absoluteWidths; - } - - float [][] getEventWidths(float xPos, int firstRow, int lastRow, boolean includeHeaders) { - if (includeHeaders) { - firstRow = Math.max(firstRow, headerRows); - lastRow = Math.max(lastRow, headerRows); - } - float widths[][] = new float[(includeHeaders ? headerRows : 0) + lastRow - firstRow][]; - if (isColspan) { - int n = 0; - if (includeHeaders) { - for (int k = 0; k < headerRows; ++k) { - PdfPRow row = (PdfPRow)rows.get(k); - if (row == null) - ++n; - else - widths[n++] = row.getEventWidth(xPos); - } - } - for (; firstRow < lastRow; ++firstRow) { - PdfPRow row = (PdfPRow)rows.get(firstRow); - if (row == null) - ++n; - else - widths[n++] = row.getEventWidth(xPos); - } - } - else { - float width[] = new float[absoluteWidths.length + 1]; - width[0] = xPos; - for (int k = 0; k < absoluteWidths.length; ++k) - width[k + 1] = width[k] + absoluteWidths[k]; - for (int k = 0; k < widths.length; ++k) - widths[k] = width; - } - return widths; - } - - - /** Getter for property skipFirstHeader. - * @return Value of property skipFirstHeader. - */ - public boolean isSkipFirstHeader() { - return skipFirstHeader; - } - - /** Skips the printing of the first header. Used when printing - * tables in succession belonging to the same printed table aspect. - * @param skipFirstHeader New value of property skipFirstHeader. - */ - public void setSkipFirstHeader(boolean skipFirstHeader) { - this.skipFirstHeader = skipFirstHeader; - } - - /** - * Sets the run direction of the contents of the table. - * @param runDirection - */ - public void setRunDirection(int runDirection) { - if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) - throw new RuntimeException("Invalid run direction: " + runDirection); - this.runDirection = runDirection; - } - - /** - * Returns the run direction of the contents in the table. - * @return One of the following values: PdfWriter.RUN_DIRECTION_DEFAULT, PdfWriter.RUN_DIRECTION_NO_BIDI, PdfWriter.RUN_DIRECTION_LTR or PdfWriter.RUN_DIRECTION_RTL. - */ - public int getRunDirection() { - return runDirection; - } - - /** - * Getter for property lockedWidth. - * @return Value of property lockedWidth. - */ - public boolean isLockedWidth() { - return this.lockedWidth; - } - - /** - * Uses the value in setTotalWidth() in Document.add(). - * @param lockedWidth true to use the value in setTotalWidth() in Document.add() - */ - public void setLockedWidth(boolean lockedWidth) { - this.lockedWidth = lockedWidth; - } - - /** - * Gets the split value. - * @return true to split; false otherwise - */ - public boolean isSplitRows() { - return this.splitRows; - } - - /** - * When set the rows that won't fit in the page will be split. - * Note that it takes at least twice the memory to handle a split table row - * than a normal table. true by default. - * @param splitRows true to split; false otherwise - */ - public void setSplitRows(boolean splitRows) { - this.splitRows = splitRows; - } - -/** - * Sets the spacing before this table. - * - * @param spacing the new spacing - */ - - public void setSpacingBefore(float spacing) { - this.spacingBefore = spacing; - } - -/** - * Sets the spacing after this table. - * - * @param spacing the new spacing - */ - - public void setSpacingAfter(float spacing) { - this.spacingAfter = spacing; - } - -/** - * Gets the spacing before this table. - * - * @return the spacing - */ - - public float spacingBefore() { - return spacingBefore; - } - -/** - * Gets the spacing before this table. - * - * @return the spacing - */ - - public float spacingAfter() { - return spacingAfter; - } - - /** - * Gets the value of the last row extension. - * @return true if the last row will extend; false otherwise - */ - public boolean isExtendLastRow() { - return this.extendLastRow; - } - - /** - * When set the last row will be extended to fill all the remaining space to the - * bottom boundary. - * @param extendLastRow true to extend the last row; false otherwise - */ - public void setExtendLastRow(boolean extendLastRow) { - this.extendLastRow = extendLastRow; - } - - /** - * Gets the header status inclusion in PdfPTableEvent. - * @return true if the headers are included; false otherwise - */ - public boolean isHeadersInEvent() { - return this.headersInEvent; - } - - /** - * When set the PdfPTableEvent will include the headers. - * @param headersInEvent true to include the headers; false otherwise - */ - public void setHeadersInEvent(boolean headersInEvent) { - this.headersInEvent = headersInEvent; - } - - /** - * Gets the property splitLate. - * @return the property splitLate - */ - public boolean isSplitLate() { - return this.splitLate; - } - - /** - * If true the row will only split if it's the first one in an empty page. - * It's true by default. - *

- * It's only meaningful if setSplitRows(true). - * @param splitLate the property value - */ - public void setSplitLate(boolean splitLate) { - this.splitLate = splitLate; - } - - /** - * If true the table will be kept on one page if it fits, by forcing a - * new page if it doesn't fit on the current page. The default is to - * split the table over multiple pages. - * - * @param p_KeepTogether whether to try to keep the table on one page - */ - public void setKeepTogether(boolean p_KeepTogether) { - keepTogether = p_KeepTogether; - } - - public boolean getKeepTogether() { - return keepTogether; - } - - /** - * Gets the number of rows in the footer. - * @return the number of rows in the footer - */ - public int getFooterRows() { - return this.footerRows; - } - - /** - * Sets the number of rows to be used for the footer. The number - * of footer rows are subtracted from the header rows. For - * example, for a table with two header rows and one footer row the - * code would be: - *

- *

-     * table.setHeaderRows(3);
-     * table.setFooterRows(1);
-     * 
- *

- * Row 0 and 1 will be the header rows and row 2 will be the footer row. - * @param footerRows the number of rows to be used for the footer - */ - public void setFooterRows(int footerRows) { - if (footerRows < 0) - footerRows = 0; - this.footerRows = footerRows; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPTableEvent.java b/src/main/java/com/lowagie/text/pdf/PdfPTableEvent.java deleted file mode 100644 index 9ae90ff..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPTableEvent.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * $Id: PdfPTableEvent.java,v 1.45 2005/05/04 14:32:42 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** An interface that can be used to retrieve the position of cells in PdfPTable. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public interface PdfPTableEvent { - - /** This method is called at the end of the table rendering. The text or graphics are added to - * one of the 4 PdfContentByte contained in - * canvases.
- * The indexes to canvases are:

- *

- * The layers are placed in sequence on top of each other. - *

- * The widths and heights have the coordinates of the cells.
- * The size of the widths array is the number of rows. - * Each sub-array in widths corresponds to the x column border positions where - * the first element is the x coordinate of the left table border and the last - * element is the x coordinate of the right table border. - * If colspan is not used all the sub-arrays in widths - * are the same.
- * For the heights the first element is the y coordinate of the top table border and the last - * element is the y coordinate of the bottom table border. - * @param table the PdfPTable in use - * @param widths an array of arrays with the cells' x positions. It has the length of the number - * of rows - * @param heights an array with the cells' y positions. It has a length of the number - * of rows + 1 - * @param headerRows the number of rows defined for the header. - * @param rowStart the first row number after the header - * @param canvases an array of PdfContentByte - */ - public void tableLayout(PdfPTable table, float widths[][], float heights[], int headerRows, int rowStart, PdfContentByte[] canvases); - -} - diff --git a/src/main/java/com/lowagie/text/pdf/PdfPage.java b/src/main/java/com/lowagie/text/pdf/PdfPage.java deleted file mode 100644 index 80e5472..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPage.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * $Id: PdfPage.java,v 1.48 2006/02/16 16:17:52 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.util.HashMap; -/** - * PdfPage is the PDF Page-object. - *

- * A Page object is a dictionary whose keys describe a single page containing text, - * graphics, and images. A Page onjects is a leaf of the Pages tree.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 6.4 (page 73-81) - * - * @see PdfPages - */ - -public class PdfPage extends PdfDictionary { - - private static final String boxStrings[] = {"crop", "trim", "art", "bleed"}; - private static final PdfName boxNames[] = {PdfName.CROPBOX, PdfName.TRIMBOX, PdfName.ARTBOX, PdfName.BLEEDBOX}; - // membervariables - -/** value of the Rotate key for a page in PORTRAIT */ - public static final PdfNumber PORTRAIT = new PdfNumber(0); - -/** value of the Rotate key for a page in LANDSCAPE */ - public static final PdfNumber LANDSCAPE = new PdfNumber(90); - -/** value of the Rotate key for a page in INVERTEDPORTRAIT */ - public static final PdfNumber INVERTEDPORTRAIT = new PdfNumber(180); - -/** value of the Rotate key for a page in SEASCAPE */ - public static final PdfNumber SEASCAPE = new PdfNumber(270); - -/** value of the MediaBox key */ - PdfRectangle mediaBox; - - // constructors - -/** - * Constructs a PdfPage. - * - * @param mediaBox a value for the MediaBox key - * @param resources an indirect reference to a PdfResources-object - * @param rotate a value for the Rotate key - */ - -// PdfPage(PdfRectangle mediaBox, Rectangle cropBox, PdfIndirectReference resources, PdfNumber rotate) { -// super(PAGE); -// this.mediaBox = mediaBox; -// put(PdfName.MEDIABOX, mediaBox); -// put(PdfName.RESOURCES, resources); -// if (rotate != null) { -// put(PdfName.ROTATE, rotate); -// } -// if (cropBox != null) -// put(PdfName.CROPBOX, new PdfRectangle(cropBox)); -// } - -/** - * Constructs a PdfPage. - * - * @param mediaBox a value for the MediaBox key - * @param resources an indirect reference to a PdfResources-object - * @param rotate a value for the Rotate key - */ - - PdfPage(PdfRectangle mediaBox, HashMap boxSize, PdfDictionary resources, int rotate) { - super(PAGE); - this.mediaBox = mediaBox; - put(PdfName.MEDIABOX, mediaBox); - put(PdfName.RESOURCES, resources); - if (rotate != 0) { - put(PdfName.ROTATE, new PdfNumber(rotate)); - } - for (int k = 0; k < boxStrings.length; ++k) { - PdfObject rect = (PdfObject)boxSize.get(boxStrings[k]); - if (rect != null) - put(boxNames[k], rect); - } - } - -/** - * Constructs a PdfPage. - * - * @param mediaBox a value for the MediaBox key - * @param resources an indirect reference to a PdfResources-object - */ - -// PdfPage(PdfRectangle mediaBox, Rectangle cropBox, PdfIndirectReference resources) { -// this(mediaBox, cropBox, resources, null); -// } - -/** - * Constructs a PdfPage. - * - * @param mediaBox a value for the MediaBox key - * @param resources an indirect reference to a PdfResources-object - */ - - PdfPage(PdfRectangle mediaBox, HashMap boxSize, PdfDictionary resources) { - this(mediaBox, boxSize, resources, 0); - } - -/** - * Checks if this page element is a tree of pages. - *

- * This method allways returns false. - * - * @return false because this is a single page - */ - - public boolean isParent() { - return false; - } - - // methods - -/** - * Adds an indirect reference pointing to a PdfContents-object. - * - * @param contents an indirect reference to a PdfContents-object - */ - - void add(PdfIndirectReference contents) { - put(PdfName.CONTENTS, contents); - } - -/** - * Rotates the mediabox, but not the text in it. - * - * @return a PdfRectangle - */ - - PdfRectangle rotateMediaBox() { - this.mediaBox = mediaBox.rotate(); - put(PdfName.MEDIABOX, this.mediaBox); - return this.mediaBox; - } - -/** - * Returns the MediaBox of this Page. - * - * @return a PdfRectangle - */ - - PdfRectangle getMediaBox() { - return mediaBox; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPageElement.java b/src/main/java/com/lowagie/text/pdf/PdfPageElement.java deleted file mode 100644 index 86edcae..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPageElement.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * $Id: PdfPageElement.java,v 1.56 2005/05/04 14:33:11 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * The PdfPageElement interface has to be implemented by PdfPage and PdfPages. - * - * @see PdfPage - * @see PdfPages - */ - -interface PdfPageElement { - -/** - * Set the value for the Parent key in the Page or Pages Dictionary. - * - * @param reference an indirect reference to a PdfPages-object - */ - - public void setParent(PdfIndirectReference reference); - -/** - * Checks if this page element is a tree of pages. - * - * @return true if it's a tree of pages; - * false if it's a single page - */ - - public boolean isParent(); -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPageEvent.java b/src/main/java/com/lowagie/text/pdf/PdfPageEvent.java deleted file mode 100644 index 5ac89c8..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPageEvent.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * $Id: PdfPageEvent.java,v 1.56 2005/05/04 14:31:45 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.Document; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Paragraph; - -/** - * Allows a class to catch several document events. - *

- * Note: do not use Document.add() inside a page event. - * - * @author Paulo Soares (psoares@consiste.pt) - */ - -public interface PdfPageEvent { - -/** - * Called when the document is opened. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onOpenDocument(PdfWriter writer, Document document); - -/** - * Called when a page is initialized. - *

- * Note that if even if a page is not written this method is still - * called. It is preferable to use onEndPage to avoid - * infinite loops. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onStartPage(PdfWriter writer, Document document); - -/** - * Called when a page is finished, just before being written to the document. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onEndPage(PdfWriter writer, Document document); - -/** - * Called when the document is closed. - *

- * Note that this method is called with the page number equal - * to the last page plus one. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onCloseDocument(PdfWriter writer, Document document); - -/** - * Called when a Paragraph is written. - *

- * paragraphPosition will hold the height at which the - * paragraph will be written to. This is useful to insert bookmarks with - * more control. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the paragraph will be written to - */ - public void onParagraph(PdfWriter writer, Document document, float paragraphPosition); - -/** - * Called when a Paragraph is written. - *

- * paragraphPosition will hold the height of the end of the paragraph. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position of the end of the paragraph - */ - public void onParagraphEnd(PdfWriter writer,Document document,float paragraphPosition); - -/** - * Called when a Chapter is written. - *

- * position will hold the height at which the - * chapter will be written to. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the chapter will be written to - * @param title the title of the Chapter - */ - public void onChapter(PdfWriter writer,Document document,float paragraphPosition, Paragraph title); - -/** - * Called when the end of a Chapter is reached. - *

- * position will hold the height of the end of the chapter. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the chapter will be written to - */ - public void onChapterEnd(PdfWriter writer,Document document,float paragraphPosition); - -/** - * Called when a Section is written. - *

- * position will hold the height at which the - * section will be written to. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the section will be written to - * @param depth the number depth of the section - * @param title the title of the section - */ - public void onSection(PdfWriter writer,Document document,float paragraphPosition, int depth, Paragraph title); - -/** - * Called when the end of a Section is reached. - *

- * position will hold the height of the section end. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the section will be written to - */ - public void onSectionEnd(PdfWriter writer,Document document,float paragraphPosition); - -/** - * Called when a Chunk with a generic tag is written. - *

- * It is usefull to pinpoint the Chunk location to generate - * bookmarks, for example. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param rect the Rectangle containing the Chunk - * @param text the text of the tag - */ - public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text); -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPageEventHelper.java b/src/main/java/com/lowagie/text/pdf/PdfPageEventHelper.java deleted file mode 100644 index e1921ed..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPageEventHelper.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * $Id: PdfPageEventHelper.java,v 1.56 2005/05/04 14:31:45 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import com.lowagie.text.Document; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Paragraph; - -/** - * Helps the use of PdfPageEvent by implementing all the interface methods. - * A class can extend PdfPageEventHelper and only implement the - * needed methods. - *

- * Note: do not use Document.add() inside a page event. - * @author Paulo Soares (psoares@consiste.pt) - */ - -public class PdfPageEventHelper implements PdfPageEvent { - -/** - * Called when the document is opened. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onOpenDocument(PdfWriter writer,Document document) { - } - -/** - * Called when a page is initialized. - *

- * Note that if even if a page is not written this method is still - * called. It is preferable to use onEndPage to avoid - * infinite loops. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onStartPage(PdfWriter writer,Document document) { - } - -/** - * Called when a page is finished, just before being written to the document. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onEndPage(PdfWriter writer,Document document) { - } - -/** - * Called when the document is closed. - *

- * Note that this method is called with the page number equal - * to the last page plus one. - * - * @param writer the PdfWriter for this document - * @param document the document - */ - public void onCloseDocument(PdfWriter writer,Document document) { - } - -/** - * Called when a Paragraph is written. - *

- * paragraphPosition will hold the height at which the - * paragraph will be written to. This is useful to insert bookmarks with - * more control. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the paragraph will be written to - */ - public void onParagraph(PdfWriter writer,Document document,float paragraphPosition) { - } - -/** - * Called when a Paragraph is written. - *

- * paragraphPosition will hold the height of the end of the paragraph. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position of the end of the paragraph - */ - public void onParagraphEnd(PdfWriter writer,Document document,float paragraphPosition) { - } - -/** - * Called when a Chapter is written. - *

- * position will hold the height at which the - * chapter will be written to. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the chapter will be written to - * @param title the title of the Chapter - */ - public void onChapter(PdfWriter writer,Document document,float paragraphPosition,Paragraph title) { - } - -/** - * Called when the end of a Chapter is reached. - *

- * position will hold the height of the end of the chapter. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param position the position of the end of the chapter. - */ - public void onChapterEnd(PdfWriter writer,Document document,float position) { - } - -/** - * Called when a Section is written. - *

- * position will hold the height at which the - * section will be written to. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param paragraphPosition the position the section will be written to - * @param depth the number depth of the Section - * @param title the title of the section - */ - public void onSection(PdfWriter writer,Document document,float paragraphPosition,int depth,Paragraph title) { - } - -/** - * Called when the end of a Section is reached. - *

- * position will hold the height of the section end. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param position the position of the end of the section - */ - public void onSectionEnd(PdfWriter writer,Document document,float position) { - } - -/** - * Called when a Chunk with a generic tag is written. - *

- * It is usefull to pinpoint the Chunk location to generate - * bookmarks, for example. - * - * @param writer the PdfWriter for this document - * @param document the document - * @param rect the Rectangle containing the Chunk - * @param text the text of the tag - */ - public void onGenericTag(PdfWriter writer,Document document,Rectangle rect,String text) { - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPageLabels.java b/src/main/java/com/lowagie/text/pdf/PdfPageLabels.java deleted file mode 100644 index 2c3bf28..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPageLabels.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * $Id: PdfPageLabels.java,v 1.46 2005/05/04 14:32:31 blowagie Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.Comparator; -import java.util.TreeMap; -import java.util.Iterator; - -/** Page labels are used to identify each - * page visually on the screen or in print. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfPageLabels implements Comparator { - - /** Logical pages will have the form 1,2,3,... - */ - public static int DECIMAL_ARABIC_NUMERALS = 0; - /** Logical pages will have the form I,II,III,IV,... - */ - public static int UPPERCASE_ROMAN_NUMERALS = 1; - /** Logical pages will have the form i,ii,iii,iv,... - */ - public static int LOWERCASE_ROMAN_NUMERALS = 2; - /** Logical pages will have the form of uppercase letters - * (A to Z for the first 26 pages, AA to ZZ for the next 26, and so on) - */ - public static int UPPERCASE_LETTERS = 3; - /** Logical pages will have the form of uppercase letters - * (a to z for the first 26 pages, aa to zz for the next 26, and so on) - */ - public static int LOWERCASE_LETTERS = 4; - /** No logical page numbers are generated but fixed text may - * still exist - */ - public static int EMPTY = 5; - /** Dictionary values to set the logical page styles - */ - static PdfName numberingStyle[] = new PdfName[]{PdfName.D, PdfName.R, - new PdfName("r"), PdfName.A, new PdfName("a")}; - /** The sequence of logical pages. Will contain at least a value for page 1 - */ - TreeMap map; - - /** Creates a new PdfPageLabel with a default logical page 1 - */ - public PdfPageLabels() { - map = new TreeMap(this); - addPageLabel(1, DECIMAL_ARABIC_NUMERALS, null, 1); - } - - /** Compares two Integer. - * @param obj the first Integer - * @param obj1 the second Integer - * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second - */ - public int compare(Object obj, Object obj1) { - int v1 = ((Integer)obj).intValue(); - int v2 = ((Integer)obj1).intValue(); - if (v1 < v2) - return -1; - if (v1 == v2) - return 0; - return 1; - } - - /** Not used - * @param obj not used - * @return always true - */ - public boolean equals(Object obj) { - return true; - } - - /** Adds or replaces a page label. - * @param page the real page to start the numbering. First page is 1 - * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS - * @param text the text to prefix the number. Can be null or empty - * @param firstPage the first logical page number - */ - public void addPageLabel(int page, int numberStyle, String text, int firstPage) { - if (page < 1 || firstPage < 1) - throw new IllegalArgumentException("In a page label the page numbers must be greater or equal to 1."); - PdfName pdfName = null; - if (numberStyle >= 0 && numberStyle < numberingStyle.length) - pdfName = numberingStyle[numberStyle]; - Integer iPage = new Integer(page); - Object obj = new Object[]{iPage, pdfName, text, new Integer(firstPage)}; - map.put(iPage, obj); - } - - /** Adds or replaces a page label. The first logical page has the default - * of 1. - * @param page the real page to start the numbering. First page is 1 - * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS - * @param text the text to prefix the number. Can be null or empty - */ - public void addPageLabel(int page, int numberStyle, String text) { - addPageLabel(page, numberStyle, text, 1); - } - - /** Adds or replaces a page label. There is no text prefix and the first - * logical page has the default of 1. - * @param page the real page to start the numbering. First page is 1 - * @param numberStyle the numbering style such as LOWERCASE_ROMAN_NUMERALS - */ - public void addPageLabel(int page, int numberStyle) { - addPageLabel(page, numberStyle, null, 1); - } - - /** Removes a page label. The first page label can not be removed, only changed. - * @param page the real page to remove - */ - public void removePageLabel(int page) { - if (page <= 1) - return; - map.remove(new Integer(page)); - } - - /** Gets the page label dictionary to insert into the document. - * @return the page label dictionary - */ - PdfDictionary getDictionary() { - PdfDictionary dic = new PdfDictionary(); - PdfArray array = new PdfArray(); - for (Iterator it = map.values().iterator(); it.hasNext();) { - Object obj[] = (Object[])it.next(); - PdfDictionary subDic = new PdfDictionary(); - PdfName pName = (PdfName)obj[1]; - if (pName != null) - subDic.put(PdfName.S, pName); - String text = (String)obj[2]; - if (text != null) - subDic.put(PdfName.P, new PdfString(text, PdfObject.TEXT_UNICODE)); - int st = ((Integer)obj[3]).intValue(); - if (st != 1) - subDic.put(PdfName.ST, new PdfNumber(st)); - array.add(new PdfNumber(((Integer)obj[0]).intValue() - 1)); - array.add(subDic); - } - dic.put(PdfName.NUMS, array); - return dic; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPages.java b/src/main/java/com/lowagie/text/pdf/PdfPages.java deleted file mode 100644 index cdc85a3..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPages.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * $Id: PdfPages.java,v 1.58 2006/02/16 16:17:52 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.util.ArrayList; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.ExceptionConverter; - -/** - * PdfPages is the PDF Pages-object. - *

- * The Pages of a document are accessible through a tree of nodes known as the Pages tree. - * This tree defines the ordering of the pages in the document.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 6.3 (page 71-73) - * - * @see PdfPage - */ - -public class PdfPages { - - private ArrayList pages = new ArrayList(); - private ArrayList parents = new ArrayList(); - private int leafSize = 10; - private PdfWriter writer; - private PdfIndirectReference topParent; - - // constructors - -/** - * Constructs a PdfPages-object. - */ - - PdfPages(PdfWriter writer) { - this.writer = writer; - } - - void addPage(PdfDictionary page) { - try { - if ((pages.size() % leafSize) == 0) - parents.add(writer.getPdfIndirectReference()); - PdfIndirectReference parent = (PdfIndirectReference)parents.get(parents.size() - 1); - page.put(PdfName.PARENT, parent); - PdfIndirectReference current = writer.getCurrentPage(); - writer.addToBody(page, current); - pages.add(current); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - PdfIndirectReference addPageRef(PdfIndirectReference pageRef) { - try { - if ((pages.size() % leafSize) == 0) - parents.add(writer.getPdfIndirectReference()); - pages.add(pageRef); - return (PdfIndirectReference)parents.get(parents.size() - 1); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - // returns the top parent to include in the catalog - PdfIndirectReference writePageTree() throws IOException { - if (pages.size() == 0) - throw new IOException("The document has no pages."); - int leaf = 1; - ArrayList tParents = parents; - ArrayList tPages = pages; - ArrayList nextParents = new ArrayList(); - while (true) { - leaf *= leafSize; - int stdCount = leafSize; - int rightCount = tPages.size() % leafSize; - if (rightCount == 0) - rightCount = leafSize; - for (int p = 0; p < tParents.size(); ++p) { - int count; - int thisLeaf = leaf; - if (p == tParents.size() - 1) { - count = rightCount; - thisLeaf = pages.size() % leaf; - if (thisLeaf == 0) - thisLeaf = leaf; - } - else - count = stdCount; - PdfDictionary top = new PdfDictionary(PdfName.PAGES); - top.put(PdfName.COUNT, new PdfNumber(thisLeaf)); - PdfArray kids = new PdfArray(); - ArrayList internal = kids.getArrayList(); - internal.addAll(tPages.subList(p * stdCount, p * stdCount + count)); - top.put(PdfName.KIDS, kids); - if (tParents.size() > 1) { - if ((p % leafSize) == 0) - nextParents.add(writer.getPdfIndirectReference()); - top.put(PdfName.PARENT, (PdfIndirectReference)nextParents.get(p / leafSize)); - } - writer.addToBody(top, (PdfIndirectReference)tParents.get(p)); - } - if (tParents.size() == 1) { - topParent = (PdfIndirectReference)tParents.get(0); - return topParent; - } - tPages = tParents; - tParents = nextParents; - nextParents = new ArrayList(); - } - } - - PdfIndirectReference getTopParent() { - return topParent; - } - - void setLinearMode(PdfIndirectReference topParent) { - if (parents.size() > 1) - throw new RuntimeException("Linear page mode can only be called with a single parent."); - if (topParent != null) { - this.topParent = topParent; - parents.clear(); - parents.add(topParent); - } - leafSize = 10000000; - } - - void addPage(PdfIndirectReference page) { - pages.add(page); - } - - int reorderPages(int order[]) throws DocumentException { - if (order == null) - return pages.size(); - if (parents.size() > 1) - throw new DocumentException("Page reordering requires a single parent in the page tree. Call PdfWriter.setLinearMode() after open."); - if (order.length != pages.size()) - throw new DocumentException("Page reordering requires an array with the same size as the number of pages."); - int max = pages.size(); - boolean temp[] = new boolean[max]; - for (int k = 0; k < max; ++k) { - int p = order[k]; - if (p < 1 || p > max) - throw new DocumentException("Page reordering requires pages between 1 and " + max + ". Found " + p + "."); - if (temp[p - 1]) - throw new DocumentException("Page reordering requires no page repetition. Page " + p + " is repeated."); - temp[p - 1] = true; - } - Object copy[] = pages.toArray(); - for (int k = 0; k < max; ++k) { - pages.set(k, copy[order[k] - 1]); - } - return max; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfPattern.java b/src/main/java/com/lowagie/text/pdf/PdfPattern.java deleted file mode 100644 index f2aab31..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPattern.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.ExceptionConverter; - -/** - * A PdfPattern defines a ColorSpace - * - * @see PdfStream - */ - -public class PdfPattern extends PdfStream { - - PdfPattern(PdfPatternPainter painter) { - super(); - PdfNumber one = new PdfNumber(1); - PdfArray matrix = painter.getMatrix(); - if ( matrix != null ) { - put(PdfName.MATRIX, matrix); - } - put(PdfName.TYPE, PdfName.PATTERN); - put(PdfName.BBOX, new PdfRectangle(painter.getBoundingBox())); - put(PdfName.RESOURCES, painter.getResources()); - put(PdfName.TILINGTYPE, one); - put(PdfName.PATTERNTYPE, one); - if (painter.isStencil()) - put(PdfName.PAINTTYPE, new PdfNumber(2)); - else - put(PdfName.PAINTTYPE, one); - put(PdfName.XSTEP, new PdfNumber(painter.getXStep())); - put(PdfName.YSTEP, new PdfNumber(painter.getYStep())); - bytes = painter.toPdf(null); - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - try { - flateCompress(); - } catch (Exception e) { - throw new ExceptionConverter(e); - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPatternPainter.java b/src/main/java/com/lowagie/text/pdf/PdfPatternPainter.java deleted file mode 100644 index 7c5a094..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPatternPainter.java +++ /dev/null @@ -1,391 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.Image; -import com.lowagie.text.Rectangle; -import java.awt.Color; - -/** - * Implements the pattern. - */ - -public class PdfPatternPainter extends PdfTemplate { - - protected float xstep, ystep; - protected boolean stencil = false; - protected Color defaultColor; - - /** - *Creates a PdfPattern. - */ - - private PdfPatternPainter() { - super(null); - type = TYPE_PATTERN; - } - - /** - * Creates new PdfPattern - * - * @param wr the PdfWriter - */ - - PdfPatternPainter(PdfWriter wr) { - super(wr); - type = TYPE_PATTERN; - } - - PdfPatternPainter(PdfWriter wr, Color defaultColor) { - this(wr); - stencil = true; - if (defaultColor == null) - this.defaultColor = Color.gray; - else - this.defaultColor = defaultColor; - } - - /** - * Sets the horizontal interval of this pattern. - * - * @param xstep the xstep in horizontal painting - */ - - public void setXStep(float xstep) { - this.xstep = xstep; - } - - /** - * Sets the vertical interval of this pattern. - * - * @param ystep in vertical painting - */ - - public void setYStep(float ystep) { - this.ystep = ystep; - } - - /** - * Returns the horizontal interval when repeating the pattern. - * @return a value - */ - public float getXStep() { - return this.xstep; - } - - /** - * Returns the vertical interval when repeating the pattern. - * @return a value - */ - public float getYStep() { - return this.ystep; - } - - /** - * Tells you if this pattern is colored/uncolored (stencil = uncolored, you need to set a default color). - * @return true if the pattern is an uncolored tiling pattern (stencil). - */ - public boolean isStencil() { - return stencil; - } - - /** - * Sets the transformation matrix for the pattern. - * @param a - * @param b - * @param c - * @param d - * @param e - * @param f - */ - public void setPatternMatrix(float a, float b, float c, float d, float e, float f) { - setMatrix(a, b, c, d, e, f); - } - /** - * Gets the stream representing this pattern - * - * @return the stream representing this pattern - */ - - PdfPattern getPattern() { - return new PdfPattern(this); - } - - /** - * Gets a duplicate of this PdfPatternPainter. All - * the members are copied by reference but the buffer stays different. - * @return a copy of this PdfPatternPainter - */ - - public PdfContentByte getDuplicate() { - PdfPatternPainter tpl = new PdfPatternPainter(); - tpl.writer = writer; - tpl.pdf = pdf; - tpl.thisReference = thisReference; - tpl.pageResources = pageResources; - tpl.bBox = new Rectangle(bBox); - tpl.xstep = xstep; - tpl.ystep = ystep; - tpl.matrix = matrix; - tpl.stencil = stencil; - tpl.defaultColor = defaultColor; - return tpl; - } - - /** - * Returns the default color of the pattern. - * @return a Color - */ - public Color getDefaultColor() { - return defaultColor; - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setGrayFill(float) - */ - public void setGrayFill(float gray) { - checkNoColor(); - super.setGrayFill(gray); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetGrayFill() - */ - public void resetGrayFill() { - checkNoColor(); - super.resetGrayFill(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setGrayStroke(float) - */ - public void setGrayStroke(float gray) { - checkNoColor(); - super.setGrayStroke(gray); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetGrayStroke() - */ - public void resetGrayStroke() { - checkNoColor(); - super.resetGrayStroke(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFillF(float, float, float) - */ - public void setRGBColorFillF(float red, float green, float blue) { - checkNoColor(); - super.setRGBColorFillF(red, green, blue); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorFill() - */ - public void resetRGBColorFill() { - checkNoColor(); - super.resetRGBColorFill(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStrokeF(float, float, float) - */ - public void setRGBColorStrokeF(float red, float green, float blue) { - checkNoColor(); - super.setRGBColorStrokeF(red, green, blue); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetRGBColorStroke() - */ - public void resetRGBColorStroke() { - checkNoColor(); - super.resetRGBColorStroke(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFillF(float, float, float, float) - */ - public void setCMYKColorFillF(float cyan, float magenta, float yellow, float black) { - checkNoColor(); - super.setCMYKColorFillF(cyan, magenta, yellow, black); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorFill() - */ - public void resetCMYKColorFill() { - checkNoColor(); - super.resetCMYKColorFill(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStrokeF(float, float, float, float) - */ - public void setCMYKColorStrokeF(float cyan, float magenta, float yellow, float black) { - checkNoColor(); - super.setCMYKColorStrokeF(cyan, magenta, yellow, black); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#resetCMYKColorStroke() - */ - public void resetCMYKColorStroke() { - checkNoColor(); - super.resetCMYKColorStroke(); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#addImage(com.lowagie.text.Image, float, float, float, float, float, float) - */ - public void addImage(Image image, float a, float b, float c, float d, float e, float f) throws DocumentException { - if (stencil && !image.isMask()) - checkNoColor(); - super.addImage(image, a, b, c, d, e, f); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorFill(int, int, int, int) - */ - public void setCMYKColorFill(int cyan, int magenta, int yellow, int black) { - checkNoColor(); - super.setCMYKColorFill(cyan, magenta, yellow, black); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setCMYKColorStroke(int, int, int, int) - */ - public void setCMYKColorStroke(int cyan, int magenta, int yellow, int black) { - checkNoColor(); - super.setCMYKColorStroke(cyan, magenta, yellow, black); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorFill(int, int, int) - */ - public void setRGBColorFill(int red, int green, int blue) { - checkNoColor(); - super.setRGBColorFill(red, green, blue); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setRGBColorStroke(int, int, int) - */ - public void setRGBColorStroke(int red, int green, int blue) { - checkNoColor(); - super.setRGBColorStroke(red, green, blue); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(java.awt.Color) - */ - public void setColorStroke(Color color) { - checkNoColor(); - super.setColorStroke(color); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(java.awt.Color) - */ - public void setColorFill(Color color) { - checkNoColor(); - super.setColorFill(color); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setColorFill(com.lowagie.text.pdf.PdfSpotColor, float) - */ - public void setColorFill(PdfSpotColor sp, float tint) { - checkNoColor(); - super.setColorFill(sp, tint); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setColorStroke(com.lowagie.text.pdf.PdfSpotColor, float) - */ - public void setColorStroke(PdfSpotColor sp, float tint) { - checkNoColor(); - super.setColorStroke(sp, tint); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter) - */ - public void setPatternFill(PdfPatternPainter p) { - checkNoColor(); - super.setPatternFill(p); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setPatternFill(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float) - */ - public void setPatternFill(PdfPatternPainter p, Color color, float tint) { - checkNoColor(); - super.setPatternFill(p, color, tint); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter, java.awt.Color, float) - */ - public void setPatternStroke(PdfPatternPainter p, Color color, float tint) { - checkNoColor(); - super.setPatternStroke(p, color, tint); - } - - /** - * @see com.lowagie.text.pdf.PdfContentByte#setPatternStroke(com.lowagie.text.pdf.PdfPatternPainter) - */ - public void setPatternStroke(PdfPatternPainter p) { - checkNoColor(); - super.setPatternStroke(p); - } - - void checkNoColor() { - if (stencil) - throw new RuntimeException("Colors are not allowed in uncolored tile patterns."); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfPrinterGraphics2D.java b/src/main/java/com/lowagie/text/pdf/PdfPrinterGraphics2D.java deleted file mode 100644 index 06a0aa3..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfPrinterGraphics2D.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * $Id: PdfPrinterGraphics2D.java,v 1.3 2005/02/17 09:20:53 blowagie Exp $ - * $Name: $ - * - * Copyright 2004 Paulo Soares and Alexandru Carstoiu - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.print.PrinterGraphics; -import java.awt.print.PrinterJob; - -/** - * This is an extension class for the sole purpose of implementing the - * {@link java.awt.print.PrinterGraphics PrinterGraphics} interface. - */ -public class PdfPrinterGraphics2D extends PdfGraphics2D implements PrinterGraphics -{ - private PrinterJob printerJob; - - public PdfPrinterGraphics2D(PdfContentByte cb, float width, float height, FontMapper fontMapper, - boolean onlyShapes, boolean convertImagesToJPEG, float quality, PrinterJob printerJob) { - super(cb, width, height, fontMapper, onlyShapes, convertImagesToJPEG, quality); - this.printerJob = printerJob; - } - - public PrinterJob getPrinterJob() { - return printerJob; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfReader.java b/src/main/java/com/lowagie/text/pdf/PdfReader.java deleted file mode 100644 index da46174..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfReader.java +++ /dev/null @@ -1,3172 +0,0 @@ -/* - * $Id: PdfReader.java,v 1.76 2006/05/31 16:23:26 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.List; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.Iterator; -import java.util.zip.InflaterInputStream; -import java.util.Arrays; -import java.util.Collections; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.PageSize; -import com.lowagie.text.StringCompare; -import com.lowagie.text.ExceptionConverter; - -/** Reads a PDF document. - * @author Paulo Soares (psoares@consiste.pt) - * @author Kazuya Ujihara - */ -public class PdfReader { - - static final PdfName pageInhCandidates[] = { - PdfName.MEDIABOX, PdfName.ROTATE, PdfName.RESOURCES, PdfName.CROPBOX - }; - - static final PdfName vpnames[] = {PdfName.HIDETOOLBAR, PdfName.HIDEMENUBAR, - PdfName.HIDEWINDOWUI, PdfName.FITWINDOW, PdfName.CENTERWINDOW, PdfName.DISPLAYDOCTITLE}; - static final int vpints[] = {PdfWriter.HideToolbar, PdfWriter.HideMenubar, - PdfWriter.HideWindowUI, PdfWriter.FitWindow, PdfWriter.CenterWindow, PdfWriter.DisplayDocTitle}; - - static final byte endstream[] = PdfEncodings.convertToBytes("endstream", null); - static final byte endobj[] = PdfEncodings.convertToBytes("endobj", null); - protected PRTokeniser tokens; - // Each xref pair is a position - // type 0 -> -1, 0 - // type 1 -> offset, 0 - // type 2 -> index, obj num - protected int xref[]; - protected HashMap objStmMark; - protected IntHashtable objStmToOffset; - protected boolean newXrefType; - private ArrayList xrefObj; - PdfDictionary rootPages; - protected PdfDictionary trailer; - //protected ArrayList pages; - protected PdfDictionary catalog; - protected PageRefs pageRefs; - protected PRAcroForm acroForm = null; - protected boolean acroFormParsed = false; - protected ArrayList pageInh; - protected boolean encrypted = false; - protected boolean rebuilt = false; - protected int freeXref; - protected boolean tampered = false; - protected int lastXref; - protected int eofPos; - protected char pdfVersion; - protected PdfEncryption decrypt; - protected byte password[] = null; //added by ujihara for decryption - protected ArrayList strings = new ArrayList(); - protected boolean sharedStreams = true; - protected boolean consolidateNamedDestinations = false; - protected int rValue; - protected int pValue; - private int objNum; - private int objGen; - private boolean visited[]; - private IntHashtable newHits; - private int fileLength; - private boolean hybridXref; - private int lastXrefPartial = -1; - private boolean partial; - private PRIndirectReference cryptoRef; - - /** - * Holds value of property appendable. - */ - private boolean appendable; - - protected PdfReader() { - } - - /** Reads and parses a PDF document. - * @param filename the file name of the document - * @throws IOException on error - */ - public PdfReader(String filename) throws IOException { - this(filename, null); - } - - /** Reads and parses a PDF document. - * @param filename the file name of the document - * @param ownerPassword the password to read the document - * @throws IOException on error - */ - public PdfReader(String filename, byte ownerPassword[]) throws IOException { - password = ownerPassword; - tokens = new PRTokeniser(filename); - readPdf(); - } - - /** Reads and parses a PDF document. - * @param pdfIn the byte array with the document - * @throws IOException on error - */ - public PdfReader(byte pdfIn[]) throws IOException { - this(pdfIn, null); - } - - /** Reads and parses a PDF document. - * @param pdfIn the byte array with the document - * @param ownerPassword the password to read the document - * @throws IOException on error - */ - public PdfReader(byte pdfIn[], byte ownerPassword[]) throws IOException { - password = ownerPassword; - tokens = new PRTokeniser(pdfIn); - readPdf(); - } - - /** Reads and parses a PDF document. - * @param url the URL of the document - * @throws IOException on error - */ - public PdfReader(URL url) throws IOException { - this(url, null); - } - - /** Reads and parses a PDF document. - * @param url the URL of the document - * @param ownerPassword the password to read the document - * @throws IOException on error - */ - public PdfReader(URL url, byte ownerPassword[]) throws IOException { - password = ownerPassword; - tokens = new PRTokeniser(new RandomAccessFileOrArray(url)); - readPdf(); - } - - /** - * Reads and parses a PDF document. - * @param is the InputStream containing the document. The stream is read to the - * end but is not closed - * @param ownerPassword the password to read the document - * @throws IOException on error - */ - public PdfReader(InputStream is, byte ownerPassword[]) throws IOException { - password = ownerPassword; - tokens = new PRTokeniser(new RandomAccessFileOrArray(is)); - readPdf(); - } - - /** - * Reads and parses a PDF document. - * @param is the InputStream containing the document. The stream is read to the - * end but is not closed - * @throws IOException on error - */ - public PdfReader(InputStream is) throws IOException { - this(is, null); - } - - /** - * Reads and parses a pdf document. Contrary to the other constructors only the xref is read - * into memory. The reader is said to be working in "partial" mode as only parts of the pdf - * are read as needed. The pdf is left open but may be closed at any time with - * PdfReader.close(), reopen is automatic. - * @param raf the document location - * @param ownerPassword the password or null for no password - * @throws IOException on error - */ - public PdfReader(RandomAccessFileOrArray raf, byte ownerPassword[]) throws IOException { - password = ownerPassword; - partial = true; - tokens = new PRTokeniser(raf); - readPdfPartial(); - } - - /** Creates an independent duplicate. - * @param reader the PdfReader to duplicate - */ - public PdfReader(PdfReader reader) { - this.appendable = reader.appendable; - this.consolidateNamedDestinations = reader.consolidateNamedDestinations; - this.encrypted = reader.encrypted; - this.rebuilt = reader.rebuilt; - this.sharedStreams = reader.sharedStreams; - this.tampered = reader.tampered; - this.password = reader.password; - this.pdfVersion = reader.pdfVersion; - this.eofPos = reader.eofPos; - this.freeXref = reader.freeXref; - this.lastXref = reader.lastXref; - this.tokens = new PRTokeniser(reader.tokens.getSafeFile()); - if (reader.decrypt != null) - this.decrypt = new PdfEncryption(reader.decrypt); - this.pValue = reader.pValue; - this.rValue = reader.rValue; - this.xrefObj = new ArrayList(reader.xrefObj); - for (int k = 0; k < reader.xrefObj.size(); ++k) { - this.xrefObj.set(k, duplicatePdfObject((PdfObject)reader.xrefObj.get(k), this)); - } - this.pageRefs = new PageRefs(reader.pageRefs, this); - this.trailer = (PdfDictionary)duplicatePdfObject(reader.trailer, this); - this.catalog = (PdfDictionary)getPdfObject(trailer.get(PdfName.ROOT)); - this.rootPages = (PdfDictionary)getPdfObject(catalog.get(PdfName.PAGES)); - this.fileLength = reader.fileLength; - this.partial = reader.partial; - this.hybridXref = reader.hybridXref; - this.objStmToOffset = reader.objStmToOffset; - this.xref = reader.xref; - this.cryptoRef = (PRIndirectReference)duplicatePdfObject(reader.cryptoRef, this); - } - - /** Gets a new file instance of the original PDF - * document. - * @return a new file instance of the original PDF document - */ - public RandomAccessFileOrArray getSafeFile() { - return tokens.getSafeFile(); - } - - protected PdfReaderInstance getPdfReaderInstance(PdfWriter writer) { - return new PdfReaderInstance(this, writer); - } - - /** Gets the number of pages in the document. - * @return the number of pages in the document - */ - public int getNumberOfPages() { - return pageRefs.size(); - } - - /** Returns the document's catalog. This dictionary is not a copy, - * any changes will be reflected in the catalog. - * @return the document's catalog - */ - public PdfDictionary getCatalog() { - return catalog; - } - - /** Returns the document's acroform, if it has one. - * @return the document's acroform - */ - public PRAcroForm getAcroForm() { - if (!acroFormParsed) { - acroFormParsed = true; - PdfObject form = catalog.get(PdfName.ACROFORM); - if (form != null) { - try { - acroForm = new PRAcroForm(this); - acroForm.readAcroForm((PdfDictionary)getPdfObject(form)); - } - catch (Exception e) { - acroForm = null; - } - } - } - return acroForm; - } - /** - * Gets the page rotation. This value can be 0, 90, 180 or 270. - * @param index the page number. The first page is 1 - * @return the page rotation - */ - public int getPageRotation(int index) { - return getPageRotation(pageRefs.getPageNRelease(index)); - } - - int getPageRotation(PdfDictionary page) { - PdfNumber rotate = (PdfNumber)getPdfObject(page.get(PdfName.ROTATE)); - if (rotate == null) - return 0; - else { - int n = rotate.intValue(); - n %= 360; - return n < 0 ? n + 360 : n; - } - } - /** Gets the page size, taking rotation into account. This - * is a Rectangle with the value of the /MediaBox and the /Rotate key. - * @param index the page number. The first page is 1 - * @return a Rectangle - */ - public Rectangle getPageSizeWithRotation(int index) { - return getPageSizeWithRotation(pageRefs.getPageNRelease(index)); - } - - /** - * Gets the rotated page from a page dictionary. - * @param page the page dictionary - * @return the rotated page - */ - public Rectangle getPageSizeWithRotation(PdfDictionary page) { - Rectangle rect = getPageSize(page); - int rotation = getPageRotation(page); - while (rotation > 0) { - rect = rect.rotate(); - rotation -= 90; - } - return rect; - } - - /** Gets the page size without taking rotation into account. This - * is the value of the /MediaBox key. - * @param index the page number. The first page is 1 - * @return the page size - */ - public Rectangle getPageSize(int index) { - return getPageSize(pageRefs.getPageNRelease(index)); - } - - /** - * Gets the page from a page dictionary - * @param page the page dictionary - * @return the page - */ - public Rectangle getPageSize(PdfDictionary page) { - PdfArray mediaBox = (PdfArray)getPdfObject(page.get(PdfName.MEDIABOX)); - return getNormalizedRectangle(mediaBox); - } - - /** Gets the crop box without taking rotation into account. This - * is the value of the /CropBox key. The crop box is the part - * of the document to be displayed or printed. It usually is the same - * as the media box but may be smaller. If the page doesn't have a crop - * box the page size will be returned. - * @param index the page number. The first page is 1 - * @return the crop box - */ - public Rectangle getCropBox(int index) { - PdfDictionary page = pageRefs.getPageNRelease(index); - PdfArray cropBox = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX)); - if (cropBox == null) - return getPageSize(page); - return getNormalizedRectangle(cropBox); - } - - /** Gets the box size. Allowed names are: "crop", "trim", "art", "bleed" and "media". - * @param index the page number. The first page is 1 - * @param boxName the box name - * @return the box rectangle or null - */ - public Rectangle getBoxSize(int index, String boxName) { - PdfDictionary page = pageRefs.getPageNRelease(index); - PdfArray box = null; - if (boxName.equals("trim")) - box = (PdfArray)getPdfObjectRelease(page.get(PdfName.TRIMBOX)); - else if (boxName.equals("art")) - box = (PdfArray)getPdfObjectRelease(page.get(PdfName.ARTBOX)); - else if (boxName.equals("bleed")) - box = (PdfArray)getPdfObjectRelease(page.get(PdfName.BLEEDBOX)); - else if (boxName.equals("crop")) - box = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX)); - else if (boxName.equals("media")) - box = (PdfArray)getPdfObjectRelease(page.get(PdfName.MEDIABOX)); - if (box == null) - return null; - return getNormalizedRectangle(box); - } - - /** Returns the content of the document information dictionary as a HashMap - * of String. - * @return content of the document information dictionary - */ - public HashMap getInfo() { - HashMap map = new HashMap(); - PdfDictionary info = (PdfDictionary)getPdfObject(trailer.get(PdfName.INFO)); - if (info == null) - return map; - for (Iterator it = info.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - PdfObject obj = getPdfObject(info.get(key)); - if (obj == null) - continue; - String value = obj.toString(); - switch (obj.type()) { - case PdfObject.STRING: { - value = ((PdfString)obj).toUnicodeString(); - break; - } - case PdfObject.NAME: { - value = PdfName.decodeName(value); - break; - } - } - map.put(PdfName.decodeName(key.toString()), value); - } - return map; - } - - /** Normalizes a Rectangle so that llx and lly are smaller than urx and ury. - * @param box the original rectangle - * @return a normalized Rectangle - */ - public static Rectangle getNormalizedRectangle(PdfArray box) { - ArrayList rect = box.getArrayList(); - float llx = ((PdfNumber)rect.get(0)).floatValue(); - float lly = ((PdfNumber)rect.get(1)).floatValue(); - float urx = ((PdfNumber)rect.get(2)).floatValue(); - float ury = ((PdfNumber)rect.get(3)).floatValue(); - return new Rectangle(Math.min(llx, urx), Math.min(lly, ury), - Math.max(llx, urx), Math.max(lly, ury)); - } - - protected void readPdf() throws IOException { - try { - fileLength = tokens.getFile().length(); - pdfVersion = tokens.checkPdfHeader(); - try { - readXref(); - } - catch (Exception e) { - try { - rebuilt = true; - rebuildXref(); - lastXref = -1; - } - catch (Exception ne) { - throw new IOException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage()); - } - } - try { - readDocObj(); - } - catch (IOException ne) { - if (rebuilt) - throw ne; - rebuilt = true; - encrypted = false; - rebuildXref(); - lastXref = -1; - readDocObj(); - } - - strings.clear(); - readPages(); - eliminateSharedStreams(); - removeUnusedObjects(); - } - finally { - try { - tokens.close(); - } - catch (Exception e) { - // empty on purpose - } - } - } - - protected void readPdfPartial() throws IOException { - try { - fileLength = tokens.getFile().length(); - pdfVersion = tokens.checkPdfHeader(); - try { - readXref(); - } - catch (Exception e) { - try { - rebuilt = true; - rebuildXref(); - lastXref = -1; - } - catch (Exception ne) { - throw new IOException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage()); - } - } - readDocObjPartial(); - readPages(); - } - catch (IOException e) { - try{tokens.close();}catch(Exception ee){} - throw e; - } - } - - private boolean equalsArray(byte ar1[], byte ar2[], int size) { - for (int k = 0; k < size; ++k) { - if (ar1[k] != ar2[k]) - return false; - } - return true; - } - - /** - * @throws IOException - */ - private void readDecryptedDocObj() throws IOException { - if (encrypted) - return; - PdfObject encDic = trailer.get(PdfName.ENCRYPT); - if (encDic == null || encDic.toString().equals("null")) - return; - encrypted = true; - PdfDictionary enc = (PdfDictionary)getPdfObject(encDic); - - String s; - PdfObject o; - - PdfArray documentIDs = (PdfArray)getPdfObject(trailer.get(PdfName.ID)); - byte documentID[] = null; - if (documentIDs != null) { - o = (PdfObject)documentIDs.getArrayList().get(0); - s = o.toString(); - documentID = com.lowagie.text.DocWriter.getISOBytes(s); - } - - s = enc.get(PdfName.U).toString(); - byte uValue[] = com.lowagie.text.DocWriter.getISOBytes(s); - s = enc.get(PdfName.O).toString(); - byte oValue[] = com.lowagie.text.DocWriter.getISOBytes(s); - - o = enc.get(PdfName.R); - if (!o.isNumber()) throw new IOException("Illegal R value."); - rValue = ((PdfNumber)o).intValue(); - if (rValue != 2 && rValue != 3) throw new IOException("Unknown encryption type (" + rValue + ")"); - - o = enc.get(PdfName.P); - if (!o.isNumber()) throw new IOException("Illegal P value."); - pValue = ((PdfNumber)o).intValue(); - - // get the Keylength if Revision is 3 - int lengthValue; - if ( rValue == 3 ){ - o = enc.get(PdfName.LENGTH); - if (!o.isNumber()) - throw new IOException("Illegal Length value."); - lengthValue = ( (PdfNumber) o).intValue(); - if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) - throw new IOException("Illegal Length value."); - } else { - // Keylength is 40 bit in revision 2 - lengthValue=40; - } - - - - decrypt = new PdfEncryption(); - - //check by user password - decrypt.setupByUserPassword(documentID, password, oValue, pValue, lengthValue, rValue); - if (!equalsArray(uValue, decrypt.userKey, rValue == 3 ? 16 : 32)) { - //check by owner password - decrypt.setupByOwnerPassword(documentID, password, uValue, oValue, pValue, lengthValue, rValue); - if (!equalsArray(uValue, decrypt.userKey, rValue == 3 ? 16 : 32)) { - throw new IOException("Bad user password"); - } - } - for (int k = 0; k < strings.size(); ++k) { - PdfString str = (PdfString)strings.get(k); - str.decrypt(this); - } - if (encDic.isIndirect()) { - cryptoRef = (PRIndirectReference)encDic; - xrefObj.set(cryptoRef.getNumber(), null); - } - } - - /** - * @param obj - * @return a PdfObject - */ - public static PdfObject getPdfObjectRelease(PdfObject obj) { - PdfObject obj2 = getPdfObject(obj); - releaseLastXrefPartial(obj); - return obj2; - } - - - /** - * Reads a PdfObject resolving an indirect reference - * if needed. - * @param obj the PdfObject to read - * @return the resolved PdfObject - */ - public static PdfObject getPdfObject(PdfObject obj) { - if (obj == null) - return null; - if (!obj.isIndirect()) - return obj; - try { - PRIndirectReference ref = (PRIndirectReference)obj; - int idx = ref.getNumber(); - boolean appendable = ref.getReader().appendable; - obj = ref.getReader().getPdfObject(idx); - if (obj == null) { - if (appendable) { - obj = new PdfNull(); - obj.setIndRef(ref); - return obj; - } - else - return PdfNull.PDFNULL; - } - else { - if (appendable) { - switch (obj.type()) { - case PdfObject.NULL: - obj = new PdfNull(); - break; - case PdfObject.BOOLEAN: - obj = new PdfBoolean(((PdfBoolean)obj).booleanValue()); - break; - case PdfObject.NAME: - obj = new PdfName(obj.getBytes()); - break; - } - obj.setIndRef(ref); - } - return obj; - } - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Reads a PdfObject resolving an indirect reference - * if needed. If the reader was opened in partial mode the object will be released - * to save memory. - * @param obj the PdfObject to read - * @param parent - * @return a PdfObject - */ - public static PdfObject getPdfObjectRelease(PdfObject obj, PdfObject parent) { - PdfObject obj2 = getPdfObject(obj, parent); - releaseLastXrefPartial(obj); - return obj2; - } - - /** - * @param obj - * @param parent - * @return a PdfObject - */ - public static PdfObject getPdfObject(PdfObject obj, PdfObject parent) { - if (obj == null) - return null; - if (!obj.isIndirect()) { - PRIndirectReference ref = null; - if (parent != null && (ref = parent.getIndRef()) != null && ref.getReader().isAppendable()) { - switch (obj.type()) { - case PdfObject.NULL: - obj = new PdfNull(); - break; - case PdfObject.BOOLEAN: - obj = new PdfBoolean(((PdfBoolean)obj).booleanValue()); - break; - case PdfObject.NAME: - obj = new PdfName(obj.getBytes()); - break; - } - obj.setIndRef(ref); - } - return obj; - } - return getPdfObject(obj); - } - - /** - * @param idx - * @return a PdfObject - */ - public PdfObject getPdfObjectRelease(int idx) { - PdfObject obj = getPdfObject(idx); - releaseLastXrefPartial(); - return obj; - } - - /** - * @param idx - * @return aPdfObject - */ - public PdfObject getPdfObject(int idx) { - try { - lastXrefPartial = -1; - if (idx < 0 || idx >= xrefObj.size()) - return null; - PdfObject obj = (PdfObject)xrefObj.get(idx); - if (!partial || obj != null) - return obj; - if (idx * 2 >= xref.length) - return null; - obj = readSingleObject(idx); - lastXrefPartial = -1; - if (obj != null) - lastXrefPartial = idx; - return obj; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * - */ - public void resetLastXrefPartial() { - lastXrefPartial = -1; - } - - /** - * - */ - public void releaseLastXrefPartial() { - if (partial && lastXrefPartial != -1) { - xrefObj.set(lastXrefPartial, null); - lastXrefPartial = -1; - } - } - - /** - * @param obj - */ - public static void releaseLastXrefPartial(PdfObject obj) { - if (obj == null) - return; - if (!obj.isIndirect()) - return; - PRIndirectReference ref = (PRIndirectReference)obj; - PdfReader reader = ref.getReader(); - if (reader.partial && reader.lastXrefPartial != -1 && reader.lastXrefPartial == ref.getNumber()) { - reader.xrefObj.set(reader.lastXrefPartial, null); - } - reader.lastXrefPartial = -1; - } - - private void setXrefPartialObject(int idx, PdfObject obj) { - if (!partial || idx < 0) - return; - xrefObj.set(idx, obj); - } - - /** - * @param obj - * @return an indirect reference - */ - public PRIndirectReference addPdfObject(PdfObject obj) { - xrefObj.add(obj); - return new PRIndirectReference(this, xrefObj.size() - 1); - } - - protected void readPages() throws IOException { - pageInh = new ArrayList(); - catalog = (PdfDictionary)getPdfObject(trailer.get(PdfName.ROOT)); - rootPages = (PdfDictionary)getPdfObject(catalog.get(PdfName.PAGES)); - pageRefs = new PageRefs(this); - } - - protected void readDocObjPartial() throws IOException { - xrefObj = new ArrayList(xref.length / 2); - xrefObj.addAll(Collections.nCopies(xref.length / 2, null)); - readDecryptedDocObj(); - if (objStmToOffset != null) { - int keys[] = objStmToOffset.getKeys(); - for (int k = 0; k < keys.length; ++k) { - int n = keys[k]; - objStmToOffset.put(n, xref[n * 2]); - xref[n * 2] = -1; - } - } - } - - protected PdfObject readSingleObject(int k) throws IOException { - strings.clear(); - int k2 = k * 2; - int pos = xref[k2]; - if (pos < 0) - return null; - if (xref[k2 + 1] > 0) - pos = objStmToOffset.get(xref[k2 + 1]); - tokens.seek(pos); - tokens.nextValidToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Invalid object number."); - objNum = tokens.intValue(); - tokens.nextValidToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Invalid generation number."); - objGen = tokens.intValue(); - tokens.nextValidToken(); - if (!tokens.getStringValue().equals("obj")) - tokens.throwError("Token 'obj' expected."); - PdfObject obj; - try { - obj = readPRObject(); - for (int j = 0; j < strings.size(); ++j) { - PdfString str = (PdfString)strings.get(j); - str.decrypt(this); - } - if (obj.isStream()) { - checkPRStreamLength((PRStream)obj); - } - } - catch (Exception e) { - obj = null; - } - if (xref[k2 + 1] > 0) { - obj = readOneObjStm((PRStream)obj, xref[k2]); - } - xrefObj.set(k, obj); - return obj; - } - - protected PdfObject readOneObjStm(PRStream stream, int idx) throws IOException { - int first = ((PdfNumber)getPdfObject(stream.get(PdfName.FIRST))).intValue(); - byte b[] = getStreamBytes(stream, tokens.getFile()); - PRTokeniser saveTokens = tokens; - tokens = new PRTokeniser(b); - try { - int address = 0; - boolean ok = true; - ++idx; - for (int k = 0; k < idx; ++k) { - ok = tokens.nextToken(); - if (!ok) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { - ok = false; - break; - } - ok = tokens.nextToken(); - if (!ok) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { - ok = false; - break; - } - address = tokens.intValue() + first; - } - if (!ok) - throw new IOException("Error reading ObjStm"); - tokens.seek(address); - return readPRObject(); - } - finally { - tokens = saveTokens; - } - } - - /** - * @return the percentage of the cross reference table that has been read - */ - public double dumpPerc() { - int total = 0; - for (int k = 0; k < xrefObj.size(); ++k) { - if (xrefObj.get(k) != null) - ++total; - } - return (total * 100.0 / xrefObj.size()); - } - - protected void readDocObj() throws IOException { - ArrayList streams = new ArrayList(); - xrefObj = new ArrayList(xref.length / 2); - xrefObj.addAll(Collections.nCopies(xref.length / 2, null)); - for (int k = 2; k < xref.length; k += 2) { - int pos = xref[k]; - if (pos <= 0 || xref[k + 1] > 0) - continue; - tokens.seek(pos); - tokens.nextValidToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Invalid object number."); - objNum = tokens.intValue(); - tokens.nextValidToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Invalid generation number."); - objGen = tokens.intValue(); - tokens.nextValidToken(); - if (!tokens.getStringValue().equals("obj")) - tokens.throwError("Token 'obj' expected."); - PdfObject obj; - try { - obj = readPRObject(); - if (obj.isStream()) { - streams.add(obj); - } - } - catch (Exception e) { - obj = null; - } - xrefObj.set(k / 2, obj); - } - for (int k = 0; k < streams.size(); ++k) { - checkPRStreamLength((PRStream)streams.get(k)); - } - readDecryptedDocObj(); - if (objStmMark != null) { - for (Iterator i = objStmMark.entrySet().iterator(); i.hasNext();) { - Map.Entry entry = (Map.Entry)i.next(); - int n = ((Integer)entry.getKey()).intValue(); - IntHashtable h = (IntHashtable)entry.getValue(); - readObjStm((PRStream)xrefObj.get(n), h); - xrefObj.set(n, null); - } - objStmMark = null; - } - xref = null; - } - - private void checkPRStreamLength(PRStream stream) throws IOException { - int fileLength = tokens.length(); - int start = stream.getOffset(); - boolean calc = false; - int streamLength = 0; - PdfObject obj = getPdfObjectRelease(stream.get(PdfName.LENGTH)); - if (obj != null && obj.type() == PdfObject.NUMBER) { - streamLength = ((PdfNumber)obj).intValue(); - if (streamLength + start > fileLength - 20) - calc = true; - else { - tokens.seek(start + streamLength); - String line = tokens.readString(20); - if (!line.startsWith("\nendstream") && - !line.startsWith("\r\nendstream") && - !line.startsWith("\rendstream") && - !line.startsWith("endstream")) - calc = true; - } - } - else - calc = true; - if (calc) { - byte tline[] = new byte[16]; - tokens.seek(start); - while (true) { - int pos = tokens.getFilePointer(); - if (!tokens.readLineSegment(tline)) - break; - if (equalsn(tline, endstream)) { - streamLength = pos - start; - break; - } - if (equalsn(tline, endobj)) { - tokens.seek(pos - 16); - String s = tokens.readString(16); - int index = s.indexOf("endstream"); - if (index >= 0) - pos = pos - 16 + index; - streamLength = pos - start; - break; - } - } - } - stream.setLength(streamLength); - } - - protected void readObjStm(PRStream stream, IntHashtable map) throws IOException { - int first = ((PdfNumber)getPdfObject(stream.get(PdfName.FIRST))).intValue(); - int n = ((PdfNumber)getPdfObject(stream.get(PdfName.N))).intValue(); - byte b[] = getStreamBytes(stream, tokens.getFile()); - PRTokeniser saveTokens = tokens; - tokens = new PRTokeniser(b); - try { - int address[] = new int[n]; - int objNumber[] = new int[n]; - boolean ok = true; - for (int k = 0; k < n; ++k) { - ok = tokens.nextToken(); - if (!ok) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { - ok = false; - break; - } - objNumber[k] = tokens.intValue(); - ok = tokens.nextToken(); - if (!ok) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) { - ok = false; - break; - } - address[k] = tokens.intValue() + first; - } - if (!ok) - throw new IOException("Error reading ObjStm"); - for (int k = 0; k < n; ++k) { - if (map.containsKey(k)) { - tokens.seek(address[k]); - PdfObject obj = readPRObject(); - xrefObj.set(objNumber[k], obj); - } - } - } - finally { - tokens = saveTokens; - } - } - - /** - * Eliminates the reference to the object freeing the memory used by it and clearing - * the xref entry. - * @param obj the object. If it's an indirect reference it will be eliminated - * @return the object or the already erased dereferenced object - */ - public static PdfObject killIndirect(PdfObject obj) { - if (obj == null || obj.isNull()) - return null; - PdfObject ret = getPdfObjectRelease(obj); - if (obj.isIndirect()) { - PRIndirectReference ref = (PRIndirectReference)obj; - PdfReader reader = ref.getReader(); - int n = ref.getNumber(); - reader.xrefObj.set(n, null); - if (reader.partial) - reader.xref[n * 2] = -1; - } - return ret; - } - - private void ensureXrefSize(int size) { - if (size == 0) - return; - if (xref == null) - xref = new int[size]; - else { - if (xref.length < size) { - int xref2[] = new int[size]; - System.arraycopy(xref, 0, xref2, 0, xref.length); - xref = xref2; - } - } - } - - protected void readXref() throws IOException { - hybridXref = false; - newXrefType = false; - tokens.seek(tokens.getStartxref()); - tokens.nextToken(); - if (!tokens.getStringValue().equals("startxref")) - throw new IOException("startxref not found."); - tokens.nextToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - throw new IOException("startxref is not followed by a number."); - int startxref = tokens.intValue(); - lastXref = startxref; - eofPos = tokens.getFilePointer(); - try { - if (readXRefStream(startxref)) { - newXrefType = true; - return; - } - } - catch (Exception e) {} - xref = null; - tokens.seek(startxref); - trailer = readXrefSection(); - PdfDictionary trailer2 = trailer; - while (true) { - PdfNumber prev = (PdfNumber)trailer2.get(PdfName.PREV); - if (prev == null) - break; - tokens.seek(prev.intValue()); - trailer2 = readXrefSection(); - } - } - - protected PdfDictionary readXrefSection() throws IOException { - tokens.nextValidToken(); - if (!tokens.getStringValue().equals("xref")) - tokens.throwError("xref subsection not found"); - int start = 0; - int end = 0; - int pos = 0; - int gen = 0; - while (true) { - tokens.nextValidToken(); - if (tokens.getStringValue().equals("trailer")) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Object number of the first object in this xref subsection not found"); - start = tokens.intValue(); - tokens.nextValidToken(); - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - tokens.throwError("Number of entries in this xref subsection not found"); - end = tokens.intValue() + start; - if (start == 1) { // fix incorrect start number - int back = tokens.getFilePointer(); - tokens.nextValidToken(); - pos = tokens.intValue(); - tokens.nextValidToken(); - gen = tokens.intValue(); - if (pos == 0 && gen == 65535) { - --start; - --end; - } - tokens.seek(back); - } - ensureXrefSize(end * 2); - for (int k = start; k < end; ++k) { - tokens.nextValidToken(); - pos = tokens.intValue(); - tokens.nextValidToken(); - gen = tokens.intValue(); - tokens.nextValidToken(); - int p = k * 2; - if (tokens.getStringValue().equals("n")) { - if (xref[p] == 0 && xref[p + 1] == 0) { -// if (pos == 0) -// tokens.throwError("File position 0 cross-reference entry in this xref subsection"); - xref[p] = pos; - } - } - else if (tokens.getStringValue().equals("f")) { - if (xref[p] == 0 && xref[p + 1] == 0) - xref[p] = -1; - } - else - tokens.throwError("Invalid cross-reference entry in this xref subsection"); - } - } - PdfDictionary trailer = (PdfDictionary)readPRObject(); - PdfNumber xrefSize = (PdfNumber)trailer.get(PdfName.SIZE); - ensureXrefSize(xrefSize.intValue() * 2); - PdfObject xrs = trailer.get(PdfName.XREFSTM); - if (xrs != null && xrs.isNumber()) { - int loc = ((PdfNumber)xrs).intValue(); - try { - readXRefStream(loc); - newXrefType = true; - hybridXref = true; - } - catch (IOException e) { - xref = null; - throw e; - } - } - return trailer; - } - - protected boolean readXRefStream(int ptr) throws IOException { - tokens.seek(ptr); - int thisStream = 0; - if (!tokens.nextToken()) - return false; - if (tokens.getTokenType() != PRTokeniser.TK_NUMBER) - return false; - thisStream = tokens.intValue(); - if (!tokens.nextToken() || tokens.getTokenType() != PRTokeniser.TK_NUMBER) - return false; - if (!tokens.nextToken() || !tokens.getStringValue().equals("obj")) - return false; - PdfObject object = readPRObject(); - PRStream stm = null; - if (object.isStream()) { - stm = (PRStream)object; - if (!PdfName.XREF.equals(stm.get(PdfName.TYPE))) - return false; - } - if (trailer == null) { - trailer = new PdfDictionary(); - trailer.putAll(stm); - } - stm.setLength(((PdfNumber)stm.get(PdfName.LENGTH)).intValue()); - int size = ((PdfNumber)stm.get(PdfName.SIZE)).intValue(); - PdfArray index; - PdfObject obj = stm.get(PdfName.INDEX); - if (obj == null) { - index = new PdfArray(); - index.add(new int[]{0, size}); - } - else - index = (PdfArray)obj; - PdfArray w = (PdfArray)stm.get(PdfName.W); - int prev = -1; - obj = stm.get(PdfName.PREV); - if (obj != null) - prev = ((PdfNumber)obj).intValue(); - // Each xref pair is a position - // type 0 -> -1, 0 - // type 1 -> offset, 0 - // type 2 -> index, obj num - ensureXrefSize(size * 2); - if (objStmMark == null && !partial) - objStmMark = new HashMap(); - if (objStmToOffset == null && partial) - objStmToOffset = new IntHashtable(); - byte b[] = getStreamBytes(stm, tokens.getFile()); - int bptr = 0; - ArrayList wa = w.getArrayList(); - int wc[] = new int[3]; - for (int k = 0; k < 3; ++k) - wc[k] = ((PdfNumber)wa.get(k)).intValue(); - ArrayList sections = index.getArrayList(); - for (int idx = 0; idx < sections.size(); idx += 2) { - int start = ((PdfNumber)sections.get(idx)).intValue(); - int length = ((PdfNumber)sections.get(idx + 1)).intValue(); - ensureXrefSize((start + length) * 2); - while (length-- > 0) { - int type = 1; - if (wc[0] > 0) { - type = 0; - for (int k = 0; k < wc[0]; ++k) - type = (type << 8) + (b[bptr++] & 0xff); - } - int field2 = 0; - for (int k = 0; k < wc[1]; ++k) - field2 = (field2 << 8) + (b[bptr++] & 0xff); - int field3 = 0; - for (int k = 0; k < wc[2]; ++k) - field3 = (field3 << 8) + (b[bptr++] & 0xff); - int base = start * 2; - if (xref[base] == 0 && xref[base + 1] == 0) { - switch (type) { - case 0: - xref[base] = -1; - break; - case 1: - xref[base] = field2; - break; - case 2: - xref[base] = field3; - xref[base + 1] = field2; - if (partial) { - objStmToOffset.put(field2, 0); - } - else { - Integer on = new Integer(field2); - IntHashtable seq = (IntHashtable)objStmMark.get(on); - if (seq == null) { - seq = new IntHashtable(); - seq.put(field3, 1); - objStmMark.put(on, seq); - } - else - seq.put(field3, 1); - } - break; - } - } - ++start; - } - } - thisStream *= 2; - if (thisStream < xref.length) - xref[thisStream] = -1; - - if (prev == -1) - return true; - return readXRefStream(prev); - } - - protected void rebuildXref() throws IOException { - hybridXref = false; - newXrefType = false; - tokens.seek(0); - int xr[][] = new int[1024][]; - int top = 0; - trailer = null; - byte line[] = new byte[64]; - for (;;) { - int pos = tokens.getFilePointer(); - if (!tokens.readLineSegment(line)) - break; - if (line[0] == 't') { - if (!PdfEncodings.convertToString(line, null).startsWith("trailer")) - continue; - tokens.seek(pos); - tokens.nextToken(); - pos = tokens.getFilePointer(); - try { - PdfDictionary dic = (PdfDictionary)readPRObject(); - if (dic.get(PdfName.ROOT) != null) - trailer = dic; - else - tokens.seek(pos); - } - catch (Exception e) { - tokens.seek(pos); - } - } - else if (line[0] >= '0' && line[0] <= '9') { - int obj[] = PRTokeniser.checkObjectStart(line); - if (obj == null) - continue; - int num = obj[0]; - int gen = obj[1]; - if (num >= xr.length) { - int newLength = num * 2; - int xr2[][] = new int[newLength][]; - System.arraycopy(xr, 0, xr2, 0, top); - xr = xr2; - } - if (num >= top) - top = num + 1; - if (xr[num] == null || gen >= xr[num][1]) { - obj[0] = pos; - xr[num] = obj; - } - } - } - if (trailer == null) - throw new IOException("trailer not found."); - xref = new int[top * 2]; - for (int k = 0; k < top; ++k) { - int obj[] = xr[k]; - if (obj != null) - xref[k * 2] = obj[0]; - } - } - - protected PdfDictionary readDictionary() throws IOException { - PdfDictionary dic = new PdfDictionary(); - while (true) { - tokens.nextValidToken(); - if (tokens.getTokenType() == PRTokeniser.TK_END_DIC) - break; - if (tokens.getTokenType() != PRTokeniser.TK_NAME) - tokens.throwError("Dictionary key is not a name."); - PdfName name = new PdfName(tokens.getStringValue(), false); - PdfObject obj = readPRObject(); - int type = obj.type(); - if (-type == PRTokeniser.TK_END_DIC) - tokens.throwError("Unexpected '>>'"); - if (-type == PRTokeniser.TK_END_ARRAY) - tokens.throwError("Unexpected ']'"); - dic.put(name, obj); - } - return dic; - } - - protected PdfArray readArray() throws IOException { - PdfArray array = new PdfArray(); - while (true) { - PdfObject obj = readPRObject(); - int type = obj.type(); - if (-type == PRTokeniser.TK_END_ARRAY) - break; - if (-type == PRTokeniser.TK_END_DIC) - tokens.throwError("Unexpected '>>'"); - array.add(obj); - } - return array; - } - - protected PdfObject readPRObject() throws IOException { - tokens.nextValidToken(); - int type = tokens.getTokenType(); - switch (type) { - case PRTokeniser.TK_START_DIC: { - PdfDictionary dic = readDictionary(); - int pos = tokens.getFilePointer(); - // be careful in the trailer. May not be a "next" token. - if (tokens.nextToken() && tokens.getStringValue().equals("stream")) { - int ch = tokens.read(); - if (ch != '\n') - ch = tokens.read(); - if (ch != '\n') - tokens.backOnePosition(ch); - PRStream stream = new PRStream(this, tokens.getFilePointer()); - stream.putAll(dic); - stream.setObjNum(objNum, objGen); - return stream; - } - else { - tokens.seek(pos); - return dic; - } - } - case PRTokeniser.TK_START_ARRAY: - return readArray(); - case PRTokeniser.TK_NUMBER: - return new PdfNumber(tokens.getStringValue()); - case PRTokeniser.TK_STRING: - PdfString str = new PdfString(tokens.getStringValue(), null).setHexWriting(tokens.isHexString()); - str.setObjNum(objNum, objGen); - if (strings != null) - strings.add(str); - return str; - case PRTokeniser.TK_NAME: - return new PdfName(tokens.getStringValue(), false); - case PRTokeniser.TK_REF: - int num = tokens.getReference(); - PRIndirectReference ref = new PRIndirectReference(this, num, tokens.getGeneration()); - if (visited != null && !visited[num]) { - visited[num] = true; - newHits.put(num, 1); - } - return ref; - default: - return new PdfLiteral(-type, tokens.getStringValue()); - } - } - - /** Decodes a stream that has the FlateDecode filter. - * @param in the input data - * @return the decoded data - */ - public static byte[] FlateDecode(byte in[]) { - byte b[] = FlateDecode(in, true); - if (b == null) - return FlateDecode(in, false); - return b; - } - - /** - * @param in - * @param dicPar - * @return a byte array - */ - public static byte[] decodePredictor(byte in[], PdfObject dicPar) { - if (dicPar == null || !dicPar.isDictionary()) - return in; - PdfDictionary dic = (PdfDictionary)dicPar; - PdfObject obj = getPdfObject(dic.get(PdfName.PREDICTOR)); - if (obj == null || !obj.isNumber()) - return in; - int predictor = ((PdfNumber)obj).intValue(); - if (predictor < 10) - return in; - int width = 1; - obj = getPdfObject(dic.get(PdfName.COLUMNS)); - if (obj != null && obj.isNumber()) - width = ((PdfNumber)obj).intValue(); - int colors = 1; - obj = getPdfObject(dic.get(PdfName.COLORS)); - if (obj != null && obj.isNumber()) - colors = ((PdfNumber)obj).intValue(); - int bpc = 8; - obj = getPdfObject(dic.get(PdfName.BITSPERCOMPONENT)); - if (obj != null && obj.isNumber()) - bpc = ((PdfNumber)obj).intValue(); - DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(in)); - ByteArrayOutputStream fout = new ByteArrayOutputStream(in.length); - int bytesPerPixel = colors * bpc / 8; - int bytesPerRow = (colors*width*bpc + 7)/8; - byte[] curr = new byte[bytesPerRow]; - byte[] prior = new byte[bytesPerRow]; - - // Decode the (sub)image row-by-row - while (true) { - // Read the filter type byte and a row of data - int filter = 0; - try { - filter = dataStream.read(); - if (filter < 0) { - return fout.toByteArray(); - } - dataStream.readFully(curr, 0, bytesPerRow); - } catch (Exception e) { - return fout.toByteArray(); - } - - switch (filter) { - case 0: //PNG_FILTER_NONE - break; - case 1: //PNG_FILTER_SUB - for (int i = bytesPerPixel; i < bytesPerRow; i++) { - curr[i] += curr[i - bytesPerPixel]; - } - break; - case 2: //PNG_FILTER_UP - for (int i = 0; i < bytesPerRow; i++) { - curr[i] += prior[i]; - } - break; - case 3: //PNG_FILTER_AVERAGE - for (int i = 0; i < bytesPerPixel; i++) { - curr[i] += prior[i] / 2; - } - for (int i = bytesPerPixel; i < bytesPerRow; i++) { - curr[i] += ((curr[i - bytesPerPixel] & 0xff) + (prior[i] & 0xff))/2; - } - break; - case 4: //PNG_FILTER_PAETH - for (int i = 0; i < bytesPerPixel; i++) { - curr[i] += prior[i]; - } - - for (int i = bytesPerPixel; i < bytesPerRow; i++) { - int a = curr[i - bytesPerPixel] & 0xff; - int b = prior[i] & 0xff; - int c = prior[i - bytesPerPixel] & 0xff; - - int p = a + b - c; - int pa = Math.abs(p - a); - int pb = Math.abs(p - b); - int pc = Math.abs(p - c); - - int ret; - - if ((pa <= pb) && (pa <= pc)) { - ret = a; - } else if (pb <= pc) { - ret = b; - } else { - ret = c; - } - curr[i] += (byte)(ret); - } - break; - default: - // Error -- uknown filter type - throw new RuntimeException("PNG filter unknown."); - } - try { - fout.write(curr); - } - catch (IOException ioe) { - // Never happens - } - - // Swap curr and prior - byte[] tmp = prior; - prior = curr; - curr = tmp; - } - } - - /** A helper to FlateDecode. - * @param in the input data - * @param strict true to read a correct stream. false - * to try to read a corrupted stream - * @return the decoded data - */ - public static byte[] FlateDecode(byte in[], boolean strict) { - ByteArrayInputStream stream = new ByteArrayInputStream(in); - InflaterInputStream zip = new InflaterInputStream(stream); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - byte b[] = new byte[strict ? 4092 : 1]; - try { - int n; - while ((n = zip.read(b)) >= 0) { - out.write(b, 0, n); - } - zip.close(); - out.close(); - return out.toByteArray(); - } - catch (Exception e) { - if (strict) - return null; - return out.toByteArray(); - } - } - - /** Decodes a stream that has the ASCIIHexDecode filter. - * @param in the input data - * @return the decoded data - */ - public static byte[] ASCIIHexDecode(byte in[]) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - boolean first = true; - int n1 = 0; - for (int k = 0; k < in.length; ++k) { - int ch = in[k] & 0xff; - if (ch == '>') - break; - if (PRTokeniser.isWhitespace(ch)) - continue; - int n = PRTokeniser.getHex(ch); - if (n == -1) - throw new RuntimeException("Illegal character in ASCIIHexDecode."); - if (first) - n1 = n; - else - out.write((byte)((n1 << 4) + n)); - first = !first; - } - if (!first) - out.write((byte)(n1 << 4)); - return out.toByteArray(); - } - - /** Decodes a stream that has the ASCII85Decode filter. - * @param in the input data - * @return the decoded data - */ - public static byte[] ASCII85Decode(byte in[]) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - int state = 0; - int chn[] = new int[5]; - for (int k = 0; k < in.length; ++k) { - int ch = in[k] & 0xff; - if (ch == '~') - break; - if (PRTokeniser.isWhitespace(ch)) - continue; - if (ch == 'z' && state == 0) { - out.write(0); - out.write(0); - out.write(0); - out.write(0); - continue; - } - if (ch < '!' || ch > 'u') - throw new RuntimeException("Illegal character in ASCII85Decode."); - chn[state] = ch - '!'; - ++state; - if (state == 5) { - state = 0; - int r = 0; - for (int j = 0; j < 5; ++j) - r = r * 85 + chn[j]; - out.write((byte)(r >> 24)); - out.write((byte)(r >> 16)); - out.write((byte)(r >> 8)); - out.write((byte)r); - } - } - int r = 0; - if (state == 1) - throw new RuntimeException("Illegal length in ASCII85Decode."); - if (state == 2) { - r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85; - out.write((byte)(r >> 24)); - } - else if (state == 3) { - r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85; - out.write((byte)(r >> 24)); - out.write((byte)(r >> 16)); - } - else if (state == 4) { - r = chn[0] * 85 * 85 * 85 * 85 + chn[1] * 85 * 85 * 85 + chn[2] * 85 * 85 + chn[3] * 85 ; - out.write((byte)(r >> 24)); - out.write((byte)(r >> 16)); - out.write((byte)(r >> 8)); - } - return out.toByteArray(); - } - - /** Decodes a stream that has the LZWDecode filter. - * @param in the input data - * @return the decoded data - */ - public static byte[] LZWDecode(byte in[]) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - LZWDecoder lzw = new LZWDecoder(); - lzw.decode(in, out); - return out.toByteArray(); - } - - /** Checks if the document had errors and was rebuilt. - * @return true if rebuilt. - * - */ - public boolean isRebuilt() { - return this.rebuilt; - } - - /** Gets the dictionary that represents a page. - * @param pageNum the page number. 1 is the first - * @return the page dictionary - */ - public PdfDictionary getPageN(int pageNum) { - PdfDictionary dic = pageRefs.getPageN(pageNum); - if (dic == null) - return null; - if (appendable) - dic.setIndRef(pageRefs.getPageOrigRef(pageNum)); - return dic; - } - - /** - * @param pageNum - * @return a Dictionary object - */ - public PdfDictionary getPageNRelease(int pageNum) { - PdfDictionary dic = getPageN(pageNum); - pageRefs.releasePage(pageNum); - return dic; - } - - /** - * @param pageNum - */ - public void releasePage(int pageNum) { - pageRefs.releasePage(pageNum); - } - - /** - * - */ - public void resetReleasePage() { - pageRefs.resetReleasePage(); - } - - /** Gets the page reference to this page. - * @param pageNum the page number. 1 is the first - * @return the page reference - */ - public PRIndirectReference getPageOrigRef(int pageNum) { - return pageRefs.getPageOrigRef(pageNum); - } - - /** Gets the contents of the page. - * @param pageNum the page number. 1 is the first - * @param file the location of the PDF document - * @throws IOException on error - * @return the content - */ - public byte[] getPageContent(int pageNum, RandomAccessFileOrArray file) throws IOException{ - PdfDictionary page = getPageNRelease(pageNum); - if (page == null) - return null; - PdfObject contents = getPdfObjectRelease(page.get(PdfName.CONTENTS)); - if (contents == null) - return new byte[0]; - ByteArrayOutputStream bout = null; - if (contents.isStream()) { - return getStreamBytes((PRStream)contents, file); - } - else if (contents.isArray()) { - PdfArray array = (PdfArray)contents; - ArrayList list = array.getArrayList(); - bout = new ByteArrayOutputStream(); - for (int k = 0; k < list.size(); ++k) { - PdfObject item = getPdfObjectRelease((PdfObject)list.get(k)); - if (item == null || !item.isStream()) - continue; - byte[] b = getStreamBytes((PRStream)item, file); - bout.write(b); - if (k != list.size() - 1) - bout.write('\n'); - } - return bout.toByteArray(); - } - else - return new byte[0]; - } - - /** Gets the contents of the page. - * @param pageNum the page number. 1 is the first - * @throws IOException on error - * @return the content - */ - public byte[] getPageContent(int pageNum) throws IOException{ - RandomAccessFileOrArray rf = getSafeFile(); - try { - rf.reOpen(); - return getPageContent(pageNum, rf); - } - finally { - try{rf.close();}catch(Exception e){} - } - } - - protected void killXref(PdfObject obj) { - if (obj == null) - return; - if ((obj instanceof PdfIndirectReference) && !obj.isIndirect()) - return; - switch (obj.type()) { - case PdfObject.INDIRECT: { - int xr = ((PRIndirectReference)obj).getNumber(); - obj = (PdfObject)xrefObj.get(xr); - xrefObj.set(xr, null); - freeXref = xr; - killXref(obj); - break; - } - case PdfObject.ARRAY: { - ArrayList t = ((PdfArray)obj).getArrayList(); - for (int i = 0; i < t.size(); ++i) - killXref((PdfObject)t.get(i)); - break; - } - case PdfObject.STREAM: - case PdfObject.DICTIONARY: { - PdfDictionary dic = (PdfDictionary)obj; - for (Iterator i = dic.getKeys().iterator(); i.hasNext();){ - killXref(dic.get((PdfName)i.next())); - } - break; - } - } - } - - /** Sets the contents of the page. - * @param content the new page content - * @param pageNum the page number. 1 is the first - * @throws IOException on error - */ - public void setPageContent(int pageNum, byte content[]) throws IOException{ - PdfDictionary page = getPageN(pageNum); - if (page == null) - return; - PdfObject contents = page.get(PdfName.CONTENTS); - freeXref = -1; - killXref(contents); - if (freeXref == -1) { - xrefObj.add(null); - freeXref = xrefObj.size() - 1; - } - page.put(PdfName.CONTENTS, new PRIndirectReference(this, freeXref)); - xrefObj.set(freeXref, new PRStream(this, content)); - } - - /** Get the content from a stream applying the required filters. - * @param stream the stream - * @param file the location where the stream is - * @throws IOException on error - * @return the stream content - */ - public static byte[] getStreamBytes(PRStream stream, RandomAccessFileOrArray file) throws IOException { - PdfObject filter = getPdfObjectRelease(stream.get(PdfName.FILTER)); - byte[] b = getStreamBytesRaw(stream, file); - ArrayList filters = new ArrayList(); - if (filter != null) { - if (filter.isName()) - filters.add(filter); - else if (filter.isArray()) - filters = ((PdfArray)filter).getArrayList(); - } - ArrayList dp = new ArrayList(); - PdfObject dpo = getPdfObjectRelease(stream.get(PdfName.DECODEPARMS)); - if (dpo == null || (!dpo.isDictionary() && !dpo.isArray())) - dpo = getPdfObjectRelease(stream.get(PdfName.DP)); - if (dpo != null) { - if (dpo.isDictionary()) - dp.add(dpo); - else if (dpo.isArray()) - dp = ((PdfArray)dpo).getArrayList(); - } - String name; - for (int j = 0; j < filters.size(); ++j) { - name = ((PdfName)PdfReader.getPdfObjectRelease((PdfObject)filters.get(j))).toString(); - if (name.equals("/FlateDecode") || name.equals("/Fl")) { - b = PdfReader.FlateDecode(b); - PdfObject dicParam = null; - if (j < dp.size()) { - dicParam = (PdfObject)dp.get(j); - b = decodePredictor(b, dicParam); - } - } - else if (name.equals("/ASCIIHexDecode") || name.equals("/AHx")) - b = PdfReader.ASCIIHexDecode(b); - else if (name.equals("/ASCII85Decode") || name.equals("/A85")) - b = PdfReader.ASCII85Decode(b); - else if (name.equals("/LZWDecode")) { - b = PdfReader.LZWDecode(b); - PdfObject dicParam = null; - if (j < dp.size()) { - dicParam = (PdfObject)dp.get(j); - b = decodePredictor(b, dicParam); - } - } - else - throw new IOException("The filter " + name + " is not supported."); - } - return b; - } - - /** Get the content from a stream applying the required filters. - * @param stream the stream - * @throws IOException on error - * @return the stream content - */ - public static byte[] getStreamBytes(PRStream stream) throws IOException { - RandomAccessFileOrArray rf = stream.getReader().getSafeFile(); - try { - rf.reOpen(); - return PdfReader.getStreamBytes(stream, rf); - } - finally { - try{rf.close();}catch(Exception e){} - } - } - - /** Get the content from a stream as it is without applying any filter. - * @param stream the stream - * @param file the location where the stream is - * @throws IOException on error - * @return the stream content - */ - public static byte[] getStreamBytesRaw(PRStream stream, RandomAccessFileOrArray file) throws IOException { - PdfReader reader = stream.getReader(); - byte b[]; - if (stream.getOffset() < 0) - b = stream.getBytes(); - else { - b = new byte[stream.getLength()]; - file.seek(stream.getOffset()); - file.readFully(b); - PdfEncryption decrypt = reader.getDecrypt(); - if (decrypt != null) { - decrypt.setHashKey(stream.getObjNum(), stream.getObjGen()); - decrypt.prepareKey(); - decrypt.encryptRC4(b); - } - } - return b; - } - - /** Get the content from a stream as it is without applying any filter. - * @param stream the stream - * @throws IOException on error - * @return the stream content - */ - public static byte[] getStreamBytesRaw(PRStream stream) throws IOException { - RandomAccessFileOrArray rf = stream.getReader().getSafeFile(); - try { - rf.reOpen(); - return PdfReader.getStreamBytesRaw(stream, rf); - } - finally { - try{rf.close();}catch(Exception e){} - } - } - - /** Eliminates shared streams if they exist. */ - public void eliminateSharedStreams() { - if (!sharedStreams) - return; - sharedStreams = false; - if (pageRefs.size() == 1) - return; - ArrayList newRefs = new ArrayList(); - ArrayList newStreams = new ArrayList(); - IntHashtable visited = new IntHashtable(); - for (int k = 1; k <= pageRefs.size(); ++k) { - PdfDictionary page = pageRefs.getPageN(k); - if (page == null) - continue; - PdfObject contents = getPdfObject(page.get(PdfName.CONTENTS)); - if (contents == null) - continue; - if (contents.isStream()) { - PRIndirectReference ref = (PRIndirectReference)page.get(PdfName.CONTENTS); - if (visited.containsKey(ref.getNumber())) { - // need to duplicate - newRefs.add(ref); - newStreams.add(new PRStream((PRStream)contents, null)); - } - else - visited.put(ref.getNumber(), 1); - } - else if (contents.isArray()) { - PdfArray array = (PdfArray)contents; - ArrayList list = array.getArrayList(); - for (int j = 0; j < list.size(); ++j) { - PRIndirectReference ref = (PRIndirectReference)list.get(j); - if (visited.containsKey(ref.getNumber())) { - // need to duplicate - newRefs.add(ref); - newStreams.add(new PRStream((PRStream)getPdfObject(ref), null)); - } - else - visited.put(ref.getNumber(), 1); - } - } - } - if (newStreams.size() == 0) - return; - for (int k = 0; k < newStreams.size(); ++k) { - xrefObj.add(newStreams.get(k)); - PRIndirectReference ref = (PRIndirectReference)newRefs.get(k); - ref.setNumber(xrefObj.size() - 1, 0); - } - } - - /** Checks if the document was changed. - * @return true if the document was changed, - * false otherwise - */ - public boolean isTampered() { - return tampered; - } - - /** - * Sets the tampered state. A tampered PdfReader cannot be reused in PdfStamper. - * @param tampered the tampered state - */ - public void setTampered(boolean tampered) { - this.tampered = tampered; - } - - /** Gets the XML metadata. - * @throws IOException on error - * @return the XML metadata - */ - public byte[] getMetadata() throws IOException { - PdfObject obj = getPdfObject(catalog.get(PdfName.METADATA)); - if (!(obj instanceof PRStream)) - return null; - RandomAccessFileOrArray rf = getSafeFile(); - byte b[] = null; - try { - rf.reOpen(); - b = getStreamBytes((PRStream)obj, rf); - } - finally { - try { - rf.close(); - } - catch (Exception e) { - // empty on purpose - } - } - return b; - } - - /** - * Gets the byte address of the last xref table. - * @return the byte address of the last xref table - */ - public int getLastXref() { - return lastXref; - } - - /** - * Gets the number of xref objects. - * @return the number of xref objects - */ - public int getXrefSize() { - return xrefObj.size(); - } - - /** - * Gets the byte address of the %%EOF marker. - * @return the byte address of the %%EOF marker - */ - public int getEofPos() { - return eofPos; - } - - /** - * Gets the PDF version. Only the last version char is returned. For example - * version 1.4 is returned as '4'. - * @return the PDF version - */ - public char getPdfVersion() { - return pdfVersion; - } - - /** - * Returns true if the PDF is encrypted. - * @return true if the PDF is encrypted - */ - public boolean isEncrypted() { - return encrypted; - } - - /** - * Gets the encryption permissions. It can be used directly in - * PdfWriter.setEncryption(). - * @return the encryption permissions - */ - public int getPermissions() { - return pValue; - } - - /** - * Returns true if the PDF has a 128 bit key encryption. - * @return true if the PDF has a 128 bit key encryption - */ - public boolean is128Key() { - return rValue == 3; - } - - /** - * Gets the trailer dictionary - * @return the trailer dictionary - */ - public PdfDictionary getTrailer() { - return trailer; - } - - PdfEncryption getDecrypt() { - return decrypt; - } - - static boolean equalsn(byte a1[], byte a2[]) { - int length = a2.length; - for (int k = 0; k < length; ++k) { - if (a1[k] != a2[k]) - return false; - } - return true; - } - - static boolean existsName(PdfDictionary dic, PdfName key, PdfName value) { - PdfObject type = getPdfObjectRelease(dic.get(key)); - if (type == null || !type.isName()) - return false; - PdfName name = (PdfName)type; - return name.equals(value); - } - - static String getFontName(PdfDictionary dic) { - PdfObject type = getPdfObjectRelease(dic.get(PdfName.BASEFONT)); - if (type == null || !type.isName()) - return null; - return PdfName.decodeName(type.toString()); - } - - static String getSubsetPrefix(PdfDictionary dic) { - String s = getFontName(dic); - if (s == null) - return null; - if (s.length() < 8 || s.charAt(6) != '+') - return null; - for (int k = 0; k < 6; ++k) { - char c = s.charAt(k); - if (c < 'A' || c > 'Z') - return null; - } - return s; - } - - /** Finds all the font subsets and changes the prefixes to some - * random values. - * @return the number of font subsets altered - */ - public int shuffleSubsetNames() { - int total = 0; - for (int k = 1; k < xrefObj.size(); ++k) { - PdfObject obj = getPdfObjectRelease(k); - if (obj == null || !obj.isDictionary()) - continue; - PdfDictionary dic = (PdfDictionary)obj; - if (!existsName(dic, PdfName.TYPE, PdfName.FONT)) - continue; - if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE1) - || existsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1) - || existsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) { - String s = getSubsetPrefix(dic); - if (s == null) - continue; - String ns = BaseFont.createSubsetPrefix() + s.substring(7); - PdfName newName = new PdfName(ns); - dic.put(PdfName.BASEFONT, newName); - setXrefPartialObject(k, dic); - ++total; - PdfDictionary fd = (PdfDictionary)getPdfObject(dic.get(PdfName.FONTDESCRIPTOR)); - if (fd == null) - continue; - fd.put(PdfName.FONTNAME, newName); - } - else if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE0)) { - String s = getSubsetPrefix(dic); - PdfArray arr = (PdfArray)getPdfObject(dic.get(PdfName.DESCENDANTFONTS)); - if (arr == null) - continue; - ArrayList list = arr.getArrayList(); - if (list.size() == 0) - continue; - PdfDictionary desc = (PdfDictionary)getPdfObject((PdfObject)list.get(0)); - String sde = getSubsetPrefix(desc); - if (sde == null) - continue; - String ns = BaseFont.createSubsetPrefix(); - if (s != null) - dic.put(PdfName.BASEFONT, new PdfName(ns + s.substring(7))); - setXrefPartialObject(k, dic); - PdfName newName = new PdfName(ns + sde.substring(7)); - desc.put(PdfName.BASEFONT, newName); - ++total; - PdfDictionary fd = (PdfDictionary)getPdfObject(desc.get(PdfName.FONTDESCRIPTOR)); - if (fd == null) - continue; - fd.put(PdfName.FONTNAME, newName); - } - } - return total; - } - - /** Finds all the fonts not subset but embedded and marks them as subset. - * @return the number of fonts altered - */ - public int createFakeFontSubsets() { - int total = 0; - for (int k = 1; k < xrefObj.size(); ++k) { - PdfObject obj = getPdfObjectRelease(k); - if (obj == null || !obj.isDictionary()) - continue; - PdfDictionary dic = (PdfDictionary)obj; - if (!existsName(dic, PdfName.TYPE, PdfName.FONT)) - continue; - if (existsName(dic, PdfName.SUBTYPE, PdfName.TYPE1) - || existsName(dic, PdfName.SUBTYPE, PdfName.MMTYPE1) - || existsName(dic, PdfName.SUBTYPE, PdfName.TRUETYPE)) { - String s = getSubsetPrefix(dic); - if (s != null) - continue; - s = getFontName(dic); - if (s == null) - continue; - String ns = BaseFont.createSubsetPrefix() + s; - PdfDictionary fd = (PdfDictionary)getPdfObjectRelease(dic.get(PdfName.FONTDESCRIPTOR)); - if (fd == null) - continue; - if (fd.get(PdfName.FONTFILE) == null && fd.get(PdfName.FONTFILE2) == null - && fd.get(PdfName.FONTFILE3) == null) - continue; - fd = (PdfDictionary)getPdfObject(dic.get(PdfName.FONTDESCRIPTOR)); - PdfName newName = new PdfName(ns); - dic.put(PdfName.BASEFONT, newName); - fd.put(PdfName.FONTNAME, newName); - setXrefPartialObject(k, dic); - ++total; - } - } - return total; - } - - private static PdfArray getNameArray(PdfObject obj) { - if (obj == null) - return null; - obj = getPdfObjectRelease(obj); - if (obj.isArray()) - return (PdfArray)obj; - else if (obj.isDictionary()) { - PdfObject arr2 = getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.D)); - if (arr2 != null && arr2.isArray()) - return (PdfArray)arr2; - } - return null; - } - - /** - * Gets all the named destinations as an HashMap. The key is the name - * and the value is the destinations array. - * @return gets all the named destinations - */ - public HashMap getNamedDestination() { - HashMap names = getNamedDestinationFromNames(); - names.putAll(getNamedDestinationFromStrings()); - return names; - } - - /** - * Gets the named destinations from the /Dests key in the catalog as an HashMap. The key is the name - * and the value is the destinations array. - * @return gets the named destinations - */ - public HashMap getNamedDestinationFromNames() { - HashMap names = new HashMap(); - if (catalog.get(PdfName.DESTS) != null) { - PdfDictionary dic = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.DESTS)); - Set keys = dic.getKeys(); - for (Iterator it = keys.iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - String name = PdfName.decodeName(key.toString()); - PdfArray arr = getNameArray(dic.get(key)); - if (arr != null) - names.put(name, arr); - } - } - return names; - } - - /** - * Gets the named destinations from the /Names key in the catalog as an HashMap. The key is the name - * and the value is the destinations array. - * @return gets the named destinations - */ - public HashMap getNamedDestinationFromStrings() { - if (catalog.get(PdfName.NAMES) != null) { - PdfDictionary dic = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.NAMES)); - dic = (PdfDictionary)getPdfObjectRelease(dic.get(PdfName.DESTS)); - if (dic != null) { - HashMap names = PdfNameTree.readTree(dic); - for (Iterator it = names.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - PdfArray arr = getNameArray((PdfObject)entry.getValue()); - if (arr != null) - entry.setValue(arr); - else - it.remove(); - } - return names; - } - } - return new HashMap(); - } - - private boolean replaceNamedDestination(PdfObject obj, HashMap names) { - obj = getPdfObject(obj); - int objIdx = lastXrefPartial; - releaseLastXrefPartial(); - if (obj != null && obj.isDictionary()) { - PdfObject ob2 = getPdfObjectRelease(((PdfDictionary)obj).get(PdfName.DEST)); - String name = null; - if (ob2 != null) { - if (ob2.isName()) - name = PdfName.decodeName(ob2.toString()); - else if (ob2.isString()) - name = ob2.toString(); - PdfArray dest = (PdfArray)names.get(name); - if (dest != null) { - ((PdfDictionary)obj).put(PdfName.DEST, dest); - setXrefPartialObject(objIdx, obj); - return true; - } - } - else if ((ob2 = getPdfObject(((PdfDictionary)obj).get(PdfName.A))) != null) { - int obj2Idx = lastXrefPartial; - releaseLastXrefPartial(); - PdfDictionary dic = (PdfDictionary)ob2; - PdfName type = (PdfName)getPdfObjectRelease(dic.get(PdfName.S)); - if (PdfName.GOTO.equals(type)) { - PdfObject ob3 = getPdfObjectRelease(dic.get(PdfName.D)); - if (ob3.isName()) - name = PdfName.decodeName(ob3.toString()); - else if (ob3.isString()) - name = ob3.toString(); - PdfArray dest = (PdfArray)names.get(name); - if (dest != null) { - dic.put(PdfName.D, dest); - setXrefPartialObject(obj2Idx, ob2); - setXrefPartialObject(objIdx, obj); - return true; - } - } - } - } - return false; - } - - /** - * Removes all the fields from the document. - */ - public void removeFields() { - pageRefs.resetReleasePage(); - for (int k = 1; k <= pageRefs.size(); ++k) { - PdfDictionary page = pageRefs.getPageN(k); - PdfArray annots = (PdfArray)getPdfObject(page.get(PdfName.ANNOTS)); - if (annots == null) { - pageRefs.releasePage(k); - continue; - } - ArrayList arr = annots.getArrayList(); - for (int j = 0; j < arr.size(); ++j) { - PdfDictionary annot = (PdfDictionary)getPdfObjectRelease((PdfObject)arr.get(j)); - if (PdfName.WIDGET.equals(annot.get(PdfName.SUBTYPE))) - arr.remove(j--); - } - if (arr.isEmpty()) - page.remove(PdfName.ANNOTS); - else - pageRefs.releasePage(k); - } - catalog.remove(PdfName.ACROFORM); - pageRefs.resetReleasePage(); - } - - /** - * Removes all the annotations and fields from the document. - */ - public void removeAnnotations() { - pageRefs.resetReleasePage(); - for (int k = 1; k <= pageRefs.size(); ++k) { - PdfDictionary page = pageRefs.getPageN(k); - if (page.get(PdfName.ANNOTS) == null) - pageRefs.releasePage(k); - else - page.remove(PdfName.ANNOTS); - } - catalog.remove(PdfName.ACROFORM); - pageRefs.resetReleasePage(); - } - - private void iterateBookmarks(PdfObject outlineRef, HashMap names) { - while (outlineRef != null) { - replaceNamedDestination(outlineRef, names); - PdfDictionary outline = (PdfDictionary)getPdfObjectRelease(outlineRef); - PdfObject first = outline.get(PdfName.FIRST); - if (first != null) { - iterateBookmarks(first, names); - } - outlineRef = outline.get(PdfName.NEXT); - } - } - - /** Replaces all the local named links with the actual destinations. */ - public void consolidateNamedDestinations() { - if (consolidateNamedDestinations) - return; - consolidateNamedDestinations = true; - HashMap names = getNamedDestination(); - if (names.size() == 0) - return; - for (int k = 1; k <= pageRefs.size(); ++k) { - PdfDictionary page = pageRefs.getPageN(k); - PdfObject annotsRef; - PdfArray annots = (PdfArray)getPdfObject(annotsRef = page.get(PdfName.ANNOTS)); - int annotIdx = lastXrefPartial; - releaseLastXrefPartial(); - if (annots == null) { - pageRefs.releasePage(k); - continue; - } - ArrayList list = annots.getArrayList(); - boolean commitAnnots = false; - for (int an = 0; an < list.size(); ++an) { - PdfObject objRef = (PdfObject)list.get(an); - if (replaceNamedDestination(objRef, names) && !objRef.isIndirect()) - commitAnnots = true; - } - if (commitAnnots) - setXrefPartialObject(annotIdx, annots); - if (!commitAnnots || annotsRef.isIndirect()) - pageRefs.releasePage(k); - } - PdfDictionary outlines = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.OUTLINES)); - if (outlines == null) - return; - iterateBookmarks(outlines.get(PdfName.FIRST), names); - } - - protected static PdfDictionary duplicatePdfDictionary(PdfDictionary original, PdfDictionary copy, PdfReader newReader) { - if (copy == null) - copy = new PdfDictionary(); - for (Iterator it = original.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - copy.put(key, duplicatePdfObject(original.get(key), newReader)); - } - return copy; - } - - protected static PdfObject duplicatePdfObject(PdfObject original, PdfReader newReader) { - if (original == null) - return null; - switch (original.type()) { - case PdfObject.DICTIONARY: { - return duplicatePdfDictionary((PdfDictionary)original, null, newReader); - } - case PdfObject.STREAM: { - PRStream org = (PRStream)original; - PRStream stream = new PRStream(org, null, newReader); - duplicatePdfDictionary(org, stream, newReader); - return stream; - } - case PdfObject.ARRAY: { - ArrayList list = ((PdfArray)original).getArrayList(); - PdfArray arr = new PdfArray(); - for (Iterator it = list.iterator(); it.hasNext();) { - arr.add(duplicatePdfObject((PdfObject)it.next(), newReader)); - } - return arr; - } - case PdfObject.INDIRECT: { - PRIndirectReference org = (PRIndirectReference)original; - return new PRIndirectReference(newReader, org.getNumber(), org.getGeneration()); - } - default: - return original; - } - } - - /** - * Closes the reader - */ - public void close() { - if (!partial) - return; - try { - tokens.close(); - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - protected void removeUnusedNode(PdfObject obj, boolean hits[]) { - if (obj == null) - return; - switch (obj.type()) { - case PdfObject.DICTIONARY: - case PdfObject.STREAM: { - PdfDictionary dic = (PdfDictionary)obj; - for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - PdfObject v = dic.get(key); - if (v.isIndirect()) { - int num = ((PRIndirectReference)v).getNumber(); - if (num >= xrefObj.size() || (!partial && xrefObj.get(num) == null)) { - dic.put(key, PdfNull.PDFNULL); - continue; - } - } - removeUnusedNode(v, hits); - } - break; - } - case PdfObject.ARRAY: { - ArrayList list = ((PdfArray)obj).getArrayList(); - for (int k = 0; k < list.size(); ++k) { - PdfObject v = (PdfObject)list.get(k); - if (v.isIndirect()) { - int num = ((PRIndirectReference)v).getNumber(); - if (num >= xrefObj.size() || (!partial && xrefObj.get(num) == null)) { - list.set(k, PdfNull.PDFNULL); - continue; - } - } - removeUnusedNode(v, hits); - } - break; - } - case PdfObject.INDIRECT: { - PRIndirectReference ref = (PRIndirectReference)obj; - int num = ref.getNumber(); - if (!hits[num]) { - hits[num] = true; - removeUnusedNode(getPdfObjectRelease(ref), hits); - } - } - } - } - - /** Removes all the unreachable objects. - * @return the number of indirect objects removed - */ - public int removeUnusedObjects() { - boolean hits[] = new boolean[xrefObj.size()]; - removeUnusedNode(trailer, hits); - int total = 0; - if (partial) { - for (int k = 1; k < hits.length; ++k) { - if (!hits[k]) { - xref[k * 2] = -1; - xref[k * 2 + 1] = 0; - xrefObj.set(k, null); - ++total; - } - } - } - else { - for (int k = 1; k < hits.length; ++k) { - if (!hits[k]) { - xrefObj.set(k, null); - ++total; - } - } - } - return total; - } - - /** Gets a read-only version of AcroFields. - * @return a read-only version of AcroFields - */ - public AcroFields getAcroFields() { - return new AcroFields(this, null); - } - - /** - * Gets the global document JavaScript. - * @param file the document file - * @throws IOException on error - * @return the global document JavaScript - */ - public String getJavaScript(RandomAccessFileOrArray file) throws IOException { - PdfDictionary names = (PdfDictionary)getPdfObjectRelease(catalog.get(PdfName.NAMES)); - if (names == null) - return null; - PdfDictionary js = (PdfDictionary)getPdfObjectRelease(names.get(PdfName.JAVASCRIPT)); - if (js == null) - return null; - HashMap jscript = PdfNameTree.readTree(js); - String sortedNames[] = new String[jscript.size()]; - sortedNames = (String[])jscript.keySet().toArray(sortedNames); - Arrays.sort(sortedNames, new StringCompare()); - StringBuffer buf = new StringBuffer(); - for (int k = 0; k < sortedNames.length; ++k) { - PdfDictionary j = (PdfDictionary)getPdfObjectRelease((PdfIndirectReference)jscript.get(sortedNames[k])); - if (j == null) - continue; - PdfObject obj = getPdfObjectRelease(j.get(PdfName.JS)); - if (obj.isString()) - buf.append(((PdfString)obj).toUnicodeString()).append('\n'); - else if (obj.isStream()) { - byte bytes[] = getStreamBytes((PRStream)obj, file); - if (bytes.length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255) - buf.append(PdfEncodings.convertToString(bytes, PdfObject.TEXT_UNICODE)); - else - buf.append(PdfEncodings.convertToString(bytes, PdfObject.TEXT_PDFDOCENCODING)); - buf.append('\n'); - } - } - return buf.toString(); - } - - /** - * Gets the global document JavaScript. - * @throws IOException on error - * @return the global document JavaScript - */ - public String getJavaScript() throws IOException { - RandomAccessFileOrArray rf = getSafeFile(); - try { - rf.reOpen(); - return getJavaScript(rf); - } - finally { - try{rf.close();}catch(Exception e){} - } - } - - /** - * Selects the pages to keep in the document. The pages are described as - * ranges. The page ordering can be changed but - * no page repetitions are allowed. Note that it may be very slow in partial mode. - * @param ranges the comma separated ranges as described in {@link SequenceList} - */ - public void selectPages(String ranges) { - selectPages(SequenceList.expand(ranges, getNumberOfPages())); - } - - /** - * Selects the pages to keep in the document. The pages are described as a - * List of Integer. The page ordering can be changed but - * no page repetitions are allowed. Note that it may be very slow in partial mode. - * @param pagesToKeep the pages to keep in the document - */ - public void selectPages(List pagesToKeep) { - pageRefs.selectPages(pagesToKeep); - removeUnusedObjects(); - } - - /** - * @param preferences - * @param catalog - */ - public static void setViewerPreferences(int preferences, PdfDictionary catalog) { - catalog.remove(PdfName.PAGELAYOUT); - catalog.remove(PdfName.PAGEMODE); - catalog.remove(PdfName.VIEWERPREFERENCES); - if ((preferences & PdfWriter.PageLayoutSinglePage) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.SINGLEPAGE); - else if ((preferences & PdfWriter.PageLayoutOneColumn) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.ONECOLUMN); - else if ((preferences & PdfWriter.PageLayoutTwoColumnLeft) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNLEFT); - else if ((preferences & PdfWriter.PageLayoutTwoColumnRight) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.TWOCOLUMNRIGHT); - else if ((preferences & PdfWriter.PageLayoutTwoPageLeft) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGELEFT); - else if ((preferences & PdfWriter.PageLayoutTwoPageRight) != 0) - catalog.put(PdfName.PAGELAYOUT, PdfName.TWOPAGERIGHT); - if ((preferences & PdfWriter.PageModeUseNone) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.USENONE); - else if ((preferences & PdfWriter.PageModeUseOutlines) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.USEOUTLINES); - else if ((preferences & PdfWriter.PageModeUseThumbs) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.USETHUMBS); - else if ((preferences & PdfWriter.PageModeFullScreen) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.FULLSCREEN); - else if ((preferences & PdfWriter.PageModeUseOC) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.USEOC); - else if ((preferences & PdfWriter.PageModeUseAttachments) != 0) - catalog.put(PdfName.PAGEMODE, PdfName.USEATTACHMENTS); - if ((preferences & PdfWriter.ViewerPreferencesMask) == 0) - return; - PdfDictionary vp = new PdfDictionary(); - if ((preferences & PdfWriter.HideToolbar) != 0) - vp.put(PdfName.HIDETOOLBAR, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.HideMenubar) != 0) - vp.put(PdfName.HIDEMENUBAR, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.HideWindowUI) != 0) - vp.put(PdfName.HIDEWINDOWUI, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.FitWindow) != 0) - vp.put(PdfName.FITWINDOW, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.CenterWindow) != 0) - vp.put(PdfName.CENTERWINDOW, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.DisplayDocTitle) != 0) - vp.put(PdfName.DISPLAYDOCTITLE, PdfBoolean.PDFTRUE); - if ((preferences & PdfWriter.NonFullScreenPageModeUseNone) != 0) - vp.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USENONE); - else if ((preferences & PdfWriter.NonFullScreenPageModeUseOutlines) != 0) - vp.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOUTLINES); - else if ((preferences & PdfWriter.NonFullScreenPageModeUseThumbs) != 0) - vp.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USETHUMBS); - else if ((preferences & PdfWriter.NonFullScreenPageModeUseOC) != 0) - vp.put(PdfName.NONFULLSCREENPAGEMODE, PdfName.USEOC); - if ((preferences & PdfWriter.DirectionL2R) != 0) - vp.put(PdfName.DIRECTION, PdfName.L2R); - else if ((preferences & PdfWriter.DirectionR2L) != 0) - vp.put(PdfName.DIRECTION, PdfName.R2L); - if ((preferences & PdfWriter.PrintScalingNone) != 0) - vp.put(PdfName.PRINTSCALING, PdfName.NONE); - catalog.put(PdfName.VIEWERPREFERENCES, vp); - } - - /** - * @param preferences - */ - public void setViewerPreferences(int preferences) { - setViewerPreferences(preferences, catalog); - } - - /** - * @return an int that contains the Viewer Preferences. - */ - public int getViewerPreferences() { - int prefs = 0; - PdfName name = null; - PdfObject obj = getPdfObjectRelease(catalog.get(PdfName.PAGELAYOUT)); - if (obj != null && obj.isName()) { - name = (PdfName)obj; - if (name.equals(PdfName.SINGLEPAGE)) - prefs |= PdfWriter.PageLayoutSinglePage; - else if (name.equals(PdfName.ONECOLUMN)) - prefs |= PdfWriter.PageLayoutOneColumn; - else if (name.equals(PdfName.TWOCOLUMNLEFT)) - prefs |= PdfWriter.PageLayoutTwoColumnLeft; - else if (name.equals(PdfName.TWOCOLUMNRIGHT)) - prefs |= PdfWriter.PageLayoutTwoColumnRight; - else if (name.equals(PdfName.TWOPAGELEFT)) - prefs |= PdfWriter.PageLayoutTwoPageLeft; - else if (name.equals(PdfName.TWOPAGERIGHT)) - prefs |= PdfWriter.PageLayoutTwoPageRight; - } - obj = getPdfObjectRelease(catalog.get(PdfName.PAGEMODE)); - if (obj != null && obj.isName()) { - name = (PdfName)obj; - if (name.equals(PdfName.USENONE)) - prefs |= PdfWriter.PageModeUseNone; - else if (name.equals(PdfName.USEOUTLINES)) - prefs |= PdfWriter.PageModeUseOutlines; - else if (name.equals(PdfName.USETHUMBS)) - prefs |= PdfWriter.PageModeUseThumbs; - else if (name.equals(PdfName.USEOC)) - prefs |= PdfWriter.PageModeUseOC; - else if (name.equals(PdfName.USEATTACHMENTS)) - prefs |= PdfWriter.PageModeUseAttachments; - } - obj = getPdfObjectRelease(catalog.get(PdfName.VIEWERPREFERENCES)); - if (obj == null || !obj.isDictionary()) - return prefs; - PdfDictionary vp = (PdfDictionary)obj; - for (int k = 0; k < vpnames.length; ++k) { - obj = getPdfObject(vp.get(vpnames[k])); - if (obj != null && "true".equals(obj.toString())) - prefs |= vpints[k]; - } - obj = getPdfObjectRelease(vp.get(PdfName.PRINTSCALING)); - if (PdfName.NONE.equals(obj)) - prefs |= PdfWriter.PrintScalingNone; - obj = getPdfObjectRelease(vp.get(PdfName.NONFULLSCREENPAGEMODE)); - if (obj != null && obj.isName()) { - name = (PdfName)obj; - if (name.equals(PdfName.USENONE)) - prefs |= PdfWriter.NonFullScreenPageModeUseNone; - else if (name.equals(PdfName.USEOUTLINES)) - prefs |= PdfWriter.NonFullScreenPageModeUseOutlines; - else if (name.equals(PdfName.USETHUMBS)) - prefs |= PdfWriter.NonFullScreenPageModeUseThumbs; - else if (name.equals(PdfName.USEOC)) - prefs |= PdfWriter.NonFullScreenPageModeUseOC; - } - obj = getPdfObjectRelease(vp.get(PdfName.DIRECTION)); - if (obj != null && obj.isName()) { - name = (PdfName)obj; - if (name.equals(PdfName.L2R)) - prefs |= PdfWriter.DirectionL2R; - else if (name.equals(PdfName.R2L)) - prefs |= PdfWriter.DirectionR2L; - } - return prefs; - } - - /** - * Getter for property appendable. - * @return Value of property appendable. - */ - public boolean isAppendable() { - return this.appendable; - } - - /** - * Setter for property appendable. - * @param appendable New value of property appendable. - */ - public void setAppendable(boolean appendable) { - this.appendable = appendable; - if (appendable) - getPdfObject(trailer.get(PdfName.ROOT)); - } - - /** - * Getter for property newXrefType. - * @return Value of property newXrefType. - */ - public boolean isNewXrefType() { - return newXrefType; - } - - /** - * Getter for property fileLength. - * @return Value of property fileLength. - */ - public int getFileLength() { - return fileLength; - } - - /** - * Getter for property hybridXref. - * @return Value of property hybridXref. - */ - public boolean isHybridXref() { - return hybridXref; - } - - static class PageRefs { - private PdfReader reader; - private IntHashtable refsp; - private ArrayList refsn; - private ArrayList pageInh; - private int lastPageRead = -1; - private int sizep; - - private PageRefs(PdfReader reader) throws IOException { - this.reader = reader; - if (reader.partial) { - refsp = new IntHashtable(); - PdfNumber npages = (PdfNumber)PdfReader.getPdfObjectRelease(reader.rootPages.get(PdfName.COUNT)); - sizep = npages.intValue(); - } - else { - readPages(); - } - } - - PageRefs(PageRefs other, PdfReader reader) { - this.reader = reader; - this.sizep = other.sizep; - if (other.refsn != null) { - refsn = new ArrayList(other.refsn); - for (int k = 0; k < refsn.size(); ++k) { - refsn.set(k, duplicatePdfObject((PdfObject)refsn.get(k), reader)); - } - } - else - this.refsp = (IntHashtable)other.refsp.clone(); - } - - int size() { - if (refsn != null) - return refsn.size(); - else - return sizep; - } - - void readPages() throws IOException { - if (refsn != null) - return; - refsp = null; - refsn = new ArrayList(); - pageInh = new ArrayList(); - iteratePages((PRIndirectReference)reader.catalog.get(PdfName.PAGES)); - pageInh = null; - reader.rootPages.put(PdfName.COUNT, new PdfNumber(refsn.size())); - } - - void reReadPages() throws IOException { - refsn = null; - readPages(); - } - - /** Gets the dictionary that represents a page. - * @param pageNum the page number. 1 is the first - * @return the page dictionary - */ - public PdfDictionary getPageN(int pageNum) { - PRIndirectReference ref = getPageOrigRef(pageNum); - return (PdfDictionary)PdfReader.getPdfObject(ref); - } - - /** - * @param pageNum - * @return a dictionary object - */ - public PdfDictionary getPageNRelease(int pageNum) { - PdfDictionary page = getPageN(pageNum); - releasePage(pageNum); - return page; - } - - /** - * @param pageNum - * @return an indirect reference - */ - public PRIndirectReference getPageOrigRefRelease(int pageNum) { - PRIndirectReference ref = getPageOrigRef(pageNum); - releasePage(pageNum); - return ref; - } - - /** Gets the page reference to this page. - * @param pageNum the page number. 1 is the first - * @return the page reference - */ - public PRIndirectReference getPageOrigRef(int pageNum) { - try { - --pageNum; - if (pageNum < 0 || pageNum >= size()) - return null; - if (refsn != null) - return (PRIndirectReference)refsn.get(pageNum); - else { - int n = refsp.get(pageNum); - if (n == 0) { - PRIndirectReference ref = getSinglePage(pageNum); - if (reader.lastXrefPartial == -1) - lastPageRead = -1; - else - lastPageRead = pageNum; - reader.lastXrefPartial = -1; - refsp.put(pageNum, ref.getNumber()); - return ref; - } - else { - if (lastPageRead != pageNum) - lastPageRead = -1; - return new PRIndirectReference(reader, n); - } - } - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * @param pageNum - */ - public void releasePage(int pageNum) { - if (refsp == null) - return; - --pageNum; - if (pageNum < 0 || pageNum >= size()) - return; - if (pageNum != lastPageRead) - return; - lastPageRead = -1; - reader.lastXrefPartial = refsp.get(pageNum); - reader.releaseLastXrefPartial(); - refsp.remove(pageNum); - } - - /** - * - */ - public void resetReleasePage() { - if (refsp == null) - return; - lastPageRead = -1; - } - - void insertPage(int pageNum, PRIndirectReference ref) { - --pageNum; - if (refsn != null) { - if (pageNum >= refsn.size()) - refsn.add(ref); - else - refsn.add(pageNum, ref); - } - else { - ++sizep; - lastPageRead = -1; - if (pageNum >= size()) { - refsp.put(size(), ref.getNumber()); - } - else { - IntHashtable refs2 = new IntHashtable((refsp.size() + 1) * 2); - for (Iterator it = refsp.getEntryIterator(); it.hasNext();) { - IntHashtable.IntHashtableEntry entry = (IntHashtable.IntHashtableEntry)it.next(); - int p = entry.getKey(); - refs2.put(p >= pageNum ? p + 1 : p, entry.getValue()); - } - refs2.put(pageNum, ref.getNumber()); - refsp = refs2; - } - } - } - - private void pushPageAttributes(PdfDictionary nodePages) { - PdfDictionary dic = new PdfDictionary(); - if (pageInh.size() != 0) { - dic.putAll((PdfDictionary)pageInh.get(pageInh.size() - 1)); - } - for (int k = 0; k < pageInhCandidates.length; ++k) { - PdfObject obj = nodePages.get(pageInhCandidates[k]); - if (obj != null) - dic.put(pageInhCandidates[k], obj); - } - pageInh.add(dic); - } - - private void popPageAttributes() { - pageInh.remove(pageInh.size() - 1); - } - - private void iteratePages(PRIndirectReference rpage) throws IOException { - PdfDictionary page = (PdfDictionary)getPdfObject(rpage); - PdfArray kidsPR = (PdfArray)getPdfObject(page.get(PdfName.KIDS)); - if (kidsPR == null) { - page.put(PdfName.TYPE, PdfName.PAGE); - PdfDictionary dic = (PdfDictionary)pageInh.get(pageInh.size() - 1); - PdfName key; - for (Iterator i = dic.getKeys().iterator(); i.hasNext();) { - key = (PdfName)i.next(); - if (page.get(key) == null) - page.put(key, dic.get(key)); - } - if (page.get(PdfName.MEDIABOX) == null) { - PdfArray arr = new PdfArray(new float[]{0,0,PageSize.LETTER.right(),PageSize.LETTER.top()}); - page.put(PdfName.MEDIABOX, arr); - } - refsn.add(rpage); - } - else { - page.put(PdfName.TYPE, PdfName.PAGES); - pushPageAttributes(page); - ArrayList kids = kidsPR.getArrayList(); - for (int k = 0; k < kids.size(); ++k){ - PdfObject obj = (PdfObject)kids.get(k); - if (!obj.isIndirect()) { - while (k < kids.size()) - kids.remove(k); - break; - } - iteratePages((PRIndirectReference)obj); - } - popPageAttributes(); - } - } - - protected PRIndirectReference getSinglePage(int n) throws IOException { - PdfDictionary acc = new PdfDictionary(); - PdfDictionary top = reader.rootPages; - int base = 0; - while (true) { - for (int k = 0; k < pageInhCandidates.length; ++k) { - PdfObject obj = top.get(pageInhCandidates[k]); - if (obj != null) - acc.put(pageInhCandidates[k], obj); - } - PdfArray kids = (PdfArray)PdfReader.getPdfObjectRelease(top.get(PdfName.KIDS)); - for (Iterator it = kids.listIterator(); it.hasNext();) { - PRIndirectReference ref = (PRIndirectReference)it.next(); - PdfDictionary dic = (PdfDictionary)getPdfObject(ref); - int last = reader.lastXrefPartial; - PdfObject count = getPdfObjectRelease(dic.get(PdfName.COUNT)); - reader.lastXrefPartial = last; - int acn = 1; - if (count != null && count.type() == PdfObject.NUMBER) - acn = ((PdfNumber)count).intValue(); - if (n < base + acn) { - if (count == null) { - dic.mergeDifferent(acc); - return ref; - } - reader.releaseLastXrefPartial(); - top = dic; - break; - } - reader.releaseLastXrefPartial(); - base += acn; - } - } - } - - private void selectPages(List pagesToKeep) { - IntHashtable pg = new IntHashtable(); - ArrayList finalPages = new ArrayList(); - int psize = size(); - for (Iterator it = pagesToKeep.iterator(); it.hasNext();) { - Integer pi = (Integer)it.next(); - int p = pi.intValue(); - if (p >= 1 && p <= psize && pg.put(p, 1) == 0) - finalPages.add(pi); - } - if (reader.partial) { - for (int k = 1; k <= psize; ++k) { - getPageOrigRef(k); - resetReleasePage(); - } - } - PRIndirectReference parent = (PRIndirectReference)reader.catalog.get(PdfName.PAGES); - PdfDictionary topPages = (PdfDictionary)PdfReader.getPdfObject(parent); - ArrayList newPageRefs = new ArrayList(finalPages.size()); - PdfArray kids = new PdfArray(); - for (int k = 0; k < finalPages.size(); ++k) { - int p = ((Integer)finalPages.get(k)).intValue(); - PRIndirectReference pref = getPageOrigRef(p); - resetReleasePage(); - kids.add(pref); - newPageRefs.add(pref); - getPageN(p).put(PdfName.PARENT, parent); - } - AcroFields af = reader.getAcroFields(); - boolean removeFields = (af.getFields().size() > 0); - for (int k = 1; k <= psize; ++k) { - if (!pg.containsKey(k)) { - if (removeFields) - af.removeFieldsFromPage(k); - PRIndirectReference pref = getPageOrigRef(k); - int nref = pref.getNumber(); - reader.xrefObj.set(nref, null); - if (reader.partial) { - reader.xref[nref * 2] = -1; - reader.xref[nref * 2 + 1] = 0; - } - } - } - topPages.put(PdfName.COUNT, new PdfNumber(finalPages.size())); - topPages.put(PdfName.KIDS, kids); - refsp = null; - refsn = newPageRefs; - } - } - - PdfIndirectReference getCryptoRef() { - if (cryptoRef == null) - return null; - return new PdfIndirectReference(0, cryptoRef.getNumber(), cryptoRef.getGeneration()); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfReaderInstance.java b/src/main/java/com/lowagie/text/pdf/PdfReaderInstance.java deleted file mode 100644 index 294e52d..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfReaderInstance.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * $Id: PdfReaderInstance.java,v 1.52 2005/11/01 12:27:05 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.io.*; -/** - * Instance of PdfReader in each output document. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -class PdfReaderInstance { - static final PdfLiteral IDENTITYMATRIX = new PdfLiteral("[1 0 0 1 0 0]"); - static final PdfNumber ONE = new PdfNumber(1); - int myXref[]; - PdfReader reader; - RandomAccessFileOrArray file; - HashMap importedPages = new HashMap(); - PdfWriter writer; - HashMap visited = new HashMap(); - ArrayList nextRound = new ArrayList(); - - PdfReaderInstance(PdfReader reader, PdfWriter writer) { - this.reader = reader; - this.writer = writer; - file = reader.getSafeFile(); - myXref = new int[reader.getXrefSize()]; - } - - PdfReader getReader() { - return reader; - } - - PdfImportedPage getImportedPage(int pageNumber) { - if (pageNumber < 1 || pageNumber > reader.getNumberOfPages()) - throw new IllegalArgumentException("Invalid page number"); - Integer i = new Integer(pageNumber); - PdfImportedPage pageT = (PdfImportedPage)importedPages.get(i); - if (pageT == null) { - pageT = new PdfImportedPage(this, writer, pageNumber); - importedPages.put(i, pageT); - } - return pageT; - } - - int getNewObjectNumber(int number, int generation) { - if (myXref[number] == 0) { - myXref[number] = writer.getIndirectReferenceNumber(); - nextRound.add(new Integer(number)); - } - return myXref[number]; - } - - RandomAccessFileOrArray getReaderFile() { - return file; - } - - PdfObject getResources(int pageNumber) { - PdfObject obj = PdfReader.getPdfObjectRelease(reader.getPageNRelease(pageNumber).get(PdfName.RESOURCES)); - return obj; - } - - - PdfStream getFormXObject(int pageNumber) throws IOException { - PdfDictionary page = reader.getPageNRelease(pageNumber); - PdfObject contents = PdfReader.getPdfObjectRelease(page.get(PdfName.CONTENTS)); - PdfDictionary dic = new PdfDictionary(); - byte bout[] = null; - if (contents != null) { - if (contents.isStream()) - dic.putAll((PRStream)contents); - else - bout = reader.getPageContent(pageNumber, file); - } - else - bout = new byte[0]; - dic.put(PdfName.RESOURCES, PdfReader.getPdfObjectRelease(page.get(PdfName.RESOURCES))); - dic.put(PdfName.TYPE, PdfName.XOBJECT); - dic.put(PdfName.SUBTYPE, PdfName.FORM); - PdfImportedPage impPage = (PdfImportedPage)importedPages.get(new Integer(pageNumber)); - dic.put(PdfName.BBOX, new PdfRectangle(impPage.getBoundingBox())); - PdfArray matrix = impPage.getMatrix(); - if (matrix == null) - dic.put(PdfName.MATRIX, IDENTITYMATRIX); - else - dic.put(PdfName.MATRIX, matrix); - dic.put(PdfName.FORMTYPE, ONE); - PRStream stream; - if (bout == null) { - stream = new PRStream((PRStream)contents, dic); - } - else { - stream = new PRStream(reader, bout); - stream.putAll(dic); - } - return stream; - } - - void writeAllVisited() throws IOException { - while (nextRound.size() > 0) { - ArrayList vec = nextRound; - nextRound = new ArrayList(); - for (int k = 0; k < vec.size(); ++k) { - Integer i = (Integer)vec.get(k); - if (!visited.containsKey(i)) { - visited.put(i, null); - int n = i.intValue(); - writer.addToBody(reader.getPdfObjectRelease(n), myXref[n]); - } - } - } - } - - void writeAllPages() throws IOException { - try { - file.reOpen(); - for (Iterator it = importedPages.values().iterator(); it.hasNext();) { - PdfImportedPage ip = (PdfImportedPage)it.next(); - writer.addToBody(ip.getFormXObject(), ip.getIndirectReference()); - } - writeAllVisited(); - } - finally { - try { - reader.close(); - file.close(); - } - catch (Exception e) { - //Empty on purpose - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfRectangle.java b/src/main/java/com/lowagie/text/pdf/PdfRectangle.java deleted file mode 100644 index c1d5f0d..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfRectangle.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * $Id: PdfRectangle.java,v 1.59 2006/01/16 13:46:20 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; - -/** - * PdfRectangle is the PDF Rectangle object. - *

- * Rectangles are used to describe locations on the page and bounding boxes for several - * objects in PDF, such as fonts. A rectangle is represented as an array of - * four numbers, specifying the lower lef x, lower left y, upper right x, - * and upper right y coordinates of the rectangle, in that order.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 7.1 (page 183). - * - * @see com.lowagie.text.Rectangle - * @see PdfArray - */ - -public class PdfRectangle extends PdfArray { - - // membervariables - -/** lower left x */ - private float llx = 0; - -/** lower left y */ - private float lly = 0; - -/** upper right x */ - private float urx = 0; - -/** upper right y */ - private float ury = 0; - - // constructors - -/** - * Constructs a PdfRectangle-object. - * - * @param llx lower left x - * @param lly lower left y - * @param urx upper right x - * @param ury upper right y - * - * @since rugPdf0.10 - */ - - public PdfRectangle(float llx, float lly, float urx, float ury, int rotation) { - super(); - if (rotation == 90 || rotation == 270) { - this.llx = lly; - this.lly = llx; - this.urx = ury; - this.ury = urx; - } - else { - this.llx = llx; - this.lly = lly; - this.urx = urx; - this.ury = ury; - } - super.add(new PdfNumber(this.llx)); - super.add(new PdfNumber(this.lly)); - super.add(new PdfNumber(this.urx)); - super.add(new PdfNumber(this.ury)); - } - - public PdfRectangle(float llx, float lly, float urx, float ury) { - this(llx, lly, urx, ury, 0); - } - -/** - * Constructs a PdfRectangle-object starting from the origin (0, 0). - * - * @param urx upper right x - * @param ury upper right y - */ - - public PdfRectangle(float urx, float ury, int rotation) { - this(0, 0, urx, ury, rotation); - } - - public PdfRectangle(float urx, float ury) { - this(0, 0, urx, ury, 0); - } - -/** - * Constructs a PdfRectangle-object with a Rectangle-object. - * - * @param rectangle a Rectangle - */ - - public PdfRectangle(Rectangle rectangle, int rotation) { - this(rectangle.left(), rectangle.bottom(), rectangle.right(), rectangle.top(), rotation); - } - - public PdfRectangle(Rectangle rectangle) { - this(rectangle.left(), rectangle.bottom(), rectangle.right(), rectangle.top(), 0); - } - - // methods - /** - * Returns the high level version of this PdfRectangle - * @return this PdfRectangle translated to class Rectangle - */ - public Rectangle getRectangle() { - return new Rectangle(left(), bottom(), right(), top()); - } - -/** - * Overrides the add-method in PdfArray in order to prevent the adding of extra object to the array. - * - * @param object PdfObject to add (will not be added here) - * @return false - */ - - public boolean add(PdfObject object) { - return false; - } - -/** - * Returns the lower left x-coordinate. - * - * @return the lower left x-coordinaat - */ - - public float left() { - return llx; - } - -/** - * Returns the upper right x-coordinate. - * - * @return the upper right x-coordinate - */ - - public float right() { - return urx; - } - -/** - * Returns the upper right y-coordinate. - * - * @return the upper right y-coordinate - */ - - public float top() { - return ury; - } - -/** - * Returns the lower left y-coordinate. - * - * @return the lower left y-coordinate - */ - - public float bottom() { - return lly; - } - -/** - * Returns the lower left x-coordinate, considering a given margin. - * - * @param margin a margin - * @return the lower left x-coordinate - */ - - public float left(int margin) { - return llx + margin; - } - -/** - * Returns the upper right x-coordinate, considering a given margin. - * - * @param margin a margin - * @return the upper right x-coordinate - */ - - public float right(int margin) { - return urx - margin; - } - -/** - * Returns the upper right y-coordinate, considering a given margin. - * - * @param margin a margin - * @return the upper right y-coordinate - */ - - public float top(int margin) { - return ury - margin; - } - -/** - * Returns the lower left y-coordinate, considering a given margin. - * - * @param margin a margin - * @return the lower left y-coordinate - */ - - public float bottom(int margin) { - return lly + margin; - } - -/** - * Returns the width of the rectangle. - * - * @return a width - */ - - public float width() { - return urx - llx; - } - -/** - * Returns the height of the rectangle. - * - * @return a height - */ - - public float height() { - return ury - lly; - } - -/** - * Swaps the values of urx and ury and of lly and llx in order to rotate the rectangle. - * - * @return a PdfRectangle - */ - - public PdfRectangle rotate() { - return new PdfRectangle(lly, llx, ury, urx, 0); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfRendition.java b/src/main/java/com/lowagie/text/pdf/PdfRendition.java deleted file mode 100644 index bcbd114..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfRendition.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2003 Galo Gimenez - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; - -/** - * A Rendition dictionary (pdf spec 1.5) - */ -public class PdfRendition extends PdfDictionary { - PdfRendition(String file, PdfFileSpecification fs, String mimeType) throws IOException{ - put(PdfName.S, new PdfName("MR")); - put(PdfName.N, new PdfString("Rendition for "+file)); - put(PdfName.C, new PdfMediaClipData(file, fs, mimeType)); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfResources.java b/src/main/java/com/lowagie/text/pdf/PdfResources.java deleted file mode 100644 index 3480a19..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfResources.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * $Id: PdfResources.java,v 1.56 2005/05/04 14:31:53 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * PdfResources is the PDF Resources-object. - *

- * The marking operations for drawing a page are stored in a stream that is the value of the - * Contents key in the Page object's dictionary. Each marking context includes a list - * of the named resources it uses. This resource list is stored as a dictionary that is the - * value of the context's Resources key, and it serves two functions: it enumerates - * the named resources in the contents stream, and it established the mapping from the names - * to the objects used by the marking operations.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 7.5 (page 195-197). - * - * @see PdfPage - */ - -class PdfResources extends PdfDictionary { - - // constructor - -/** - * Constructs a PDF ResourcesDictionary. - */ - - PdfResources() { - super(); - } - - // methods - - void add(PdfName key, PdfDictionary resource) { - if (resource.size() == 0) - return; - PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObject(get(key)); - if (dic == null) - put(key, resource); - else - dic.putAll(resource); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfShading.java b/src/main/java/com/lowagie/text/pdf/PdfShading.java deleted file mode 100644 index 54e2067..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfShading.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.awt.Color; -import java.io.IOException; -/** Implements the shading dictionary (or stream). - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfShading { - - protected PdfDictionary shading; - - protected PdfWriter writer; - - protected int shadingType; - - protected ColorDetails colorDetails; - - protected PdfName shadingName; - - protected PdfIndirectReference shadingReference; - - private Color cspace; - - /** Holds value of property bBox. */ - protected float[] bBox; - - /** Holds value of property antiAlias. */ - protected boolean antiAlias = false; - - /** Creates new PdfShading */ - protected PdfShading(PdfWriter writer) { - this.writer = writer; - } - - protected void setColorSpace(Color color) { - cspace = color; - int type = ExtendedColor.getType(color); - PdfObject colorSpace = null; - switch (type) { - case ExtendedColor.TYPE_GRAY: { - colorSpace = PdfName.DEVICEGRAY; - break; - } - case ExtendedColor.TYPE_CMYK: { - colorSpace = PdfName.DEVICECMYK; - break; - } - case ExtendedColor.TYPE_SEPARATION: { - SpotColor spot = (SpotColor)color; - colorDetails = writer.addSimple(spot.getPdfSpotColor()); - colorSpace = colorDetails.getIndirectReference(); - break; - } - case ExtendedColor.TYPE_PATTERN: - case ExtendedColor.TYPE_SHADING: { - throwColorSpaceError(); - } - default: - colorSpace = PdfName.DEVICERGB; - break; - } - shading.put(PdfName.COLORSPACE, colorSpace); - } - - Color getColorSpace() { - return cspace; - } - - public static void throwColorSpaceError() { - throw new IllegalArgumentException("A tiling or shading pattern cannot be used as a color space in a shading pattern"); - } - - public static void checkCompatibleColors(Color c1, Color c2) { - int type1 = ExtendedColor.getType(c1); - int type2 = ExtendedColor.getType(c2); - if (type1 != type2) - throw new IllegalArgumentException("Both colors must be of the same type."); - if (type1 == ExtendedColor.TYPE_SEPARATION && ((SpotColor)c1).getPdfSpotColor() != ((SpotColor)c2).getPdfSpotColor()) - throw new IllegalArgumentException("The spot color must be the same, only the tint can vary."); - if (type1 == ExtendedColor.TYPE_PATTERN || type1 == ExtendedColor.TYPE_SHADING) - throwColorSpaceError(); - } - - public static float[] getColorArray(Color color) { - int type = ExtendedColor.getType(color); - switch (type) { - case ExtendedColor.TYPE_GRAY: { - return new float[]{((GrayColor)color).getGray()}; - } - case ExtendedColor.TYPE_CMYK: { - CMYKColor cmyk = (CMYKColor)color; - return new float[]{cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()}; - } - case ExtendedColor.TYPE_SEPARATION: { - return new float[]{((SpotColor)color).getTint()}; - } - case ExtendedColor.TYPE_RGB: { - return new float[]{color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f}; - } - } - throwColorSpaceError(); - return null; - } - - public static PdfShading type1(PdfWriter writer, Color colorSpace, float domain[], float tMatrix[], PdfFunction function) { - PdfShading sp = new PdfShading(writer); - sp.shading = new PdfDictionary(); - sp.shadingType = 1; - sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); - sp.setColorSpace(colorSpace); - if (domain != null) - sp.shading.put(PdfName.DOMAIN, new PdfArray(domain)); - if (tMatrix != null) - sp.shading.put(PdfName.MATRIX, new PdfArray(tMatrix)); - sp.shading.put(PdfName.FUNCTION, function.getReference()); - return sp; - } - - public static PdfShading type2(PdfWriter writer, Color colorSpace, float coords[], float domain[], PdfFunction function, boolean extend[]) { - PdfShading sp = new PdfShading(writer); - sp.shading = new PdfDictionary(); - sp.shadingType = 2; - sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); - sp.setColorSpace(colorSpace); - sp.shading.put(PdfName.COORDS, new PdfArray(coords)); - if (domain != null) - sp.shading.put(PdfName.DOMAIN, new PdfArray(domain)); - sp.shading.put(PdfName.FUNCTION, function.getReference()); - if (extend != null && (extend[0] || extend[1])) { - PdfArray array = new PdfArray(extend[0] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - array.add(extend[1] ? PdfBoolean.PDFTRUE : PdfBoolean.PDFFALSE); - sp.shading.put(PdfName.EXTEND, array); - } - return sp; - } - - public static PdfShading type3(PdfWriter writer, Color colorSpace, float coords[], float domain[], PdfFunction function, boolean extend[]) { - PdfShading sp = type2(writer, colorSpace, coords, domain, function, extend); - sp.shadingType = 3; - sp.shading.put(PdfName.SHADINGTYPE, new PdfNumber(sp.shadingType)); - return sp; - } - - public static PdfShading simpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor, boolean extendStart, boolean extendEnd) { - checkCompatibleColors(startColor, endColor); - PdfFunction function = PdfFunction.type2(writer, new float[]{0, 1}, null, getColorArray(startColor), - getColorArray(endColor), 1); - return type2(writer, startColor, new float[]{x0, y0, x1, y1}, null, function, new boolean[]{extendStart, extendEnd}); - } - - public static PdfShading simpleAxial(PdfWriter writer, float x0, float y0, float x1, float y1, Color startColor, Color endColor) { - return simpleAxial(writer, x0, y0, x1, y1, startColor, endColor, true, true); - } - - public static PdfShading simpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor, boolean extendStart, boolean extendEnd) { - checkCompatibleColors(startColor, endColor); - PdfFunction function = PdfFunction.type2(writer, new float[]{0, 1}, null, getColorArray(startColor), - getColorArray(endColor), 1); - return type3(writer, startColor, new float[]{x0, y0, r0, x1, y1, r1}, null, function, new boolean[]{extendStart, extendEnd}); - } - - public static PdfShading simpleRadial(PdfWriter writer, float x0, float y0, float r0, float x1, float y1, float r1, Color startColor, Color endColor) { - return simpleRadial(writer, x0, y0, r0, x1, y1, r1, startColor, endColor, true, true); - } - - PdfName getShadingName() { - return shadingName; - } - - PdfIndirectReference getShadingReference() { - if (shadingReference == null) - shadingReference = writer.getPdfIndirectReference(); - return shadingReference; - } - - void setName(int number) { - shadingName = new PdfName("Sh" + number); - } - - void addToBody() throws IOException { - if (bBox != null) - shading.put(PdfName.BBOX, new PdfArray(bBox)); - if (antiAlias) - shading.put(PdfName.ANTIALIAS, PdfBoolean.PDFTRUE); - writer.addToBody(shading, getShadingReference()); - } - - PdfWriter getWriter() { - return writer; - } - - ColorDetails getColorDetails() { - return colorDetails; - } - - public float[] getBBox() { - return bBox; - } - - public void setBBox(float[] bBox) { - if (bBox.length != 4) - throw new IllegalArgumentException("BBox must be a 4 element array."); - this.bBox = bBox; - } - - public boolean isAntiAlias() { - return antiAlias; - } - - public void setAntiAlias(boolean antiAlias) { - this.antiAlias = antiAlias; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfShadingPattern.java b/src/main/java/com/lowagie/text/pdf/PdfShadingPattern.java deleted file mode 100644 index c90e97c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfShadingPattern.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; -/** Implements the shading pattern dictionary. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfShadingPattern extends PdfDictionary { - - protected PdfShading shading; - - protected PdfWriter writer; - - protected float matrix[] = {1, 0, 0, 1, 0, 0}; - - protected PdfName patternName; - - protected PdfIndirectReference patternReference; - - /** Creates new PdfShadingPattern */ - public PdfShadingPattern(PdfShading shading) { - writer = shading.getWriter(); - put(PdfName.PATTERNTYPE, new PdfNumber(2)); - this.shading = shading; - } - - PdfName getPatternName() { - return patternName; - } - - PdfName getShadingName() { - return shading.getShadingName(); - } - - PdfIndirectReference getPatternReference() { - if (patternReference == null) - patternReference = writer.getPdfIndirectReference(); - return patternReference; - } - - PdfIndirectReference getShadingReference() { - return shading.getShadingReference(); - } - - void setName(int number) { - patternName = new PdfName("P" + number); - } - - void addToBody() throws IOException { - put(PdfName.SHADING, getShadingReference()); - put(PdfName.MATRIX, new PdfArray(matrix)); - writer.addToBody(this, getPatternReference()); - } - - public void setMatrix(float matrix[]) { - if (matrix.length != 6) - throw new RuntimeException("The matrix size must be 6."); - this.matrix = matrix; - } - - public float[] getMatrix() { - return matrix; - } - - PdfShading getShading() { - return shading; - } - - ColorDetails getColorDetails() { - return shading.getColorDetails(); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfSigGenericPKCS.java b/src/main/java/com/lowagie/text/pdf/PdfSigGenericPKCS.java deleted file mode 100644 index 2cbee88..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfSigGenericPKCS.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.security.cert.Certificate; -import java.security.cert.CRL; -import java.security.PrivateKey; -import com.lowagie.text.ExceptionConverter; -import java.io.ByteArrayOutputStream; - -/** - * A signature dictionary representation for the standard filters. - */ -public abstract class PdfSigGenericPKCS extends PdfSignature { - /** - * The hash algorith, for example "SHA1" - */ - protected String hashAlgorithm; - /** - * The crypto provider - */ - protected String provider = null; - /** - * The class instance that calculates the PKCS#1 and PKCS#7 - */ - protected PdfPKCS7 pkcs; - /** - * The subject name in the signing certificate (the element "CN") - */ - protected String name; - - private byte externalDigest[]; - private byte externalRSAdata[]; - private String digestEncryptionAlgorithm; - - /** - * Creates a generic standard filter. - * @param filter the filter name - * @param subFilter the sub-filter name - */ - public PdfSigGenericPKCS(PdfName filter, PdfName subFilter) { - super(filter, subFilter); - } - - /** - * Sets the crypto information to sign. - * @param privKey the private key - * @param certChain the certificate chain - * @param crlList the certificate revocation list. It can be null - */ - public void setSignInfo(PrivateKey privKey, Certificate[] certChain, CRL[] crlList) { - try { - pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); - pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); - if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - for (int k = 0; k < certChain.length; ++k) { - bout.write(certChain[k].getEncoded()); - } - bout.close(); - setCert(bout.toByteArray()); - setContents(pkcs.getEncodedPKCS1()); - } - else - setContents(pkcs.getEncodedPKCS7()); - name = PdfPKCS7.getSubjectFields(pkcs.getSigningCertificate()).getField("CN"); - if (name != null) - put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); - pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); - pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Sets the digest/signature to an external calculated value. - * @param digest the digest. This is the actual signature - * @param RSAdata the extra data that goes into the data tag in PKCS#7 - * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest - * is also null. If the digest is not null - * then it may be "RSA" or "DSA" - */ - public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { - externalDigest = digest; - externalRSAdata = RSAdata; - this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; - } - - /** - * Gets the subject name in the signing certificate (the element "CN") - * @return the subject name in the signing certificate (the element "CN") - */ - public String getName() { - return name; - } - - /** - * Gets the class instance that does the actual signing. - * @return the class instance that does the actual signing - */ - public PdfPKCS7 getSigner() { - return pkcs; - } - - /** - * Gets the signature content. This can be a PKCS#1 or a PKCS#7. It corresponds to - * the /Contents key. - * @return the signature content - */ - public byte[] getSignerContents() { - if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) - return pkcs.getEncodedPKCS1(); - else - return pkcs.getEncodedPKCS7(); - } - - /** - * Creates a standard filter of the type VeriSign. - */ - public static class VeriSign extends PdfSigGenericPKCS { - /** - * The constructor for the default provider. - */ - public VeriSign() { - super(PdfName.VERISIGN_PPKVS, PdfName.ADBE_PKCS7_DETACHED); - hashAlgorithm = "MD5"; - put(PdfName.R, new PdfNumber(65537)); - } - - /** - * The constructor for an explicit provider. - * @param provider the crypto provider - */ - public VeriSign(String provider) { - this(); - this.provider = provider; - } - } - - /** - * Creates a standard filter of the type self signed. - */ - public static class PPKLite extends PdfSigGenericPKCS { - /** - * The constructor for the default provider. - */ - public PPKLite() { - super(PdfName.ADOBE_PPKLITE, PdfName.ADBE_X509_RSA_SHA1); - hashAlgorithm = "SHA1"; - put(PdfName.R, new PdfNumber(65541)); - } - - /** - * The constructor for an explicit provider. - * @param provider the crypto provider - */ - public PPKLite(String provider) { - this(); - this.provider = provider; - } - } - - /** - * Creates a standard filter of the type Windows Certificate. - */ - public static class PPKMS extends PdfSigGenericPKCS { - /** - * The constructor for the default provider. - */ - public PPKMS() { - super(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); - hashAlgorithm = "SHA1"; - } - - /** - * The constructor for an explicit provider. - * @param provider the crypto provider - */ - public PPKMS(String provider) { - this(); - this.provider = provider; - } - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfSignature.java b/src/main/java/com/lowagie/text/pdf/PdfSignature.java deleted file mode 100644 index 759a7ae..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfSignature.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2002 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** Implements the signature dictionary. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfSignature extends PdfDictionary { - - /** Creates new PdfSignature */ - public PdfSignature(PdfName filter, PdfName subFilter) { - super(PdfName.SIG); - put(PdfName.FILTER, filter); - put(PdfName.SUBFILTER, subFilter); - } - - public void setByteRange(int range[]) { - PdfArray array = new PdfArray(); - for (int k = 0; k < range.length; ++k) - array.add(new PdfNumber(range[k])); - put(PdfName.BYTERANGE, array); - } - - public void setContents(byte contents[]) { - put(PdfName.CONTENTS, new PdfString(contents).setHexWriting(true)); - } - - public void setCert(byte cert[]) { - put(PdfName.CERT, new PdfString(cert)); - } - - public void setName(String name) { - put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); - } - - public void setDate(PdfDate date) { - put(PdfName.M, date); - } - - public void setLocation(String name) { - put(PdfName.LOCATION, new PdfString(name, PdfObject.TEXT_UNICODE)); - } - - public void setReason(String name) { - put(PdfName.REASON, new PdfString(name, PdfObject.TEXT_UNICODE)); - } - - public void setContact(String name) { - put(PdfName.CONTACTINFO, new PdfString(name, PdfObject.TEXT_UNICODE)); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfSignatureAppearance.java b/src/main/java/com/lowagie/text/pdf/PdfSignatureAppearance.java deleted file mode 100644 index 52b186c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfSignatureAppearance.java +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Phrase; -import com.lowagie.text.Font; -import com.lowagie.text.Element; -import com.lowagie.text.Image; -import com.lowagie.text.DocumentException; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Iterator; -import java.text.SimpleDateFormat; -import java.security.cert.Certificate; -import java.security.cert.X509Certificate; -import java.security.cert.CRL; -import java.security.PrivateKey; -import java.io.OutputStream; -import java.io.IOException; -import java.io.EOFException; -import java.io.RandomAccessFile; -import java.io.File; -import java.io.InputStream; - -/** - * This class takes care of the cryptographic options and appearances that form a signature. - */ -public class PdfSignatureAppearance { - - /** - * The self signed filter. - */ - public static final PdfName SELF_SIGNED = PdfName.ADOBE_PPKLITE; - /** - * The VeriSign filter. - */ - public static final PdfName VERISIGN_SIGNED = PdfName.VERISIGN_PPKVS; - /** - * The Windows Certificate Security. - */ - public static final PdfName WINCER_SIGNED = PdfName.ADOBE_PPKMS; - - private static final float topSection = 0.3f; - private static final float margin = 2; - private Rectangle rect; - private Rectangle pageRect; - private PdfTemplate app[] = new PdfTemplate[5]; - private PdfTemplate frm; - private PdfStamperImp writer; - private String layer2Text; - private String reason; - private String location; - private Calendar signDate; - private String provider; - private int page = 1; - private String fieldName; - private PrivateKey privKey; - private Certificate[] certChain; - private CRL[] crlList; - private PdfName filter; - private boolean newField; - private ByteBuffer sigout; - private OutputStream originalout; - private File tempFile; - private PdfDictionary cryptoDictionary; - private PdfStamper stamper; - private boolean preClosed = false; - private PdfSigGenericPKCS sigStandard; - private int range[]; - private RandomAccessFile raf; - private int rangePosition = 0; - private byte bout[]; - private int boutLen; - private byte externalDigest[]; - private byte externalRSAdata[]; - private String digestEncryptionAlgorithm; - private HashMap exclusionLocations; - - PdfSignatureAppearance(PdfStamperImp writer) { - this.writer = writer; - signDate = new GregorianCalendar(); - fieldName = getNewSigName(); - } - - /** - * Sets the signature text identifying the signer. - * @param text the signature text identifying the signer. If null or not set - * a standard description will be used - */ - public void setLayer2Text(String text) { - layer2Text = text; - } - - /** - * Gets the signature text identifying the signer if set by setLayer2Text(). - * @return the signature text identifying the signer - */ - public String getLayer2Text() { - return layer2Text; - } - - /** - * Sets the text identifying the signature status. - * @param text the text identifying the signature status. If null or not set - * the description "Signature Not Verified" will be used - */ - public void setLayer4Text(String text) { - layer4Text = text; - } - - /** - * Gets the text identifying the signature status if set by setLayer4Text(). - * @return the text identifying the signature status - */ - public String getLayer4Text() { - return layer4Text; - } - - /** - * Gets the rectangle representing the signature dimensions. - * @return the rectangle representing the signature dimensions. It may be null - * or have zero width or height for invisible signatures - */ - public Rectangle getRect() { - return rect; - } - - /** - * Gets the visibility status of the signature. - * @return the visibility status of the signature - */ - public boolean isInvisible() { - return (rect == null || rect.width() == 0 || rect.height() == 0); - } - - /** - * Sets the cryptographic parameters. - * @param privKey the private key - * @param certChain the certificate chain - * @param crlList the certificate revocation list. It may be null - * @param filter the crytographic filter type. It can be SELF_SIGNED, VERISIGN_SIGNED or WINCER_SIGNED - */ - public void setCrypto(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, PdfName filter) { - this.privKey = privKey; - this.certChain = certChain; - this.crlList = crlList; - this.filter = filter; - } - - /** - * Sets the signature to be visible. It creates a new visible signature field. - * @param pageRect the position and dimension of the field in the page - * @param page the page to place the field. The fist page is 1 - * @param fieldName the field name or null to generate automatically a new field name - */ - public void setVisibleSignature(Rectangle pageRect, int page, String fieldName) { - if (fieldName != null) { - if (fieldName.indexOf('.') >= 0) - throw new IllegalArgumentException("Field names cannot contain a dot."); - AcroFields af = writer.getAcroFields(); - AcroFields.Item item = af.getFieldItem(fieldName); - if (item != null) - throw new IllegalArgumentException("The field " + fieldName + " already exists."); - this.fieldName = fieldName; - } - if (page < 1 || page > writer.reader.getNumberOfPages()) - throw new IllegalArgumentException("Invalid page number: " + page); - this.pageRect = new Rectangle(pageRect); - this.pageRect.normalize(); - rect = new Rectangle(this.pageRect.width(), this.pageRect.height()); - this.page = page; - newField = true; - } - - /** - * Sets the signature to be visible. An empty signature field with the same name must already exist. - * @param fieldName the existing empty signature field name - */ - public void setVisibleSignature(String fieldName) { - AcroFields af = writer.getAcroFields(); - AcroFields.Item item = af.getFieldItem(fieldName); - if (item == null) - throw new IllegalArgumentException("The field " + fieldName + " does not exist."); - PdfDictionary merged = (PdfDictionary)item.merged.get(0); - if (!PdfName.SIG.equals(PdfReader.getPdfObject(merged.get(PdfName.FT)))) - throw new IllegalArgumentException("The field " + fieldName + " is not a signature field."); - this.fieldName = fieldName; - PdfArray r = (PdfArray)PdfReader.getPdfObject(merged.get(PdfName.RECT)); - ArrayList ar = r.getArrayList(); - float llx = ((PdfNumber)PdfReader.getPdfObject((PdfObject)ar.get(0))).floatValue(); - float lly = ((PdfNumber)PdfReader.getPdfObject((PdfObject)ar.get(1))).floatValue(); - float urx = ((PdfNumber)PdfReader.getPdfObject((PdfObject)ar.get(2))).floatValue(); - float ury = ((PdfNumber)PdfReader.getPdfObject((PdfObject)ar.get(3))).floatValue(); - pageRect = new Rectangle(llx, lly, urx, ury); - pageRect.normalize(); - page = ((Integer)item.page.get(0)).intValue(); - int rotation = writer.reader.getPageRotation(page); - Rectangle pageSize = writer.reader.getPageSizeWithRotation(page); - switch (rotation) { - case 90: - pageRect = new Rectangle( - pageRect.bottom(), - pageSize.top() - pageRect.left(), - pageRect.top(), - pageSize.top() - pageRect.right()); - break; - case 180: - pageRect = new Rectangle( - pageSize.right() - pageRect.left(), - pageSize.top() - pageRect.bottom(), - pageSize.right() - pageRect.right(), - pageSize.top() - pageRect.top()); - break; - case 270: - pageRect = new Rectangle( - pageSize.right() - pageRect.bottom(), - pageRect.left(), - pageSize.right() - pageRect.top(), - pageRect.right()); - break; - } - if (rotation != 0) - pageRect.normalize(); - rect = new Rectangle(this.pageRect.width(), this.pageRect.height()); - } - - /** - * Gets a template layer to create a signature appearance. The layers can go from 0 to 4. - *

- * Consult PPKAppearances.pdf - * for further details. - * @param layer the layer - * @return a template - */ - public PdfTemplate getLayer(int layer) { - if (layer < 0 || layer >= app.length) - return null; - PdfTemplate t = app[layer]; - if (t == null) { - t = app[layer] = new PdfTemplate(writer); - t.setBoundingBox(rect); - writer.addDirectTemplateSimple(t, new PdfName("n" + layer)); - } - return t; - } - - /** - * Gets the template that aggregates all appearance layers. This corresponds to the /FRM resource. - *

- * Consult PPKAppearances.pdf - * for further details. - * @return the template that aggregates all appearance layers - */ - public PdfTemplate getTopLayer() { - if (frm == null) { - frm = new PdfTemplate(writer); - frm.setBoundingBox(rect); - writer.addDirectTemplateSimple(frm, new PdfName("FRM")); - } - return frm; - } - - /** - * Gets the main appearance layer. - *

- * Consult PPKAppearances.pdf - * for further details. - * @return the main appearance layer - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfTemplate getAppearance() throws DocumentException, IOException { - if (app[0] == null) { - PdfTemplate t = app[0] = new PdfTemplate(writer); - t.setBoundingBox(new Rectangle(100, 100)); - writer.addDirectTemplateSimple(t, new PdfName("n0")); - t.setLiteral("% DSBlank\n"); - } - if (app[1] == null && !acro6Layers) { - PdfTemplate t = app[1] = new PdfTemplate(writer); - t.setBoundingBox(new Rectangle(100, 100)); - writer.addDirectTemplateSimple(t, new PdfName("n1")); - t.setLiteral(questionMark); - } - if (app[2] == null) { - String text; - if (layer2Text == null) { - StringBuffer buf = new StringBuffer(); - buf.append("Digitally signed by ").append(PdfPKCS7.getSubjectFields((X509Certificate)certChain[0]).getField("CN")).append("\n"); - SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z"); - buf.append("Date: ").append(sd.format(signDate.getTime())); - if (reason != null) - buf.append("\n").append("Reason: ").append(reason); - if (location != null) - buf.append("\n").append("Location: ").append(location); - text = buf.toString(); - } - else - text = layer2Text; - PdfTemplate t = app[2] = new PdfTemplate(writer); - t.setBoundingBox(rect); - writer.addDirectTemplateSimple(t, new PdfName("n2")); - if (image != null) { - if (imageScale == 0) { - t.addImage(image, rect.width(), 0, 0, rect.height(), 0, 0); - } - else { - float usableScale = imageScale; - if (imageScale < 0) - usableScale = Math.min(rect.width() / image.width(), rect.height() / image.height()); - float w = image.width() * usableScale; - float h = image.height() * usableScale; - float x = (rect.width() - w) / 2; - float y = (rect.height() - h) / 2; - t.addImage(image, w, 0, 0, h, x, y); - } - } - Font font; - if (layer2Font == null) - font = new Font(); - else - font = new Font(layer2Font); - float size = font.size(); - if (size <= 0) { - Rectangle sr = new Rectangle(rect.width() - 2 * margin, rect.height() * (1 - topSection) - 2 * margin); - size = fitText(font, text, sr, 12, runDirection); - } - ColumnText ct = new ColumnText(t); - ct.setRunDirection(runDirection); - ct.setSimpleColumn(new Phrase(text, font), margin, 0, rect.width() - margin, rect.height() * (1 - topSection) - margin, size, Element.ALIGN_LEFT); - ct.go(); - } - if (app[3] == null && !acro6Layers) { - PdfTemplate t = app[3] = new PdfTemplate(writer); - t.setBoundingBox(new Rectangle(100, 100)); - writer.addDirectTemplateSimple(t, new PdfName("n3")); - t.setLiteral("% DSBlank\n"); - } - if (app[4] == null && !acro6Layers) { - PdfTemplate t = app[4] = new PdfTemplate(writer); - t.setBoundingBox(new Rectangle(0, rect.height() * (1 - topSection), rect.right(), rect.top())); - writer.addDirectTemplateSimple(t, new PdfName("n4")); - Font font; - if (layer2Font == null) - font = new Font(); - else - font = new Font(layer2Font); - float size = font.size(); - String text = "Signature Not Verified"; - if (layer4Text != null) - text = layer4Text; - Rectangle sr = new Rectangle(rect.width() - 2 * margin, rect.height() * topSection - 2 * margin); - size = fitText(font, text, sr, 15, runDirection); - ColumnText ct = new ColumnText(t); - ct.setRunDirection(runDirection); - ct.setSimpleColumn(new Phrase(text, font), margin, 0, rect.width() - margin, rect.height() - margin, size, Element.ALIGN_LEFT); - ct.go(); - } - int rotation = writer.reader.getPageRotation(page); - Rectangle rotated = new Rectangle(rect); - int n = rotation; - while (n > 0) { - rotated = rotated.rotate(); - n -= 90; - } - if (frm == null) { - frm = new PdfTemplate(writer); - frm.setBoundingBox(rotated); - writer.addDirectTemplateSimple(frm, new PdfName("FRM")); - float scale = Math.min(rect.width(), rect.height()) * 0.9f; - float x = (rect.width() - scale) / 2; - float y = (rect.height() - scale) / 2; - scale /= 100; - if (rotation == 90) - frm.concatCTM(0, 1, -1, 0, rect.height(), 0); - else if (rotation == 180) - frm.concatCTM(-1, 0, 0, -1, rect.width(), rect.height()); - else if (rotation == 270) - frm.concatCTM(0, -1, 1, 0, 0, rect.width()); - frm.addTemplate(app[0], 0, 0); - if (!acro6Layers) - frm.addTemplate(app[1], scale, 0, 0, scale, x, y); - frm.addTemplate(app[2], 0, 0); - if (!acro6Layers) { - frm.addTemplate(app[3], scale, 0, 0, scale, x, y); - frm.addTemplate(app[4], 0, 0); - } - } - PdfTemplate napp = new PdfTemplate(writer); - napp.setBoundingBox(rotated); - writer.addDirectTemplateSimple(napp, null); - napp.addTemplate(frm, 0, 0); - return napp; - } - - /** - * Fits the text to some rectangle adjusting the font size as needed. - * @param font the font to use - * @param text the text - * @param rect the rectangle where the text must fit - * @param maxFontSize the maximum font size - * @param runDirection the run direction - * @return the calculated font size that makes the text fit - */ - public static float fitText(Font font, String text, Rectangle rect, float maxFontSize, int runDirection) { - try { - ColumnText ct = null; - int status = 0; - if (maxFontSize <= 0) { - int cr = 0; - int lf = 0; - char t[] = text.toCharArray(); - for (int k = 0; k < t.length; ++k) { - if (t[k] == '\n') - ++lf; - else if (t[k] == '\r') - ++cr; - } - int minLines = Math.max(cr, lf) + 1; - maxFontSize = Math.abs(rect.height()) / minLines - 0.001f; - } - font.setSize(maxFontSize); - Phrase ph = new Phrase(text, font); - ct = new ColumnText(null); - ct.setSimpleColumn(ph, rect.left(), rect.bottom(), rect.right(), rect.top(), maxFontSize, Element.ALIGN_LEFT); - ct.setRunDirection(runDirection); - status = ct.go(true); - if ((status & ColumnText.NO_MORE_TEXT) != 0) - return maxFontSize; - float precision = 0.1f; - float min = 0; - float max = maxFontSize; - float size = maxFontSize; - for (int k = 0; k < 50; ++k) { //just in case it doesn't converge - size = (min + max) / 2; - ct = new ColumnText(null); - font.setSize(size); - ct.setSimpleColumn(new Phrase(text, font), rect.left(), rect.bottom(), rect.right(), rect.top(), size, Element.ALIGN_LEFT); - ct.setRunDirection(runDirection); - status = ct.go(true); - if ((status & ColumnText.NO_MORE_TEXT) != 0) { - if (max - min < size * precision) - return size; - min = size; - } - else - max = size; - } - return size; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Sets the digest/signature to an external calculated value. - * @param digest the digest. This is the actual signature - * @param RSAdata the extra data that goes into the data tag in PKCS#7 - * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest - * is also null. If the digest is not null - * then it may be "RSA" or "DSA" - */ - public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { - externalDigest = digest; - externalRSAdata = RSAdata; - this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; - } - - /** - * Gets the signing reason. - * @return the signing reason - */ - public String getReason() { - return this.reason; - } - - /** - * Sets the signing reason. - * @param reason the signing reason - */ - public void setReason(String reason) { - this.reason = reason; - } - - /** - * Gets the signing location. - * @return the signing location - */ - public String getLocation() { - return this.location; - } - - /** - * Sets the signing location. - * @param location the signing location - */ - public void setLocation(String location) { - this.location = location; - } - - /** - * Returns the Cryptographic Service Provider that will sign the document. - * @return provider the name of the provider, for example "SUN", - * or null to use the default provider. - */ - public String getProvider() { - return this.provider; - } - - /** - * Sets the Cryptographic Service Provider that will sign the document. - * - * @param provider the name of the provider, for example "SUN", or - * null to use the default provider. - */ - public void setProvider(String provider) { - this.provider = provider; - } - - /** - * Gets the private key. - * @return the private key - */ - public java.security.PrivateKey getPrivKey() { - return privKey; - } - - /** - * Gets the certificate chain. - * @return the certificate chain - */ - public java.security.cert.Certificate[] getCertChain() { - return this.certChain; - } - - /** - * Gets the certificate revocation list. - * @return the certificate revocation list - */ - public java.security.cert.CRL[] getCrlList() { - return this.crlList; - } - - /** - * Gets the filter used to sign the document. - * @return the filter used to sign the document - */ - public com.lowagie.text.pdf.PdfName getFilter() { - return filter; - } - - /** - * Checks if a new field was created. - * @return true if a new field was created, false if signing - * an existing field or if the signature is invisible - */ - public boolean isNewField() { - return this.newField; - } - - /** - * Gets the page number of the field. - * @return the page number of the field - */ - public int getPage() { - return page; - } - - /** - * Gets the field name. - * @return the field name - */ - public java.lang.String getFieldName() { - return fieldName; - } - - /** - * Gets the rectangle that represent the position and dimension of the signature in the page. - * @return the rectangle that represent the position and dimension of the signature in the page - */ - public com.lowagie.text.Rectangle getPageRect() { - return pageRect; - } - - /** - * Gets the signature date. - * @return the signature date - */ - public java.util.Calendar getSignDate() { - return signDate; - } - - /** - * Sets the signature date. - * @param signDate the signature date - */ - public void setSignDate(java.util.Calendar signDate) { - this.signDate = signDate; - } - - com.lowagie.text.pdf.ByteBuffer getSigout() { - return sigout; - } - - void setSigout(com.lowagie.text.pdf.ByteBuffer sigout) { - this.sigout = sigout; - } - - java.io.OutputStream getOriginalout() { - return originalout; - } - - void setOriginalout(java.io.OutputStream originalout) { - this.originalout = originalout; - } - - /** - * Gets the temporary file. - * @return the temporary file or null is the document is created in memory - */ - public java.io.File getTempFile() { - return tempFile; - } - - void setTempFile(java.io.File tempFile) { - this.tempFile = tempFile; - } - - /** - * Gets a new signature fied name that doesn't clash with any existing name. - * @return a new signature fied name - */ - public String getNewSigName() { - AcroFields af = writer.getAcroFields(); - String name = "Signature"; - int step = 0; - boolean found = false; - while (!found) { - ++step; - String n1 = name + step; - if (af.getFieldItem(n1) != null) - continue; - n1 += "."; - found = true; - for (Iterator it = af.getFields().keySet().iterator(); it.hasNext();) { - String fn = (String)it.next(); - if (fn.startsWith(n1)) { - found = false; - break; - } - } - } - name += step; - return name; - } - - /** - * This is the first method to be called when using external signatures. The general sequence is: - * preClose(), getDocumentBytes() and close(). - *

- * If calling preClose() dont't call PdfStamper.close(). - *

- * No external signatures are allowed if this methos is called. - * @throws IOException on error - * @throws DocumentException on error - */ - public void preClose() throws IOException, DocumentException { - preClose(null); - } - /** - * This is the first method to be called when using external signatures. The general sequence is: - * preClose(), getDocumentBytes() and close(). - *

- * If calling preClose() dont't call PdfStamper.close(). - *

- * If using an external signature exclusionSizes must contain at least - * the PdfName.CONTENTS key with the size that it will take in the - * document. Note that due to the hex string coding this size should be - * byte_size*2+2. - * @param exclusionSizes a HashMap with names and sizes to be excluded in the signature - * calculation. The key is a PdfName and the value an - * Integer. At least the PdfName.CONTENTS must be present - * @throws IOException on error - * @throws DocumentException on error - */ - public void preClose(HashMap exclusionSizes) throws IOException, DocumentException { - if (preClosed) - throw new DocumentException("Document already pre closed."); - preClosed = true; - AcroFields af = writer.getAcroFields(); - String name = getFieldName(); - boolean fieldExists = !(isInvisible() || isNewField()); - int flags = 132; - PdfIndirectReference refSig = writer.getPdfIndirectReference(); - if (fieldExists && name.indexOf('.') >= 0) { - ArrayList widgets = af.getFieldItem(name).widgets; - PdfDictionary widget = (PdfDictionary)widgets.get(0); - writer.markUsed(widget); - widget.put(PdfName.P, writer.getPageReference(getPage())); - widget.put(PdfName.V, refSig); - PdfDictionary ap = new PdfDictionary(); - ap.put(PdfName.N, getAppearance().getIndirectReference()); - widget.put(PdfName.AP, ap); - } - else { - if (fieldExists) { - flags = 0; - ArrayList merged = af.getFieldItem(name).merged; - PdfObject obj = PdfReader.getPdfObjectRelease(((PdfDictionary)merged.get(0)).get(PdfName.F)); - if (obj != null && obj.isNumber()) - flags = ((PdfNumber)obj).intValue(); - af.removeField(name); - } - writer.setSigFlags(3); - PdfFormField sigField = PdfFormField.createSignature(writer); - sigField.setFieldName(name); - sigField.put(PdfName.V, refSig); - sigField.setFlags(flags); - - int pagen = getPage(); - if (!isInvisible()) { - sigField.setWidget(getPageRect(), null); - sigField.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, getAppearance()); - } - else - sigField.setWidget(new Rectangle(0, 0), null); - sigField.setPage(pagen); - writer.addAnnotation(sigField, pagen); - } - - exclusionLocations = new HashMap(); - if (cryptoDictionary == null) { - if (PdfName.ADOBE_PPKLITE.equals(getFilter())) - sigStandard = new PdfSigGenericPKCS.PPKLite(getProvider()); - else if (PdfName.ADOBE_PPKMS.equals(getFilter())) - sigStandard = new PdfSigGenericPKCS.PPKMS(getProvider()); - else if (PdfName.VERISIGN_PPKVS.equals(getFilter())) - sigStandard = new PdfSigGenericPKCS.VeriSign(getProvider()); - else - throw new IllegalArgumentException("Unknown filter: " + getFilter()); - sigStandard.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); - if (getReason() != null) - sigStandard.setReason(getReason()); - if (getLocation() != null) - sigStandard.setLocation(getLocation()); - if (getContact() != null) - sigStandard.setContact(getContact()); - sigStandard.put(PdfName.M, new PdfDate(getSignDate())); - sigStandard.setSignInfo(getPrivKey(), getCertChain(), getCrlList()); - PdfString contents = (PdfString)sigStandard.get(PdfName.CONTENTS); - PdfLiteral lit = new PdfLiteral((contents.toString().length() + (PdfName.ADOBE_PPKLITE.equals(getFilter())?0:64)) * 2 + 2); - exclusionLocations.put(PdfName.CONTENTS, lit); - sigStandard.put(PdfName.CONTENTS, lit); - lit = new PdfLiteral(80); - exclusionLocations.put(PdfName.BYTERANGE, lit); - sigStandard.put(PdfName.BYTERANGE, lit); - if (certified) - addDocMDP(sigStandard); - if (signatureEvent != null) - signatureEvent.getSignatureDictionary(sigStandard); - writer.addToBody(sigStandard, refSig, false); - } - else { - PdfLiteral lit = new PdfLiteral(80); - exclusionLocations.put(PdfName.BYTERANGE, lit); - cryptoDictionary.put(PdfName.BYTERANGE, lit); - for (Iterator it = exclusionSizes.entrySet().iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry)it.next(); - PdfName key = (PdfName)entry.getKey(); - Integer v = (Integer)entry.getValue(); - lit = new PdfLiteral(v.intValue()); - exclusionLocations.put(key, lit); - cryptoDictionary.put(key, lit); - } - if (certified) - addDocMDP(cryptoDictionary); - if (signatureEvent != null) - signatureEvent.getSignatureDictionary(cryptoDictionary); - writer.addToBody(cryptoDictionary, refSig, false); - } - if (certified) { - // add DocMDP entry to root - PdfDictionary docmdp = new PdfDictionary(); - docmdp.put(new PdfName("DocMDP"), refSig); - writer.reader.getCatalog().put(new PdfName("Perms"), docmdp); - } - writer.close(stamper.getMoreInfo()); - - range = new int[exclusionLocations.size() * 2]; - int byteRangePosition = ((PdfLiteral)exclusionLocations.get(PdfName.BYTERANGE)).getPosition(); - exclusionLocations.remove(PdfName.BYTERANGE); - int idx = 1; - for (Iterator it = exclusionLocations.values().iterator(); it.hasNext();) { - PdfLiteral lit = (PdfLiteral)it.next(); - int n = lit.getPosition(); - range[idx++] = n; - range[idx++] = lit.getPosLength() + n; - } - Arrays.sort(range, 1, range.length - 1); - for (int k = 3; k < range.length - 2; k += 2) - range[k] -= range[k - 1]; - - if (tempFile == null) { - bout = sigout.getBuffer(); - boutLen = sigout.size(); - range[range.length - 1] = boutLen - range[range.length - 2]; - ByteBuffer bf = new ByteBuffer(); - bf.append('['); - for (int k = 0; k < range.length; ++k) - bf.append(range[k]).append(' '); - bf.append(']'); - System.arraycopy(bf.getBuffer(), 0, bout, byteRangePosition, bf.size()); - } - else { - try { - raf = new RandomAccessFile(tempFile, "rw"); - int boutLen = (int)raf.length(); - range[range.length - 1] = boutLen - range[range.length - 2]; - ByteBuffer bf = new ByteBuffer(); - bf.append('['); - for (int k = 0; k < range.length; ++k) - bf.append(range[k]).append(' '); - bf.append(']'); - raf.seek(byteRangePosition); - raf.write(bf.getBuffer(), 0, bf.size()); - } - catch (IOException e) { - try{raf.close();}catch(Exception ee){} - try{tempFile.delete();}catch(Exception ee){} - throw e; - } - } - } - - /** - * This is the last method to be called when using external signatures. The general sequence is: - * preClose(), getDocumentBytes() and close(). - *

- * update is a PdfDictionary that must have exactly the - * same keys as the ones provided in {@link #preClose(HashMap)}. - * @param update a PdfDictionary with the key/value that will fill the holes defined - * in {@link #preClose(HashMap)} - * @throws DocumentException on error - * @throws IOException on error - */ - public void close(PdfDictionary update) throws IOException, DocumentException { - try { - if (!preClosed) - throw new DocumentException("preClose() must be called first."); - ByteBuffer bf = new ByteBuffer(); - for (Iterator it = update.getKeys().iterator(); it.hasNext();) { - PdfName key = (PdfName)it.next(); - PdfObject obj = update.get(key); - PdfLiteral lit = (PdfLiteral)exclusionLocations.get(key); - if (lit == null) - throw new IllegalArgumentException("The key " + key.toString() + " didn't reserve space in preClose()."); - bf.reset(); - obj.toPdf(null, bf); - if (bf.size() > lit.getPosLength()) - throw new IllegalArgumentException("The key " + key.toString() + " is too big. Is " + bf.size() + ", reserved " + lit.getPosLength()); - if (tempFile == null) - System.arraycopy(bf.getBuffer(), 0, bout, lit.getPosition(), bf.size()); - else { - raf.seek(lit.getPosition()); - raf.write(bf.getBuffer(), 0, bf.size()); - } - } - if (update.size() != exclusionLocations.size()) - throw new IllegalArgumentException("The update dictionary has less keys than required."); - if (tempFile == null) { - originalout.write(bout, 0, boutLen); - } - else { - if (originalout != null) { - raf.seek(0); - int length = (int)raf.length(); - byte buf[] = new byte[8192]; - while (length > 0) { - int r = raf.read(buf, 0, Math.min(buf.length, length)); - if (r < 0) - throw new EOFException("Unexpected EOF"); - originalout.write(buf, 0, r); - length -= r; - } - } - } - } - finally { - if (tempFile != null) { - try{raf.close();}catch(Exception ee){} - if (originalout != null) - try{tempFile.delete();}catch(Exception ee){} - } - if (originalout != null) - try{originalout.close();}catch(Exception e){} - } - } - - private void addDocMDP(PdfDictionary crypto) { - PdfDictionary reference = new PdfDictionary(); - PdfDictionary transformParams = new PdfDictionary(); - transformParams.put(PdfName.P, new PdfNumber(1)); - transformParams.put(PdfName.V, new PdfName("1.2")); - transformParams.put(PdfName.TYPE, new PdfName("TransformParams")); - reference.put(new PdfName("TransformMethod"), new PdfName("DocMDP")); - reference.put(PdfName.TYPE, new PdfName("SigRef")); - reference.put(new PdfName("TransformParams"), transformParams); - PdfArray types = new PdfArray(); - types.add(reference); - crypto.put(new PdfName("Reference"), types); - } - - private static int indexArray(byte bout[], int position, String search) { - byte ss[] = PdfEncodings.convertToBytes(search, null); - while (true) { - int k; - for (k = 0; k < ss.length; ++k) { - if (ss[k] != bout[position + k]) - break; - } - if (k == ss.length) - return position; - ++position; - } - } - - private static int indexFile(RandomAccessFile raf, int position, String search) throws IOException { - byte ss[] = PdfEncodings.convertToBytes(search, null); - while (true) { - raf.seek(position); - int k; - for (k = 0; k < ss.length; ++k) { - int b = raf.read(); - if (b < 0) - throw new EOFException("Unexpected EOF"); - if (ss[k] != (byte)b) - break; - } - if (k == ss.length) - return position; - ++position; - } - } - - /** - * Gets the document bytes that are hashable when using external signatures. The general sequence is: - * preClose(), getRangeStream() and close(). - *

- * @return the document bytes that are hashable - */ - public InputStream getRangeStream() { - return new PdfSignatureAppearance.RangeStream(raf, bout, range); - } - - /** - * Gets the user made signature dictionary. This is the dictionary at the /V key. - * @return the user made signature dictionary - */ - public com.lowagie.text.pdf.PdfDictionary getCryptoDictionary() { - return cryptoDictionary; - } - - /** - * Sets a user made signature dictionary. This is the dictionary at the /V key. - * @param cryptoDictionary a user made signature dictionary - */ - public void setCryptoDictionary(com.lowagie.text.pdf.PdfDictionary cryptoDictionary) { - this.cryptoDictionary = cryptoDictionary; - } - - /** - * Gets the PdfStamper associated with this instance. - * @return the PdfStamper associated with this instance - */ - public com.lowagie.text.pdf.PdfStamper getStamper() { - return stamper; - } - - void setStamper(com.lowagie.text.pdf.PdfStamper stamper) { - this.stamper = stamper; - } - - /** - * Checks if the document is in the process of closing. - * @return true if the document is in the process of closing, - * false otherwise - */ - public boolean isPreClosed() { - return preClosed; - } - - /** - * Gets the instance of the standard signature dictionary. This instance - * is only available after pre close. - *

- * The main use is to insert external signatures. - * @return the instance of the standard signature dictionary - */ - public com.lowagie.text.pdf.PdfSigGenericPKCS getSigStandard() { - return sigStandard; - } - - /** - * Gets the signing contact. - * @return the signing contact - */ - public String getContact() { - return this.contact; - } - - /** - * Sets the signing contact. - * @param contact the signing contact - */ - public void setContact(String contact) { - this.contact = contact; - } - - /** - * Gets the n2 and n4 layer font. - * @return the n2 and n4 layer font - */ - public Font getLayer2Font() { - return this.layer2Font; - } - - /** - * Sets the n2 and n4 layer font. If the font size is zero, auto-fit will be used. - * @param layer2Font the n2 and n4 font - */ - public void setLayer2Font(Font layer2Font) { - this.layer2Font = layer2Font; - } - - /** - * Gets the Acrobat 6.0 layer mode. - * @return the Acrobat 6.0 layer mode - */ - public boolean isAcro6Layers() { - return this.acro6Layers; - } - - /** - * Acrobat 6.0 and higher recomends that only layer n2 and n4 be present. This method sets that mode. - * @param acro6Layers if true only the layers n2 and n4 will be present - */ - public void setAcro6Layers(boolean acro6Layers) { - this.acro6Layers = acro6Layers; - } - - /** Sets the run direction in the n2 and n4 layer. - * @param runDirection the run direction - */ - public void setRunDirection(int runDirection) { - if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) - throw new RuntimeException("Invalid run direction: " + runDirection); - this.runDirection = runDirection; - } - - /** Gets the run direction. - * @return the run direction - */ - public int getRunDirection() { - return runDirection; - } - - /** - * Getter for property signatureEvent. - * @return Value of property signatureEvent. - */ - public SignatureEvent getSignatureEvent() { - return this.signatureEvent; - } - - /** - * Sets the signature event to allow modification of the signature dictionary. - * @param signatureEvent the signature event - */ - public void setSignatureEvent(SignatureEvent signatureEvent) { - this.signatureEvent = signatureEvent; - } - - /** - * Gets the background image for the layer 2. - * @return the background image for the layer 2 - */ - public Image getImage() { - return this.image; - } - - /** - * Sets the background image for the layer 2. - * @param image the background image for the layer 2 - */ - public void setImage(Image image) { - this.image = image; - } - - /** - * Gets the scaling to be applied to the background image. - * @return the scaling to be applied to the background image - */ - public float getImageScale() { - return this.imageScale; - } - - /** - * Sets the scaling to be applied to the background image. If it's zero the image - * will fully fill the rectangle. If it's less than zero the image will fill the rectangle but - * will keep the proportions. If it's greater than zero that scaling will be applied. - * In any of the cases the image will always be centered. It's zero by default. - * @param imageScale the scaling to be applied to the background image - */ - public void setImageScale(float imageScale) { - this.imageScale = imageScale; - } - - /** - * Commands to draw a yellow question mark in a stream content - */ - public static final String questionMark = - "% DSUnknown\n" + - "q\n" + - "1 G\n" + - "1 g\n" + - "0.1 0 0 0.1 9 0 cm\n" + - "0 J 0 j 4 M []0 d\n" + - "1 i \n" + - "0 g\n" + - "313 292 m\n" + - "313 404 325 453 432 529 c\n" + - "478 561 504 597 504 645 c\n" + - "504 736 440 760 391 760 c\n" + - "286 760 271 681 265 626 c\n" + - "265 625 l\n" + - "100 625 l\n" + - "100 828 253 898 381 898 c\n" + - "451 898 679 878 679 650 c\n" + - "679 555 628 499 538 435 c\n" + - "488 399 467 376 467 292 c\n" + - "313 292 l\n" + - "h\n" + - "308 214 170 -164 re\n" + - "f\n" + - "0.44 G\n" + - "1.2 w\n" + - "1 1 0.4 rg\n" + - "287 318 m\n" + - "287 430 299 479 406 555 c\n" + - "451 587 478 623 478 671 c\n" + - "478 762 414 786 365 786 c\n" + - "260 786 245 707 239 652 c\n" + - "239 651 l\n" + - "74 651 l\n" + - "74 854 227 924 355 924 c\n" + - "425 924 653 904 653 676 c\n" + - "653 581 602 525 512 461 c\n" + - "462 425 441 402 441 318 c\n" + - "287 318 l\n" + - "h\n" + - "282 240 170 -164 re\n" + - "B\n" + - "Q\n"; - - /** - * Holds value of property contact. - */ - private String contact; - - /** - * Holds value of property layer2Font. - */ - private Font layer2Font; - - /** - * Holds value of property layer4Text. - */ - private String layer4Text; - - /** - * Holds value of property acro6Layers. - */ - private boolean acro6Layers; - - /** - * Holds value of property runDirection. - */ - private int runDirection = PdfWriter.RUN_DIRECTION_NO_BIDI; - - /** - * Holds value of property signatureEvent. - */ - private SignatureEvent signatureEvent; - - /** - * Holds value of property image. - */ - private Image image; - - /** - * Holds value of property imageScale. - */ - private float imageScale; - - /** - * - */ - private static class RangeStream extends InputStream { - private byte b[] = new byte[1]; - private RandomAccessFile raf; - private byte bout[]; - private int range[]; - private int rangePosition = 0; - - private RangeStream(RandomAccessFile raf, byte bout[], int range[]) { - this.raf = raf; - this.bout = bout; - this.range = range; - } - - /** - * @see java.io.InputStream#read() - */ - public int read() throws IOException { - int n = read(b); - if (n != 1) - return -1; - return b[0] & 0xff; - } - - /** - * @see java.io.InputStream#read(byte[], int, int) - */ - public int read(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } else if ((off < 0) || (off > b.length) || (len < 0) || - ((off + len) > b.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - if (rangePosition >= range[range.length - 2] + range[range.length - 1]) { - return -1; - } - for (int k = 0; k < range.length; k += 2) { - int start = range[k]; - int end = start + range[k + 1]; - if (rangePosition < start) - rangePosition = start; - if (rangePosition >= start && rangePosition < end) { - int lenf = Math.min(len, end - rangePosition); - if (raf == null) - System.arraycopy(bout, rangePosition, b, off, lenf); - else { - raf.seek(rangePosition); - raf.readFully(b, off, lenf); - } - rangePosition += lenf; - return lenf; - } - } - return -1; - } - } - - /** - * An interface to retrieve the signature dictionary for modification. - */ - public interface SignatureEvent { - /** - * Allows modification of the signature dictionary. - * @param sig the signature dictionary - */ - public void getSignatureDictionary(PdfDictionary sig); - } - - /** - * Holds value of property certified. - */ - private boolean certified; - - /** - * Gets the certified status of this document. - * @return the certified status - */ - public boolean isCertified() { - return this.certified; - } - - /** - * Sets the document type to certified instead of simply signed. The certified document doesn't allow any changes. - * @param certified true to certify the document, false to just apply a simple signature - */ - public void setCertified(boolean certified) { - this.certified = certified; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfSpotColor.java b/src/main/java/com/lowagie/text/pdf/PdfSpotColor.java deleted file mode 100644 index 4bb2de6..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfSpotColor.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * $Id: PdfSpotColor.java,v 1.46 2005/06/08 11:09:28 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; -import java.io.IOException; -/** - * A PdfSpotColor defines a ColorSpace - * - * @see PdfDictionary - */ - -public class PdfSpotColor{ - -/* The tint value */ - protected float tint; - -/** The color name */ - public PdfName name; - -/** The alternative color space */ - public Color altcs; - // constructors - - /** - * Constructs a new PdfSpotColor. - * - * @param name a String value - * @param tint a tint value between 0 and 1 - * @param altcs a altnative colorspace value - */ - - public PdfSpotColor(String name, float tint, Color altcs) { - this.name = new PdfName(name); - this.tint = tint; - this.altcs = altcs; - } - - /** - * Gets the tint of the SpotColor. - * @return a float - */ - public float getTint() { - return tint; - } - - /** - * Gets the alternative ColorSpace. - * @return a Colot - */ - public Color getAlternativeCS() { - return altcs; - } - - protected PdfObject getSpotObject(PdfWriter writer) throws IOException { - PdfArray array = new PdfArray(PdfName.SEPARATION); - array.add(name); - PdfFunction func = null; - if (altcs instanceof ExtendedColor) { - int type = ((ExtendedColor)altcs).type; - switch (type) { - case ExtendedColor.TYPE_GRAY: - array.add(PdfName.DEVICEGRAY); - func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{0}, new float[]{((GrayColor)altcs).getGray()}, 1); - break; - case ExtendedColor.TYPE_CMYK: - array.add(PdfName.DEVICECMYK); - CMYKColor cmyk = (CMYKColor)altcs; - func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{0, 0, 0, 0}, - new float[]{cmyk.getCyan(), cmyk.getMagenta(), cmyk.getYellow(), cmyk.getBlack()}, 1); - break; - default: - throw new RuntimeException("Only RGB, Gray and CMYK are supported as alternative color spaces."); - } - } - else { - array.add(PdfName.DEVICERGB); - func = PdfFunction.type2(writer, new float[]{0, 1}, null, new float[]{1, 1, 1}, - new float[]{(float)altcs.getRed() / 255, (float)altcs.getGreen() / 255, (float)altcs.getBlue() / 255}, 1); - } - array.add(func.getReference()); - return array; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfStamper.java b/src/main/java/com/lowagie/text/pdf/PdfStamper.java deleted file mode 100644 index f0d6eea..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfStamper.java +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright 2003, 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.security.SignatureException; -import java.io.OutputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.EOFException; -import java.io.RandomAccessFile; -import java.io.File; -import java.io.InputStream; -import com.lowagie.text.DocumentException; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.DocWriter; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Image; -import java.util.HashMap; -import java.util.List; -import java.util.Iterator; - -/** Applies extra content to the pages of a PDF document. - * This extra content can be all the objects allowed in PdfContentByte - * including pages from other Pdfs. The original PDF will keep - * all the interactive elements including bookmarks, links and form fields. - *

- * It is also possible to change the field values and to - * flatten them. New fields can be added but not flattened. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfStamper { - /** - * The writer - */ - protected PdfStamperImp stamper; - private HashMap moreInfo; - private boolean hasSignature; - private PdfSignatureAppearance sigApp; - - /** Starts the process of adding extra content to an existing PDF - * document. - * @param reader the original document. It cannot be reused - * @param os the output stream - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfStamper(PdfReader reader, OutputStream os) throws DocumentException, IOException { - stamper = new PdfStamperImp(reader, os, '\0', false); - } - - /** - * Starts the process of adding extra content to an existing PDF - * document. - * @param reader the original document. It cannot be reused - * @param os the output stream - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfStamper(PdfReader reader, OutputStream os, char pdfVersion) throws DocumentException, IOException { - stamper = new PdfStamperImp(reader, os, pdfVersion, false); - } - - /** - * Starts the process of adding extra content to an existing PDF - * document, possibly as a new revision. - * @param reader the original document. It cannot be reused - * @param os the output stream - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @param append if true appends the document changes as a new revision. This is - * only useful for multiple signatures as nothing is gained in speed or memory - * @throws DocumentException on error - * @throws IOException on error - */ - public PdfStamper(PdfReader reader, OutputStream os, char pdfVersion, boolean append) throws DocumentException, IOException { - stamper = new PdfStamperImp(reader, os, pdfVersion, append); - } - - /** Gets the optional String map to add or change values in - * the info dictionary. - * @return the map or null - * - */ - public HashMap getMoreInfo() { - return this.moreInfo; - } - - /** An optional String map to add or change values in - * the info dictionary. Entries with null - * values delete the key in the original info dictionary - * @param moreInfo additional entries to the info dictionary - * - */ - public void setMoreInfo(HashMap moreInfo) { - this.moreInfo = moreInfo; - } - - /** - * Inserts a blank page. All the pages above and including pageNumber will - * be shifted up. If pageNumber is bigger than the total number of pages - * the new page will be the last one. - * @param pageNumber the page number position where the new page will be inserted - * @param mediabox the size of the new page - */ - public void insertPage(int pageNumber, Rectangle mediabox) { - stamper.insertPage(pageNumber, mediabox); - } - - /** - * Gets the signing instance. The appearances and other parameters can the be set. - * @return the signing instance - */ - public PdfSignatureAppearance getSignatureAppearance() { - return sigApp; - } - - private String getNewSigName() { - AcroFields af = getAcroFields(); - String name = "Signature"; - int step = 0; - boolean found = false; - while (!found) { - ++step; - String n1 = name + step; - if (af.getFieldItem(n1) != null) - continue; - n1 += "."; - found = true; - for (Iterator it = af.getFields().keySet().iterator(); it.hasNext();) { - String fn = (String)it.next(); - if (fn.startsWith(n1)) { - found = false; - break; - } - } - } - name += step; - return name; - } - /** - * Closes the document. No more content can be written after the - * document is closed. - *

- * If closing a signed document with an external signature the closing must be done - * in the PdfSignatureAppearance instance. - * @throws DocumentException on error - * @throws IOException on error - */ - public void close() throws DocumentException, IOException { - if (!hasSignature) { - stamper.close(moreInfo); - return; - } - sigApp.preClose(); - PdfSigGenericPKCS sig = sigApp.getSigStandard(); - PdfLiteral lit = (PdfLiteral)sig.get(PdfName.CONTENTS); - int totalBuf = (lit.getPosLength() - 2) / 2; - byte buf[] = new byte[8192]; - int n; - InputStream inp = sigApp.getRangeStream(); - try { - while ((n = inp.read(buf)) > 0) { - sig.getSigner().update(buf, 0, n); - } - } - catch (SignatureException se) { - throw new ExceptionConverter(se); - } - buf = new byte[totalBuf]; - byte[] bsig = sig.getSignerContents(); - System.arraycopy(bsig, 0, buf, 0, bsig.length); - PdfString str = new PdfString(buf); - str.setHexWriting(true); - PdfDictionary dic = new PdfDictionary(); - dic.put(PdfName.CONTENTS, str); - sigApp.close(dic); - stamper.reader.close(); - } - - private static int indexArray(byte bout[], int position, String search) { - byte ss[] = PdfEncodings.convertToBytes(search, null); - while (true) { - int k; - for (k = 0; k < ss.length; ++k) { - if (ss[k] != bout[position + k]) - break; - } - if (k == ss.length) - return position; - ++position; - } - } - - private static int indexFile(RandomAccessFile raf, int position, String search) throws IOException { - byte ss[] = PdfEncodings.convertToBytes(search, null); - while (true) { - raf.seek(position); - int k; - for (k = 0; k < ss.length; ++k) { - int b = raf.read(); - if (b < 0) - throw new EOFException("Unexpected EOF"); - if (ss[k] != (byte)b) - break; - } - if (k == ss.length) - return position; - ++position; - } - } - - /** Gets a PdfContentByte to write under the page of - * the original document. - * @param pageNum the page number where the extra content is written - * @return a PdfContentByte to write under the page of - * the original document - */ - public PdfContentByte getUnderContent(int pageNum) { - return stamper.getUnderContent(pageNum); - } - - /** Gets a PdfContentByte to write over the page of - * the original document. - * @param pageNum the page number where the extra content is written - * @return a PdfContentByte to write over the page of - * the original document - */ - public PdfContentByte getOverContent(int pageNum) { - return stamper.getOverContent(pageNum); - } - - /** Checks if the content is automatically adjusted to compensate - * the original page rotation. - * @return the auto-rotation status - */ - public boolean isRotateContents() { - return stamper.isRotateContents(); - } - - /** Flags the content to be automatically adjusted to compensate - * the original page rotation. The default is true. - * @param rotateContents true to set auto-rotation, false - * otherwise - */ - public void setRotateContents(boolean rotateContents) { - stamper.setRotateContents(rotateContents); - } - - /** Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param strength128Bits true for 128 bit key length, false for 40 bit key length - * @throws DocumentException if anything was already written to the output - */ - public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { - if (stamper.isAppend()) - throw new DocumentException("Append mode does not support changing the encryption status."); - if (stamper.isContentWritten()) - throw new DocumentException("Content was already written to the output."); - stamper.setEncryption(userPassword, ownerPassword, permissions, strength128Bits); - } - - /** - * Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param strength true for 128 bit key length, false for 40 bit key length - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @throws DocumentException if anything was already written to the output - */ - public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { - setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength); - } - - /** Gets a page from other PDF document. Note that calling this method more than - * once with the same parameters will retrieve the same object. - * @param reader the PDF document where the page is - * @param pageNumber the page number. The first page is 1 - * @return the template representing the imported page - */ - public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { - return stamper.getImportedPage(reader, pageNumber); - } - - /** Gets the underlying PdfWriter. - * @return the underlying PdfWriter - */ - public PdfWriter getWriter() { - return stamper; - } - - /** Gets the underlying PdfReader. - * @return the underlying PdfReader - */ - public PdfReader getReader() { - return stamper.reader; - } - - /** Gets the AcroFields object that allows to get and set field values - * and to merge FDF forms. - * @return the AcroFields object - */ - public AcroFields getAcroFields() { - return stamper.getAcroFields(); - } - - /** Determines if the fields are flattened on close. The fields added with - * {@link #addAnnotation(PdfAnnotation,int)} will never be flattened. - * @param flat true to flatten the fields, false - * to keep the fields - */ - public void setFormFlattening(boolean flat) { - stamper.setFormFlattening(flat); - } - - /** Determines if the FreeText annotations are flattened on close. - * @param flat true to flatten the FreeText annotations, false - * (the default) to keep the FreeText annotations as active content. - */ - public void setFreeTextFlattening(boolean flat) { - stamper.setFreeTextFlattening(flat); - } - - /** - * Adds an annotation of form field in a specific page. This page number - * can be overridden with {@link PdfAnnotation#setPlaceInPage(int)}. - * @param annot the annotation - * @param page the page - */ - public void addAnnotation(PdfAnnotation annot, int page) { - stamper.addAnnotation(annot, page); - } - - /** - * Adds the comments present in an FDF file. - * @param fdf the FDF file - * @throws IOException on error - */ - public void addComments(FdfReader fdf) throws IOException { - stamper.addComments(fdf); - } - - /** - * Sets the bookmarks. The list structure is defined in - * {@link SimpleBookmark}. - * @param outlines the bookmarks or null to remove any - * @throws IOException on error - */ - public void setOutlines(List outlines) throws IOException { - stamper.setOutlines(outlines); - } - - /** - * Sets the thumbnail image for a page. - * @param image the image - * @param page the page - * @throws PdfException on error - * @throws DocumentException on error - */ - public void setThumbnail(Image image, int page) throws PdfException, DocumentException { - stamper.setThumbnail(image, page); - } - - /** - * Adds name to the list of fields that will be flattened on close, - * all the other fields will remain. If this method is never called or is called - * with invalid field names, all the fields will be flattened. - *

- * Calling setFormFlattening(true) is needed to have any kind of - * flattening. - * @param name the field name - * @return true if the field exists, false otherwise - */ - public boolean partialFormFlattening(String name) { - return stamper.partialFormFlattening(name); - } - - /** Adds a JavaScript action at the document level. When the document - * opens all this JavaScript runs. The existing JavaScript will be replaced. - * @param js the JavaScript code - */ - public void addJavaScript(String js) { - stamper.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js)); - } - - /** Adds a file attachment at the document level. Existing attachments will be kept. - * @param description the file description - * @param fileStore an array with the file. If it's null - * the file will be read from the disk - * @param file the path to the file. It will only be used if - * fileStore is not null - * @param fileDisplay the actual file name stored in the pdf - * @throws IOException on error - */ - public void addFileAttachment(String description, byte fileStore[], String file, String fileDisplay) throws IOException { - addFileAttachment(description, PdfFileSpecification.fileEmbedded(stamper, file, fileDisplay, fileStore)); - } - - /** Adds a file attachment at the document level. Existing attachments will be kept. - * @param description the file description - * @param fs the file specification - */ - public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { - stamper.addFileAttachment(description, fs); - } - - /** - * Sets the viewer preferences. - * @param preferences the viewer preferences - * @see PdfWriter#setViewerPreferences(int) - */ - public void setViewerPreferences(int preferences) { - stamper.setViewerPreferences(preferences); - } - - /** - * Sets the XMP metadata. - * @param xmp - * @see PdfWriter#setXmpMetadata(byte[]) - */ - public void setXmpMetadata(byte[] xmp) { - stamper.setXmpMetadata(xmp); - } - - /** - * Gets the 1.5 compression status. - * @return true if the 1.5 compression is on - */ - public boolean isFullCompression() { - return stamper.isFullCompression(); - } - - /** - * Sets the document's compression to the new 1.5 mode with object streams and xref - * streams. It can be set at any time but once set it can't be unset. - */ - public void setFullCompression() { - if (stamper.isAppend()) - return; - stamper.setFullCompression(); - } - - /** - * Sets the open and close page additional action. - * @param actionType the action type. It can be PdfWriter.PAGE_OPEN - * or PdfWriter.PAGE_CLOSE - * @param action the action to perform - * @param page the page where the action will be applied. The first page is 1 - * @throws PdfException if the action type is invalid - */ - public void setPageAction(PdfName actionType, PdfAction action, int page) throws PdfException { - stamper.setPageAction(actionType, action, page); - } - - /** - * Sets the display duration for the page (for presentations) - * @param seconds the number of seconds to display the page. A negative value removes the entry - * @param page the page where the duration will be applied. The first page is 1 - */ - public void setDuration(int seconds, int page) { - stamper.setDuration(seconds, page); - } - - /** - * Sets the transition for the page - * @param transition the transition object. A null removes the transition - * @param page the page where the transition will be applied. The first page is 1 - */ - public void setTransition(PdfTransition transition, int page) { - stamper.setTransition(transition, page); - } - - /** - * Applies a digital signature to a document, possibly as a new revision, making - * possible multiple signatures. The returned PdfStamper - * can be used normally as the signature is only applied when closing. - *

- * A possible use for adding a signature without invalidating an existing one is: - *

- *

-     * KeyStore ks = KeyStore.getInstance("pkcs12");
-     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
-     * String alias = (String)ks.aliases().nextElement();
-     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
-     * Certificate[] chain = ks.getCertificateChain(alias);
-     * PdfReader reader = new PdfReader("original.pdf");
-     * FileOutputStream fout = new FileOutputStream("signed.pdf");
-     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new
-     * File("/temp"), true);
-     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
-     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
-     * sap.setReason("I'm the author");
-     * sap.setLocation("Lisbon");
-     * // comment next line to have an invisible signature
-     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
-     * stp.close();
-     * 
- * @param reader the original document - * @param os the output stream or null to keep the document in the temporary file - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there. - * If it's a file it will be used directly. The file will be deleted on exit unless os is null. - * In that case the document can be retrieved directly from the temporary file. If it's null - * no temporary file will be created and memory will be used - * @param append if true the signature and all the other content will be added as a - * new revision thus not invalidating existing signatures - * @return a PdfStamper - * @throws DocumentException on error - * @throws IOException on error - */ - public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion, File tempFile, boolean append) throws DocumentException, IOException { - PdfStamper stp; - if (tempFile == null) { - ByteBuffer bout = new ByteBuffer(); - stp = new PdfStamper(reader, bout, pdfVersion, append); - stp.sigApp = new PdfSignatureAppearance(stp.stamper); - stp.sigApp.setSigout(bout); - } - else { - if (tempFile.isDirectory()) - tempFile = File.createTempFile("pdf", null, tempFile); - FileOutputStream fout = new FileOutputStream(tempFile); - stp = new PdfStamper(reader, fout, pdfVersion, append); - stp.sigApp = new PdfSignatureAppearance(stp.stamper); - stp.sigApp.setTempFile(tempFile); - } - stp.sigApp.setOriginalout(os); - stp.sigApp.setStamper(stp); - stp.hasSignature = true; - return stp; - } - - /** - * Applies a digital signature to a document. The returned PdfStamper - * can be used normally as the signature is only applied when closing. - *

- * Note that the pdf is created in memory. - *

- * A possible use is: - *

- *

-     * KeyStore ks = KeyStore.getInstance("pkcs12");
-     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
-     * String alias = (String)ks.aliases().nextElement();
-     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
-     * Certificate[] chain = ks.getCertificateChain(alias);
-     * PdfReader reader = new PdfReader("original.pdf");
-     * FileOutputStream fout = new FileOutputStream("signed.pdf");
-     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
-     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
-     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
-     * sap.setReason("I'm the author");
-     * sap.setLocation("Lisbon");
-     * // comment next line to have an invisible signature
-     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
-     * stp.close();
-     * 
- * @param reader the original document - * @param os the output stream - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @throws DocumentException on error - * @throws IOException on error - * @return a PdfStamper - */ - public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion) throws DocumentException, IOException { - return createSignature(reader, os, pdfVersion, null, false); - } - - /** - * Applies a digital signature to a document. The returned PdfStamper - * can be used normally as the signature is only applied when closing. - *

- * A possible use is: - *

- *

-     * KeyStore ks = KeyStore.getInstance("pkcs12");
-     * ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
-     * String alias = (String)ks.aliases().nextElement();
-     * PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
-     * Certificate[] chain = ks.getCertificateChain(alias);
-     * PdfReader reader = new PdfReader("original.pdf");
-     * FileOutputStream fout = new FileOutputStream("signed.pdf");
-     * PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new File("/temp"));
-     * PdfSignatureAppearance sap = stp.getSignatureAppearance();
-     * sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
-     * sap.setReason("I'm the author");
-     * sap.setLocation("Lisbon");
-     * // comment next line to have an invisible signature
-     * sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
-     * stp.close();
-     * 
- * @param reader the original document - * @param os the output stream or null to keep the document in the temporary file - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @param tempFile location of the temporary file. If it's a directory a temporary file will be created there. - * If it's a file it will be used directly. The file will be deleted on exit unless os is null. - * In that case the document can be retrieved directly from the temporary file. If it's null - * no temporary file will be created and memory will be used - * @return a PdfStamper - * @throws DocumentException on error - * @throws IOException on error - */ - public static PdfStamper createSignature(PdfReader reader, OutputStream os, char pdfVersion, File tempFile) throws DocumentException, IOException - { - return createSignature(reader, os, pdfVersion, tempFile, false); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfStamperImp.java b/src/main/java/com/lowagie/text/pdf/PdfStamperImp.java deleted file mode 100644 index 7a36cf6..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfStamperImp.java +++ /dev/null @@ -1,1461 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -import com.lowagie.text.DocumentException; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Image; -import com.lowagie.text.ExceptionConverter; - -// wprinz: had to change this to public, as we want to explicitely mark something as USED. -public class PdfStamperImp extends PdfWriter { - HashMap readers2intrefs = new HashMap(); - HashMap readers2file = new HashMap(); - RandomAccessFileOrArray file; - PdfReader reader; - IntHashtable myXref = new IntHashtable(); - /** Integer(page number) -> PageStamp */ - HashMap pagesToContent = new HashMap(); - boolean closed = false; - /** Holds value of property rotateContents. */ - private boolean rotateContents = true; - protected AcroFields acroFields; - protected boolean flat = false; - protected boolean flatFreeText = false; - protected int namePtr[] = {0}; - protected boolean namedAsNames; - protected List newBookmarks; - protected HashSet partialFlattening = new HashSet(); - protected boolean useVp = false; - protected int vp = 0; - protected HashMap fieldTemplates = new HashMap(); - protected boolean fieldsAdded = false; - protected int sigFlags = 0; - protected boolean append; - protected IntHashtable marked; - protected int initialXrefSize; - protected PdfAction openAction; - - // egiz code: - protected PdfName egiz_dict_name = null; - protected PdfIndirectReference egiz_dict_ir = null; - /** - * Sets the key and the contents of the entry to be added to the trailer if an egiz dict is present. - * @param name The name of the egiz dict in the trailer. - * @param ir The indirect reference of the egiz dict. - */ - public void setEgizDictTrailerInfo(PdfName name, PdfIndirectReference ir) - { - this.egiz_dict_name = name; - this.egiz_dict_ir = ir; - } - // end egiz code; - - - /** Creates new PdfStamperImp. - * @param reader the read PDF - * @param os the output destination - * @param pdfVersion the new pdf version or '\0' to keep the same version as the original - * document - * @param append - * @throws DocumentException on error - * @throws IOException - */ - PdfStamperImp(PdfReader reader, OutputStream os, char pdfVersion, boolean append) throws DocumentException, IOException { - super(new PdfDocument(), os); - if (reader.isTampered()) - throw new DocumentException("The original document was reused. Read it again from file."); - reader.setTampered(true); - this.reader = reader; - file = reader.getSafeFile(); - this.append = append; - if (append) { - if (reader.isRebuilt()) - throw new DocumentException("Append mode requires a document without errors even if recovery was possible."); - if (reader.isEncrypted()) - crypto = new PdfEncryption(reader.getDecrypt()); - HEADER = getISOBytes("\n"); - file.reOpen(); - byte buf[] = new byte[8192]; - int n; - while ((n = file.read(buf)) > 0) - this.os.write(buf, 0, n); - file.close(); - prevxref = reader.getLastXref(); - reader.setAppendable(true); - } - else { - if (pdfVersion == 0) - super.setPdfVersion(reader.getPdfVersion()); - else - super.setPdfVersion(pdfVersion); - } - super.open(); - pdf.addWriter(this); - if (append) { - body.setRefnum(reader.getXrefSize()); - marked = new IntHashtable(); - if (reader.isNewXrefType()) - fullCompression = true; - if (reader.isHybridXref()) - fullCompression = false; - } - initialXrefSize = reader.getXrefSize(); - } - - void close(HashMap moreInfo) throws DocumentException, IOException { - if (closed) - return; - if (useVp) { - reader.setViewerPreferences(vp); - markUsed(reader.getTrailer().get(PdfName.ROOT)); - } - if (flat) - flatFields(); - if (flatFreeText) - flatFreeTextFields(); - addFieldResources(); - if (sigFlags != 0) { - PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM), reader.getCatalog()); - if (acroForm != null) { - acroForm.put(PdfName.SIGFLAGS, new PdfNumber(sigFlags)); - markUsed(acroForm); - } - } - closed = true; - addSharedObjectsToBody(); - setOutlines(); - setJavaScript(); - addFileAttachments(); - if (openAction != null) { - reader.getCatalog().put(PdfName.OPENACTION, openAction); - } - // if there is XMP data to add: add it - if (xmpMetadata != null) { - PdfDictionary catalog = reader.getCatalog(); - PdfStream xmp = new PdfStream(xmpMetadata); - xmp.put(PdfName.TYPE, PdfName.METADATA); - xmp.put(PdfName.SUBTYPE, PdfName.XML); - catalog.put(PdfName.METADATA, body.add(xmp).getIndirectReference()); - markUsed(catalog); - } - PRIndirectReference iInfo = null; - try { - file.reOpen(); - alterContents(); - iInfo = (PRIndirectReference)reader.trailer.get(PdfName.INFO); - int skip = -1; - if (iInfo != null) - skip = iInfo.getNumber(); - int rootN = ((PRIndirectReference)reader.trailer.get(PdfName.ROOT)).getNumber(); - if (append) { - int keys[] = marked.getKeys(); - for (int k = 0; k < keys.length; ++k) { - int j = keys[k]; - PdfObject obj = reader.getPdfObjectRelease(j); - if (obj != null && skip != j && j < initialXrefSize) { - addToBody(obj, j, j != rootN); - } - } - for (int k = initialXrefSize; k < reader.getXrefSize(); ++k) { - PdfObject obj = reader.getPdfObject(k); - if (obj != null) { - addToBody(obj, getNewObjectNumber(reader, k, 0)); - } - } - } - else { - for (int k = 1; k < reader.getXrefSize(); ++k) { - PdfObject obj = reader.getPdfObjectRelease(k); - if (obj != null && skip != k) { - addToBody(obj, getNewObjectNumber(reader, k, 0), k != rootN); - } - } - } - } - finally { - try { - file.close(); - } - catch (Exception e) { - // empty on purpose - } - } - PdfIndirectReference encryption = null; - PdfObject fileID = null; - if (crypto != null) { - if (append) { - encryption = reader.getCryptoRef(); - } - else { - PdfIndirectObject encryptionObject = addToBody(crypto.getEncryptionDictionary(), false); - encryption = encryptionObject.getIndirectReference(); - } - fileID = crypto.getFileID(); - } - PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.get(PdfName.ROOT); - PdfIndirectReference root = new PdfIndirectReference(0, getNewObjectNumber(reader, iRoot.getNumber(), 0)); - PdfIndirectReference info = null; - PdfDictionary oldInfo = (PdfDictionary)PdfReader.getPdfObject(iInfo); - PdfDictionary newInfo = new PdfDictionary(); - if (oldInfo != null) { - for (Iterator i = oldInfo.getKeys().iterator(); i.hasNext();) { - PdfName key = (PdfName)i.next(); - PdfObject value = PdfReader.getPdfObject(oldInfo.get(key)); - newInfo.put(key, value); - } - } - if (moreInfo != null) { - for (Iterator i = moreInfo.keySet().iterator(); i.hasNext();) { - String key = (String)i.next(); - PdfName keyName = new PdfName(key); - String value = (String)moreInfo.get(key); - if (value == null) - newInfo.remove(keyName); - else - newInfo.put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE)); - } - } - if (append) { - if (iInfo == null) - info = addToBody(newInfo, false).getIndirectReference(); - else - info = addToBody(newInfo, iInfo.getNumber(), false).getIndirectReference(); - } - else { - if (!newInfo.getKeys().isEmpty()) - info = addToBody(newInfo, false).getIndirectReference(); - } - // write the cross-reference table of the body - body.writeCrossReferenceTable(os, root, info, encryption, fileID, prevxref); - if (fullCompression) { - os.write(getISOBytes("startxref\n")); - os.write(getISOBytes(String.valueOf(body.offset()))); - os.write(getISOBytes("\n%%EOF\n")); - } - else { - PdfTrailer trailer = new PdfTrailer(body.size(), - body.offset(), - root, - info, - encryption, - fileID, prevxref); - // EGIZ code - add EGIZ dict to trailer) - if (this.egiz_dict_name != null) - { - trailer.put(this.egiz_dict_name, this.egiz_dict_ir); - } - // endo of egiz code. - trailer.toPdf(this, os); - } - os.flush(); - if (isCloseStream()) - os.close(); - reader.close(); - } - - void applyRotation(PdfDictionary pageN, ByteBuffer out) { - if (!rotateContents) - return; - Rectangle page = reader.getPageSizeWithRotation(pageN); - int rotation = page.getRotation(); - switch (rotation) { - case 90: - out.append(PdfContents.ROTATE90); - out.append(page.top()); - out.append(' ').append('0').append(PdfContents.ROTATEFINAL); - break; - case 180: - out.append(PdfContents.ROTATE180); - out.append(page.right()); - out.append(' '); - out.append(page.top()); - out.append(PdfContents.ROTATEFINAL); - break; - case 270: - out.append(PdfContents.ROTATE270); - out.append('0').append(' '); - out.append(page.right()); - out.append(PdfContents.ROTATEFINAL); - break; - } - } - - void alterContents() throws IOException { - for (Iterator i = pagesToContent.values().iterator(); i.hasNext();) { - PageStamp ps = (PageStamp)i.next(); - PdfDictionary pageN = ps.pageN; - markUsed(pageN); - PdfArray ar = null; - PdfObject content = PdfReader.getPdfObject(pageN.get(PdfName.CONTENTS), pageN); - if (content == null) { - ar = new PdfArray(); - pageN.put(PdfName.CONTENTS, ar); - } - else if (content.isArray()) { - ar = (PdfArray)content; - markUsed(ar); - } - else if (content.isStream()) { - ar = new PdfArray(); - ar.add(pageN.get(PdfName.CONTENTS)); - pageN.put(PdfName.CONTENTS, ar); - } - else { - ar = new PdfArray(); - pageN.put(PdfName.CONTENTS, ar); - } - ByteBuffer out = new ByteBuffer(); - if (ps.under != null) { - out.append(PdfContents.SAVESTATE); - applyRotation(pageN, out); - out.append(ps.under.getInternalBuffer()); - out.append(PdfContents.RESTORESTATE); - } - if (ps.over != null) - out.append(PdfContents.SAVESTATE); - PdfStream stream = new PdfStream(out.toByteArray()); - try{stream.flateCompress();}catch(Exception e){throw new ExceptionConverter(e);} - ar.addFirst(addToBody(stream).getIndirectReference()); - out.reset(); - if (ps.over != null) { - out.append(' '); - out.append(PdfContents.RESTORESTATE); - out.append(PdfContents.SAVESTATE); - applyRotation(pageN, out); - out.append(ps.over.getInternalBuffer()); - out.append(PdfContents.RESTORESTATE); - stream = new PdfStream(out.toByteArray()); - try{stream.flateCompress();}catch(Exception e){throw new ExceptionConverter(e);} - ar.add(addToBody(stream).getIndirectReference()); - } - alterResources(ps); - } - } - - void alterResources(PageStamp ps) { - ps.pageN.put(PdfName.RESOURCES, ps.pageResources.getResources()); - } - - protected int getNewObjectNumber(PdfReader reader, int number, int generation) { - IntHashtable ref = (IntHashtable)readers2intrefs.get(reader); - if (ref != null) { - int n = ref.get(number); - if (n == 0) { - n = getIndirectReferenceNumber(); - ref.put(number, n); - } - return n; - } - if (currentPdfReaderInstance == null) { - if (append && number < initialXrefSize) - return number; - int n = myXref.get(number); - if (n == 0) { - n = getIndirectReferenceNumber(); - myXref.put(number, n); - } - return n; - } - else - return currentPdfReaderInstance.getNewObjectNumber(number, generation); - } - - RandomAccessFileOrArray getReaderFile(PdfReader reader) { - if (readers2intrefs.containsKey(reader)) { - RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file.get(reader); - if (raf != null) - return raf; - return reader.getSafeFile(); - } - if (currentPdfReaderInstance == null) - return file; - else - return currentPdfReaderInstance.getReaderFile(); - } - - /** - * @param reader - * @param openFile - * @throws IOException - */ - public void registerReader(PdfReader reader, boolean openFile) throws IOException { - if (readers2intrefs.containsKey(reader)) - return; - readers2intrefs.put(reader, new IntHashtable()); - if (openFile) { - RandomAccessFileOrArray raf = reader.getSafeFile(); - readers2file.put(reader, raf); - raf.reOpen(); - } - } - - /** - * @param reader - */ - public void unRegisterReader(PdfReader reader) { - if (!readers2intrefs.containsKey(reader)) - return; - readers2intrefs.remove(reader); - RandomAccessFileOrArray raf = (RandomAccessFileOrArray)readers2file.get(reader); - if (raf == null) - return; - readers2file.remove(reader); - try{raf.close();}catch(Exception e){} - } - - static void findAllObjects(PdfReader reader, PdfObject obj, IntHashtable hits) { - if (obj == null) - return; - switch (obj.type()) { - case PdfObject.INDIRECT: - PRIndirectReference iref = (PRIndirectReference)obj; - if (reader != iref.getReader()) - return; - if (hits.containsKey(iref.getNumber())) - return; - hits.put(iref.getNumber(), 1); - findAllObjects(reader, PdfReader.getPdfObject(obj), hits); - return; - case PdfObject.ARRAY: - ArrayList lst = ((PdfArray)obj).getArrayList(); - for (int k = 0; k < lst.size(); ++k) { - findAllObjects(reader, (PdfObject)lst.get(k), hits); - } - return; - case PdfObject.DICTIONARY: - case PdfObject.STREAM: - PdfDictionary dic = (PdfDictionary)obj; - for (Iterator it = dic.getKeys().iterator(); it.hasNext();) { - PdfName name = (PdfName)it.next(); - findAllObjects(reader, dic.get(name), hits); - } - return; - } - } - - /** - * @param fdf - * @throws IOException - */ - public void addComments(FdfReader fdf) throws IOException{ - if (readers2intrefs.containsKey(fdf)) - return; - PdfDictionary catalog = fdf.getCatalog(); - catalog = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.FDF)); - if (catalog == null) - return; - PdfArray annots = (PdfArray)PdfReader.getPdfObject(catalog.get(PdfName.ANNOTS)); - if (annots == null || annots.size() == 0) - return; - registerReader(fdf, false); - IntHashtable hits = new IntHashtable(); - HashMap irt = new HashMap(); - ArrayList an = new ArrayList(); - ArrayList ar = annots.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - PdfObject obj = (PdfObject)ar.get(k); - PdfDictionary annot = (PdfDictionary)PdfReader.getPdfObject(obj); - PdfNumber page = (PdfNumber)PdfReader.getPdfObject(annot.get(PdfName.PAGE)); - if (page == null || page.intValue() >= reader.getNumberOfPages()) - continue; - findAllObjects(fdf, obj, hits); - an.add(obj); - if (obj.type() == PdfObject.INDIRECT) { - PdfObject nm = PdfReader.getPdfObject(annot.get(PdfName.NM)); - if (nm != null && nm.type() == PdfObject.STRING) - irt.put(nm.toString(), obj); - } - } - int arhits[] = hits.getKeys(); - for (int k = 0; k < arhits.length; ++k) { - int n = arhits[k]; - PdfObject obj = fdf.getPdfObject(n); - if (obj.type() == PdfObject.DICTIONARY) { - PdfObject str = PdfReader.getPdfObject(((PdfDictionary)obj).get(PdfName.IRT)); - if (str != null && str.type() == PdfObject.STRING) { - PdfObject i = (PdfObject)irt.get(str.toString()); - if (i != null) { - PdfDictionary dic2 = new PdfDictionary(); - dic2.merge((PdfDictionary)obj); - dic2.put(PdfName.IRT, i); - obj = dic2; - } - } - } - addToBody(obj, getNewObjectNumber(fdf, n, 0)); - } - for (int k = 0; k < an.size(); ++k) { - PdfObject obj = (PdfObject)an.get(k); - PdfDictionary annot = (PdfDictionary)PdfReader.getPdfObject(obj); - PdfNumber page = (PdfNumber)PdfReader.getPdfObject(annot.get(PdfName.PAGE)); - PdfDictionary dic = reader.getPageN(page.intValue() + 1); - PdfArray annotsp = (PdfArray)PdfReader.getPdfObject(dic.get(PdfName.ANNOTS), dic); - if (annotsp == null) { - annotsp = new PdfArray(); - dic.put(PdfName.ANNOTS, annotsp); - markUsed(dic); - } - markUsed(annotsp); - annotsp.add(obj); - } - } - - PageStamp getPageStamp(int pageNum) { - PdfDictionary pageN = reader.getPageN(pageNum); - PageStamp ps = (PageStamp)pagesToContent.get(pageN); - if (ps == null) { - ps = new PageStamp(this, reader, pageN); - pagesToContent.put(pageN, ps); - } - return ps; - } - - PdfContentByte getUnderContent(int pageNum) { - if (pageNum < 1 || pageNum > reader.getNumberOfPages()) - return null; - PageStamp ps = getPageStamp(pageNum); - if (ps.under == null) - ps.under = new StampContent(this, ps); - return ps.under; - } - - PdfContentByte getOverContent(int pageNum) { - if (pageNum < 1 || pageNum > reader.getNumberOfPages()) - return null; - PageStamp ps = getPageStamp(pageNum); - if (ps.over == null) - ps.over = new StampContent(this, ps); - return ps.over; - } - - void correctAcroFieldPages(int page) { - if (acroFields == null) - return; - if (page > reader.getNumberOfPages()) - return; - HashMap fields = acroFields.getFields(); - for (Iterator it = fields.values().iterator(); it.hasNext();) { - AcroFields.Item item = (AcroFields.Item)it.next(); - ArrayList pages = item.page; - for (int k = 0; k < pages.size(); ++k) { - int p = ((Integer)pages.get(k)).intValue(); - if (p >= page) - pages.set(k, new Integer(p + 1)); - } - } - } - - void insertPage(int pageNumber, Rectangle mediabox) { - Rectangle media = new Rectangle(mediabox); - int rotation = media.getRotation() % 360; - PdfDictionary page = new PdfDictionary(PdfName.PAGE); - PdfDictionary resources = new PdfDictionary(); - PdfArray procset = new PdfArray(); - procset.add(PdfName.PDF); - procset.add(PdfName.TEXT); - procset.add(PdfName.IMAGEB); - procset.add(PdfName.IMAGEC); - procset.add(PdfName.IMAGEI); - resources.put(PdfName.PROCSET, procset); - page.put(PdfName.RESOURCES, resources); - page.put(PdfName.ROTATE, new PdfNumber(rotation)); - page.put(PdfName.MEDIABOX, new PdfRectangle(media, rotation)); - PRIndirectReference pref = reader.addPdfObject(page); - PdfDictionary parent; - PRIndirectReference parentRef; - if (pageNumber > reader.getNumberOfPages()) { - PdfDictionary lastPage = reader.getPageNRelease(reader.getNumberOfPages()); - parentRef = (PRIndirectReference)lastPage.get(PdfName.PARENT); - parentRef = new PRIndirectReference(reader, parentRef.getNumber()); - parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); - PdfArray kids = (PdfArray)PdfReader.getPdfObject(parent.get(PdfName.KIDS), parent); - kids.add(pref); - markUsed(kids); - reader.pageRefs.insertPage(pageNumber, pref); - } - else { - if (pageNumber < 1) - pageNumber = 1; - PdfDictionary firstPage = reader.getPageN(pageNumber); - PRIndirectReference firstPageRef = reader.getPageOrigRef(pageNumber); - reader.releasePage(pageNumber); - parentRef = (PRIndirectReference)firstPage.get(PdfName.PARENT); - parentRef = new PRIndirectReference(reader, parentRef.getNumber()); - parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); - PdfArray kids = (PdfArray)PdfReader.getPdfObject(parent.get(PdfName.KIDS), parent); - ArrayList ar = kids.getArrayList(); - int len = ar.size(); - int num = firstPageRef.getNumber(); - for (int k = 0; k < len; ++k) { - PRIndirectReference cur = (PRIndirectReference)ar.get(k); - if (num == cur.getNumber()) { - ar.add(k, pref); - break; - } - } - if (len == ar.size()) - throw new RuntimeException("Internal inconsistence."); - markUsed(kids); - reader.pageRefs.insertPage(pageNumber, pref); - correctAcroFieldPages(pageNumber); - } - page.put(PdfName.PARENT, parentRef); - while (parent != null) { - markUsed(parent); - PdfNumber count = (PdfNumber)PdfReader.getPdfObjectRelease(parent.get(PdfName.COUNT)); - parent.put(PdfName.COUNT, new PdfNumber(count.intValue() + 1)); - parent = (PdfDictionary)PdfReader.getPdfObject(parent.get(PdfName.PARENT)); - } - } - - /** Getter for property rotateContents. - * @return Value of property rotateContents. - * - */ - boolean isRotateContents() { - return this.rotateContents; - } - - /** Setter for property rotateContents. - * @param rotateContents New value of property rotateContents. - * - */ - void setRotateContents(boolean rotateContents) { - this.rotateContents = rotateContents; - } - - boolean isContentWritten() { - return body.size() > 1; - } - - AcroFields getAcroFields() { - if (acroFields == null) { - acroFields = new AcroFields(reader, this); - } - return acroFields; - } - - void setFormFlattening(boolean flat) { - this.flat = flat; - } - - void setFreeTextFlattening(boolean flat) { - this.flatFreeText = flat; - } - - boolean partialFormFlattening(String name) { - getAcroFields(); - if (!acroFields.getFields().containsKey(name)) - return false; - partialFlattening.add(name); - return true; - } - - void flatFields() { - if (append) - throw new IllegalArgumentException("Field flattening is not supported in append mode."); - getAcroFields(); - HashMap fields = acroFields.getFields(); - if (fieldsAdded && partialFlattening.isEmpty()) { - for (Iterator i = fields.keySet().iterator(); i.hasNext();) { - partialFlattening.add(i.next()); - } - } - PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.ACROFORM)); - ArrayList acroFds = null; - if (acroForm != null) { - PdfArray array = (PdfArray)PdfReader.getPdfObject(acroForm.get(PdfName.FIELDS), acroForm); - if (array != null) - acroFds = array.getArrayList(); - } - for (Iterator i = fields.keySet().iterator(); i.hasNext();) { - String name = (String)i.next(); - if (!partialFlattening.isEmpty() && !partialFlattening.contains(name)) - continue; - AcroFields.Item item = (AcroFields.Item)fields.get(name); - for (int k = 0; k < item.merged.size(); ++k) { - PdfDictionary merged = (PdfDictionary)item.merged.get(k); - PdfNumber ff = (PdfNumber)PdfReader.getPdfObject(merged.get(PdfName.F)); - int flags = 0; - if (ff != null) - flags = ff.intValue(); - int page = ((Integer)item.page.get(k)).intValue(); - PdfDictionary appDic = (PdfDictionary)PdfReader.getPdfObject(merged.get(PdfName.AP)); - if (appDic != null && (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) { - PdfObject obj = appDic.get(PdfName.N); - PdfAppearance app = null; - if (obj != null) { - PdfObject objReal = PdfReader.getPdfObject(obj); - if (obj instanceof PdfIndirectReference && !obj.isIndirect()) - app = new PdfAppearance((PdfIndirectReference)obj); - else if (objReal instanceof PdfStream) { - ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); - app = new PdfAppearance((PdfIndirectReference)obj); - } - else { - if (objReal.isDictionary()) { - PdfName as = (PdfName)PdfReader.getPdfObject(merged.get(PdfName.AS)); - if (as != null) { - PdfIndirectReference iref = (PdfIndirectReference)((PdfDictionary)objReal).get(as); - if (iref != null) { - app = new PdfAppearance(iref); - if (iref.isIndirect()) { - objReal = PdfReader.getPdfObject(iref); - ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); - } - } - } - } - } - } - if (app != null) { - Rectangle box = PdfReader.getNormalizedRectangle((PdfArray)PdfReader.getPdfObject(merged.get(PdfName.RECT))); - PdfContentByte cb = getOverContent(page); - cb.setLiteral("Q "); - cb.addTemplate(app, box.left(), box.bottom()); - cb.setLiteral("q "); - } - } - if (partialFlattening.isEmpty()) - continue; - PdfDictionary pageDic = reader.getPageN(page); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS)); - if (annots == null) - continue; - ArrayList ar = annots.getArrayList(); - for (int idx = 0; idx < ar.size(); ++idx) { - PdfObject ran = (PdfObject)ar.get(idx); - if (!ran.isIndirect()) - continue; - PdfObject ran2 = (PdfObject)item.widget_refs.get(k); - if (!ran2.isIndirect()) - continue; - if (((PRIndirectReference)ran).getNumber() == ((PRIndirectReference)ran2).getNumber()) { - ar.remove(idx--); - PRIndirectReference wdref = (PRIndirectReference)ran2; - while (true) { - PdfDictionary wd = (PdfDictionary)PdfReader.getPdfObject(wdref); - PRIndirectReference parentRef = (PRIndirectReference)wd.get(PdfName.PARENT); - PdfReader.killIndirect(wdref); - if (parentRef == null) { // reached AcroForm - for (int fr = 0; fr < acroFds.size(); ++fr) { - PdfObject h = (PdfObject)acroFds.get(fr); - if (h.isIndirect() && ((PRIndirectReference)h).getNumber() == wdref.getNumber()) { - acroFds.remove(fr); - --fr; - } - } - break; - } - PdfDictionary parent = (PdfDictionary)PdfReader.getPdfObject(parentRef); - PdfArray kids = (PdfArray)PdfReader.getPdfObject(parent.get(PdfName.KIDS)); - ArrayList kar = kids.getArrayList(); - for (int fr = 0; fr < kar.size(); ++fr) { - PdfObject h = (PdfObject)kar.get(fr); - if (h.isIndirect() && ((PRIndirectReference)h).getNumber() == wdref.getNumber()) { - kar.remove(fr); - --fr; - } - } - if (!kar.isEmpty()) - break; - wdref = parentRef; - } - } - } - if (ar.size() == 0) { - PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); - pageDic.remove(PdfName.ANNOTS); - } - } - } - if (!fieldsAdded && partialFlattening.isEmpty()) { - for (int page = 1; page <= reader.getNumberOfPages(); ++page) { - PdfDictionary pageDic = reader.getPageN(page); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS)); - if (annots == null) - continue; - ArrayList ar = annots.getArrayList(); - for (int idx = 0; idx < ar.size(); ++idx) { - PdfObject annoto = PdfReader.getPdfObject((PdfObject)ar.get(idx)); - if ((annoto instanceof PdfIndirectReference) && !annoto.isIndirect()) - continue; - PdfDictionary annot = (PdfDictionary)annoto; - if (PdfName.WIDGET.equals(annot.get(PdfName.SUBTYPE))) { - ar.remove(idx); - --idx; - } - } - if (ar.size() == 0) { - PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); - pageDic.remove(PdfName.ANNOTS); - } - } - eliminateAcroformObjects(); - } - } - - void eliminateAcroformObjects() { - PdfObject acro = reader.getCatalog().get(PdfName.ACROFORM); - if (acro == null) - return; - PdfDictionary acrodic = (PdfDictionary)PdfReader.getPdfObject(acro); - PdfObject iFields = acrodic.get(PdfName.FIELDS); - if (iFields != null) { - PdfDictionary kids = new PdfDictionary(); - kids.put(PdfName.KIDS, iFields); - sweepKids(kids); - PdfReader.killIndirect(iFields); - acrodic.put(PdfName.FIELDS, new PdfArray()); - } -// PdfReader.killIndirect(acro); -// reader.getCatalog().remove(PdfName.ACROFORM); - } - - void sweepKids(PdfObject obj) { - PdfObject oo = PdfReader.killIndirect(obj); - if (oo == null || !oo.isDictionary()) - return; - PdfDictionary dic = (PdfDictionary)oo; - PdfArray kids = (PdfArray)PdfReader.killIndirect(dic.get(PdfName.KIDS)); - if (kids == null) - return; - ArrayList ar = kids.getArrayList(); - for (int k = 0; k < ar.size(); ++k) { - sweepKids((PdfObject)ar.get(k)); - } - } - - private void flatFreeTextFields() - { - if (append) - throw new IllegalArgumentException("FreeText flattening is not supported in append mode."); - - for (int page = 1; page <= reader.getNumberOfPages(); ++page) - { - PdfDictionary pageDic = reader.getPageN(page); - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageDic.get(PdfName.ANNOTS)); - if (annots == null) - continue; - ArrayList ar = annots.getArrayList(); - for (int idx = 0; idx < ar.size(); ++idx) - { - PdfObject annoto = PdfReader.getPdfObject((PdfObject)ar.get(idx)); - if ((annoto instanceof PdfIndirectReference) && !annoto.isIndirect()) - continue; - - PdfDictionary annDic = (PdfDictionary)annoto; - if (!((PdfName)annDic.get(PdfName.SUBTYPE)).equals(PdfName.FREETEXT)) - continue; - PdfNumber ff = (PdfNumber)PdfReader.getPdfObject(annDic.get(PdfName.F)); - int flags = (ff != null) ? ff.intValue() : 0; - - if ( (flags & PdfFormField.FLAGS_PRINT) != 0 && (flags & PdfFormField.FLAGS_HIDDEN) == 0) - { - PdfObject obj1 = annDic.get(PdfName.AP); - if (obj1 == null) - continue; - PdfDictionary appDic = (obj1 instanceof PdfIndirectReference) ? - (PdfDictionary) PdfReader.getPdfObject(obj1) : (PdfDictionary) obj1; - PdfObject obj = appDic.get(PdfName.N); - PdfAppearance app = null; - PdfObject objReal = PdfReader.getPdfObject(obj); - - if (obj instanceof PdfIndirectReference && !obj.isIndirect()) - app = new PdfAppearance((PdfIndirectReference)obj); - else if (objReal instanceof PdfStream) - { - ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); - app = new PdfAppearance((PdfIndirectReference)obj); - } - else - { - if (objReal.isDictionary()) - { - PdfName as_p = (PdfName)PdfReader.getPdfObject(appDic.get(PdfName.AS)); - if (as_p != null) - { - PdfIndirectReference iref = (PdfIndirectReference)((PdfDictionary)objReal).get(as_p); - if (iref != null) - { - app = new PdfAppearance(iref); - if (iref.isIndirect()) - { - objReal = PdfReader.getPdfObject(iref); - ((PdfDictionary)objReal).put(PdfName.SUBTYPE, PdfName.FORM); - } - } - } - } - } - if (app != null) - { - Rectangle box = PdfReader.getNormalizedRectangle((PdfArray)PdfReader.getPdfObject(annDic.get(PdfName.RECT))); - PdfContentByte cb = getOverContent(page); - cb.setLiteral("Q "); - cb.addTemplate(app, box.left(), box.bottom()); - cb.setLiteral("q "); - } - } - if (partialFlattening.size() == 0) - continue; - } - for (int idx = 0; idx < ar.size(); ++idx) - { - PdfObject annoto = PdfReader.getPdfObject((PdfObject)ar.get(idx)); - if ((annoto instanceof PdfIndirectReference) && annoto.isIndirect()) - { - PdfDictionary annot = (PdfDictionary)annoto; - if (PdfName.FREETEXT.equals(annot.get(PdfName.SUBTYPE))) - { - ar.remove(idx); - --idx; - } - } - } - if (ar.size() == 0) - { - PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS)); - pageDic.remove(PdfName.ANNOTS); - } - } - } - - /** - * @see com.lowagie.text.pdf.PdfWriter#getPageReference(int) - */ - public PdfIndirectReference getPageReference(int page) { - PdfIndirectReference ref = reader.getPageOrigRef(page); - if (ref == null) - throw new IllegalArgumentException("Invalid page number " + page); - return ref; - } - - /** - * @see com.lowagie.text.pdf.PdfWriter#addAnnotation(com.lowagie.text.pdf.PdfAnnotation) - */ - public void addAnnotation(PdfAnnotation annot) { - throw new RuntimeException("Unsupported in this context. Use PdfStamper.addAnnotation()"); - } - - void addDocumentField(PdfIndirectReference ref) { - PdfDictionary catalog = reader.getCatalog(); - PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), catalog); - if (acroForm == null) { - acroForm = new PdfDictionary(); - catalog.put(PdfName.ACROFORM, acroForm); - markUsed(catalog); - } - PdfArray fields = (PdfArray)PdfReader.getPdfObject(acroForm.get(PdfName.FIELDS), acroForm); - if (fields == null) { - fields = new PdfArray(); - acroForm.put(PdfName.FIELDS, fields); - markUsed(acroForm); - } - fields.add(ref); - markUsed(fields); - } - - void addFieldResources() { - if (fieldTemplates.size() == 0) - return; - PdfDictionary catalog = reader.getCatalog(); - PdfDictionary acroForm = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.ACROFORM), catalog); - if (acroForm == null) { - acroForm = new PdfDictionary(); - catalog.put(PdfName.ACROFORM, acroForm); - markUsed(catalog); - } - PdfDictionary dr = (PdfDictionary)PdfReader.getPdfObject(acroForm.get(PdfName.DR), acroForm); - if (dr == null) { - dr = new PdfDictionary(); - acroForm.put(PdfName.DR, dr); - markUsed(acroForm); - } - markUsed(dr); - for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) { - PdfTemplate template = (PdfTemplate)it.next(); - PdfFormField.mergeResources(dr, (PdfDictionary)template.getResources(), this); - } - PdfDictionary fonts = (PdfDictionary)PdfReader.getPdfObject(dr.get(PdfName.FONT)); - if (fonts != null && acroForm.get(PdfName.DA) == null) { - acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g ")); - markUsed(acroForm); - } - } - - void expandFields(PdfFormField field, ArrayList allAnnots) { - allAnnots.add(field); - ArrayList kids = field.getKids(); - if (kids != null) { - for (int k = 0; k < kids.size(); ++k) - expandFields((PdfFormField)kids.get(k), allAnnots); - } - } - - void addAnnotation(PdfAnnotation annot, PdfDictionary pageN) { - try { - ArrayList allAnnots = new ArrayList(); - if (annot.isForm()) { - fieldsAdded = true; - getAcroFields(); - PdfFormField field = (PdfFormField)annot; - if (field.getParent() != null) - return; - expandFields(field, allAnnots); - } - else - allAnnots.add(annot); - for (int k = 0; k < allAnnots.size(); ++k) { - annot = (PdfAnnotation)allAnnots.get(k); - if (annot.getPlaceInPage() > 0) - pageN = reader.getPageN(annot.getPlaceInPage()); - if (annot.isForm()) { - if (!annot.isUsed()) { - HashMap templates = annot.getTemplates(); - if (templates != null) - fieldTemplates.putAll(templates); - } - PdfFormField field = (PdfFormField)annot; - if (field.getParent() == null) - addDocumentField(field.getIndirectReference()); - } - if (annot.isAnnotation()) { - PdfArray annots = (PdfArray)PdfReader.getPdfObject(pageN.get(PdfName.ANNOTS), pageN); - if (annots == null) { - annots = new PdfArray(); - pageN.put(PdfName.ANNOTS, annots); - markUsed(pageN); - } - annots.add(annot.getIndirectReference()); - markUsed(annots); - if (!annot.isUsed()) { - PdfRectangle rect = (PdfRectangle)annot.get(PdfName.RECT); - if (rect != null && (rect.left() != 0 || rect.right() != 0 || rect.top() != 0 || rect.bottom() != 0)) { - int rotation = reader.getPageRotation(pageN); - Rectangle pageSize = reader.getPageSizeWithRotation(pageN); - switch (rotation) { - case 90: - annot.put(PdfName.RECT, new PdfRectangle( - pageSize.top() - rect.bottom(), - rect.left(), - pageSize.top() - rect.top(), - rect.right())); - break; - case 180: - annot.put(PdfName.RECT, new PdfRectangle( - pageSize.right() - rect.left(), - pageSize.top() - rect.bottom(), - pageSize.right() - rect.right(), - pageSize.top() - rect.top())); - break; - case 270: - annot.put(PdfName.RECT, new PdfRectangle( - rect.bottom(), - pageSize.right() - rect.left(), - rect.top(), - pageSize.right() - rect.right())); - break; - } - } - } - } - if (!annot.isUsed()) { - annot.setUsed(); - addToBody(annot, annot.getIndirectReference()); - } - } - } - catch (IOException e) { - throw new ExceptionConverter(e); - } - } - - void addAnnotation(PdfAnnotation annot, int page) { - addAnnotation(annot, reader.getPageN(page)); - } - - private void outlineTravel(PRIndirectReference outline) { - while (outline != null) { - PdfDictionary outlineR = (PdfDictionary)PdfReader.getPdfObjectRelease(outline); - PRIndirectReference first = (PRIndirectReference)outlineR.get(PdfName.FIRST); - if (first != null) { - outlineTravel(first); - } - PdfReader.killIndirect(outlineR.get(PdfName.DEST)); - PdfReader.killIndirect(outlineR.get(PdfName.A)); - PdfReader.killIndirect(outline); - outline = (PRIndirectReference)outlineR.get(PdfName.NEXT); - } - } - - void deleteOutlines() { - PdfDictionary catalog = reader.getCatalog(); - PRIndirectReference outlines = (PRIndirectReference)catalog.get(PdfName.OUTLINES); - if (outlines == null) - return; - outlineTravel(outlines); - PdfReader.killIndirect(outlines); - catalog.remove(PdfName.OUTLINES); - markUsed(catalog); - } - - void setJavaScript() throws IOException { - ArrayList djs = pdf.getDocumentJavaScript(); - if (djs.size() == 0) - return; - PdfDictionary catalog = reader.getCatalog(); - PdfDictionary names = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.NAMES), catalog); - if (names == null) { - names = new PdfDictionary(); - catalog.put(PdfName.NAMES, names); - markUsed(catalog); - } - markUsed(names); - String s = String.valueOf(djs.size() - 1); - int n = s.length(); - String pad = "000000000000000"; - HashMap maptree = new HashMap(); - for (int k = 0; k < djs.size(); ++k) { - s = String.valueOf(k); - s = pad.substring(0, n - s.length()) + s; - maptree.put(s, djs.get(k)); - } - PdfDictionary tree = PdfNameTree.writeTree(maptree, this); - names.put(PdfName.JAVASCRIPT, addToBody(tree).getIndirectReference()); - } - - void addFileAttachments() throws IOException { - HashMap fs = pdf.getDocumentFileAttachment(); - if (fs.size() == 0) - return; - PdfDictionary catalog = reader.getCatalog(); - PdfDictionary names = (PdfDictionary)PdfReader.getPdfObject(catalog.get(PdfName.NAMES), catalog); - if (names == null) { - names = new PdfDictionary(); - catalog.put(PdfName.NAMES, names); - markUsed(catalog); - } - markUsed(names); - HashMap old = PdfNameTree.readTree((PdfDictionary)PdfReader.getPdfObjectRelease(names.get(PdfName.EMBEDDEDFILES))); - for (Iterator it = fs.keySet().iterator(); it.hasNext();) { - String name = (String)it.next(); - int k = 0; - String nn = name; - while (old.containsKey(nn)) { - ++k; - nn += " " + k; - } - old.put(nn, fs.get(name)); - } - PdfDictionary tree = PdfNameTree.writeTree(old, this); - names.put(PdfName.EMBEDDEDFILES, addToBody(tree).getIndirectReference()); - } - - void setOutlines() throws IOException { - if (newBookmarks == null) - return; - deleteOutlines(); - if (newBookmarks.size() == 0) - return; - namedAsNames = (reader.getCatalog().get(PdfName.DESTS) != null); - PdfDictionary top = new PdfDictionary(); - PdfIndirectReference topRef = getPdfIndirectReference(); - Object kids[] = SimpleBookmark.iterateOutlines(this, topRef, newBookmarks, namedAsNames); - top.put(PdfName.FIRST, (PdfIndirectReference)kids[0]); - top.put(PdfName.LAST, (PdfIndirectReference)kids[1]); - top.put(PdfName.COUNT, new PdfNumber(((Integer)kids[2]).intValue())); - addToBody(top, topRef); - reader.getCatalog().put(PdfName.OUTLINES, topRef); - markUsed(reader.getCatalog()); - } - - void setOutlines(List outlines) { - newBookmarks = outlines; - } - - /** - * Sets the viewer preferences. - * @param preferences the viewer preferences - * @see PdfWriter#setViewerPreferences(int) - */ - public void setViewerPreferences(int preferences) { - useVp = true; - vp |= preferences; - } - - /** - * Set the signature flags. - * @param f the flags. This flags are ORed with current ones - */ - public void setSigFlags(int f) { - sigFlags |= f; - } - - /** Always throws an UnsupportedOperationException. - * @param actionType ignore - * @param action ignore - * @throws PdfException ignore - * @see PdfStamper#setPageAction(PdfName, PdfAction, int) - */ - public void setPageAction(PdfName actionType, PdfAction action) throws PdfException { - throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); - } - - /** - * Sets the open and close page additional action. - * @param actionType the action type. It can be PdfWriter.PAGE_OPEN - * or PdfWriter.PAGE_CLOSE - * @param action the action to perform - * @param page the page where the action will be applied. The first page is 1 - * @throws PdfException if the action type is invalid - */ - void setPageAction(PdfName actionType, PdfAction action, int page) throws PdfException { - if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) - throw new PdfException("Invalid page additional action type: " + actionType.toString()); - PdfDictionary pg = reader.getPageN(page); - PdfDictionary aa = (PdfDictionary)PdfReader.getPdfObject(pg.get(PdfName.AA), pg); - if (aa == null) { - aa = new PdfDictionary(); - pg.put(PdfName.AA, aa); - markUsed(pg); - } - aa.put(actionType, action); - markUsed(aa); - } - - /** - * Always throws an UnsupportedOperationException. - * @param seconds ignore - */ - public void setDuration(int seconds) { - throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); - } - - /** - * Always throws an UnsupportedOperationException. - * @param transition ignore - */ - public void setTransition(PdfTransition transition) { - throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)"); - } - - /** - * Sets the display duration for the page (for presentations) - * @param seconds the number of seconds to display the page. A negative value removes the entry - * @param page the page where the duration will be applied. The first page is 1 - */ - void setDuration(int seconds, int page) { - PdfDictionary pg = reader.getPageN(page); - if (seconds < 0) - pg.remove(PdfName.DUR); - else - pg.put(PdfName.DUR, new PdfNumber(seconds)); - markUsed(pg); - } - - /** - * Sets the transition for the page - * @param transition the transition object. A null removes the transition - * @param page the page where the transition will be applied. The first page is 1 - */ - void setTransition(PdfTransition transition, int page) { - PdfDictionary pg = reader.getPageN(page); - if (transition == null) - pg.remove(PdfName.TRANS); - else - pg.put(PdfName.TRANS, transition.getTransitionDictionary()); - markUsed(pg); - } - - // wprinz: had to make this public as we want to explicitely mark something as USED. - public void markUsed(PdfObject obj) { - if (append && obj != null) { - PRIndirectReference ref = null; - if (obj.type() == PdfObject.INDIRECT) - ref = (PRIndirectReference)obj; - else - ref = obj.getIndRef(); - if (ref != null) - marked.put(ref.getNumber(), 1); - } - } - - protected void markUsed(int num) { - if (append) - marked.put(num, 1); - } - - /** - * Getter for property append. - * @return Value of property append. - */ - boolean isAppend() { - return append; - } - - /** Additional-actions defining the actions to be taken in - * response to various trigger events affecting the document - * as a whole. The actions types allowed are: DOCUMENT_CLOSE, - * WILL_SAVE, DID_SAVE, WILL_PRINT - * and DID_PRINT. - * - * @param actionType the action type - * @param action the action to execute in response to the trigger - * @throws PdfException on invalid action type - */ - public void setAdditionalAction(PdfName actionType, PdfAction action) throws PdfException { - if (!(actionType.equals(DOCUMENT_CLOSE) || - actionType.equals(WILL_SAVE) || - actionType.equals(DID_SAVE) || - actionType.equals(WILL_PRINT) || - actionType.equals(DID_PRINT))) { - throw new PdfException("Invalid additional action type: " + actionType.toString()); - } - PdfDictionary aa = (PdfDictionary)PdfReader.getPdfObject(reader.getCatalog().get(PdfName.AA)); - if (aa == null) { - if (action == null) - return; - aa = new PdfDictionary(); - reader.getCatalog().put(PdfName.AA, aa); - } - markUsed(aa); - if (action == null) - aa.remove(actionType); - else - aa.put(actionType, action); - } - - /** - * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(com.lowagie.text.pdf.PdfAction) - */ - public void setOpenAction(PdfAction action) { - openAction = action; - } - - /** - * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(java.lang.String) - */ - public void setOpenAction(String name) { - throw new UnsupportedOperationException("Open actions by name are not supported."); - } - - /** - * @see com.lowagie.text.pdf.PdfWriter#setThumbnail(com.lowagie.text.Image) - */ - public void setThumbnail(com.lowagie.text.Image image) { - throw new UnsupportedOperationException("Use PdfStamper.setThumbnail()."); - } - - void setThumbnail(Image image, int page) throws PdfException, DocumentException { - PdfIndirectReference thumb = getImageReference(addDirectImageSimple(image)); - reader.resetReleasePage(); - PdfDictionary dic = reader.getPageN(page); - dic.put(PdfName.THUMB, thumb); - reader.resetReleasePage(); - } - - public PdfContentByte getDirectContentUnder() { - throw new UnsupportedOperationException("Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()"); - } - - public PdfContentByte getDirectContent() { - throw new UnsupportedOperationException("Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()"); - } - - static class PageStamp { - - PdfDictionary pageN; - StampContent under; - StampContent over; - PageResources pageResources; - - PageStamp(PdfStamperImp stamper, PdfReader reader, PdfDictionary pageN) { - this.pageN = pageN; - pageResources = new PageResources(); - PdfDictionary resources = (PdfDictionary)PdfReader.getPdfObject(pageN.get(PdfName.RESOURCES)); - - - // wprinz: flatten out the /Resource dictionary so that, when incrementally written, all new Resources are written correctly. - // alternatively, indirect resource dictionary for /Font and /XObject could be marked as used - // when they are modified. - e.g. in PageResources - but that would be far more effort than flattening the dict. - // (actually the objects that were flattened out could be deleted in the IncrementalUpdate xref) - //System.out.println("pageN = " + pageN.getIndRef()); - //System.out.println("pageN.get(/Resources) = " + pageN.get(PdfName.RESOURCES)); - //System.out.println("new resources = " + resources); - //System.out.println("flattening out new resources:"); - for (Iterator it = resources.getKeys().iterator(); it.hasNext(); ) - { - PdfName key = (PdfName)it.next(); - PdfObject value = resources.get(key); - //System.out.println(" " + key + " = " + value); - - if (value.isIndirect() && (key.compareTo(PdfName.FONT) == 0 || key.compareTo(PdfName.XOBJECT) == 0)) - { - PRIndirectReference ref = (PRIndirectReference)value; - PdfObject direct_object = PdfReader.getPdfObject(ref); - - resources.put(key, direct_object); - //System.out.println(" flattended " + key + " to " + direct_object); - } - } - // wprinz: end - - - pageResources.setOriginalResources(resources, stamper.namePtr); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfStream.java b/src/main/java/com/lowagie/text/pdf/PdfStream.java deleted file mode 100644 index 3d3b9dd..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfStream.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * $Id: PdfStream.java,v 1.57 2005/11/01 12:27:05 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.io.InputStream; -import java.io.IOException; -import java.util.zip.DeflaterOutputStream; -import java.util.zip.Deflater; -import com.lowagie.text.Document; -import com.lowagie.text.DocWriter; -import com.lowagie.text.ExceptionConverter; - -/** - * PdfStream is the Pdf stream object. - *

- * A stream, like a string, is a sequence of characters. However, an application can - * read a small portion of a stream at a time, while a string must be read in its entirety. - * For this reason, objects with potentially large amounts of data, such as images and - * page descriptions, are represented as streams.
- * A stream consists of a dictionary that describes a sequence of characters, followed by - * the keyword stream, followed by zero or more lines of characters, followed by - * the keyword endstream.
- * All streams must be PdfIndirectObjects. The stream dictionary must be a direct - * object. The keyword stream that follows the stream dictionary should be followed by - * a carriage return and linefeed or just a linefeed.
- * Remark: In this version only the FLATEDECODE-filter is supported.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.8 (page 41-53).
- * - * @see PdfObject - * @see PdfDictionary - */ - -public class PdfStream extends PdfDictionary { - - // membervariables - -/** is the stream compressed? */ - protected boolean compressed = false; - - protected ByteArrayOutputStream streamBytes = null; - protected InputStream inputStream; - protected PdfIndirectReference ref; - protected int inputStreamLength = -1; - protected PdfWriter writer; - protected int rawLength; - - static final byte STARTSTREAM[] = DocWriter.getISOBytes("stream\n"); - static final byte ENDSTREAM[] = DocWriter.getISOBytes("\nendstream"); - static final int SIZESTREAM = STARTSTREAM.length + ENDSTREAM.length; - - // constructors - -/** - * Constructs a PdfStream-object. - * - * @param bytes content of the new PdfObject as an array of byte. - */ - - public PdfStream(byte[] bytes) { - super(); - type = STREAM; - this.bytes = bytes; - rawLength = bytes.length; - put(PdfName.LENGTH, new PdfNumber(bytes.length)); - } - - /** - * Creates an efficient stream. No temporary array is ever created. The InputStream - * is totally consumed but is not closed. The general usage is: - *

- *

-     * InputStream in = ...;
-     * PdfStream stream = new PdfStream(in, writer);
-     * stream.flateCompress();
-     * writer.addToBody(stream);
-     * stream.writeLength();
-     * in.close();
-     * 
- * @param inputStream the data to write to this stream - * @param writer the PdfWriter for this stream - */ - public PdfStream(InputStream inputStream, PdfWriter writer) { - super(); - type = STREAM; - this.inputStream = inputStream; - this.writer = writer; - ref = writer.getPdfIndirectReference(); - put(PdfName.LENGTH, ref); - } - -/** - * Constructs a PdfStream-object. - */ - - protected PdfStream() { - super(); - type = STREAM; - } - - /** - * Writes the stream length to the PdfWriter. - *

- * This method must be called and can only be called if the contructor {@link #PdfStream(InputStream,PdfWriter)} - * is used to create the stream. - * @throws IOException on error - * @see #PdfStream(InputStream,PdfWriter) - */ - public void writeLength() throws IOException { - if (inputStream == null) - throw new UnsupportedOperationException("writeLength() can only be called in a contructed PdfStream(InputStream,PdfWriter)."); - if (inputStreamLength == -1) - throw new IOException("writeLength() can only be called after output of the stream body."); - writer.addToBody(new PdfNumber(inputStreamLength), ref, false); - } - - /** - * Gets the raw length of the stream. - * @return the raw length of the stream - */ - public int getRawLength() { - return rawLength; - } - - /** - * Compresses the stream. - */ - - public void flateCompress() { - if (!Document.compress) - return; - // check if the flateCompress-method has already been - if (compressed) { - return; - } - if (inputStream != null) { - compressed = true; - return; - } - // check if a filter already exists - PdfObject filter = get(PdfName.FILTER); - if (filter != null) { - if (filter.isName() && ((PdfName) filter).compareTo(PdfName.FLATEDECODE) == 0) { - return; - } - else if (filter.isArray() && ((PdfArray) filter).contains(PdfName.FLATEDECODE)) { - return; - } - else { - throw new RuntimeException("Stream could not be compressed: filter is not a name or array."); - } - } - try { - // compress - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - DeflaterOutputStream zip = new DeflaterOutputStream(stream); - if (streamBytes != null) - streamBytes.writeTo(zip); - else - zip.write(bytes); - zip.close(); - // update the object - streamBytes = stream; - bytes = null; - put(PdfName.LENGTH, new PdfNumber(streamBytes.size())); - if (filter == null) { - put(PdfName.FILTER, PdfName.FLATEDECODE); - } - else { - PdfArray filters = new PdfArray(filter); - filters.add(PdfName.FLATEDECODE); - put(PdfName.FILTER, filters); - } - compressed = true; - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - } - -// public int getStreamLength(PdfWriter writer) { -// if (dicBytes == null) -// toPdf(writer); -// if (streamBytes != null) -// return streamBytes.size() + dicBytes.length + SIZESTREAM; -// else -// return bytes.length + dicBytes.length + SIZESTREAM; -// } - - protected void superToPdf(PdfWriter writer, OutputStream os) throws IOException { - super.toPdf(writer, os); - } - - /** - * @see com.lowagie.text.pdf.PdfDictionary#toPdf(com.lowagie.text.pdf.PdfWriter, java.io.OutputStream) - */ - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - if (inputStream != null && compressed) - put(PdfName.FILTER, PdfName.FLATEDECODE); - superToPdf(writer, os); - os.write(STARTSTREAM); - PdfEncryption crypto = null; - if (writer != null) - crypto = writer.getEncryption(); - if (crypto != null) - crypto.prepareKey(); - if (inputStream != null) { - rawLength = 0; - DeflaterOutputStream def = null; - OutputStreamCounter osc = new OutputStreamCounter(os); - OutputStream fout = osc; - if (crypto != null) - fout = new PdfEncryptionStream(fout, crypto); - if (compressed) - fout = def = new DeflaterOutputStream(fout, new Deflater(Deflater.BEST_COMPRESSION), 0x8000); - - byte buf[] = new byte[0x10000]; - while (true) { - int n = inputStream.read(buf); - if (n <= 0) - break; - fout.write(buf, 0, n); - rawLength += n; - } - if (def != null) - def.finish(); - inputStreamLength = osc.getCounter(); - } - else { - if (crypto == null) { - if (streamBytes != null) - streamBytes.writeTo(os); - else - os.write(bytes); - } - else { - byte b[]; - if (streamBytes != null) { - b = streamBytes.toByteArray(); - crypto.encryptRC4(b); - } - else { - b = new byte[bytes.length]; - crypto.encryptRC4(bytes, b); - } - os.write(b); - } - } - os.write(ENDSTREAM); - } - - /** - * Writes the data content to an OutputStream. - * @param os the destination to write to - * @throws IOException on error - */ - public void writeContent(OutputStream os) throws IOException { - if (streamBytes != null) - streamBytes.writeTo(os); - else if (bytes != null) - os.write(bytes); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfString.java b/src/main/java/com/lowagie/text/pdf/PdfString.java deleted file mode 100644 index dac4035..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfString.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * $Id: PdfString.java,v 1.58 2005/05/04 14:32:24 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.OutputStream; -import java.io.IOException; - -/** - * A PdfString-class is the PDF-equivalent of a JAVA-String-object. - *

- * A string is a sequence of characters delimited by parenthesis. If a string is too long - * to be conveniently placed on a single line, it may be split across multiple lines by using - * the backslash character (\) at the end of a line to indicate that the string continues - * on the following line. Within a string, the backslash character is used as an escape to - * specify unbalanced parenthesis, non-printing ASCII characters, and the backslash character - * itself. Use of the \ddd escape sequence is the preferred way to represent characters - * outside the printable ASCII character set.
- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 4.4 (page 37-39). - * - * @see PdfObject - * @see BadPdfFormatException - */ - -public class PdfString extends PdfObject { - - // membervariables - - /** The value of this object. */ - protected String value = NOTHING; - protected String originalValue = null; - - /** The encoding. */ - protected String encoding = TEXT_PDFDOCENCODING; - protected int objNum = 0; - protected int objGen = 0; - protected boolean hexWriting = false; - - // constructors - - /** - * Constructs an empty PdfString-object. - */ - - public PdfString() { - super(STRING); - } - - /** - * Constructs a PdfString-object. - * - * @param value the content of the string - */ - - public PdfString(String value) { - super(STRING); - this.value = value; - } - - /** - * Constructs a PdfString-object. - * - * @param value the content of the string - * @param encoding an encoding - */ - - public PdfString(String value, String encoding) { - super(STRING); - this.value = value; - this.encoding = encoding; - } - - /** - * Constructs a PdfString-object. - * - * @param bytes an array of byte - */ - - public PdfString(byte[] bytes) { - super(STRING); - value = PdfEncodings.convertToString(bytes, null); - encoding = NOTHING; - } - - // methods overriding some methods in PdfObject - - /** - * Returns the PDF representation of this PdfString. - * - * @return an array of bytes - */ - - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - byte b[] = getBytes(); - PdfEncryption crypto = null; - if (writer != null) - crypto = writer.getEncryption(); - if (crypto != null) { - b = (byte[])bytes.clone(); - crypto.prepareKey(); - crypto.encryptRC4(b); - } - if (hexWriting) { - ByteBuffer buf = new ByteBuffer(); - buf.append('<'); - int len = b.length; - for (int k = 0; k < len; ++k) - buf.appendHex(b[k]); - buf.append('>'); - os.write(buf.toByteArray()); - } - else - os.write(PdfContentByte.escapeString(b)); - } - - /** - * Returns the String value of the PdfString-object. - * - * @return a String - */ - - public String toString() { - return value; - } - - // other methods - - /** - * Gets the encoding of this string. - * - * @return a String - */ - - public String getEncoding() { - return encoding; - } - - public String toUnicodeString() { - if (encoding != null && encoding.length() != 0) - return value; - getBytes(); - if (bytes.length >= 2 && bytes[0] == (byte)254 && bytes[1] == (byte)255) - return PdfEncodings.convertToString(bytes, PdfObject.TEXT_UNICODE); - else - return PdfEncodings.convertToString(bytes, PdfObject.TEXT_PDFDOCENCODING); - } - - void setObjNum(int objNum, int objGen) { - this.objNum = objNum; - this.objGen = objGen; - } - - void decrypt(PdfReader reader) { - PdfEncryption decrypt = reader.getDecrypt(); - if (decrypt != null) { - originalValue = value; - decrypt.setHashKey(objNum, objGen); - decrypt.prepareKey(); - bytes = PdfEncodings.convertToBytes(value, null); - decrypt.encryptRC4(bytes); - value = PdfEncodings.convertToString(bytes, null); - } - } - - public byte[] getBytes() { - if (bytes == null) { - if (encoding != null && encoding.equals(TEXT_UNICODE) && PdfEncodings.isPdfDocEncoding(value)) - bytes = PdfEncodings.convertToBytes(value, TEXT_PDFDOCENCODING); - else - bytes = PdfEncodings.convertToBytes(value, encoding); - } - return bytes; - } - - public byte[] getOriginalBytes() { - if (originalValue == null) - return getBytes(); - return PdfEncodings.convertToBytes(originalValue, null); - } - - public PdfString setHexWriting(boolean hexWriting) { - this.hexWriting = hexWriting; - return this; - } - - public boolean isHexWriting() { - return hexWriting; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfStructureElement.java b/src/main/java/com/lowagie/text/pdf/PdfStructureElement.java deleted file mode 100644 index 57e8654..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfStructureElement.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * $Id: PdfStructureElement.java,v 1.3 2005/11/01 12:27:05 psoares33 Exp $ - * - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * This is a node in a document logical structure. It may contain a mark point or it may contain - * other nodes. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfStructureElement extends PdfDictionary { - - /** - * Holds value of property kids. - */ - private PdfStructureElement parent; - private PdfStructureTreeRoot top; - - /** - * Holds value of property reference. - */ - private PdfIndirectReference reference; - - /** - * Creates a new instance of PdfStructureElement. - * @param parent the parent of this node - * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map - */ - public PdfStructureElement(PdfStructureElement parent, PdfName structureType) { - top = parent.top; - init(parent, structureType); - this.parent = parent; - put(PdfName.P, parent.reference); - } - - /** - * Creates a new instance of PdfStructureElement. - * @param parent the parent of this node - * @param structureType the type of structure. It may be a standard type or a user type mapped by the role map - */ - public PdfStructureElement(PdfStructureTreeRoot parent, PdfName structureType) { - top = parent; - init(parent, structureType); - put(PdfName.P, parent.getReference()); - } - - private void init(PdfDictionary parent, PdfName structureType) { - PdfObject kido = parent.get(PdfName.K); - PdfArray kids = null; - if (kido != null && !kido.isArray()) - throw new IllegalArgumentException("The parent has already another function."); - if (kido == null) { - kids = new PdfArray(); - parent.put(PdfName.K, kids); - } - else - kids = (PdfArray)kido; - kids.add(this); - put(PdfName.S, structureType); - reference = top.getWriter().getPdfIndirectReference(); - } - - /** - * Gets the parent of this node. - * @return the parent of this node - */ - public PdfDictionary getParent() { - return parent; - } - - void setPageMark(int page, int mark) { - if (mark >= 0) - put(PdfName.K, new PdfNumber(mark)); - top.setPageMark(page, reference); - } - - /** - * Gets the reference this object will be written to. - * @return the reference this object will be written to - */ - public PdfIndirectReference getReference() { - return this.reference; - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfStructureTreeRoot.java b/src/main/java/com/lowagie/text/pdf/PdfStructureTreeRoot.java deleted file mode 100644 index e6e8c2c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfStructureTreeRoot.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * $Id: PdfStructureTreeRoot.java,v 1.2 2005/10/18 15:30:42 psoares33 Exp $ - * - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.io.IOException; - -/** - * The structure tree root corresponds to the highest hierarchy level in a tagged PDF. - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfStructureTreeRoot extends PdfDictionary { - - private HashMap parentTree = new HashMap(); - private PdfIndirectReference reference; - - /** - * Holds value of property writer. - */ - private PdfWriter writer; - - /** Creates a new instance of PdfStructureTreeRoot */ - PdfStructureTreeRoot(PdfWriter writer) { - super(PdfName.STRUCTTREEROOT); - this.writer = writer; - reference = writer.getPdfIndirectReference(); - } - - /** - * Maps the user tags to the standard tags. The mapping will allow a standard application to make some sense of the tagged - * document whatever the user tags may be. - * @param used the user tag - * @param standard the standard tag - */ - public void mapRole(PdfName used, PdfName standard) { - PdfDictionary rm = (PdfDictionary)get(PdfName.ROLEMAP); - if (rm == null) { - rm = new PdfDictionary(); - put(PdfName.ROLEMAP, rm); - } - rm.put(used, standard); - } - - /** - * Gets the writer. - * @return the writer - */ - public PdfWriter getWriter() { - return this.writer; - } - - /** - * Gets the reference this object will be written to. - * @return the reference this object will be written to - */ - public PdfIndirectReference getReference() { - return this.reference; - } - - void setPageMark(int page, PdfIndirectReference struc) { - Integer i = new Integer(page); - PdfArray ar = (PdfArray)parentTree.get(i); - if (ar == null) { - ar = new PdfArray(); - parentTree.put(i, ar); - } - ar.add(struc); - } - - private void nodeProcess(PdfDictionary struc, PdfIndirectReference reference) throws IOException { - PdfObject obj = struc.get(PdfName.K); - if (obj != null && obj.isArray() && !((PdfObject)((PdfArray)obj).getArrayList().get(0)).isNumber()) { - PdfArray ar = (PdfArray)obj; - ArrayList a = ar.getArrayList(); - for (int k = 0; k < a.size(); ++k) { - PdfStructureElement e = (PdfStructureElement)a.get(k); - a.set(k, e.getReference()); - nodeProcess(e, e.getReference()); - } - } - if (reference != null) - writer.addToBody(struc, reference); - } - - void buildTree() throws IOException { - HashMap numTree = new HashMap(); - for (Iterator it = parentTree.keySet().iterator(); it.hasNext();) { - Integer i = (Integer)it.next(); - PdfArray ar = (PdfArray)parentTree.get(i); - numTree.put(i, writer.addToBody(ar).getIndirectReference()); - } - PdfDictionary dicTree = PdfNumberTree.writeTree(numTree, writer); - if (dicTree != null) - put(PdfName.PARENTTREE, writer.addToBody(dicTree).getIndirectReference()); - - nodeProcess(this, reference); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfTable.java b/src/main/java/com/lowagie/text/pdf/PdfTable.java deleted file mode 100644 index 0fa6009..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfTable.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * $Id: PdfTable.java,v 1.68 2005/05/04 14:31:53 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; -import java.util.Iterator; - -import com.lowagie.text.Element; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Cell; -import com.lowagie.text.Row; -import com.lowagie.text.Table; - -/** - * PdfTable is an object that contains the graphics and text of a table. - * - * @see com.lowagie.text.Table - * @see com.lowagie.text.Row - * @see com.lowagie.text.Cell - * @see PdfCell - */ - -public class PdfTable extends Rectangle { - - // membervariables - - /** this is the number of columns in the table. */ - private int columns; - - /** this is the ArrayList with all the cell of the table header. */ - private ArrayList headercells; - - /** this is the ArrayList with all the cells in the table. */ - private ArrayList cells; - - /** Original table used to build this object*/ - protected Table table; - - /** Cached column widths. */ - protected float[] positions; - - // constructors - - /** - * Constructs a PdfTable-object. - * - * @param table a Table - * @param left the left border on the page - * @param right the right border on the page - * @param top the start position of the top of the table - * @param supportUpdateRowAdditions - * if true, table rows will be deleted after building the PdfTable table, - * in order to preserve memory and detect future row additions - */ - - PdfTable(Table table, float left, float right, float top, boolean supportUpdateRowAdditions) { - // constructs a Rectangle (the bottomvalue will be changed afterwards) - super(left, top, right, top); - this.table = table; - table.complete(); - - // copying the attributes from class Table - cloneNonPositionParameters(table); - - this.columns = table.columns(); - positions = table.getWidths(left, right - left); - - // initialisation of some parameters - setLeft(positions[0]); - setRight(positions[positions.length - 1]); - - headercells = new ArrayList(); - cells = new ArrayList(); - - updateRowAdditionsInternal(); - if (supportUpdateRowAdditions) { - table.deleteAllRows(); - } - } - - // methods - - /** - * Updates the table row additions in the underlying table object and deletes all table rows, - * in order to preserve memory and detect future row additions. - *

Pre-requisite: the object must have been built with the parameter supportUpdateRowAdditions equals to true. - */ - - void updateRowAdditions() { - table.complete(); - updateRowAdditionsInternal(); - table.deleteAllRows(); - } - - /** - * Updates the table row additions in the underlying table object - */ - - private void updateRowAdditionsInternal() { - // correct table : fill empty cells/ parse table in table - Row row; - int prevRows = rows(); - int rowNumber = 0; - int groupNumber = 0; - boolean groupChange; - int firstDataRow = table.firstDataRow(); - Cell cell; - PdfCell currentCell; - ArrayList newCells = new ArrayList(); - int rows = table.size() + 1; - float[] offsets = new float[rows]; - for (int i = 0; i < rows; i++) { - offsets[i] = bottom(); - } - - // loop over all the rows - for (Iterator rowIterator = table.iterator(); rowIterator.hasNext(); ) { - groupChange = false; - row = (Row) rowIterator.next(); - if (row.isEmpty()) { - if (rowNumber < rows - 1 && offsets[rowNumber + 1] > offsets[rowNumber]) offsets[rowNumber + 1] = offsets[rowNumber]; - } - else { - for(int i = 0; i < row.columns(); i++) { - cell = (Cell) row.getCell(i); - if (cell != null) { - currentCell = new PdfCell(cell, rowNumber+prevRows, positions[i], positions[i + cell.colspan()], offsets[rowNumber], cellspacing(), cellpadding()); - try { - if (offsets[rowNumber] - currentCell.height() - cellpadding() < offsets[rowNumber + currentCell.rowspan()]) { - offsets[rowNumber + currentCell.rowspan()] = offsets[rowNumber] - currentCell.height() - cellpadding(); - } - } - catch(ArrayIndexOutOfBoundsException aioobe) { - if (offsets[rowNumber] - currentCell.height() < offsets[rows - 1]) { - offsets[rows - 1] = offsets[rowNumber] - currentCell.height(); - } - } - if (rowNumber < firstDataRow) { - currentCell.setHeader(); - headercells.add(currentCell); - } - currentCell.setGroupNumber(groupNumber); - groupChange |= cell.getGroupChange(); - newCells.add(currentCell); - } - } - } - rowNumber++; - if( groupChange ) groupNumber++; - } - - // loop over all the cells - int n = newCells.size(); - for (int i = 0; i < n; i++) { - currentCell = (PdfCell) newCells.get(i); - try { - currentCell.setBottom(offsets[currentCell.rownumber()-prevRows + currentCell.rowspan()]); - } - catch(ArrayIndexOutOfBoundsException aioobe) { - currentCell.setBottom(offsets[rows - 1]); - } - } - cells.addAll(newCells); - setBottom(offsets[rows - 1]); - } - - /** - * Get the number of rows - */ - - int rows() { - return cells.size() == 0 ? 0 : ((PdfCell)cells.get(cells.size()-1)).rownumber()+1; - } - - /** @see com.lowagie.text.Element#type() */ - public int type() { - return Element.TABLE; - } - - /** - * Returns the arraylist with the cells of the table header. - * - * @return an ArrayList - */ - - ArrayList getHeaderCells() { - return headercells; - } - - /** - * Checks if there is a table header. - * - * @return an ArrayList - */ - - boolean hasHeader() { - return headercells.size() > 0; - } - - /** - * Returns the arraylist with the cells of the table. - * - * @return an ArrayList - */ - - ArrayList getCells() { - return cells; - } - - /** - * Returns the number of columns of the table. - * - * @return the number of columns - */ - - int columns() { - return columns; - } - - /** - * Returns the cellpadding of the table. - * - * @return the cellpadding - */ - - final float cellpadding() { - return table.cellpadding(); - } - - /** - * Returns the cellspacing of the table. - * - * @return the cellspacing - */ - - final float cellspacing() { - return table.cellspacing(); - } - - /** - * Checks if this Table has to fit a page. - * - * @return true if the table may not be split - */ - - public final boolean hasToFitPageTable() { - return table.hasToFitPageTable(); - } - - /** - * Checks if the cells of this Table have to fit a page. - * - * @return true if the cells may not be split - */ - - public final boolean hasToFitPageCells() { - return table.hasToFitPageCells(); - } - - /** - * Gets the offset of this table. - * - * @return the space between this table and the previous element. - */ - public float getOffset() { - return table.getOffset(); - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfTemplate.java b/src/main/java/com/lowagie/text/pdf/PdfTemplate.java deleted file mode 100644 index e7ba7ba..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfTemplate.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * $Id: PdfTemplate.java,v 1.61 2006/03/02 17:56:30 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; -import java.io.IOException; - -import com.lowagie.text.Rectangle; - -/** - * Implements the form XObject. - */ - -public class PdfTemplate extends PdfContentByte { - public static final int TYPE_TEMPLATE = 1; - public static final int TYPE_IMPORTED = 2; - public static final int TYPE_PATTERN = 3; - protected int type; - /** The indirect reference to this template */ - protected PdfIndirectReference thisReference; - - /** The resources used by this template */ - protected PageResources pageResources; - - - /** The bounding box of this template */ - protected Rectangle bBox = new Rectangle(0, 0); - - protected PdfArray matrix; - - protected PdfTransparencyGroup group; - - protected PdfOCG layer; - - /** - *Creates a PdfTemplate. - */ - - protected PdfTemplate() { - super(null); - type = TYPE_TEMPLATE; - } - - /** - * Creates new PdfTemplate - * - * @param wr the PdfWriter - */ - - PdfTemplate(PdfWriter wr) { - super(wr); - type = TYPE_TEMPLATE; - pageResources = new PageResources(); - pageResources.addDefaultColor(wr.getDefaultColorspace()); - thisReference = writer.getPdfIndirectReference(); - } - - /** - * Sets the bounding width of this template. - * - * @param width the bounding width - */ - - public void setWidth(float width) { - bBox.setLeft(0); - bBox.setRight(width); - } - - /** - * Sets the bounding heigth of this template. - * - * @param height the bounding height - */ - - public void setHeight(float height) { - bBox.setBottom(0); - bBox.setTop(height); - } - - /** - * Gets the bounding width of this template. - * - * @return width the bounding width - */ - public float getWidth() { - return bBox.width(); - } - - /** - * Gets the bounding heigth of this template. - * - * @return heigth the bounding height - */ - - public float getHeight() { - return bBox.height(); - } - - public Rectangle getBoundingBox() { - return bBox; - } - - public void setBoundingBox(Rectangle bBox) { - this.bBox = bBox; - } - - /** - * Sets the layer this template belongs to. - * @param layer the layer this template belongs to - */ - public void setLayer(PdfOCG layer) { - this.layer = layer; - } - - /** - * Gets the layer this template belongs to. - * @return the layer this template belongs to or null for no layer defined - */ - public PdfOCG getLayer() { - return layer; - } - - public void setMatrix(float a, float b, float c, float d, float e, float f) { - matrix = new PdfArray(); - matrix.add(new PdfNumber(a)); - matrix.add(new PdfNumber(b)); - matrix.add(new PdfNumber(c)); - matrix.add(new PdfNumber(d)); - matrix.add(new PdfNumber(e)); - matrix.add(new PdfNumber(f)); - } - - PdfArray getMatrix() { - return matrix; - } - - /** - * Gets the indirect reference to this template. - * - * @return the indirect reference to this template - */ - - public PdfIndirectReference getIndirectReference() { - return thisReference; - } - - public void beginVariableText() { - content.append("/Tx BMC "); - } - - public void endVariableText() { - content.append("EMC "); - } - - /** - * Constructs the resources used by this template. - * - * @return the resources used by this template - */ - - PdfObject getResources() { - return getPageResources().getResources(); - } - - /** - * Gets the stream representing this template. - * - * @return the stream representing this template - */ - - PdfStream getFormXObject() throws IOException { - return new PdfFormXObject(this); - } - - /** - * Gets a duplicate of this PdfTemplate. All - * the members are copied by reference but the buffer stays different. - * @return a copy of this PdfTemplate - */ - - public PdfContentByte getDuplicate() { - PdfTemplate tpl = new PdfTemplate(); - tpl.writer = writer; - tpl.pdf = pdf; - tpl.thisReference = thisReference; - tpl.pageResources = pageResources; - tpl.bBox = new Rectangle(bBox); - tpl.group = group; - tpl.layer = layer; - if (matrix != null) { - tpl.matrix = new PdfArray(matrix); - } - tpl.separator = separator; - return tpl; - } - - public int getType() { - return type; - } - - PageResources getPageResources() { - return pageResources; - } - - /** Getter for property group. - * @return Value of property group. - * - */ - public PdfTransparencyGroup getGroup() { - return this.group; - } - - /** Setter for property group. - * @param group New value of property group. - * - */ - public void setGroup(PdfTransparencyGroup group) { - this.group = group; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfTextArray.java b/src/main/java/com/lowagie/text/pdf/PdfTextArray.java deleted file mode 100644 index 16901bb..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfTextArray.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * $Id: PdfTextArray.java,v 1.58 2005/05/04 14:32:21 blowagie Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.ArrayList; - -/** - * PdfTextArray defines an array with displacements and PdfString-objects. - *

- * A TextArray is used with the operator TJ in PdfText. - * The first object in this array has to be a PdfString; - * see reference manual version 1.3 section 8.7.5, pages 346-347. - */ - -public class PdfTextArray{ - ArrayList arrayList = new ArrayList(); - // constructors - - - public PdfTextArray(String str) { - arrayList.add(str); - } - - public PdfTextArray() { - } - -/** - * Adds a PdfNumber to the PdfArray. - * - * @param number displacement of the string - */ - - public void add(PdfNumber number) - { - arrayList.add(new Float(number.doubleValue())); - } - - public void add(float number) - { - arrayList.add(new Float(number)); - } - - public void add(String str) - { - arrayList.add(str); - } - - ArrayList getArrayList() { - return arrayList; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfTransition.java b/src/main/java/com/lowagie/text/pdf/PdfTransition.java deleted file mode 100644 index 038d4fb..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfTransition.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2002 by Josselin PUJO. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -public class PdfTransition { - /** - * Out Vertical Split - */ - public static final int SPLITVOUT = 1; - /** - * Out Horizontal Split - */ - public static final int SPLITHOUT = 2; - /** - * In Vertical Split - */ - public static final int SPLITVIN = 3; - /** - * IN Horizontal Split - */ - public static final int SPLITHIN = 4; - /** - * Vertical Blinds - */ - public static final int BLINDV = 5; - /** - * Vertical Blinds - */ - public static final int BLINDH = 6; - /** - * Inward Box - */ - public static final int INBOX = 7; - /** - * Outward Box - */ - public static final int OUTBOX = 8; - /** - * Left-Right Wipe - */ - public static final int LRWIPE = 9; - /** - * Right-Left Wipe - */ - public static final int RLWIPE = 10; - /** - * Bottom-Top Wipe - */ - public static final int BTWIPE = 11; - /** - * Top-Bottom Wipe - */ - public static final int TBWIPE = 12; - /** - * Dissolve - */ - public static final int DISSOLVE = 13; - /** - * Left-Right Glitter - */ - public static final int LRGLITTER = 14; - /** - * Top-Bottom Glitter - */ - public static final int TBGLITTER = 15; - /** - * Diagonal Glitter - */ - public static final int DGLITTER = 16; - - /** - * duration of the transition effect - */ - protected int duration; - /** - * type of the transition effect - */ - protected int type; - - /** - * Constructs a Transition. - * - */ - public PdfTransition() { - this(BLINDH); - } - - /** - * Constructs a Transition. - * - *@param type type of the transition effect - */ - public PdfTransition(int type) { - this(type,1); - } - - /** - * Constructs a Transition. - * - *@param type type of the transition effect - *@param duration duration of the transition effect - */ - public PdfTransition(int type, int duration) { - this.duration = duration; - this.type = type; - } - - - public int getDuration() { - return duration; - } - - - public int getType() { - return type; - } - - public PdfDictionary getTransitionDictionary() { - PdfDictionary trans = new PdfDictionary(PdfName.TRANS); - switch (type) { - case SPLITVOUT: - trans.put(PdfName.S,PdfName.SPLIT); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.V); - trans.put(PdfName.M,PdfName.O); - break; - case SPLITHOUT: - trans.put(PdfName.S,PdfName.SPLIT); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.H); - trans.put(PdfName.M,PdfName.O); - break; - case SPLITVIN: - trans.put(PdfName.S,PdfName.SPLIT); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.V); - trans.put(PdfName.M,PdfName.I); - break; - case SPLITHIN: - trans.put(PdfName.S,PdfName.SPLIT); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.H); - trans.put(PdfName.M,PdfName.I); - break; - case BLINDV: - trans.put(PdfName.S,PdfName.BLINDS); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.V); - break; - case BLINDH: - trans.put(PdfName.S,PdfName.BLINDS); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DM,PdfName.H); - break; - case INBOX: - trans.put(PdfName.S,PdfName.BOX); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.M,PdfName.I); - break; - case OUTBOX: - trans.put(PdfName.S,PdfName.BOX); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.M,PdfName.O); - break; - case LRWIPE: - trans.put(PdfName.S,PdfName.WIPE); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(0)); - break; - case RLWIPE: - trans.put(PdfName.S,PdfName.WIPE); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(180)); - break; - case BTWIPE: - trans.put(PdfName.S,PdfName.WIPE); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(90)); - break; - case TBWIPE: - trans.put(PdfName.S,PdfName.WIPE); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(270)); - break; - case DISSOLVE: - trans.put(PdfName.S,PdfName.DISSOLVE); - trans.put(PdfName.D,new PdfNumber(duration)); - break; - case LRGLITTER: - trans.put(PdfName.S,PdfName.GLITTER); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(0)); - break; - case TBGLITTER: - trans.put(PdfName.S,PdfName.GLITTER); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(270)); - break; - case DGLITTER: - trans.put(PdfName.S,PdfName.GLITTER); - trans.put(PdfName.D,new PdfNumber(duration)); - trans.put(PdfName.DI,new PdfNumber(315)); - break; - } - return trans; - } -} - diff --git a/src/main/java/com/lowagie/text/pdf/PdfTransparencyGroup.java b/src/main/java/com/lowagie/text/pdf/PdfTransparencyGroup.java deleted file mode 100644 index 873b065..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfTransparencyGroup.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2003 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -/** The transparency group dictionary. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class PdfTransparencyGroup extends PdfDictionary { - - /** - * Constructs a transparencyGroup. - */ - public PdfTransparencyGroup() { - super(); - put(PdfName.S, PdfName.TRANSPARENCY); - } - - /** - * Determining the initial backdrop against which its stack is composited. - * @param isolated - */ - public void setIsolated(boolean isolated) { - if (isolated) - put(PdfName.I, PdfBoolean.PDFTRUE); - else - remove(PdfName.I); - } - - /** - * Determining whether the objects within the stack are composited with one another or only with the group's backdrop. - * @param knockout - */ - public void setKnockout(boolean knockout) { - if (knockout) - put(PdfName.K, PdfBoolean.PDFTRUE); - else - remove(PdfName.K); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/PdfWriter.java b/src/main/java/com/lowagie/text/pdf/PdfWriter.java deleted file mode 100644 index ed93b71..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfWriter.java +++ /dev/null @@ -1,2752 +0,0 @@ -/* - * $Id: PdfWriter.java,v 1.114 2006/06/04 22:23:33 psoares33 Exp $ - * $Name: $ - * - * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.awt.Color; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.HashSet; - -import com.lowagie.text.DocListener; -import com.lowagie.text.DocWriter; -import com.lowagie.text.Document; -import com.lowagie.text.DocumentException; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.Image; -import com.lowagie.text.ImgWMF; -import com.lowagie.text.Rectangle; -import com.lowagie.text.Table; -import com.lowagie.text.ImgPostscript; -import com.lowagie.text.pdf.events.PdfPageEventForwarder; - -/** - * A DocWriter class for PDF. - *

- * When this PdfWriter is added - * to a certain PdfDocument, the PDF representation of every Element - * added to this Document will be written to the outputstream.

- */ - -public class PdfWriter extends DocWriter { - - // inner classes - - /** - * This class generates the structure of a PDF document. - *

- * This class covers the third section of Chapter 5 in the 'Portable Document Format - * Reference Manual version 1.3' (page 55-60). It contains the body of a PDF document - * (section 5.14) and it can also generate a Cross-reference Table (section 5.15). - * - * @see PdfWriter - * @see PdfObject - * @see PdfIndirectObject - */ - - public static class PdfBody { - - // inner classes - - /** - * PdfCrossReference is an entry in the PDF Cross-Reference table. - */ - - static class PdfCrossReference implements Comparable { - - // membervariables - private int type; - - /** Byte offset in the PDF file. */ - private int offset; - - private int refnum; - /** generation of the object. */ - private int generation; - - // constructors - /** - * Constructs a cross-reference element for a PdfIndirectObject. - * @param refnum - * @param offset byte offset of the object - * @param generation generationnumber of the object - */ - - PdfCrossReference(int refnum, int offset, int generation) { - type = 0; - this.offset = offset; - this.refnum = refnum; - this.generation = generation; - } - - /** - * Constructs a cross-reference element for a PdfIndirectObject. - * @param refnum - * @param offset byte offset of the object - */ - - PdfCrossReference(int refnum, int offset) { - type = 1; - this.offset = offset; - this.refnum = refnum; - this.generation = 0; - } - - PdfCrossReference(int type, int refnum, int offset, int generation) { - this.type = type; - this.offset = offset; - this.refnum = refnum; - this.generation = generation; - } - - int getRefnum() { - return refnum; - } - - /** - * Returns the PDF representation of this PdfObject. - * @param os - * @throws IOException - */ - - public void toPdf(OutputStream os) throws IOException { - // This code makes it more difficult to port the lib to JDK1.1.x: - // StringBuffer off = new StringBuffer("0000000000").append(offset); - // off.delete(0, off.length() - 10); - // StringBuffer gen = new StringBuffer("00000").append(generation); - // gen.delete(0, gen.length() - 5); - // so it was changed into this: - String s = "0000000000" + offset; - StringBuffer off = new StringBuffer(s.substring(s.length() - 10)); - s = "00000" + generation; - String gen = s.substring(s.length() - 5); - if (generation == 65535) { - os.write(getISOBytes(off.append(' ').append(gen).append(" f \n").toString())); - } - else - os.write(getISOBytes(off.append(' ').append(gen).append(" n \n").toString())); - } - - /** - * Writes PDF syntax to the OutputStream - * @param midSize - * @param os - * @throws IOException - */ - public void toPdf(int midSize, OutputStream os) throws IOException { - os.write((byte)type); - while (--midSize >= 0) - os.write((byte)((offset >>> (8 * midSize)) & 0xff)); - os.write((byte)((generation >>> 8) & 0xff)); - os.write((byte)(generation & 0xff)); - } - - /** - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(Object o) { - PdfCrossReference other = (PdfCrossReference)o; - return (refnum < other.refnum ? -1 : (refnum==other.refnum ? 0 : 1)); - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object obj) { - if (obj instanceof PdfCrossReference) { - PdfCrossReference other = (PdfCrossReference)obj; - return (refnum == other.refnum); - } - else - return false; - } - - } - - // membervariables - - /** array containing the cross-reference table of the normal objects. */ - private TreeSet xrefs; - private int refnum; - /** the current byteposition in the body. */ - private int position; - private PdfWriter writer; - // constructors - - /** - * Constructs a new PdfBody. - * @param writer - */ - PdfBody(PdfWriter writer) { - xrefs = new TreeSet(); - xrefs.add(new PdfCrossReference(0, 0, 65535)); - position = writer.getOs().getCounter(); - refnum = 1; - this.writer = writer; - } - - void setRefnum(int refnum) { - this.refnum = refnum; - } - - // methods - - private static final int OBJSINSTREAM = 200; - - private ByteBuffer index; - private ByteBuffer streamObjects; - private int currentObjNum; - private int numObj = 0; - - private PdfWriter.PdfBody.PdfCrossReference addToObjStm(PdfObject obj, int nObj) throws IOException { - if (numObj >= OBJSINSTREAM) - flushObjStm(); - if (index == null) { - index = new ByteBuffer(); - streamObjects = new ByteBuffer(); - currentObjNum = getIndirectReferenceNumber(); - numObj = 0; - } - int p = streamObjects.size(); - int idx = numObj++; - PdfEncryption enc = writer.crypto; - writer.crypto = null; - obj.toPdf(writer, streamObjects); - writer.crypto = enc; - streamObjects.append(' '); - index.append(nObj).append(' ').append(p).append(' '); - return new PdfWriter.PdfBody.PdfCrossReference(2, nObj, currentObjNum, idx); - } - - private void flushObjStm() throws IOException { - if (numObj == 0) - return; - int first = index.size(); - index.append(streamObjects); - PdfStream stream = new PdfStream(index.toByteArray()); - stream.flateCompress(); - stream.put(PdfName.TYPE, PdfName.OBJSTM); - stream.put(PdfName.N, new PdfNumber(numObj)); - stream.put(PdfName.FIRST, new PdfNumber(first)); - add(stream, currentObjNum); - index = null; - streamObjects = null; - numObj = 0; - } - - /** - * Adds a PdfObject to the body. - *

- * This methods creates a PdfIndirectObject with a - * certain number, containing the given PdfObject. - * It also adds a PdfCrossReference for this object - * to an ArrayList that will be used to build the - * Cross-reference Table. - * - * @param object a PdfObject - * @return a PdfIndirectObject - * @throws IOException - */ - - PdfIndirectObject add(PdfObject object) throws IOException { - return add(object, getIndirectReferenceNumber()); - } - - PdfIndirectObject add(PdfObject object, boolean inObjStm) throws IOException { - return add(object, getIndirectReferenceNumber(), inObjStm); - } - - /** - * Gets a PdfIndirectReference for an object that will be created in the future. - * @return a PdfIndirectReference - */ - - PdfIndirectReference getPdfIndirectReference() { - return new PdfIndirectReference(0, getIndirectReferenceNumber()); - } - - int getIndirectReferenceNumber() { - int n = refnum++; - xrefs.add(new PdfCrossReference(n, 0, 65536)); - return n; - } - - /** - * Adds a PdfObject to the body given an already existing - * PdfIndirectReference. - *

- * This methods creates a PdfIndirectObject with the number given by - * ref, containing the given PdfObject. - * It also adds a PdfCrossReference for this object - * to an ArrayList that will be used to build the - * Cross-reference Table. - * - * @param object a PdfObject - * @param ref a PdfIndirectReference - * @return a PdfIndirectObject - * @throws IOException - */ - - PdfIndirectObject add(PdfObject object, PdfIndirectReference ref) throws IOException { - return add(object, ref.getNumber()); - } - - PdfIndirectObject add(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { - return add(object, ref.getNumber(), inObjStm); - } - - PdfIndirectObject add(PdfObject object, int refNumber) throws IOException { - return add(object, refNumber, true); // to false - } - - PdfIndirectObject add(PdfObject object, int refNumber, boolean inObjStm) throws IOException { - if (inObjStm && object.canBeInObjStm() && writer.isFullCompression()) { - PdfCrossReference pxref = addToObjStm(object, refNumber); - PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); - if (!xrefs.add(pxref)) { - xrefs.remove(pxref); - xrefs.add(pxref); - } - return indirect; - } - else { - PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, writer); - PdfCrossReference pxref = new PdfCrossReference(refNumber, position); - if (!xrefs.add(pxref)) { - xrefs.remove(pxref); - xrefs.add(pxref); - } - indirect.writeTo(writer.getOs()); - position = writer.getOs().getCounter(); - return indirect; - } - } - - /** - * Adds a PdfResources object to the body. - * - * @param object the PdfResources - * @return a PdfIndirectObject - */ - -// PdfIndirectObject add(PdfResources object) { -// return add(object); -// } - - /** - * Adds a PdfPages object to the body. - * - * @param object the root of the document - * @return a PdfIndirectObject - */ - -// PdfIndirectObject add(PdfPages object) throws IOException { -// PdfIndirectObject indirect = new PdfIndirectObject(PdfWriter.ROOT, object, writer); -// rootOffset = position; -// indirect.writeTo(writer.getOs()); -// position = writer.getOs().getCounter(); -// return indirect; -// } - - /** - * Returns the offset of the Cross-Reference table. - * - * @return an offset - */ - - int offset() { - return position; - } - - /** - * Returns the total number of objects contained in the CrossReferenceTable of this Body. - * - * @return a number of objects - */ - - int size() { - return Math.max(((PdfCrossReference)xrefs.last()).getRefnum() + 1, refnum); - } - - /** - * Returns the CrossReferenceTable of the Body. - * @param os - * @param root - * @param info - * @param encryption - * @param fileID - * @param prevxref - * @throws IOException - */ - - void writeCrossReferenceTable(OutputStream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) throws IOException { - int refNumber = 0; - if (writer.isFullCompression()) { - flushObjStm(); - refNumber = getIndirectReferenceNumber(); - xrefs.add(new PdfCrossReference(refNumber, position)); - } - PdfCrossReference entry = (PdfCrossReference)xrefs.first(); - int first = entry.getRefnum(); - int len = 0; - ArrayList sections = new ArrayList(); - for (Iterator i = xrefs.iterator(); i.hasNext(); ) { - entry = (PdfCrossReference)i.next(); - if (first + len == entry.getRefnum()) - ++len; - else { - sections.add(new Integer(first)); - sections.add(new Integer(len)); - first = entry.getRefnum(); - len = 1; - } - } - sections.add(new Integer(first)); - sections.add(new Integer(len)); - if (writer.isFullCompression()) { - int mid = 4; - int mask = 0xff000000; - for (; mid > 1; --mid) { - if ((mask & position) != 0) - break; - mask >>>= 8; - } - ByteBuffer buf = new ByteBuffer(); - - for (Iterator i = xrefs.iterator(); i.hasNext(); ) { - entry = (PdfCrossReference) i.next(); - entry.toPdf(mid, buf); - } - PdfStream xr = new PdfStream(buf.toByteArray()); - buf = null; - xr.flateCompress(); - xr.put(PdfName.SIZE, new PdfNumber(size())); - xr.put(PdfName.ROOT, root); - if (info != null) { - xr.put(PdfName.INFO, info); - } - if (encryption != null) - xr.put(PdfName.ENCRYPT, encryption); - if (fileID != null) - xr.put(PdfName.ID, fileID); - xr.put(PdfName.W, new PdfArray(new int[]{1, mid, 2})); - xr.put(PdfName.TYPE, PdfName.XREF); - PdfArray idx = new PdfArray(); - for (int k = 0; k < sections.size(); ++k) - idx.add(new PdfNumber(((Integer)sections.get(k)).intValue())); - xr.put(PdfName.INDEX, idx); - if (prevxref > 0) - xr.put(PdfName.PREV, new PdfNumber(prevxref)); - PdfEncryption enc = writer.crypto; - writer.crypto = null; - PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer); - indirect.writeTo(writer.getOs()); - writer.crypto = enc; - } - else { - os.write(getISOBytes("xref\n")); - Iterator i = xrefs.iterator(); - for (int k = 0; k < sections.size(); k += 2) { - first = ((Integer)sections.get(k)).intValue(); - len = ((Integer)sections.get(k + 1)).intValue(); - os.write(getISOBytes(String.valueOf(first))); - os.write(getISOBytes(" ")); - os.write(getISOBytes(String.valueOf(len))); - os.write('\n'); - while (len-- > 0) { - entry = (PdfCrossReference) i.next(); - entry.toPdf(os); - } - } - } - } - } - - /** - * PdfTrailer is the PDF Trailer object. - *

- * This object is described in the 'Portable Document Format Reference Manual version 1.3' - * section 5.16 (page 59-60). - */ - - static class PdfTrailer extends PdfDictionary { - - // membervariables - - int offset; - - // constructors - - /** - * Constructs a PDF-Trailer. - * - * @param size the number of entries in the PdfCrossReferenceTable - * @param offset offset of the PdfCrossReferenceTable - * @param root an indirect reference to the root of the PDF document - * @param info an indirect reference to the info object of the PDF document - * @param encryption - * @param fileID - * @param prevxref - */ - - PdfTrailer(int size, int offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, int prevxref) { - this.offset = offset; - put(PdfName.SIZE, new PdfNumber(size)); - put(PdfName.ROOT, root); - if (info != null) { - put(PdfName.INFO, info); - } - if (encryption != null) - put(PdfName.ENCRYPT, encryption); - if (fileID != null) - put(PdfName.ID, fileID); - if (prevxref > 0) - put(PdfName.PREV, new PdfNumber(prevxref)); - } - - /** - * Returns the PDF representation of this PdfObject. - * @param writer - * @param os - * @throws IOException - */ - public void toPdf(PdfWriter writer, OutputStream os) throws IOException { - os.write(getISOBytes("trailer\n")); - super.toPdf(null, os); - os.write(getISOBytes("\nstartxref\n")); - os.write(getISOBytes(String.valueOf(offset))); - os.write(getISOBytes("\n%%EOF\n")); - } - } - // static membervariables - - /** A viewer preference */ - public static final int PageLayoutSinglePage = 1; - /** A viewer preference */ - public static final int PageLayoutOneColumn = 2; - /** A viewer preference */ - public static final int PageLayoutTwoColumnLeft = 4; - /** A viewer preference */ - public static final int PageLayoutTwoColumnRight = 8; - /** A viewer preference */ - public static final int PageLayoutTwoPageLeft = 1 << 22; - /** A viewer preference */ - public static final int PageLayoutTwoPageRight = 1 << 23; - - /** A viewer preference */ - public static final int PageModeUseNone = 16; - /** A viewer preference */ - public static final int PageModeUseOutlines = 32; - /** A viewer preference */ - public static final int PageModeUseThumbs = 64; - /** A viewer preference */ - public static final int PageModeFullScreen = 128; - /** A viewer preference */ - public static final int PageModeUseOC = 1 << 20; - /** A viewer preference */ - public static final int PageModeUseAttachments = 1 << 24; - - /** A viewer preference */ - public static final int HideToolbar = 256; - /** A viewer preference */ - public static final int HideMenubar = 512; - /** A viewer preference */ - public static final int HideWindowUI = 1024; - /** A viewer preference */ - public static final int FitWindow = 2048; - /** A viewer preference */ - public static final int CenterWindow = 4096; - - /** A viewer preference */ - public static final int NonFullScreenPageModeUseNone = 8192; - /** A viewer preference */ - public static final int NonFullScreenPageModeUseOutlines = 16384; - /** A viewer preference */ - public static final int NonFullScreenPageModeUseThumbs = 32768; - /** A viewer preference */ - public static final int NonFullScreenPageModeUseOC = 1 << 19; - - /** A viewer preference */ - public static final int DirectionL2R = 1 << 16; - /** A viewer preference */ - public static final int DirectionR2L = 1 << 17; - /** A viewer preference */ - public static final int DisplayDocTitle = 1 << 18; - /** A viewer preference */ - public static final int PrintScalingNone = 1 << 21; - /** The mask to decide if a ViewerPreferences dictionary is needed */ - static final int ViewerPreferencesMask = 0xffff00; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowPrinting = 4 + 2048; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowModifyContents = 8; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowCopy = 16; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowModifyAnnotations = 32; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowFillIn = 256; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowScreenReaders = 512; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowAssembly = 1024; - /** The operation permitted when the document is opened with the user password */ - public static final int AllowDegradedPrinting = 4; - /** Type of encryption */ - public static final boolean STRENGTH40BITS = false; - /** Type of encryption */ - public static final boolean STRENGTH128BITS = true; - /** action value */ - public static final PdfName DOCUMENT_CLOSE = PdfName.WC; - /** action value */ - public static final PdfName WILL_SAVE = PdfName.WS; - /** action value */ - public static final PdfName DID_SAVE = PdfName.DS; - /** action value */ - public static final PdfName WILL_PRINT = PdfName.WP; - /** action value */ - public static final PdfName DID_PRINT = PdfName.DP; - /** action value */ - public static final PdfName PAGE_OPEN = PdfName.O; - /** action value */ - public static final PdfName PAGE_CLOSE = PdfName.C; - - /** signature value */ - public static final int SIGNATURE_EXISTS = 1; - /** signature value */ - public static final int SIGNATURE_APPEND_ONLY = 2; - - /** possible PDF version */ - public static final char VERSION_1_2 = '2'; - /** possible PDF version */ - public static final char VERSION_1_3 = '3'; - /** possible PDF version */ - public static final char VERSION_1_4 = '4'; - /** possible PDF version */ - public static final char VERSION_1_5 = '5'; - /** possible PDF version */ - public static final char VERSION_1_6 = '6'; - - private static final int VPOINT = 7; - /** this is the header of a PDF document */ - protected byte[] HEADER = getISOBytes("%PDF-1.4\n%\u00e2\u00e3\u00cf\u00d3\n"); - - protected int prevxref = 0; - - protected PdfPages root = new PdfPages(this); - - /** Dictionary, containing all the images of the PDF document */ - protected PdfDictionary imageDictionary = new PdfDictionary(); - - /** This is the list with all the images in the document. */ - private HashMap images = new HashMap(); - - /** The form XObjects in this document. The key is the xref and the value - is Object[]{PdfName, template}.*/ - protected HashMap formXObjects = new HashMap(); - - /** The name counter for the form XObjects name. */ - protected int formXObjectsCounter = 1; - - /** The font number counter for the fonts in the document. */ - protected int fontNumber = 1; - - /** The color number counter for the colors in the document. */ - protected int colorNumber = 1; - - /** The patten number counter for the colors in the document. */ - protected int patternNumber = 1; - - /** The direct content in this document. */ - protected PdfContentByte directContent; - - /** The direct content under in this document. */ - protected PdfContentByte directContentUnder; - - /** The fonts of this document */ - protected HashMap documentFonts = new HashMap(); - - /** The colors of this document */ - protected HashMap documentColors = new HashMap(); - - /** The patterns of this document */ - protected HashMap documentPatterns = new HashMap(); - - protected HashMap documentShadings = new HashMap(); - - protected HashMap documentShadingPatterns = new HashMap(); - - protected ColorDetails patternColorspaceRGB; - protected ColorDetails patternColorspaceGRAY; - protected ColorDetails patternColorspaceCMYK; - protected HashMap documentSpotPatterns = new HashMap(); - - protected HashMap documentExtGState = new HashMap(); - - protected HashMap documentProperties = new HashMap(); - protected HashSet documentOCG = new HashSet(); - protected ArrayList documentOCGorder = new ArrayList(); - protected PdfOCProperties OCProperties; - protected PdfArray OCGRadioGroup = new PdfArray(); - - protected PdfDictionary defaultColorspace = new PdfDictionary(); - protected float userunit = 0f; - - /** PDF/X value */ - public static final int PDFXNONE = 0; - /** PDF/X value */ - public static final int PDFX1A2001 = 1; - /** PDF/X value */ - public static final int PDFX32002 = 2; - - private int pdfxConformance = PDFXNONE; - - static final int PDFXKEY_COLOR = 1; - static final int PDFXKEY_CMYK = 2; - static final int PDFXKEY_RGB = 3; - static final int PDFXKEY_FONT = 4; - static final int PDFXKEY_IMAGE = 5; - static final int PDFXKEY_GSTATE = 6; - static final int PDFXKEY_LAYER = 7; - - // membervariables - - /** body of the PDF document */ - protected PdfBody body; - - /** the pdfdocument object. */ - protected PdfDocument pdf; - - /** The PdfPageEvent for this document. */ - private PdfPageEvent pageEvent; - - protected PdfEncryption crypto; - - protected HashMap importedPages = new HashMap(); - - protected PdfReaderInstance currentPdfReaderInstance; - - /** The PdfIndirectReference to the pages. */ - protected ArrayList pageReferences = new ArrayList(); - - protected int currentPageNumber = 1; - - protected PdfDictionary group; - - /** The default space-char ratio. */ - public static final float SPACE_CHAR_RATIO_DEFAULT = 2.5f; - /** Disable the inter-character spacing. */ - public static final float NO_SPACE_CHAR_RATIO = 10000000f; - - /** Use the default run direction. */ - public static final int RUN_DIRECTION_DEFAULT = 0; - /** Do not use bidirectional reordering. */ - public static final int RUN_DIRECTION_NO_BIDI = 1; - /** Use bidirectional reordering with left-to-right - * preferential run direction. - */ - public static final int RUN_DIRECTION_LTR = 2; - /** Use bidirectional reordering with right-to-left - * preferential run direction. - */ - public static final int RUN_DIRECTION_RTL = 3; - protected int runDirection = RUN_DIRECTION_NO_BIDI; - /** - * The ratio between the extra word spacing and the extra character spacing. - * Extra word spacing will grow ratio times more than extra character spacing. - */ - private float spaceCharRatio = SPACE_CHAR_RATIO_DEFAULT; - - /** Holds value of property extraCatalog. */ - private PdfDictionary extraCatalog; - - /** XMP Metadata for the document. */ - protected byte[] xmpMetadata = null; - /** - * Holds value of property fullCompression. - */ - protected boolean fullCompression = false; - - protected boolean tagged = false; - - protected PdfStructureTreeRoot structureTreeRoot; - - // constructor - - protected PdfWriter() { - } - - /** - * Constructs a PdfWriter. - *

- * Remark: a PdfWriter can only be constructed by calling the method - * getInstance(Document document, OutputStream os). - * - * @param document The PdfDocument that has to be written - * @param os The OutputStream the writer has to write to. - */ - - protected PdfWriter(PdfDocument document, OutputStream os) { - super(document, os); - pdf = document; - directContent = new PdfContentByte(this); - directContentUnder = new PdfContentByte(this); - } - - // get an instance of the PdfWriter - - /** - * Gets an instance of the PdfWriter. - * - * @param document The Document that has to be written - * @param os The OutputStream the writer has to write to. - * @return a new PdfWriter - * - * @throws DocumentException on error - */ - - public static PdfWriter getInstance(Document document, OutputStream os) - throws DocumentException { - PdfDocument pdf = new PdfDocument(); - document.addDocListener(pdf); - PdfWriter writer = new PdfWriter(pdf, os); - pdf.addWriter(writer); - return writer; - } - - /** Gets an instance of the PdfWriter. - * - * @return a new PdfWriter - * @param document The Document that has to be written - * @param os The OutputStream the writer has to write to. - * @param listener A DocListener to pass to the PdfDocument. - * @throws DocumentException on error - */ - - public static PdfWriter getInstance(Document document, OutputStream os, DocListener listener) - throws DocumentException { - PdfDocument pdf = new PdfDocument(); - pdf.addDocListener(listener); - document.addDocListener(pdf); - PdfWriter writer = new PdfWriter(pdf, os); - pdf.addWriter(writer); - return writer; - } - - // methods to write objects to the outputstream - - /** - * Adds some PdfContents to this Writer. - *

- * The document has to be open before you can begin to add content - * to the body of the document. - * - * @return a PdfIndirectReference - * @param page the PdfPage to add - * @param contents the PdfContents of the page - * @throws PdfException on error - */ - - PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException { - if (!open) { - throw new PdfException("The document isn't open."); - } - PdfIndirectObject object; - try { - object = addToBody(contents); - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - page.add(object.getIndirectReference()); - if (group != null) { - page.put(PdfName.GROUP, group); - group = null; - } - root.addPage(page); - currentPageNumber++; - return null; - } - - /** - * Adds an image to the document but not to the page resources. It is used with - * templates and Document.add(Image). - * @param image the Image to add - * @return the name of the image added - * @throws PdfException on error - * @throws DocumentException on error - */ - public PdfName addDirectImageSimple(Image image) throws PdfException, DocumentException { - return addDirectImageSimple(image, null); - } - - /** - * Adds an image to the document but not to the page resources. It is used with - * templates and Document.add(Image). - * @param image the Image to add - * @param fixedRef the reference to used. It may be null, - * a PdfIndirectReference or a PRIndirectReference. - * @return the name of the image added - * @throws PdfException on error - * @throws DocumentException on error - */ - public PdfName addDirectImageSimple(Image image, PdfIndirectReference fixedRef) throws PdfException, DocumentException { - PdfName name; - // if the images is already added, just retrieve the name - if (images.containsKey(image.getMySerialId())) { - name = (PdfName) images.get(image.getMySerialId()); - } - // if it's a new image, add it to the document - else { - if (image.isImgTemplate()) { - name = new PdfName("img" + images.size()); - if (image.templateData() == null) { - if(image instanceof ImgWMF){ - try { - ImgWMF wmf = (ImgWMF)image; - wmf.readWMF(getDirectContent().createTemplate(0, 0)); - } - catch (Exception e) { - throw new DocumentException(e); - } - }else{ - try { - ((ImgPostscript)image).readPostscript(getDirectContent().createTemplate(0, 0)); - } - catch (Exception e) { - throw new DocumentException(e); - } - - } - } - } - else { - PdfIndirectReference dref = image.getDirectReference(); - if (dref != null) { - PdfName rname = new PdfName("img" + images.size()); - images.put(image.getMySerialId(), rname); - imageDictionary.put(rname, dref); - return rname; - } - Image maskImage = image.getImageMask(); - PdfIndirectReference maskRef = null; - if (maskImage != null) { - PdfName mname = (PdfName)images.get(maskImage.getMySerialId()); - maskRef = getImageReference(mname); - } - PdfImage i = new PdfImage(image, "img" + images.size(), maskRef); - if (image.hasICCProfile()) { - PdfICCBased icc = new PdfICCBased(image.getICCProfile()); - PdfIndirectReference iccRef = add(icc); - PdfArray iccArray = new PdfArray(); - iccArray.add(PdfName.ICCBASED); - iccArray.add(iccRef); - PdfObject colorspace = i.get(PdfName.COLORSPACE); - if (colorspace != null && colorspace.isArray()) { - ArrayList ar = ((PdfArray)colorspace).getArrayList(); - if (ar.size() > 1 && PdfName.INDEXED.equals(ar.get(0))) - ar.set(1, iccArray); - else - i.put(PdfName.COLORSPACE, iccArray); - } - else - i.put(PdfName.COLORSPACE, iccArray); - } - add(i, fixedRef); - name = i.name(); - } - images.put(image.getMySerialId(), name); - } - return name; - } - - /** - * Writes a PdfImage to the outputstream. - * - * @param pdfImage the image to be added - * @return a PdfIndirectReference to the encapsulated image - * @throws PdfException when a document isn't open yet, or has been closed - */ - - PdfIndirectReference add(PdfImage pdfImage, PdfIndirectReference fixedRef) throws PdfException { - if (! imageDictionary.contains(pdfImage.name())) { - checkPDFXConformance(this, PDFXKEY_IMAGE, pdfImage); - if (fixedRef != null && fixedRef instanceof PRIndirectReference) { - PRIndirectReference r2 = (PRIndirectReference)fixedRef; - fixedRef = new PdfIndirectReference(0, getNewObjectNumber(r2.getReader(), r2.getNumber(), r2.getGeneration())); - } - try { - if (fixedRef == null) - fixedRef = addToBody(pdfImage).getIndirectReference(); - else - addToBody(pdfImage, fixedRef); - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - imageDictionary.put(pdfImage.name(), fixedRef); - return fixedRef; - } - return (PdfIndirectReference) imageDictionary.get(pdfImage.name()); - } - - protected PdfIndirectReference add(PdfICCBased icc) throws PdfException { - PdfIndirectObject object; - try { - object = addToBody(icc); - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - return object.getIndirectReference(); - } - - /** - * return the PdfIndirectReference to the image with a given name. - * - * @param name the name of the image - * @return a PdfIndirectReference - */ - - PdfIndirectReference getImageReference(PdfName name) { - return (PdfIndirectReference) imageDictionary.get(name); - } - - // methods to open and close the writer - - /** - * Signals that the Document has been opened and that - * Elements can be added. - *

- * When this method is called, the PDF-document header is - * written to the outputstream. - */ - - public void open() { - super.open(); - try { - os.write(HEADER); - body = new PdfBody(this); - if (pdfxConformance == PDFX32002) { - PdfDictionary sec = new PdfDictionary(); - sec.put(PdfName.GAMMA, new PdfArray(new float[]{2.2f,2.2f,2.2f})); - sec.put(PdfName.MATRIX, new PdfArray(new float[]{0.4124f,0.2126f,0.0193f,0.3576f,0.7152f,0.1192f,0.1805f,0.0722f,0.9505f})); - sec.put(PdfName.WHITEPOINT, new PdfArray(new float[]{0.9505f,1f,1.089f})); - PdfArray arr = new PdfArray(PdfName.CALRGB); - arr.add(sec); - setDefaultColorspace(PdfName.DEFAULTRGB, addToBody(arr).getIndirectReference()); - } - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - } - - private static void getOCGOrder(PdfArray order, PdfLayer layer) { - if (!layer.isOnPanel()) - return; - if (layer.getTitle() == null) - order.add(layer.getRef()); - ArrayList children = layer.getChildren(); - if (children == null) - return; - PdfArray kids = new PdfArray(); - if (layer.getTitle() != null) - kids.add(new PdfString(layer.getTitle(), PdfObject.TEXT_UNICODE)); - for (int k = 0; k < children.size(); ++k) { - getOCGOrder(kids, (PdfLayer)children.get(k)); - } - if (kids.size() > 0) - order.add(kids); - } - - private void addASEvent(PdfName event, PdfName category) { - PdfArray arr = new PdfArray(); - for (Iterator it = documentOCG.iterator(); it.hasNext();) { - PdfLayer layer = (PdfLayer)it.next(); - PdfDictionary usage = (PdfDictionary)layer.get(PdfName.USAGE); - if (usage != null && usage.get(category) != null) - arr.add(layer.getRef()); - } - if (arr.size() == 0) - return; - PdfDictionary d = (PdfDictionary)OCProperties.get(PdfName.D); - PdfArray arras = (PdfArray)d.get(PdfName.AS); - if (arras == null) { - arras = new PdfArray(); - d.put(PdfName.AS, arras); - } - PdfDictionary as = new PdfDictionary(); - as.put(PdfName.EVENT, event); - as.put(PdfName.CATEGORY, new PdfArray(category)); - as.put(PdfName.OCGS, arr); - arras.add(as); - } - - private void fillOCProperties(boolean erase) { - if (OCProperties == null) - OCProperties = new PdfOCProperties(); - if (erase) { - OCProperties.remove(PdfName.OCGS); - OCProperties.remove(PdfName.D); - } - if (OCProperties.get(PdfName.OCGS) == null) { - PdfArray gr = new PdfArray(); - for (Iterator it = documentOCG.iterator(); it.hasNext();) { - PdfLayer layer = (PdfLayer)it.next(); - gr.add(layer.getRef()); - } - OCProperties.put(PdfName.OCGS, gr); - } - if (OCProperties.get(PdfName.D) != null) - return; - ArrayList docOrder = new ArrayList(documentOCGorder); - for (Iterator it = docOrder.iterator(); it.hasNext();) { - PdfLayer layer = (PdfLayer)it.next(); - if (layer.getParent() != null) - it.remove(); - } - PdfArray order = new PdfArray(); - for (Iterator it = docOrder.iterator(); it.hasNext();) { - PdfLayer layer = (PdfLayer)it.next(); - getOCGOrder(order, layer); - } - PdfDictionary d = new PdfDictionary(); - OCProperties.put(PdfName.D, d); - d.put(PdfName.ORDER, order); - PdfArray gr = new PdfArray(); - for (Iterator it = documentOCG.iterator(); it.hasNext();) { - PdfLayer layer = (PdfLayer)it.next(); - if (!layer.isOn()) - gr.add(layer.getRef()); - } - if (gr.size() > 0) - d.put(PdfName.OFF, gr); - if (OCGRadioGroup.size() > 0) - d.put(PdfName.RBGROUPS, OCGRadioGroup); - addASEvent(PdfName.VIEW, PdfName.ZOOM); - addASEvent(PdfName.VIEW, PdfName.VIEW); - addASEvent(PdfName.PRINT, PdfName.PRINT); - addASEvent(PdfName.EXPORT, PdfName.EXPORT); - d.put(PdfName.LISTMODE, PdfName.VISIBLEPAGES); - } - - protected PdfDictionary getCatalog(PdfIndirectReference rootObj) - { - PdfDictionary catalog = ((PdfDocument)document).getCatalog(rootObj); - if (tagged) { - try { - getStructureTreeRoot().buildTree(); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - catalog.put(PdfName.STRUCTTREEROOT, structureTreeRoot.getReference()); - PdfDictionary mi = new PdfDictionary(); - mi.put(PdfName.MARKED, PdfBoolean.PDFTRUE); - catalog.put(PdfName.MARKINFO, mi); - } - if (documentOCG.size() == 0) - return catalog; - fillOCProperties(false); - catalog.put(PdfName.OCPROPERTIES, OCProperties); - return catalog; - } - - protected void addSharedObjectsToBody() throws IOException { - // add the fonts - for (Iterator it = documentFonts.values().iterator(); it.hasNext();) { - FontDetails details = (FontDetails)it.next(); - details.writeFont(this); - } - // add the form XObjects - for (Iterator it = formXObjects.values().iterator(); it.hasNext();) { - Object objs[] = (Object[])it.next(); - PdfTemplate template = (PdfTemplate)objs[1]; - if (template != null && template.getIndirectReference() instanceof PRIndirectReference) - continue; - if (template != null && template.getType() == PdfTemplate.TYPE_TEMPLATE) { - addToBody(template.getFormXObject(), template.getIndirectReference()); - } - } - // add all the dependencies in the imported pages - for (Iterator it = importedPages.values().iterator(); it.hasNext();) { - currentPdfReaderInstance = (PdfReaderInstance)it.next(); - currentPdfReaderInstance.writeAllPages(); - } - currentPdfReaderInstance = null; - // add the color - for (Iterator it = documentColors.values().iterator(); it.hasNext();) { - ColorDetails color = (ColorDetails)it.next(); - addToBody(color.getSpotColor(this), color.getIndirectReference()); - } - // add the pattern - for (Iterator it = documentPatterns.keySet().iterator(); it.hasNext();) { - PdfPatternPainter pat = (PdfPatternPainter)it.next(); - addToBody(pat.getPattern(), pat.getIndirectReference()); - } - // add the shading patterns - for (Iterator it = documentShadingPatterns.keySet().iterator(); it.hasNext();) { - PdfShadingPattern shadingPattern = (PdfShadingPattern)it.next(); - shadingPattern.addToBody(); - } - // add the shadings - for (Iterator it = documentShadings.keySet().iterator(); it.hasNext();) { - PdfShading shading = (PdfShading)it.next(); - shading.addToBody(); - } - // add the extgstate - for (Iterator it = documentExtGState.keySet().iterator(); it.hasNext();) { - PdfDictionary gstate = (PdfDictionary)it.next(); - PdfObject obj[] = (PdfObject[])documentExtGState.get(gstate); - addToBody(gstate, (PdfIndirectReference)obj[1]); - } - // add the properties - for (Iterator it = documentProperties.keySet().iterator(); it.hasNext();) { - Object prop = it.next(); - PdfObject[] obj = (PdfObject[])documentProperties.get(prop); - if (prop instanceof PdfLayerMembership){ - PdfLayerMembership layer = (PdfLayerMembership)prop; - addToBody(layer.getPdfObject(), layer.getRef()); - } - else if ((prop instanceof PdfDictionary) && !(prop instanceof PdfLayer)){ - addToBody((PdfDictionary)prop, (PdfIndirectReference)obj[1]); - } - } - for (Iterator it = documentOCG.iterator(); it.hasNext();) { - PdfOCG layer = (PdfOCG)it.next(); - addToBody(layer.getPdfObject(), layer.getRef()); - } - } - - /** - * Signals that the Document was closed and that no other - * Elements will be added. - *

- * The pages-tree is built and written to the outputstream. - * A Catalog is constructed, as well as an Info-object, - * the referencetable is composed and everything is written - * to the outputstream embedded in a Trailer. - */ - - public synchronized void close() { - if (open) { - if ((currentPageNumber - 1) != pageReferences.size()) - throw new RuntimeException("The page " + pageReferences.size() + - " was requested but the document has only " + (currentPageNumber - 1) + " pages."); - pdf.close(); - try { - addSharedObjectsToBody(); - // add the root to the body - PdfIndirectReference rootRef = root.writePageTree(); - // make the catalog-object and add it to the body - PdfDictionary catalog = getCatalog(rootRef); - // if there is XMP data to add: add it - if (xmpMetadata != null) { - PdfStream xmp = new PdfStream(xmpMetadata); - xmp.put(PdfName.TYPE, PdfName.METADATA); - xmp.put(PdfName.SUBTYPE, PdfName.XML); - catalog.put(PdfName.METADATA, body.add(xmp).getIndirectReference()); - } - // make pdfx conformant - PdfDictionary info = getInfo(); - if (pdfxConformance != PDFXNONE) { - if (info.get(PdfName.GTS_PDFXVERSION) == null) { - if (pdfxConformance == PDFX1A2001) { - info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-1:2001")); - info.put(new PdfName("GTS_PDFXConformance"), new PdfString("PDF/X-1a:2001")); - } - else if (pdfxConformance == PDFX32002) - info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-3:2002")); - } - if (info.get(PdfName.TITLE) == null) { - info.put(PdfName.TITLE, new PdfString("Pdf document")); - } - if (info.get(PdfName.CREATOR) == null) { - info.put(PdfName.CREATOR, new PdfString("Unknown")); - } - if (info.get(PdfName.TRAPPED) == null) { - info.put(PdfName.TRAPPED, new PdfName("False")); - } - getExtraCatalog(); - if (extraCatalog.get(PdfName.OUTPUTINTENTS) == null) { - PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT); - out.put(PdfName.OUTPUTCONDITION, new PdfString("SWOP CGATS TR 001-1995")); - out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("CGATS TR 001")); - out.put(PdfName.REGISTRYNAME, new PdfString("http://www.color.org")); - out.put(PdfName.INFO, new PdfString("")); - out.put(PdfName.S, PdfName.GTS_PDFX); - extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out)); - } - } - if (extraCatalog != null) { - catalog.mergeDifferent(extraCatalog); - } - PdfIndirectObject indirectCatalog = addToBody(catalog, false); - // add the info-object to the body - PdfIndirectObject infoObj = addToBody(info, false); - PdfIndirectReference encryption = null; - PdfObject fileID = null; - body.flushObjStm(); - if (crypto != null) { - PdfIndirectObject encryptionObject = addToBody(crypto.getEncryptionDictionary(), false); - encryption = encryptionObject.getIndirectReference(); - fileID = crypto.getFileID(); - } - else - fileID = PdfEncryption.createInfoId(PdfEncryption.createDocumentId()); - - // write the cross-reference table of the body - body.writeCrossReferenceTable(os, indirectCatalog.getIndirectReference(), - infoObj.getIndirectReference(), encryption, fileID, prevxref); - - // make the trailer - if (fullCompression) { - os.write(getISOBytes("startxref\n")); - os.write(getISOBytes(String.valueOf(body.offset()))); - os.write(getISOBytes("\n%%EOF\n")); - } - else { - PdfTrailer trailer = new PdfTrailer(body.size(), - body.offset(), - indirectCatalog.getIndirectReference(), - infoObj.getIndirectReference(), - encryption, - fileID, prevxref); - trailer.toPdf(this, os); - } - super.close(); - } - catch(IOException ioe) { - throw new ExceptionConverter(ioe); - } - } - } - - // methods - - /** - * Sometimes it is necessary to know where the just added Table ends. - * - * For instance to avoid to add another table in a page that is ending up, because - * the new table will be probably splitted just after the header (it is an - * unpleasant effect, isn't it?). - * - * Added on September 8th, 2001 - * by Francesco De Milato - * francesco.demilato@tiscalinet.it - * @param table the Table - * @return the bottom height of the just added table - */ - - public float getTableBottom(Table table) { - return pdf.bottom(table) - pdf.indentBottom(); - } - - /** - * Gets a pre-rendered table. - * (Contributed by dperezcar@fcc.es) - * @param table Contains the table definition. Its contents are deleted, after being pre-rendered. - * @return a PdfTable - */ - - public PdfTable getPdfTable(Table table) { - return pdf.getPdfTable(table, true); - } - - /** - * Row additions to the original {@link Table} used to build the {@link PdfTable} are processed and pre-rendered, - * and then the contents are deleted. - * If the pre-rendered table doesn't fit, then it is fully rendered and its data discarded. - * There shouldn't be any column change in the underlying {@link Table} object. - * (Contributed by dperezcar@fcc.es) - * - * @param table The pre-rendered table obtained from {@link #getPdfTable(Table)} - * @return true if the table is rendered and emptied. - * @throws DocumentException - * @see #getPdfTable(Table) - */ - - public boolean breakTableIfDoesntFit(PdfTable table) throws DocumentException { - return pdf.breakTableIfDoesntFit(table); - } - - /** - * Checks if a Table fits the current page of the PdfDocument. - * - * @param table the table that has to be checked - * @param margin a certain margin - * @return true if the Table fits the page, false otherwise. - */ - - public boolean fitsPage(Table table, float margin) { - return pdf.bottom(table) > pdf.indentBottom() + margin; - } - - /** - * Checks if a Table fits the current page of the PdfDocument. - * - * @param table the table that has to be checked - * @return true if the Table fits the page, false otherwise. - */ - - public boolean fitsPage(Table table) { - return fitsPage(table, 0); - } - - /** - * Checks if a PdfPTable fits the current page of the PdfDocument. - * - * @param table the table that has to be checked - * @param margin a certain margin - * @return true if the PdfPTable fits the page, false otherwise. - */ - public boolean fitsPage(PdfPTable table, float margin) { - return pdf.fitsPage(table, margin); - } - - /** - * Checks if a PdfPTable fits the current page of the PdfDocument. - * - * @param table the table that has to be checked - * @return true if the PdfPTable fits the page, false otherwise. - */ - public boolean fitsPage(PdfPTable table) { - return pdf.fitsPage(table, 0); - } - - /** - * Gets the current vertical page position. - * @param ensureNewLine Tells whether a new line shall be enforced. This may cause side effects - * for elements that do not terminate the lines they've started because those lines will get - * terminated. - * @return The current vertical page position. - */ - public float getVerticalPosition(boolean ensureNewLine) { - return pdf.getVerticalPosition(ensureNewLine); - } - - /** - * Checks if writing is paused. - * - * @return true if writing temporarely has to be paused, false otherwise. - */ - - boolean isPaused() { - return pause; - } - - /** - * Gets the direct content for this document. There is only one direct content, - * multiple calls to this method will allways retrieve the same. - * @return the direct content - */ - - public PdfContentByte getDirectContent() { - if (!open) - throw new RuntimeException("The document is not open."); - return directContent; - } - - /** - * Gets the direct content under for this document. There is only one direct content, - * multiple calls to this method will allways retrieve the same. - * @return the direct content - */ - - public PdfContentByte getDirectContentUnder() { - if (!open) - throw new RuntimeException("The document is not open."); - return directContentUnder; - } - - /** - * Resets all the direct contents to empty. This happens when a new page is started. - */ - - void resetContent() { - directContent.reset(); - directContentUnder.reset(); - } - - /** Gets the AcroForm object. - * @return the PdfAcroForm - */ - - public PdfAcroForm getAcroForm() { - return pdf.getAcroForm(); - } - - /** Gets the root outline. - * @return the root outline - */ - - public PdfOutline getRootOutline() { - return directContent.getRootOutline(); - } - - /** - * Returns the outputStreamCounter. - * @return the outputStreamCounter - */ - public OutputStreamCounter getOs() { - return os; - } - - /** - * Adds a BaseFont to the document but not to the page resources. - * It is used for templates. - * @param bf the BaseFont to add - * @return an Object[] where position 0 is a PdfName - * and position 1 is an PdfIndirectReference - */ - - FontDetails addSimple(BaseFont bf) { - if (bf.getFontType() == BaseFont.FONT_TYPE_DOCUMENT) { - return new FontDetails(new PdfName("F" + (fontNumber++)), ((DocumentFont)bf).getIndirectReference(), bf); - } - FontDetails ret = (FontDetails)documentFonts.get(bf); - if (ret == null) { - checkPDFXConformance(this, PDFXKEY_FONT, bf); - ret = new FontDetails(new PdfName("F" + (fontNumber++)), body.getPdfIndirectReference(), bf); - documentFonts.put(bf, ret); - } - return ret; - } - - void eliminateFontSubset(PdfDictionary fonts) { - for (Iterator it = documentFonts.values().iterator(); it.hasNext();) { - FontDetails ft = (FontDetails)it.next(); - if (fonts.get(ft.getFontName()) != null) - ft.setSubset(false); - } - } - - PdfName getColorspaceName() { - return new PdfName("CS" + (colorNumber++)); - } - - /** - * Adds a SpotColor to the document but not to the page resources. - * @param spc the SpotColor to add - * @return an Object[] where position 0 is a PdfName - * and position 1 is an PdfIndirectReference - */ - - ColorDetails addSimple(PdfSpotColor spc) { - ColorDetails ret = (ColorDetails)documentColors.get(spc); - if (ret == null) { - ret = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), spc); - documentColors.put(spc, ret); - } - return ret; - } - - ColorDetails addSimplePatternColorspace(Color color) { - int type = ExtendedColor.getType(color); - if (type == ExtendedColor.TYPE_PATTERN || type == ExtendedColor.TYPE_SHADING) - throw new RuntimeException("An uncolored tile pattern can not have another pattern or shading as color."); - try { - switch (type) { - case ExtendedColor.TYPE_RGB: - if (patternColorspaceRGB == null) { - patternColorspaceRGB = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); - PdfArray array = new PdfArray(PdfName.PATTERN); - array.add(PdfName.DEVICERGB); - addToBody(array, patternColorspaceRGB.getIndirectReference()); - } - return patternColorspaceRGB; - case ExtendedColor.TYPE_CMYK: - if (patternColorspaceCMYK == null) { - patternColorspaceCMYK = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); - PdfArray array = new PdfArray(PdfName.PATTERN); - array.add(PdfName.DEVICECMYK); - addToBody(array, patternColorspaceCMYK.getIndirectReference()); - } - return patternColorspaceCMYK; - case ExtendedColor.TYPE_GRAY: - if (patternColorspaceGRAY == null) { - patternColorspaceGRAY = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); - PdfArray array = new PdfArray(PdfName.PATTERN); - array.add(PdfName.DEVICEGRAY); - addToBody(array, patternColorspaceGRAY.getIndirectReference()); - } - return patternColorspaceGRAY; - case ExtendedColor.TYPE_SEPARATION: { - ColorDetails details = addSimple(((SpotColor)color).getPdfSpotColor()); - ColorDetails patternDetails = (ColorDetails)documentSpotPatterns.get(details); - if (patternDetails == null) { - patternDetails = new ColorDetails(getColorspaceName(), body.getPdfIndirectReference(), null); - PdfArray array = new PdfArray(PdfName.PATTERN); - array.add(details.getIndirectReference()); - addToBody(array, patternDetails.getIndirectReference()); - documentSpotPatterns.put(details, patternDetails); - } - return patternDetails; - } - default: - throw new RuntimeException("Invalid color type in PdfWriter.addSimplePatternColorspace()."); - } - } - catch (Exception e) { - throw new RuntimeException(e.getMessage()); - } - } - - void addSimpleShadingPattern(PdfShadingPattern shading) { - if (!documentShadingPatterns.containsKey(shading)) { - shading.setName(patternNumber); - ++patternNumber; - documentShadingPatterns.put(shading, null); - addSimpleShading(shading.getShading()); - } - } - - void addSimpleShading(PdfShading shading) { - if (!documentShadings.containsKey(shading)) { - documentShadings.put(shading, null); - shading.setName(documentShadings.size()); - } - } - - PdfObject[] addSimpleExtGState(PdfDictionary gstate) { - if (!documentExtGState.containsKey(gstate)) { - checkPDFXConformance(this, PDFXKEY_GSTATE, gstate); - documentExtGState.put(gstate, new PdfObject[]{new PdfName("GS" + (documentExtGState.size() + 1)), getPdfIndirectReference()}); - } - return (PdfObject[])documentExtGState.get(gstate); - } - - void registerLayer(PdfOCG layer) { - checkPDFXConformance(this, PDFXKEY_LAYER, null); - if (layer instanceof PdfLayer) { - PdfLayer la = (PdfLayer)layer; - if (la.getTitle() == null) { - if (!documentOCG.contains(layer)) { - documentOCG.add(layer); - documentOCGorder.add(layer); - } - } - else { - documentOCGorder.add(layer); - } - } - else - throw new IllegalArgumentException("Only PdfLayer is accepted."); - } - - PdfObject[] addSimpleProperty(Object prop, PdfIndirectReference refi) { - if (!documentProperties.containsKey(prop)) { - if (prop instanceof PdfOCG) - checkPDFXConformance(this, PDFXKEY_LAYER, null); - documentProperties.put(prop, new PdfObject[]{new PdfName("Pr" + (documentProperties.size() + 1)), refi}); - } - return (PdfObject[])documentProperties.get(prop); - } - - boolean propertyExists(Object prop) { - return documentProperties.containsKey(prop); - } - /** - * Gets the PdfDocument associated with this writer. - * @return the PdfDocument - */ - - PdfDocument getPdfDocument() { - return pdf; - } - - /** - * Gets a PdfIndirectReference for an object that - * will be created in the future. - * @return the PdfIndirectReference - */ - - public PdfIndirectReference getPdfIndirectReference() { - return body.getPdfIndirectReference(); - } - - int getIndirectReferenceNumber() { - return body.getIndirectReferenceNumber(); - } - - PdfName addSimplePattern(PdfPatternPainter painter) { - PdfName name = (PdfName)documentPatterns.get(painter); - try { - if ( name == null ) { - name = new PdfName("P" + patternNumber); - ++patternNumber; - documentPatterns.put(painter, name); - } - } catch (Exception e) { - throw new ExceptionConverter(e); - } - return name; - } - - /** - * Adds a template to the document but not to the page resources. - * @param template the template to add - * @param forcedName the template name, rather than a generated one. Can be null - * @return the PdfName for this template - */ - - PdfName addDirectTemplateSimple(PdfTemplate template, PdfName forcedName) { - PdfIndirectReference ref = template.getIndirectReference(); - Object obj[] = (Object[])formXObjects.get(ref); - PdfName name = null; - try { - if (obj == null) { - if (forcedName == null) { - name = new PdfName("Xf" + formXObjectsCounter); - ++formXObjectsCounter; - } - else - name = forcedName; - if (template.getType() == PdfTemplate.TYPE_IMPORTED) - template = null; - formXObjects.put(ref, new Object[]{name, template}); - } - else - name = (PdfName)obj[0]; - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - return name; - } - - /** - * Sets the PdfPageEvent for this document. - * @param event the PdfPageEvent for this document - */ - - public void setPageEvent(PdfPageEvent event) { - if (event == null) this.pageEvent = null; - else if (this.pageEvent == null) this.pageEvent = event; - else if (this.pageEvent instanceof PdfPageEventForwarder) ((PdfPageEventForwarder)this.pageEvent).addPageEvent(event); - else { - PdfPageEventForwarder forward = new PdfPageEventForwarder(); - forward.addPageEvent(this.pageEvent); - forward.addPageEvent(event); - this.pageEvent = forward; - } - } - - /** - * Gets the PdfPageEvent for this document or null - * if none is set. - * @return the PdfPageEvent for this document or null - * if none is set - */ - - public PdfPageEvent getPageEvent() { - return pageEvent; - } - - /** - * Adds the local destinations to the body of the document. - * @param dest the HashMap containing the destinations - * @throws IOException on error - */ - - void addLocalDestinations(TreeMap dest) throws IOException { - for (Iterator i = dest.keySet().iterator(); i.hasNext();) { - String name = (String)i.next(); - Object obj[] = (Object[])dest.get(name); - PdfDestination destination = (PdfDestination)obj[2]; - if (destination == null) - throw new RuntimeException("The name '" + name + "' has no local destination."); - if (obj[1] == null) - obj[1] = getPdfIndirectReference(); - addToBody(destination, (PdfIndirectReference)obj[1]); - } - } - - /** - * Gets the current pagenumber of this document. - * - * @return a page number - */ - - public int getPageNumber() { - return pdf.getPageNumber(); - } - - /** - * Sets the viewer preferences by ORing some constants. - *

- *

- * @param preferences the viewer preferences - */ - - public void setViewerPreferences(int preferences) { - pdf.setViewerPreferences(preferences); - } - - /** Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @param strength128Bits true for 128 bit key length, false for 40 bit key length - * @throws DocumentException if the document is already open - */ - public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException { - if (pdf.isOpen()) - throw new DocumentException("Encryption can only be added before opening the document."); - crypto = new PdfEncryption(); - crypto.setupAllKeys(userPassword, ownerPassword, permissions, strength128Bits); - } - - /** - * Sets the encryption options for this document. The userPassword and the - * ownerPassword can be null or have zero length. In this case the ownerPassword - * is replaced by a random string. The open permissions for the document can be - * AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations, - * AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting. - * The permissions can be combined by ORing them. - * @param strength true for 128 bit key length, false for 40 bit key length - * @param userPassword the user password. Can be null or empty - * @param ownerPassword the owner password. Can be null or empty - * @param permissions the user permissions - * @throws DocumentException if the document is already open - */ - public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException { - setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, strength); - } - - /** - * Adds an object to the PDF body. - * @param object - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object) throws IOException { - PdfIndirectObject iobj = body.add(object); - return iobj; - } - - /** - * Adds an object to the PDF body. - * @param object - * @param inObjStm - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object, boolean inObjStm) throws IOException { - PdfIndirectObject iobj = body.add(object, inObjStm); - return iobj; - } - - /** - * Adds an object to the PDF body. - * @param object - * @param ref - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref) throws IOException { - PdfIndirectObject iobj = body.add(object, ref); - return iobj; - } - - /** - * Adds an object to the PDF body. - * @param object - * @param ref - * @param inObjStm - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException { - PdfIndirectObject iobj = body.add(object, ref, inObjStm); - return iobj; - } - - /** - * Adds an object to the PDF body. - * @param object - * @param refNumber - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object, int refNumber) throws IOException { - PdfIndirectObject iobj = body.add(object, refNumber); - return iobj; - } - - /** - * Adds an object to the PDF body. - * @param object - * @param refNumber - * @param inObjStm - * @return a PdfIndirectObject - * @throws IOException - */ - public PdfIndirectObject addToBody(PdfObject object, int refNumber, boolean inObjStm) throws IOException { - PdfIndirectObject iobj = body.add(object, refNumber, inObjStm); - return iobj; - } - - /** When the document opens it will jump to the destination with - * this name. - * @param name the name of the destination to jump to - */ - public void setOpenAction(String name) { - pdf.setOpenAction(name); - } - - /** Additional-actions defining the actions to be taken in - * response to various trigger events affecting the document - * as a whole. The actions types allowed are: DOCUMENT_CLOSE, - * WILL_SAVE, DID_SAVE, WILL_PRINT - * and DID_PRINT. - * - * @param actionType the action type - * @param action the action to execute in response to the trigger - * @throws PdfException on invalid action type - */ - public void setAdditionalAction(PdfName actionType, PdfAction action) throws PdfException { - if (!(actionType.equals(DOCUMENT_CLOSE) || - actionType.equals(WILL_SAVE) || - actionType.equals(DID_SAVE) || - actionType.equals(WILL_PRINT) || - actionType.equals(DID_PRINT))) { - throw new PdfException("Invalid additional action type: " + actionType.toString()); - } - pdf.addAdditionalAction(actionType, action); - } - - /** When the document opens this action will be - * invoked. - * @param action the action to be invoked - */ - public void setOpenAction(PdfAction action) { - pdf.setOpenAction(action); - } - - /** Sets the page labels - * @param pageLabels the page labels - */ - public void setPageLabels(PdfPageLabels pageLabels) { - pdf.setPageLabels(pageLabels); - } - - PdfEncryption getEncryption() { - return crypto; - } - - RandomAccessFileOrArray getReaderFile(PdfReader reader) { - return currentPdfReaderInstance.getReaderFile(); - } - - protected int getNewObjectNumber(PdfReader reader, int number, int generation) { - return currentPdfReaderInstance.getNewObjectNumber(number, generation); - } - - /** Gets a page from other PDF document. The page can be used as - * any other PdfTemplate. Note that calling this method more than - * once with the same parameters will retrieve the same object. - * @param reader the PDF document where the page is - * @param pageNumber the page number. The first page is 1 - * @return the template representing the imported page - */ - public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) { - PdfReaderInstance inst = (PdfReaderInstance)importedPages.get(reader); - if (inst == null) { - inst = reader.getPdfReaderInstance(this); - importedPages.put(reader, inst); - } - return inst.getImportedPage(pageNumber); - } - - /** Adds a JavaScript action at the document level. When the document - * opens all this JavaScript runs. - * @param js The JavaScrip action - */ - public void addJavaScript(PdfAction js) { - pdf.addJavaScript(js); - } - - /** Adds a JavaScript action at the document level. When the document - * opens all this JavaScript runs. - * @param code the JavaScript code - * @param unicode select JavaScript unicode. Note that the internal - * Acrobat JavaScript engine does not support unicode, - * so this may or may not work for you - */ - public void addJavaScript(String code, boolean unicode) { - addJavaScript(PdfAction.javaScript(code, this, unicode)); - } - - /** Adds a JavaScript action at the document level. When the document - * opens all this JavaScript runs. - * @param code the JavaScript code - */ - public void addJavaScript(String code) { - addJavaScript(code, false); - } - - /** Adds a file attachment at the document level. - * @param description the file description - * @param fileStore an array with the file. If it's null - * the file will be read from the disk - * @param file the path to the file. It will only be used if - * fileStore is not null - * @param fileDisplay the actual file name stored in the pdf - * @throws IOException on error - */ - public void addFileAttachment(String description, byte fileStore[], String file, String fileDisplay) throws IOException { - addFileAttachment(description, PdfFileSpecification.fileEmbedded(this, file, fileDisplay, fileStore)); - } - - /** Adds a file attachment at the document level. - * @param description the file description - * @param fs the file specification - */ - public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException { - pdf.addFileAttachment(description, fs); - } - - /** Sets the crop box. The crop box should not be rotated even if the - * page is rotated. This change only takes effect in the next - * page. - * @param crop the crop box - */ - public void setCropBoxSize(Rectangle crop) { - pdf.setCropBoxSize(crop); - } - - /** Gets a reference to a page existing or not. If the page does not exist - * yet the reference will be created in advance. If on closing the document, a - * page number greater than the total number of pages was requested, an - * exception is thrown. - * @param page the page number. The first page is 1 - * @return the reference to the page - */ - public PdfIndirectReference getPageReference(int page) { - --page; - if (page < 0) - throw new IndexOutOfBoundsException("The page numbers start at 1."); - PdfIndirectReference ref; - if (page < pageReferences.size()) { - ref = (PdfIndirectReference)pageReferences.get(page); - if (ref == null) { - ref = body.getPdfIndirectReference(); - pageReferences.set(page, ref); - } - } - else { - int empty = page - pageReferences.size(); - for (int k = 0; k < empty; ++k) - pageReferences.add(null); - ref = body.getPdfIndirectReference(); - pageReferences.add(ref); - } - return ref; - } - - PdfIndirectReference getCurrentPage() { - return getPageReference(currentPageNumber); - } - - int getCurrentPageNumber() { - return currentPageNumber; - } - - /** Adds the PdfAnnotation to the calculation order - * array. - * @param annot the PdfAnnotation to be added - */ - public void addCalculationOrder(PdfFormField annot) { - pdf.addCalculationOrder(annot); - } - - /** Set the signature flags. - * @param f the flags. This flags are ORed with current ones - */ - public void setSigFlags(int f) { - pdf.setSigFlags(f); - } - - /** Adds a PdfAnnotation or a PdfFormField - * to the document. Only the top parent of a PdfFormField - * needs to be added. - * @param annot the PdfAnnotation or the PdfFormField to add - */ - public void addAnnotation(PdfAnnotation annot) { - pdf.addAnnotation(annot); - } - - void addAnnotation(PdfAnnotation annot, int page) { - addAnnotation(annot); - } - - /** Sets the PDF version. Must be used right before the document - * is opened. Valid options are VERSION_1_2, VERSION_1_3, - * VERSION_1_4, VERSION_1_5 and VERSION_1_6. VERSION_1_4 is the default. - * @param version the version number - */ - public void setPdfVersion(char version) { - if (HEADER.length > VPOINT) - HEADER[VPOINT] = (byte)version; - } - - /** Reorder the pages in the document. A null argument value - * only returns the number of pages to process. It is - * advisable to issue a Document.newPage() - * before using this method. - * @return the total number of pages - * @param order an array with the new page sequence. It must have the - * same size as the number of pages. - * @throws DocumentException if all the pages are not present in the array - */ - public int reorderPages(int order[]) throws DocumentException { - return root.reorderPages(order); - } - - /** Gets the space/character extra spacing ratio for - * fully justified text. - * @return the space/character extra spacing ratio - */ - public float getSpaceCharRatio() { - return spaceCharRatio; - } - - /** Sets the ratio between the extra word spacing and the extra character spacing - * when the text is fully justified. - * Extra word spacing will grow spaceCharRatio times more than extra character spacing. - * If the ratio is PdfWriter.NO_SPACE_CHAR_RATIO then the extra character spacing - * will be zero. - * @param spaceCharRatio the ratio between the extra word spacing and the extra character spacing - */ - public void setSpaceCharRatio(float spaceCharRatio) { - if (spaceCharRatio < 0.001f) - this.spaceCharRatio = 0.001f; - else - this.spaceCharRatio = spaceCharRatio; - } - - /** Sets the run direction. This is only used as a placeholder - * as it does not affect anything. - * @param runDirection the run direction - */ - public void setRunDirection(int runDirection) { - if (runDirection < RUN_DIRECTION_NO_BIDI || runDirection > RUN_DIRECTION_RTL) - throw new RuntimeException("Invalid run direction: " + runDirection); - this.runDirection = runDirection; - } - - /** Gets the run direction. - * @return the run direction - */ - public int getRunDirection() { - return runDirection; - } - - /** - * Sets the display duration for the page (for presentations) - * @param seconds the number of seconds to display the page - */ - public void setDuration(int seconds) { - pdf.setDuration(seconds); - } - - /** - * Sets the transition for the page - * @param transition the Transition object - */ - public void setTransition(PdfTransition transition) { - pdf.setTransition(transition); - } - - /** Writes the reader to the document and frees the memory used by it. - * The main use is when concatenating multiple documents to keep the - * memory usage restricted to the current appending document. - * @param reader the PdfReader to free - * @throws IOException on error - */ - public void freeReader(PdfReader reader) throws IOException { - currentPdfReaderInstance = (PdfReaderInstance)importedPages.get(reader); - if (currentPdfReaderInstance == null) - return; - currentPdfReaderInstance.writeAllPages(); - currentPdfReaderInstance = null; - importedPages.remove(reader); - } - - /** Sets the open and close page additional action. - * @param actionType the action type. It can be PdfWriter.PAGE_OPEN - * or PdfWriter.PAGE_CLOSE - * @param action the action to perform - * @throws PdfException if the action type is invalid - */ - public void setPageAction(PdfName actionType, PdfAction action) throws PdfException { - if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) - throw new PdfException("Invalid page additional action type: " + actionType.toString()); - pdf.setPageAction(actionType, action); - } - - /** Gets the current document size. This size only includes - * the data already writen to the output stream, it does not - * include templates or fonts. It is usefull if used with - * freeReader() when concatenating many documents - * and an idea of the current size is needed. - * @return the approximate size without fonts or templates - */ - public int getCurrentDocumentSize() { - return body.offset() + body.size() * 20 + 0x48; - } - - /** Getter for property strictImageSequence. - * @return value of property strictImageSequence - * - */ - public boolean isStrictImageSequence() { - return pdf.isStrictImageSequence(); - } - - /** Sets the image sequence to follow the text in strict order. - * @param strictImageSequence new value of property strictImageSequence - * - */ - public void setStrictImageSequence(boolean strictImageSequence) { - pdf.setStrictImageSequence(strictImageSequence); - } - - /** - * If you use setPageEmpty(false), invoking newPage() after a blank page will add a newPage. - * @param pageEmpty the state - */ - public void setPageEmpty(boolean pageEmpty) { - pdf.setPageEmpty(pageEmpty); - } - - /** Gets the info dictionary for changing. - * @return the info dictionary - */ - public PdfDictionary getInfo() { - return ((PdfDocument)document).getInfo(); - } - - /** - * Sets extra keys to the catalog. - * @return the catalog to change - */ - public PdfDictionary getExtraCatalog() { - if (extraCatalog == null) - extraCatalog = new PdfDictionary(); - return this.extraCatalog; - } - - /** - * Sets the document in a suitable way to do page reordering. - */ - public void setLinearPageMode() { - root.setLinearMode(null); - } - - /** Getter for property group. - * @return Value of property group. - * - */ - public PdfDictionary getGroup() { - return this.group; - } - - /** Setter for property group. - * @param group New value of property group. - * - */ - public void setGroup(PdfDictionary group) { - this.group = group; - } - - /** - * Sets the PDFX conformance level. Allowed values are PDFX1A2001 and PDFX32002. It - * must be called before opening the document. - * @param pdfxConformance the conformance level - */ - public void setPDFXConformance(int pdfxConformance) { - if (this.pdfxConformance == pdfxConformance) - return; - if (pdf.isOpen()) - throw new PdfXConformanceException("PDFX conformance can only be set before opening the document."); - if (crypto != null) - throw new PdfXConformanceException("A PDFX conforming document cannot be encrypted."); - if (pdfxConformance != PDFXNONE) - setPdfVersion(VERSION_1_3); - this.pdfxConformance = pdfxConformance; - } - - /** - * Gets the PDFX conformance level. - * @return the PDFX conformance level - */ - public int getPDFXConformance() { - return pdfxConformance; - } - - static void checkPDFXConformance(PdfWriter writer, int key, Object obj1) { - if (writer == null || writer.pdfxConformance == PDFXNONE) - return; - int conf = writer.pdfxConformance; - switch (key) { - case PDFXKEY_COLOR: - switch (conf) { - case PDFX1A2001: - if (obj1 instanceof ExtendedColor) { - ExtendedColor ec = (ExtendedColor)obj1; - switch (ec.getType()) { - case ExtendedColor.TYPE_CMYK: - case ExtendedColor.TYPE_GRAY: - return; - case ExtendedColor.TYPE_RGB: - throw new PdfXConformanceException("Colorspace RGB is not allowed."); - case ExtendedColor.TYPE_SEPARATION: - SpotColor sc = (SpotColor)ec; - checkPDFXConformance(writer, PDFXKEY_COLOR, sc.getPdfSpotColor().getAlternativeCS()); - break; - case ExtendedColor.TYPE_SHADING: - ShadingColor xc = (ShadingColor)ec; - checkPDFXConformance(writer, PDFXKEY_COLOR, xc.getPdfShadingPattern().getShading().getColorSpace()); - break; - case ExtendedColor.TYPE_PATTERN: - PatternColor pc = (PatternColor)ec; - checkPDFXConformance(writer, PDFXKEY_COLOR, pc.getPainter().getDefaultColor()); - break; - } - } - else if (obj1 instanceof Color) - throw new PdfXConformanceException("Colorspace RGB is not allowed."); - break; - } - break; - case PDFXKEY_CMYK: - break; - case PDFXKEY_RGB: - if (conf == PDFX1A2001) - throw new PdfXConformanceException("Colorspace RGB is not allowed."); - break; - case PDFXKEY_FONT: - if (!((BaseFont)obj1).isEmbedded()) - throw new PdfXConformanceException("All the fonts must be embedded."); - break; - case PDFXKEY_IMAGE: - PdfImage image = (PdfImage)obj1; - if (image.get(PdfName.SMASK) != null) - throw new PdfXConformanceException("The /SMask key is not allowed in images."); - switch (conf) { - case PDFX1A2001: - PdfObject cs = image.get(PdfName.COLORSPACE); - if (cs == null) - return; - if (cs.isName()) { - if (PdfName.DEVICERGB.equals(cs)) - throw new PdfXConformanceException("Colorspace RGB is not allowed."); - } - else if (cs.isArray()) { - if (PdfName.CALRGB.equals(((PdfArray)cs).getArrayList().get(0))) - throw new PdfXConformanceException("Colorspace CalRGB is not allowed."); - } - break; - } - break; - case PDFXKEY_GSTATE: - PdfDictionary gs = (PdfDictionary)obj1; - PdfObject obj = gs.get(PdfName.BM); - if (obj != null && !PdfGState.BM_NORMAL.equals(obj) && !PdfGState.BM_COMPATIBLE.equals(obj)) - throw new PdfXConformanceException("Blend mode " + obj.toString() + " not allowed."); - obj = gs.get(PdfName.CA); - double v = 0.0; - if (obj != null && (v = ((PdfNumber)obj).doubleValue()) != 1.0) - throw new PdfXConformanceException("Transparency is not allowed: /CA = " + v); - obj = gs.get(PdfName.ca); - v = 0.0; - if (obj != null && (v = ((PdfNumber)obj).doubleValue()) != 1.0) - throw new PdfXConformanceException("Transparency is not allowed: /ca = " + v); - break; - case PDFXKEY_LAYER: - throw new PdfXConformanceException("Layers are not allowed."); - } - } - - /** - * Sets the values of the output intent dictionary. Null values are allowed to - * suppress any key. - * @param outputConditionIdentifier a value - * @param outputCondition a value - * @param registryName a value - * @param info a value - * @param destOutputProfile a value - * @throws IOException on error - */ - public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, byte destOutputProfile[]) throws IOException { - getExtraCatalog(); - PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT); - if (outputCondition != null) - out.put(PdfName.OUTPUTCONDITION, new PdfString(outputCondition, PdfObject.TEXT_UNICODE)); - if (outputConditionIdentifier != null) - out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString(outputConditionIdentifier, PdfObject.TEXT_UNICODE)); - if (registryName != null) - out.put(PdfName.REGISTRYNAME, new PdfString(registryName, PdfObject.TEXT_UNICODE)); - if (info != null) - out.put(PdfName.INFO, new PdfString(registryName, PdfObject.TEXT_UNICODE)); - if (destOutputProfile != null) { - PdfStream stream = new PdfStream(destOutputProfile); - stream.flateCompress(); - out.put(PdfName.DESTOUTPUTPROFILE, addToBody(stream).getIndirectReference()); - } - out.put(PdfName.S, PdfName.GTS_PDFX); - extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out)); - } - - private static String getNameString(PdfDictionary dic, PdfName key) { - PdfObject obj = PdfReader.getPdfObject(dic.get(key)); - if (obj == null || !obj.isString()) - return null; - return ((PdfString)obj).toUnicodeString(); - } - - /** - * Copies the output intent dictionary from other document to this one. - * @param reader the other document - * @param checkExistence true to just check for the existence of a valid output intent - * dictionary, false to insert the dictionary if it exists - * @throws IOException on error - * @return true if the output intent dictionary exists, false - * otherwise - */ - public boolean setOutputIntents(PdfReader reader, boolean checkExistence) throws IOException { - PdfDictionary catalog = reader.getCatalog(); - PdfArray outs = (PdfArray)PdfReader.getPdfObject(catalog.get(PdfName.OUTPUTINTENTS)); - if (outs == null) - return false; - ArrayList arr = outs.getArrayList(); - if (arr.size() == 0) - return false; - PdfDictionary out = (PdfDictionary)PdfReader.getPdfObject((PdfObject)arr.get(0)); - PdfObject obj = PdfReader.getPdfObject(out.get(PdfName.S)); - if (obj == null || !PdfName.GTS_PDFX.equals(obj)) - return false; - if (checkExistence) - return true; - PRStream stream = (PRStream)PdfReader.getPdfObject(out.get(PdfName.DESTOUTPUTPROFILE)); - byte destProfile[] = null; - if (stream != null) { - destProfile = PdfReader.getStreamBytes(stream); - } - setOutputIntents(getNameString(out, PdfName.OUTPUTCONDITIONIDENTIFIER), getNameString(out, PdfName.OUTPUTCONDITION), - getNameString(out, PdfName.REGISTRYNAME), getNameString(out, PdfName.INFO), destProfile); - return true; - } - - /** - * Sets the page box sizes. Allowed names are: "crop", "trim", "art" and "bleed". - * @param boxName the box size - * @param size the size - */ - public void setBoxSize(String boxName, Rectangle size) { - pdf.setBoxSize(boxName, size); - } - - /** - * Gives the size of a trim, art, crop or bleed box, or null if not defined. - * @param boxName crop, trim, art or bleed - */ - public Rectangle getBoxSize(String boxName) { - return pdf.getBoxSize(boxName); - } - - /** - * Gives the size of the media box. - * @return a Rectangle - */ - public Rectangle getPageSize() { - return pdf.getPageSize(); - } - /** - * Gets the default colorspaces. - * @return the default colorspaces - */ - public PdfDictionary getDefaultColorspace() { - return defaultColorspace; - } - - /** - * Sets the default colorspace that will be applied to all the document. - * The colorspace is only applied if another colorspace with the same name - * is not present in the content. - *

- * The colorspace is applied immediately when creating templates and at the page - * end for the main document content. - * @param key the name of the colorspace. It can be PdfName.DEFAULTGRAY, PdfName.DEFAULTRGB - * or PdfName.DEFAULTCMYK - * @param cs the colorspace. A null or PdfNull removes any colorspace with the same name - */ - public void setDefaultColorspace(PdfName key, PdfObject cs) { - if (cs == null || cs.isNull()) - defaultColorspace.remove(key); - defaultColorspace.put(key, cs); - } - - /** - * Gets the 1.5 compression status. - * @return true if the 1.5 compression is on - */ - public boolean isFullCompression() { - return this.fullCompression; - } - - /** - * Sets the document's compression to the new 1.5 mode with object streams and xref - * streams. It can be set at any time but once set it can't be unset. - *

- * If set before opening the document it will also set the pdf version to 1.5. - */ - public void setFullCompression() { - this.fullCompression = true; - setPdfVersion(VERSION_1_5); - } - - /** - * Gets the Optional Content Properties Dictionary. Each call fills the dictionary with the current layer - * state. It's advisable to only call this method right before close and do any modifications - * at that time. - * @return the Optional Content Properties Dictionary - */ - public PdfOCProperties getOCProperties() { - fillOCProperties(true); - return OCProperties; - } - - /** - * Sets a collection of optional content groups whose states are intended to follow - * a "radio button" paradigm. That is, the state of at most one optional - * content group in the array should be ON at a time: if one group is turned - * ON, all others must be turned OFF. - * @param group the radio group - */ - public void addOCGRadioGroup(ArrayList group) { - PdfArray ar = new PdfArray(); - for (int k = 0; k < group.size(); ++k) { - PdfLayer layer = (PdfLayer)group.get(k); - if (layer.getTitle() == null) - ar.add(layer.getRef()); - } - if (ar.size() == 0) - return; - OCGRadioGroup.add(ar); - } - - /** - * Sets the the thumbnail image for the current page. - * @param image the image - * @throws PdfException on error - * @throws DocumentException or error - */ - public void setThumbnail(Image image) throws PdfException, DocumentException { - pdf.setThumbnail(image); - } - - /** - * A UserUnit is a value that defines the default user space unit. - * The minimum UserUnit is 1 (1 unit = 1/72 inch). - * The maximum UserUnit is 75,000. - * Remark that this userunit only works starting with PDF1.6! - * @return Returns the userunit. - */ - public float getUserunit() { - return userunit; - } - /** - * A UserUnit is a value that defines the default user space unit. - * The minimum UserUnit is 1 (1 unit = 1/72 inch). - * The maximum UserUnit is 75,000. - * Remark that this userunit only works starting with PDF1.6! - * @param userunit The userunit to set. - * @throws DocumentException - */ - public void setUserunit(float userunit) throws DocumentException { - if (userunit < 1f || userunit > 75000f) throw new DocumentException("UserUnit should be a value between 1 and 75000."); - this.userunit = userunit; - setPdfVersion(VERSION_1_6); - } - - /** - * Sets XMP Metadata. - * @param xmpMetadata The xmpMetadata to set. - */ - public void setXmpMetadata(byte[] xmpMetadata) { - this.xmpMetadata = xmpMetadata; - } - - /** - * Creates XMP Metadata based on the metadata in the PdfDocument. - */ - public void createXmpMetadata() { - setXmpMetadata(pdf.createXmpMetadata()); - } - - /** - * Releases the memory used by a template by writing it to the output. The template - * can still be added to any content but changes to the template itself won't have - * any effect. - * @param tp the template to release - * @throws IOException on error - */ - public void releaseTemplate(PdfTemplate tp) throws IOException { - PdfIndirectReference ref = tp.getIndirectReference(); - Object[] objs = (Object[])formXObjects.get(ref); - if (objs == null || objs[1] == null) - return; - PdfTemplate template = (PdfTemplate)objs[1]; - if (template.getIndirectReference() instanceof PRIndirectReference) - return; - if (template.getType() == PdfTemplate.TYPE_TEMPLATE) { - addToBody(template.getFormXObject(), template.getIndirectReference()); - objs[1] = null; - } - } - - /** - * Mark this document for tagging. It must be called before open. - */ - public void setTagged() { - if (open) - throw new IllegalArgumentException("Tagging must be set before opening the document."); - tagged = true; - } - - /** - * Check if the document is marked for tagging. - * @return true if the document is marked for tagging - */ - public boolean isTagged() { - return tagged; - } - - /** - * Gets the structure tree root. If the document is not marked for tagging it will return null. - * @return the structure tree root - */ - public PdfStructureTreeRoot getStructureTreeRoot() { - if (tagged && structureTreeRoot == null) - structureTreeRoot = new PdfStructureTreeRoot(this); - return structureTreeRoot; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PdfXConformanceException.java b/src/main/java/com/lowagie/text/pdf/PdfXConformanceException.java deleted file mode 100644 index fd9607c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PdfXConformanceException.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * $Id: PdfXConformanceException.java,v 1.2 2005/02/17 09:20:54 blowagie Exp $ - * $Name: $ - * - * Copyright 2004 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999-2005 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000-2005 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** - * - * @author psoares - */ -public class PdfXConformanceException extends RuntimeException { - - /** Creates a new instance of PdfXConformanceException. */ - public PdfXConformanceException() { - } - - /** - * Creates a new instance of PdfXConformanceException. - * @param s - */ - public PdfXConformanceException(String s) { - super(s); - } -} diff --git a/src/main/java/com/lowagie/text/pdf/Pfm2afm.java b/src/main/java/com/lowagie/text/pdf/Pfm2afm.java deleted file mode 100644 index 1428f53..0000000 --- a/src/main/java/com/lowagie/text/pdf/Pfm2afm.java +++ /dev/null @@ -1,773 +0,0 @@ -/* - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -/******************************************************************** - * * - * Title: pfm2afm - Convert Windows .pfm files to .afm files * - * * - * Author: Ken Borgendale 10/9/91 Version 1.0 * - * * - * Function: * - * Convert a Windows .pfm (Printer Font Metrics) file to a * - * .afm (Adobe Font Metrics) file. The purpose of this is * - * to allow fonts put out for Windows to be used with OS/2. * - * * - * Syntax: * - * pfm2afm infile [outfile] -a * - * * - * Copyright: * - * pfm2afm - Copyright (C) IBM Corp., 1991 * - * * - * This code is released for public use as long as the * - * copyright remains intact. This code is provided asis * - * without any warrenties, express or implied. * - * * - * Notes: * - * 1. Much of the information in the original .afm file is * - * lost when the .pfm file is created, and thus cannot be * - * reconstructed by this utility. This is especially true * - * of data for characters not in the Windows character set. * - * * - * 2. This module is coded to be compiled by the MSC 6.0. * - * For other compilers, be careful of the packing of the * - * PFM structure. * - * * - ********************************************************************/ - -/******************************************************************** - * * - * Modifications by Rod Smith, 5/22/96 * - * * - * These changes look for the strings "italic", "bold", "black", * - * and "light" in the font's name and set the weight accordingly * - * and adds an ItalicAngle line with a value of "0" or "-12.00". * - * This allows OS/2 programs such as DeScribe to handle the bold * - * and italic attributes appropriately, which was not the case * - * when I used the original version on fonts from the KeyFonts * - * Pro 2002 font CD. * - * * - * I've also increased the size of the buffer used to load the * - * .PFM file; the old size was inadequate for most of the fonts * - * from the SoftKey collection. * - * * - * Compiled with Watcom C 10.6 * - * * - ********************************************************************/ - -/******************************************************************** - * * - * Further modifications, 4/21/98, by Rod Smith * - * * - * Minor changes to get the program to compile with gcc under * - * Linux (Red Hat 5.0, to be precise). I had to add an itoa * - * function from the net (the function was buggy, so I had to fix * - * it, too!). I also made the program more friendly towards * - * files with mixed-case filenames. * - * * - ********************************************************************/ -package com.lowagie.text.pdf; - -import java.io.*; - -/** - * Converts a PFM file into an AFM file. - */ -public class Pfm2afm { - private RandomAccessFileOrArray in; - private PrintWriter out; - - /** Creates a new instance of Pfm2afm */ - private Pfm2afm(RandomAccessFileOrArray in, OutputStream out) throws IOException { - this.in = in; - this.out = new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1")); - } - - /** - * Converts a PFM file into an AFM file. - * @param in the PFM file - * @param out the AFM file - * @throws IOException on error - */ - public static void convert(RandomAccessFileOrArray in, OutputStream out) throws IOException { - Pfm2afm p = new Pfm2afm(in, out); - p.openpfm(); - p.putheader(); - p.putchartab(); - p.putkerntab(); - p.puttrailer(); - p.out.flush(); - } - - public static void main(String[] args) { - try { - RandomAccessFileOrArray in = new RandomAccessFileOrArray(args[0]); - OutputStream out = new FileOutputStream(args[1]); - convert(in, out); - in.close(); - out.close(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - - private String readString(int n) throws IOException { - byte b[] = new byte[n]; - in.readFully(b); - int k; - for (k = 0; k < b.length; ++k) { - if (b[k] == 0) - break; - } - return new String(b, 0, k, "ISO-8859-1"); - } - - private String readString() throws IOException { - StringBuffer buf = new StringBuffer(); - while (true) { - int c = in.read(); - if (c <= 0) - break; - buf.append((char)c); - } - return buf.toString(); - } - - private void outval(int n) { - out.print(' '); - out.print(n); - } - - /* - * Output a character entry - */ - private void outchar(int code, int width, String name) { - out.print("C "); - outval(code); - out.print(" ; WX "); - outval(width); - if (name != null) { - out.print(" ; N "); - out.print(name); - } - out.print(" ;\n"); - } - - private void openpfm() throws IOException { - in.seek(0); - vers = in.readShortLE(); - h_len = in.readIntLE(); - copyright = readString(60); - type = in.readShortLE(); - points = in.readShortLE(); - verres = in.readShortLE(); - horres = in.readShortLE(); - ascent = in.readShortLE(); - intleading = in.readShortLE(); - extleading = in.readShortLE(); - italic = (byte)in.read(); - uline = (byte)in.read(); - overs = (byte)in.read(); - weight = in.readShortLE(); - charset = (byte)in.read(); - pixwidth = in.readShortLE(); - pixheight = in.readShortLE(); - kind = (byte)in.read(); - avgwidth = in.readShortLE(); - maxwidth = in.readShortLE(); - firstchar = in.read(); - lastchar = in.read(); - defchar = (byte)in.read(); - brkchar = (byte)in.read(); - widthby = in.readShortLE(); - device = in.readIntLE(); - face = in.readIntLE(); - bits = in.readIntLE(); - bitoff = in.readIntLE(); - extlen = in.readShortLE(); - psext = in.readIntLE(); - chartab = in.readIntLE(); - res1 = in.readIntLE(); - kernpairs = in.readIntLE(); - res2 = in.readIntLE(); - fontname = in.readIntLE(); - if (h_len != in.length() || extlen != 30 || fontname < 75 || fontname > 512) - throw new IOException("Not a valid PFM file."); - in.seek(psext + 14); - capheight = in.readShortLE(); - xheight = in.readShortLE(); - ascender = in.readShortLE(); - descender = in.readShortLE(); - } - - private void putheader() throws IOException { - out.print("StartFontMetrics 2.0\n"); - if (copyright.length() > 0) - out.print("Comment " + copyright + '\n'); - out.print("FontName "); - in.seek(fontname); - String fname = readString(); - out.print(fname); - out.print("\nEncodingScheme "); - if (charset != 0) - out.print("FontSpecific\n"); - else - out.print("AdobeStandardEncoding\n"); - /* - * The .pfm is missing full name, so construct from font name by - * changing the hyphen to a space. This actually works in a lot - * of cases. - */ - out.print("FullName " + fname.replace('-', ' ')); - if (face != 0) { - in.seek(face); - out.print("\nFamilyName " + readString()); - } - - out.print("\nWeight "); - if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0) - out.print("Bold"); - else if ((weight < 325 && weight != 0) || fname.toLowerCase().indexOf("light") >= 0) - out.print("Light"); - else if (fname.toLowerCase().indexOf("black") >= 0) - out.print("Black"); - else - out.print("Medium"); - - out.print("\nItalicAngle "); - if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0) - out.print("-12.00"); - /* this is a typical value; something else may work better for a - specific font */ - else - out.print("0"); - - /* - * The mono flag in the pfm actually indicates whether there is a - * table of font widths, not if they are all the same. - */ - out.print("\nIsFixedPitch "); - if ((kind & 1) == 0 || /* Flag for mono */ - avgwidth == maxwidth ) { /* Avg width = max width */ - out.print("true"); - isMono = true; - } - else { - out.print("false"); - isMono = false; - } - - /* - * The font bounding box is lost, but try to reconstruct it. - * Much of this is just guess work. The bounding box is required in - * the .afm, but is not used by the PM font installer. - */ - out.print("\nFontBBox"); - if (isMono) - outval(-20); /* Just guess at left bounds */ - else - outval(-100); - outval(-(descender+5)); /* Descender is given as positive value */ - outval(maxwidth+10); - outval(ascent+5); - - /* - * Give other metrics that were kept - */ - out.print("\nCapHeight"); - outval(capheight); - out.print("\nXHeight"); - outval(xheight); - out.print("\nDescender"); - outval(descender); - out.print("\nAscender"); - outval(ascender); - out.print('\n'); - } - - private void putchartab() throws IOException { - int count = lastchar - firstchar + 1; - int ctabs[] = new int[count]; - in.seek(chartab); - for (int k = 0; k < count; ++k) - ctabs[k] = in.readUnsignedShortLE(); - int back[] = new int[256]; - if (charset == 0) { - for (int i = firstchar; i <= lastchar; ++i) { - if (Win2PSStd[i] != 0) - back[Win2PSStd[i]] = i; - } - } - /* Put out the header */ - out.print("StartCharMetrics"); - outval(count); - out.print('\n'); - - /* Put out all encoded chars */ - if (charset != 0) { - /* - * If the charset is not the Windows standard, just put out - * unnamed entries. - */ - for (int i = firstchar; i <= lastchar; i++) { - if (ctabs[i - firstchar] != 0) { - outchar(i, ctabs[i - firstchar], null); - } - } - } - else { - for (int i = 0; i < 256; i++) { - int j = back[i]; - if (j != 0) { - outchar(i, ctabs[j - firstchar], WinChars[j]); - ctabs[j - firstchar] = 0; - } - } - /* Put out all non-encoded chars */ - for (int i = firstchar; i <= lastchar; i++) { - if (ctabs[i - firstchar] != 0) { - outchar(-1, ctabs[i - firstchar], WinChars[i]); - } - } - } - /* Put out the trailer */ - out.print("EndCharMetrics\n"); - - } - - private void putkerntab() throws IOException { - if (kernpairs == 0) - return; - in.seek(kernpairs); - int count = in.readUnsignedShortLE(); - int nzero = 0; - int kerns[] = new int[count * 3]; - for (int k = 0; k < kerns.length;) { - kerns[k++] = in.read(); - kerns[k++] = in.read(); - if ((kerns[k++] = in.readShortLE()) != 0) - ++nzero; - } - if (nzero == 0) - return; - out.print("StartKernData\nStartKernPairs"); - outval(nzero); - out.print('\n'); - for (int k = 0; k < kerns.length; k += 3) { - if (kerns[k + 2] != 0) { - out.print("KPX "); - out.print(WinChars[kerns[k]]); - out.print(' '); - out.print(WinChars[kerns[k + 1]]); - outval(kerns[k + 2]); - out.print('\n'); - } - } - /* Put out trailer */ - out.print("EndKernPairs\nEndKernData\n"); - } - - - private void puttrailer() { - out.print("EndFontMetrics\n"); - } - - private short vers; - private int h_len; /* Total length of .pfm file */ - private String copyright; /* Copyright string [60]*/ - private short type; - private short points; - private short verres; - private short horres; - private short ascent; - private short intleading; - private short extleading; - private byte italic; - private byte uline; - private byte overs; - private short weight; - private byte charset; /* 0=windows, otherwise nomap */ - private short pixwidth; /* Width for mono fonts */ - private short pixheight; - private byte kind; /* Lower bit off in mono */ - private short avgwidth; /* Mono if avg=max width */ - private short maxwidth; /* Use to compute bounding box */ - private int firstchar; /* First char in table */ - private int lastchar; /* Last char in table */ - private byte defchar; - private byte brkchar; - private short widthby; - private int device; - private int face; /* Face name */ - private int bits; - private int bitoff; - private short extlen; - private int psext; /* PostScript extension */ - private int chartab; /* Character width tables */ - private int res1; - private int kernpairs; /* Kerning pairs */ - private int res2; - private int fontname; /* Font name */ - -/* - * Some metrics from the PostScript extension - */ - private short capheight; /* Cap height */ - private short xheight; /* X height */ - private short ascender; /* Ascender */ - private short descender; /* Descender (positive) */ - - - private boolean isMono; -/* - * Translate table from 1004 to psstd. 1004 is an extension of the - * Windows translate table used in PM. - */ - private int Win2PSStd[] = { - 0, 0, 0, 0, 197, 198, 199, 0, 202, 0, 205, 206, 207, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 193, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 0, 0, 184, 0, 185, 188, 178, 179, 94, 189, 0, 172, 234, 0, 0, 0, - 0, 96, 0, 170, 186, 0, 177, 208, 126, 0, 0, 173, 250, 0, 0, 0, - 0, 161, 162, 163, 168, 165, 0, 167, 200, 0, 227, 171, 0, 0, 0, 0, - 0, 0, 0, 0, 194, 0, 182, 180, 203, 0, 235, 187, 0, 0, 0, 191, - 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 251, - 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0 - }; - -/* - * Character class. This is a minor attempt to overcome the problem that - * in the pfm file, all unused characters are given the width of space. - */ - private int WinClass[] = { - 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, /* 00 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, /* 70 */ - 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 80 */ - 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, /* 90 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f0 */ - }; - -/* - * Windows chararacter names. Give a name to the usused locations - * for when the all flag is specified. - */ - private String WinChars[] = { - "W00", /* 00 */ - "W01", /* 01 */ - "W02", /* 02 */ - "W03", /* 03 */ - "macron", /* 04 */ - "breve", /* 05 */ - "dotaccent", /* 06 */ - "W07", /* 07 */ - "ring", /* 08 */ - "W09", /* 09 */ - "W0a", /* 0a */ - "W0b", /* 0b */ - "W0c", /* 0c */ - "W0d", /* 0d */ - "W0e", /* 0e */ - "W0f", /* 0f */ - "hungarumlaut", /* 10 */ - "ogonek", /* 11 */ - "caron", /* 12 */ - "W13", /* 13 */ - "W14", /* 14 */ - "W15", /* 15 */ - "W16", /* 16 */ - "W17", /* 17 */ - "W18", /* 18 */ - "W19", /* 19 */ - "W1a", /* 1a */ - "W1b", /* 1b */ - "W1c", /* 1c */ - "W1d", /* 1d */ - "W1e", /* 1e */ - "W1f", /* 1f */ - "space", /* 20 */ - "exclam", /* 21 */ - "quotedbl", /* 22 */ - "numbersign", /* 23 */ - "dollar", /* 24 */ - "percent", /* 25 */ - "ampersand", /* 26 */ - "quotesingle", /* 27 */ - "parenleft", /* 28 */ - "parenright", /* 29 */ - "asterisk", /* 2A */ - "plus", /* 2B */ - "comma", /* 2C */ - "hyphen", /* 2D */ - "period", /* 2E */ - "slash", /* 2F */ - "zero", /* 30 */ - "one", /* 31 */ - "two", /* 32 */ - "three", /* 33 */ - "four", /* 34 */ - "five", /* 35 */ - "six", /* 36 */ - "seven", /* 37 */ - "eight", /* 38 */ - "nine", /* 39 */ - "colon", /* 3A */ - "semicolon", /* 3B */ - "less", /* 3C */ - "equal", /* 3D */ - "greater", /* 3E */ - "question", /* 3F */ - "at", /* 40 */ - "A", /* 41 */ - "B", /* 42 */ - "C", /* 43 */ - "D", /* 44 */ - "E", /* 45 */ - "F", /* 46 */ - "G", /* 47 */ - "H", /* 48 */ - "I", /* 49 */ - "J", /* 4A */ - "K", /* 4B */ - "L", /* 4C */ - "M", /* 4D */ - "N", /* 4E */ - "O", /* 4F */ - "P", /* 50 */ - "Q", /* 51 */ - "R", /* 52 */ - "S", /* 53 */ - "T", /* 54 */ - "U", /* 55 */ - "V", /* 56 */ - "W", /* 57 */ - "X", /* 58 */ - "Y", /* 59 */ - "Z", /* 5A */ - "bracketleft", /* 5B */ - "backslash", /* 5C */ - "bracketright", /* 5D */ - "asciicircum", /* 5E */ - "underscore", /* 5F */ - "grave", /* 60 */ - "a", /* 61 */ - "b", /* 62 */ - "c", /* 63 */ - "d", /* 64 */ - "e", /* 65 */ - "f", /* 66 */ - "g", /* 67 */ - "h", /* 68 */ - "i", /* 69 */ - "j", /* 6A */ - "k", /* 6B */ - "l", /* 6C */ - "m", /* 6D */ - "n", /* 6E */ - "o", /* 6F */ - "p", /* 70 */ - "q", /* 71 */ - "r", /* 72 */ - "s", /* 73 */ - "t", /* 74 */ - "u", /* 75 */ - "v", /* 76 */ - "w", /* 77 */ - "x", /* 78 */ - "y", /* 79 */ - "z", /* 7A */ - "braceleft", /* 7B */ - "bar", /* 7C */ - "braceright", /* 7D */ - "asciitilde", /* 7E */ - "W7f", /* 7F */ - "W80", /* 80 */ - "W81", /* 81 */ - "quotesinglbase", /* 82 */ - "W83", /* 83 */ - "quotedblbase", /* 84 */ - "ellipsis", /* 85 */ - "dagger", /* 86 */ - "daggerdbl", /* 87 */ - "asciicircum", /* 88 */ - "perthousand", /* 89 */ - "Scaron", /* 8A */ - "guilsinglleft", /* 8B */ - "OE", /* 8C */ - "W8d", /* 8D */ - "W8e", /* 8E */ - "W8f", /* 8F */ - "W90", /* 90 */ - "quoteleft", /* 91 */ - "quoteright", /* 92 */ - "quotedblleft", /* 93 */ - "quotedblright", /* 94 */ - "bullet1", /* 95 */ - "endash", /* 96 */ - "emdash", /* 97 */ - "asciitilde", /* 98 */ - "trademark", /* 99 */ - "scaron", /* 9A */ - "guilsinglright", /* 9B */ - "oe", /* 9C */ - "W9d", /* 9D */ - "W9e", /* 9E */ - "Ydieresis", /* 9F */ - "reqspace", /* A0 */ - "exclamdown", /* A1 */ - "cent", /* A2 */ - "sterling", /* A3 */ - "currency", /* A4 */ - "yen", /* A5 */ - "brokenbar", /* A6 */ - "section", /* A7 */ - "dieresis", /* A8 */ - "copyright", /* A9 */ - "ordfeminine", /* AA */ - "guillemotleft", /* AB */ - "logicalnot", /* AC */ - "syllable", /* AD */ - "registered", /* AE */ - "overbar", /* AF */ - "degree", /* B0 */ - "plusminus", /* B1 */ - "twosuperior", /* B2 */ - "threesuperior", /* B3 */ - "acute", /* B4 */ - "mu", /* B5 */ - "paragraph", /* B6 */ - "periodcentered", /* B7 */ - "cedilla", /* B8 */ - "onesuperior", /* B9 */ - "ordmasculine", /* BA */ - "guillemotright", /* BB */ - "onequarter", /* BC */ - "onehalf", /* BD */ - "threequarters", /* BE */ - "questiondown", /* BF */ - "Agrave", /* C0 */ - "Aacute", /* C1 */ - "Acircumflex", /* C2 */ - "Atilde", /* C3 */ - "Adieresis", /* C4 */ - "Aring", /* C5 */ - "AE", /* C6 */ - "Ccedilla", /* C7 */ - "Egrave", /* C8 */ - "Eacute", /* C9 */ - "Ecircumflex", /* CA */ - "Edieresis", /* CB */ - "Igrave", /* CC */ - "Iacute", /* CD */ - "Icircumflex", /* CE */ - "Idieresis", /* CF */ - "Eth", /* D0 */ - "Ntilde", /* D1 */ - "Ograve", /* D2 */ - "Oacute", /* D3 */ - "Ocircumflex", /* D4 */ - "Otilde", /* D5 */ - "Odieresis", /* D6 */ - "multiply", /* D7 */ - "Oslash", /* D8 */ - "Ugrave", /* D9 */ - "Uacute", /* DA */ - "Ucircumflex", /* DB */ - "Udieresis", /* DC */ - "Yacute", /* DD */ - "Thorn", /* DE */ - "germandbls", /* DF */ - "agrave", /* E0 */ - "aacute", /* E1 */ - "acircumflex", /* E2 */ - "atilde", /* E3 */ - "adieresis", /* E4 */ - "aring", /* E5 */ - "ae", /* E6 */ - "ccedilla", /* E7 */ - "egrave", /* E8 */ - "eacute", /* E9 */ - "ecircumflex", /* EA */ - "edieresis", /* EB */ - "igrave", /* EC */ - "iacute", /* ED */ - "icircumflex", /* EE */ - "idieresis", /* EF */ - "eth", /* F0 */ - "ntilde", /* F1 */ - "ograve", /* F2 */ - "oacute", /* F3 */ - "ocircumflex", /* F4 */ - "otilde", /* F5 */ - "odieresis", /* F6 */ - "divide", /* F7 */ - "oslash", /* F8 */ - "ugrave", /* F9 */ - "uacute", /* FA */ - "ucircumflex", /* FB */ - "udieresis", /* FC */ - "yacute", /* FD */ - "thorn", /* FE */ - "ydieresis" /* FF */ - }; -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/PushbuttonField.java b/src/main/java/com/lowagie/text/pdf/PushbuttonField.java deleted file mode 100644 index ff1769c..0000000 --- a/src/main/java/com/lowagie/text/pdf/PushbuttonField.java +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.Image; -import com.lowagie.text.DocumentException; -import java.io.IOException; -/** - * Creates a pushbutton field. It supports all the text and icon alignments. - * The icon may be an image or a template. - *

- * Example usage: - *

- *

- * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
- * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
- * document.open();
- * PdfContentByte cb = writer.getDirectContent();
- * Image img = Image.getInstance("image.png");
- * PushbuttonField bt = new PushbuttonField(writer, new Rectangle(100, 100, 200, 200), "Button1");
- * bt.setText("My Caption");
- * bt.setFontSize(0);
- * bt.setImage(img);
- * bt.setLayout(PushbuttonField.LAYOUT_ICON_TOP_LABEL_BOTTOM);
- * bt.setBackgroundColor(Color.cyan);
- * bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
- * bt.setBorderColor(Color.red);
- * bt.setBorderWidth(3);
- * PdfFormField ff = bt.getField();
- * PdfAction ac = PdfAction.createSubmitForm("http://www.submit-site.com", null, 0);
- * ff.setAction(ac);
- * writer.addAnnotation(ff);
- * document.close();
- * 
- * @author Paulo Soares (psoares@consiste.pt) - */ -public class PushbuttonField extends BaseField { - - /** A layout option */ - public static final int LAYOUT_LABEL_ONLY = 1; - /** A layout option */ - public static final int LAYOUT_ICON_ONLY = 2; - /** A layout option */ - public static final int LAYOUT_ICON_TOP_LABEL_BOTTOM = 3; - /** A layout option */ - public static final int LAYOUT_LABEL_TOP_ICON_BOTTOM = 4; - /** A layout option */ - public static final int LAYOUT_ICON_LEFT_LABEL_RIGHT = 5; - /** A layout option */ - public static final int LAYOUT_LABEL_LEFT_ICON_RIGHT = 6; - /** A layout option */ - public static final int LAYOUT_LABEL_OVER_ICON = 7; - /** An icon scaling option */ - public static final int SCALE_ICON_ALWAYS = 1; - /** An icon scaling option */ - public static final int SCALE_ICON_NEVER = 2; - /** An icon scaling option */ - public static final int SCALE_ICON_IS_TOO_BIG = 3; - /** An icon scaling option */ - public static final int SCALE_ICON_IS_TOO_SMALL = 4; - - /** - * Holds value of property layout. - */ - private int layout = LAYOUT_LABEL_ONLY; - - /** - * Holds value of property image. - */ - private Image image; - - /** - * Holds value of property template. - */ - private PdfTemplate template; - - /** - * Holds value of property scaleIcon. - */ - private int scaleIcon = SCALE_ICON_ALWAYS; - - /** - * Holds value of property proportionalIcon. - */ - private boolean proportionalIcon = true; - - /** - * Holds value of property iconVerticalAdjustment. - */ - private float iconVerticalAdjustment = 0.5f; - - /** - * Holds value of property iconHorizontalAdjustment. - */ - private float iconHorizontalAdjustment = 0.5f; - - /** - * Holds value of property iconFitToBounds. - */ - private boolean iconFitToBounds; - - private PdfTemplate tp; - - /** - * Creates a new instance of PushbuttonField - * @param writer the document PdfWriter - * @param box the field location and dimensions - * @param fieldName the field name. If null only the widget keys - * will be included in the field allowing it to be used as a kid field. - */ - public PushbuttonField(PdfWriter writer, Rectangle box, String fieldName) { - super(writer, box, fieldName); - } - - /** - * Getter for property layout. - * @return Value of property layout. - */ - public int getLayout() { - return this.layout; - } - - /** - * Sets the icon and label layout. Possible values are LAYOUT_LABEL_ONLY, - * LAYOUT_ICON_ONLY, LAYOUT_ICON_TOP_LABEL_BOTTOM, - * LAYOUT_LABEL_TOP_ICON_BOTTOM, LAYOUT_ICON_LEFT_LABEL_RIGHT, - * LAYOUT_LABEL_LEFT_ICON_RIGHT and LAYOUT_LABEL_OVER_ICON. - * The default is LAYOUT_LABEL_ONLY. - * @param layout New value of property layout. - */ - public void setLayout(int layout) { - if (layout < LAYOUT_LABEL_ONLY || layout > LAYOUT_LABEL_OVER_ICON) - throw new IllegalArgumentException("Layout out of bounds."); - this.layout = layout; - } - - /** - * Getter for property image. - * @return Value of property image. - */ - public Image getImage() { - return this.image; - } - - /** - * Sets the icon as an image. - * @param image the image - */ - public void setImage(Image image) { - this.image = image; - template = null; - } - - /** - * Getter for property template. - * @return Value of property template. - */ - public PdfTemplate getTemplate() { - return this.template; - } - - /** - * Sets the icon as a template. - * @param template the template - */ - public void setTemplate(PdfTemplate template) { - this.template = template; - image = null; - } - - /** - * Getter for property scaleIcon. - * @return Value of property scaleIcon. - */ - public int getScaleIcon() { - return this.scaleIcon; - } - - /** - * Sets the way the icon will be scaled. Possible values are - * SCALE_ICON_ALWAYS, SCALE_ICON_NEVER, - * SCALE_ICON_IS_TOO_BIG and SCALE_ICON_IS_TOO_SMALL. - * The default is SCALE_ICON_ALWAYS. - * @param scaleIcon the way the icon will be scaled - */ - public void setScaleIcon(int scaleIcon) { - if (scaleIcon < SCALE_ICON_ALWAYS || scaleIcon > SCALE_ICON_IS_TOO_SMALL) - scaleIcon = SCALE_ICON_ALWAYS; - this.scaleIcon = scaleIcon; - } - - /** - * Getter for property proportionalIcon. - * @return Value of property proportionalIcon. - */ - public boolean isProportionalIcon() { - return this.proportionalIcon; - } - - /** - * Sets the way the icon is scaled. If true the icon is scaled proportionally, - * if false the scaling is done anamorphicaly. - * @param proportionalIcon the way the icon is scaled - */ - public void setProportionalIcon(boolean proportionalIcon) { - this.proportionalIcon = proportionalIcon; - } - - /** - * Getter for property iconVerticalAdjustment. - * @return Value of property iconVerticalAdjustment. - */ - public float getIconVerticalAdjustment() { - return this.iconVerticalAdjustment; - } - - /** - * A number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon. - * A value of 0 positions the icon at the bottom of the annotation rectangle. - * A value of 0.5 centers it within the rectangle. The default is 0.5. - * @param iconVerticalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the bottom of the icon - */ - public void setIconVerticalAdjustment(float iconVerticalAdjustment) { - if (iconVerticalAdjustment < 0) - iconVerticalAdjustment = 0; - else if (iconVerticalAdjustment > 1) - iconVerticalAdjustment = 1; - this.iconVerticalAdjustment = iconVerticalAdjustment; - } - - /** - * Getter for property iconHorizontalAdjustment. - * @return Value of property iconHorizontalAdjustment. - */ - public float getIconHorizontalAdjustment() { - return this.iconHorizontalAdjustment; - } - - /** - * A number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon. - * A value of 0 positions the icon at the left of the annotation rectangle. - * A value of 0.5 centers it within the rectangle. The default is 0.5. - * @param iconHorizontalAdjustment a number between 0 and 1 indicating the fraction of leftover space to allocate at the left of the icon - */ - public void setIconHorizontalAdjustment(float iconHorizontalAdjustment) { - if (iconHorizontalAdjustment < 0) - iconHorizontalAdjustment = 0; - else if (iconHorizontalAdjustment > 1) - iconHorizontalAdjustment = 1; - this.iconHorizontalAdjustment = iconHorizontalAdjustment; - } - - private float calculateFontSize(float w, float h) throws IOException, DocumentException { - BaseFont ufont = getRealFont(); - float fsize = fontSize; - if (fsize == 0) { - float bw = ufont.getWidthPoint(text, 1); - if (bw == 0) - fsize = 12; - else - fsize = w / bw; - float nfsize = h / (1 - ufont.getFontDescriptor(BaseFont.DESCENT, 1)); - fsize = Math.min(fsize, nfsize); - if (fsize < 4) - fsize = 4; - } - return fsize; - } - - /** - * Gets the button appearance. - * @throws IOException on error - * @throws DocumentException on error - * @return the button appearance - */ - public PdfAppearance getAppearance() throws IOException, DocumentException { - PdfAppearance app = getBorderAppearance(); - Rectangle box = new Rectangle(app.getBoundingBox()); - if ((text == null || text.length() == 0) && (layout == LAYOUT_LABEL_ONLY || (image == null && template == null))) { - return app; - } - if (layout == LAYOUT_ICON_ONLY && image == null && template == null) - return app; - BaseFont ufont = getRealFont(); - boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; - float h = box.height() - borderWidth * 2; - float bw2 = borderWidth; - if (borderExtra) { - h -= borderWidth * 2; - bw2 *= 2; - } - float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); - offsetX = Math.max(offsetX, 1); - float offX = Math.min(bw2, offsetX); - tp = null; - float textX = Float.NaN; - float textY = 0; - float fsize = fontSize; - float wt = box.width() - 2 * offX - 2; - float ht = box.height() - 2 * offX; - float adj = (iconFitToBounds ? 0 : offX + 1); - int nlayout = layout; - if (image == null && template == null) - nlayout = LAYOUT_LABEL_ONLY; - Rectangle iconBox = null; - while (true) { - switch (nlayout) { - case LAYOUT_LABEL_ONLY: - case LAYOUT_LABEL_OVER_ICON: - if (text != null && text.length() > 0 && wt > 0 && ht > 0) { - fsize = calculateFontSize(wt, ht); - textX = (box.width() - ufont.getWidthPoint(text, fsize)) / 2; - textY = (box.height() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; - } - case LAYOUT_ICON_ONLY: - if (nlayout == LAYOUT_LABEL_OVER_ICON || nlayout == LAYOUT_ICON_ONLY) - iconBox = new Rectangle(box.left() + adj, box.bottom() + adj, box.right() - adj, box.top() - adj); - break; - case LAYOUT_ICON_TOP_LABEL_BOTTOM: - if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { - nlayout = LAYOUT_ICON_ONLY; - continue; - } - float nht = box.height() * 0.35f - offX; - if (nht > 0) - fsize = calculateFontSize(wt, nht); - else - fsize = 4; - textX = (box.width() - ufont.getWidthPoint(text, fsize)) / 2; - textY = offX - ufont.getFontDescriptor(BaseFont.DESCENT, fsize); - iconBox = new Rectangle(box.left() + adj, textY + fsize, box.right() - adj, box.top() - adj); - break; - case LAYOUT_LABEL_TOP_ICON_BOTTOM: - if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { - nlayout = LAYOUT_ICON_ONLY; - continue; - } - nht = box.height() * 0.35f - offX; - if (nht > 0) - fsize = calculateFontSize(wt, nht); - else - fsize = 4; - textX = (box.width() - ufont.getWidthPoint(text, fsize)) / 2; - textY = box.height() - offX - fsize; - if (textY < offX) - textY = offX; - iconBox = new Rectangle(box.left() + adj, box.bottom() + adj, box.right() - adj, textY + ufont.getFontDescriptor(BaseFont.DESCENT, fsize)); - break; - case LAYOUT_LABEL_LEFT_ICON_RIGHT: - if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { - nlayout = LAYOUT_ICON_ONLY; - continue; - } - float nw = box.width() * 0.35f - offX; - if (nw > 0) - fsize = calculateFontSize(wt, nw); - else - fsize = 4; - if (ufont.getWidthPoint(text, fsize) >= wt) { - nlayout = LAYOUT_LABEL_ONLY; - fsize = fontSize; - continue; - } - textX = offX + 1; - textY = (box.height() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; - iconBox = new Rectangle(textX + ufont.getWidthPoint(text, fsize), box.bottom() + adj, box.right() - adj, box.top() - adj); - break; - case LAYOUT_ICON_LEFT_LABEL_RIGHT: - if (text == null || text.length() == 0 || wt <= 0 || ht <= 0) { - nlayout = LAYOUT_ICON_ONLY; - continue; - } - nw = box.width() * 0.35f - offX; - if (nw > 0) - fsize = calculateFontSize(wt, nw); - else - fsize = 4; - if (ufont.getWidthPoint(text, fsize) >= wt) { - nlayout = LAYOUT_LABEL_ONLY; - fsize = fontSize; - continue; - } - textX = box.width() - ufont.getWidthPoint(text, fsize) - offX - 1; - textY = (box.height() - ufont.getFontDescriptor(BaseFont.ASCENT, fsize)) / 2; - iconBox = new Rectangle(box.left() + adj, box.bottom() + adj, textX - 1, box.top() - adj); - break; - } - break; - } - if (textY < box.bottom() + offX) - textY = box.bottom() + offX; - if (iconBox != null && (iconBox.width() <= 0 || iconBox.height() <= 0)) - iconBox = null; - if (iconBox != null) { - if (image != null) { - tp = new PdfTemplate(writer); - tp.setBoundingBox(new Rectangle(image)); - writer.addDirectTemplateSimple(tp, new PdfName("FRM")); - tp.addImage(image, image.width(), 0, 0, image.height(), 0, 0); - } - else if (template != null) { - tp = new PdfTemplate(writer); - tp.setBoundingBox(new Rectangle(template.getWidth(), template.getHeight())); - writer.addDirectTemplateSimple(tp, new PdfName("FRM")); - tp.addTemplate(template, template.getBoundingBox().left(), template.getBoundingBox().bottom()); - } - } - if (tp != null) { - float icx = iconBox.width() / tp.getBoundingBox().width(); - float icy = iconBox.height() / tp.getBoundingBox().height(); - if (proportionalIcon) { - switch (scaleIcon) { - case SCALE_ICON_IS_TOO_BIG: - icx = Math.min(icx, icy); - icx = Math.min(icx, 1); - break; - case SCALE_ICON_IS_TOO_SMALL: - icx = Math.min(icx, icy); - icx = Math.max(icx, 1); - break; - case SCALE_ICON_NEVER: - icx = 1; - break; - default: - icx = Math.min(icx, icy); - break; - } - icy = icx; - } - else { - switch (scaleIcon) { - case SCALE_ICON_IS_TOO_BIG: - icx = Math.min(icx, 1); - icy = Math.min(icy, 1); - break; - case SCALE_ICON_IS_TOO_SMALL: - icx = Math.max(icx, 1); - icy = Math.max(icy, 1); - break; - case SCALE_ICON_NEVER: - icx = icy = 1; - break; - default: - break; - } - } - float xpos = iconBox.left() + (iconBox.width() - (tp.getBoundingBox().width() * icx)) * iconHorizontalAdjustment; - float ypos = iconBox.bottom() + (iconBox.height() - (tp.getBoundingBox().height() * icy)) * iconVerticalAdjustment; - app.saveState(); - app.rectangle(iconBox.left(), iconBox.bottom(), iconBox.width(), iconBox.height()); - app.clip(); - app.newPath(); - app.addTemplate(tp, icx, 0, 0, icy, xpos, ypos); - app.restoreState(); - } - if (!Float.isNaN(textX)) { - app.saveState(); - app.rectangle(offX, offX, box.width() - 2 * offX, box.height() - 2 * offX); - app.clip(); - app.newPath(); - if (textColor == null) - app.resetGrayFill(); - else - app.setColorFill(textColor); - app.beginText(); - app.setFontAndSize(ufont, fsize); - app.setTextMatrix(textX, textY); - app.showText(text); - app.endText(); - app.restoreState(); - } - return app; - } - - /** - * Gets the pushbutton field. - * @throws IOException on error - * @throws DocumentException on error - * @return the pushbutton field - */ - public PdfFormField getField() throws IOException, DocumentException { - PdfFormField field = PdfFormField.createPushButton(writer); - field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); - if (fieldName != null) { - field.setFieldName(fieldName); - if ((options & READ_ONLY) != 0) - field.setFieldFlags(PdfFormField.FF_READ_ONLY); - if ((options & REQUIRED) != 0) - field.setFieldFlags(PdfFormField.FF_REQUIRED); - } - if (text != null) - field.setMKNormalCaption(text); - if (rotation != 0) - field.setMKRotation(rotation); - field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); - PdfAppearance tpa = getAppearance(); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tpa); - PdfAppearance da = (PdfAppearance)tpa.getDuplicate(); - da.setFontAndSize(getRealFont(), fontSize); - if (textColor == null) - da.setGrayFill(0); - else - da.setColorFill(textColor); - field.setDefaultAppearanceString(da); - if (borderColor != null) - field.setMKBorderColor(borderColor); - if (backgroundColor != null) - field.setMKBackgroundColor(backgroundColor); - switch (visibility) { - case HIDDEN: - field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); - break; - case VISIBLE_BUT_DOES_NOT_PRINT: - break; - case HIDDEN_BUT_PRINTABLE: - field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); - break; - default: - field.setFlags(PdfAnnotation.FLAGS_PRINT); - break; - } - if (tp != null) - field.setMKNormalIcon(tp); - field.setMKTextPosition(layout - 1); - PdfName scale = PdfName.A; - if (scaleIcon == SCALE_ICON_IS_TOO_BIG) - scale = PdfName.B; - else if (scaleIcon == SCALE_ICON_IS_TOO_SMALL) - scale = PdfName.S; - else if (scaleIcon == SCALE_ICON_NEVER) - scale = PdfName.N; - field.setMKIconFit(scale, proportionalIcon ? PdfName.P : PdfName.A, iconHorizontalAdjustment, - iconVerticalAdjustment, iconFitToBounds); - return field; - } - - /** - * Getter for property iconFitToBounds. - * @return Value of property iconFitToBounds. - */ - public boolean isIconFitToBounds() { - return this.iconFitToBounds; - } - - /** - * If true the icon will be scaled to fit fully within the bounds of the annotation, - * if false the border width will be taken into account. The default - * is false. - * @param iconFitToBounds if true the icon will be scaled to fit fully within the bounds of the annotation, - * if false the border width will be taken into account - */ - public void setIconFitToBounds(boolean iconFitToBounds) { - this.iconFitToBounds = iconFitToBounds; - } - -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/RadioCheckField.java b/src/main/java/com/lowagie/text/pdf/RadioCheckField.java deleted file mode 100644 index e6a254e..0000000 --- a/src/main/java/com/lowagie/text/pdf/RadioCheckField.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright 2005 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import com.lowagie.text.Rectangle; -import com.lowagie.text.ExceptionConverter; -import com.lowagie.text.DocumentException; -import java.io.IOException; - -/** - * Creates a radio or a check field. - *

- * Example usage: - *

- *

- * Document document = new Document(PageSize.A4, 50, 50, 50, 50);
- * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("output.pdf"));
- * document.open();
- * PdfContentByte cb = writer.getDirectContent();
- * RadioCheckField bt = new RadioCheckField(writer, new Rectangle(100, 100, 200, 200), "radio", "v1");
- * bt.setCheckType(RadioCheckField.TYPE_CIRCLE);
- * bt.setBackgroundColor(Color.cyan);
- * bt.setBorderStyle(PdfBorderDictionary.STYLE_SOLID);
- * bt.setBorderColor(Color.red);
- * bt.setTextColor(Color.yellow);
- * bt.setBorderWidth(BaseField.BORDER_WIDTH_THICK);
- * bt.setChecked(false);
- * PdfFormField f1 = bt.getRadioField();
- * bt.setOnValue("v2");
- * bt.setChecked(true);
- * bt.setBox(new Rectangle(100, 300, 200, 400));
- * PdfFormField f2 = bt.getRadioField();
- * bt.setChecked(false);
- * PdfFormField top = bt.getRadioGroup(true, false);
- * bt.setOnValue("v3");
- * bt.setBox(new Rectangle(100, 500, 200, 600));
- * PdfFormField f3 = bt.getRadioField();
- * top.addKid(f1);
- * top.addKid(f2);
- * top.addKid(f3);
- * writer.addAnnotation(top);
- * bt = new RadioCheckField(writer, new Rectangle(300, 300, 400, 400), "check1", "Yes");
- * bt.setCheckType(RadioCheckField.TYPE_CHECK);
- * bt.setBorderWidth(BaseField.BORDER_WIDTH_THIN);
- * bt.setBorderColor(Color.black);
- * bt.setBackgroundColor(Color.white);
- * PdfFormField ck = bt.getCheckField();
- * writer.addAnnotation(ck);
- * document.close();
- * 
- * @author Paulo Soares (psoares@consiste.pt) - */ -public class RadioCheckField extends BaseField { - - /** A field with the symbol check */ - public static final int TYPE_CHECK = 1; - /** A field with the symbol circle */ - public static final int TYPE_CIRCLE = 2; - /** A field with the symbol cross */ - public static final int TYPE_CROSS = 3; - /** A field with the symbol diamond */ - public static final int TYPE_DIAMOND = 4; - /** A field with the symbol square */ - public static final int TYPE_SQUARE = 5; - /** A field with the symbol star */ - public static final int TYPE_STAR = 6; - - private static String typeChars[] = {"4", "l", "8", "u", "n", "H"}; - - /** - * Holds value of property checkType. - */ - private int checkType; - - /** - * Holds value of property onValue. - */ - private String onValue; - - /** - * Holds value of property checked. - */ - private boolean checked; - - /** - * Creates a new instance of RadioCheckField - * @param writer the document PdfWriter - * @param box the field location and dimensions - * @param fieldName the field name. It must not be null - * @param onValue the value when the field is checked - */ - public RadioCheckField(PdfWriter writer, Rectangle box, String fieldName, String onValue) { - super(writer, box, fieldName); - setOnValue(onValue); - setCheckType(TYPE_CIRCLE); - } - - /** - * Getter for property checkType. - * @return Value of property checkType. - */ - public int getCheckType() { - return this.checkType; - } - - /** - * Sets the checked symbol. It can be - * TYPE_CHECK, - * TYPE_CIRCLE, - * TYPE_CROSS, - * TYPE_DIAMOND, - * TYPE_SQUARE and - * TYPE_STAR. - * @param checkType the checked symbol - */ - public void setCheckType(int checkType) { - if (checkType < TYPE_CHECK || checkType > TYPE_STAR) - checkType = TYPE_CIRCLE; - this.checkType = checkType; - setText(typeChars[checkType - 1]); - try { - setFont(BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, false)); - } - catch (Exception e) { - throw new ExceptionConverter(e); - } - } - - /** - * Getter for property onValue. - * @return Value of property onValue. - */ - public String getOnValue() { - return this.onValue; - } - - /** - * Sets the value when the field is checked. - * @param onValue the value when the field is checked - */ - public void setOnValue(String onValue) { - this.onValue = onValue; - } - - /** - * Getter for property checked. - * @return Value of property checked. - */ - public boolean isChecked() { - return this.checked; - } - - /** - * Sets the state of the field to checked or unchecked. - * @param checked the state of the field, true for checked - * and false for unchecked - */ - public void setChecked(boolean checked) { - this.checked = checked; - } - - /** - * Gets the field appearance. - * @param isRadio true for a radio field and false - * for a check field - * @param on true for the checked state, false - * otherwise - * @throws IOException on error - * @throws DocumentException on error - * @return the appearance - */ - public PdfAppearance getAppearance(boolean isRadio, boolean on) throws IOException, DocumentException { - if (isRadio && checkType == TYPE_CIRCLE) - return getAppearanceRadioCircle(on); - PdfAppearance app = getBorderAppearance(); - if (!on) - return app; - BaseFont ufont = getRealFont(); - boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET; - float h = box.height() - borderWidth * 2; - float bw2 = borderWidth; - if (borderExtra) { - h -= borderWidth * 2; - bw2 *= 2; - } - float offsetX = (borderExtra ? 2 * borderWidth : borderWidth); - offsetX = Math.max(offsetX, 1); - float offX = Math.min(bw2, offsetX); - float wt = box.width() - 2 * offX; - float ht = box.height() - 2 * offX; - float fsize = fontSize; - if (fsize == 0) { - float bw = ufont.getWidthPoint(text, 1); - if (bw == 0) - fsize = 12; - else - fsize = wt / bw; - float nfsize = h / (ufont.getFontDescriptor(BaseFont.ASCENT, 1)); - fsize = Math.min(fsize, nfsize); - } - app.saveState(); - app.rectangle(offX, offX, box.width() - 2 * offX, box.height() - 2 * offX); - app.clip(); - app.newPath(); - if (textColor == null) - app.resetGrayFill(); - else - app.setColorFill(textColor); - app.beginText(); - app.setFontAndSize(ufont, fsize); - app.setTextMatrix((box.width() - ufont.getWidthPoint(text, fsize)) / 2, - (box.height() - ufont.getAscentPoint(text, fsize)) / 2); - app.showText(text); - app.endText(); - app.restoreState(); - return app; - } - - /** - * Gets the special field appearance for the radio circle. - * @param on true for the checked state, false - * otherwise - * @return the appearance - */ - public PdfAppearance getAppearanceRadioCircle(boolean on) { - PdfAppearance app = new PdfContentByte(writer).createAppearance(box.width(), box.height()); - switch (rotation) { - case 90: - app.setMatrix(0, 1, -1, 0, box.height(), 0); - break; - case 180: - app.setMatrix(-1, 0, 0, -1, box.width(), box.height()); - break; - case 270: - app.setMatrix(0, -1, 1, 0, 0, box.width()); - break; - } - Rectangle box = new Rectangle(app.getBoundingBox()); - float cx = box.width() / 2; - float cy = box.height() / 2; - float r = (Math.min(box.width(), box.height()) - borderWidth) / 2; - if (r <= 0) - return app; - if (backgroundColor != null) { - app.setColorFill(backgroundColor); - app.circle(cx, cy, r + borderWidth / 2); - app.fill(); - } - if (borderWidth > 0 && borderColor != null) { - app.setLineWidth(borderWidth); - app.setColorStroke(borderColor); - app.circle(cx, cy, r); - app.stroke(); - } - if (on) { - if (textColor == null) - app.resetGrayFill(); - else - app.setColorFill(textColor); - app.circle(cx, cy, r / 2); - app.fill(); - } - return app; - } - - /** - * Gets a radio group. It's composed of the field specific keys, without the widget - * ones. This field is to be used as a field aggregator with {@link PdfFormField#addKid(PdfFormField) addKid()}. - * @param noToggleToOff if true, exactly one radio button must be selected at all - * times; clicking the currently selected button has no effect. - * If false, clicking - * the selected button deselects it, leaving no button selected. - * @param radiosInUnison if true, a group of radio buttons within a radio button field that - * use the same value for the on state will turn on and off in unison; that is if - * one is checked, they are all checked. If false, the buttons are mutually exclusive - * (the same behavior as HTML radio buttons) - * @return the radio group - */ - public PdfFormField getRadioGroup(boolean noToggleToOff, boolean radiosInUnison) { - PdfFormField field = PdfFormField.createRadioButton(writer, noToggleToOff); - if (radiosInUnison) - field.setFieldFlags(PdfFormField.FF_RADIOSINUNISON); - field.setFieldName(fieldName); - if ((options & READ_ONLY) != 0) - field.setFieldFlags(PdfFormField.FF_READ_ONLY); - if ((options & REQUIRED) != 0) - field.setFieldFlags(PdfFormField.FF_REQUIRED); - field.setValueAsName(checked ? onValue : "Off"); - return field; - } - - /** - * Gets the radio field. It's only composed of the widget keys and must be used - * with {@link #getRadioGroup(boolean,boolean)}. - * @return the radio field - * @throws IOException on error - * @throws DocumentException on error - */ - public PdfFormField getRadioField() throws IOException, DocumentException { - return getField(true); - } - - /** - * Gets the check field. - * @return the check field - * @throws IOException on error - * @throws DocumentException on error - */ - public PdfFormField getCheckField() throws IOException, DocumentException { - return getField(false); - } - - /** - * Gets a radio or check field. - * @param isRadio true to get a radio field, false to get - * a check field - * @throws IOException on error - * @throws DocumentException on error - * @return the field - */ - protected PdfFormField getField(boolean isRadio) throws IOException, DocumentException { - PdfFormField field = null; - if (isRadio) - field = PdfFormField.createEmpty(writer); - else - field = PdfFormField.createCheckBox(writer); - field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT); - if (!isRadio) { - field.setFieldName(fieldName); - if ((options & READ_ONLY) != 0) - field.setFieldFlags(PdfFormField.FF_READ_ONLY); - if ((options & REQUIRED) != 0) - field.setFieldFlags(PdfFormField.FF_REQUIRED); - field.setValueAsName(checked ? onValue : "Off"); - } - if (text != null) - field.setMKNormalCaption(text); - if (rotation != 0) - field.setMKRotation(rotation); - field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3))); - PdfAppearance tpon = getAppearance(isRadio, true); - PdfAppearance tpoff = getAppearance(isRadio, false); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, onValue, tpon); - field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpoff); - field.setAppearanceState(checked ? onValue : "Off"); - PdfAppearance da = (PdfAppearance)tpon.getDuplicate(); - da.setFontAndSize(getRealFont(), fontSize); - if (textColor == null) - da.setGrayFill(0); - else - da.setColorFill(textColor); - field.setDefaultAppearanceString(da); - if (borderColor != null) - field.setMKBorderColor(borderColor); - if (backgroundColor != null) - field.setMKBackgroundColor(backgroundColor); - switch (visibility) { - case HIDDEN: - field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_HIDDEN); - break; - case VISIBLE_BUT_DOES_NOT_PRINT: - break; - case HIDDEN_BUT_PRINTABLE: - field.setFlags(PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_NOVIEW); - break; - default: - field.setFlags(PdfAnnotation.FLAGS_PRINT); - break; - } - return field; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/RandomAccessFileOrArray.java b/src/main/java/com/lowagie/text/pdf/RandomAccessFileOrArray.java deleted file mode 100644 index 212a6c8..0000000 --- a/src/main/java/com/lowagie/text/pdf/RandomAccessFileOrArray.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * $Id: RandomAccessFileOrArray.java,v 1.49 2005/09/12 16:15:23 psoares33 Exp $ - * $Name: $ - * - * Copyright 2001, 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.io.DataInputStream; -import java.io.DataInput; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.EOFException; -import java.io.RandomAccessFile; -import java.io.File; -import java.io.InputStream; -import java.io.ByteArrayOutputStream; -import java.net.URL; -/** An implementation of a RandomAccessFile for input only - * that accepts a file or a byte array as data source. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class RandomAccessFileOrArray implements DataInput { - - RandomAccessFile rf; - String filename; - byte arrayIn[]; - int arrayInPtr; - byte back; - boolean isBack = false; - - /** Holds value of property startOffset. */ - private int startOffset = 0; - - public RandomAccessFileOrArray(String filename) throws IOException { - this(filename, false); - } - - public RandomAccessFileOrArray(String filename, boolean forceRead) throws IOException { - File file = new File(filename); - if (!file.canRead()) { - if (filename.startsWith("file:/") || filename.startsWith("http://") || filename.startsWith("https://") || filename.startsWith("jar:")) { - InputStream is = new URL(filename).openStream(); - try { - this.arrayIn = InputStreamToArray(is); - return; - } - finally { - try {is.close();}catch(IOException ioe){} - } - } - else { - InputStream is = BaseFont.getResourceStream(filename); - if (is == null) - throw new IOException(filename + " not found as file or resource."); - try { - this.arrayIn = InputStreamToArray(is); - return; - } - finally { - try {is.close();}catch(IOException ioe){} - } - } - } - else if (forceRead) { - InputStream s = null; - try { - s = new FileInputStream(file); - this.arrayIn = InputStreamToArray(s); - } - finally { - try {s.close();}catch(Exception e){} - } - return; - } - this.filename = filename; - rf = new RandomAccessFile(filename, "r"); - } - - public RandomAccessFileOrArray(URL url) throws IOException { - InputStream is = url.openStream(); - try { - this.arrayIn = InputStreamToArray(is); - } - finally { - try {is.close();}catch(IOException ioe){} - } - } - - public RandomAccessFileOrArray(InputStream is) throws IOException { - this.arrayIn = InputStreamToArray(is); - } - - public static byte[] InputStreamToArray(InputStream is) throws IOException { - byte b[] = new byte[8192]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - while (true) { - int read = is.read(b); - if (read < 1) - break; - out.write(b, 0, read); - } - return out.toByteArray(); - } - - public RandomAccessFileOrArray(byte arrayIn[]) { - this.arrayIn = arrayIn; - } - - public RandomAccessFileOrArray(RandomAccessFileOrArray file) { - filename = file.filename; - arrayIn = file.arrayIn; - startOffset = file.startOffset; - } - - public void pushBack(byte b) { - back = b; - isBack = true; - } - - public int read() throws IOException { - if(isBack) { - isBack = false; - return back & 0xff; - } - if (arrayIn == null) - return rf.read(); - else { - if (arrayInPtr >= arrayIn.length) - return -1; - return arrayIn[arrayInPtr++] & 0xff; - } - } - - public int read(byte[] b, int off, int len) throws IOException { - if (len == 0) - return 0; - int n = 0; - if (isBack) { - isBack = false; - if (len == 1) { - b[off] = back; - return 1; - } - else { - n = 1; - b[off++] = back; - --len; - } - } - if (arrayIn == null) { - return rf.read(b, off, len) + n; - } - else { - if (arrayInPtr >= arrayIn.length) - return -1; - if (arrayInPtr + len > arrayIn.length) - len = arrayIn.length - arrayInPtr; - System.arraycopy(arrayIn, arrayInPtr, b, off, len); - arrayInPtr += len; - return len + n; - } - } - - public int read(byte b[]) throws IOException { - return read(b, 0, b.length); - } - - public void readFully(byte b[]) throws IOException { - readFully(b, 0, b.length); - } - - public void readFully(byte b[], int off, int len) throws IOException { - int n = 0; - do { - int count = read(b, off + n, len - n); - if (count < 0) - throw new EOFException(); - n += count; - } while (n < len); - } - - public long skip(long n) throws IOException { - return skipBytes((int)n); - } - - public int skipBytes(int n) throws IOException { - if (n <= 0) { - return 0; - } - int adj = 0; - if (isBack) { - isBack = false; - if (n == 1) { - return 1; - } - else { - --n; - adj = 1; - } - } - int pos; - int len; - int newpos; - - pos = getFilePointer(); - len = length(); - newpos = pos + n; - if (newpos > len) { - newpos = len; - } - seek(newpos); - - /* return the actual number of bytes skipped */ - return newpos - pos + adj; - } - - public void reOpen() throws IOException { - if (filename != null && rf == null) - rf = new RandomAccessFile(filename, "r"); - seek(0); - } - - protected void insureOpen() throws IOException { - if (filename != null && rf == null) { - reOpen(); - } - } - - public boolean isOpen() { - return (filename == null || rf != null); - } - - public void close() throws IOException { - isBack = false; - if (rf != null) { - rf.close(); - rf = null; - } - } - - public int length() throws IOException { - if (arrayIn == null) { - insureOpen(); - return (int)rf.length() - startOffset; - } - else - return arrayIn.length - startOffset; - } - - public void seek(int pos) throws IOException { - pos += startOffset; - isBack = false; - if (arrayIn == null) { - insureOpen(); - rf.seek(pos); - } - else - arrayInPtr = pos; - } - - public void seek(long pos) throws IOException { - seek((int)pos); - } - - public int getFilePointer() throws IOException { - insureOpen(); - int n = isBack ? 1 : 0; - if (arrayIn == null) { - return (int)rf.getFilePointer() - n - startOffset; - } - else - return arrayInPtr - n - startOffset; - } - - public boolean readBoolean() throws IOException { - int ch = this.read(); - if (ch < 0) - throw new EOFException(); - return (ch != 0); - } - - public byte readByte() throws IOException { - int ch = this.read(); - if (ch < 0) - throw new EOFException(); - return (byte)(ch); - } - - public int readUnsignedByte() throws IOException { - int ch = this.read(); - if (ch < 0) - throw new EOFException(); - return ch; - } - - public short readShort() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (short)((ch1 << 8) + ch2); - } - - /** - * Reads a signed 16-bit number from this stream in little-endian order. - * The method reads two - * bytes from this stream, starting at the current stream pointer. - * If the two bytes read, in order, are - * b1 and b2, where each of the two values is - * between 0 and 255, inclusive, then the - * result is equal to: - *
-     *     (short)((b2 << 8) | b1)
-     * 
- *

- * This method blocks until the two bytes are read, the end of the - * stream is detected, or an exception is thrown. - * - * @return the next two bytes of this stream, interpreted as a signed - * 16-bit number. - * @exception EOFException if this stream reaches the end before reading - * two bytes. - * @exception IOException if an I/O error occurs. - */ - public final short readShortLE() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (short)((ch2 << 8) + (ch1 << 0)); - } - - public int readUnsignedShort() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (ch1 << 8) + ch2; - } - - /** - * Reads an unsigned 16-bit number from this stream in little-endian order. - * This method reads - * two bytes from the stream, starting at the current stream pointer. - * If the bytes read, in order, are - * b1 and b2, where - * 0 <= b1, b2 <= 255, - * then the result is equal to: - *

-     *     (b2 << 8) | b1
-     * 
- *

- * This method blocks until the two bytes are read, the end of the - * stream is detected, or an exception is thrown. - * - * @return the next two bytes of this stream, interpreted as an - * unsigned 16-bit integer. - * @exception EOFException if this stream reaches the end before reading - * two bytes. - * @exception IOException if an I/O error occurs. - */ - public final int readUnsignedShortLE() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (ch2 << 8) + (ch1 << 0); - } - - public char readChar() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (char)((ch1 << 8) + ch2); - } - - /** - * Reads a Unicode character from this stream in little-endian order. - * This method reads two - * bytes from the stream, starting at the current stream pointer. - * If the bytes read, in order, are - * b1 and b2, where - * 0 <= b1, b2 <= 255, - * then the result is equal to: - *

-     *     (char)((b2 << 8) | b1)
-     * 
- *

- * This method blocks until the two bytes are read, the end of the - * stream is detected, or an exception is thrown. - * - * @return the next two bytes of this stream as a Unicode character. - * @exception EOFException if this stream reaches the end before reading - * two bytes. - * @exception IOException if an I/O error occurs. - */ - public final char readCharLE() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - if ((ch1 | ch2) < 0) - throw new EOFException(); - return (char)((ch2 << 8) + (ch1 << 0)); - } - - public int readInt() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - int ch3 = this.read(); - int ch4 = this.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) - throw new EOFException(); - return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4); - } - - /** - * Reads a signed 32-bit integer from this stream in little-endian order. - * This method reads 4 - * bytes from the stream, starting at the current stream pointer. - * If the bytes read, in order, are b1, - * b2, b3, and b4, where - * 0 <= b1, b2, b3, b4 <= 255, - * then the result is equal to: - *

-     *     (b4 << 24) | (b3 << 16) + (b2 << 8) + b1
-     * 
- *

- * This method blocks until the four bytes are read, the end of the - * stream is detected, or an exception is thrown. - * - * @return the next four bytes of this stream, interpreted as an - * int. - * @exception EOFException if this stream reaches the end before reading - * four bytes. - * @exception IOException if an I/O error occurs. - */ - public final int readIntLE() throws IOException { - int ch1 = this.read(); - int ch2 = this.read(); - int ch3 = this.read(); - int ch4 = this.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) - throw new EOFException(); - return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); - } - - /** - * Reads an unsigned 32-bit integer from this stream. This method reads 4 - * bytes from the stream, starting at the current stream pointer. - * If the bytes read, in order, are b1, - * b2, b3, and b4, where - * 0 <= b1, b2, b3, b4 <= 255, - * then the result is equal to: - *

-     *     (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
-     * 
- *

- * This method blocks until the four bytes are read, the end of the - * stream is detected, or an exception is thrown. - * - * @return the next four bytes of this stream, interpreted as a - * long. - * @exception EOFException if this stream reaches the end before reading - * four bytes. - * @exception IOException if an I/O error occurs. - */ - public final long readUnsignedInt() throws IOException { - long ch1 = this.read(); - long ch2 = this.read(); - long ch3 = this.read(); - long ch4 = this.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) - throw new EOFException(); - return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); - } - - public final long readUnsignedIntLE() throws IOException { - long ch1 = this.read(); - long ch2 = this.read(); - long ch3 = this.read(); - long ch4 = this.read(); - if ((ch1 | ch2 | ch3 | ch4) < 0) - throw new EOFException(); - return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); - } - - public long readLong() throws IOException { - return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL); - } - - public final long readLongLE() throws IOException { - int i1 = readIntLE(); - int i2 = readIntLE(); - return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); - } - - public float readFloat() throws IOException { - return Float.intBitsToFloat(readInt()); - } - - public final float readFloatLE() throws IOException { - return Float.intBitsToFloat(readIntLE()); - } - - public double readDouble() throws IOException { - return Double.longBitsToDouble(readLong()); - } - - public final double readDoubleLE() throws IOException { - return Double.longBitsToDouble(readLongLE()); - } - - public String readLine() throws IOException { - StringBuffer input = new StringBuffer(); - int c = -1; - boolean eol = false; - - while (!eol) { - switch (c = read()) { - case -1: - case '\n': - eol = true; - break; - case '\r': - eol = true; - int cur = getFilePointer(); - if ((read()) != '\n') { - seek(cur); - } - break; - default: - input.append((char)c); - break; - } - } - - if ((c == -1) && (input.length() == 0)) { - return null; - } - return input.toString(); - } - - public String readUTF() throws IOException { - return DataInputStream.readUTF(this); - } - - /** Getter for property startOffset. - * @return Value of property startOffset. - * - */ - public int getStartOffset() { - return this.startOffset; - } - - /** Setter for property startOffset. - * @param startOffset New value of property startOffset. - * - */ - public void setStartOffset(int startOffset) { - this.startOffset = startOffset; - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/SequenceList.java b/src/main/java/com/lowagie/text/pdf/SequenceList.java deleted file mode 100644 index e00d1d4..0000000 --- a/src/main/java/com/lowagie/text/pdf/SequenceList.java +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright 2004 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ -package com.lowagie.text.pdf; - -import java.util.List; -import java.util.LinkedList; -import java.util.ListIterator; - -/** - * This class expands a string into a list of numbers. The main use is to select a - * range of pages. - *

- * The general systax is:
- * [!][o][odd][e][even]start-end - *

- * You can have multiple ranges separated by commas ','. The '!' modifier removes the - * range from what is already selected. The range changes are incremental, that is, - * numbers are added or deleted as the range appears. The start or the end, but not both, can be ommited. - */ -public class SequenceList { - protected static final int COMMA = 1; - protected static final int MINUS = 2; - protected static final int NOT = 3; - protected static final int TEXT = 4; - protected static final int NUMBER = 5; - protected static final int END = 6; - protected static final char EOT = '\uffff'; - - private static final int FIRST = 0; - private static final int DIGIT = 1; - private static final int OTHER = 2; - private static final int DIGIT2 = 3; - private static final String NOT_OTHER = "-,!0123456789"; - - protected char text[]; - protected int ptr; - protected int number; - protected String other; - - protected int low; - protected int high; - protected boolean odd; - protected boolean even; - protected boolean inverse; - - protected SequenceList(String range) { - ptr = 0; - text = range.toCharArray(); - } - - protected char nextChar() { - while (true) { - if (ptr >= text.length) - return EOT; - char c = text[ptr++]; - if (c > ' ') - return c; - } - } - - protected void putBack() { - --ptr; - if (ptr < 0) - ptr = 0; - } - - protected int getType() { - StringBuffer buf = new StringBuffer(); - int state = FIRST; - while (true) { - char c = nextChar(); - if (c == EOT) { - if (state == DIGIT) { - number = Integer.parseInt(other = buf.toString()); - return NUMBER; - } - else if (state == OTHER) { - other = buf.toString().toLowerCase(); - return TEXT; - } - return END; - } - switch (state) { - case FIRST: - switch (c) { - case '!': - return NOT; - case '-': - return MINUS; - case ',': - return COMMA; - } - buf.append(c); - if (c >= '0' && c <= '9') - state = DIGIT; - else - state = OTHER; - break; - case DIGIT: - if (c >= '0' && c <= '9') - buf.append(c); - else { - putBack(); - number = Integer.parseInt(other = buf.toString()); - return NUMBER; - } - break; - case OTHER: - if (NOT_OTHER.indexOf(c) < 0) - buf.append(c); - else { - putBack(); - other = buf.toString().toLowerCase(); - return TEXT; - } - break; - } - } - } - - private void otherProc() { - if (other.equals("odd") || other.equals("o")) { - odd = true; - even = false; - } - else if (other.equals("even") || other.equals("e")) { - odd = false; - even = true; - } - } - - protected boolean getAttributes() { - low = -1; - high = -1; - odd = even = inverse = false; - int state = OTHER; - while (true) { - int type = getType(); - if (type == END || type == COMMA) { - if (state == DIGIT) - high = low; - return (type == END); - } - switch (state) { - case OTHER: - switch (type) { - case NOT: - inverse = true; - break; - case MINUS: - state = DIGIT2; - break; - default: - if (type == NUMBER) { - low = number; - state = DIGIT; - } - else - otherProc(); - break; - } - break; - case DIGIT: - switch (type) { - case NOT: - inverse = true; - state = OTHER; - high = low; - break; - case MINUS: - state = DIGIT2; - break; - default: - high = low; - state = OTHER; - otherProc(); - break; - } - break; - case DIGIT2: - switch (type) { - case NOT: - inverse = true; - state = OTHER; - break; - case MINUS: - break; - case NUMBER: - high = number; - state = OTHER; - break; - default: - state = OTHER; - otherProc(); - break; - } - break; - } - } - } - - /** - * Generates a list of numbers from a string. - * @param ranges the comma separated ranges - * @param maxNumber the maximum number in the range - * @return a list with the numbers as Integer - */ - public static List expand(String ranges, int maxNumber) { - SequenceList parse = new SequenceList(ranges); - LinkedList list = new LinkedList(); - boolean sair = false; - while (!sair) { - sair = parse.getAttributes(); - if (parse.low == -1 && parse.high == -1 && !parse.even && !parse.odd) - continue; - if (parse.low < 1) - parse.low = 1; - if (parse.high < 1 || parse.high > maxNumber) - parse.high = maxNumber; - if (parse.low > maxNumber) - parse.low = maxNumber; - - //System.out.println("low="+parse.low+",high="+parse.high+",odd="+parse.odd+",even="+parse.even+",inverse="+parse.inverse); - int inc = 1; - if (parse.inverse) { - if (parse.low > parse.high) { - int t = parse.low; - parse.low = parse.high; - parse.high = t; - } - for (ListIterator it = list.listIterator(); it.hasNext();) { - int n = ((Integer)it.next()).intValue(); - if (parse.even && (n & 1) == 1) - continue; - if (parse.odd && (n & 1) == 0) - continue; - if (n >= parse.low && n <= parse.high) - it.remove(); - } - } - else { - if (parse.low > parse.high) { - inc = -1; - if (parse.odd || parse.even) { - --inc; - if (parse.even) - parse.low &= ~1; - else - parse.low -= ((parse.low & 1) == 1 ? 0 : 1); - } - for (int k = parse.low; k >= parse.high; k += inc) - list.add(new Integer(k)); - } - else { - if (parse.odd || parse.even) { - ++inc; - if (parse.odd) - parse.low |= 1; - else - parse.low += ((parse.low & 1) == 1 ? 1 : 0); - } - for (int k = parse.low; k <= parse.high; k += inc) { - list.add(new Integer(k)); - } - } - } -// for (int k = 0; k < list.size(); ++k) -// System.out.print(((Integer)list.get(k)).intValue() + ","); -// System.out.println(); - } - return list; - } -} \ No newline at end of file diff --git a/src/main/java/com/lowagie/text/pdf/ShadingColor.java b/src/main/java/com/lowagie/text/pdf/ShadingColor.java deleted file mode 100644 index 8d38277..0000000 --- a/src/main/java/com/lowagie/text/pdf/ShadingColor.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2002 Paulo Soares - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -/** Implements a shading pattern as a Color. - * - * @author Paulo Soares (psoares@consiste.pt) - */ -public class ShadingColor extends ExtendedColor { - - PdfShadingPattern shadingPattern; - - /** - * Creates a shading color. - * @param shadingPattern - */ - public ShadingColor(PdfShadingPattern shadingPattern) { - super(TYPE_SHADING, .5f, .5f, .5f); - this.shadingPattern = shadingPattern; - } - - /** - * Gets the shading pattern. - * @return a shading pattern. - */ - public PdfShadingPattern getPdfShadingPattern() { - return shadingPattern; - } - - public boolean equals(Object obj) { - return this == obj; - } - - public int hashCode() { - return shadingPattern.hashCode(); - } - -} diff --git a/src/main/java/com/lowagie/text/pdf/SimpleBookmark.java b/src/main/java/com/lowagie/text/pdf/SimpleBookmark.java deleted file mode 100644 index f7bb5a8..0000000 --- a/src/main/java/com/lowagie/text/pdf/SimpleBookmark.java +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright 2003 by Paulo Soares. - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the License. - * - * The Original Code is 'iText, a free JAVA-PDF library'. - * - * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by - * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. - * All Rights Reserved. - * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer - * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. - * - * Contributor(s): all the names of the contributors are added in the source code - * where applicable. - * - * Alternatively, the contents of this file may be used under the terms of the - * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the - * provisions of LGPL are applicable instead of those above. If you wish to - * allow use of your version of this file only under the terms of the LGPL - * License and not to allow others to use your version of this file under - * the MPL, indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by the LGPL. - * If you do not delete the provisions above, a recipient may use your version - * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the MPL as stated above or under the terms of the GNU - * Library General Public License as published by the Free Software Foundation; - * either version 2 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more - * details. - * - * If you didn't download this code from the following link, you should check if - * you aren't using an obsolete version: - * http://www.lowagie.com/iText/ - */ - -package com.lowagie.text.pdf; - -import java.util.List; -import java.util.Iterator; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.StringTokenizer; -import java.io.IOException; -import java.io.OutputStream; -import java.io.InputStream; -import java.io.Writer; -import java.io.Reader; -import java.io.BufferedWriter; -import java.io.OutputStreamWriter; -import java.util.Stack; -/** - * Bookmark processing in a simple way. It has some limitations, mainly the only - * action types supported are GoTo, GoToR, URI and Launch. - *

- * The list structure is composed by a number of HashMap, keyed by strings, one HashMap - * for each bookmark. - * The element values are all strings with the exception of the key "Kids" that has - * another list for the child bookmarks. - *

- * All the bookmarks have a "Title" with the - * bookmark title and optionally a "Style" that can be "bold", "italic" or a - * combination of both. They can also have a "Color" key with a value of three - * floats separated by spaces. The key "Open" can have the values "true" or "false" and - * signals the open status of the children. It's "true" by default. - *

- * The actions and the parameters can be: - *