aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/lowagie/text/pdf
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/lowagie/text/pdf')
-rw-r--r--src/main/java/com/lowagie/text/pdf/AcroFields.java1883
-rw-r--r--src/main/java/com/lowagie/text/pdf/ArabicLigaturizer.java771
-rw-r--r--src/main/java/com/lowagie/text/pdf/AsianFontMapper.java103
-rw-r--r--src/main/java/com/lowagie/text/pdf/BadPdfFormatException.java85
-rw-r--r--src/main/java/com/lowagie/text/pdf/Barcode.java477
-rw-r--r--src/main/java/com/lowagie/text/pdf/Barcode128.java825
-rw-r--r--src/main/java/com/lowagie/text/pdf/Barcode39.java392
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodeCodabar.java345
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodeEAN.java718
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodeEANSUPP.java153
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodeInter25.java338
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodePDF417.java1604
-rw-r--r--src/main/java/com/lowagie/text/pdf/BarcodePostnet.java233
-rw-r--r--src/main/java/com/lowagie/text/pdf/BaseField.java665
-rw-r--r--src/main/java/com/lowagie/text/pdf/BaseFont.java1137
-rw-r--r--src/main/java/com/lowagie/text/pdf/BidiLine.java915
-rw-r--r--src/main/java/com/lowagie/text/pdf/BidiOrder.java1240
-rw-r--r--src/main/java/com/lowagie/text/pdf/ByteBuffer.java623
-rw-r--r--src/main/java/com/lowagie/text/pdf/CFFFont.java1184
-rw-r--r--src/main/java/com/lowagie/text/pdf/CFFFontSubset.java1633
-rw-r--r--src/main/java/com/lowagie/text/pdf/CJKFont.java626
-rw-r--r--src/main/java/com/lowagie/text/pdf/CMYKColor.java129
-rw-r--r--src/main/java/com/lowagie/text/pdf/ColorDetails.java101
-rw-r--r--src/main/java/com/lowagie/text/pdf/ColumnText.java1520
-rw-r--r--src/main/java/com/lowagie/text/pdf/DefaultFontMapper.java308
-rw-r--r--src/main/java/com/lowagie/text/pdf/DocumentFont.java599
-rw-r--r--src/main/java/com/lowagie/text/pdf/EnumerateTTC.java118
-rw-r--r--src/main/java/com/lowagie/text/pdf/ExtendedColor.java122
-rw-r--r--src/main/java/com/lowagie/text/pdf/ExtraEncoding.java74
-rw-r--r--src/main/java/com/lowagie/text/pdf/FdfReader.java214
-rw-r--r--src/main/java/com/lowagie/text/pdf/FdfWriter.java333
-rw-r--r--src/main/java/com/lowagie/text/pdf/FontDetails.java275
-rw-r--r--src/main/java/com/lowagie/text/pdf/FontMapper.java80
-rw-r--r--src/main/java/com/lowagie/text/pdf/FontSelector.java124
-rw-r--r--src/main/java/com/lowagie/text/pdf/GlyphList.java2200
-rw-r--r--src/main/java/com/lowagie/text/pdf/GrayColor.java85
-rw-r--r--src/main/java/com/lowagie/text/pdf/HyphenationAuto.java125
-rw-r--r--src/main/java/com/lowagie/text/pdf/HyphenationEvent.java78
-rw-r--r--src/main/java/com/lowagie/text/pdf/IntHashtable.java338
-rw-r--r--src/main/java/com/lowagie/text/pdf/LZWDecoder.java231
-rw-r--r--src/main/java/com/lowagie/text/pdf/MultiColumnText.java575
-rw-r--r--src/main/java/com/lowagie/text/pdf/OutputStreamCounter.java170
-rw-r--r--src/main/java/com/lowagie/text/pdf/PRAcroForm.java210
-rw-r--r--src/main/java/com/lowagie/text/pdf/PRIndirectReference.java103
-rw-r--r--src/main/java/com/lowagie/text/pdf/PRStream.java229
-rw-r--r--src/main/java/com/lowagie/text/pdf/PRTokeniser.java585
-rw-r--r--src/main/java/com/lowagie/text/pdf/PageResources.java187
-rw-r--r--src/main/java/com/lowagie/text/pdf/PatternColor.java79
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfAcroForm.java744
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfAction.java558
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfAnnotation.java742
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfAppearance.java155
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfArray.java227
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfBoolean.java134
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfBorderArray.java82
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfBorderDictionary.java100
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfCell.java890
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfChunk.java781
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfColor.java80
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfContentByte.java3053
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfContentParser.java204
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfContents.java147
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfCopy.java474
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfCopyFields.java208
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfCopyFieldsImp.java639
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDashPattern.java144
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDate.java210
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDestination.java221
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDictionary.java353
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfDocument.java3279
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfEncodings.java716
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfEncryption.java390
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfEncryptionStream.java85
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfEncryptor.java176
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfException.java86
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfFileSpecification.java194
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfFont.java188
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfFormField.java347
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfFormXObject.java103
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfFunction.java142
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfGState.java144
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfGraphics2D.java1450
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfICCBased.java86
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfImage.java279
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfImportedPage.java149
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfIndirectObject.java170
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfIndirectReference.java133
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfLayer.java302
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfLayerMembership.java139
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfLine.java477
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfLister.java187
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfLiteral.java111
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfMediaClipData.java63
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfName.java1141
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfNameTree.java165
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfNull.java87
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfNumber.java159
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfNumberTree.java159
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfOCG.java67
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfOCProperties.java59
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfObject.java369
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfOutline.java542
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPCell.java735
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPCellEvent.java74
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPKCS7.java1276
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPRow.java659
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPSXObject.java99
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPTable.java1081
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPTableEvent.java94
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPage.java197
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPageElement.java78
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPageEvent.java190
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPageEventHelper.java202
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPageLabels.java191
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPages.java205
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPattern.java83
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPatternPainter.java391
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfPrinterGraphics2D.java73
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfReader.java3172
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfReaderInstance.java182
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfRectangle.java284
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfRendition.java61
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfResources.java91
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfShading.java261
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfShadingPattern.java119
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfSigGenericPKCS.java230
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfSignature.java97
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfSignatureAppearance.java1349
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfSpotColor.java132
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfStamper.java667
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfStamperImp.java1461
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfStream.java313
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfString.java236
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfStructureElement.java130
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfStructureTreeRoot.java146
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfTable.java316
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfTemplate.java267
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfTextArray.java99
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfTransition.java253
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfTransparencyGroup.java85
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfWriter.java2752
-rw-r--r--src/main/java/com/lowagie/text/pdf/PdfXConformanceException.java70
-rw-r--r--src/main/java/com/lowagie/text/pdf/Pfm2afm.java773
-rw-r--r--src/main/java/com/lowagie/text/pdf/PushbuttonField.java601
-rw-r--r--src/main/java/com/lowagie/text/pdf/RadioCheckField.java416
-rw-r--r--src/main/java/com/lowagie/text/pdf/RandomAccessFileOrArray.java609
-rw-r--r--src/main/java/com/lowagie/text/pdf/SequenceList.java317
-rw-r--r--src/main/java/com/lowagie/text/pdf/ShadingColor.java83
-rw-r--r--src/main/java/com/lowagie/text/pdf/SimpleBookmark.java745
-rw-r--r--src/main/java/com/lowagie/text/pdf/SimpleNamedDestination.java335
-rw-r--r--src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandler.java80
-rw-r--r--src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandlerComment.java59
-rw-r--r--src/main/java/com/lowagie/text/pdf/SimpleXMLParser.java1177
-rw-r--r--src/main/java/com/lowagie/text/pdf/SpotColor.java90
-rw-r--r--src/main/java/com/lowagie/text/pdf/StampContent.java81
-rw-r--r--src/main/java/com/lowagie/text/pdf/TextField.java661
-rw-r--r--src/main/java/com/lowagie/text/pdf/TrueTypeFont.java1377
-rw-r--r--src/main/java/com/lowagie/text/pdf/TrueTypeFontSubSet.java428
-rw-r--r--src/main/java/com/lowagie/text/pdf/TrueTypeFontUnicode.java456
-rw-r--r--src/main/java/com/lowagie/text/pdf/Type1Font.java807
-rw-r--r--src/main/java/com/lowagie/text/pdf/Type3Font.java306
-rw-r--r--src/main/java/com/lowagie/text/pdf/Type3Glyph.java94
-rw-r--r--src/main/java/com/lowagie/text/pdf/VerticalText.java349
-rw-r--r--src/main/java/com/lowagie/text/pdf/XfdfReader.java208
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/BmpImage.java1282
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/CCITTG4Encoder.java600
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/GifImage.java593
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/PngImage.java987
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TIFFConstants.java296
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TIFFDirectory.java656
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java1477
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TIFFField.java472
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java255
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/TiffImage.java522
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/JavaCharStream.java547
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/MetaDoPS.java98
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PACommand.java19
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAContext.java2772
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAEngine.java155
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAParser.java351
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserConstants.java60
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserTokenManager.java1011
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAPencil.java431
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PAToken.java66
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/PainterException.java20
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/ParseException.java192
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/Token.java81
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/postscript/TokenMgrError.java133
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java112
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java94
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java760
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java211
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java71
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java91
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java372
-rw-r--r--src/main/java/com/lowagie/text/pdf/events/FieldPositioningEvents.java186
-rw-r--r--src/main/java/com/lowagie/text/pdf/events/IndexEvents.java401
-rw-r--r--src/main/java/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java91
-rw-r--r--src/main/java/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java90
-rw-r--r--src/main/java/com/lowagie/text/pdf/events/PdfPageEventForwarder.java312
-rw-r--r--src/main/java/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java62
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/ByteVector.java124
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/CharVector.java134
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/Hyphen.java68
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenation.java83
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationException.java28
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationTree.java454
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenator.java240
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/PatternConsumer.java55
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java278
-rw-r--r--src/main/java/com/lowagie/text/pdf/hyphenation/TernaryTree.java667
211 files changed, 0 insertions, 93945 deletions
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 <CODE>null</CODE> 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
- * <CODE>null</CODE>.
- * @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
- * <CODE>null</CODE>.
- * @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 <CODE>exportValues</CODE>
- * or <CODE>displayValues</CODE> may be <CODE>null</CODE> but not both. This method will only
- * set the list but will not set the value or appearance. For that, calling <CODE>setField()</CODE>
- * is required.
- * <p>
- * An example:
- * <p>
- * <PRE>
- * 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();
- * </PRE>
- * @param fieldName the field name
- * @param exportValues the export values
- * @param displayValues the display values
- * @return <CODE>true</CODE> if the operation succeeded, <CODE>false</CODE> 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: <CODE>FIELD_TYPE_PUSHBUTTON</CODE>,
- * <CODE>FIELD_TYPE_CHECKBOX</CODE>, <CODE>FIELD_TYPE_RADIOBUTTON</CODE>,
- * <CODE>FIELD_TYPE_TEXT</CODE>, <CODE>FIELD_TYPE_LIST</CODE>,
- * <CODE>FIELD_TYPE_COMBO</CODE> or <CODE>FIELD_TYPE_SIGNATURE</CODE>.
- * <p>
- * If the field does not exist or is invalid it returns
- * <CODE>FIELD_TYPE_NONE</CODE>.
- * @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 <CODE>true</CODE> if the renaming was successful, <CODE>false</CODE>
- * 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:
- * <p>
- * <ul>
- * <li>textfont - sets the text font. The value for this entry is a <CODE>BaseFont</CODE>.<br>
- * <li>textcolor - sets the text color. The value for this entry is a <CODE>java.awt.Color</CODE>.<br>
- * <li>textsize - sets the text size. The value for this entry is a <CODE>Float</CODE>.
- * <li>bgcolor - sets the background color. The value for this entry is a <CODE>java.awt.Color</CODE>.
- * If <code>null</code> removes the background.<br>
- * <li>bordercolor - sets the border color. The value for this entry is a <CODE>java.awt.Color</CODE>.
- * If <code>null</code> removes the border.<br>
- * </ul>
- * @param field the field name
- * @param name the property name
- * @param value the property value
- * @param inst an array of <CODE>int</CODE> indexing into <CODE>AcroField.Item.merged</CODE> elements to process.
- * Set to <CODE>null</CODE> to process all
- * @return <CODE>true</CODE> if the property exists, <CODE>false</CODE> 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:
- * <p>
- * <ul>
- * <li>flags - a set of flags specifying various characteristics of the field’s widget annotation.
- * The value of this entry replaces that of the F entry in the form’s corresponding annotation dictionary.<br>
- * <li>setflags - a set of flags to be set (turned on) in the F entry of the form’s corresponding
- * widget annotation dictionary. Bits equal to 1 cause the corresponding bits in F to be set to 1.<br>
- * <li>clrflags - a set of flags to be cleared (turned off) in the F entry of the form’s corresponding
- * widget annotation dictionary. Bits equal to 1 cause the corresponding
- * bits in F to be set to 0.<br>
- * <li>fflags - a set of flags specifying various characteristics of the field. The value
- * of this entry replaces that of the Ff entry in the form’s corresponding field dictionary.<br>
- * <li>setfflags - a set of flags to be set (turned on) in the Ff entry of the form’s corresponding
- * field dictionary. Bits equal to 1 cause the corresponding bits in Ff to be set to 1.<br>
- * <li>clrfflags - a set of flags to be cleared (turned off) in the Ff entry of the form’s corresponding
- * field dictionary. Bits equal to 1 cause the corresponding bits in Ff
- * to be set to 0.<br>
- * </ul>
- * @param field the field name
- * @param name the property name
- * @param value the property value
- * @param inst an array of <CODE>int</CODE> indexing into <CODE>AcroField.Item.merged</CODE> elements to process.
- * Set to <CODE>null</CODE> to process all
- * @return <CODE>true</CODE> if the property exists, <CODE>false</CODE> 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 <CODE>true</CODE> if the field was found and changed,
- * <CODE>false</CODE> 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 <CODE>true</CODE> if the field was found and changed,
- * <CODE>false</CODE> 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 <CODE>AcroFields.Item</CODE>.
- * @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 <CODE>null</CODE> 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 <CODE>float</CODE>
- * 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 <CODE>null</CODE> 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 <CODE>page</CODE>.
- * @param page the page to remove the fields from
- * @return <CODE>true</CODE> if any field was removed, <CODE>false otherwise</CODE>
- */
- 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
- * <CODE>name</CODE> 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 <CODE>true</CODE> if the field exists, <CODE>false otherwise</CODE>
- */
- 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 <CODE>true</CODE> if the field exists, <CODE>false otherwise</CODE>
- */
- 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 <CODE>true</CODE>.
- * @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 <CODE>PdfDictionary</CODE> where the value tag /V
- * is present.
- */
- public ArrayList values = new ArrayList();
- /** An array of <CODE>PdfDictionary</CODE> with the widgets.
- */
- public ArrayList widgets = new ArrayList();
- /** An array of <CODE>PdfDictionary</CODE> with the widget references.
- */
- public ArrayList widget_refs = new ArrayList();
- /** An array of <CODE>PdfDictionary</CODE> with all the field
- * and widget tags merged.
- */
- public ArrayList merged = new ArrayList();
- /** An array of <CODE>Integer</CODE> with the page numbers where
- * the widgets are displayed.
- */
- public ArrayList page = new ArrayList();
- /** An array of <CODE>Integer</CODE> 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 <CODE>null</CODE> 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 <CODE>true</CODE> if the signature covers the entire document,
- * <CODE>false</CODE> 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:
- * <p>
- * <pre>
- * 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 &lt; 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]);
- * }
- * </pre>
- * @param name the signature field name
- * @return a <CODE>PdfPKCS7</CODE> class to continue the verification
- */
- public PdfPKCS7 verifySignature(String name) {
- return verifySignature(name, null);
- }
-
- /**
- * Verifies a signature. An example usage is:
- * <p>
- * <pre>
- * 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 &lt; 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]);
- * }
- * </pre>
- * @param name the signature field name
- * @param provider the provider or <code>null</code> for the default provider
- * @return a <CODE>PdfPKCS7</CODE> 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 <CODE>field</CODE> 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 <CODE>InputStream</CODE> covering the revision. Returns <CODE>null</CODE> 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:
- * <p>
- * <pre>
- * 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 &lt; 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();
- * }
- * </pre>
- * @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 <CODE>BaseFont</CODE> and can be <CODE>null</CODE>. 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 <CODE>BaseFont</CODE> and can also be <CODE>null</CODE>. 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 <CODE>PdfObject</CODE>.
- *
- * @see PdfException
- * @see PdfBoolean
- * @see PdfNumber
- * @see PdfString
- * @see PdfName
- * @see PdfDictionary
- */
-
-public class BadPdfFormatException extends PdfException {
-
- // constructors
-
-/**
- * Constructs a <CODE>BadPdfFormatException</CODE> whithout a message.
- */
-
- BadPdfFormatException() {
- super();
- }
-
-/**
- * Constructs a <code>BadPdfFormatException</code> 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. <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
- * <CODE>Element.ALIGN_CENTER</CODE> or <CODE>Element.ALIGN_RIGHT</CODE>.
- */
- 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. <CODE>null</CODE> if no text.
- * @return the text font. <CODE>null</CODE> if no text
- */
- public BaseFont getFont() {
- return font;
- }
-
- /** Sets the text font.
- * @param font the text font. Set to <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
- * <CODE>Element.ALIGN_CENTER</CODE> or <CODE>Element.ALIGN_RIGHT</CODE>.
- * @return the text alignment
- */
- public int getTextAlignment() {
- return textAlignment;
- }
-
- /** Sets the text alignment. Can be <CODE>Element.ALIGN_LEFT</CODE>,
- * <CODE>Element.ALIGN_CENTER</CODE> or <CODE>Element.ALIGN_RIGHT</CODE>.
- * @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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>PdfContentByte</CODE> to create the template. It
- * serves no other use
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>Image</CODE> with the barcode.
- * @param cb the <CODE>PdfContentByte</CODE> to create the <CODE>Image</CODE>. It
- * serves no other use
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @return the <CODE>Image</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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.<p>
- * The code types allowed are:<br>
- * <ul>
- * <li><b>CODE128</b> - plain barcode 128.
- * <li><b>CODE128_UCC</b> - support for UCC/EAN-128 with a full list of AI.
- * <li><b>CODE128_RAW</b> - raw mode. The code attribute has the actual codes from 0
- * to 105 followed by '&#92;uffff' and the human readable text.
- * </ul>
- * The default parameters are:
- * <pre>
- * x = 0.8f;
- * font = BaseFont.createFont("Helvetica", "winansi", false);
- * size = 8;
- * baseline = size;
- * barHeight = size * 3;
- * textAlignment = Element.ALIGN_CENTER;
- * codeType = CODE128;
- * </pre>
- * @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 <CODE>true</CODE> if the next <CODE>numDigits</CODE>
- * starting from index <CODE>textIndex</CODE> 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 <CODE>true</CODE> 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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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:
- * <p>
- * <code>(01)00000090311314(10)ABC123(15)060916</code>
- * @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:
- * <pre>
- *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;
- * </pre>
- *
- * @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 <CODE>BARS</CODE>.
- */
- 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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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:
- * <pre>
- *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;
- * </pre>
- *
- * @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 <CODE>BARS</CODE>.
- */
- 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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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:
- * <pre>
- *x = 0.8f;
- *font = BaseFont.createFont("Helvetica", "winansi", false);
- *size = 8;
- *baseline = size;
- *barHeight = size * 3;
- *guardBars = true;
- *codeType = EAN13;
- *code = "";
- * </pre>
- *
- * @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 <CODE>null</CODE> is returned.
- * @param text the code to convert. It must have 12 numeric characters
- * @return the 8 converted digits or <CODE>null</CODE> 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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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.<p>
- * The default parameters are:
- * <pre>
- *n = 8; // horizontal distance between the two barcodes
- * </pre>
- *
- * @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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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:
- * <pre>
- *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;
- * </pre>
- *
- * @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 <CODE>text</CODE>.
- * @param text the text
- * @return a <CODE>String</CODE> 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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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 <CODE>Image</CODE> or a raw bitmap.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class BarcodePDF417 {
-
- /** Auto-size is made based on <CODE>aspectRatio</CODE> and <CODE>yHeight</CODE>. */
- public static final int PDF417_USE_ASPECT_RATIO = 0;
- /** The size of the barcode will be at least <CODE>codeColumns*codeRows</CODE>. */
- public static final int PDF417_FIXED_RECTANGLE = 1;
- /** The size will be at least <CODE>codeColumns</CODE>
- * with a variable number of <CODE>codeRows</CODE>.
- */
- public static final int PDF417_FIXED_COLUMNS = 2;
- /** The size will be at least <CODE>codeRows</CODE>
- * with a variable number of <CODE>codeColumns</CODE>.
- */
- 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 <CODE>text</CODE> interpretation is done and the content of <CODE>codewords</CODE>
- * 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 <CODE>BarcodePDF417</CODE> 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 <CODE>PDF417_USE_ASPECT_RATIO</CODE>
- * and <CODE>PDF417_AUTO_ERROR_LEVEL</CODE>.
- */
- 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 <CODE>Image</CODE> with the barcode. The image will have to be
- * scaled in the Y direction by <CODE>yHeight</CODE>for the barcode
- * to have the right printing aspect.
- * @return the barcode <CODE>Image</CODE>
- * @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 <CODE>java.awt.Image</CODE>.
- * @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 <CODE>yHeight</CODE>.
- * @return The raw barcode image
- */
- public byte[] getOutBits() {
- return this.outBits;
- }
-
- /** Gets the number of X pixels of <CODE>outBits</CODE>.
- * @return the number of X pixels of <CODE>outBits</CODE>
- */
- public int getBitColumns() {
- return this.bitColumns;
- }
-
- /** Gets the number of Y pixels of <CODE>outBits</CODE>.
- * It is also the number of rows in the barcode.
- * @return the number of Y pixels of <CODE>outBits</CODE>
- */
- 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 <CODE>PDF417_USE_RAW_CODEWORDS</CODE>
- * 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 <CODE>PDF417_*</CODE> 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:
- * <pre>
- *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
- * </pre>
- *
- * @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 <CODE>PdfContentByte</CODE>. The
- * barcode is always placed at coodinates (0, 0). Use the
- * translation matrix to move it elsewhere.<p>
- * The bars and text are written in the following colors:<p>
- * <P><TABLE BORDER=1>
- * <TR>
- * <TH><P><CODE>barColor</CODE></TH>
- * <TH><P><CODE>textColor</CODE></TH>
- * <TH><P>Result</TH>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with current fill color</TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P>bars and text painted with <CODE>barColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>null</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with current color<br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * <TR>
- * <TD><P><CODE>barColor</CODE></TD>
- * <TD><P><CODE>textColor</CODE></TD>
- * <TD><P>bars painted with <CODE>barColor</CODE><br>text painted with <CODE>textColor</CODE></TD>
- * </TR>
- * </TABLE>
- * @param cb the <CODE>PdfContentByte</CODE> where the barcode will be placed
- * @param barColor the color of the bars. It can be <CODE>null</CODE>
- * @param textColor the color of the text. It can be <CODE>null</CODE>
- * @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 <CODE>java.awt.Image</CODE>. 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 <CODE>EDIT</CODE> 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 <CODE>TextField</CODE>.
- * @param writer the document <CODE>PdfWriter</CODE>
- * @param box the field location and dimensions
- * @param fieldName the field name. If <CODE>null</CODE> 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 <CODE>null</CODE>.
- * @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 <CODE>PdfBorderDictionary</CODE>
- * and can be <CODE>STYLE_SOLID</CODE>, <CODE>STYLE_DASHED</CODE>,
- * <CODE>STYLE_BEVELED</CODE>, <CODE>STYLE_INSET</CODE> and
- * <CODE>STYLE_UNDERLINE</CODE>.
- * @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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>Element.ALIGN_LEFT</CODE>,
- * <CODE>Element.ALIGN_CENTER</CODE> and <CODE>Element.ALIGN_RIGHT</CODE>.
- * @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
- * <CODE>VISIBLE</CODE>, <CODE>HIDDEN</CODE>, <CODE>VISIBLE_BUT_DOES_NOT_PRINT</CODE>
- * and <CODE>HIDDEN_BUT_PRINTABLE</CODE>.
- * @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 <CODE>null</CODE> 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
- * <CODE>READ_ONLY</CODE>, <CODE>REQUIRED</CODE>,
- * <CODE>MULTILINE</CODE>, <CODE>DO_NOT_SCROLL</CODE>,
- * <CODE>PASSWORD</CODE>, <CODE>FILE_SELECTION</CODE>,
- * <CODE>DO_NOT_SPELL_CHECK</CODE> and <CODE>EDIT</CODE>.
- * @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 <CODE>from</CODE> to <CODE>to</CODE>. The moved keys
- * are removed from <CODE>from</CODE>.
- * @param from the source
- * @param to the destination. It may be <CODE>null</CODE>
- */
- 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
- * <CODE>encoding</CODE> 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 <CODE>char</CODE> directly to <CODE>byte</CODE>
- * 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".
- * <P>
- * The fonts are cached and if they already exist they are extracted from the cache,
- * not parsed again.
- * <P>
- * This method calls:<br>
- * <PRE>
- * createFont(name, encoding, embedded, true, null, null);
- * </PRE>
- * @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".
- * <P>
- * The fonts may or may not be cached depending on the flag <CODE>cached</CODE>.
- * If the <CODE>byte</CODE> 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 <CODE>widths</CODE> and the <CODE>differences</CODE> 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 <CODE>c</CODE>
- * or the <CODE>name</CODE>. If the <CODE>name</CODE> 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 <code>true</code> if the kerning was applied, <code>false</code> otherwise
- */
- public abstract boolean setKerning(char char1, char char2, int kern);
-
- /**
- * Gets the width of a <CODE>char</CODE> in normalized 1000 units.
- * @param char1 the unicode <CODE>char</CODE> 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 <CODE>String</CODE> in normalized 1000 units.
- * @param text the <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> 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 <CODE>String</CODE> in points taking kerning
- * into account.
- * @param text the <CODE>String</CODE> 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 <CODE>String</CODE> in points.
- * @param text the <CODE>String</CODE> 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 <CODE>char</CODE> in points.
- * @param char1 the <CODE>char</CODE> 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 <CODE>String</CODE> to a </CODE>byte</CODE> array according
- * to the font's encoding.
- * @param text the <CODE>String</CODE> to be converted
- * @return an array of <CODE>byte</CODE> 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 <CODE>String</CODE> into <CODE>byte[]</CODE>.
- * @return the encoding name
- */
- public String getEncoding() {
- return encoding;
- }
-
- /** Gets the font parameter identified by <CODE>key</CODE>. Valid values
- * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>AWT_ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>,
- * <CODE>DESCENT</CODE>, <CODE>AWT_DESCENT</CODE>,
- * <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE>
- * and <CODE>BBOXURY</CODE>.
- * @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 <CODE>true</CODE> if the font is embedded.
- */
- public boolean isEmbedded() {
- return embedded;
- }
-
- /** Gets the symbolic flag of the font.
- * @return <CODE>true</CODE> 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.<br>
- * 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.<br>
- * 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.<br>
- * 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 <CODE>byte</CODE> 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 <CODE>true</CODE> to force the generation of the
- * widths array.
- * @param forceWidthsOutput <CODE>true</CODE> to force the generation of the
- * widths array
- */
- public void setForceWidthsOutput(boolean forceWidthsOutput) {
- this.forceWidthsOutput = forceWidthsOutput;
- }
-
- /** Gets the direct conversion of <CODE>char</CODE> to <CODE>byte</CODE>.
- * @return value of property directTextToByte.
- * @see #setDirectTextToByte(boolean directTextToByte)
- */
- public boolean isDirectTextToByte() {
- return directTextToByte;
- }
-
- /** Sets the conversion of <CODE>char</CODE> directly to <CODE>byte</CODE>
- * 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 <CODE>false</CODE> 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 <CODE>true</CODE>
- * only the glyphs used will be included in the font. When set to <CODE>false</CODE>
- * 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 <CODE>InputStream</CODE> to get the resource or
- * <CODE>null</CODE> 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 <CODE>InputStream</CODE> to get the resource or
- * <CODE>null</CODE> 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 <FF00> 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 <CODE>true</CODE> 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 <CODE>true</CODE> if the character has a glyph,
- * <CODE>false</CODE> 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 <CODE>true</CODE> if the advance was set,
- * <CODE>false</CODE> 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 <CODE>ArrayList</CODE>
- * contains a <CODE>Object[]{String,PRIndirectReference}</CODE> 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 <CODE>ArrayList</CODE>
- * contains a <CODE>Object[]{String,PRIndirectReference}</CODE> 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
- * <CODE>null</CODE> 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
- * <code>null</code>
- */
- 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 <CODE>int</CODE> 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.
- *
- * <p>
- * 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.
- * <p>
- * <b>Input:</b><br>
- * 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.
- * <ol>
- * <li>unicode type array
- * <li>unicode type array, with externally supplied base line direction
- * </ol>
- * <p><b>Output:</b><br>
- * Output is separated into several stages as well, to better enable clients
- * to evaluate various aspects of implementation conformance.
- * <ol>
- * <li>levels array over entire paragraph
- * <li>reordering array over entire paragraph
- * <li>levels array over line
- * <li>reordering array over line
- * </ol>
- * 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.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * Rules P2, P3.
- * <p>
- * 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.
- * <p>
- * 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. <br>
- * Rule L1.
- * <p>
- * The returned levels array contains the resolved level for each
- * bidi code passed to the constructor.
- * <p>
- * 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.
- * <p>
- * 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
- * <pre> getReordering(linebreaks)[linebreaks[1] + 4]</pre>
- * (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).
- * <p>
- * 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 <CODE>StringBuffer</CODE> but works with <CODE>byte</CODE> 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 <CODE>true</CODE> always output floating point numbers with 6 decimal digits.
- * If <CODE>false</CODE> 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.
- * <P>
- * 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 <CODE>int</CODE>. The size of the array will grow by one.
- * @param b the int to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> 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 <CODE>byte</CODE> array. The buffer will grow by
- * <CODE>len</CODE> 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 <CODE>ByteBuffer</CODE> 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 <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(byte b[]) {
- return append(b, 0, b.length);
- }
-
- /**
- * Appends a <CODE>String</CODE> to the buffer. The <CODE>String</CODE> is
- * converted according to the encoding ISO-8859-1.
- * @param str the <CODE>String</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(String str) {
- if (str != null)
- return append(DocWriter.getISOBytes(str));
- return this;
- }
-
- /**
- * Appends a <CODE>char</CODE> to the buffer. The <CODE>char</CODE> is
- * converted according to the encoding ISO-8859-1.
- * @param c the <CODE>char</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(char c) {
- return append_i(c);
- }
-
- /**
- * Appends another <CODE>ByteBuffer</CODE> to this buffer.
- * @param buf the <CODE>ByteBuffer</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(ByteBuffer buf) {
- return append(buf.buf, 0, buf.count);
- }
-
- /**
- * Appends the string representation of an <CODE>int</CODE>.
- * @param i the <CODE>int</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> 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 <CODE>float</CODE> according
- * to the Pdf conventions.
- * @param i the <CODE>float</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(float i) {
- return append((double)i);
- }
-
- /**
- * Appends a string representation of a <CODE>double</CODE> according
- * to the Pdf conventions.
- * @param d the <CODE>double</CODE> to be appended
- * @return a reference to this <CODE>ByteBuffer</CODE> object
- */
- public ByteBuffer append(double d) {
- append(formatDouble(d, this));
- return this;
- }
-
- /**
- * Outputs a <CODE>double</CODE> into a format suitable for the PDF.
- * @param d a double
- * @return the <CODE>String</CODE> representation of the <CODE>double</CODE>
- */
- public static String formatDouble(double d) {
- return formatDouble(d, null);
- }
-
- /**
- * Outputs a <CODE>double</CODE> into a format suitable for the PDF.
- * @param d a double
- * @param buf a ByteBuffer
- * @return the <CODE>String</CODE> representation of the <CODE>double</CODE> if
- * <CODE>buf</CODE> is <CODE>null</CODE>. If <CODE>buf</CODE> is <B>not</B> <CODE>null</CODE>,
- * then the double is appended directly to the buffer and this methods returns <CODE>null</CODE>.
- */
- 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 <code>count</code> 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 <code>out.write(buf, 0, count)</code>.
- *
- * @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<stringOffsets[j+1]; k++) {
- s.append(getCard8());
- }
- seek(p);
- return s.toString();
- }
-
- char getCard8() {
- try {
- byte i = buf.readByte();
- return (char)(i & 0xff);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- char getCard16() {
- try {
- return buf.readChar();
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- int getOffset(int offSize) {
- int offset = 0;
- for (int i=0; i<offSize; i++) {
- offset *= 256;
- offset += getCard8();
- }
- return offset;
- }
-
- void seek(int offset) {
- try {
- buf.seek(offset);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- short getShort() {
- try {
- return buf.readShort();
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- int getInt() {
- try {
- return buf.readInt();
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- int getPosition() {
- try {
- return buf.getFilePointer();
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
- int nextIndexOffset;
- // read the offsets in the next index
- // data structure, convert to global
- // offsets, and return them.
- // Sets the nextIndexOffset.
- int[] getIndex(int nextIndexOffset) {
- int count, indexOffSize;
-
- seek(nextIndexOffset);
- count = getCard16();
- int[] offsets = new int[count+1];
-
- if (count==0) {
- offsets[0] = -1;
- nextIndexOffset += 2;
- return offsets;
- }
-
- indexOffSize = getCard8();
-
- for (int j=0; j<=count; j++) {
- //nextIndexOffset = ofset to relative segment
- offsets[j] = nextIndexOffset
- //2-> 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<arg_count; i++) args[i]=null;
- arg_count = 0;
- key = null;
- boolean gotKey = false;
-
- while (!gotKey) {
- char b0 = getCard8();
- if (b0 == 29) {
- int item = getInt();
- args[arg_count] = new Integer(item);
- arg_count++;
- //System.err.println(item+" ");
- continue;
- }
- if (b0 == 28) {
- short item = getShort();
- args[arg_count] = new Integer(item);
- arg_count++;
- //System.err.println(item+" ");
- continue;
- }
- if (b0 >= 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 += "<NIBBLE ERROR: "+String.valueOf(nibble)+">";
- 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<arg_count; i++)
- // System.err.print(args[i].toString()+" ");
- //System.err.println(key+" ;");
- continue;
- }
- }
- }
-
- /** List items for the linked list that builds the new CID font.
- */
-
- protected static abstract class Item {
- protected int myOffset = -1;
- /** remember the current offset and increment by item's size in bytes. */
- public void increment(int[] currentOffset) {
- myOffset = currentOffset[0];
- }
- /** Emit the byte stream for this item. */
- public void emit(byte[] buffer) {}
- /** Fix up cross references to this item (applies only to markers). */
- public void xref() {}
- }
-
- protected static abstract class OffsetItem extends Item {
- public int value;
- /** set the value of an offset item that was initially unknown.
- * It will be fixed up latex by a call to xref on some marker.
- */
- public void set(int offset) { this.value = offset; }
- }
-
-
- /** A range item.
- */
-
- protected static final class RangeItem extends Item {
- public int offset, length;
- private RandomAccessFileOrArray buf;
- public RangeItem(RandomAccessFileOrArray buf, int offset, int length) {
- this.offset = offset;
- this.length = length;
- this.buf = buf;
- }
- public void increment(int[] currentOffset) {
- super.increment(currentOffset);
- currentOffset[0] += length;
- }
- public void emit(byte[] buffer) {
- //System.err.println("range emit offset "+offset+" size="+length);
- try {
- buf.seek(offset);
- for (int i=myOffset; i<myOffset+length; i++)
- buffer[i] = buf.readByte();
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- //System.err.println("finished range emit");
- }
- }
-
- /** An index-offset item for the list.
- * The size denotes the required size in the CFF. A positive
- * value means that we need a specific size in bytes (for offset arrays)
- * and a negative value means that this is a dict item that uses a
- * variable-size representation.
- */
- static protected final class IndexOffsetItem extends OffsetItem {
- public final int size;
- public IndexOffsetItem(int size, int value) {this.size=size; this.value=value;}
- public IndexOffsetItem(int size) {this.size=size; }
-
- public void increment(int[] currentOffset) {
- super.increment(currentOffset);
- currentOffset[0] += size;
- }
- public void emit(byte[] buffer) {
- int i=0;
- switch (size) {
- case 4:
- buffer[myOffset+i] = (byte) ((value >>> 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<s.length(); i++)
- buffer[myOffset+i] = (byte) (s.charAt(i) & 0xff);
- }
- }
-
-
- /** A dictionary number on the list.
- * This implementation is inefficient: it doesn't use the variable-length
- * representation.
- */
-
- static protected final class DictNumberItem extends Item {
- public final int value;
- public int size = 5;
- public DictNumberItem(int value) {this.value=value;}
- public void increment(int[] currentOffset) {
- super.increment(currentOffset);
- currentOffset[0] += size;
- }
- // this is imcomplete!
- 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);
- }
- }
- }
-
- /** 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<fonts.length; j++)
- if (fontName.equals(fonts[j].name)) break;
- if (j==fonts.length) return null;
-
- LinkedList l = new LinkedList();
-
- // copy the header
-
- seek(0);
-
- int major = getCard8();
- int minor = getCard8();
- int hdrSize = getCard8();
- int offSize = getCard8();
- nextIndexOffset = hdrSize;
-
- l.addLast(new RangeItem(buf,0,hdrSize));
-
- int nglyphs=-1, nstrings=-1;
- if ( ! fonts[j].isCID ) {
- // count the glyphs
- seek(fonts[j].charstringsOffset);
- nglyphs = getCard16();
- seek(stringIndexOffset);
- nstrings = getCard16()+standardStrings.length;
- //System.err.println("number of glyphs = "+nglyphs);
- }
-
- // create a name index
-
- l.addLast(new UInt16Item((char)1)); // count
- l.addLast(new UInt8Item((char)1)); // offSize
- l.addLast(new UInt8Item((char)1)); // first offset
- l.addLast(new UInt8Item((char)( 1+fonts[j].name.length() )));
- l.addLast(new StringItem(fonts[j].name));
-
- // create the topdict Index
-
-
- l.addLast(new UInt16Item((char)1)); // count
- l.addLast(new UInt8Item((char)2)); // offSize
- l.addLast(new UInt16Item((char)1)); // first offset
- OffsetItem topdictIndex1Ref = new IndexOffsetItem(2);
- l.addLast(topdictIndex1Ref);
- IndexBaseItem topdictBase = new IndexBaseItem();
- l.addLast(topdictBase);
-
- /*
- int maxTopdictLen = (topdictOffsets[j+1]-topdictOffsets[j])
- + 9*2 // at most 9 new keys
- + 8*5 // 8 new integer arguments
- + 3*2;// 3 new SID arguments
- */
-
- //int topdictNext = 0;
- //byte[] topdict = new byte[maxTopdictLen];
-
- OffsetItem charsetRef = new DictOffsetItem();
- OffsetItem charstringsRef = new DictOffsetItem();
- OffsetItem fdarrayRef = new DictOffsetItem();
- OffsetItem fdselectRef = new DictOffsetItem();
-
- if ( !fonts[j].isCID ) {
- // create a ROS key
- l.addLast(new DictNumberItem(nstrings));
- l.addLast(new DictNumberItem(nstrings+1));
- l.addLast(new DictNumberItem(0));
- l.addLast(new UInt8Item((char)12));
- l.addLast(new UInt8Item((char)30));
- // create a CIDCount key
- l.addLast(new DictNumberItem(nglyphs));
- l.addLast(new UInt8Item((char)12));
- l.addLast(new UInt8Item((char)34));
- // What about UIDBase (12,35)? Don't know what is it.
- // I don't think we need FontName; the font I looked at didn't have it.
- }
-
- // create an FDArray key
- l.addLast(fdarrayRef);
- l.addLast(new UInt8Item((char)12));
- l.addLast(new UInt8Item((char)36));
- // create an FDSelect key
- l.addLast(fdselectRef);
- l.addLast(new UInt8Item((char)12));
- l.addLast(new UInt8Item((char)37));
- // create an charset key
- l.addLast(charsetRef);
- l.addLast(new UInt8Item((char)15));
- // create a CharStrings key
- l.addLast(charstringsRef);
- l.addLast(new UInt8Item((char)17));
-
- seek(topdictOffsets[j]);
- while (getPosition() < topdictOffsets[j+1]) {
- int p1 = getPosition();
- getDictItem();
- int p2 = getPosition();
- if (key=="Encoding"
- || key=="Private"
- || key=="FDSelect"
- || key=="FDArray"
- || key=="charset"
- || key=="CharStrings"
- ) {
- // just drop them
- } else {
- l.add(new RangeItem(buf,p1,p2-p1));
- }
- }
-
- l.addLast(new IndexMarkerItem(topdictIndex1Ref,topdictBase));
-
- // Copy the string index and append new strings.
- // We need 3 more strings: Registry, Ordering, and a FontName for one FD.
- // The total length is at most "Adobe"+"Identity"+63 = 76
-
- if (fonts[j].isCID) {
- l.addLast(getEntireIndexRange(stringIndexOffset));
- } else {
- String fdFontName = fonts[j].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;
-
- l.addLast(new UInt16Item((char)((stringOffsets.length-1)+3))); // count
- l.addLast(new UInt8Item((char)stringsIndexOffSize)); // offSize
- for (int i=0; i<stringOffsets.length; i++)
- l.addLast(new IndexOffsetItem(stringsIndexOffSize,
- stringOffsets[i]-stringsBaseOffset));
- int currentStringsOffset = stringOffsets[stringOffsets.length-1]
- - stringsBaseOffset;
- //l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += ("Adobe").length();
- l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += ("Identity").length();
- l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += fdFontName.length();
- l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
-
- l.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen));
- l.addLast(new StringItem(extraStrings));
- }
-
- // copy the global subroutine index
-
- l.addLast(getEntireIndexRange(gsubrIndexOffset));
-
- // deal with fdarray, fdselect, and the font descriptors
-
- if (fonts[j].isCID) {
- // copy the FDArray, FDSelect, charset
- } else {
- // create FDSelect
- l.addLast(new MarkerItem(fdselectRef));
- l.addLast(new UInt8Item((char)3)); // format identifier
- l.addLast(new UInt16Item((char)1)); // nRanges
-
- l.addLast(new UInt16Item((char)0)); // Range[0].firstGlyph
- l.addLast(new UInt8Item((char)0)); // Range[0].fd
-
- l.addLast(new UInt16Item((char)nglyphs)); // sentinel
-
- // recreate a new charset
- // This format is suitable only for fonts without subsetting
-
- l.addLast(new MarkerItem(charsetRef));
- l.addLast(new UInt8Item((char)2)); // format identifier
-
- l.addLast(new UInt16Item((char)1)); // first glyph in range (ignore .notdef)
- l.addLast(new UInt16Item((char)(nglyphs-1))); // nLeft
- // now all are covered, the data structure is complete.
-
- // create a font dict index (fdarray)
-
- l.addLast(new MarkerItem(fdarrayRef));
- l.addLast(new UInt16Item((char)1));
- l.addLast(new UInt8Item((char)1)); // offSize
- l.addLast(new UInt8Item((char)1)); // first offset
-
- OffsetItem privateIndex1Ref = new IndexOffsetItem(1);
- l.addLast(privateIndex1Ref);
- IndexBaseItem privateBase = new IndexBaseItem();
- l.addLast(privateBase);
-
- // looking at the PS that acrobat generates from a PDF with
- // a CFF opentype font embeded with an identity-H encoding,
- // it seems that it does not need a FontName.
- //l.addLast(new DictNumberItem((standardStrings.length+(stringOffsets.length-1)+2)));
- //l.addLast(new UInt8Item((char)12));
- //l.addLast(new UInt8Item((char)38)); // FontName
-
- l.addLast(new DictNumberItem(fonts[j].privateLength));
- OffsetItem privateRef = new DictOffsetItem();
- l.addLast(privateRef);
- l.addLast(new UInt8Item((char)18)); // Private
-
- l.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase));
-
- // copy the private index & local subroutines
-
- l.addLast(new MarkerItem(privateRef));
- // copy the private dict and the local subroutines.
- // the length of the private dict seems to NOT include
- // the local subroutines.
- l.addLast(new RangeItem(buf,fonts[j].privateOffset,fonts[j].privateLength));
- if (fonts[j].privateSubrs >= 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<fonts.length; j++)
- if (fontName.equals(fonts[j].name)) return fonts[j].isCID;
- return false;
- }
-
- public boolean exists(String fontName) {
- int j;
- for (j=0; j<fonts.length; j++)
- if (fontName.equals(fonts[j].name)) return true;
- return false;
- }
-
-
- public String[] getNames() {
- String[] names = new String[ fonts.length ];
- for (int i=0; i<fonts.length; i++)
- names[i] = fonts[i].name;
- return names;
- }
- /**
- * A random Access File or an array
- * (contributed by orly manor)
- */
- protected RandomAccessFileOrArray buf;
- private int offSize;
-
- protected int nameIndexOffset;
- protected int topdictIndexOffset;
- protected int stringIndexOffset;
- protected int gsubrIndexOffset;
- protected int[] nameOffsets;
- protected int[] topdictOffsets;
- protected int[] stringOffsets;
- protected int[] gsubrOffsets;
-
- /**
- * @author orly manor
- * TODO Changed from private to protected by Ygal&Oren
- */
- protected final class Font {
- public String name;
- public String fullName;
- public boolean isCID = false;
- public int privateOffset = -1; // only if not CID
- public int privateLength = -1; // only if not CID
- public int privateSubrs = -1;
- public int charstringsOffset = -1;
- public int encodingOffset = -1;
- public int charsetOffset = -1;
- public int fdarrayOffset = -1; // only if CID
- public int fdselectOffset = -1; // only if CID
- public int[] fdprivateOffsets;
- public int[] fdprivateLengths;
- public int[] fdprivateSubrs;
-
- // Added by Oren & Ygal
- public int nglyphs;
- public int nstrings;
- public int CharsetLength;
- public int[] charstringsOffsets;
- public int[] charset;
- public int[] FDSelect;
- public int FDSelectLength;
- public int FDSelectFormat;
- public int CharstringType = 2;
- public int FDArrayCount;
- public int FDArrayOffsize;
- public int[] FDArrayOffsets;
- public int[] PrivateSubrsOffset;
- public int[][] PrivateSubrsOffsetsArray;
- public int[] SubrsOffsets;
- }
- // Changed from private to protected by Ygal&Oren
- protected Font[] fonts;
-
- public CFFFont(RandomAccessFileOrArray inputbuffer) {
-
- //System.err.println("CFF: nStdString = "+standardStrings.length);
- buf = inputbuffer;
- seek(0);
-
- int major, minor;
- major = getCard8();
- minor = getCard8();
-
- //System.err.println("CFF Major-Minor = "+major+"-"+minor);
-
- int hdrSize = getCard8();
-
- offSize = getCard8();
-
- //System.err.println("offSize = "+offSize);
-
- //int count, indexOffSize, indexOffset, nextOffset;
-
- nameIndexOffset = hdrSize;
- nameOffsets = getIndex(nameIndexOffset);
- topdictIndexOffset = nameOffsets[nameOffsets.length-1];
- topdictOffsets = getIndex(topdictIndexOffset);
- stringIndexOffset = topdictOffsets[topdictOffsets.length-1];
- stringOffsets = getIndex(stringIndexOffset);
- gsubrIndexOffset = stringOffsets[stringOffsets.length-1];
- gsubrOffsets = getIndex(gsubrIndexOffset);
-
- fonts = new Font[nameOffsets.length-1];
-
- // now get the name index
-
- /*
- names = new String[nfonts];
- privateOffset = new int[nfonts];
- charsetOffset = new int[nfonts];
- encodingOffset = new int[nfonts];
- charstringsOffset = new int[nfonts];
- fdarrayOffset = new int[nfonts];
- fdselectOffset = new int[nfonts];
- */
-
- for (int j=0; j<nameOffsets.length-1; j++) {
- fonts[j] = new Font();
- seek(nameOffsets[j]);
- fonts[j].name = "";
- for (int k=nameOffsets[j]; k<nameOffsets[j+1]; k++) {
- fonts[j].name += (char)getCard8();
- }
- //System.err.println("name["+j+"]=<"+fonts[j].name+">");
- }
-
- // 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<standardStrings.length+(stringOffsets.length-1); j++) {
- //seek(stringOffsets[j]);
- //strings[j] = "";
- //for (int k=stringOffsets[j]; k<stringOffsets[j+1]; k++) {
- // strings[j] += (char)getCard8();
- //}
- System.err.println("j="+(int)j+" <? "+(standardStrings.length+(stringOffsets.length-1)));
- System.err.println("strings["+(int)j+"]=<"+getString(j)+">");
- }
- */
-
- // top dict
-
- for (int j=0; j<topdictOffsets.length-1; j++) {
- seek(topdictOffsets[j]);
- while (getPosition() < topdictOffsets[j+1]) {
- getDictItem();
- if (key=="FullName") {
- //System.err.println("getting fullname sid = "+((Integer)args[0]).intValue());
- fonts[j].fullName = getString((char)((Integer)args[0]).intValue());
- //System.err.println("got it");
- } else if (key=="ROS")
- fonts[j].isCID = true;
- else if (key=="Private") {
- fonts[j].privateLength = ((Integer)args[0]).intValue();
- fonts[j].privateOffset = ((Integer)args[1]).intValue();
- }
- else if (key=="charset"){
- fonts[j].charsetOffset = ((Integer)args[0]).intValue();
-
- }
- else if (key=="Encoding"){
- fonts[j].encodingOffset = ((Integer)args[0]).intValue();
- ReadEncoding(fonts[j].encodingOffset);
- }
- else if (key=="CharStrings") {
- fonts[j].charstringsOffset = ((Integer)args[0]).intValue();
- //System.err.println("charstrings "+fonts[j].charstringsOffset);
- // Added by Oren & Ygal
- int p = getPosition();
- fonts[j].charstringsOffsets = getIndex(fonts[j].charstringsOffset);
- seek(p);
- } else if (key=="FDArray")
- fonts[j].fdarrayOffset = ((Integer)args[0]).intValue();
- else if (key=="FDSelect")
- fonts[j].fdselectOffset = ((Integer)args[0]).intValue();
- else if (key=="CharstringType")
- fonts[j].CharstringType = ((Integer)args[0]).intValue();
- }
-
- // private dict
- if (fonts[j].privateOffset >= 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<fdarrayOffsets.length-1; k++) {
- seek(fdarrayOffsets[k]);
- while (getPosition() < fdarrayOffsets[k+1])
- getDictItem();
- if (key=="Private") {
- fonts[j].fdprivateLengths[k] = ((Integer)args[0]).intValue();
- fonts[j].fdprivateOffsets[k] = ((Integer)args[1]).intValue();
- }
-
- }
- }
- }
- //System.err.println("CFF: done");
- }
-
- // ADDED BY Oren & Ygal
-
- void ReadEncoding(int nextIndexOffset){
- int format;
- seek(nextIndexOffset);
- format = getCard8();
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java b/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java
deleted file mode 100644
index 111f899..0000000
--- a/src/main/java/com/lowagie/text/pdf/CFFFontSubset.java
+++ /dev/null
@@ -1,1633 +0,0 @@
-/*
- * $Id: CFFFontSubset.java,v 1.3 2005/02/17 09:20:54 blowagie Exp $
- * $Name: $
- *
- * Copyright 2004 Oren Manor and Ygal Blum
- *
- * 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.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ArrayList;
-import java.io.*;
-
-/**
- * This Class subsets a CFF Type Font. The subset is preformed for CID fonts and NON CID fonts.
- * The Charstring is subseted for both types. For CID fonts only the FDArray which are used are embedded.
- * The Lsubroutines of the FDArrays used are subsetted as well. The Subroutine subset supports both Type1 and Type2
- * formatting altough only tested on Type2 Format.
- * For Non CID the Lsubroutines are subsetted. On both types the Gsubroutines is subsetted.
- * A font which was not of CID type is transformed into CID as a part of the subset process.
- * The CID synthetic creation was written by Sivan Toledo <sivan@math.tau.ac.il>
- * @author Oren Manor <manorore@post.tau.ac.il> & Ygal Blum <blumygal@post.tau.ac.il>
- */
-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<fonts.length;++i)
- {
- // Read the number of glyphs in the font
- seek(fonts[i].charstringsOffset);
- fonts[i].nglyphs = getCard16();
-
- // Jump to the count field of the String Index
- seek(stringIndexOffset);
- fonts[i].nstrings = getCard16()+standardStrings.length;
-
- // For each font save the offset array of the charstring
- fonts[i].charstringsOffsets = getIndex(fonts[i].charstringsOffset);
-
- // Proces the FDSelect if exist
- if (fonts[i].fdselectOffset>=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<NumofGlyphs){
- num++;
- Sid = getCard16();
- if (Type==1)
- nLeft = getCard8();
- else
- nLeft = getCard16();
- i += nLeft+1;
- }
- return num;
- }
-
-
- /**
- * Read the FDSelect of the font and compute the array and its length
- * @param Font The index of the font being processed
- * @return The Processed FDSelect of the font
- */
- protected void readFDSelect(int Font)
- {
- // Restore the number of glyphs
- int NumOfGlyphs = fonts[Font].nglyphs;
- int[] FDSelect = new int[NumOfGlyphs];
- // Go to the beginning of the FDSelect
- seek(fonts[Font].fdselectOffset);
- // Read the FDSelect's format
- fonts[Font].FDSelectFormat = getCard8();
-
- switch(fonts[Font].FDSelectFormat){
- // Format==0 means each glyph has an entry that indicated
- // its FD.
- case 0:
- for (int i=0;i<NumOfGlyphs;i++)
- {
- FDSelect[i] = getCard8();
- }
- // The FDSelect's Length is one for each glyph + the format
- // for later use
- fonts[Font].FDSelectLength = fonts[Font].nglyphs+1;
- break;
- case 3:
- // Format==3 means the ranges version
- // The number of ranges
- int nRanges = getCard16();
- int l=0;
- // Read the first in the first range
- int first = getCard16();
- for (int i=0;i<nRanges;i++)
- {
- // Read the FD index
- int fd = getCard8();
- // Read the first of the next range
- int last = getCard16();
- // Calc the steps and write to the array
- int steps = last-first;
- for (int k=0;k<steps;k++)
- {
- FDSelect[l] = fd;
- l++;
- }
- // The last from this iteration is the first of the next
- first = last;
- }
- // Store the length for later use
- fonts[Font].FDSelectLength = 1+2+nRanges*3+2;
- break;
- default:
- break;
- }
- // Save the FDSelect of the font
- fonts[Font].FDSelect = FDSelect;
- }
-
- /**
- * Function reads the FDSelect and builds the FDArrayUsed HashMap According to the glyphs used
- * @param Font the Number of font being processed
- */
- protected void BuildFDArrayUsed(int Font)
- {
- int[] FDSelect = fonts[Font].FDSelect;
- // For each glyph used
- for (int i=0;i<glyphsInList.size();i++)
- {
- // Pop the glyphs index
- int glyph = ((Integer)glyphsInList.get(i)).intValue();
- // Pop the glyph's FD
- int FD = FDSelect[glyph];
- // Put the FD index into the FDArrayUsed HashMap
- FDArrayUsed.put(new Integer(FD),null);
- }
- }
-
- /**
- * Read the FDArray count, offsize and Offset array
- * @param Font
- */
- protected void ReadFDArray(int Font)
- {
- seek(fonts[Font].fdarrayOffset);
- fonts[Font].FDArrayCount = getCard16();
- fonts[Font].FDArrayOffsize = getCard8();
- // Since we will change values inside the FDArray objects
- // We increase its offsize to prevent errors
- if (fonts[Font].FDArrayOffsize < 4)
- fonts[Font].FDArrayOffsize++;
- fonts[Font].FDArrayOffsets = getIndex(fonts[Font].fdarrayOffset);
- }
-
-
- /**
- * The Process function extracts one font out of the CFF file and returns a
- * subset version of the original.
- * @param fontName - The name of the font to be taken out of the CFF
- * @return The new font stream
- * @throws IOException
- */
- public byte[] Process(String fontName)throws IOException{
- try
- {
- // Verify that the file is open
- buf.reOpen();
- // Find the Font that we will be dealing with
- int j;
- for (j=0; j<fonts.length; j++)
- if (fontName.equals(fonts[j].name)) break;
- if (j==fonts.length) return null;
-
- // Calc the bias for the global subrs
- if (gsubrIndexOffset >= 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<FDInList.size();j++)
- {
- // The FDArray index, Hash Map, Arrat List to work on
- int FD = ((Integer)FDInList.get(j)).intValue();
- hSubrsUsed[FD] = new HashMap();
- lSubrsUsed[FD] = new ArrayList();
- //Reads the private dicts looking for the subr operator and
- // store both the offest for the index and its offset array
- BuildFDSubrsOffsets(Font,FD);
- // Verify that FDPrivate has a LSubrs index
- if(fonts[Font].PrivateSubrsOffset[FD]>=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<glyphsInList.size();i++)
- {
- int glyph = ((Integer)glyphsInList.get(i)).intValue();
- int Start = fonts[Font].charstringsOffsets[glyph];
- int End = fonts[Font].charstringsOffsets[glyph+1];
-
- // IF CID:
- if (FD >= 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<lSubr.size();i++)
- {
- // Pop the subr value from the hash
- int Subr = ((Integer)lSubr.get(i)).intValue();
- // Ensure the Lsubr call is valid
- if (Subr < SubrsOffsets.length-1 && Subr>=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<lGSubrsUsed.size();i++)
- {
- //Pop the value + check valid
- int Subr = ((Integer)lGSubrsUsed.get(i)).intValue();
- if (Subr < gsubrOffsets.length-1 && Subr>=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<lSubrsUsedNonCID.size();j++)
- {
- //Pop the value + check valid
- int LSubr = ((Integer)lSubrsUsedNonCID.get(j)).intValue();
- if (LSubr < fonts[Font].SubrsOffsets.length-1 && LSubr>=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<SizeOfMask;i++)
- getCard8();
- }
- }
- }
-
- /**
- * Function Checks how the current operator effects the run time stack after being run
- * An operator may increase or decrease the stack size
- */
- protected void HandelStack()
- {
- // Findout what the operator does to the stack
- int StackHandel = StackOpp();
- if (StackHandel < 2)
- {
- // The operators that enlarge the stack by one
- if (StackHandel==1)
- PushStack();
- // The operators that pop the stack
- else
- {
- // Abs value for the for loop
- StackHandel *= -1;
- for (int i=0;i<StackHandel;i++)
- PopStack();
- }
-
- }
- // All other flush the stack
- else
- EmptyStack();
- }
-
- /**
- * Function checks the key and return the change to the stack after the operator
- * @return The change in the stack. 2-> 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; i<arg_count; i++) args[i]=null;
- arg_count = 0;
- }
-
- /**
- * Pop one element from the stack
- *
- */
- protected void PopStack()
- {
- if (arg_count>0)
- {
- 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<SizeOfMask;i++)
- getCard8();
- }
- }
- return NumOfHints;
- }
-
-
- /**
- * Function builds the new offset array, object array and assembles the index.
- * used for creating the glyph and subrs subsetted index
- * @param Offsets the offset array of the original index
- * @param Used the hashmap of the used objects
- * @return the new index subset version
- * @throws IOException
- */
- protected byte[] BuildNewIndex(int[] Offsets,HashMap Used) throws IOException
- {
- int Offset=0;
- int[] NewOffsets = new int[Offsets.length];
- // Build the Offsets Array for the Subset
- for (int i=0;i<Offsets.length;++i)
- {
- NewOffsets[i] = Offset;
- // If the object in the offset is also present in the used
- // HashMap then increment the offset var by its size
- if (Used.containsKey(new Integer(i)))
- Offset += Offsets[i+1] - Offsets[i];
- // Else the same offset is kept in i+1.
- }
- // Offset var determines the size of the object array
- byte[] NewObjects = new byte[Offset];
- // Build the new Object array
- for (int i=0;i<Offsets.length-1;++i)
- {
- int start = NewOffsets[i];
- int end = NewOffsets[i+1];
- // If start != End then the Object is used
- // So, we will copy the object data from the font file
- if (start != end)
- {
- // All offsets are Global Offsets relative to the begining of the font file.
- // Jump the file pointer to the start address to read from.
- buf.seek(Offsets[i]);
- // Read from the buffer and write into the array at start.
- buf.readFully(NewObjects, start, end-start);
- }
- }
- // Use AssembleIndex to build the index from the offset & object arrays
- return AssembleIndex(NewOffsets,NewObjects);
- }
-
- /**
- * Function creates the new index, inserting the count,offsetsize,offset array
- * and object array.
- * @param NewOffsets the subsetted offset array
- * @param NewObjects the subsetted object array
- * @return the new index created
- */
- protected byte[] AssembleIndex(int[] NewOffsets,byte[] NewObjects)
- {
- // Calc the index' count field
- char Count = (char)(NewOffsets.length-1);
- // Calc the size of the object array
- int Size = NewOffsets[NewOffsets.length-1];
- // Calc the Offsize
- byte Offsize;
- if (Size <= 0xff) Offsize = 1;
- else if (Size <= 0xffff) Offsize = 2;
- else if (Size <= 0xffffff) Offsize = 3;
- else Offsize = 4;
- // The byte array for the new index. The size is calc by
- // Count=2, Offsize=1, OffsetArray = Offsize*(Count+1), The object array
- byte[] NewIndex = new byte[2+1+Offsize*(Count+1)+NewObjects.length];
- // The counter for writing
- int Place = 0;
- // Write the count field
- NewIndex[Place++] = (byte) ((Count >>> 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<NewOffsets.length;i++)
- {
- // The value to be written
- int Num = NewOffsets[i]-NewOffsets[0]+1;
- // Write in bytes according to the offsize
- switch (Offsize) {
- case 4:
- NewIndex[Place++] = (byte) ((Num >>> 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<NewObjects.length;i++)
- {
- NewIndex[Place++] = NewObjects[i];
- }
- // Return the new index
- return NewIndex;
- }
-
- /**
- * The function builds the new output stream according to the subset process
- * @param Font the font
- * @return the subseted font stream
- * @throws IOException
- */
- protected byte[] BuildNewFile(int Font)throws IOException
- {
- // Prepare linked list for new font components
- OutputList = new LinkedList();
-
- // copy the header of the font
- CopyHeader();
-
- // create a name index
- BuildIndexHeader(1,1,1);
- OutputList.addLast(new UInt8Item((char)( 1+fonts[Font].name.length() )));
- OutputList.addLast(new StringItem(fonts[Font].name));
-
- // create the topdict Index
- BuildIndexHeader(1,2,1);
- OffsetItem topdictIndex1Ref = new IndexOffsetItem(2);
- OutputList.addLast(topdictIndex1Ref);
- IndexBaseItem topdictBase = new IndexBaseItem();
- OutputList.addLast(topdictBase);
-
- // Initialise the Dict Items for later use
- OffsetItem charsetRef = new DictOffsetItem();
- OffsetItem charstringsRef = new DictOffsetItem();
- OffsetItem fdarrayRef = new DictOffsetItem();
- OffsetItem fdselectRef = new DictOffsetItem();
- OffsetItem privateRef = new DictOffsetItem();
-
- // If the font is not CID create the following keys
- if ( !fonts[Font].isCID ) {
- // create a ROS key
- OutputList.addLast(new DictNumberItem(fonts[Font].nstrings));
- OutputList.addLast(new DictNumberItem(fonts[Font].nstrings+1));
- OutputList.addLast(new DictNumberItem(0));
- OutputList.addLast(new UInt8Item((char)12));
- OutputList.addLast(new UInt8Item((char)30));
- // create a CIDCount key
- OutputList.addLast(new DictNumberItem(fonts[Font].nglyphs));
- OutputList.addLast(new UInt8Item((char)12));
- OutputList.addLast(new UInt8Item((char)34));
- // Sivan's comments
- // What about UIDBase (12,35)? Don't know what is it.
- // I don't think we need FontName; the font I looked at didn't have it.
- }
- // Go to the TopDict of the font being processed
- seek(topdictOffsets[Font]);
- // Run untill the end of the TopDict
- while (getPosition() < topdictOffsets[Font+1]) {
- int p1 = getPosition();
- getDictItem();
- int p2 = getPosition();
- // The encoding key is disregarded since CID has no encoding
- if (key=="Encoding"
- // These keys will be added manualy by the process.
- || key=="Private"
- || key=="FDSelect"
- || key=="FDArray"
- || key=="charset"
- || key=="CharStrings"
- ) {
- }else {
- //OtherWise copy key "as is" to the output list
- OutputList.add(new RangeItem(buf,p1,p2-p1));
- }
- }
- // Create the FDArray, FDSelect, Charset and CharStrings Keys
- CreateKeys(fdarrayRef,fdselectRef,charsetRef,charstringsRef);
-
- // Mark the end of the top dict area
- OutputList.addLast(new IndexMarkerItem(topdictIndex1Ref,topdictBase));
-
- // Copy the string index
-
- if (fonts[Font].isCID)
- OutputList.addLast(getEntireIndexRange(stringIndexOffset));
- // If the font is not CID we need to append new strings.
- // We need 3 more strings: Registry, Ordering, and a FontName for one FD.
- // The total length is at most "Adobe"+"Identity"+63 = 76
- else
- CreateNewStringIndex(Font);
-
- // copy the new subsetted global subroutine index
- OutputList.addLast(new RangeItem(new RandomAccessFileOrArray(NewGSubrsIndex),0,NewGSubrsIndex.length));
-
- // deal with fdarray, fdselect, and the font descriptors
- // If the font is CID:
- if (fonts[Font].isCID) {
- // copy the FDArray, FDSelect, charset
-
- // Copy FDSelect
- // Mark the beginning
- OutputList.addLast(new MarkerItem(fdselectRef));
- // If an FDSelect exists copy it
- if (fonts[Font].fdselectOffset>=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<stringOffsets.length; i++)
- OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,
- stringOffsets[i]-stringsBaseOffset));
- int currentStringsOffset = stringOffsets[stringOffsets.length-1]
- - stringsBaseOffset;
- //l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += ("Adobe").length();
- OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += ("Identity").length();
- OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
- currentStringsOffset += fdFontName.length();
- OutputList.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
-
- OutputList.addLast(new RangeItem(buf,stringOffsets[0],origStringsLen));
- OutputList.addLast(new StringItem(extraStrings));
- }
-
- /**
- * Function creates new FDSelect for non-CID fonts.
- * The FDSelect built uses a single range for all glyphs
- * @param fdselectRef OffsetItem for the FDSelect
- * @param nglyphs the number of glyphs in the font
- */
- protected void CreateFDSelect(OffsetItem fdselectRef,int nglyphs)
- {
- OutputList.addLast(new MarkerItem(fdselectRef));
- OutputList.addLast(new UInt8Item((char)3)); // format identifier
- OutputList.addLast(new UInt16Item((char)1)); // nRanges
-
- OutputList.addLast(new UInt16Item((char)0)); // Range[0].firstGlyph
- OutputList.addLast(new UInt8Item((char)0)); // Range[0].fd
-
- OutputList.addLast(new UInt16Item((char)nglyphs)); // sentinel
- }
-
- /**
- * Function creates new CharSet for non-CID fonts.
- * The CharSet built uses a single range for all glyphs
- * @param charsetRef OffsetItem for the CharSet
- * @param nglyphs the number of glyphs in the font
- */
- protected void CreateCharset(OffsetItem charsetRef,int nglyphs)
- {
- OutputList.addLast(new MarkerItem(charsetRef));
- OutputList.addLast(new UInt8Item((char)2)); // format identifier
- OutputList.addLast(new UInt16Item((char)1)); // first glyph in range (ignore .notdef)
- OutputList.addLast(new UInt16Item((char)(nglyphs-1))); // nLeft
- }
-
- /**
- * Function creates new FDArray for non-CID fonts.
- * The FDArray built has only the "Private" operator that points to the font's
- * original private dict
- * @param fdarrayRef OffsetItem for the FDArray
- * @param privateRef OffsetItem for the Private Dict
- * @param Font the font
- */
- protected void CreateFDArray(OffsetItem fdarrayRef,OffsetItem privateRef,int Font)
- {
- OutputList.addLast(new MarkerItem(fdarrayRef));
- // Build the header (count=offsize=first=1)
- BuildIndexHeader(1,1,1);
-
- // Mark
- OffsetItem privateIndex1Ref = new IndexOffsetItem(1);
- OutputList.addLast(privateIndex1Ref);
- IndexBaseItem privateBase = new IndexBaseItem();
- // Insert the private operands and operator
- OutputList.addLast(privateBase);
- // Calc the new size of the private after subsetting
- // Origianl size
- int NewSize = fonts[Font].privateLength;
- // Calc the original size of the Subr offset in the private
- int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].privateOffset,fonts[Font].privateLength);
- // Increase the ptivate's size
- if (OrgSubrsOffsetSize != 0)
- NewSize += 5-OrgSubrsOffsetSize;
- OutputList.addLast(new DictNumberItem(NewSize));
- OutputList.addLast(privateRef);
- OutputList.addLast(new UInt8Item((char)18)); // Private
-
- OutputList.addLast(new IndexMarkerItem(privateIndex1Ref,privateBase));
- }
-
- /**
- * Function reconstructs the FDArray, PrivateDict and LSubr for CID fonts
- * @param Font the font
- * @throws IOException
- */
- void Reconstruct(int Font)throws IOException
- {
- // Init for later use
- OffsetItem[] fdPrivate = new DictOffsetItem[fonts[Font].FDArrayOffsets.length-1];
- IndexBaseItem[] fdPrivateBase = new IndexBaseItem[fonts[Font].fdprivateOffsets.length];
- OffsetItem[] fdSubrs = new DictOffsetItem[fonts[Font].fdprivateOffsets.length];
- // Reconstruct each type
- ReconstructFDArray(Font,fdPrivate);
- ReconstructPrivateDict(Font,fdPrivate,fdPrivateBase,fdSubrs);
- ReconstructPrivateSubrs(Font,fdPrivateBase,fdSubrs);
- }
-
- /**
- * Function subsets the FDArray and builds the new one with new offsets
- * @param Font The font
- * @param fdPrivate OffsetItem Array (one for each FDArray)
- * @throws IOException
- */
- void ReconstructFDArray(int Font,OffsetItem[] fdPrivate)throws IOException
- {
- // Build the header of the index
- BuildIndexHeader(fonts[Font].FDArrayCount,fonts[Font].FDArrayOffsize,1);
-
- // For each offset create an Offset Item
- OffsetItem[] fdOffsets = new IndexOffsetItem[fonts[Font].FDArrayOffsets.length-1];
- for (int i=0;i<fonts[Font].FDArrayOffsets.length-1;i++)
- {
- fdOffsets[i] = new IndexOffsetItem(fonts[Font].FDArrayOffsize);
- OutputList.addLast(fdOffsets[i]);
- }
-
- // Declare beginning of the object array
- IndexBaseItem fdArrayBase = new IndexBaseItem();
- OutputList.addLast(fdArrayBase);
-
- // For each object check if that FD is used.
- // if is used build a new one by changing the private object
- // Else do nothing
- // At the end of each object mark its ending (Even if wasn't written)
- for (int k=0; k<fonts[Font].FDArrayOffsets.length-1; k++) {
- if (FDArrayUsed.containsKey(new Integer (k)))
- {
- // Goto begining of objects
- seek(fonts[Font].FDArrayOffsets[k]);
- while (getPosition() < fonts[Font].FDArrayOffsets[k+1])
- {
- int p1 = getPosition();
- getDictItem();
- int p2 = getPosition();
- // If the dictItem is the "Private" then compute and copy length,
- // use marker for offset and write operator number
- if (key=="Private") {
- // Save the original length of the private dict
- int NewSize = ((Integer)args[0]).intValue();
- // Save the size of the offset to the subrs in that private
- int OrgSubrsOffsetSize = CalcSubrOffsetSize(fonts[Font].fdprivateOffsets[k],fonts[Font].fdprivateLengths[k]);
- // Increase the private's length accordingly
- if (OrgSubrsOffsetSize != 0)
- NewSize += 5-OrgSubrsOffsetSize;
- // Insert the new size, OffsetItem and operator key number
- OutputList.addLast(new DictNumberItem(NewSize));
- fdPrivate[k] = new DictOffsetItem();
- OutputList.addLast(fdPrivate[k]);
- OutputList.addLast(new UInt8Item((char)18)); // Private
- // Go back to place
- seek(p2);
- }
- // Else copy the entire range
- else // other than private
- OutputList.addLast(new RangeItem(buf,p1,p2-p1));
- }
- }
- // Mark the ending of the object (even if wasn't written)
- OutputList.addLast(new IndexMarkerItem(fdOffsets[k],fdArrayBase));
- }
- }
- /**
- * Function Adds the new private dicts (only for the FDs used) to the list
- * @param Font the font
- * @param fdPrivate OffsetItem array one element for each private
- * @param fdPrivateBase IndexBaseItem array one element for each private
- * @param fdSubrs OffsetItem array one element for each private
- * @throws IOException
- */
- void ReconstructPrivateDict(int Font,OffsetItem[] fdPrivate,IndexBaseItem[] fdPrivateBase,
- OffsetItem[] fdSubrs)throws IOException
- {
-
- // For each fdarray private dict check if that FD is used.
- // if is used build a new one by changing the subrs offset
- // Else do nothing
- for (int i=0;i<fonts[Font].fdprivateOffsets.length;i++)
- {
- if (FDArrayUsed.containsKey(new Integer (i)))
- {
- // Mark beginning
- OutputList.addLast(new MarkerItem(fdPrivate[i]));
- fdPrivateBase[i] = new IndexBaseItem();
- OutputList.addLast(fdPrivateBase[i]);
- // Goto begining of objects
- seek(fonts[Font].fdprivateOffsets[i]);
- while (getPosition() < fonts[Font].fdprivateOffsets[i]+fonts[Font].fdprivateLengths[i])
- {
- 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") {
- fdSubrs[i] = new DictOffsetItem();
- OutputList.addLast(fdSubrs[i]);
- OutputList.addLast(new UInt8Item((char)19)); // Subrs
- }
- // Else copy the entire range
- else
- OutputList.addLast(new RangeItem(buf,p1,p2-p1));
- }
- }
- }
- }
-
- /**
- * Function Adds the new LSubrs dicts (only for the FDs used) to the list
- * @param Font The index of the font
- * @param fdPrivateBase The IndexBaseItem array for the linked list
- * @param fdSubrs OffsetItem array for the linked list
- * @throws IOException
- */
-
- void ReconstructPrivateSubrs(int Font,IndexBaseItem[] fdPrivateBase,
- OffsetItem[] fdSubrs)throws IOException
- {
- // For each private dict
- for (int i=0;i<fonts[Font].fdprivateLengths.length;i++)
- {
- // If that private dict's Subrs are used insert the new LSubrs
- // computed earlier
- if (fdSubrs[i]!= null && fonts[Font].PrivateSubrsOffset[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 <CODE>false</CODE>. 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 <CODE>true</CODE> 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 <CODE>key</CODE>. Valid values
- * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>
- * and <CODE>ITALICANGLE</CODE>.
- * @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.<br>
- * 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.<br>
- * 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 <CODE>false</CODE>
- */
- public boolean hasKernPairs() {
- return false;
- }
-
- /**
- * Checks if a character exists in this font.
- * @param c the character to check
- * @return <CODE>true</CODE> if the character has a glyph,
- * <CODE>false</CODE> 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 <CODE>true</CODE> if the advance was set,
- * <CODE>false</CODE> otherwise. Will always return <CODE>false</CODE>
- */
- 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 <CODE>PDfSpotColor</CODE>
- */
- 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 <CODE>SpotColor</CODE> object.
- * @return the <CODE>PdfSpotColor</CODE>
- */
- 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.
- * <P>
- * Several parameters can be set like the first paragraph line indent and
- * extra space between paragraphs.
- * <P>
- * A call to the method <CODE>go</CODE> will return one of the following
- * situations: the column ended or the text ended.
- * <P>
- * I the column ended, a new column definition can be loaded with the method
- * <CODE>setColumns</CODE> and the method <CODE>go</CODE> can be called again.
- * <P>
- * If the text ended, more text can be loaded with <CODE>addText</CODE>
- * and the method <CODE>go</CODE> can be called again.<BR>
- * The only limitation is that one or more complete paragraphs must be loaded
- * each time.
- * <P>
- * Full bidirectional reordering is supported. If the run direction is
- * <CODE>PdfWriter.RUN_DIRECTION_RTL</CODE> 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 <CODE>PdfContent</CODE> 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 <CODE>ColumnText</CODE>.
- * @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 <CODE>org</CODE>.
- * @param org the original <CODE>ColumnText</CODE>
- * @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 <CODE>org</CODE>.
- * @param org the original <CODE>ColumnText</CODE>
- * @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 <CODE>Phrase</CODE> 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 <CODE>Phrase</CODE>.
- * 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 <CODE>Chunk</CODE> 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 <CODE>Paragraph</CODE>,
- * <CODE>List</CODE>, <CODE>PdfPTable</CODE>, <CODE>Image</CODE> and
- * <CODE>Graphic</CODE>.
- * <p>
- * It removes all the text placed with <CODE>addText()</CODE>.
- * @param element the <CODE>Element</CODE>
- */
- 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.
- * <p>
- * Each array element will contain a <CODE>float[4]</CODE> 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 <CODE>yLine</CODE> and the column. It will
- * set the <CODE>lineStatus</CODE> 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 <CODE>yLine</CODE> and the two
- * column bounds. It will set the <CODE>lineStatus</CODE> apropriatly.
- * @return a <CODE>float[2]</CODE>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 <CODE>yLine</CODE>,
- * the <CODE>yLine-leading</CODE>and the two
- * column bounds. It will set the <CODE>lineStatus</CODE> apropriatly.
- * @return a <CODE>float[4]</CODE>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
- * <CODE>float[]</CODE> 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 <CODE>Phrase</CODE>
- * @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 <CODE>go(false)</CODE>.
- * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE>
- * and/or <CODE>NO_MORE_COLUMN</CODE>
- * @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 <CODE>true</CODE> to simulate the writting to the document
- * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE>
- * and/or <CODE>NO_MORE_COLUMN</CODE>
- * @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 <CODE>go()</CODE> 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 <CODE>spaceCharRatio</CODE> times more than extra character spacing.
- * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> 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 <CODE>Phrase</CODE> 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 <CODE>Phrase</CODE> 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 <CODE>Phrase</CODE> 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 <CODE>Phrase</CODE> 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 <CODE>filledWidth</CODE> if greater than the existing one.
- * @param w the new <CODE>filledWidth</CODE> 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 <CODE>null</CODE> 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
- * <CODE>directory</CODE> into the map. The encoding
- * will be <CODE>BaseFont.CP1252</CODE> 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.<br>
- * 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 <CODE>key</CODE>. Valid values
- * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>,
- * <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE>
- * and <CODE>BBOXURY</CODE>.
- * @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.<br>
- * 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 <CODE>c</CODE>
- * or the <CODE>name</CODE>. If the <CODE>name</CODE> 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 <CODE>true</CODE> 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 <code>PdfEncoding</code>.
- * @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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>InputStream</CODE> 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 <CODE>PdfDictionary</CODE>
- * 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 <CODE>null</CODE> if the field does not
- * exist or has no value defined.
- * @param name the fully qualified field name
- * @return the field value or <CODE>null</CODE>
- */
- 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 <CODE>true</CODE> if the field was found and removed,
- * <CODE>false</CODE> 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 <CODE>PdfObject</CODE>.
- * @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 <CODE>null</CODE> 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 <CODE>true</CODE> if the value was inserted,
- * <CODE>false</CODE> 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 <CODE>true</CODE> if the value was inserted,
- * <CODE>false</CODE> 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 <CODE>FdfReader</CODE>
- * @param fdf the <CODE>FdfReader</CODE>
- */
- 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 <CODE>PdfReader</CODE>
- * @param pdf the <CODE>PdfReader</CODE>
- */
- public void setFields(PdfReader pdf) {
- setFields(pdf.getAcroFields());
- }
-
- /** Sets all the fields from this <CODE>AcroFields</CODE>
- * @param af the <CODE>AcroFields</CODE>
- */
- 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 <CODE>TrueTypeFontUnicode</CODE>
- */
- 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;
- /** <CODE>true</CODE> 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 <CODE>BaseFont</CODE>
- */
- 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 <CODE>BaseFont</CODE> of this font.
- * @return the <CODE>BaseFont</CODE> 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 <CODE>PdfWriter</CODE> 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 <CODE>false</CODE> 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 <CODE>false</CODE>
- * 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 <bowmanjm@attbi.com>.
- *
- * 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.
- * <p>
- * 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 <CODE>Font</CODE> to be searched for valid characters.
- * @param font the <CODE>Font</CODE>
- */
- 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 <CODE>Phrase</CODE> 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 <CODE>Chunk</CODE>.
- * @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 <CODE>getHyphenatedWordPost()</CODE>.
- * @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 <CODE>getHyphenatedWordPre()</CODE>.
- * @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 <code>Chunk</code> 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 <CODE>getHyphenatedWordPost()</CODE>.
- * @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 <CODE>getHyphenatedWordPre()</CODE>.
- * @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.
-// <P>
-// 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.
-// <P>
-// <A HREF="/resources/classes/Acme/IntHashtable.java">Fetch the software.</A><BR>
-// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
-// <P>
-// @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 <code>newString</code> to the end of <code>oldString</code>.
- */
- 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 <CODE>Document.add</CODE>.
- * @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 <CODE>AUTOMATIC</CODE>, 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 <CODE>AUTOMATIC</CODE>, 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 <CODE>ColumnDef</CODE> 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 <CODE>AUTOMATIC</CODE>.
- * 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 <CODE>AUTOMATIC</CODE>, 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 <CODE>setArabicOptions</CODE>
- * 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 <CODE>Phrase</CODE>
- * or a <CODE>Chunk</CODE> 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
- * <CODE>ElementListener</CODE>.
- *
- * @param listener an <CODE>ElementListener</CODE>
- * @return <CODE>true</CODE> 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 <CODE>spaceCharRatio</CODE> times more than extra character spacing.
- * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> 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 <CODE>Rectangle.LEFT</CODE>
- * or <CODE>Rectangle.RIGHT</CODE>
- * @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 <code>close</code>
- * is that it closes the output stream. A closed stream cannot perform
- * output operations and cannot be reopened.
- * <p>
- * The <code>close</code> method of <code>OutputStream</code> 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 <code>flush</code> 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.
- * <p>
- * The <code>flush</code> method of <code>OutputStream</code> does nothing.
- *
- * @exception IOException if an I/O error occurs.
- *
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /** Writes <code>b.length</code> bytes from the specified byte array
- * to this output stream. The general contract for <code>write(b)</code>
- * is that it should have exactly the same effect as the call
- * <code>write(b, 0, b.length)</code>.
- *
- * @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 <code>write</code> is that one byte is written
- * to the output stream. The byte to be written is the eight
- * low-order bits of the argument <code>b</code>. The 24
- * high-order bits of <code>b</code> are ignored.
- * <p>
- * Subclasses of <code>OutputStream</code> must provide an
- * implementation for this method.
- *
- * @param b the <code>byte</code>.
- * @exception IOException if an I/O error occurs. In particular,
- * an <code>IOException</code> may be thrown if the
- * output stream has been closed.
- *
- */
- public void write(int b) throws IOException {
- ++counter;
- out.write(b);
- }
-
- /** Writes <code>len</code> bytes from the specified byte array
- * starting at offset <code>off</code> to this output stream.
- * The general contract for <code>write(b, off, len)</code> is that
- * some of the bytes in the array <code>b</code> are written to the
- * output stream in order; element <code>b[off]</code> is the first
- * byte written and <code>b[off+len-1]</code> is the last byte written
- * by this operation.
- * <p>
- * The <code>write</code> method of <code>OutputStream</code> 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.
- * <p>
- * If <code>b</code> is <code>null</code>, a
- * <code>NullPointerException</code> is thrown.
- * <p>
- * If <code>off</code> is negative, or <code>len</code> is negative, or
- * <code>off+len</code> is greater than the length of the array
- * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> 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 <code>IOException</code> 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 <CODE>PdfIndirectReference</CODE>.
- *
- * @param reader a <CODE>PdfReader</CODE>
- * @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 <CODE>PdfIndirectReference</CODE>.
- *
- * @param reader a <CODE>PdfReader</CODE>
- * @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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> of Subtype URI.
- *
- * @param url the Url to go to
- */
-
- public PdfAction(URL url) {
- this(url.toExternalForm());
- }
-
- /**
- * Construct a new <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> of Subtype URI.
- *
- * @param url the url to go to
- */
-
- public PdfAction(String url) {
- this(url, false);
- }
-
- /**
- * Construct a new <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>PdfAction</CODE> 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 <CODE>null</CODE>.
- * @param operation (Windows-specific) the operation to perform: "open" - Open a document,
- * "print" - Print a document.
- * It can be <CODE>null</CODE>.
- * @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
- * It can be <CODE>null</CODE>.
- */
- 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 <CODE>null</CODE>.
- * @param operation (Windows-specific) the operation to perform: "open" - Open a document,
- * "print" - Print a document.
- * It can be <CODE>null</CODE>.
- * @param defaultDir (Windows-specific) the default directory in standard DOS syntax.
- * It can be <CODE>null</CODE>.
- * @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 <CODE>true</CODE>, 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 <CODE>PdfName</CODE>
- * or <CODE>String</CODE> (ON, OFF, or Toggle) followed by one or more optional content group dictionaries
- * <CODE>PdfLayer</CODE> or a <CODE>PdfIndirectReference</CODE> to a <CODE>PdfLayer</CODE>.<br>
- * The array elements are processed from left to right; each name is applied
- * to the subsequent groups until the next name is encountered:
- * <ul>
- * <li>ON sets the state of subsequent groups to ON</li>
- * <li>OFF sets the state of subsequent groups to OFF</li>
- * <li>Toggle reverses the state of subsequent groups</li>
- * </ul>
- * @param preserveRB if <CODE>true</CODE>, 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
- * <CODE>state</CODE> array are applied. That is, if a group is set to ON (either by ON or Toggle) during
- * processing of the <CODE>state</CODE> 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.<br>
- * If <CODE>false</CODE>, 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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfAnnotation</CODE> 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 <CODE>PdfWriter</CODE>
- * @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 <CODE>null</CODE>
- * the file will be read from the disk
- * @param file the path to the file. It will only be used if
- * <CODE>fileStore</CODE> is not <CODE>null</CODE>
- * @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
- * <CODE>HIGHLIGHT_NONE</CODE>, <CODE>HIGHLIGHT_INVERT</CODE>,
- * <CODE>HIGHLIGHT_OUTLINE</CODE> and <CODE>HIGHLIGHT_PUSH</CODE>;
- * @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 <code>PdfStamper</code> 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 <CODE>PdfAppearance</CODE>.
- */
-
- PdfAppearance() {
- super();
- separator = ' ';
- }
-
- PdfAppearance(PdfIndirectReference iref) {
- thisReference = iref;
- }
-
- /**
- * Creates new PdfTemplate
- *
- * @param wr the <CODE>PdfWriter</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfArray</CODE> is the PDF Array object.
- * <P>
- * 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 (]).<BR>
- * 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 <CODE>PdfArray</CODE>-object.
- */
-
- public PdfArray() {
- super(ARRAY);
- arrayList = new ArrayList();
- }
-
-/**
- * Constructs an <CODE>PdfArray</CODE>-object, containing 1 <CODE>PdfObject</CODE>.
- *
- * @param object a <CODE>PdfObject</CODE> 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 <CODE>PdfArray</CODE>-object, containing all the <CODE>PdfObject</CODE>s in a given <CODE>PdfArray</CODE>.
- *
- * @param array a <CODE>PdfArray</CODE> 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 <CODE>PdfArray</CODE>.
- *
- * @return an array of <CODE>byte</CODE>s
- */
-
- 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 <CODE>PdfObject</CODE>s.
- *
- * @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 <CODE>PdfObject</CODE> to the <CODE>PdfArray</CODE>.
- *
- * @param object <CODE>PdfObject</CODE> to add
- * @return <CODE>true</CODE>
- */
-
- 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 <CODE>PdfObject</CODE> to the <CODE>PdfArray</CODE>.
- * <P>
- * The newly added object will be the first element in the <CODE>ArrayList</CODE>.
- *
- * @param object <CODE>PdfObject</CODE> to add
- */
-
- public void addFirst(PdfObject object) {
- arrayList.add(0, object);
- }
-
-/**
- * Checks if the <CODE>PdfArray</CODE> already contains a certain <CODE>PdfObject</CODE>.
- *
- * @param object <CODE>PdfObject</CODE> to check
- * @return <CODE>true</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfBoolean</CODE> is the boolean object represented by the keywords <VAR>true</VAR> or <VAR>false</VAR>.
- * <P>
- * 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 <CODE>PdfBoolean</CODE> */
- public static final String TRUE = "true";
-
-/** A possible value of <CODE>PdfBoolean</CODE> */
- public static final String FALSE = "false";
-
- // membervariables
-
-/** the boolean value of this object */
- private boolean value;
-
- // constructors
-
-/**
- * Constructs a <CODE>PdfBoolean</CODE>-object.
- *
- * @param value the value of the new <CODE>PdfObject</CODE>
- */
-
- public PdfBoolean(boolean value) {
- super(BOOLEAN);
- if (value) {
- setContent(TRUE);
- }
- else {
- setContent(FALSE);
- }
- this.value = value;
- }
-
-/**
- * Constructs a <CODE>PdfBoolean</CODE>-object.
- *
- * @param value the value of the new <CODE>PdfObject</CODE>, represented as a <CODE>String</CODE>
- *
- * @throws BadPdfFormatException thrown if the <VAR>value</VAR> isn't '<CODE>true</CODE>' or '<CODE>false</CODE>'
- */
-
- 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 <CODE>PdfBoolean</CODE>-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 <CODE>PdfBorderArray</CODE> defines the border of a <CODE>PdfAnnotation</CODE>.
- *
- * @see PdfArray
- */
-
-public class PdfBorderArray extends PdfArray {
-
- // constructors
-
-/**
- * Constructs a new <CODE>PdfBorderArray</CODE>.
- */
-
- public PdfBorderArray(float hRadius, float vRadius, float width) {
- this(hRadius, vRadius, width, null);
- }
-
-/**
- * Constructs a new <CODE>PdfBorderArray</CODE>.
- */
-
- 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 <CODE>PdfBorderDictionary</CODE> 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 <CODE>PdfBorderDictionary</CODE>.
- */
-
- 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 <CODE>PdfCell</CODE> is the PDF translation of a <CODE>Cell</CODE>.
- * <P>
- * A <CODE>PdfCell</CODE> is an <CODE>ArrayList</CODE> of <CODE>PdfLine</CODE>s.
- * <P>
- * 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 <CODE>PdfTable</CODE>
- */
- 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 <CODE>PdfCell</CODE>-object.
- *
- * @param cell the original <CODE>Cell</CODE>
- * @param rownumber the number of the <CODE>Row</CODE> the <CODE>Cell</CODE> was in.
- * @param left the left border of the <CODE>PdfCell</CODE>
- * @param right the right border of the <CODE>PdfCell</CODE>
- * @param top the top border of the <CODE>PdfCell</CODE>
- * @param cellspacing the cellspacing of the <CODE>Table</CODE>
- * @param cellpadding the cellpadding of the <CODE>Table</CODE>
- */
-
- 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.
- * <P>
- * 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 <CODE>ArrayList</CODE> of <CODE>PdfLine</CODE>s
- */
-
- 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.
- * <P>
- * 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 <CODE>ArrayList</CODE> of <CODE>Image</CODE>s
- */
-
- 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 <CODE>PdfTable</CODE>.
- *
- * @return <CODE>void</CODE>
- */
-
- boolean isHeader() {
- return header;
- }
-
- /**
- * Indicates that this cell belongs to the header of a <CODE>PdfTable</CODE>.
- */
-
- void setHeader() {
- header = true;
- }
-
- /**
- * Checks if the cell may be removed.
- * <P>
- * Headers may allways be removed, even if they are drawn only partially:
- * they will be repeated on each following page anyway!
- *
- * @return <CODE>true</CODE> if all the lines are allready drawn; <CODE>false</CODE> 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 <CODE>Rectangle</CODE>
- */
-
- 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 <CODE>PdfChunk</CODE> is the PDF translation of a <CODE>Chunk</CODE>.
- * <P>
- * A <CODE>PdfChunk</CODE> is a <CODE>PdfString</CODE> in a certain
- * <CODE>PdfFont</CODE> and <CODE>Color</CODE>.
- *
- * @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 <CODE>attributes</CODE>. */
- private static final HashMap keysAttributes = new HashMap();
-
-/** The allowed attributes in variable <CODE>noStroke</CODE>. */
- 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 <CODE>PdfChunk</CODE>. */
- protected PdfFont font;
-
- protected BaseFont baseFont;
-
- protected SplitCharacter splitCharacter;
-/**
- * Metric attributes.
- * <P>
- * This attributes require the mesurement of characters widths when rendering
- * such as underline.
- */
- protected HashMap attributes = new HashMap();
-
-/**
- * Non metric attributes.
- * <P>
- * This attributes do not require the mesurement of characters widths when rendering
- * such as Color.
- */
- protected HashMap noStroke = new HashMap();
-
-/** <CODE>true</CODE> if the chunk split was cause by a newline. */
- protected boolean newlineSplit;
-
-/** The image in this <CODE>PdfChunk</CODE>, 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 <CODE>PdfChunk</CODE>-object.
- *
- * @param string the content of the <CODE>PdfChunk</CODE>-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 <CODE>PdfChunk</CODE>-object.
- *
- * @param chunk the original <CODE>Chunk</CODE>-object
- * @param action the <CODE>PdfAction</CODE> if the <CODE>Chunk</CODE> comes from an <CODE>Anchor</CODE>
- */
-
- 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 <FF00> 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 <CODE>PdfChunk</CODE> if it's too long for the given width.
- * <P>
- * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
- *
- * @param width a given width
- * @return the <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> if it's too long for the given width.
- * <P>
- * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
- *
- * @param width a given width
- * @return the <CODE>PdfChunk</CODE> 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 <CODE>Chunk</CODE>.
- *
- * @return a <CODE>PdfFont</CODE>
- */
-
- PdfFont font() {
- return font;
- }
-
-/**
- * Returns the color of this <CODE>Chunk</CODE>.
- *
- * @return a <CODE>Color</CODE>
- */
-
- Color color() {
- return (Color)noStroke.get(Chunk.COLOR);
- }
-
-/**
- * Returns the width of this <CODE>PdfChunk</CODE>.
- *
- * @return a width
- */
-
- float width() {
- return font.width(value);
- }
-
-/**
- * Checks if the <CODE>PdfChunk</CODE> split was caused by a newline.
- * @return <CODE>true</CODE> if the <CODE>PdfChunk</CODE> split was caused by a newline.
- */
-
- public boolean isNewlineSplit()
- {
- return newlineSplit;
- }
-
-/**
- * Gets the width of the <CODE>PdfChunk</CODE> 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 <CODE>attributes</CODE>
- * and <CODE>noStroke</CODE>.
- * @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 <CODE>true</CODE> if the attribute exists
- */
-
- boolean isAttribute(String name)
- {
- if (attributes.containsKey(name))
- return true;
- return noStroke.containsKey(name);
- }
-
-/**
- * Checks if this <CODE>PdfChunk</CODE> needs some special metrics handling.
- * @return <CODE>true</CODE> if this <CODE>PdfChunk</CODE> needs some special metrics handling.
- */
-
- boolean isStroked()
- {
- return (attributes.size() > 0);
- }
-
-/**
- * Checks if there is an image in the <CODE>PdfChunk</CODE>.
- * @return <CODE>true</CODE> if an image is present
- */
-
- boolean isImage()
- {
- return image != null;
- }
-
-/**
- * Gets the image in the <CODE>PdfChunk</CODE>.
- * @return the image or <CODE>null</CODE>
- */
-
- 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 <CODE>String</CODE>
- */
-
- String getEncoding() {
- return encoding;
- }
-
- int length() {
- return value.length();
- }
-/**
- * Checks if a character can be used to split a <CODE>PdfString</CODE>.
- * <P>
- * 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 <CODE>true</CODE> if the character can be used to split a string, <CODE>false</CODE> 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 <VAR>' '</VAR> and <VAR>'-'</VAR>-characters on the right of a <CODE>String</CODE>.
- * <P>
- * @param string the <CODE>String<CODE> that has to be trimmed.
- * @return the trimmed <CODE>String</CODE>
- */
- 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 <CODE>PdfColor</CODE> defines a Color (it's a <CODE>PdfArray</CODE> containing 3 values).
- *
- * @see PdfDictionary
- */
-
-class PdfColor extends PdfArray {
-
- // constructors
-
-/**
- * Constructs a new <CODE>PdfColor</CODE>.
- *
- * @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;
-
-/**
- * <CODE>PdfContentByte</CODE> 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 <CODE>PdfContentByte</CODE>-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 <CODE>String</CODE> representation of this <CODE>PdfContentByte</CODE>-object.
- *
- * @return a <CODE>String</CODE>
- */
-
- 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 <CODE>PdfContentByte</CODE>-object.
- *
- * @param writer the <CODE>PdfWriter</CODE>
- * @return a <CODE>byte</CODE> array with the representation
- */
-
- public byte[] toPdf(PdfWriter writer) {
- return content.toByteArray();
- }
-
- // methods to add graphical content
-
- /**
- * Adds the content of another <CODE>PdfContent</CODE>-object to this object.
- *
- * @param other another <CODE>PdfByteContent</CODE>-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 <VAR>Flatness</VAR>.
- * <P>
- * <VAR>Flatness</VAR> sets the maximum permitted distance in device pixels between the
- * mathematically correct path and an approximation constructed from straight line segments.<BR>
- *
- * @param flatness a value
- */
-
- public void setFlatness(float flatness) {
- if (flatness >= 0 && flatness <= 100) {
- content.append(flatness).append(" i").append_i(separator);
- }
- }
-
- /**
- * Changes the <VAR>Line cap style</VAR>.
- * <P>
- * The <VAR>line cap style</VAR> specifies the shape to be used at the end of open subpaths
- * when they are stroked.<BR>
- * Allowed values are LINE_CAP_BUTT, LINE_CAP_ROUND and LINE_CAP_PROJECTING_SQUARE.<BR>
- *
- * @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 <VAR>line dash pattern</VAR>.
- * <P>
- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
- * It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
- * of the alternating dashes and gaps. The phase specifies the distance into the dash
- * pattern to start the dash.<BR>
- *
- * @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 <VAR>line dash pattern</VAR>.
- * <P>
- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
- * It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
- * of the alternating dashes and gaps. The phase specifies the distance into the dash
- * pattern to start the dash.<BR>
- *
- * @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 <VAR>line dash pattern</VAR>.
- * <P>
- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
- * It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
- * of the alternating dashes and gaps. The phase specifies the distance into the dash
- * pattern to start the dash.<BR>
- *
- * @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 <VAR>line dash pattern</VAR>.
- * <P>
- * The line dash pattern controls the pattern of dashes and gaps used to stroke paths.
- * It is specified by an <I>array</I> and a <I>phase</I>. The array specifies the length
- * of the alternating dashes and gaps. The phase specifies the distance into the dash
- * pattern to start the dash.<BR>
- *
- * @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 <VAR>Line join style</VAR>.
- * <P>
- * The <VAR>line join style</VAR> specifies the shape to be used at the corners of paths
- * that are stroked.<BR>
- * Allowed values are LINE_JOIN_MITER (Miter joins), LINE_JOIN_ROUND (Round joins) and LINE_JOIN_BEVEL (Bevel joins).<BR>
- *
- * @param style a value
- */
-
- public void setLineJoin(int style) {
- if (style >= 0 && style <= 2) {
- content.append(style).append(" j").append_i(separator);
- }
- }
-
- /**
- * Changes the <VAR>line width</VAR>.
- * <P>
- * The line width specifies the thickness of the line used to stroke a path and is measured
- * in user space units.<BR>
- *
- * @param w a width
- */
-
- public void setLineWidth(float w) {
- content.append(w).append(" w").append_i(separator);
- }
-
- /**
- * Changes the <VAR>Miter limit</VAR>.
- * <P>
- * 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.<BR>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceGray</B> (or the <B>DefaultGray</B> color space),
- * and sets the gray tint to use for filling paths.</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceGray</B> (or the <B>DefaultGray</B> color space),
- * and sets the gray tint to use for stroking paths.</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
- * and sets the color to use for filling paths.</P>
- * <P>
- * Following the PDF manual, each operand must be a number between 0 (minimum intensity) and
- * 1 (maximum intensity).</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
- * and sets the color to use for stroking paths.</P>
- * <P>
- * 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!).
- * <P>
- * Sets the color space to <B>DeviceCMYK</B> (or the <B>DefaultCMYK</B> color space),
- * and sets the color to use for filling paths.</P>
- * <P>
- * Following the PDF manual, each operand must be a number between 0 (no ink) and
- * 1 (maximum ink).</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceCMYK</B> (or the <B>DefaultCMYK</B> color space),
- * and sets the color to use for stroking paths.</P>
- * <P>
- * 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 <I>(x, y)</I>, 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 <I>(x, y)</I>. The new current
- * point is <I>(x, y)</I>.
- *
- * @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 <CODE>Rectangle</CODE>
- */
- 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 <CODE>Rectangle</CODE>
- */
-
- 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 <CODE>Image</CODE> to the page. The <CODE>Image</CODE> must have
- * absolute positioning.
- * @param image the <CODE>Image</CODE> object
- * @throws DocumentException if the <CODE>Image</CODE> does not have absolute positioning
- */
- public void addImage(Image image) throws DocumentException {
- addImage(image, false);
- }
-
- /**
- * Adds an <CODE>Image</CODE> to the page. The <CODE>Image</CODE> must have
- * absolute positioning. The image can be placed inline.
- * @param image the <CODE>Image</CODE> object
- * @param inlineImage <CODE>true</CODE> to place this image inline, <CODE>false</CODE> otherwise
- * @throws DocumentException if the <CODE>Image</CODE> 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 <CODE>Image</CODE> to the page. The positioning of the <CODE>Image</CODE>
- * is done with the transformation matrix. To position an <CODE>image</CODE> at (x,y)
- * use addImage(image, image_width, 0, 0, image_height, x, y).
- * @param image the <CODE>Image</CODE> 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 <CODE>Image</CODE> to the page. The positioning of the <CODE>Image</CODE>
- * is done with the transformation matrix. To position an <CODE>image</CODE> at (x,y)
- * use addImage(image, image_width, 0, 0, image_height, x, y). The image can be placed inline.
- * @param image the <CODE>Image</CODE> 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 <CODE>true</CODE> to place this image inline, <CODE>false</CODE> 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 <CODE>PdfContentByte</CODE> 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. <CODE>saveState</CODE> and
- * <CODE>restoreState</CODE> must be balanced.
- */
- public void saveState() {
- content.append("q").append_i(separator);
- stateList.add(new GraphicState(state));
- }
-
- /**
- * Restores the graphic state. <CODE>saveState</CODE> and
- * <CODE>restoreState</CODE> 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.
- * <P>
- * The leading parameter is measured in text space units. It specifies the vertical distance
- * between the baselines of adjacent lines of text.</P>
- *
- * @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.
- * <P>
- * This allows to write text in subscript or superscript mode.</P>
- *
- * @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 <CODE>text</CODE>
- * 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 <CODE>text</CODE>.
- *
- * @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 <CODE>text</CODE> 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 <CODE>text</CODE>.
- *
- * @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.
- * <P>
- * Remark: this operation also initializes the current point position.</P>
- *
- * @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}.
- * <P>
- * Remark: this operation also initializes the current point position.</P>
- *
- * @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.
- * <P>
- * As a side effect, this sets the leading parameter in the text state.</P>
- *
- * @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 <CODE>byte</CODE> array according to the PDF conventions.
- *
- * @param b the <CODE>byte</CODE> array to escape
- * @return an escaped <CODE>byte</CODE> array
- */
- static byte[] escapeString(byte b[]) {
- ByteBuffer content = new ByteBuffer();
- escapeString(b, content);
- return content.toByteArray();
- }
-
- /**
- * Escapes a <CODE>byte</CODE> array according to the PDF conventions.
- *
- * @param b the <CODE>byte</CODE> 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.
- * <P>
- * (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.
- * <P>
- * 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.
- * <P>
- * 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 <CODE>PdfPatternPainter</CODE> 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 <CODE>PdfPatternPainter</CODE> 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 <CODE>null</CODE>
- * @return the <CODE>PdfPatternPainter</CODE> 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 <CODE>null</CODE>
- * @return the <CODE>PdfPatternPainter</CODE> 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.
- * <P>
- * Creates a new template that is nothing more than a form XObject. This template can be included
- * in this <CODE>PdfContentByte</CODE> 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!).
- * <P>
- * Sets the color space to <B>DeviceCMYK</B> (or the <B>DefaultCMYK</B> color space),
- * and sets the color to use for filling paths.</P>
- * <P>
- * This method is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 8.5.2.1 (page 331).</P>
- * <P>
- * 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.</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceCMYK</B> (or the <B>DefaultCMYK</B> color space),
- * and sets the color to use for stroking paths.</P>
- * <P>
- * This method is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 8.5.2.1 (page 331).</P>
- * 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!).
- * <P>
- * Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
- * and sets the color to use for filling paths.</P>
- * <P>
- * This method is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 8.5.2.1 (page 331).</P>
- * <P>
- * 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.</P>
- *
- * @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!).
- * <P>
- * Sets the color space to <B>DeviceRGB</B> (or the <B>DefaultRGB</B> color space),
- * and sets the color to use for stroking paths.</P>
- * <P>
- * This method is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 8.5.2.1 (page 331).</P>
- * 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. <CODE>color</CODE> can be an
- * <CODE>ExtendedColor</CODE>.
- * @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. <CODE>color</CODE> can be an
- * <CODE>ExtendedColor</CODE>.
- * @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 <CODE>PdfWriter</CODE> in use by this object.
- * @return the <CODE>PdfWriter</CODE> in use by this object
- */
- public PdfWriter getPdfWriter() {
- return writer;
- }
-
- /**
- * Gets the <CODE>PdfDocument</CODE> in use by this object.
- * @return the <CODE>PdfDocument</CODE> 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 <CODE>PdfDestination</CODE> with the jump coordinates
- * @return <CODE>true</CODE> if the local destination was added,
- * <CODE>false</CODE> 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 <CODE>PdfContentByte</CODE>. All
- * the members are copied by reference but the buffer stays different.
- *
- * @return a copy of this <CODE>PdfContentByte</CODE>
- */
- 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 <CODE>PdfAction</CODE>
- * @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 <CODE>String</CODE> directly to the content.
- * @param s the <CODE>String</CODE>
- */
- public void setLiteral(String s) {
- content.append(s);
- }
-
- /** Outputs a <CODE>char</CODE> directly to the content.
- * @param c the <CODE>char</CODE>
- */
- public void setLiteral(char c) {
- content.append(c);
- }
-
- /** Outputs a <CODE>float</CODE> directly to the content.
- * @param n the <CODE>float</CODE>
- */
- 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 <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- public java.awt.Graphics2D createGraphicsShapes(float width, float height) {
- return new PdfGraphics2D(this, width, height, null, true, false, 0);
- }
-
- /** Gets a <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- public java.awt.Graphics2D createPrinterGraphicsShapes(float width, float height, PrinterJob printerJob) {
- return new PdfPrinterGraphics2D(this, width, height, null, true, false, 0, printerJob);
- }
-
- /** Gets a <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- public java.awt.Graphics2D createGraphics(float width, float height) {
- return new PdfGraphics2D(this, width, height, null, false, false, 0);
- }
-
- /** Gets a <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- public java.awt.Graphics2D createPrinterGraphics(float width, float height, PrinterJob printerJob) {
- return new PdfPrinterGraphics2D(this, width, height, null, false, false, 0, printerJob);
- }
-
- /** Gets a <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- 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 <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE>
- */
- 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 <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE> 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 <CODE>Graphics2D</CODE> 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 <CODE>BaseFont</CODE>
- * @return a <CODE>Graphics2D</CODE>
- */
- public java.awt.Graphics2D createGraphics(float width, float height, FontMapper fontMapper) {
- return new PdfGraphics2D(this, width, height, fontMapper, false, false, 0);
- }
-
- /** Gets a <CODE>Graphics2D</CODE> 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 <CODE>BaseFont</CODE>
- * @param printerJob a printer job
- * @return a <CODE>Graphics2D</CODE>
- */
- 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 <CODE>Graphics2D</CODE> 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 <CODE>BaseFont</CODE>
- * @param convertImagesToJPEG converts awt images to jpeg before inserting in pdf
- * @param quality the quality of the jpeg
- * @return a <CODE>Graphics2D</CODE>
- */
- 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 <CODE>Graphics2D</CODE> 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 <CODE>BaseFont</CODE>
- * @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 <CODE>Graphics2D</CODE>
- */
- 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 <CODE>layer</CODE>.
- * Blocks can be nested. Each block must be terminated by an {@link #endLayer()}.<p>
- * 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 <CODE>PdfName.DEFAULTGRAY</CODE>, <CODE>PdfName.DEFAULTRGB</CODE>
- * or <CODE>PdfName.DEFAULTCMYK</CODE>
- * @param obj the colorspace. A <CODE>null</CODE> or <CODE>PdfNull</CODE> 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 <CODE>struc</CODE>.
- * 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(" <</MCID ").append(mark).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 <CODE>null</CODE> the mark will be of the type
- * <CODE>BMC</CODE> otherwise it will be <CODE>BDC</CODE>.
- * @param tag the tag
- * @param property the property
- * @param inline <CODE>true</CODE> to include the property in the content or <CODE>false</CODE>
- * 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 <CODE>beginMarkedContentSequence(tag, null, false)</CODE>.
- * @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 <CODE>ArrayList</CODE> to use. It will be cleared before using. If it's
- * <CODE>null</CODE> will create a new <CODE>ArrayList</CODE>
- * @return the same <CODE>ArrayList</CODE> 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 "&lt;&lt;" 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 <CODE>true</CODE> if a token was read, <CODE>false</CODE> 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;
-
-/**
- * <CODE>PdfContents</CODE> is a <CODE>PdfStream</CODE> containing the contents (text + graphics) of a <CODE>PdfPage</CODE>.
- */
-
-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 <CODE>PdfContents</CODE>-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
- * <CODE>SimpleBookmark#</CODE>.
- * @param outlines the bookmarks or <CODE>null</CODE> to remove any
- */
- public void setOutlines(List outlines) {
- newBookmarks = outlines;
- }
-
- /**
- * Signals that the <CODE>Document</CODE> was closed and that no other
- * <CODE>Elements</CODE> will be added.
- * <P>
- * 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
- * <CODE>List</CODE> of <CODE>Integer</CODE>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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
- * <CODE>SimpleBookmark#</CODE>.
- * @param outlines the bookmarks or <CODE>null</CODE> 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 <code>true</code> 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.
- * <p>
- * 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
- * <CODE>SimpleBookmark#</CODE>.
- * @param outlines the bookmarks or <CODE>null</CODE> 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 <CODE>PdfDashPattern</CODE> 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 <CODE>PdfDashPattern</CODE>.
- */
-
- public PdfDashPattern() {
- super();
- }
-
-/**
- * Constructs a new <CODE>PdfDashPattern</CODE>.
- */
-
- public PdfDashPattern(float dash) {
- super(new PdfNumber(dash));
- this.dash = dash;
- }
-
-/**
- * Constructs a new <CODE>PdfDashPattern</CODE>.
- */
-
- public PdfDashPattern(float dash, float gap) {
- super(new PdfNumber(dash));
- add(new PdfNumber(gap));
- this.dash = dash;
- this.gap = gap;
- }
-
-/**
- * Constructs a new <CODE>PdfDashPattern</CODE>.
- */
-
- 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 <CODE>PdfArray</CODE>.
- *
- * @return an array of <CODE>byte</CODE>s
- */
-
- 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;
-
-/**
- * <CODE>PdfDate</CODE> is the PDF date object.
- * <P>
- * 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 <CODE>PdfString</CODE> of the form:
- * <P><BLOCKQUOTE>
- * (D: YYYYMMDDHHmmSSOHH'mm')
- * </BLOCKQUOTE><P>
- * 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 <CODE>PdfDate</CODE>-object.
- *
- * @param d the date that has to be turned into a <CODE>PdfDate</CODE>-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 <CODE>PdfDate</CODE>-object, representing the current day and time.
- */
-
- public PdfDate() {
- this(new GregorianCalendar());
- }
-
-/**
- * Adds a number of leading zeros to a given <CODE>String</CODE> in order to get a <CODE>String</CODE>
- * of a certain length.
- *
- * @param i a given number
- * @param length the length of the resulting <CODE>String</CODE>
- * @return the resulting <CODE>String</CODE>
- */
-
- 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 <CODE>Calendar</CODE> representing the date or <CODE>null</CODE> 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 <CODE>PdfColor</CODE> defines a Color (it's a <CODE>PdfArray</CODE> 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 <CODE>PdfDestination</CODE>.
- * <P>
- * If <VAR>type</VAR> equals <VAR>FITB</VAR>, the bounding box of a page
- * will fit the window of the Reader. Otherwise the type will be set to
- * <VAR>FIT</VAR> 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 <CODE>PdfDestination</CODE>.
- * <P>
- * If <VAR>type</VAR> equals <VAR>FITBH</VAR> / <VAR>FITBV</VAR>,
- * 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 <VAR>type</VAR> equals <VAR>FITH</VAR>
- * or <VAR>FITV</VAR> 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 <VAR>FITH</VAR>.
- *
- * @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 <CODE>PdfDestination</CODE>.
- * <P>
- * 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 <VAR>PdfDestination.XYZ</VAR>
- * @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 <CODE>PdfDestination</CODE>.
- * <P>
- * 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 <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfDictionary</CODE> is the Pdf dictionary object.
- * <P>
- * A dictionary is an associative table containing pairs of objects. The first element
- * of each pair is called the <I>key</I> and the second element is called the <I>value</I>.
- * Unlike dictionaries in the PostScript language, a key must be a <CODE>PdfName</CODE>.
- * A value can be any kind of <CODE>PdfObject</CODE>, 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.<BR>
- * A dictionary is represented by two left angle brackets (<<), followed by a sequence of
- * key-value pairs, followed by two right angle brackets (>>).<BR>
- * This object is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 4.7 (page 40-41).
- * <P>
- *
- * @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.
- *
- * <p>
- * 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.
- * </p>
- */
- protected List list;
-
-
- // constructors
-
-/**
- * Constructs an empty <CODE>PdfDictionary</CODE>-object.
- */
-
- public PdfDictionary() {
- super(DICTIONARY);
- hashMap = new HashMap();
- list = new ArrayList();
- }
-
-/**
- * Constructs a <CODE>PdfDictionary</CODE>-object of a certain type.
- *
- * @param type a <CODE>PdfName</CODE>
- */
-
- public PdfDictionary(PdfName type) {
- this();
- dictionaryType = type;
- put(PdfName.TYPE, dictionaryType);
- }
-
- // methods overriding some methods in PdfObject
-
-/**
- * Returns the PDF representation of this <CODE>PdfDictionary</CODE>.
- *
- * @return an array of <CODE>byte</CODE>
- */
-
- 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 <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
- *
- * @param key key of the entry (a <CODE>PdfName</CODE>)
- * @param value value of the entry (a <CODE>PdfObject</CODE>)
- * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
- */
-
- 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 <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
- * If the value is null it does nothing.
- *
- * @param key key of the entry (a <CODE>PdfName</CODE>)
- * @param value value of the entry (a <CODE>PdfObject</CODE>)
- * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
- */
- public void putEx(PdfName key, PdfObject value) {
- if (value == null)
- return;
- hashMap.put(key, value);
- list.add(key);
- }
-
-/**
- * Adds a <CODE>PdfObject</CODE> and its key to the <CODE>PdfDictionary</CODE>.
- * If the value is null the key is deleted.
- *
- * @param key key of the entry (a <CODE>PdfName</CODE>)
- * @param value value of the entry (a <CODE>PdfObject</CODE>)
- * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
- */
- 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 <CODE>PdfObject</CODE> and its key from the <CODE>PdfDictionary</CODE>.
- *
- * @param key key of the entry (a <CODE>PdfName</CODE>)
- * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
- */
-
- public void remove(PdfName key) {
- hashMap.remove(key);
- list.remove(key);
- }
-
-/**
- * Gets a <CODE>PdfObject</CODE> with a certain key from the <CODE>PdfDictionary</CODE>.
- *
- * @param key key of the entry (a <CODE>PdfName</CODE>)
- * @return the previous </CODE>PdfObject</CODE> corresponding with the <VAR>key</VAR>
- */
-
- public PdfObject get(PdfName key) {
- return (PdfObject) hashMap.get(key);
- }
-
- // methods concerning the type of Dictionary
-
-/**
- * Checks if a <CODE>PdfDictionary</CODE> is of a certain type.
- *
- * @param type a type of dictionary
- * @return <CODE>true</CODE> of <CODE>false</CODE>
- *
- * @deprecated
- */
-
- public boolean isDictionaryType(PdfName type) {
- return dictionaryType.compareTo(type) == 0;
- }
-
-/**
- * Checks if a <CODE>Dictionary</CODE> is of the type FONT.
- *
- * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
- */
-
- public boolean isFont() {
- return dictionaryType.compareTo(FONT) == 0;
- }
-
-/**
- * Checks if a <CODE>Dictionary</CODE> is of the type PAGE.
- *
- * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
- */
-
- public boolean isPage() {
- return dictionaryType.compareTo(PAGE) == 0;
- }
-
-/**
- * Checks if a <CODE>Dictionary</CODE> is of the type PAGES.
- *
- * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
- */
-
- public boolean isPages() {
- return dictionaryType.compareTo(PAGES) == 0;
- }
-
-/**
- * Checks if a <CODE>Dictionary</CODE> is of the type CATALOG.
- *
- * @return <CODE>true</CODE> if it is, <CODE>false</CODE> if it isn't.
- */
-
- public boolean isCatalog() {
- return dictionaryType.compareTo(CATALOG) == 0;
- }
-
-/**
- * Checks if a <CODE>Dictionary</CODE> is of the type OUTLINES.
- *
- * @return <CODE>true</CODE> if it is, <CODE>false</CODE> 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;
-
-/**
- * <CODE>PdfDocument</CODE> is the class that is used by <CODE>PdfWriter</CODE>
- * to translate a <CODE>Document</CODE> into a PDF with different pages.
- * <P>
- * A <CODE>PdfDocument</CODE> always listens to a <CODE>Document</CODE>
- * and adds the Pdf representation of every <CODE>Element</CODE> that is
- * added to the <CODE>Document</CODE>.
- *
- * @see com.lowagie.text.Document
- * @see com.lowagie.text.DocListener
- * @see PdfWriter
- */
-
-class PdfDocument extends Document implements DocListener {
-
- /**
- * <CODE>PdfInfo</CODE> is the PDF InfoDictionary.
- * <P>
- * 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.<BR>
- * 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 <CODE>PdfInfo</CODE>-object.
- */
-
- PdfInfo() {
- super();
- addProducer();
- addCreationDate();
- }
-
- /**
- * Constructs a <CODE>PdfInfo</CODE>-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));
- }
- }
-
- /**
- * <CODE>PdfCatalog</CODE> is the PDF Catalog-object.
- * <P>
- * 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.<BR>
- * In this class however, only the reference to the tree of pages is implemented.<BR>
- * 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 <CODE>PdfCatalog</CODE>.
- *
- * @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 <CODE>PdfCatalog</CODE>.
- *
- * @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 <CODE>PdfWriter</CODE>. */
- 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 <CODE>PdfOutline</CODE> in the hierarchy of outlines. */
- private PdfOutline currentOutline;
-
- /** The current active <CODE>PdfAction</CODE> when processing an <CODE>Anchor</CODE>. */
- private PdfAction currentAction = null;
-
- /**
- * Stores the destinations keyed by name. Value is
- * <CODE>Object[]{PdfAction,PdfIndirectReference,PdfDestintion}</CODE>.
- */
- 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 <CODE>PdfWriter</CODE> to the <CODE>PdfDocument</CODE>.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>true</CODE> 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 <CODE>Watermark</CODE>.
- *
- * @param watermark the watermark to add
- * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
- */
-
- public boolean add(Watermark watermark) {
- if (writer != null && writer.isPaused()) {
- return false;
- }
- this.watermark = watermark;
- return true;
- }
-
- /**
- * Removes the <CODE>Watermark</CODE>.
- */
-
- 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 <CODE>boolean</CODE>
- */
-
- 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 <CODE>PdfWriter</CODE>.
- *
- * @return a <CODE>boolean</CODE>
- * @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.
- * <P>
- * 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.
- * <B>
- * 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 <CODE>PdfPTable</CODE> to the document.
- * @param ptable the <CODE>PdfPTable</CODE> 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 <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
- *
- * @param element the element to add
- * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> 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 <CODE>Image</CODE> 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.
- * <P>
- * 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 <CODE>PdfInfo</CODE>-object.
- *
- * @return <CODE>PdfInfo</COPE>
- */
-
- PdfInfo getInfo() {
- return info;
- }
-
- /**
- * Gets the <CODE>PdfCatalog</CODE>-object.
- *
- * @param pages an indirect reference to this document pages
- * @return <CODE>PdfCatalog</CODE>
- */
-
- 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 <CODE>Table</CODE> 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 <CODE>PdfPTable</CODE> fits the current page of the <CODE>PdfDocument</CODE>.
- *
- * @param table the table that has to be checked
- * @param margin a certain margin
- * @return <CODE>true</CODE> if the <CODE>PdfPTable</CODE> fits the page, <CODE>false</CODE> 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.
- * <P>
- * Before entering the line position must have been established and the
- * <CODE>text</CODE> argument must be in text object scope (<CODE>beginText()</CODE>).
- * @param line the line to be written
- * @param text the <CODE>PdfContentByte</CODE> where the text will be written to
- * @param graphics the <CODE>PdfContentByte</CODE> 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 <CODE>PdfDestination</CODE> with the jump coordinates
- * @return <CODE>true</CODE> if the local destination was added,
- * <CODE>false</CODE> 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 <CODE>PdfAction</CODE>
- * @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 <CODE>String</CODE> to a </CODE>byte</CODE> array according
- * to the font's encoding.
- * @return an array of <CODE>byte</CODE> representing the conversion according to the font's encoding
- * @param encoding the encoding
- * @param text the <CODE>String</CODE> 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 </CODE>byte</CODE> array to a <CODE>String</CODE> according
- * to the some encoding.
- * @param bytes the bytes to convert
- * @param encoding the encoding
- * @return the converted <CODE>String</CODE>
- */
- 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 <CODE>text</CODE> only has PdfDocEncoding characters.
- * @param text the <CODE>String</CODE> to test
- * @return <CODE>true</CODE> 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 <CODE>name</CODE> 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 <CODE>CRLF_CID_NEWLINE</CODE>
- */
- 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 <CODE>byte</CODE> array encoded as <CODE>name</CODE>
- * to a CID string. This is needed to reach some CJK characters
- * that don't exist in 16 bit Unicode.</p>
- * The font to use this result must use the encoding "Identity-H"
- * or "Identity-V".</p>
- * See ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/.
- * @param name the CJK encoding name
- * @param seq the <CODE>byte</CODE> 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 <CODE>byte</CODE> array encoded as <CODE>name</CODE>
- * to a CID string. This is needed to reach some CJK characters
- * that don't exist in 16 bit Unicode.</p>
- * The font to use this result must use the encoding "Identity-H"
- * or "Identity-V".</p>
- * 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 <CODE>byte</CODE> 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
- * <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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
- * <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> for 40 bit key length
- * @param newInfo an optional <CODE>String</CODE> map to add or change
- * the info dictionary. Entries with <CODE>null</CODE>
- * 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
- * <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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
- * <code>PdfWriter</code>. 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 <code>true</code> for 128 bit key length, <code>false</code> 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 <CODE>String</CODE> map to add or change
- * the info dictionary. Entries with <CODE>null</CODE>
- * 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 <CODE>PdfException</CODE> whithout a message.
- */
-
- PdfException() {
- super();
- }
-
-/**
- * Constructs a <code>PdfException</code> 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 <CODE>PdfWriter</CODE>
- * @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 <CODE>PdfWriter</CODE>
- * @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 <CODE>null</CODE>
- * it takes precedence over <CODE>filePath</CODE>
- * @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 <CODE>PdfWriter</CODE>
- * @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 <CODE>null</CODE>
- * it takes precedence over <CODE>filePath</CODE>
- * @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 <CODE>PdfWriter</CODE>
- * @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;
-
-/**
- * <CODE>PdfFont</CODE> is the Pdf Font object.
- * <P>
- * 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.<BR>
- * 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 <CODE>PdfFont</CODE> with another
- *
- * @param object the other <CODE>PdfFont</CODE>
- * @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 <CODE>PdfAnnotation</CODE> 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;
-
-/**
- * <CODE>PdfFormObject</CODE> 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 <CODE>PdfFormXObject</CODE>-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 <jim@scolamoore.com>.
- *
- * 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 <CODE>PdfICCBased</CODE> 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;
-
-/**
- * <CODE>PdfImage</CODE> is a <CODE>PdfStream</CODE> containing an image-<CODE>Dictionary</CODE> and -stream.
- */
-
-class PdfImage extends PdfStream {
-
- static final int TRANSFERSIZE = 4096;
- // membervariables
-
- /** This is the <CODE>PdfName</CODE> of the image. */
- protected PdfName name = null;
-
- // constructor
-
- /**
- * Constructs a <CODE>PdfImage</CODE>-object.
- *
- * @param image the <CODE>Image</CODE>-object
- * @param name the <CODE>PdfName</CODE> 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 <CODE>PdfName</CODE> 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 <CODE>PdfImportedPage</CODE>-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;
-
-/**
- * <CODE>PdfIndirectObject</CODE> is the Pdf indirect object.
- * <P>
- * An <I>indirect object</I> is an object that has been labeled so that it can be referenced by
- * other objects. Any type of <CODE>PdfObject</CODE> may be labeled as an indirect object.<BR>
- * An indirect object consists of an object identifier, a direct object, and the <B>endobj</B>
- * keyword. The <I>object identifier</I> consists of an integer <I>object number</I>, an integer
- * <I>generation number</I>, and the <B>obj</B> keyword.<BR>
- * 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 <CODE>PdfIndirectObject</CODE>.
- *
- * @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 <CODE>PdfIndirectObject</CODE>.
- *
- * @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 <CODE>PdfIndirectObject</CODE>.
- *
- * @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 <CODE>PdfIndirectReference</CODE> to this <CODE>PdfIndirectObject</CODE>.
- *
- * @return a <CODE>PdfIndirectReference</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfIndirectReference</CODE> contains a reference to a <CODE>PdfIndirectObject</CODE>.
- * <P>
- * 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 <I>indirect reference</I> is a reference
- * to an indirect object, and consists of the indirect object's object number, generation number
- * and the <B>R</B> keyword.<BR>
- * 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 <CODE>PdfIndirectReference</CODE>.
- *
- * @param type the type of the <CODE>PdfObject</CODE> 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 <CODE>PdfIndirectReference</CODE>.
- *
- * @param type the type of the <CODE>PdfObject</CODE> 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 <CODE>PdfWriter</CODE>
- * @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 <CODE>null</CODE> if the layer has no parent
- */
- public PdfLayer getParent() {
- return parent;
- }
-
- /**
- * Gets the children layers.
- * @return the children layers or <CODE>null</CODE> if the layer has no children
- */
- public ArrayList getChildren() {
- return children;
- }
-
- /**
- * Gets the <CODE>PdfIndirectReference</CODE> that represents this layer.
- * @return the <CODE>PdfIndirectReference</CODE> 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 <CODE>this</CODE>.
- * @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 <B>Artwork</B>, for graphic-design or publishing
- * applications, and <B>Technical</B>, 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, <B>es-MX</B> 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, <B>Trapping</B>, <B>PrintersMarks</B> and <B>Watermark</B>
- * @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 <CODE>false</CODE>
- * 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 <B>ON</B> and invisible when it is <B>OFF</B>. 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 <B>ON</B>.
- */
- public static PdfName ALLON = new PdfName("AllOn");
- /**
- * Visible if any of the entries are <B>ON</B>.
- */
- public static PdfName ANYON = new PdfName("AnyOn");
- /**
- * Visible if any of the entries are <B>OFF</B>.
- */
- public static PdfName ANYOFF = new PdfName("AnyOff");
- /**
- * Visible only if all of the entries are <B>OFF</B>.
- */
- 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 <CODE>PdfIndirectReference</CODE> that represents this membership layer.
- * @return the <CODE>PdfIndirectReference</CODE> 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 <CODE>this</CODE>.
- * @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;
-
-/**
- * <CODE>PdfLine</CODE> defines an array with <CODE>PdfChunk</CODE>-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;
-
- /** <CODE>true</CODE> 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 <CODE>PdfLine</CODE>-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 <CODE>PdfChunk</CODE> to the <CODE>PdfLine</CODE>.
- *
- * @param chunk the <CODE>PdfChunk</CODE> to add
- * @return <CODE>null</CODE> if the chunk could be added completely; if not
- * a <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE>s.
- *
- * @return an <CODE>Iterator</CODE>
- */
-
- 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 <CODE>true</CODE> if the alignment equals <VAR>ALIGN_JUSTIFIED</VAR> 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.
- * <P>
- * The alignment of the last line of for instance a <CODE>Paragraph</CODE>
- * that has to be justified, has to be reset to <VAR>ALIGN_LEFT</VAR>.
- */
-
- 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.
- * <P>
- * This is only necessary for the first line of a <CODE>ListItem</CODE>.
- *
- * @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 <CODE>PdfChunk</CODE> if the line has a listsymbol; <CODE>null</CODE> 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 <CODE>String</CODE>
- */
-
- 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 <CODE>true</CODE> if a newline caused the line split
- */
- public boolean isNewlineSplit() {
- return newlineSplit && (alignment != Element.ALIGN_JUSTIFIED_ALL);
- }
-
- /**
- * Gets the index of the last <CODE>PdfChunk</CODE> with metric attributes
- * @return the last <CODE>PdfChunk</CODE> 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 <CODE>PdfChunk</CODE> by index.
- * @param idx the index
- * @return the <CODE>PdfChunk</CODE> 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;
-
-/**
- * <CODE>PdfName</CODE> is an object that can be used as a name in a PDF-file.
- * <P>
- * 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
- * %, (, ), [, ], &lt;, &gt;, {, }, / 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.<BR>
- * This object is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 4.5 (page 39-40).
- * <P>
- *
- * @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 <CODE>PdfName</CODE>. The name length will be checked.
- * @param name the new name
- */
- public PdfName(String name) {
- this(name, true);
- }
-
- /**
- * Constructs a new <CODE>PdfName</CODE>.
- * @param name the new name
- * @param lengthCheck if <CODE>true</CODE> check the lenght validity, if <CODE>false</CODE> 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.<p>
- * @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<len; i++) {
- if(myBytes[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 <code>true</code> if this object is the same as the obj
- * argument; <code>false</code> 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
- * <code>java.util.Hashtable</code>.
- *
- * @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 <CODE>String</CODE>
- * and the value is a <CODE>PdfObject</CODE>. 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;
-
-/**
- * <CODE>PdfNull</CODE> is the Null object represented by the keyword <VAR>null</VAR>.
- * <P>
- * 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 <CODE>PdfNull</CODE>-object. */
- public static final PdfNull PDFNULL = new PdfNull();
-
-/** This is the content of a <CODE>PdfNull</CODE>-object. */
- private static final String CONTENT = "null";
-
- // constructors
-
-/**
- * Constructs a <CODE>PdfNull</CODE>-object.
- * <P>
- * You never need to do this yourself, you can always use the static final object <VAR>PDFNULL</VAR>.
- */
-
- 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;
-
-/**
- * <CODE>PdfNumber</CODE> provides two types of numbers, integer and real.
- * <P>
- * Integers may be specified by signed or unsigned constants. Reals may only be
- * in decimal format.<BR>
- * 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 <CODE>PdfNumber</CODE>, represented as a <CODE>double</CODE> */
- private double value;
-
- // constructors
-
-/**
- * Constructs a <CODE>PdfNumber</CODE>-object.
- *
- * @param content value of the new <CODE>PdfNumber</CODE>-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 <CODE>PdfNumber</CODE>-object.
- *
- * @param value value of the new <CODE>PdfNumber</CODE>-object
- */
-
- public PdfNumber(int value) {
- super(NUMBER);
- this.value = value;
- setContent(String.valueOf(value));
- }
-
-/**
- * Constructs a new REAL <CODE>PdfNumber</CODE>-object.
- *
- * @param value value of the new <CODE>PdfNumber</CODE>-object
- */
-
- public PdfNumber(double value) {
- super(NUMBER);
- this.value = value;
- setContent(ByteBuffer.formatDouble(value));
- }
-
-/**
- * Constructs a new REAL <CODE>PdfNumber</CODE>-object.
- *
- * @param value value of the new <CODE>PdfNumber</CODE>-object
- */
-
- public PdfNumber(float value) {
- this((double)value);
- }
-
- // methods returning the value of this object
-
-/**
- * Returns the primitive <CODE>int</CODE> value of this object.
- *
- * @return a value
- */
-
- public int intValue() {
- return (int) value;
- }
-
-/**
- * Returns the primitive <CODE>double</CODE> 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 <CODE>PdfNumber</CODE>-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 <CODE>Integer</CODE>
- * and the value is a <CODE>PdfObject</CODE>.
- * @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 <CODE>PdfIndirectReference</CODE> that represents this layer.
- * @return the <CODE>PdfIndirectReference</CODE> 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;
-
-/**
- * <CODE>PdfObject</CODE> is the abstract superclass of all PDF objects.
- * <P>
- * 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.<BR>
- * 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 <CODE>PdfObject</CODE> */
- public static final int BOOLEAN = 1;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int NUMBER = 2;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int STRING = 3;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int NAME = 4;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int ARRAY = 5;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int DICTIONARY = 6;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int STREAM = 7;
-
-/** a possible type of <CODE>PdfObject</CODE> */
- public static final int NULL = 8;
-
- /** a possible type of <CODE>PdfObject</CODE> */
- public static final int INDIRECT = 10;
-
-/** This is an empty string used for the <CODE>PdfNull</CODE>-object and for an empty <CODE>PdfString</CODE>-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 <CODE>PdfObject</CODE> */
- protected byte[] bytes;
-
-/** the type of this <CODE>PdfObject</CODE> */
- protected int type;
-
- /**
- * Holds value of property indRef.
- */
- protected PRIndirectReference indRef;
-
- // constructors
-
-/**
- * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> without any <VAR>content</VAR>.
- *
- * @param type type of the new <CODE>PdfObject</CODE>
- */
-
- protected PdfObject(int type) {
- this.type = type;
- }
-
-/**
- * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> with a certain <VAR>content</VAR>.
- *
- * @param type type of the new <CODE>PdfObject</CODE>
- * @param content content of the new <CODE>PdfObject</CODE> as a <CODE>String</CODE>.
- */
-
- protected PdfObject(int type, String content) {
- this.type = type;
- bytes = PdfEncodings.convertToBytes(content, null);
- }
-
-/**
- * Constructs a <CODE>PdfObject</CODE> of a certain <VAR>type</VAR> with a certain <VAR>content</VAR>.
- *
- * @param type type of the new <CODE>PdfObject</CODE>
- * @param bytes content of the new <CODE>PdfObject</CODE> as an array of <CODE>byte</CODE>.
- */
-
- 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 <CODE>PdfObject</CODE> as an array of <CODE>byte</CODE>s 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 <CODE>PdfObject</CODE>.
- * <P>
- * In some cases, namely for <CODE>PdfString</CODE> and <CODE>PdfStream</CODE>,
- * this method differs from the method <CODE>length</CODE> because <CODE>length</CODE>
- * returns the length of the actual content of the <CODE>PdfObject</CODE>.</P>
- * <P>
- * Remark: the actual content of an object is in most cases identical to its representation.
- * The following statement is always true: length() &gt;= pdfLength().</P>
- *
- * @return a length
- */
-
-// public int pdfLength() {
-// return toPdf(null).length;
-// }
-
-/**
- * Returns the <CODE>String</CODE>-representation of this <CODE>PdfObject</CODE>.
- *
- * @return a <CODE>String</CODE>
- */
-
- public String toString() {
- if (bytes == null)
- return super.toString();
- else
- return PdfEncodings.convertToString(bytes, null);
- }
-
-/**
- * Returns the length of the actual content of the <CODE>PdfObject</CODE>.
- * <P>
- * In some cases, namely for <CODE>PdfString</CODE> and <CODE>PdfStream</CODE>,
- * this method differs from the method <CODE>pdfLength</CODE> because <CODE>pdfLength</CODE>
- * returns the length of the PDF representation of the object, not of the actual content
- * as does the method <CODE>length</CODE>.</P>
- * <P>
- * Remark: the actual content of an object is in some cases identical to its representation.
- * The following statement is always true: length() &gt;= pdfLength().</P>
- *
- * @return a length
- */
-
- public int length() {
- return toString().length();
- }
-
-/**
- * Changes the content of this <CODE>PdfObject</CODE>.
- *
- * @param content the new content of this <CODE>PdfObject</CODE>
- */
-
- protected void setContent(String content) {
- bytes = PdfEncodings.convertToBytes(content, null);
- }
-
- // methods dealing with the type of this object
-
-/**
- * Returns the type of this <CODE>PdfObject</CODE>.
- *
- * @return a type
- */
-
- public int type() {
- return type;
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfNull</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isNull() {
- return (this.type == NULL);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfBoolean</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isBoolean() {
- return (this.type == BOOLEAN);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfNumber</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isNumber() {
- return (this.type == NUMBER);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfString</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isString() {
- return (this.type == STRING);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfName</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isName() {
- return (this.type == NAME);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfArray</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isArray() {
- return (this.type == ARRAY);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfDictionary</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- public boolean isDictionary() {
- return (this.type == DICTIONARY);
- }
-
-/**
- * Checks if this <CODE>PdfObject</CODE> is of the type <CODE>PdfStream</CODE>.
- *
- * @return <CODE>true</CODE> or <CODE>false</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfOutline</CODE> is an object that represents a PDF outline entry.
- * <P>
- * An outline allows a user to access views of a document by name.<BR>
- * 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 <CODE>PdfIndirectReference</CODE> of this object */
- private PdfIndirectReference reference;
-
- /** value of the <B>Count</B>-key */
- private int count = 0;
-
- /** value of the <B>Parent</B>-key */
- private PdfOutline parent;
-
- /** value of the <B>Destination</B>-key */
- private PdfDestination destination;
-
- /** The <CODE>PdfAction</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for the <CODE>outlines object</CODE>.
- *
- * @param writer The PdfWriter you are adding the outline to
- */
-
- PdfOutline(PdfWriter writer) {
- super(OUTLINES);
- open = true;
- parent = null;
- this.writer = writer;
- }
-
- /**
- * Constructs a <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> for this outline item
- * @param title the title of this outline item
- * @param open <CODE>true</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @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 <CODE>true</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> for this outline item
- * @param title the title of this outline item
- * @param open <CODE>true</CODE> if the children are visible
- */
- public PdfOutline(PdfOutline parent, PdfAction action, PdfString title, boolean open) {
- this(parent, action, title.toString(), open);
- }
-
- /**
- * Constructs a <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @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 <CODE>true</CODE> if the children are visible
- */
- public PdfOutline(PdfOutline parent, PdfDestination destination, PdfString title, boolean open) {
- this(parent, destination, title.toString(), true);
- }
-
- /**
- * Constructs a <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @param parent the parent of this outline item
- * @param action the <CODE>PdfAction</CODE> for this outline item
- * @param title the title of this outline item
- * @param open <CODE>true</CODE> 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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>. The open mode is
- * <CODE>true</CODE>.
- *
- * @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 <CODE>PdfOutline</CODE>.
- * <P>
- * This is the constructor for an <CODE>outline entry</CODE>.
- *
- * @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 <CODE>true</CODE> 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 <CODE>true</CODE> 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 <CODE>PdfOutline</CODE>.
- *
- * @param reference the <CODE>PdfIndirectReference</CODE> to this outline.
- */
-
- public void setIndirectReference(PdfIndirectReference reference) {
- this.reference = reference;
- }
-
- /**
- * Gets the indirect reference of this <CODE>PdfOutline</CODE>.
- *
- * @return the <CODE>PdfIndirectReference</CODE> to this outline.
- */
-
- public PdfIndirectReference indirectReference() {
- return reference;
- }
-
- /**
- * Gets the parent of this <CODE>PdfOutline</CODE>.
- *
- * @return the <CODE>PdfOutline</CODE> that is the parent of this outline.
- */
-
- public PdfOutline parent() {
- return parent;
- }
-
- /**
- * Set the page of the <CODE>PdfDestination</CODE>-object.
- *
- * @param pageReference indirect reference to the page
- * @return <CODE>true</CODE> if this page was set as the <CODE>PdfDestination</CODE>-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 <CODE>PdfOutline</CODE>.
- *
- * @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 <CODE>PdfPCell</CODE>.
- * The default padding is 2.
- */
- public PdfPCell() {
- super(0, 0, 0, 0);
- borderWidth = 0.5f;
- border = BOX;
- column.setLeading(0, 1);
- }
-
- /** Constructs a <CODE>PdfPCell</CODE> with a <CODE>Phrase</CODE>.
- * 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 <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>.
- * The default padding is 0.
- * @param image the <CODE>Image</CODE>
- */
- 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 <CODE>PdfPCell</CODE> with an <CODE>Image</CODE>.
- * The default padding is 0.25 for a border width of 0.5.
- * @param image the <CODE>Image</CODE>
- * @param fit <CODE>true</CODE> 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 <CODE>PdfPCell</CODE> with a <CODE>PdfPtable</CODE>.
- * This constructor allows nested tables.
- * The default padding is 0.
- * @param table The <CODE>PdfPTable</CODE>
- */
- 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 <CODE>PdfPCell</CODE>.
- * @param cell the <CODE>PdfPCell</CODE> 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 <CODE>Phrase</CODE> from this cell.
- * @return the <CODE>Phrase</CODE>
- */
- public Phrase getPhrase() {
- return phrase;
- }
-
- /** Sets the <CODE>Phrase</CODE> for this cell.
- * @param phrase the <CODE>Phrase</CODE>
- */
- 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
- * <CODE>Element.ALIGN_CENTER</CODE> 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
- * <CODE>Element.ALIGN_MIDDLE</CODE> 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 <CODE>spaceCharRatio</CODE> times more than extra character spacing.
- * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> 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 <CODE>PdfContentByte</CODE> contained in
- * <CODE>canvases</CODE>.<br>
- * The indexes to <CODE>canvases</CODE> are:<p>
- * <ul>
- * <li><CODE>PdfPTable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
- * will be under the cell.
- * <li><CODE>PdfPTable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
- * <li><CODE>PdfPTable.LINECANVAS</CODE> - the layer where the lines go to.
- * <li><CODE>PdfPTable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
- * will be over the cell.
- * </ul>
- * The layers are placed in sequence on top of each other.
- * <p>
- * @param cell the cell
- * @param position the coordinates of the cell
- * @param canvases an array of <CODE>PdfContentByte</CODE>
- */
- 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.
- * <p>
- * 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> for the default provider
- * @param hasRSAdata <CODE>true</CODE> 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 <CODE>true</CODE> if the signature checks out, <CODE>false</CODE> 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 &lt;java.home&gt;/lib/security/cacerts
- * with the default provider.
- * @return a <CODE>KeyStore</CODE>
- */
- public static KeyStore loadCacertsKeyStore() {
- return loadCacertsKeyStore(null);
- }
-
- /**
- * Loads the default root certificates at &lt;java.home&gt;/lib/security/cacerts.
- * @param provider the provider or <code>null</code> for the default provider
- * @return a <CODE>KeyStore</CODE>
- */
- 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 <CODE>null</CODE>
- * @param calendar the date or <CODE>null</CODE> for the current date
- * @return a <CODE>String</CODE> with the error description or <CODE>null</CODE>
- * 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 <CODE>KeyStore</CODE>
- * @param crls the certificate revocation list or <CODE>null</CODE>
- * @param calendar the date or <CODE>null</CODE> for the current date
- * @return <CODE>null</CODE> if the certificate chain could be validade or a
- * <CODE>Object[]{cert,error}</CODE> where <CODE>cert</CODE> is the
- * failed certificate and <CODE>error</CODE> 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 <CODE>null</CODE> if the <CODE>digest</CODE>
- * is also <CODE>null</CODE>. If the <CODE>digest</CODE> is not <CODE>null</CODE>
- * 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 <CODE>null</CODE>, 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)}.
- * <p>
- * A simple example:
- * <p>
- * <pre>
- * 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)) &gt; 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);
- * </pre>
- * @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.
- * <p>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 <CODE>PdfPSXObject</CODE>. All
- * the members are copied by reference but the buffer stays different.
- * @return a copy of this <CODE>PdfPSXObject</CODE>
- */
-
- 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 <CODE>Table</CODE>.
- * 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.
- * <P>
- * 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 <CODE>PdfcontentByte</CODE>.
- */
- public static final int BASECANVAS = 0;
- /** The index of the duplicate <CODE>PdfContentByte</CODE> where the background will be drawn.
- */
- public static final int BACKGROUNDCANVAS = 1;
- /** The index of the duplicate <CODE>PdfContentByte</CODE> where the border lines will be drawn.
- */
- public static final int LINECANVAS = 2;
- /** The index of the duplicate <CODE>PdfContentByte</CODE> 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 <CODE>PdfPTable</CODE> 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 <CODE>PdfPTable</CODE> with <CODE>numColumns</CODE> 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 <CODE>PdfPTable</CODE>.
- * @param table the <CODE>PdfPTable</CODE> 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 <CODE>PdfPCell</CODE> that will be used as
- * reference for all the <CODE>addCell</CODE> methods except
- * <CODE>addCell(PdfPCell)</CODE>.
- * @return default <CODE>PdfPCell</CODE>
- */
- 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 <CODE>Image</CODE> 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 <CODE>Phrase</CODE> 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.
- * <P>
- * <CODE>canvases</CODE> is obtained from <CODE>beginWritingRows()</CODE>.
- * @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 <CODE>PdfContentByte</CODE> obtained from
- * <CODE>beginWrittingRows()</CODE>
- * @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.
- * <P>
- * <CODE>canvases</CODE> is obtained from <CODE>beginWritingRows()</CODE>.
- * <P>
- * 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 <CODE>PdfContentByte</CODE> obtained from
- * <CODE>beginWrittingRows()</CODE>
- * @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 <CODE>PdfContentByte</CODE> 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.
- * <P>
- * 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 <CODE>PdfContentByte</CODE> 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 <CODE>PdfContentByte</CODE> returned with the following order:<p>
- * <ul>
- * <li><CODE>PdfPtable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
- * will be under the table.
- * <li><CODE>PdfPtable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
- * <li><CODE>PdfPtable.LINECANVAS</CODE> - the layer where the lines go to.
- * <li><CODE>PdfPtable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
- * will be over the table.
- * </ul><p>
- * The layers are placed in sequence on top of each other.
- * @param canvas the <CODE>PdfContentByte</CODE> where the rows will
- * be written to
- * @return an array of 4 <CODE>PdfContentByte</CODE>
- * @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 <CODE>beginWritingRows()</CODE>
- */
- 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
- * <CODE>setHeaderRows()</CODE>.
- * @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 <CODE>true</CODE> 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 <CODE>true</CODE> 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 <CODE>Document</CODE>
- * 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 <CODE>ArrayList</CODE>
- */
- 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
- * <CODE>ElementListener</CODE>.
- *
- * @param listener an <CODE>ElementListener</CODE>
- * @return <CODE>true</CODE> 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 <CODE>setTotalWidth()</CODE> in <CODE>Document.add()</CODE>.
- * @param lockedWidth <CODE>true</CODE> to use the value in <CODE>setTotalWidth()</CODE> in <CODE>Document.add()</CODE>
- */
- 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. <CODE>true</CODE> 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.
- *<p>
- * 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:
- * <p>
- * <PRE>
- * table.setHeaderRows(3);
- * table.setFooterRows(1);
- * </PRE>
- * <p>
- * 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 <CODE>PdfPTable</CODE>.
- *
- * @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 <CODE>PdfContentByte</CODE> contained in
- * <CODE>canvases</CODE>.<br>
- * The indexes to <CODE>canvases</CODE> are:<p>
- * <ul>
- * <li><CODE>PdfPTable.BASECANVAS</CODE> - the original <CODE>PdfContentByte</CODE>. Anything placed here
- * will be under the table.
- * <li><CODE>PdfPTable.BACKGROUNDCANVAS</CODE> - the layer where the background goes to.
- * <li><CODE>PdfPTable.LINECANVAS</CODE> - the layer where the lines go to.
- * <li><CODE>PdfPTable.TEXTCANVAS</CODE> - the layer where the text go to. Anything placed here
- * will be over the table.
- * </ul>
- * The layers are placed in sequence on top of each other.
- * <p>
- * The <CODE>widths</CODE> and <CODE>heights</CODE> have the coordinates of the cells.<br>
- * The size of the <CODE>widths</CODE> array is the number of rows.
- * Each sub-array in <CODE>widths</CODE> 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 <CODE>widths</CODE>
- * are the same.<br>
- * For the <CODE>heights</CODE> 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 <CODE>PdfPTable</CODE> 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 <CODE>PdfContentByte</CODE>
- */
- 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;
-/**
- * <CODE>PdfPage</CODE> is the PDF Page-object.
- * <P>
- * 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.<BR>
- * 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 <B>Rotate</B> key for a page in PORTRAIT */
- public static final PdfNumber PORTRAIT = new PdfNumber(0);
-
-/** value of the <B>Rotate</B> key for a page in LANDSCAPE */
- public static final PdfNumber LANDSCAPE = new PdfNumber(90);
-
-/** value of the <B>Rotate</B> key for a page in INVERTEDPORTRAIT */
- public static final PdfNumber INVERTEDPORTRAIT = new PdfNumber(180);
-
-/** value of the <B>Rotate</B> key for a page in SEASCAPE */
- public static final PdfNumber SEASCAPE = new PdfNumber(270);
-
-/** value of the <B>MediaBox</B> key */
- PdfRectangle mediaBox;
-
- // constructors
-
-/**
- * Constructs a <CODE>PdfPage</CODE>.
- *
- * @param mediaBox a value for the <B>MediaBox</B> key
- * @param resources an indirect reference to a <CODE>PdfResources</CODE>-object
- * @param rotate a value for the <B>Rotate</B> 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 <CODE>PdfPage</CODE>.
- *
- * @param mediaBox a value for the <B>MediaBox</B> key
- * @param resources an indirect reference to a <CODE>PdfResources</CODE>-object
- * @param rotate a value for the <B>Rotate</B> 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 <CODE>PdfPage</CODE>.
- *
- * @param mediaBox a value for the <B>MediaBox</B> key
- * @param resources an indirect reference to a <CODE>PdfResources</CODE>-object
- */
-
-// PdfPage(PdfRectangle mediaBox, Rectangle cropBox, PdfIndirectReference resources) {
-// this(mediaBox, cropBox, resources, null);
-// }
-
-/**
- * Constructs a <CODE>PdfPage</CODE>.
- *
- * @param mediaBox a value for the <B>MediaBox</B> key
- * @param resources an indirect reference to a <CODE>PdfResources</CODE>-object
- */
-
- PdfPage(PdfRectangle mediaBox, HashMap boxSize, PdfDictionary resources) {
- this(mediaBox, boxSize, resources, 0);
- }
-
-/**
- * Checks if this page element is a tree of pages.
- * <P>
- * This method allways returns <CODE>false</CODE>.
- *
- * @return <CODE>false</CODE> because this is a single page
- */
-
- public boolean isParent() {
- return false;
- }
-
- // methods
-
-/**
- * Adds an indirect reference pointing to a <CODE>PdfContents</CODE>-object.
- *
- * @param contents an indirect reference to a <CODE>PdfContents</CODE>-object
- */
-
- void add(PdfIndirectReference contents) {
- put(PdfName.CONTENTS, contents);
- }
-
-/**
- * Rotates the mediabox, but not the text in it.
- *
- * @return a <CODE>PdfRectangle</CODE>
- */
-
- PdfRectangle rotateMediaBox() {
- this.mediaBox = mediaBox.rotate();
- put(PdfName.MEDIABOX, this.mediaBox);
- return this.mediaBox;
- }
-
-/**
- * Returns the MediaBox of this Page.
- *
- * @return a <CODE>PdfRectangle</CODE>
- */
-
- 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 <CODE>PdfPageElement</CODE> interface has to be implemented by <CODE>PdfPage</CODE> and <CODE>PdfPages</CODE>.
- *
- * @see PdfPage
- * @see PdfPages
- */
-
-interface PdfPageElement {
-
-/**
- * Set the value for the <B>Parent</B> key in the Page or Pages Dictionary.
- *
- * @param reference an indirect reference to a <CODE>PdfPages</CODE>-object
- */
-
- public void setParent(PdfIndirectReference reference);
-
-/**
- * Checks if this page element is a tree of pages.
- *
- * @return <CODE>true</CODE> if it's a tree of pages;
- * <CODE>false</CODE> 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.
- *<p>
- * 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 <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onOpenDocument(PdfWriter writer, Document document);
-
-/**
- * Called when a page is initialized.
- * <P>
- * Note that if even if a page is not written this method is still
- * called. It is preferable to use <CODE>onEndPage</CODE> to avoid
- * infinite loops.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onEndPage(PdfWriter writer, Document document);
-
-/**
- * Called when the document is closed.
- * <P>
- * Note that this method is called with the page number equal
- * to the last page plus one.
- *
- * @param writer the <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onCloseDocument(PdfWriter writer, Document document);
-
-/**
- * Called when a Paragraph is written.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height at which the
- * paragraph will be written to. This is useful to insert bookmarks with
- * more control.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height of the end of the paragraph.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height at which the
- * chapter will be written to.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height of the end of the chapter.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height at which the
- * section will be written to.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height of the section end.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>Chunk</CODE> with a generic tag is written.
- * <P>
- * It is usefull to pinpoint the <CODE>Chunk</CODE> location to generate
- * bookmarks, for example.
- *
- * @param writer the <CODE>PdfWriter</CODE> for this document
- * @param document the document
- * @param rect the <CODE>Rectangle</CODE> containing the <CODE>Chunk</CODE>
- * @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 <CODE>PdfPageEvent</CODE> by implementing all the interface methods.
- * A class can extend <CODE>PdfPageEventHelper</CODE> and only implement the
- * needed methods.
- *<p>
- * 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 <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onOpenDocument(PdfWriter writer,Document document) {
- }
-
-/**
- * Called when a page is initialized.
- * <P>
- * Note that if even if a page is not written this method is still
- * called. It is preferable to use <CODE>onEndPage</CODE> to avoid
- * infinite loops.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onEndPage(PdfWriter writer,Document document) {
- }
-
-/**
- * Called when the document is closed.
- * <P>
- * Note that this method is called with the page number equal
- * to the last page plus one.
- *
- * @param writer the <CODE>PdfWriter</CODE> for this document
- * @param document the document
- */
- public void onCloseDocument(PdfWriter writer,Document document) {
- }
-
-/**
- * Called when a Paragraph is written.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height at which the
- * paragraph will be written to. This is useful to insert bookmarks with
- * more control.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height of the end of the paragraph.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height at which the
- * chapter will be written to.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height of the end of the chapter.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height at which the
- * section will be written to.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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.
- * <P>
- * <CODE>position</CODE> will hold the height of the section end.
- *
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>Chunk</CODE> with a generic tag is written.
- * <P>
- * It is usefull to pinpoint the <CODE>Chunk</CODE> location to generate
- * bookmarks, for example.
- *
- * @param writer the <CODE>PdfWriter</CODE> for this document
- * @param document the document
- * @param rect the <CODE>Rectangle</CODE> containing the <CODE>Chunk</CODE>
- * @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 <CODE>Integer</CODE>.
- * @param obj the first <CODE>Integer</CODE>
- * @param obj1 the second <CODE>Integer</CODE>
- * @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 <CODE>true</CODE>
- */
- 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 <CODE>null</CODE> 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 <CODE>null</CODE> 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;
-
-/**
- * <CODE>PdfPages</CODE> is the PDF Pages-object.
- * <P>
- * 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.<BR>
- * 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 <CODE>PdfPages</CODE>-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 <CODE>PdfPattern</CODE> 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 <CODE>PdfPattern</CODE>.
- */
-
- private PdfPatternPainter() {
- super(null);
- type = TYPE_PATTERN;
- }
-
- /**
- * Creates new PdfPattern
- *
- * @param wr the <CODE>PdfWriter</CODE>
- */
-
- 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 <CODE>PdfPatternPainter</CODE>. All
- * the members are copied by reference but the buffer stays different.
- * @return a copy of this <CODE>PdfPatternPainter</CODE>
- */
-
- 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 <CODE>InputStream</CODE> 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 <CODE>InputStream</CODE> 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
- * <CODE>PdfReader.close()</CODE>, reopen is automatic.
- * @param raf the document location
- * @param ownerPassword the password or <CODE>null</CODE> 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 <CODE>PdfReader</CODE> 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 <CODE>Rectangle</CODE> with the value of the /MediaBox and the /Rotate key.
- * @param index the page number. The first page is 1
- * @return a <CODE>Rectangle</CODE>
- */
- 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 <CODE>HashMap</CODE>
- * of <CODE>String</CODE>.
- * @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 <CODE>Rectangle</CODE> so that llx and lly are smaller than urx and ury.
- * @param box the original rectangle
- * @return a normalized <CODE>Rectangle</CODE>
- */
- 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 <CODE>PdfObject</CODE> resolving an indirect reference
- * if needed.
- * @param obj the <CODE>PdfObject</CODE> to read
- * @return the resolved <CODE>PdfObject</CODE>
- */
- 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 <CODE>PdfObject</CODE> 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 <CODE>PdfObject</CODE> 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 <CODE>true</CODE> to read a correct stream. <CODE>false</CODE>
- * 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 <CODE>true</CODE> if the document was changed,
- * <CODE>false</CODE> 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 <CODE>true</CODE> if the PDF is encrypted.
- * @return <CODE>true</CODE> if the PDF is encrypted
- */
- public boolean isEncrypted() {
- return encrypted;
- }
-
- /**
- * Gets the encryption permissions. It can be used directly in
- * <CODE>PdfWriter.setEncryption()</CODE>.
- * @return the encryption permissions
- */
- public int getPermissions() {
- return pValue;
- }
-
- /**
- * Returns <CODE>true</CODE> if the PDF has a 128 bit key encryption.
- * @return <CODE>true</CODE> 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 <CODE>HashMap</CODE>. 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 <CODE>HashMap</CODE>. 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 <CODE>HashMap</CODE>. 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 <CODE>AcroFields</CODE>.
- * @return a read-only version of <CODE>AcroFields</CODE>
- */
- 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
- * <CODE>List</CODE> of <CODE>Integer</CODE>. 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;
-
-/**
- * <CODE>PdfRectangle</CODE> is the PDF Rectangle object.
- * <P>
- * 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 <CODE>array</CODE> of
- * four numbers, specifying the lower lef <I>x</I>, lower left <I>y</I>, upper right <I>x</I>,
- * and upper right <I>y</I> coordinates of the rectangle, in that order.<BR>
- * 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 <CODE>PdfRectangle</CODE>-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 <CODE>PdfRectangle</CODE>-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 <CODE>PdfRectangle</CODE>-object with a <CODE>Rectangle</CODE>-object.
- *
- * @param rectangle a <CODE>Rectangle</CODE>
- */
-
- 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 <CODE>add</CODE>-method in <CODE>PdfArray</CODE> in order to prevent the adding of extra object to the array.
- *
- * @param object <CODE>PdfObject</CODE> to add (will not be added here)
- * @return <CODE>false</CODE>
- */
-
- 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 <CODE>PdfRectangle</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfResources</CODE> is the PDF Resources-object.
- * <P>
- * The marking operations for drawing a page are stored in a stream that is the value of the
- * <B>Contents</B> 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 <B>Resources</B> 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.<BR>
- * 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 <CODE>null</CODE>
- */
- 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 <CODE>null</CODE> if the <CODE>digest</CODE>
- * is also <CODE>null</CODE>. If the <CODE>digest</CODE> is not <CODE>null</CODE>
- * 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 <CODE>null</CODE> 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 <CODE>null</CODE> 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 <CODE>null</CODE>
- * 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 <CODE>null</CODE>
- * @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 <CODE>null</CODE> 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.
- * <p>
- * Consult <A HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
- * 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.
- * <p>
- * Consult <A HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
- * 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.
- * <p>
- * Consult <A HREF="http://partners.adobe.com/asn/developer/pdfs/tn/PPKAppearances.pdf">PPKAppearances.pdf</A>
- * 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 <CODE>null</CODE> if the <CODE>digest</CODE>
- * is also <CODE>null</CODE>. If the <CODE>digest</CODE> is not <CODE>null</CODE>
- * 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 <code>null</code> 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
- * <code>null</code> 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 <CODE>true</CODE> if a new field was created, <CODE>false</CODE> 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 <CODE>null</CODE> 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().
- * <p>
- * If calling preClose() <B>dont't</B> call PdfStamper.close().
- * <p>
- * 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().
- * <p>
- * If calling preClose() <B>dont't</B> call PdfStamper.close().
- * <p>
- * If using an external signature <CODE>exclusionSizes</CODE> must contain at least
- * the <CODE>PdfName.CONTENTS</CODE> 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 <CODE>HashMap</CODE> with names and sizes to be excluded in the signature
- * calculation. The key is a <CODE>PdfName</CODE> and the value an
- * <CODE>Integer</CODE>. At least the <CODE>PdfName.CONTENTS</CODE> 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().
- * <p>
- * <CODE>update</CODE> is a <CODE>PdfDictionary</CODE> that must have exactly the
- * same keys as the ones provided in {@link #preClose(HashMap)}.
- * @param update a <CODE>PdfDictionary</CODE> 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().
- * <p>
- * @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 <CODE>PdfStamper</CODE> associated with this instance.
- * @return the <CODE>PdfStamper</CODE> 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 <CODE>true</CODE> if the document is in the process of closing,
- * <CODE>false</CODE> otherwise
- */
- public boolean isPreClosed() {
- return preClosed;
- }
-
- /**
- * Gets the instance of the standard signature dictionary. This instance
- * is only available after pre close.
- * <p>
- * 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 <code>true</code> 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 <code>true</code> to certify the document, <code>false</code> 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 <CODE>PdfSpotColor</CODE> 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 <CODE>PdfSpotColor</CODE>.
- *
- * @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.
- * <p>
- * 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 <CODE>true</CODE> 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 <CODE>String</CODE> map to add or change values in
- * the info dictionary.
- * @return the map or <CODE>null</CODE>
- *
- */
- public HashMap getMoreInfo() {
- return this.moreInfo;
- }
-
- /** An optional <CODE>String</CODE> map to add or change values in
- * the info dictionary. Entries with <CODE>null</CODE>
- * 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 <CODE>pageNumber</CODE> will
- * be shifted up. If <CODE>pageNumber</CODE> 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.
- * <p>
- * If closing a signed document with an external signature the closing must be done
- * in the <CODE>PdfSignatureAppearance</CODE> 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 <CODE>PdfContentByte</CODE> to write under the page of
- * the original document.
- * @param pageNum the page number where the extra content is written
- * @return a <CODE>PdfContentByte</CODE> to write under the page of
- * the original document
- */
- public PdfContentByte getUnderContent(int pageNum) {
- return stamper.getUnderContent(pageNum);
- }
-
- /** Gets a <CODE>PdfContentByte</CODE> to write over the page of
- * the original document.
- * @param pageNum the page number where the extra content is written
- * @return a <CODE>PdfContentByte</CODE> 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 <CODE>true</CODE>.
- * @param rotateContents <CODE>true</CODE> to set auto-rotation, <CODE>false</CODE>
- * 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 <code>true</code> for 128 bit key length, <code>false</code> 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 <code>true</code> for 128 bit key length, <code>false</code> 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 <CODE>AcroFields</CODE> object that allows to get and set field values
- * and to merge FDF forms.
- * @return the <CODE>AcroFields</CODE> 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 <CODE>true</CODE> to flatten the fields, <CODE>false</CODE>
- * to keep the fields
- */
- public void setFormFlattening(boolean flat) {
- stamper.setFormFlattening(flat);
- }
-
- /** Determines if the FreeText annotations are flattened on close.
- * @param flat <CODE>true</CODE> to flatten the FreeText annotations, <CODE>false</CODE>
- * (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 <CODE>null</CODE> 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 <CODE>name</CODE> 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.
- * <p>
- * Calling <CODE>setFormFlattening(true)</CODE> is needed to have any kind of
- * flattening.
- * @param name the field name
- * @return <CODE>true</CODE> if the field exists, <CODE>false</CODE> 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 <CODE>null</CODE>
- * the file will be read from the disk
- * @param file the path to the file. It will only be used if
- * <CODE>fileStore</CODE> is not <CODE>null</CODE>
- * @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 <code>true</code> 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 <CODE>PdfWriter.PAGE_OPEN</CODE>
- * or <CODE>PdfWriter.PAGE_CLOSE</CODE>
- * @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 <code>null</code> 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.
- * <p>
- * A possible use for adding a signature without invalidating an existing one is:
- * <p>
- * <pre>
- * 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();
- * </pre>
- * @param reader the original document
- * @param os the output stream or <CODE>null</CODE> 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 <CODE>os</CODE> is null.
- * In that case the document can be retrieved directly from the temporary file. If it's <CODE>null</CODE>
- * no temporary file will be created and memory will be used
- * @param append if <CODE>true</CODE> the signature and all the other content will be added as a
- * new revision thus not invalidating existing signatures
- * @return a <CODE>PdfStamper</CODE>
- * @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.
- * <p>
- * Note that the pdf is created in memory.
- * <p>
- * A possible use is:
- * <p>
- * <pre>
- * 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();
- * </pre>
- * @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 <CODE>PdfStamper</CODE>
- */
- 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.
- * <p>
- * A possible use is:
- * <p>
- * <pre>
- * 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();
- * </pre>
- * @param reader the original document
- * @param os the output stream or <CODE>null</CODE> 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 <CODE>os</CODE> is null.
- * In that case the document can be retrieved directly from the temporary file. If it's <CODE>null</CODE>
- * no temporary file will be created and memory will be used
- * @return a <CODE>PdfStamper</CODE>
- * @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 <code>UnsupportedOperationException</code>.
- * @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 <CODE>PdfWriter.PAGE_OPEN</CODE>
- * or <CODE>PdfWriter.PAGE_CLOSE</CODE>
- * @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 <code>UnsupportedOperationException</code>.
- * @param seconds ignore
- */
- public void setDuration(int seconds) {
- throw new UnsupportedOperationException("Use setPageAction(PdfName actionType, PdfAction action, int page)");
- }
-
- /**
- * Always throws an <code>UnsupportedOperationException</code>.
- * @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 <code>null</code> 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: <CODE>DOCUMENT_CLOSE</CODE>,
- * <CODE>WILL_SAVE</CODE>, <CODE>DID_SAVE</CODE>, <CODE>WILL_PRINT</CODE>
- * and <CODE>DID_PRINT</CODE>.
- *
- * @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;
-
-/**
- * <CODE>PdfStream</CODE> is the Pdf stream object.
- * <P>
- * 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.<BR>
- * A stream consists of a dictionary that describes a sequence of characters, followed by
- * the keyword <B>stream</B>, followed by zero or more lines of characters, followed by
- * the keyword <B>endstream</B>.<BR>
- * All streams must be <CODE>PdfIndirectObject</CODE>s. The stream dictionary must be a direct
- * object. The keyword <B>stream</B> that follows the stream dictionary should be followed by
- * a carriage return and linefeed or just a linefeed.<BR>
- * Remark: In this version only the FLATEDECODE-filter is supported.<BR>
- * This object is described in the 'Portable Document Format Reference Manual version 1.3'
- * section 4.8 (page 41-53).<BR>
- *
- * @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 <CODE>PdfStream</CODE>-object.
- *
- * @param bytes content of the new <CODE>PdfObject</CODE> as an array of <CODE>byte</CODE>.
- */
-
- 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 <CODE>InputStream</CODE>
- * is totally consumed but is not closed. The general usage is:
- * <p>
- * <pre>
- * InputStream in = ...;
- * PdfStream stream = new PdfStream(in, writer);
- * stream.flateCompress();
- * writer.addToBody(stream);
- * stream.writeLength();
- * in.close();
- * </pre>
- * @param inputStream the data to write to this stream
- * @param writer the <CODE>PdfWriter</CODE> 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 <CODE>PdfStream</CODE>-object.
- */
-
- protected PdfStream() {
- super();
- type = STREAM;
- }
-
- /**
- * Writes the stream length to the <CODE>PdfWriter</CODE>.
- * <p>
- * 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 <CODE>OutputStream</CODE>.
- * @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 <CODE>PdfString</CODE>-class is the PDF-equivalent of a JAVA-<CODE>String</CODE>-object.
- * <P>
- * 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 \<I>ddd</I> escape sequence is the preferred way to represent characters
- * outside the printable ASCII character set.<BR>
- * 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 <CODE>PdfString</CODE>-object.
- */
-
- public PdfString() {
- super(STRING);
- }
-
- /**
- * Constructs a <CODE>PdfString</CODE>-object.
- *
- * @param value the content of the string
- */
-
- public PdfString(String value) {
- super(STRING);
- this.value = value;
- }
-
- /**
- * Constructs a <CODE>PdfString</CODE>-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 <CODE>PdfString</CODE>-object.
- *
- * @param bytes an array of <CODE>byte</CODE>
- */
-
- 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 <CODE>PdfString</CODE>.
- *
- * @return an array of <CODE>byte</CODE>s
- */
-
- 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 <CODE>String</CODE> value of the <CODE>PdfString</CODE>-object.
- *
- * @return a <CODE>String</CODE>
- */
-
- public String toString() {
- return value;
- }
-
- // other methods
-
- /**
- * Gets the encoding of this string.
- *
- * @return a <CODE>String</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfTable</CODE> 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 <CODE>PdfTable</CODE>-object.
- *
- * @param table a <CODE>Table</CODE>
- * @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.
- * <p><b>Pre-requisite</b>: the object must have been built with the parameter <code>supportUpdateRowAdditions</code> 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 <CODE>ArrayList</CODE>
- */
-
- ArrayList getHeaderCells() {
- return headercells;
- }
-
- /**
- * Checks if there is a table header.
- *
- * @return an <CODE>ArrayList</CODE>
- */
-
- boolean hasHeader() {
- return headercells.size() > 0;
- }
-
- /**
- * Returns the arraylist with the cells of the table.
- *
- * @return an <CODE>ArrayList</CODE>
- */
-
- 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 <CODE>Table</CODE> 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 <CODE>Table</CODE> 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 <CODE>PdfTemplate</CODE>.
- */
-
- protected PdfTemplate() {
- super(null);
- type = TYPE_TEMPLATE;
- }
-
- /**
- * Creates new PdfTemplate
- *
- * @param wr the <CODE>PdfWriter</CODE>
- */
-
- 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 <code>null</code> 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 <CODE>PdfTemplate</CODE>. All
- * the members are copied by reference but the buffer stays different.
- * @return a copy of this <CODE>PdfTemplate</CODE>
- */
-
- 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;
-
-/**
- * <CODE>PdfTextArray</CODE> defines an array with displacements and <CODE>PdfString</CODE>-objects.
- * <P>
- * A <CODE>TextArray</CODE> is used with the operator <VAR>TJ</VAR> in <CODE>PdfText</CODE>.
- * The first object in this array has to be a <CODE>PdfString</CODE>;
- * 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 <CODE>PdfNumber</CODE> to the <CODE>PdfArray</CODE>.
- *
- * @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 <CODE>Transition</CODE>.
- *
- */
- public PdfTransition() {
- this(BLINDH);
- }
-
- /**
- * Constructs a <CODE>Transition</CODE>.
- *
- *@param type type of the transition effect
- */
- public PdfTransition(int type) {
- this(type,1);
- }
-
- /**
- * Constructs a <CODE>Transition</CODE>.
- *
- *@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 <CODE>DocWriter</CODE> class for PDF.
- * <P>
- * When this <CODE>PdfWriter</CODE> is added
- * to a certain <CODE>PdfDocument</CODE>, the PDF representation of every Element
- * added to this Document will be written to the outputstream.</P>
- */
-
-public class PdfWriter extends DocWriter {
-
- // inner classes
-
- /**
- * This class generates the structure of a PDF document.
- * <P>
- * 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
-
- /**
- * <CODE>PdfCrossReference</CODE> 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 <CODE>PdfObject</CODE>.
- * @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 <CODE>PdfBody</CODE>.
- * @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 <CODE>PdfObject</CODE> to the body.
- * <P>
- * This methods creates a <CODE>PdfIndirectObject</CODE> with a
- * certain number, containing the given <CODE>PdfObject</CODE>.
- * It also adds a <CODE>PdfCrossReference</CODE> for this object
- * to an <CODE>ArrayList</CODE> that will be used to build the
- * Cross-reference Table.
- *
- * @param object a <CODE>PdfObject</CODE>
- * @return a <CODE>PdfIndirectObject</CODE>
- * @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 <CODE>PdfObject</CODE> to the body given an already existing
- * PdfIndirectReference.
- * <P>
- * This methods creates a <CODE>PdfIndirectObject</CODE> with the number given by
- * <CODE>ref</CODE>, containing the given <CODE>PdfObject</CODE>.
- * It also adds a <CODE>PdfCrossReference</CODE> for this object
- * to an <CODE>ArrayList</CODE> that will be used to build the
- * Cross-reference Table.
- *
- * @param object a <CODE>PdfObject</CODE>
- * @param ref a <CODE>PdfIndirectReference</CODE>
- * @return a <CODE>PdfIndirectObject</CODE>
- * @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 <CODE>PdfResources</CODE> object to the body.
- *
- * @param object the <CODE>PdfResources</CODE>
- * @return a <CODE>PdfIndirectObject</CODE>
- */
-
-// PdfIndirectObject add(PdfResources object) {
-// return add(object);
-// }
-
- /**
- * Adds a <CODE>PdfPages</CODE> object to the body.
- *
- * @param object the root of the document
- * @return a <CODE>PdfIndirectObject</CODE>
- */
-
-// 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 <CODE>Body</CODE>.
- *
- * @return a number of objects
- */
-
- int size() {
- return Math.max(((PdfCrossReference)xrefs.last()).getRefnum() + 1, refnum);
- }
-
- /**
- * Returns the CrossReferenceTable of the <CODE>Body</CODE>.
- * @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);
- }
- }
- }
- }
- }
-
- /**
- * <CODE>PdfTrailer</CODE> is the PDF Trailer object.
- * <P>
- * 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 <CODE>PdfCrossReferenceTable</CODE>
- * @param offset offset of the <CODE>PdfCrossReferenceTable</CODE>
- * @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 <CODE>PdfObject</CODE>.
- * @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 <CODE>PdfPageEvent</CODE> 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 <CODE>ratio</CODE> 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 <CODE>PdfWriter</CODE>.
- * <P>
- * Remark: a PdfWriter can only be constructed by calling the method
- * <CODE>getInstance(Document document, OutputStream os)</CODE>.
- *
- * @param document The <CODE>PdfDocument</CODE> that has to be written
- * @param os The <CODE>OutputStream</CODE> 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 <CODE>PdfWriter</CODE>.
- *
- * @param document The <CODE>Document</CODE> that has to be written
- * @param os The <CODE>OutputStream</CODE> the writer has to write to.
- * @return a new <CODE>PdfWriter</CODE>
- *
- * @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 <CODE>PdfWriter</CODE>.
- *
- * @return a new <CODE>PdfWriter</CODE>
- * @param document The <CODE>Document</CODE> that has to be written
- * @param os The <CODE>OutputStream</CODE> the writer has to write to.
- * @param listener A <CODE>DocListener</CODE> 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 <CODE>PdfContents</CODE> to this Writer.
- * <P>
- * The document has to be open before you can begin to add content
- * to the body of the document.
- *
- * @return a <CODE>PdfIndirectReference</CODE>
- * @param page the <CODE>PdfPage</CODE> to add
- * @param contents the <CODE>PdfContents</CODE> 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 <CODE>Document.add(Image)</CODE>.
- * @param image the <CODE>Image</CODE> 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 <CODE>Document.add(Image)</CODE>.
- * @param image the <CODE>Image</CODE> to add
- * @param fixedRef the reference to used. It may be <CODE>null</CODE>,
- * a <CODE>PdfIndirectReference</CODE> or a <CODE>PRIndirectReference</CODE>.
- * @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 <CODE>PdfImage</CODE> to the outputstream.
- *
- * @param pdfImage the image to be added
- * @return a <CODE>PdfIndirectReference</CODE> 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 <CODE>PdfIndirectReference</CODE> to the image with a given name.
- *
- * @param name the name of the image
- * @return a <CODE>PdfIndirectReference</CODE>
- */
-
- PdfIndirectReference getImageReference(PdfName name) {
- return (PdfIndirectReference) imageDictionary.get(name);
- }
-
- // methods to open and close the writer
-
- /**
- * Signals that the <CODE>Document</CODE> has been opened and that
- * <CODE>Elements</CODE> can be added.
- * <P>
- * 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 <CODE>Document</CODE> was closed and that no other
- * <CODE>Elements</CODE> will be added.
- * <P>
- * 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 <CODE>Table</CODE> 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 <CODE>Table</CODE>
- * @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 <CODE>Table</CODE> fits the current page of the <CODE>PdfDocument</CODE>.
- *
- * @param table the table that has to be checked
- * @param margin a certain margin
- * @return <CODE>true</CODE> if the <CODE>Table</CODE> fits the page, <CODE>false</CODE> otherwise.
- */
-
- public boolean fitsPage(Table table, float margin) {
- return pdf.bottom(table) > pdf.indentBottom() + margin;
- }
-
- /**
- * Checks if a <CODE>Table</CODE> fits the current page of the <CODE>PdfDocument</CODE>.
- *
- * @param table the table that has to be checked
- * @return <CODE>true</CODE> if the <CODE>Table</CODE> fits the page, <CODE>false</CODE> otherwise.
- */
-
- public boolean fitsPage(Table table) {
- return fitsPage(table, 0);
- }
-
- /**
- * Checks if a <CODE>PdfPTable</CODE> fits the current page of the <CODE>PdfDocument</CODE>.
- *
- * @param table the table that has to be checked
- * @param margin a certain margin
- * @return <CODE>true</CODE> if the <CODE>PdfPTable</CODE> fits the page, <CODE>false</CODE> otherwise.
- */
- public boolean fitsPage(PdfPTable table, float margin) {
- return pdf.fitsPage(table, margin);
- }
-
- /**
- * Checks if a <CODE>PdfPTable</CODE> fits the current page of the <CODE>PdfDocument</CODE>.
- *
- * @param table the table that has to be checked
- * @return <CODE>true</CODE> if the <CODE>PdfPTable</CODE> fits the page, <CODE>false</CODE> 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 <CODE>true</CODE> if writing temporarely has to be paused, <CODE>false</CODE> 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 <CODE>PdfAcroForm</CODE>
- */
-
- 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 <CODE>BaseFont</CODE> to the document but not to the page resources.
- * It is used for templates.
- * @param bf the <CODE>BaseFont</CODE> to add
- * @return an <CODE>Object[]</CODE> where position 0 is a <CODE>PdfName</CODE>
- * and position 1 is an <CODE>PdfIndirectReference</CODE>
- */
-
- 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 <CODE>SpotColor</CODE> to the document but not to the page resources.
- * @param spc the <CODE>SpotColor</CODE> to add
- * @return an <CODE>Object[]</CODE> where position 0 is a <CODE>PdfName</CODE>
- * and position 1 is an <CODE>PdfIndirectReference</CODE>
- */
-
- 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 <CODE>PdfDocument</CODE> associated with this writer.
- * @return the <CODE>PdfDocument</CODE>
- */
-
- PdfDocument getPdfDocument() {
- return pdf;
- }
-
- /**
- * Gets a <CODE>PdfIndirectReference</CODE> for an object that
- * will be created in the future.
- * @return the <CODE>PdfIndirectReference</CODE>
- */
-
- 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 <CODE>PdfName</CODE> 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 <CODE>PdfPageEvent</CODE> for this document.
- * @param event the <CODE>PdfPageEvent</CODE> 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 <CODE>PdfPageEvent</CODE> for this document or <CODE>null</CODE>
- * if none is set.
- * @return the <CODE>PdfPageEvent</CODE> for this document or <CODE>null</CODE>
- * if none is set
- */
-
- public PdfPageEvent getPageEvent() {
- return pageEvent;
- }
-
- /**
- * Adds the local destinations to the body of the document.
- * @param dest the <CODE>HashMap</CODE> 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.
- * <p>
- * <ul>
- * <li>The page layout to be used when the document is opened (choose one).
- * <ul>
- * <li><b>PageLayoutSinglePage</b> - Display one page at a time. (default)
- * <li><b>PageLayoutOneColumn</b> - Display the pages in one column.
- * <li><b>PageLayoutTwoColumnLeft</b> - Display the pages in two columns, with
- * oddnumbered pages on the left.
- * <li><b>PageLayoutTwoColumnRight</b> - Display the pages in two columns, with
- * oddnumbered pages on the right.
- * <li><b>PageLayoutTwoPageLeft</b> - Display the pages two at a time, with
- * oddnumbered pages on the left.
- * <li><b>PageLayoutTwoPageRight</b> - Display the pages two at a time, with
- * oddnumbered pages on the right.
- * </ul>
- * <li>The page mode how the document should be displayed
- * when opened (choose one).
- * <ul>
- * <li><b>PageModeUseNone</b> - Neither document outline nor thumbnail images visible. (default)
- * <li><b>PageModeUseOutlines</b> - Document outline visible.
- * <li><b>PageModeUseThumbs</b> - Thumbnail images visible.
- * <li><b>PageModeFullScreen</b> - Full-screen mode, with no menu bar, window
- * controls, or any other window visible.
- * <li><b>PageModeUseOC</b> - Optional content group panel visible
- * <li><b>PageModeUseAttachments</b> - Attachments panel visible
- * </ul>
- * <li><b>HideToolbar</b> - A flag specifying whether to hide the viewer application's tool
- * bars when the document is active.
- * <li><b>HideMenubar</b> - A flag specifying whether to hide the viewer application's
- * menu bar when the document is active.
- * <li><b>HideWindowUI</b> - A flag specifying whether to hide user interface elements in
- * the document's window (such as scroll bars and navigation controls),
- * leaving only the document's contents displayed.
- * <li><b>FitWindow</b> - A flag specifying whether to resize the document's window to
- * fit the size of the first displayed page.
- * <li><b>CenterWindow</b> - A flag specifying whether to position the document's window
- * in the center of the screen.
- * <li><b>DisplayDocTitle</b> - A flag specifying whether to display the document's title
- * in the top bar.
- * <li>The predominant reading order for text. This entry has no direct effect on the
- * document's contents or page numbering, but can be used to determine the relative
- * positioning of pages when displayed side by side or printed <i>n-up</i> (choose one).
- * <ul>
- * <li><b>DirectionL2R</b> - Left to right
- * <li><b>DirectionR2L</b> - Right to left (including vertical writing systems such as
- * Chinese, Japanese, and Korean)
- * </ul>
- * <li>The document's page mode, specifying how to display the
- * document on exiting full-screen mode. It is meaningful only
- * if the page mode is <b>PageModeFullScreen</b> (choose one).
- * <ul>
- * <li><b>NonFullScreenPageModeUseNone</b> - Neither document outline nor thumbnail images
- * visible
- * <li><b>NonFullScreenPageModeUseOutlines</b> - Document outline visible
- * <li><b>NonFullScreenPageModeUseThumbs</b> - Thumbnail images visible
- * <li><b>NonFullScreenPageModeUseOC</b> - Optional content group panel visible
- * </ul>
- * <li><b>PrintScalingNone</b> - Indicates that the print dialog should reflect no page scaling.
- * </ul>
- * @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 <code>true</code> for 128 bit key length, <code>false</code> 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 <code>true</code> for 128 bit key length, <code>false</code> 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: <CODE>DOCUMENT_CLOSE</CODE>,
- * <CODE>WILL_SAVE</CODE>, <CODE>DID_SAVE</CODE>, <CODE>WILL_PRINT</CODE>
- * and <CODE>DID_PRINT</CODE>.
- *
- * @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 <CODE>action</CODE> 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 <CODE>null</CODE>
- * the file will be read from the disk
- * @param file the path to the file. It will only be used if
- * <CODE>fileStore</CODE> is not <CODE>null</CODE>
- * @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 <CODE>PdfAnnotation</CODE> to the calculation order
- * array.
- * @param annot the <CODE>PdfAnnotation</CODE> 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 <CODE>PdfAnnotation</CODE> or a <CODE>PdfFormField</CODE>
- * to the document. Only the top parent of a <CODE>PdfFormField</CODE>
- * needs to be added.
- * @param annot the <CODE>PdfAnnotation</CODE> or the <CODE>PdfFormField</CODE> 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 <CODE>null</CODE> argument value
- * only returns the number of pages to process. It is
- * advisable to issue a <CODE>Document.newPage()</CODE>
- * 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 <CODE>spaceCharRatio</CODE> times more than extra character spacing.
- * If the ratio is <CODE>PdfWriter.NO_SPACE_CHAR_RATIO</CODE> 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 <CODE>PdfReader</CODE> 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 <CODE>PdfWriter.PAGE_OPEN</CODE>
- * or <CODE>PdfWriter.PAGE_CLOSE</CODE>
- * @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
- * <CODE>freeReader()</CODE> 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 <CODE>true</CODE> to just check for the existence of a valid output intent
- * dictionary, <CODE>false</CODE> to insert the dictionary if it exists
- * @throws IOException on error
- * @return <CODE>true</CODE> if the output intent dictionary exists, <CODE>false</CODE>
- * 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.
- * <p>
- * 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 <CODE>PdfName.DEFAULTGRAY</CODE>, <CODE>PdfName.DEFAULTRGB</CODE>
- * or <CODE>PdfName.DEFAULTCMYK</CODE>
- * @param cs the colorspace. A <CODE>null</CODE> or <CODE>PdfNull</CODE> 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 <code>true</code> 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.
- * <p>
- * 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 <B>Optional Content Properties Dictionary</B>. 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 <CODE>true</CODE> 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 <CODE>null</CODE>.
- * @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.
- * <p>
- * Example usage:
- * <p>
- * <PRE>
- * 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();
- * </PRE>
- * @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 <CODE>PdfWriter</CODE>
- * @param box the field location and dimensions
- * @param fieldName the field name. If <CODE>null</CODE> 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 <CODE>LAYOUT_LABEL_ONLY</CODE>,
- * <CODE>LAYOUT_ICON_ONLY</CODE>, <CODE>LAYOUT_ICON_TOP_LABEL_BOTTOM</CODE>,
- * <CODE>LAYOUT_LABEL_TOP_ICON_BOTTOM</CODE>, <CODE>LAYOUT_ICON_LEFT_LABEL_RIGHT</CODE>,
- * <CODE>LAYOUT_LABEL_LEFT_ICON_RIGHT</CODE> and <CODE>LAYOUT_LABEL_OVER_ICON</CODE>.
- * The default is <CODE>LAYOUT_LABEL_ONLY</CODE>.
- * @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
- * <CODE>SCALE_ICON_ALWAYS</CODE>, <CODE>SCALE_ICON_NEVER</CODE>,
- * <CODE>SCALE_ICON_IS_TOO_BIG</CODE> and <CODE>SCALE_ICON_IS_TOO_SMALL</CODE>.
- * The default is <CODE>SCALE_ICON_ALWAYS</CODE>.
- * @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 <CODE>true</CODE> the icon is scaled proportionally,
- * if <CODE>false</CODE> 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 <CODE>true</CODE> the icon will be scaled to fit fully within the bounds of the annotation,
- * if <CODE>false</CODE> the border width will be taken into account. The default
- * is <CODE>false</CODE>.
- * @param iconFitToBounds if <CODE>true</CODE> the icon will be scaled to fit fully within the bounds of the annotation,
- * if <CODE>false</CODE> 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.
- * <p>
- * Example usage:
- * <p>
- * <PRE>
- * 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();
- * </PRE>
- * @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 <CODE>PdfWriter</CODE>
- * @param box the field location and dimensions
- * @param fieldName the field name. It must not be <CODE>null</CODE>
- * @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
- * <CODE>TYPE_CHECK</CODE>,
- * <CODE>TYPE_CIRCLE</CODE>,
- * <CODE>TYPE_CROSS</CODE>,
- * <CODE>TYPE_DIAMOND</CODE>,
- * <CODE>TYPE_SQUARE</CODE> and
- * <CODE>TYPE_STAR</CODE>.
- * @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, <CODE>true</CODE> for checked
- * and <CODE>false</CODE> for unchecked
- */
- public void setChecked(boolean checked) {
- this.checked = checked;
- }
-
- /**
- * Gets the field appearance.
- * @param isRadio <CODE>true</CODE> for a radio field and <CODE>false</CODE>
- * for a check field
- * @param on <CODE>true</CODE> for the checked state, <CODE>false</CODE>
- * 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 <CODE>true</CODE> for the checked state, <CODE>false</CODE>
- * 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 <CODE>true</CODE>, exactly one radio button must be selected at all
- * times; clicking the currently selected button has no effect.
- * If <CODE>false</CODE>, clicking
- * the selected button deselects it, leaving no button selected.
- * @param radiosInUnison if <CODE>true</CODE>, 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 <CODE>false</CODE>, 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 <CODE>true</CODE> to get a radio field, <CODE>false</CODE> 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
- * <code>b1</code> and <code>b2</code>, where each of the two values is
- * between <code>0</code> and <code>255</code>, inclusive, then the
- * result is equal to:
- * <blockquote><pre>
- * (short)((b2 &lt;&lt; 8) | b1)
- * </pre></blockquote>
- * <p>
- * 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
- * <code>b1</code> and <code>b2</code>, where
- * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>,
- * then the result is equal to:
- * <blockquote><pre>
- * (b2 &lt;&lt; 8) | b1
- * </pre></blockquote>
- * <p>
- * 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
- * <code>b1</code> and <code>b2</code>, where
- * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>,
- * then the result is equal to:
- * <blockquote><pre>
- * (char)((b2 &lt;&lt; 8) | b1)
- * </pre></blockquote>
- * <p>
- * 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 <code>b1</code>,
- * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
- * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
- * then the result is equal to:
- * <blockquote><pre>
- * (b4 &lt;&lt; 24) | (b3 &lt;&lt; 16) + (b2 &lt;&lt; 8) + b1
- * </pre></blockquote>
- * <p>
- * 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
- * <code>int</code>.
- * @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 <code>b1</code>,
- * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
- * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
- * then the result is equal to:
- * <blockquote><pre>
- * (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
- * </pre></blockquote>
- * <p>
- * 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
- * <code>long</code>.
- * @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.
- * <p>
- * The general systax is:<br>
- * [!][o][odd][e][even]start-end
- * <p>
- * 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 <CODE>Integer</CODE>
- */
- 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 <code>Color</code>.
- *
- * @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.
- * <p>
- * 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.
- * <p>
- * 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.
- * <p>
- * The actions and the parameters can be:
- * <ul>
- * <li>"Action" = "GoTo" - "Page" | "Named"
- * <ul>
- * <li>"Page" = "3 XYZ 70 400 null" - page number followed by a destination (/XYZ is also accepted)
- * <li>"Named" = "named_destination"
- * </ul>
- * <li>"Action" = "GoToR" - "Page" | "Named" | "NamedN", "File", ["NewWindow"]
- * <ul>
- * <li>"Page" = "3 XYZ 70 400 null" - page number followed by a destination (/XYZ is also accepted)
- * <li>"Named" = "named_destination_as_a_string"
- * <li>"NamedN" = "named_destination_as_a_name"
- * <li>"File" - "the_file_to_open"
- * <li>"NewWindow" - "true" or "false"
- * </ul>
- * <li>"Action" = "URI" - "URI"
- * <ul>
- * <li>"URI" = "http://sf.net" - URI to jump to
- * </ul>
- * <li>"Action" = "Launch" - "File"
- * <ul>
- * <li>"File" - "the_file_to_open_or_execute"
- * </ul>
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class SimpleBookmark implements SimpleXMLDocHandler {
-
- private ArrayList topList;
- private Stack attr = new Stack();
-
- /** Creates a new instance of SimpleBookmark */
- private SimpleBookmark() {
- }
-
- private static List bookmarkDepth(PdfReader reader, PdfDictionary outline, IntHashtable pages) {
- ArrayList list = new ArrayList();
- while (outline != null) {
- HashMap map = new HashMap();
- PdfString title = (PdfString)PdfReader.getPdfObjectRelease(outline.get(PdfName.TITLE));
- map.put("Title", title.toUnicodeString());
- PdfArray color = (PdfArray)PdfReader.getPdfObjectRelease(outline.get(PdfName.C));
- if (color != null && color.getArrayList().size() == 3) {
- ByteBuffer out = new ByteBuffer();
- ArrayList arr = color.getArrayList();
- out.append(((PdfNumber)arr.get(0)).floatValue()).append(' ');
- out.append(((PdfNumber)arr.get(1)).floatValue()).append(' ');
- out.append(((PdfNumber)arr.get(2)).floatValue());
- map.put("Color", PdfEncodings.convertToString(out.toByteArray(), null));
- }
- PdfNumber style = (PdfNumber)PdfReader.getPdfObjectRelease(outline.get(PdfName.F));
- if (style != null) {
- int f = style.intValue();
- String s = "";
- if ((f & 1) != 0)
- s += "italic ";
- if ((f & 2) != 0)
- s += "bold ";
- s = s.trim();
- if (s.length() != 0)
- map.put("Style", s);
- }
- PdfNumber count = (PdfNumber)PdfReader.getPdfObjectRelease(outline.get(PdfName.COUNT));
- if (count != null && count.intValue() < 0)
- map.put("Open", "false");
- try {
- PdfObject dest = PdfReader.getPdfObjectRelease(outline.get(PdfName.DEST));
- if (dest != null) {
- mapGotoBookmark(map, dest, pages); //changed by ujihara 2004-06-13
- }
- else {
- PdfDictionary action = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.A));
- if (action != null) {
- if (PdfName.GOTO.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) {
- dest = PdfReader.getPdfObjectRelease(action.get(PdfName.D));
- if (dest != null) {
- mapGotoBookmark(map, dest, pages);
- }
- }
- else if (PdfName.URI.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) {
- map.put("Action", "URI");
- map.put("URI", ((PdfString)PdfReader.getPdfObjectRelease(action.get(PdfName.URI))).toUnicodeString());
- }
- else if (PdfName.GOTOR.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) {
- dest = PdfReader.getPdfObjectRelease(action.get(PdfName.D));
- if (dest != null) {
- if (dest.isString())
- map.put("Named", dest.toString());
- else if (dest.isName())
- map.put("NamedN", PdfName.decodeName(dest.toString()));
- else if (dest.isArray()) {
- ArrayList arr = ((PdfArray)dest).getArrayList();
- StringBuffer s = new StringBuffer();
- s.append(arr.get(0).toString());
- s.append(' ').append(arr.get(1).toString());
- for (int k = 2; k < arr.size(); ++k)
- s.append(' ').append(arr.get(k).toString());
- map.put("Page", s.toString());
- }
- }
- map.put("Action", "GoToR");
- PdfObject file = PdfReader.getPdfObjectRelease(action.get(PdfName.F));
- if (file != null) {
- if (file.isString())
- map.put("File", ((PdfString)file).toUnicodeString());
- else if (file.isDictionary()) {
- file = PdfReader.getPdfObject(((PdfDictionary)file).get(PdfName.F));
- if (file.isString())
- map.put("File", ((PdfString)file).toUnicodeString());
- }
- }
- PdfObject newWindow = PdfReader.getPdfObjectRelease(action.get(PdfName.NEWWINDOW));
- if (newWindow != null)
- map.put("NewWindow", newWindow.toString());
- }
- else if (PdfName.LAUNCH.equals(PdfReader.getPdfObjectRelease(action.get(PdfName.S)))) {
- map.put("Action", "Launch");
- PdfObject file = PdfReader.getPdfObjectRelease(action.get(PdfName.F));
- if (file == null)
- file = PdfReader.getPdfObjectRelease(action.get(PdfName.WIN));
- if (file != null) {
- if (file.isString())
- map.put("File", ((PdfString)file).toUnicodeString());
- else if (file.isDictionary()) {
- file = PdfReader.getPdfObjectRelease(((PdfDictionary)file).get(PdfName.F));
- if (file.isString())
- map.put("File", ((PdfString)file).toUnicodeString());
- }
- }
- }
- }
- }
- }
- catch (Exception e) {
- //empty on purpose
- }
- PdfDictionary first = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.FIRST));
- if (first != null) {
- map.put("Kids", bookmarkDepth(reader, first, pages));
- }
- list.add(map);
- outline = (PdfDictionary)PdfReader.getPdfObjectRelease(outline.get(PdfName.NEXT));
- }
- return list;
- }
-
- private static void mapGotoBookmark(HashMap map, PdfObject dest, IntHashtable pages)
- {
- if (dest.isString())
- map.put("Named", dest.toString());
- else if (dest.isName())
- map.put("Named", PdfName.decodeName(dest.toString()));
- else if (dest.isArray())
- map.put("Page", makeBookmarkParam((PdfArray)dest, pages)); //changed by ujihara 2004-06-13
- map.put("Action", "GoTo");
- }
-
- private static String makeBookmarkParam(PdfArray dest, IntHashtable pages)
- {
- ArrayList arr = dest.getArrayList();
- StringBuffer s = new StringBuffer();
- s.append(pages.get(getNumber((PdfIndirectReference)arr.get(0)))); //changed by ujihara 2004-06-13
- s.append(' ').append(arr.get(1).toString().substring(1));
- for (int k = 2; k < arr.size(); ++k)
- s.append(' ').append(arr.get(k).toString());
- return s.toString();
- }
-
- /**
- * Gets number of indirect. If type of directed indirect is PAGES, it refers PAGE object through KIDS.
- * (Contributed by Kazuya Ujihara)
- * @param indirect
- * 2004-06-13
- */
- private static int getNumber(PdfIndirectReference indirect)
- {
- PdfDictionary pdfObj = (PdfDictionary)PdfReader.getPdfObjectRelease(indirect);
- if (pdfObj.contains(PdfName.TYPE) && pdfObj.get(PdfName.TYPE).equals(PdfName.PAGES) && pdfObj.contains(PdfName.KIDS))
- {
- PdfArray kids = (PdfArray)pdfObj.get(PdfName.KIDS);
- indirect = (PdfIndirectReference)kids.arrayList.get(0);
- }
- return indirect.getNumber();
- }
-
- /**
- * Gets a <CODE>List</CODE> with the bookmarks. It returns <CODE>null</CODE> if
- * the document doesn't have any bookmarks.
- * @param reader the document
- * @return a <CODE>List</CODE> with the bookmarks or <CODE>null</CODE> if the
- * document doesn't have any
- */
- public static List getBookmark(PdfReader reader) {
- PdfDictionary catalog = reader.getCatalog();
- PdfObject obj = PdfReader.getPdfObjectRelease(catalog.get(PdfName.OUTLINES));
- if (obj == null || !obj.isDictionary())
- return null;
- PdfDictionary outlines = (PdfDictionary)obj;
- IntHashtable pages = new IntHashtable();
- int numPages = reader.getNumberOfPages();
- for (int k = 1; k <= numPages; ++k) {
- pages.put(reader.getPageOrigRef(k).getNumber(), k);
- reader.releasePage(k);
- }
- return bookmarkDepth(reader, (PdfDictionary)PdfReader.getPdfObjectRelease(outlines.get(PdfName.FIRST)), pages);
- }
-
- /**
- * Removes the bookmark entries for a number of page ranges. The page ranges
- * consists of a number of pairs with the start/end page range. The page numbers
- * are inclusive.
- * @param list the bookmarks
- * @param pageRange the page ranges, always in pairs.
- */
- public static void eliminatePages(List list, int pageRange[]) {
- if (list == null)
- return;
- for (Iterator it = list.listIterator(); it.hasNext();) {
- HashMap map = (HashMap)it.next();
- boolean hit = false;
- if ("GoTo".equals(map.get("Action"))) {
- String page = (String)map.get("Page");
- if (page != null) {
- page = page.trim();
- int idx = page.indexOf(' ');
- int pageNum;
- if (idx < 0)
- pageNum = Integer.parseInt(page);
- else
- pageNum = Integer.parseInt(page.substring(0, idx));
- int len = pageRange.length & 0xfffffffe;
- for (int k = 0; k < len; k += 2) {
- if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) {
- hit = true;
- break;
- }
- }
- }
- }
- List kids = (List)map.get("Kids");
- if (kids != null) {
- eliminatePages(kids, pageRange);
- if (kids.size() == 0) {
- map.remove("Kids");
- kids = null;
- }
- }
- if (hit) {
- if (kids == null)
- it.remove();
- else {
- map.remove("Action");
- map.remove("Page");
- map.remove("Named");
- }
- }
- }
- }
-
- /**
- * For the pages in range add the <CODE>pageShift</CODE> to the page number.
- * The page ranges
- * consists of a number of pairs with the start/end page range. The page numbers
- * are inclusive.
- * @param list the bookmarks
- * @param pageShift the number to add to the pages in range
- * @param pageRange the page ranges, always in pairs. It can be <CODE>null</CODE>
- * to include all the pages
- */
- public static void shiftPageNumbers(List list, int pageShift, int pageRange[]) {
- if (list == null)
- return;
- for (Iterator it = list.listIterator(); it.hasNext();) {
- HashMap map = (HashMap)it.next();
- if ("GoTo".equals(map.get("Action"))) {
- String page = (String)map.get("Page");
- if (page != null) {
- page = page.trim();
- int idx = page.indexOf(' ');
- int pageNum;
- if (idx < 0)
- pageNum = Integer.parseInt(page);
- else
- pageNum = Integer.parseInt(page.substring(0, idx));
- boolean hit = false;
- if (pageRange == null)
- hit = true;
- else {
- int len = pageRange.length & 0xfffffffe;
- for (int k = 0; k < len; k += 2) {
- if (pageNum >= pageRange[k] && pageNum <= pageRange[k + 1]) {
- hit = true;
- break;
- }
- }
- }
- if (hit) {
- if (idx < 0)
- page = (pageNum + pageShift) + "";
- else
- page = (pageNum + pageShift) + page.substring(idx);
- }
- map.put("Page", page);
- }
- }
- List kids = (List)map.get("Kids");
- if (kids != null)
- shiftPageNumbers(kids, pageShift, pageRange);
- }
- }
-
- static void createOutlineAction(PdfDictionary outline, HashMap map, PdfWriter writer, boolean namedAsNames) throws IOException {
- try {
- String action = (String)map.get("Action");
- if ("GoTo".equals(action)) {
- String p;
- if ((p = (String)map.get("Named")) != null) {
- if (namedAsNames)
- outline.put(PdfName.DEST, new PdfName(p));
- else
- outline.put(PdfName.DEST, new PdfString(p, null));
- }
- else if ((p = (String)map.get("Page")) != null) {
- PdfArray ar = new PdfArray();
- StringTokenizer tk = new StringTokenizer(p);
- int n = Integer.parseInt(tk.nextToken());
- ar.add(writer.getPageReference(n));
- if (!tk.hasMoreTokens()) {
- ar.add(PdfName.XYZ);
- ar.add(new float[]{0, 10000, 0});
- }
- else {
- String fn = tk.nextToken();
- if (fn.startsWith("/"))
- fn = fn.substring(1);
- ar.add(new PdfName(fn));
- for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) {
- fn = tk.nextToken();
- if (fn.equals("null"))
- ar.add(PdfNull.PDFNULL);
- else
- ar.add(new PdfNumber(fn));
- }
- }
- outline.put(PdfName.DEST, ar);
- }
- }
- else if ("GoToR".equals(action)) {
- String p;
- PdfDictionary dic = new PdfDictionary();
- if ((p = (String)map.get("Named")) != null)
- dic.put(PdfName.D, new PdfString(p, null));
- else if ((p = (String)map.get("NamedN")) != null)
- dic.put(PdfName.D, new PdfName(p));
- else if ((p = (String)map.get("Page")) != null){
- PdfArray ar = new PdfArray();
- StringTokenizer tk = new StringTokenizer(p);
- ar.add(new PdfNumber(tk.nextToken()));
- if (!tk.hasMoreTokens()) {
- ar.add(PdfName.XYZ);
- ar.add(new float[]{0, 10000, 0});
- }
- else {
- String fn = tk.nextToken();
- if (fn.startsWith("/"))
- fn = fn.substring(1);
- ar.add(new PdfName(fn));
- for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) {
- fn = tk.nextToken();
- if (fn.equals("null"))
- ar.add(PdfNull.PDFNULL);
- else
- ar.add(new PdfNumber(fn));
- }
- }
- dic.put(PdfName.D, ar);
- }
- String file = (String)map.get("File");
- if (dic.size() > 0 && file != null) {
- dic.put(PdfName.S, PdfName.GOTOR);
- dic.put(PdfName.F, new PdfString(file));
- String nw = (String)map.get("NewWindow");
- if (nw != null) {
- if (nw.equals("true"))
- dic.put(PdfName.NEWWINDOW, PdfBoolean.PDFTRUE);
- else if (nw.equals("false"))
- dic.put(PdfName.NEWWINDOW, PdfBoolean.PDFFALSE);
- }
- outline.put(PdfName.A, dic);
- }
- }
- else if ("URI".equals(action)) {
- String uri = (String)map.get("URI");
- if (uri != null) {
- PdfDictionary dic = new PdfDictionary();
- dic.put(PdfName.S, PdfName.URI);
- dic.put(PdfName.URI, new PdfString(uri));
- outline.put(PdfName.A, dic);
- }
- }
- else if ("Launch".equals(action)) {
- String file = (String)map.get("File");
- if (file != null) {
- PdfDictionary dic = new PdfDictionary();
- dic.put(PdfName.S, PdfName.LAUNCH);
- dic.put(PdfName.F, new PdfString(file));
- outline.put(PdfName.A, dic);
- }
- }
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
-
- public static Object[] iterateOutlines(PdfWriter writer, PdfIndirectReference parent, List kids, boolean namedAsNames) throws IOException {
- PdfIndirectReference refs[] = new PdfIndirectReference[kids.size()];
- for (int k = 0; k < refs.length; ++k)
- refs[k] = writer.getPdfIndirectReference();
- int ptr = 0;
- int count = 0;
- for (Iterator it = kids.listIterator(); it.hasNext(); ++ptr) {
- HashMap map = (HashMap)it.next();
- Object lower[] = null;
- List subKid = (List)map.get("Kids");
- if (subKid != null && subKid.size() > 0)
- lower = iterateOutlines(writer, refs[ptr], subKid, namedAsNames);
- PdfDictionary outline = new PdfDictionary();
- ++count;
- if (lower != null) {
- outline.put(PdfName.FIRST, (PdfIndirectReference)lower[0]);
- outline.put(PdfName.LAST, (PdfIndirectReference)lower[1]);
- int n = ((Integer)lower[2]).intValue();
- if ("false".equals(map.get("Open"))) {
- outline.put(PdfName.COUNT, new PdfNumber(-n));
- }
- else {
- outline.put(PdfName.COUNT, new PdfNumber(n));
- count += n;
- }
- }
- outline.put(PdfName.PARENT, parent);
- if (ptr > 0)
- outline.put(PdfName.PREV, refs[ptr - 1]);
- if (ptr < refs.length - 1)
- outline.put(PdfName.NEXT, refs[ptr + 1]);
- outline.put(PdfName.TITLE, new PdfString((String)map.get("Title"), PdfObject.TEXT_UNICODE));
- String color = (String)map.get("Color");
- if (color != null) {
- try {
- PdfArray arr = new PdfArray();
- StringTokenizer tk = new StringTokenizer(color);
- for (int k = 0; k < 3; ++k) {
- float f = Float.valueOf(tk.nextToken()).intValue();
- if (f < 0) f = 0;
- if (f > 1) f = 1;
- arr.add(new PdfNumber(f));
- }
- outline.put(PdfName.C, arr);
- } catch(Exception e){} //in case it's malformed
- }
- String style = (String)map.get("Style");
- if (style != null) {
- style = style.toLowerCase();
- int bits = 0;
- if (style.indexOf("italic") >= 0)
- bits |= 1;
- if (style.indexOf("bold") >= 0)
- bits |= 2;
- if (bits != 0)
- outline.put(PdfName.F, new PdfNumber(bits));
- }
- createOutlineAction(outline, map, writer, namedAsNames);
- writer.addToBody(outline, refs[ptr]);
- }
- return new Object[]{refs[0], refs[refs.length - 1], new Integer(count)};
- }
-
- /**
- * Exports the bookmarks to XML. Only of use if the generation is to be include in
- * some other XML document.
- * @param list the bookmarks
- * @param out the export destination. The writer is not closed
- * @param indent the indentation level. Pretty printing significant only
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>,
- * whatever the encoding
- * @throws IOException on error
- */
- public static void exportToXMLNode(List list, Writer out, int indent, boolean onlyASCII) throws IOException {
- String dep = "";
- for (int k = 0; k < indent; ++k)
- dep += " ";
- for (Iterator it = list.iterator(); it.hasNext();) {
- HashMap map = (HashMap)it.next();
- String title = null;
- out.write(dep);
- out.write("<Title ");
- List kids = null;
- for (Iterator e = map.keySet().iterator(); e.hasNext();) {
- String key = (String)e.next();
- if (key.equals("Title")) {
- title = (String)map.get(key);
- continue;
- }
- else if (key.equals("Kids")) {
- kids = (List)map.get(key);
- continue;
- }
- else {
- out.write(key);
- out.write("=\"");
- String value = (String)map.get(key);
- if (key.equals("Named") || key.equals("NamedN"))
- value = SimpleNamedDestination.escapeBinaryString(value);
- out.write(SimpleXMLParser.escapeXML(value, onlyASCII));
- out.write("\" ");
- }
- }
- out.write(">");
- if (title == null)
- title = "";
- out.write(SimpleXMLParser.escapeXML(title, onlyASCII));
- if (kids != null) {
- out.write("\n");
- exportToXMLNode(kids, out, indent + 1, onlyASCII);
- out.write(dep);
- }
- out.write("</Title>\n");
- }
- }
-
- /**
- * Exports the bookmarks to XML. The DTD for this XML is:
- * <p>
- * <pre>
- * &lt;?xml version='1.0' encoding='UTF-8'?&gt;
- * &lt;!ELEMENT Title (#PCDATA|Title)*&gt;
- * &lt;!ATTLIST Title
- * Action CDATA #IMPLIED
- * Open CDATA #IMPLIED
- * Page CDATA #IMPLIED
- * URI CDATA #IMPLIED
- * File CDATA #IMPLIED
- * Named CDATA #IMPLIED
- * NamedN CDATA #IMPLIED
- * NewWindow CDATA #IMPLIED
- * Style CDATA #IMPLIED
- * Color CDATA #IMPLIED
- * &gt;
- * &lt;!ELEMENT Bookmark (Title)*&gt;
- * </pre>
- * @param list the bookmarks
- * @param out the export destination. The stream is not closed
- * @param encoding the encoding according to IANA conventions
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>,
- * whatever the encoding
- * @throws IOException on error
- */
- public static void exportToXML(List list, OutputStream out, String encoding, boolean onlyASCII) throws IOException {
- String jenc = SimpleXMLParser.getJavaEncoding(encoding);
- Writer wrt = new BufferedWriter(new OutputStreamWriter(out, jenc));
- exportToXML(list, wrt, encoding, onlyASCII);
- }
-
- /**
- * Exports the bookmarks to XML.
- * @param list the bookmarks
- * @param wrt the export destination. The writer is not closed
- * @param encoding the encoding according to IANA conventions
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>,
- * whatever the encoding
- * @throws IOException on error
- */
- public static void exportToXML(List list, Writer wrt, String encoding, boolean onlyASCII) throws IOException {
- wrt.write("<?xml version=\"1.0\" encoding=\"");
- wrt.write(SimpleXMLParser.escapeXML(encoding, onlyASCII));
- wrt.write("\"?>\n<Bookmark>\n");
- exportToXMLNode(list, wrt, 1, onlyASCII);
- wrt.write("</Bookmark>\n");
- wrt.flush();
- }
-
- /**
- * Import the bookmarks from XML.
- * @param in the XML source. The stream is not closed
- * @throws IOException on error
- * @return the bookmarks
- */
- public static List importFromXML(InputStream in) throws IOException {
- SimpleBookmark book = new SimpleBookmark();
- SimpleXMLParser.parse(book, in);
- return book.topList;
- }
-
- /**
- * Import the bookmarks from XML.
- * @param in the XML source. The reader is not closed
- * @throws IOException on error
- * @return the bookmarks
- */
- public static List importFromXML(Reader in) throws IOException {
- SimpleBookmark book = new SimpleBookmark();
- SimpleXMLParser.parse(book, in);
- return book.topList;
- }
-
- public void endDocument() {
- }
-
- public void endElement(String tag) {
- if (tag.equals("Bookmark")) {
- if (attr.isEmpty())
- return;
- else
- throw new RuntimeException("Bookmark end tag out of place.");
- }
- if (!tag.equals("Title"))
- throw new RuntimeException("Invalid end tag - " + tag);
- HashMap attributes = (HashMap)attr.pop();
- String title = (String)attributes.get("Title");
- attributes.put("Title", title.trim());
- String named = (String)attributes.get("Named");
- if (named != null)
- attributes.put("Named", SimpleNamedDestination.unEscapeBinaryString(named));
- named = (String)attributes.get("NamedN");
- if (named != null)
- attributes.put("NamedN", SimpleNamedDestination.unEscapeBinaryString(named));
- if (attr.isEmpty())
- topList.add(attributes);
- else {
- HashMap parent = (HashMap)attr.peek();
- List kids = (List)parent.get("Kids");
- if (kids == null) {
- kids = new ArrayList();
- parent.put("Kids", kids);
- }
- kids.add(attributes);
- }
- }
-
- public void startDocument() {
- }
-
- public void startElement(String tag, HashMap h) {
- if (topList == null) {
- if (tag.equals("Bookmark")) {
- topList = new ArrayList();
- return;
- }
- else
- throw new RuntimeException("Root element is not Bookmark.");
- }
- if (!tag.equals("Title"))
- throw new RuntimeException("Tag " + tag + " not allowed.");
- HashMap attributes = new HashMap(h);
- attributes.put("Title", "");
- attributes.remove("Kids");
- attr.push(attributes);
- }
-
- public void text(String str) {
- if (attr.isEmpty())
- return;
- HashMap attributes = (HashMap)attr.peek();
- String title = (String)attributes.get("Title");
- title += str;
- attributes.put("Title", title);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/SimpleNamedDestination.java b/src/main/java/com/lowagie/text/pdf/SimpleNamedDestination.java
deleted file mode 100644
index 1d6410c..0000000
--- a/src/main/java/com/lowagie/text/pdf/SimpleNamedDestination.java
+++ /dev/null
@@ -1,335 +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.Map;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.io.BufferedWriter;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class SimpleNamedDestination implements SimpleXMLDocHandler {
-
- private HashMap xmlNames;
- private HashMap xmlLast;
-
- private SimpleNamedDestination() {
- }
-
- public static HashMap getNamedDestination(PdfReader reader, boolean fromNames) {
- IntHashtable pages = new IntHashtable();
- int numPages = reader.getNumberOfPages();
- for (int k = 1; k <= numPages; ++k)
- pages.put(reader.getPageOrigRef(k).getNumber(), k);
- HashMap names = fromNames ? reader.getNamedDestinationFromNames() : reader.getNamedDestinationFromStrings();
- for (Iterator it = names.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry)it.next();
- ArrayList arr = ((PdfArray)entry.getValue()).getArrayList();
- StringBuffer s = new StringBuffer();
- try {
- s.append(pages.get(((PdfIndirectReference)arr.get(0)).getNumber()));
- s.append(' ').append(arr.get(1).toString().substring(1));
- for (int k = 2; k < arr.size(); ++k)
- s.append(' ').append(arr.get(k).toString());
- entry.setValue(s.toString());
- }
- catch (Exception e) {
- it.remove();
- }
- }
- return names;
- }
-
- /**
- * Exports the bookmarks to XML. The DTD for this XML is:
- * <p>
- * <pre>
- * &lt;?xml version='1.0' encoding='UTF-8'?&gt;
- * &lt;!ELEMENT Name (#PCDATA)&gt;
- * &lt;!ATTLIST Name
- * Page CDATA #IMPLIED
- * &gt;
- * &lt;!ELEMENT Destination (Name)*&gt;
- * </pre>
- * @param names the names
- * @param out the export destination. The stream is not closed
- * @param encoding the encoding according to IANA conventions
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>,
- * whatever the encoding
- * @throws IOException on error
- */
- public static void exportToXML(HashMap names, OutputStream out, String encoding, boolean onlyASCII) throws IOException {
- String jenc = SimpleXMLParser.getJavaEncoding(encoding);
- Writer wrt = new BufferedWriter(new OutputStreamWriter(out, jenc));
- exportToXML(names, wrt, encoding, onlyASCII);
- }
-
- /**
- * Exports the bookmarks to XML.
- * @param names the names
- * @param wrt the export destination. The writer is not closed
- * @param encoding the encoding according to IANA conventions
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>,
- * whatever the encoding
- * @throws IOException on error
- */
- public static void exportToXML(HashMap names, Writer wrt, String encoding, boolean onlyASCII) throws IOException {
- wrt.write("<?xml version=\"1.0\" encoding=\"");
- wrt.write(SimpleXMLParser.escapeXML(encoding, onlyASCII));
- wrt.write("\"?>\n<Destination>\n");
- for (Iterator it = names.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry)it.next();
- String key = (String)entry.getKey();
- String value = (String)entry.getValue();
- wrt.write(" <Name Page=\"");
- wrt.write(SimpleXMLParser.escapeXML(value, onlyASCII));
- wrt.write("\">");
- wrt.write(SimpleXMLParser.escapeXML(escapeBinaryString(key), onlyASCII));
- wrt.write("</Name>\n");
- }
- wrt.write("</Destination>\n");
- wrt.flush();
- }
-
- /**
- * Import the names from XML.
- * @param in the XML source. The stream is not closed
- * @throws IOException on error
- * @return the names
- */
- public static HashMap importFromXML(InputStream in) throws IOException {
- SimpleNamedDestination names = new SimpleNamedDestination();
- SimpleXMLParser.parse(names, in);
- return names.xmlNames;
- }
-
- /**
- * Import the names from XML.
- * @param in the XML source. The reader is not closed
- * @throws IOException on error
- * @return the names
- */
- public static HashMap importFromXML(Reader in) throws IOException {
- SimpleNamedDestination names = new SimpleNamedDestination();
- SimpleXMLParser.parse(names, in);
- return names.xmlNames;
- }
-
- static PdfArray createDestinationArray(String value, PdfWriter writer) throws IOException {
- PdfArray ar = new PdfArray();
- StringTokenizer tk = new StringTokenizer(value);
- int n = Integer.parseInt(tk.nextToken());
- ar.add(writer.getPageReference(n));
- if (!tk.hasMoreTokens()) {
- ar.add(PdfName.XYZ);
- ar.add(new float[]{0, 10000, 0});
- }
- else {
- String fn = tk.nextToken();
- if (fn.startsWith("/"))
- fn = fn.substring(1);
- ar.add(new PdfName(fn));
- for (int k = 0; k < 4 && tk.hasMoreTokens(); ++k) {
- fn = tk.nextToken();
- if (fn.equals("null"))
- ar.add(PdfNull.PDFNULL);
- else
- ar.add(new PdfNumber(fn));
- }
- }
- return ar;
- }
-
- public static PdfDictionary outputNamedDestinationAsNames(HashMap names, PdfWriter writer) throws IOException {
- PdfDictionary dic = new PdfDictionary();
- for (Iterator it = names.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry)it.next();
- try {
- String key = (String)entry.getKey();
- String value = (String)entry.getValue();
- PdfArray ar = createDestinationArray(value, writer);
- PdfName kn = new PdfName(key);
- dic.put(kn, ar);
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- return dic;
- }
-
- public static PdfDictionary outputNamedDestinationAsStrings(HashMap names, PdfWriter writer) throws IOException {
- HashMap n2 = new HashMap(names);
- for (Iterator it = n2.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry)it.next();
- try {
- String value = (String)entry.getValue();
- PdfArray ar = createDestinationArray(value, writer);
- entry.setValue(writer.addToBody(ar).getIndirectReference());
- }
- catch (Exception e) {
- it.remove();
- }
- }
- return PdfNameTree.writeTree(n2, writer);
- }
-
- public static String escapeBinaryString(String s) {
- StringBuffer buf = new StringBuffer();
- char cc[] = s.toCharArray();
- int len = cc.length;
- for (int k = 0; k < len; ++k) {
- char c = cc[k];
- if (c < ' ') {
- buf.append('\\');
- String octal = "00" + Integer.toOctalString((int)c);
- buf.append(octal.substring(octal.length() - 3));
- }
- else if (c == '\\')
- buf.append("\\\\");
- else
- buf.append(c);
- }
- return buf.toString();
- }
-
- public static String unEscapeBinaryString(String s) {
- StringBuffer buf = new StringBuffer();
- char cc[] = s.toCharArray();
- int len = cc.length;
- for (int k = 0; k < len; ++k) {
- char c = cc[k];
- if (c == '\\') {
- if (++k >= len) {
- buf.append('\\');
- break;
- }
- c = cc[k];
- if (c >= '0' && c <= '7') {
- int n = c - '0';
- ++k;
- for (int j = 0; j < 2 && k < len; ++j) {
- c = cc[k];
- if (c >= '0' && c <= '7') {
- ++k;
- n = n * 8 + c - '0';
- }
- else {
- break;
- }
- }
- --k;
- buf.append((char)n);
- }
- else
- buf.append(c);
- }
- else
- buf.append(c);
- }
- return buf.toString();
- }
-
- public void endDocument() {
- }
-
- public void endElement(String tag) {
- if (tag.equals("Destination")) {
- if (xmlLast == null && xmlNames != null)
- return;
- else
- throw new RuntimeException("Destination end tag out of place.");
- }
- if (!tag.equals("Name"))
- throw new RuntimeException("Invalid end tag - " + tag);
- if (xmlLast == null || xmlNames == null)
- throw new RuntimeException("Name end tag out of place.");
- if (!xmlLast.containsKey("Page"))
- throw new RuntimeException("Page attribute missing.");
- xmlNames.put(unEscapeBinaryString((String)xmlLast.get("Name")), xmlLast.get("Page"));
- xmlLast = null;
- }
-
- public void startDocument() {
- }
-
- public void startElement(String tag, HashMap h) {
- if (xmlNames == null) {
- if (tag.equals("Destination")) {
- xmlNames = new HashMap();
- return;
- }
- else
- throw new RuntimeException("Root element is not Destination.");
- }
- if (!tag.equals("Name"))
- throw new RuntimeException("Tag " + tag + " not allowed.");
- if (xmlLast != null)
- throw new RuntimeException("Nested tags are not allowed.");
- xmlLast = new HashMap(h);
- xmlLast.put("Name", "");
- }
-
- public void text(String str) {
- if (xmlLast == null)
- return;
- String name = (String)xmlLast.get("Name");
- name += str;
- xmlLast.put("Name", name);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandler.java b/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandler.java
deleted file mode 100644
index 152b894..0000000
--- a/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandler.java
+++ /dev/null
@@ -1,80 +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.util.HashMap;
-
-/**
- * The handler for the events fired by <CODE>SimpleXMLParser</CODE>.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public interface SimpleXMLDocHandler {
- /**
- * Called when a start tag is found.
- * @param tag the tag name
- * @param h the tag's attributes
- */
- public void startElement(String tag, HashMap h);
- /**
- * Called when an end tag is found.
- * @param tag the tag name
- */
- public void endElement(String tag);
- /**
- * Called when the document starts to be parsed.
- */
- public void startDocument();
- /**
- * Called after the document is parsed.
- */
- public void endDocument();
- /**
- * Called when a text element is found.
- * @param str the text element, probably a fragment.
- */
- public void text(String str);
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandlerComment.java b/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandlerComment.java
deleted file mode 100644
index 4d2ceb9..0000000
--- a/src/main/java/com/lowagie/text/pdf/SimpleXMLDocHandlerComment.java
+++ /dev/null
@@ -1,59 +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 handler for the events fired by <CODE>SimpleXMLParser</CODE>.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public interface SimpleXMLDocHandlerComment {
- /**
- * Called when a comment is found.
- * @param text the comment text
- */
- public void comment(String text);
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/SimpleXMLParser.java b/src/main/java/com/lowagie/text/pdf/SimpleXMLParser.java
deleted file mode 100644
index b00c2d7..0000000
--- a/src/main/java/com/lowagie/text/pdf/SimpleXMLParser.java
+++ /dev/null
@@ -1,1177 +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.util.Stack;
-import java.util.HashMap;
-
-/**
- * A simple XML and HTML parser. This parser is, like the SAX parser,
- * an event based parser, but with much less functionality.
- * <p>
- * The parser can:
- * <p>
- * <ul>
- * <li>It recognizes the encoding used
- * <li>It recognizes all the elements' start tags and end tags
- * <li>It lists attributes, where attribute values can be enclosed in single or double quotes
- * <li>It recognizes the <code>&lt;[CDATA[ ... ]]&gt;</code> construct
- * <li>It recognizes the standard entities: &amp;amp;, &amp;lt;, &amp;gt;, &amp;quot;, and &amp;apos;, as well as numeric entities
- * <li>It maps lines ending in <code>\r\n</code> and <code>\r</code> to <code>\n</code> on input, in accordance with the XML Specification, Section 2.11
- * </ul>
- * <p>
- * The code is based on <A HREF="http://www.javaworld.com/javaworld/javatips/javatip128/">
- * http://www.javaworld.com/javaworld/javatips/javatip128/</A> with some extra
- * code from XERCES to recognize the encoding.
- */
-public class SimpleXMLParser {
- private static final HashMap fIANA2JavaMap = new HashMap();
- private static final HashMap entityMap = new HashMap();
-
- private static int popMode(Stack st) {
- if(!st.empty())
- return ((Integer)st.pop()).intValue();
- else
- return PRE;
- }
-
- private final static int
- TEXT = 1,
- ENTITY = 2,
- OPEN_TAG = 3,
- CLOSE_TAG = 4,
- START_TAG = 5,
- ATTRIBUTE_LVALUE = 6,
- ATTRIBUTE_EQUAL = 9,
- ATTRIBUTE_RVALUE = 10,
- QUOTE = 7,
- IN_TAG = 8,
- SINGLE_TAG = 12,
- COMMENT = 13,
- DONE = 11,
- DOCTYPE = 14,
- PRE = 15,
- CDATA = 16;
-
- private SimpleXMLParser() {
- }
-
- /**
- * Parses the XML document firing the events to the handler.
- * @param doc the document handler
- * @param in the document. The encoding is deduced from the stream. The stream is not closed
- * @throws IOException on error
- */
- public static void parse(SimpleXMLDocHandler doc, InputStream in) throws IOException {
- byte b4[] = new byte[4];
- int count = in.read(b4);
- if (count != 4)
- throw new IOException("Insufficient length.");
- String encoding = getEncodingName(b4);
- String decl = null;
- if (encoding.equals("UTF-8")) {
- StringBuffer sb = new StringBuffer();
- int c;
- while ((c = in.read()) != -1) {
- if (c == '>')
- break;
- sb.append((char)c);
- }
- decl = sb.toString();
- }
- else if (encoding.equals("CP037")) {
- ByteArrayOutputStream bi = new ByteArrayOutputStream();
- int c;
- while ((c = in.read()) != -1) {
- if (c == 0x6e) // that's '>' in ebcdic
- break;
- bi.write(c);
- }
- decl = new String(bi.toByteArray(), "CP037");
- }
- if (decl != null) {
- decl = getDeclaredEncoding(decl);
- if (decl != null)
- encoding = decl;
- }
- parse(doc, new InputStreamReader(in, getJavaEncoding(encoding)));
- }
-
- private static String getDeclaredEncoding(String decl) {
- if (decl == null)
- return null;
- int idx = decl.indexOf("encoding");
- if (idx < 0)
- return null;
- int idx1 = decl.indexOf('"', idx);
- int idx2 = decl.indexOf('\'', idx);
- if (idx1 == idx2)
- return null;
- if ((idx1 < 0 && idx2 > 0) || (idx2 > 0 && idx2 < idx1)) {
- int idx3 = decl.indexOf('\'', idx2 + 1);
- if (idx3 < 0)
- return null;
- return decl.substring(idx2 + 1, idx3);
- }
- if ((idx2 < 0 && idx1 > 0) || (idx1 > 0 && idx1 < idx2)) {
- int idx3 = decl.indexOf('"', idx1 + 1);
- if (idx3 < 0)
- return null;
- return decl.substring(idx1 + 1, idx3);
- }
- return null;
- }
-
- /**
- * Gets the java encoding from the IANA encoding. If the encoding cannot be found
- * it returns the input.
- * @param iana the IANA encoding
- * @return the java encoding
- */
- public static String getJavaEncoding(String iana) {
- String IANA = iana.toUpperCase();
- String jdec = (String)fIANA2JavaMap.get(IANA);
- if (jdec == null)
- jdec = iana;
- return jdec;
- }
-
- public static void parse(SimpleXMLDocHandler doc,Reader r) throws IOException {
- parse(doc, null, r, false);
- }
-
- /**
- * Parses the XML document firing the events to the handler.
- * @param doc the document handler
- * @param r the document. The encoding is already resolved. The reader is not closed
- * @throws IOException on error
- */
- public static void parse(SimpleXMLDocHandler doc, SimpleXMLDocHandlerComment comment, Reader r, boolean html) throws IOException {
- BufferedReader reader;
- if (r instanceof BufferedReader)
- reader = (BufferedReader)r;
- else
- reader = new BufferedReader(r);
- Stack st = new Stack();
- int depth = 0;
- int mode = PRE;
- int c = 0;
- int quotec = '"';
- depth = 0;
- StringBuffer sb = new StringBuffer();
- StringBuffer etag = new StringBuffer();
- String tagName = null;
- String lvalue = null;
- String rvalue = null;
- HashMap attrs = null;
- st = new Stack();
- doc.startDocument();
- int line=1, col=0;
- boolean eol = false;
- if (html)
- mode = TEXT;
- int pushBack = -1;
- while(true) {
- if (pushBack != -1) {
- c = pushBack;
- pushBack = -1;
- }
- else
- c = reader.read();
- if (c == -1)
- break;
-
- // We need to map \r, \r\n, and \n to \n
- // See XML spec section 2.11
- if(c == '\n' && eol) {
- eol = false;
- continue;
- } else if(eol) {
- eol = false;
- } else if(c == '\n') {
- line++;
- col=0;
- } else if(c == '\r') {
- eol = true;
- c = '\n';
- line++;
- col=0;
- } else {
- col++;
- }
-
- if(mode == DONE) {
- doc.endDocument();
- return;
-
- // We are between tags collecting text.
- } else if(mode == TEXT) {
- if(c == '<') {
- st.push(new Integer(mode));
- mode = START_TAG;
- if(sb.length() > 0) {
- doc.text(sb.toString());
- sb.setLength(0);
- }
- } else if(c == '&') {
- st.push(new Integer(mode));
- mode = ENTITY;
- etag.setLength(0);
- } else
- sb.append((char)c);
-
- // we are processing a closing tag: e.g. </foo>
- } else if(mode == CLOSE_TAG) {
- if(c == '>') {
- mode = popMode(st);
- tagName = sb.toString();
- if (html)
- tagName = tagName.toLowerCase();
- sb.setLength(0);
- depth--;
- if(!html && depth==0)
- mode = DONE;
- doc.endElement(tagName);
- } else {
- if (!Character.isWhitespace((char)c))
- sb.append((char)c);
- }
-
- // we are processing CDATA
- } else if(mode == CDATA) {
- if(c == '>'
- && sb.toString().endsWith("]]")) {
- sb.setLength(sb.length()-2);
- doc.text(sb.toString());
- sb.setLength(0);
- mode = popMode(st);
- } else
- sb.append((char)c);
-
- // we are processing a comment. We are inside
- // the <!-- .... --> looking for the -->.
- } else if(mode == COMMENT) {
- if(c == '>'
- && sb.toString().endsWith("--")) {
- if (comment != null) {
- sb.setLength(sb.length() - 2);
- comment.comment(sb.toString());
- }
- sb.setLength(0);
- mode = popMode(st);
- } else
- sb.append((char)c);
-
- // We are outside the root tag element
- } else if(mode == PRE) {
- if(c == '<') {
- mode = TEXT;
- st.push(new Integer(mode));
- mode = START_TAG;
- }
-
- // We are inside one of these <? ... ?>
- // or one of these <!DOCTYPE ... >
- } else if(mode == DOCTYPE) {
- if(c == '>') {
- mode = popMode(st);
- if(mode == TEXT) mode = PRE;
- }
-
- // we have just seen a < and
- // are wondering what we are looking at
- // <foo>, </foo>, <!-- ... --->, etc.
- } else if(mode == START_TAG) {
- mode = popMode(st);
- if(c == '/') {
- st.push(new Integer(mode));
- mode = CLOSE_TAG;
- } else if (c == '?') {
- mode = DOCTYPE;
- } else {
- st.push(new Integer(mode));
- mode = OPEN_TAG;
- tagName = null;
- attrs = new HashMap();
- sb.append((char)c);
- }
-
- // we are processing an entity, e.g. &lt;, &#187;, etc.
- } else if(mode == ENTITY) {
- if(c == ';') {
- mode = popMode(st);
- String cent = etag.toString();
- etag.setLength(0);
- if(cent.startsWith("#x")) {
- try {
- char ci = (char)Integer.parseInt(cent.substring(2),16);
- sb.append(ci);
- }
- catch (Exception es) {
- sb.append('&').append(cent).append(';');
- }
- }
- else if(cent.startsWith("#")) {
- try {
- char ci = (char)Integer.parseInt(cent.substring(1));
- sb.append(ci);
- }
- catch (Exception es) {
- sb.append('&').append(cent).append(';');
- }
- }
- else {
- char ce = decodeEntity(cent);
- if (ce == '\0')
- sb.append('&').append(cent).append(';');
- else
- sb.append(ce);
- }
- } else if ((c != '#' && (c < '0' || c > '9') && (c < 'a' || c > 'z')
- && (c < 'A' || c > 'Z')) || etag.length() >= 7) {
- mode = popMode(st);
- pushBack = c;
- sb.append('&').append(etag.toString());
- etag.setLength(0);
- }
- else {
- etag.append((char)c);
- }
-
- // we have just seen something like this:
- // <foo a="b"/
- // and are looking for the final >.
- } else if(mode == SINGLE_TAG) {
- if(tagName == null)
- tagName = sb.toString();
- if (html)
- tagName = tagName.toLowerCase();
- if(c != '>')
- exc("Expected > for tag: <"+tagName+"/>",line,col);
- doc.startElement(tagName,attrs);
- doc.endElement(tagName);
- if(!html && depth==0) {
- doc.endDocument();
- return;
- }
- sb.setLength(0);
- attrs = new HashMap();
- tagName = null;
- mode = popMode(st);
-
- // we are processing something
- // like this <foo ... >. It could
- // still be a <!-- ... --> or something.
- } else if(mode == OPEN_TAG) {
- if(c == '>') {
- if(tagName == null)
- tagName = sb.toString();
- if (html)
- tagName = tagName.toLowerCase();
- sb.setLength(0);
- depth++;
- doc.startElement(tagName,attrs);
- tagName = null;
- attrs = new HashMap();
- mode = popMode(st);
- } else if(c == '/') {
- mode = SINGLE_TAG;
- } else if(c == '-' && sb.toString().equals("!-")) {
- mode = COMMENT;
- sb.setLength(0);
- } else if(c == '[' && sb.toString().equals("![CDATA")) {
- mode = CDATA;
- sb.setLength(0);
- } else if(c == 'E' && sb.toString().equals("!DOCTYP")) {
- sb.setLength(0);
- mode = DOCTYPE;
- } else if(Character.isWhitespace((char)c)) {
- tagName = sb.toString();
- if (html)
- tagName = tagName.toLowerCase();
- sb.setLength(0);
- mode = IN_TAG;
- } else {
- sb.append((char)c);
- }
-
- // We are processing the quoted right-hand side
- // of an element's attribute.
- } else if(mode == QUOTE) {
- if (html && quotec == ' ' && c == '>') {
- rvalue = sb.toString();
- sb.setLength(0);
- attrs.put(lvalue,rvalue);
- mode = popMode(st);
- doc.startElement(tagName,attrs);
- depth++;
- tagName = null;
- attrs = new HashMap();
- }
- else if (html && quotec == ' ' && Character.isWhitespace((char)c)) {
- rvalue = sb.toString();
- sb.setLength(0);
- attrs.put(lvalue,rvalue);
- mode = IN_TAG;
- }
- else if (html && quotec == ' ') {
- sb.append((char)c);
- }
- else if(c == quotec) {
- rvalue = sb.toString();
- sb.setLength(0);
- attrs.put(lvalue,rvalue);
- mode = IN_TAG;
- // See section the XML spec, section 3.3.3
- // on normalization processing.
- } else if(" \r\n\u0009".indexOf(c)>=0) {
- sb.append(' ');
- } else if(c == '&') {
- st.push(new Integer(mode));
- mode = ENTITY;
- etag.setLength(0);
- } else {
- sb.append((char)c);
- }
-
- } else if(mode == ATTRIBUTE_RVALUE) {
- if(c == '"' || c == '\'') {
- quotec = c;
- mode = QUOTE;
- } else if(Character.isWhitespace((char)c)) {
- ;
- } else if (html && c == '>') {
- attrs.put(lvalue,sb.toString());
- sb.setLength(0);
- mode = popMode(st);
- doc.startElement(tagName,attrs);
- depth++;
- tagName = null;
- attrs = new HashMap();
- } else if (html) {
- sb.append((char)c);
- quotec = ' ';
- mode = QUOTE;
- } else {
- exc("Error in attribute processing",line,col);
- }
-
- } else if(mode == ATTRIBUTE_LVALUE) {
- if(Character.isWhitespace((char)c)) {
- lvalue = sb.toString();
- if (html)
- lvalue = lvalue.toLowerCase();
- sb.setLength(0);
- mode = ATTRIBUTE_EQUAL;
- } else if(c == '=') {
- lvalue = sb.toString();
- if (html)
- lvalue = lvalue.toLowerCase();
- sb.setLength(0);
- mode = ATTRIBUTE_RVALUE;
- } else if (html && c == '>') {
- sb.setLength(0);
- mode = popMode(st);
- doc.startElement(tagName,attrs);
- depth++;
- tagName = null;
- attrs = new HashMap();
- } else {
- sb.append((char)c);
- }
-
- } else if(mode == ATTRIBUTE_EQUAL) {
- if(c == '=') {
- mode = ATTRIBUTE_RVALUE;
- } else if(Character.isWhitespace((char)c)) {
- ;
- } else if (html && c == '>') {
- sb.setLength(0);
- mode = popMode(st);
- doc.startElement(tagName,attrs);
- depth++;
- tagName = null;
- attrs = new HashMap();
- } else if (html && c == '/') {
- sb.setLength(0);
- mode = SINGLE_TAG;
- } else if (html) {
- sb.setLength(0);
- sb.append((char)c);
- mode = ATTRIBUTE_LVALUE;
- } else {
- exc("Error in attribute processing.",line,col);
- }
-
- } else if(mode == IN_TAG) {
- if(c == '>') {
- mode = popMode(st);
- doc.startElement(tagName,attrs);
- depth++;
- tagName = null;
- attrs = new HashMap();
- } else if(c == '/') {
- mode = SINGLE_TAG;
- } else if(Character.isWhitespace((char)c)) {
- ;
- } else {
- mode = ATTRIBUTE_LVALUE;
- sb.append((char)c);
- }
- }
- }
- if(html || mode == DONE) {
- if (html && mode == TEXT)
- doc.text(sb.toString());
- doc.endDocument();
- }
- else
- exc("missing end tag",line,col);
- }
- private static void exc(String s,int line,int col) throws IOException {
- throw new IOException(s+" near line "+line+", column "+col);
- }
-
- /**
- * Escapes a string with the appropriated XML codes.
- * @param s the string to be escaped
- * @param onlyASCII codes above 127 will always be escaped with &amp;#nn; if <CODE>true</CODE>
- * @return the escaped string
- */
- public static String escapeXML(String s, boolean onlyASCII) {
- char cc[] = s.toCharArray();
- int len = cc.length;
- StringBuffer sb = new StringBuffer();
- for (int k = 0; k < len; ++k) {
- int c = cc[k];
- switch (c) {
- case '<':
- sb.append("&lt;");
- break;
- case '>':
- sb.append("&gt;");
- break;
- case '&':
- sb.append("&amp;");
- break;
- case '"':
- sb.append("&quot;");
- break;
- case '\'':
- sb.append("&apos;");
- break;
- default:
- if (onlyASCII && c > 127)
- sb.append("&#").append(c).append(";");
- else
- sb.append((char)c);
- }
- }
- return sb.toString();
- }
-
- public static char decodeEntity(String s) {
- Character c = (Character)entityMap.get(s);
- if (c == null)
- return '\0';
- else
- return c.charValue();
- }
-
- private static String getEncodingName(byte[] b4) {
-
- // UTF-16, with BOM
- int b0 = b4[0] & 0xFF;
- int b1 = b4[1] & 0xFF;
- if (b0 == 0xFE && b1 == 0xFF) {
- // UTF-16, big-endian
- return "UTF-16BE";
- }
- if (b0 == 0xFF && b1 == 0xFE) {
- // UTF-16, little-endian
- return "UTF-16LE";
- }
-
- // UTF-8 with a BOM
- int b2 = b4[2] & 0xFF;
- if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) {
- return "UTF-8";
- }
-
- // other encodings
- int b3 = b4[3] & 0xFF;
- if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) {
- // UCS-4, big endian (1234)
- return "ISO-10646-UCS-4";
- }
- if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) {
- // UCS-4, little endian (4321)
- return "ISO-10646-UCS-4";
- }
- if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) {
- // UCS-4, unusual octet order (2143)
- // REVISIT: What should this be?
- return "ISO-10646-UCS-4";
- }
- if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) {
- // UCS-4, unusual octect order (3412)
- // REVISIT: What should this be?
- return "ISO-10646-UCS-4";
- }
- if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) {
- // UTF-16, big-endian, no BOM
- // (or could turn out to be UCS-2...
- // REVISIT: What should this be?
- return "UTF-16BE";
- }
- if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) {
- // UTF-16, little-endian, no BOM
- // (or could turn out to be UCS-2...
- return "UTF-16LE";
- }
- if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) {
- // EBCDIC
- // a la xerces1, return CP037 instead of EBCDIC here
- return "CP037";
- }
-
- // default encoding
- return "UTF-8";
- }
-
- static {
- // add IANA to Java encoding mappings.
- fIANA2JavaMap.put("BIG5", "Big5");
- fIANA2JavaMap.put("CSBIG5", "Big5");
- fIANA2JavaMap.put("CP037", "CP037");
- fIANA2JavaMap.put("IBM037", "CP037");
- fIANA2JavaMap.put("CSIBM037", "CP037");
- fIANA2JavaMap.put("EBCDIC-CP-US", "CP037");
- fIANA2JavaMap.put("EBCDIC-CP-CA", "CP037");
- fIANA2JavaMap.put("EBCDIC-CP-NL", "CP037");
- fIANA2JavaMap.put("EBCDIC-CP-WT", "CP037");
- fIANA2JavaMap.put("IBM277", "CP277");
- fIANA2JavaMap.put("CP277", "CP277");
- fIANA2JavaMap.put("CSIBM277", "CP277");
- fIANA2JavaMap.put("EBCDIC-CP-DK", "CP277");
- fIANA2JavaMap.put("EBCDIC-CP-NO", "CP277");
- fIANA2JavaMap.put("IBM278", "CP278");
- fIANA2JavaMap.put("CP278", "CP278");
- fIANA2JavaMap.put("CSIBM278", "CP278");
- fIANA2JavaMap.put("EBCDIC-CP-FI", "CP278");
- fIANA2JavaMap.put("EBCDIC-CP-SE", "CP278");
- fIANA2JavaMap.put("IBM280", "CP280");
- fIANA2JavaMap.put("CP280", "CP280");
- fIANA2JavaMap.put("CSIBM280", "CP280");
- fIANA2JavaMap.put("EBCDIC-CP-IT", "CP280");
- fIANA2JavaMap.put("IBM284", "CP284");
- fIANA2JavaMap.put("CP284", "CP284");
- fIANA2JavaMap.put("CSIBM284", "CP284");
- fIANA2JavaMap.put("EBCDIC-CP-ES", "CP284");
- fIANA2JavaMap.put("EBCDIC-CP-GB", "CP285");
- fIANA2JavaMap.put("IBM285", "CP285");
- fIANA2JavaMap.put("CP285", "CP285");
- fIANA2JavaMap.put("CSIBM285", "CP285");
- fIANA2JavaMap.put("EBCDIC-CP-FR", "CP297");
- fIANA2JavaMap.put("IBM297", "CP297");
- fIANA2JavaMap.put("CP297", "CP297");
- fIANA2JavaMap.put("CSIBM297", "CP297");
- fIANA2JavaMap.put("EBCDIC-CP-AR1", "CP420");
- fIANA2JavaMap.put("IBM420", "CP420");
- fIANA2JavaMap.put("CP420", "CP420");
- fIANA2JavaMap.put("CSIBM420", "CP420");
- fIANA2JavaMap.put("EBCDIC-CP-HE", "CP424");
- fIANA2JavaMap.put("IBM424", "CP424");
- fIANA2JavaMap.put("CP424", "CP424");
- fIANA2JavaMap.put("CSIBM424", "CP424");
- fIANA2JavaMap.put("EBCDIC-CP-CH", "CP500");
- fIANA2JavaMap.put("IBM500", "CP500");
- fIANA2JavaMap.put("CP500", "CP500");
- fIANA2JavaMap.put("CSIBM500", "CP500");
- fIANA2JavaMap.put("EBCDIC-CP-CH", "CP500");
- fIANA2JavaMap.put("EBCDIC-CP-BE", "CP500");
- fIANA2JavaMap.put("IBM868", "CP868");
- fIANA2JavaMap.put("CP868", "CP868");
- fIANA2JavaMap.put("CSIBM868", "CP868");
- fIANA2JavaMap.put("CP-AR", "CP868");
- fIANA2JavaMap.put("IBM869", "CP869");
- fIANA2JavaMap.put("CP869", "CP869");
- fIANA2JavaMap.put("CSIBM869", "CP869");
- fIANA2JavaMap.put("CP-GR", "CP869");
- fIANA2JavaMap.put("IBM870", "CP870");
- fIANA2JavaMap.put("CP870", "CP870");
- fIANA2JavaMap.put("CSIBM870", "CP870");
- fIANA2JavaMap.put("EBCDIC-CP-ROECE", "CP870");
- fIANA2JavaMap.put("EBCDIC-CP-YU", "CP870");
- fIANA2JavaMap.put("IBM871", "CP871");
- fIANA2JavaMap.put("CP871", "CP871");
- fIANA2JavaMap.put("CSIBM871", "CP871");
- fIANA2JavaMap.put("EBCDIC-CP-IS", "CP871");
- fIANA2JavaMap.put("IBM918", "CP918");
- fIANA2JavaMap.put("CP918", "CP918");
- fIANA2JavaMap.put("CSIBM918", "CP918");
- fIANA2JavaMap.put("EBCDIC-CP-AR2", "CP918");
- fIANA2JavaMap.put("EUC-JP", "EUCJIS");
- fIANA2JavaMap.put("CSEUCPkdFmtJapanese", "EUCJIS");
- fIANA2JavaMap.put("EUC-KR", "KSC5601");
- fIANA2JavaMap.put("GB2312", "GB2312");
- fIANA2JavaMap.put("CSGB2312", "GB2312");
- fIANA2JavaMap.put("ISO-2022-JP", "JIS");
- fIANA2JavaMap.put("CSISO2022JP", "JIS");
- fIANA2JavaMap.put("ISO-2022-KR", "ISO2022KR");
- fIANA2JavaMap.put("CSISO2022KR", "ISO2022KR");
- fIANA2JavaMap.put("ISO-2022-CN", "ISO2022CN");
-
- fIANA2JavaMap.put("X0201", "JIS0201");
- fIANA2JavaMap.put("CSISO13JISC6220JP", "JIS0201");
- fIANA2JavaMap.put("X0208", "JIS0208");
- fIANA2JavaMap.put("ISO-IR-87", "JIS0208");
- fIANA2JavaMap.put("X0208dbiJIS_X0208-1983", "JIS0208");
- fIANA2JavaMap.put("CSISO87JISX0208", "JIS0208");
- fIANA2JavaMap.put("X0212", "JIS0212");
- fIANA2JavaMap.put("ISO-IR-159", "JIS0212");
- fIANA2JavaMap.put("CSISO159JISX02121990", "JIS0212");
- fIANA2JavaMap.put("SHIFT_JIS", "SJIS");
- fIANA2JavaMap.put("CSSHIFT_JIS", "SJIS");
- fIANA2JavaMap.put("MS_Kanji", "SJIS");
-
- // Add support for Cp1252 and its friends
- fIANA2JavaMap.put("WINDOWS-1250", "Cp1250");
- fIANA2JavaMap.put("WINDOWS-1251", "Cp1251");
- fIANA2JavaMap.put("WINDOWS-1252", "Cp1252");
- fIANA2JavaMap.put("WINDOWS-1253", "Cp1253");
- fIANA2JavaMap.put("WINDOWS-1254", "Cp1254");
- fIANA2JavaMap.put("WINDOWS-1255", "Cp1255");
- fIANA2JavaMap.put("WINDOWS-1256", "Cp1256");
- fIANA2JavaMap.put("WINDOWS-1257", "Cp1257");
- fIANA2JavaMap.put("WINDOWS-1258", "Cp1258");
- fIANA2JavaMap.put("TIS-620", "TIS620");
-
- fIANA2JavaMap.put("ISO-8859-1", "ISO8859_1");
- fIANA2JavaMap.put("ISO-IR-100", "ISO8859_1");
- fIANA2JavaMap.put("ISO_8859-1", "ISO8859_1");
- fIANA2JavaMap.put("LATIN1", "ISO8859_1");
- fIANA2JavaMap.put("CSISOLATIN1", "ISO8859_1");
- fIANA2JavaMap.put("L1", "ISO8859_1");
- fIANA2JavaMap.put("IBM819", "ISO8859_1");
- fIANA2JavaMap.put("CP819", "ISO8859_1");
-
- fIANA2JavaMap.put("ISO-8859-2", "ISO8859_2");
- fIANA2JavaMap.put("ISO-IR-101", "ISO8859_2");
- fIANA2JavaMap.put("ISO_8859-2", "ISO8859_2");
- fIANA2JavaMap.put("LATIN2", "ISO8859_2");
- fIANA2JavaMap.put("CSISOLATIN2", "ISO8859_2");
- fIANA2JavaMap.put("L2", "ISO8859_2");
-
- fIANA2JavaMap.put("ISO-8859-3", "ISO8859_3");
- fIANA2JavaMap.put("ISO-IR-109", "ISO8859_3");
- fIANA2JavaMap.put("ISO_8859-3", "ISO8859_3");
- fIANA2JavaMap.put("LATIN3", "ISO8859_3");
- fIANA2JavaMap.put("CSISOLATIN3", "ISO8859_3");
- fIANA2JavaMap.put("L3", "ISO8859_3");
-
- fIANA2JavaMap.put("ISO-8859-4", "ISO8859_4");
- fIANA2JavaMap.put("ISO-IR-110", "ISO8859_4");
- fIANA2JavaMap.put("ISO_8859-4", "ISO8859_4");
- fIANA2JavaMap.put("LATIN4", "ISO8859_4");
- fIANA2JavaMap.put("CSISOLATIN4", "ISO8859_4");
- fIANA2JavaMap.put("L4", "ISO8859_4");
-
- fIANA2JavaMap.put("ISO-8859-5", "ISO8859_5");
- fIANA2JavaMap.put("ISO-IR-144", "ISO8859_5");
- fIANA2JavaMap.put("ISO_8859-5", "ISO8859_5");
- fIANA2JavaMap.put("CYRILLIC", "ISO8859_5");
- fIANA2JavaMap.put("CSISOLATINCYRILLIC", "ISO8859_5");
-
- fIANA2JavaMap.put("ISO-8859-6", "ISO8859_6");
- fIANA2JavaMap.put("ISO-IR-127", "ISO8859_6");
- fIANA2JavaMap.put("ISO_8859-6", "ISO8859_6");
- fIANA2JavaMap.put("ECMA-114", "ISO8859_6");
- fIANA2JavaMap.put("ASMO-708", "ISO8859_6");
- fIANA2JavaMap.put("ARABIC", "ISO8859_6");
- fIANA2JavaMap.put("CSISOLATINARABIC", "ISO8859_6");
-
- fIANA2JavaMap.put("ISO-8859-7", "ISO8859_7");
- fIANA2JavaMap.put("ISO-IR-126", "ISO8859_7");
- fIANA2JavaMap.put("ISO_8859-7", "ISO8859_7");
- fIANA2JavaMap.put("ELOT_928", "ISO8859_7");
- fIANA2JavaMap.put("ECMA-118", "ISO8859_7");
- fIANA2JavaMap.put("GREEK", "ISO8859_7");
- fIANA2JavaMap.put("CSISOLATINGREEK", "ISO8859_7");
- fIANA2JavaMap.put("GREEK8", "ISO8859_7");
-
- fIANA2JavaMap.put("ISO-8859-8", "ISO8859_8");
- fIANA2JavaMap.put("ISO-8859-8-I", "ISO8859_8"); // added since this encoding only differs w.r.t. presentation
- fIANA2JavaMap.put("ISO-IR-138", "ISO8859_8");
- fIANA2JavaMap.put("ISO_8859-8", "ISO8859_8");
- fIANA2JavaMap.put("HEBREW", "ISO8859_8");
- fIANA2JavaMap.put("CSISOLATINHEBREW", "ISO8859_8");
-
- fIANA2JavaMap.put("ISO-8859-9", "ISO8859_9");
- fIANA2JavaMap.put("ISO-IR-148", "ISO8859_9");
- fIANA2JavaMap.put("ISO_8859-9", "ISO8859_9");
- fIANA2JavaMap.put("LATIN5", "ISO8859_9");
- fIANA2JavaMap.put("CSISOLATIN5", "ISO8859_9");
- fIANA2JavaMap.put("L5", "ISO8859_9");
-
- fIANA2JavaMap.put("KOI8-R", "KOI8_R");
- fIANA2JavaMap.put("CSKOI8-R", "KOI8_R");
- fIANA2JavaMap.put("US-ASCII", "ASCII");
- fIANA2JavaMap.put("ISO-IR-6", "ASCII");
- fIANA2JavaMap.put("ANSI_X3.4-1986", "ASCII");
- fIANA2JavaMap.put("ISO_646.IRV:1991", "ASCII");
- fIANA2JavaMap.put("ASCII", "ASCII");
- fIANA2JavaMap.put("CSASCII", "ASCII");
- fIANA2JavaMap.put("ISO646-US", "ASCII");
- fIANA2JavaMap.put("US", "ASCII");
- fIANA2JavaMap.put("IBM367", "ASCII");
- fIANA2JavaMap.put("CP367", "ASCII");
- fIANA2JavaMap.put("UTF-8", "UTF8");
- fIANA2JavaMap.put("UTF-16", "Unicode");
- fIANA2JavaMap.put("UTF-16BE", "UnicodeBig");
- fIANA2JavaMap.put("UTF-16LE", "UnicodeLittle");
-
- entityMap.put("nbsp", new Character('\u00a0')); // no-break space = non-breaking space, U+00A0 ISOnum
- entityMap.put("iexcl", new Character('\u00a1')); // inverted exclamation mark, U+00A1 ISOnum
- entityMap.put("cent", new Character('\u00a2')); // cent sign, U+00A2 ISOnum
- entityMap.put("pound", new Character('\u00a3')); // pound sign, U+00A3 ISOnum
- entityMap.put("curren", new Character('\u00a4')); // currency sign, U+00A4 ISOnum
- entityMap.put("yen", new Character('\u00a5')); // yen sign = yuan sign, U+00A5 ISOnum
- entityMap.put("brvbar", new Character('\u00a6')); // broken bar = broken vertical bar, U+00A6 ISOnum
- entityMap.put("sect", new Character('\u00a7')); // section sign, U+00A7 ISOnum
- entityMap.put("uml", new Character('\u00a8')); // diaeresis = spacing diaeresis, U+00A8 ISOdia
- entityMap.put("copy", new Character('\u00a9')); // copyright sign, U+00A9 ISOnum
- entityMap.put("ordf", new Character('\u00aa')); // feminine ordinal indicator, U+00AA ISOnum
- entityMap.put("laquo", new Character('\u00ab')); // left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum
- entityMap.put("not", new Character('\u00ac')); // not sign, U+00AC ISOnum
- entityMap.put("shy", new Character('\u00ad')); // soft hyphen = discretionary hyphen, U+00AD ISOnum
- entityMap.put("reg", new Character('\u00ae')); // registered sign = registered trade mark sign, U+00AE ISOnum
- entityMap.put("macr", new Character('\u00af')); // macron = spacing macron = overline = APL overbar, U+00AF ISOdia
- entityMap.put("deg", new Character('\u00b0')); // degree sign, U+00B0 ISOnum
- entityMap.put("plusmn", new Character('\u00b1')); // plus-minus sign = plus-or-minus sign, U+00B1 ISOnum
- entityMap.put("sup2", new Character('\u00b2')); // superscript two = superscript digit two = squared, U+00B2 ISOnum
- entityMap.put("sup3", new Character('\u00b3')); // superscript three = superscript digit three = cubed, U+00B3 ISOnum
- entityMap.put("acute", new Character('\u00b4')); // acute accent = spacing acute, U+00B4 ISOdia
- entityMap.put("micro", new Character('\u00b5')); // micro sign, U+00B5 ISOnum
- entityMap.put("para", new Character('\u00b6')); // pilcrow sign = paragraph sign, U+00B6 ISOnum
- entityMap.put("middot", new Character('\u00b7')); // middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum
- entityMap.put("cedil", new Character('\u00b8')); // cedilla = spacing cedilla, U+00B8 ISOdia
- entityMap.put("sup1", new Character('\u00b9')); // superscript one = superscript digit one, U+00B9 ISOnum
- entityMap.put("ordm", new Character('\u00ba')); // masculine ordinal indicator, U+00BA ISOnum
- entityMap.put("raquo", new Character('\u00bb')); // right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum
- entityMap.put("frac14", new Character('\u00bc')); // vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum
- entityMap.put("frac12", new Character('\u00bd')); // vulgar fraction one half = fraction one half, U+00BD ISOnum
- entityMap.put("frac34", new Character('\u00be')); // vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum
- entityMap.put("iquest", new Character('\u00bf')); // inverted question mark = turned question mark, U+00BF ISOnum
- entityMap.put("Agrave", new Character('\u00c0')); // latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1
- entityMap.put("Aacute", new Character('\u00c1')); // latin capital letter A with acute, U+00C1 ISOlat1
- entityMap.put("Acirc", new Character('\u00c2')); // latin capital letter A with circumflex, U+00C2 ISOlat1
- entityMap.put("Atilde", new Character('\u00c3')); // latin capital letter A with tilde, U+00C3 ISOlat1
- entityMap.put("Auml", new Character('\u00c4')); // latin capital letter A with diaeresis, U+00C4 ISOlat1
- entityMap.put("Aring", new Character('\u00c5')); // latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1
- entityMap.put("AElig", new Character('\u00c6')); // latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1
- entityMap.put("Ccedil", new Character('\u00c7')); // latin capital letter C with cedilla, U+00C7 ISOlat1
- entityMap.put("Egrave", new Character('\u00c8')); // latin capital letter E with grave, U+00C8 ISOlat1
- entityMap.put("Eacute", new Character('\u00c9')); // latin capital letter E with acute, U+00C9 ISOlat1
- entityMap.put("Ecirc", new Character('\u00ca')); // latin capital letter E with circumflex, U+00CA ISOlat1
- entityMap.put("Euml", new Character('\u00cb')); // latin capital letter E with diaeresis, U+00CB ISOlat1
- entityMap.put("Igrave", new Character('\u00cc')); // latin capital letter I with grave, U+00CC ISOlat1
- entityMap.put("Iacute", new Character('\u00cd')); // latin capital letter I with acute, U+00CD ISOlat1
- entityMap.put("Icirc", new Character('\u00ce')); // latin capital letter I with circumflex, U+00CE ISOlat1
- entityMap.put("Iuml", new Character('\u00cf')); // latin capital letter I with diaeresis, U+00CF ISOlat1
- entityMap.put("ETH", new Character('\u00d0')); // latin capital letter ETH, U+00D0 ISOlat1
- entityMap.put("Ntilde", new Character('\u00d1')); // latin capital letter N with tilde, U+00D1 ISOlat1
- entityMap.put("Ograve", new Character('\u00d2')); // latin capital letter O with grave, U+00D2 ISOlat1
- entityMap.put("Oacute", new Character('\u00d3')); // latin capital letter O with acute, U+00D3 ISOlat1
- entityMap.put("Ocirc", new Character('\u00d4')); // latin capital letter O with circumflex, U+00D4 ISOlat1
- entityMap.put("Otilde", new Character('\u00d5')); // latin capital letter O with tilde, U+00D5 ISOlat1
- entityMap.put("Ouml", new Character('\u00d6')); // latin capital letter O with diaeresis, U+00D6 ISOlat1
- entityMap.put("times", new Character('\u00d7')); // multiplication sign, U+00D7 ISOnum
- entityMap.put("Oslash", new Character('\u00d8')); // latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1
- entityMap.put("Ugrave", new Character('\u00d9')); // latin capital letter U with grave, U+00D9 ISOlat1
- entityMap.put("Uacute", new Character('\u00da')); // latin capital letter U with acute, U+00DA ISOlat1
- entityMap.put("Ucirc", new Character('\u00db')); // latin capital letter U with circumflex, U+00DB ISOlat1
- entityMap.put("Uuml", new Character('\u00dc')); // latin capital letter U with diaeresis, U+00DC ISOlat1
- entityMap.put("Yacute", new Character('\u00dd')); // latin capital letter Y with acute, U+00DD ISOlat1
- entityMap.put("THORN", new Character('\u00de')); // latin capital letter THORN, U+00DE ISOlat1
- entityMap.put("szlig", new Character('\u00df')); // latin small letter sharp s = ess-zed, U+00DF ISOlat1
- entityMap.put("agrave", new Character('\u00e0')); // latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1
- entityMap.put("aacute", new Character('\u00e1')); // latin small letter a with acute, U+00E1 ISOlat1
- entityMap.put("acirc", new Character('\u00e2')); // latin small letter a with circumflex, U+00E2 ISOlat1
- entityMap.put("atilde", new Character('\u00e3')); // latin small letter a with tilde, U+00E3 ISOlat1
- entityMap.put("auml", new Character('\u00e4')); // latin small letter a with diaeresis, U+00E4 ISOlat1
- entityMap.put("aring", new Character('\u00e5')); // latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1
- entityMap.put("aelig", new Character('\u00e6')); // latin small letter ae = latin small ligature ae, U+00E6 ISOlat1
- entityMap.put("ccedil", new Character('\u00e7')); // latin small letter c with cedilla, U+00E7 ISOlat1
- entityMap.put("egrave", new Character('\u00e8')); // latin small letter e with grave, U+00E8 ISOlat1
- entityMap.put("eacute", new Character('\u00e9')); // latin small letter e with acute, U+00E9 ISOlat1
- entityMap.put("ecirc", new Character('\u00ea')); // latin small letter e with circumflex, U+00EA ISOlat1
- entityMap.put("euml", new Character('\u00eb')); // latin small letter e with diaeresis, U+00EB ISOlat1
- entityMap.put("igrave", new Character('\u00ec')); // latin small letter i with grave, U+00EC ISOlat1
- entityMap.put("iacute", new Character('\u00ed')); // latin small letter i with acute, U+00ED ISOlat1
- entityMap.put("icirc", new Character('\u00ee')); // latin small letter i with circumflex, U+00EE ISOlat1
- entityMap.put("iuml", new Character('\u00ef')); // latin small letter i with diaeresis, U+00EF ISOlat1
- entityMap.put("eth", new Character('\u00f0')); // latin small letter eth, U+00F0 ISOlat1
- entityMap.put("ntilde", new Character('\u00f1')); // latin small letter n with tilde, U+00F1 ISOlat1
- entityMap.put("ograve", new Character('\u00f2')); // latin small letter o with grave, U+00F2 ISOlat1
- entityMap.put("oacute", new Character('\u00f3')); // latin small letter o with acute, U+00F3 ISOlat1
- entityMap.put("ocirc", new Character('\u00f4')); // latin small letter o with circumflex, U+00F4 ISOlat1
- entityMap.put("otilde", new Character('\u00f5')); // latin small letter o with tilde, U+00F5 ISOlat1
- entityMap.put("ouml", new Character('\u00f6')); // latin small letter o with diaeresis, U+00F6 ISOlat1
- entityMap.put("divide", new Character('\u00f7')); // division sign, U+00F7 ISOnum
- entityMap.put("oslash", new Character('\u00f8')); // latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1
- entityMap.put("ugrave", new Character('\u00f9')); // latin small letter u with grave, U+00F9 ISOlat1
- entityMap.put("uacute", new Character('\u00fa')); // latin small letter u with acute, U+00FA ISOlat1
- entityMap.put("ucirc", new Character('\u00fb')); // latin small letter u with circumflex, U+00FB ISOlat1
- entityMap.put("uuml", new Character('\u00fc')); // latin small letter u with diaeresis, U+00FC ISOlat1
- entityMap.put("yacute", new Character('\u00fd')); // latin small letter y with acute, U+00FD ISOlat1
- entityMap.put("thorn", new Character('\u00fe')); // latin small letter thorn, U+00FE ISOlat1
- entityMap.put("yuml", new Character('\u00ff')); // latin small letter y with diaeresis, U+00FF ISOlat1
- // Latin Extended-B
- entityMap.put("fnof", new Character('\u0192')); // latin small f with hook = function = florin, U+0192 ISOtech
- // Greek
- entityMap.put("Alpha", new Character('\u0391')); // greek capital letter alpha, U+0391
- entityMap.put("Beta", new Character('\u0392')); // greek capital letter beta, U+0392
- entityMap.put("Gamma", new Character('\u0393')); // greek capital letter gamma, U+0393 ISOgrk3
- entityMap.put("Delta", new Character('\u0394')); // greek capital letter delta, U+0394 ISOgrk3
- entityMap.put("Epsilon", new Character('\u0395')); // greek capital letter epsilon, U+0395
- entityMap.put("Zeta", new Character('\u0396')); // greek capital letter zeta, U+0396
- entityMap.put("Eta", new Character('\u0397')); // greek capital letter eta, U+0397
- entityMap.put("Theta", new Character('\u0398')); // greek capital letter theta, U+0398 ISOgrk3
- entityMap.put("Iota", new Character('\u0399')); // greek capital letter iota, U+0399
- entityMap.put("Kappa", new Character('\u039a')); // greek capital letter kappa, U+039A
- entityMap.put("Lambda", new Character('\u039b')); // greek capital letter lambda, U+039B ISOgrk3
- entityMap.put("Mu", new Character('\u039c')); // greek capital letter mu, U+039C
- entityMap.put("Nu", new Character('\u039d')); // greek capital letter nu, U+039D
- entityMap.put("Xi", new Character('\u039e')); // greek capital letter xi, U+039E ISOgrk3
- entityMap.put("Omicron", new Character('\u039f')); // greek capital letter omicron, U+039F
- entityMap.put("Pi", new Character('\u03a0')); // greek capital letter pi, U+03A0 ISOgrk3
- entityMap.put("Rho", new Character('\u03a1')); // greek capital letter rho, U+03A1
- // there is no Sigmaf, and no U+03A2 character either
- entityMap.put("Sigma", new Character('\u03a3')); // greek capital letter sigma, U+03A3 ISOgrk3
- entityMap.put("Tau", new Character('\u03a4')); // greek capital letter tau, U+03A4
- entityMap.put("Upsilon", new Character('\u03a5')); // greek capital letter upsilon, U+03A5 ISOgrk3
- entityMap.put("Phi", new Character('\u03a6')); // greek capital letter phi, U+03A6 ISOgrk3
- entityMap.put("Chi", new Character('\u03a7')); // greek capital letter chi, U+03A7
- entityMap.put("Psi", new Character('\u03a8')); // greek capital letter psi, U+03A8 ISOgrk3
- entityMap.put("Omega", new Character('\u03a9')); // greek capital letter omega, U+03A9 ISOgrk3
- entityMap.put("alpha", new Character('\u03b1')); // greek small letter alpha, U+03B1 ISOgrk3
- entityMap.put("beta", new Character('\u03b2')); // greek small letter beta, U+03B2 ISOgrk3
- entityMap.put("gamma", new Character('\u03b3')); // greek small letter gamma, U+03B3 ISOgrk3
- entityMap.put("delta", new Character('\u03b4')); // greek small letter delta, U+03B4 ISOgrk3
- entityMap.put("epsilon", new Character('\u03b5')); // greek small letter epsilon, U+03B5 ISOgrk3
- entityMap.put("zeta", new Character('\u03b6')); // greek small letter zeta, U+03B6 ISOgrk3
- entityMap.put("eta", new Character('\u03b7')); // greek small letter eta, U+03B7 ISOgrk3
- entityMap.put("theta", new Character('\u03b8')); // greek small letter theta, U+03B8 ISOgrk3
- entityMap.put("iota", new Character('\u03b9')); // greek small letter iota, U+03B9 ISOgrk3
- entityMap.put("kappa", new Character('\u03ba')); // greek small letter kappa, U+03BA ISOgrk3
- entityMap.put("lambda", new Character('\u03bb')); // greek small letter lambda, U+03BB ISOgrk3
- entityMap.put("mu", new Character('\u03bc')); // greek small letter mu, U+03BC ISOgrk3
- entityMap.put("nu", new Character('\u03bd')); // greek small letter nu, U+03BD ISOgrk3
- entityMap.put("xi", new Character('\u03be')); // greek small letter xi, U+03BE ISOgrk3
- entityMap.put("omicron", new Character('\u03bf')); // greek small letter omicron, U+03BF NEW
- entityMap.put("pi", new Character('\u03c0')); // greek small letter pi, U+03C0 ISOgrk3
- entityMap.put("rho", new Character('\u03c1')); // greek small letter rho, U+03C1 ISOgrk3
- entityMap.put("sigmaf", new Character('\u03c2')); // greek small letter final sigma, U+03C2 ISOgrk3
- entityMap.put("sigma", new Character('\u03c3')); // greek small letter sigma, U+03C3 ISOgrk3
- entityMap.put("tau", new Character('\u03c4')); // greek small letter tau, U+03C4 ISOgrk3
- entityMap.put("upsilon", new Character('\u03c5')); // greek small letter upsilon, U+03C5 ISOgrk3
- entityMap.put("phi", new Character('\u03c6')); // greek small letter phi, U+03C6 ISOgrk3
- entityMap.put("chi", new Character('\u03c7')); // greek small letter chi, U+03C7 ISOgrk3
- entityMap.put("psi", new Character('\u03c8')); // greek small letter psi, U+03C8 ISOgrk3
- entityMap.put("omega", new Character('\u03c9')); // greek small letter omega, U+03C9 ISOgrk3
- entityMap.put("thetasym", new Character('\u03d1')); // greek small letter theta symbol, U+03D1 NEW
- entityMap.put("upsih", new Character('\u03d2')); // greek upsilon with hook symbol, U+03D2 NEW
- entityMap.put("piv", new Character('\u03d6')); // greek pi symbol, U+03D6 ISOgrk3
- // General Punctuation
- entityMap.put("bull", new Character('\u2022')); // bullet = black small circle, U+2022 ISOpub
- // bullet is NOT the same as bullet operator, U+2219
- entityMap.put("hellip", new Character('\u2026')); // horizontal ellipsis = three dot leader, U+2026 ISOpub
- entityMap.put("prime", new Character('\u2032')); // prime = minutes = feet, U+2032 ISOtech
- entityMap.put("Prime", new Character('\u2033')); // double prime = seconds = inches, U+2033 ISOtech
- entityMap.put("oline", new Character('\u203e')); // overline = spacing overscore, U+203E NEW
- entityMap.put("frasl", new Character('\u2044')); // fraction slash, U+2044 NEW
- // Letterlike Symbols
- entityMap.put("weierp", new Character('\u2118')); // script capital P = power set = Weierstrass p, U+2118 ISOamso
- entityMap.put("image", new Character('\u2111')); // blackletter capital I = imaginary part, U+2111 ISOamso
- entityMap.put("real", new Character('\u211c')); // blackletter capital R = real part symbol, U+211C ISOamso
- entityMap.put("trade", new Character('\u2122')); // trade mark sign, U+2122 ISOnum
- entityMap.put("alefsym", new Character('\u2135')); // alef symbol = first transfinite cardinal, U+2135 NEW
- // alef symbol is NOT the same as hebrew letter alef,
- // U+05D0 although the same glyph could be used to depict both characters
- // Arrows
- entityMap.put("larr", new Character('\u2190')); // leftwards arrow, U+2190 ISOnum
- entityMap.put("uarr", new Character('\u2191')); // upwards arrow, U+2191 ISOnum
- entityMap.put("rarr", new Character('\u2192')); // rightwards arrow, U+2192 ISOnum
- entityMap.put("darr", new Character('\u2193')); // downwards arrow, U+2193 ISOnum
- entityMap.put("harr", new Character('\u2194')); // left right arrow, U+2194 ISOamsa
- entityMap.put("crarr", new Character('\u21b5')); // downwards arrow with corner leftwards = carriage return, U+21B5 NEW
- entityMap.put("lArr", new Character('\u21d0')); // leftwards double arrow, U+21D0 ISOtech
- // ISO 10646 does not say that lArr is the same as the 'is implied by' arrow
- // but also does not have any other character for that function. So ? lArr can
- // be used for 'is implied by' as ISOtech suggests
- entityMap.put("uArr", new Character('\u21d1')); // upwards double arrow, U+21D1 ISOamsa
- entityMap.put("rArr", new Character('\u21d2')); // rightwards double arrow, U+21D2 ISOtech
- // ISO 10646 does not say this is the 'implies' character but does not have
- // another character with this function so ?
- // rArr can be used for 'implies' as ISOtech suggests
- entityMap.put("dArr", new Character('\u21d3')); // downwards double arrow, U+21D3 ISOamsa
- entityMap.put("hArr", new Character('\u21d4')); // left right double arrow, U+21D4 ISOamsa
- // Mathematical Operators
- entityMap.put("forall", new Character('\u2200')); // for all, U+2200 ISOtech
- entityMap.put("part", new Character('\u2202')); // partial differential, U+2202 ISOtech
- entityMap.put("exist", new Character('\u2203')); // there exists, U+2203 ISOtech
- entityMap.put("empty", new Character('\u2205')); // empty set = null set = diameter, U+2205 ISOamso
- entityMap.put("nabla", new Character('\u2207')); // nabla = backward difference, U+2207 ISOtech
- entityMap.put("isin", new Character('\u2208')); // element of, U+2208 ISOtech
- entityMap.put("notin", new Character('\u2209')); // not an element of, U+2209 ISOtech
- entityMap.put("ni", new Character('\u220b')); // contains as member, U+220B ISOtech
- // should there be a more memorable name than 'ni'?
- entityMap.put("prod", new Character('\u220f')); // n-ary product = product sign, U+220F ISOamsb
- // prod is NOT the same character as U+03A0 'greek capital letter pi' though
- // the same glyph might be used for both
- entityMap.put("sum", new Character('\u2211')); // n-ary sumation, U+2211 ISOamsb
- // sum is NOT the same character as U+03A3 'greek capital letter sigma'
- // though the same glyph might be used for both
- entityMap.put("minus", new Character('\u2212')); // minus sign, U+2212 ISOtech
- entityMap.put("lowast", new Character('\u2217')); // asterisk operator, U+2217 ISOtech
- entityMap.put("radic", new Character('\u221a')); // square root = radical sign, U+221A ISOtech
- entityMap.put("prop", new Character('\u221d')); // proportional to, U+221D ISOtech
- entityMap.put("infin", new Character('\u221e')); // infinity, U+221E ISOtech
- entityMap.put("ang", new Character('\u2220')); // angle, U+2220 ISOamso
- entityMap.put("and", new Character('\u2227')); // logical and = wedge, U+2227 ISOtech
- entityMap.put("or", new Character('\u2228')); // logical or = vee, U+2228 ISOtech
- entityMap.put("cap", new Character('\u2229')); // intersection = cap, U+2229 ISOtech
- entityMap.put("cup", new Character('\u222a')); // union = cup, U+222A ISOtech
- entityMap.put("int", new Character('\u222b')); // integral, U+222B ISOtech
- entityMap.put("there4", new Character('\u2234')); // therefore, U+2234 ISOtech
- entityMap.put("sim", new Character('\u223c')); // tilde operator = varies with = similar to, U+223C ISOtech
- // tilde operator is NOT the same character as the tilde, U+007E,
- // although the same glyph might be used to represent both
- entityMap.put("cong", new Character('\u2245')); // approximately equal to, U+2245 ISOtech
- entityMap.put("asymp", new Character('\u2248')); // almost equal to = asymptotic to, U+2248 ISOamsr
- entityMap.put("ne", new Character('\u2260')); // not equal to, U+2260 ISOtech
- entityMap.put("equiv", new Character('\u2261')); // identical to, U+2261 ISOtech
- entityMap.put("le", new Character('\u2264')); // less-than or equal to, U+2264 ISOtech
- entityMap.put("ge", new Character('\u2265')); // greater-than or equal to, U+2265 ISOtech
- entityMap.put("sub", new Character('\u2282')); // subset of, U+2282 ISOtech
- entityMap.put("sup", new Character('\u2283')); // superset of, U+2283 ISOtech
- // note that nsup, 'not a superset of, U+2283' is not covered by the Symbol
- // font encoding and is not included. Should it be, for symmetry?
- // It is in ISOamsn
- entityMap.put("nsub", new Character('\u2284')); // not a subset of, U+2284 ISOamsn
- entityMap.put("sube", new Character('\u2286')); // subset of or equal to, U+2286 ISOtech
- entityMap.put("supe", new Character('\u2287')); // superset of or equal to, U+2287 ISOtech
- entityMap.put("oplus", new Character('\u2295')); // circled plus = direct sum, U+2295 ISOamsb
- entityMap.put("otimes", new Character('\u2297')); // circled times = vector product, U+2297 ISOamsb
- entityMap.put("perp", new Character('\u22a5')); // up tack = orthogonal to = perpendicular, U+22A5 ISOtech
- entityMap.put("sdot", new Character('\u22c5')); // dot operator, U+22C5 ISOamsb
- // dot operator is NOT the same character as U+00B7 middle dot
- // Miscellaneous Technical
- entityMap.put("lceil", new Character('\u2308')); // left ceiling = apl upstile, U+2308 ISOamsc
- entityMap.put("rceil", new Character('\u2309')); // right ceiling, U+2309 ISOamsc
- entityMap.put("lfloor", new Character('\u230a')); // left floor = apl downstile, U+230A ISOamsc
- entityMap.put("rfloor", new Character('\u230b')); // right floor, U+230B ISOamsc
- entityMap.put("lang", new Character('\u2329')); // left-pointing angle bracket = bra, U+2329 ISOtech
- // lang is NOT the same character as U+003C 'less than'
- // or U+2039 'single left-pointing angle quotation mark'
- entityMap.put("rang", new Character('\u232a')); // right-pointing angle bracket = ket, U+232A ISOtech
- // rang is NOT the same character as U+003E 'greater than'
- // or U+203A 'single right-pointing angle quotation mark'
- // Geometric Shapes
- entityMap.put("loz", new Character('\u25ca')); // lozenge, U+25CA ISOpub
- // Miscellaneous Symbols
- entityMap.put("spades", new Character('\u2660')); // black spade suit, U+2660 ISOpub
- // black here seems to mean filled as opposed to hollow
- entityMap.put("clubs", new Character('\u2663')); // black club suit = shamrock, U+2663 ISOpub
- entityMap.put("hearts", new Character('\u2665')); // black heart suit = valentine, U+2665 ISOpub
- entityMap.put("diams", new Character('\u2666')); // black diamond suit, U+2666 ISOpub
- // C0 Controls and Basic Latin
- entityMap.put("quot", new Character('\u0022')); // quotation mark = APL quote, U+0022 ISOnum
- entityMap.put("amp", new Character('\u0026')); // ampersand, U+0026 ISOnum
- entityMap.put("apos", new Character('\''));
- entityMap.put("lt", new Character('\u003c')); // less-than sign, U+003C ISOnum
- entityMap.put("gt", new Character('\u003e')); // greater-than sign, U+003E ISOnum
- // Latin Extended-A
- entityMap.put("OElig", new Character('\u0152')); // latin capital ligature OE, U+0152 ISOlat2
- entityMap.put("oelig", new Character('\u0153')); // latin small ligature oe, U+0153 ISOlat2
- // ligature is a misnomer, this is a separate character in some languages
- entityMap.put("Scaron", new Character('\u0160')); // latin capital letter S with caron, U+0160 ISOlat2
- entityMap.put("scaron", new Character('\u0161')); // latin small letter s with caron, U+0161 ISOlat2
- entityMap.put("Yuml", new Character('\u0178')); // latin capital letter Y with diaeresis, U+0178 ISOlat2
- // Spacing Modifier Letters
- entityMap.put("circ", new Character('\u02c6')); // modifier letter circumflex accent, U+02C6 ISOpub
- entityMap.put("tilde", new Character('\u02dc')); // small tilde, U+02DC ISOdia
- // General Punctuation
- entityMap.put("ensp", new Character('\u2002')); // en space, U+2002 ISOpub
- entityMap.put("emsp", new Character('\u2003')); // em space, U+2003 ISOpub
- entityMap.put("thinsp", new Character('\u2009')); // thin space, U+2009 ISOpub
- entityMap.put("zwnj", new Character('\u200c')); // zero width non-joiner, U+200C NEW RFC 2070
- entityMap.put("zwj", new Character('\u200d')); // zero width joiner, U+200D NEW RFC 2070
- entityMap.put("lrm", new Character('\u200e')); // left-to-right mark, U+200E NEW RFC 2070
- entityMap.put("rlm", new Character('\u200f')); // right-to-left mark, U+200F NEW RFC 2070
- entityMap.put("ndash", new Character('\u2013')); // en dash, U+2013 ISOpub
- entityMap.put("mdash", new Character('\u2014')); // em dash, U+2014 ISOpub
- entityMap.put("lsquo", new Character('\u2018')); // left single quotation mark, U+2018 ISOnum
- entityMap.put("rsquo", new Character('\u2019')); // right single quotation mark, U+2019 ISOnum
- entityMap.put("sbquo", new Character('\u201a')); // single low-9 quotation mark, U+201A NEW
- entityMap.put("ldquo", new Character('\u201c')); // left double quotation mark, U+201C ISOnum
- entityMap.put("rdquo", new Character('\u201d')); // right double quotation mark, U+201D ISOnum
- entityMap.put("bdquo", new Character('\u201e')); // double low-9 quotation mark, U+201E NEW
- entityMap.put("dagger", new Character('\u2020')); // dagger, U+2020 ISOpub
- entityMap.put("Dagger", new Character('\u2021')); // double dagger, U+2021 ISOpub
- entityMap.put("permil", new Character('\u2030')); // per mille sign, U+2030 ISOtech
- entityMap.put("lsaquo", new Character('\u2039')); // single left-pointing angle quotation mark, U+2039 ISO proposed
- // lsaquo is proposed but not yet ISO standardized
- entityMap.put("rsaquo", new Character('\u203a')); // single right-pointing angle quotation mark, U+203A ISO proposed
- // rsaquo is proposed but not yet ISO standardized
- entityMap.put("euro", new Character('\u20ac')); // euro sign, U+20AC NEW
-
-
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/SpotColor.java b/src/main/java/com/lowagie/text/pdf/SpotColor.java
deleted file mode 100644
index a9da97c..0000000
--- a/src/main/java/com/lowagie/text/pdf/SpotColor.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * $Id: SpotColor.java,v 1.48 2005/12/11 15:31:04 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;
-
-/**
- *
- * @author psoares
- */
-public class SpotColor extends ExtendedColor {
-
- PdfSpotColor spot;
- float tint;
-
- public SpotColor(PdfSpotColor spot, float tint) {
- super(TYPE_SEPARATION,
- ((float)spot.getAlternativeCS().getRed() / 255f - 1f) * tint + 1,
- ((float)spot.getAlternativeCS().getGreen() / 255f - 1f) * tint + 1,
- ((float)spot.getAlternativeCS().getBlue() / 255f - 1f) * tint + 1);
- this.spot = spot;
- this.tint = tint;
- }
-
- public SpotColor(PdfSpotColor spot) {
- this(spot, spot.getTint());
- }
-
- public PdfSpotColor getPdfSpotColor() {
- return spot;
- }
-
- public float getTint() {
- return tint;
- }
-
- public boolean equals(Object obj) {
- return this == obj;
- }
-
- public int hashCode() {
- return spot.hashCode() ^ Float.floatToIntBits(tint);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/StampContent.java b/src/main/java/com/lowagie/text/pdf/StampContent.java
deleted file mode 100644
index 57b85c7..0000000
--- a/src/main/java/com/lowagie/text/pdf/StampContent.java
+++ /dev/null
@@ -1,81 +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;
-
-public class StampContent extends PdfContentByte {
- PdfStamperImp.PageStamp ps;
- PageResources pageResources;
-
- /** Creates a new instance of StampContent */
- StampContent(PdfStamperImp stamper, PdfStamperImp.PageStamp ps) {
- super(stamper);
- this.ps = ps;
- pageResources = ps.pageResources;
- }
-
- public void setAction(PdfAction action, float llx, float lly, float urx, float ury) {
- ((PdfStamperImp)writer).addAnnotation(new PdfAnnotation(writer, llx, lly, urx, ury, action), ps.pageN);
- }
-
- /**
- * Gets a duplicate of this <CODE>PdfContentByte</CODE>. All
- * the members are copied by reference but the buffer stays different.
- *
- * @return a copy of this <CODE>PdfContentByte</CODE>
- */
- public PdfContentByte getDuplicate() {
- return new StampContent((PdfStamperImp)writer, ps);
- }
-
- PageResources getPageResources() {
- return pageResources;
- }
-
- void addAnnotation(PdfAnnotation annot) {
- ((PdfStamperImp)writer).addAnnotation(annot, ps.pageN);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/TextField.java b/src/main/java/com/lowagie/text/pdf/TextField.java
deleted file mode 100644
index 1535069..0000000
--- a/src/main/java/com/lowagie/text/pdf/TextField.java
+++ /dev/null
@@ -1,661 +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.awt.Color;
-import com.lowagie.text.Element;
-import com.lowagie.text.DocumentException;
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.Phrase;
-import com.lowagie.text.Font;
-import com.lowagie.text.Chunk;
-import java.io.IOException;
-import java.util.ArrayList;
-
-/** Supports text, combo and list fields generating the correct appearances.
- * All the option in the Acrobat GUI are supported in an easy to use API.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class TextField extends BaseField {
-
- /** Holds value of property defaultText. */
- private String defaultText;
-
- /** Holds value of property choices. */
- private String[] choices;
-
- /** Holds value of property choiceExports. */
- private String[] choiceExports;
-
- /** Holds value of property choiceSelection. */
- private int choiceSelection;
-
- private int topFirst;
-
- private float extraMarginLeft;
- private float extraMarginTop;
-
- /** Creates a new <CODE>TextField</CODE>.
- * @param writer the document <CODE>PdfWriter</CODE>
- * @param box the field location and dimensions
- * @param fieldName the field name. If <CODE>null</CODE> only the widget keys
- * will be included in the field allowing it to be used as a kid field.
- */
- public TextField(PdfWriter writer, Rectangle box, String fieldName) {
- super(writer, box, fieldName);
- }
-
- private static boolean checkRTL(String text) {
- if (text == null || text.length() == 0)
- return false;
- char[] cc = text.toCharArray();
- for (int k = 0; k < cc.length; ++k) {
- int c = (int)cc[k];
- if (c >= 0x590 && c < 0x0780)
- return true;
- }
- return false;
- }
-
- private static void changeFontSize(Phrase p, float size) {
- for (int k = 0; k < p.size(); ++k) {
- ((Chunk)p.get(k)).font().setSize(size);
- }
- }
-
- private Phrase composePhrase(String text, BaseFont ufont, Color color, float fontSize) {
- Phrase phrase = null;
- if (extensionFont == null && (substitutionFonts == null || substitutionFonts.size() == 0))
- phrase = new Phrase(new Chunk(text, new Font(ufont, fontSize, 0, color)));
- else {
- FontSelector fs = new FontSelector();
- fs.addFont(new Font(ufont, fontSize, 0, color));
- if (extensionFont != null)
- fs.addFont(new Font(extensionFont, fontSize, 0, color));
- if (substitutionFonts != null) {
- for (int k = 0; k < substitutionFonts.size(); ++k) {
- fs.addFont(new Font((BaseFont)substitutionFonts.get(k), fontSize, 0, color));
- }
- }
- phrase = fs.process(text);
- }
- return phrase;
- }
-
- private static String removeCRLF(String text) {
- if (text.indexOf('\n') >= 0 || text.indexOf('\r') >= 0) {
- char[] p = text.toCharArray();
- StringBuffer sb = new StringBuffer(p.length);
- for (int k = 0; k < p.length; ++k) {
- char c = p[k];
- if (c == '\n')
- sb.append(' ');
- else if (c == '\r') {
- sb.append(' ');
- if (k < p.length - 1 && p[k + 1] == '\n')
- ++k;
- }
- else
- sb.append(c);
- }
- return sb.toString();
- }
- return text;
- }
-
- public PdfAppearance getAppearance() throws IOException, DocumentException {
- PdfAppearance app = getBorderAppearance();
- app.beginVariableText();
- if (text == null || text.length() == 0) {
- app.endVariableText();
- 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;
- }
- h -= extraMarginTop;
- float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
- offsetX = Math.max(offsetX, 1);
- float offX = Math.min(bw2, offsetX);
- app.saveState();
- app.rectangle(offX, offX, box.width() - 2 * offX, box.height() - 2 * offX);
- app.clip();
- app.newPath();
- Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor;
- String ptext = text; //fixed by Kazuya Ujihara (ujihara.jp)
- if ((options & PASSWORD) != 0) {
- char[] pchar = new char[text.length()];
- for (int i = 0; i < text.length(); i++)
- pchar[i] = '*';
- ptext = new String(pchar);
- }
- int rtl = checkRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI;
- if ((options & MULTILINE) == 0) {
- ptext = removeCRLF(text);
- }
- Phrase phrase = composePhrase(ptext, ufont, fcolor, fontSize);
- if ((options & MULTILINE) != 0) {
- float usize = fontSize;
- float width = box.width() - 4 * offsetX - extraMarginLeft;
- float factor = ufont.getFontDescriptor(BaseFont.BBOXURY, 1) - ufont.getFontDescriptor(BaseFont.BBOXLLY, 1);
- ColumnText ct = new ColumnText(null);
- if (usize == 0) {
- usize = h / factor;
- if (usize > 4) {
- if (usize > 12)
- usize = 12;
- float step = Math.max((usize - 4) / 10, 0.2f);
- ct.setSimpleColumn(0, -h, width, 0);
- ct.setAlignment(alignment);
- ct.setRunDirection(rtl);
- for (; usize > 4; usize -= step) {
- ct.setYLine(0);
- changeFontSize(phrase, usize);
- ct.setText(phrase);
- ct.setLeading(factor * usize);
- int status = ct.go(true);
- if ((status & ColumnText.NO_MORE_COLUMN) == 0)
- break;
- }
- }
- if (usize < 4) {
- usize = 4;
- }
- }
- changeFontSize(phrase, usize);
- ct.setCanvas(app);
- float leading = usize * factor;
- float offsetY = offsetX + h - ufont.getFontDescriptor(BaseFont.BBOXURY, usize);
- ct.setSimpleColumn(extraMarginLeft + 2 * offsetX, -20000, box.width() - 2 * offsetX, offsetY + leading);
- ct.setLeading(leading);
- ct.setAlignment(alignment);
- ct.setRunDirection(rtl);
- ct.setText(phrase);
- ct.go();
- }
- else {
- float usize = fontSize;
- if (usize == 0) {
- float maxCalculatedSize = h / (ufont.getFontDescriptor(BaseFont.BBOXURX, 1) - ufont.getFontDescriptor(BaseFont.BBOXLLY, 1));
- changeFontSize(phrase, 1);
- float wd = ColumnText.getWidth(phrase, rtl, 0);
- if (wd == 0)
- usize = maxCalculatedSize;
- else
- usize = (box.width() - extraMarginLeft - 4 * offsetX) / wd;
- if (usize > maxCalculatedSize)
- usize = maxCalculatedSize;
- if (usize < 4)
- usize = 4;
- }
- changeFontSize(phrase, usize);
- float offsetY = offX + ((box.height() - 2*offX) - ufont.getFontDescriptor(BaseFont.ASCENT, usize)) / 2;
- if (offsetY < offX)
- offsetY = offX;
- if (offsetY - offX < -ufont.getFontDescriptor(BaseFont.DESCENT, usize)) {
- float ny = -ufont.getFontDescriptor(BaseFont.DESCENT, usize) + offX;
- float dy = box.height() - offX - ufont.getFontDescriptor(BaseFont.ASCENT, usize);
- offsetY = Math.min(ny, Math.max(offsetY, dy));
- }
- if ((options & COMB) != 0 && maxCharacterLength > 0) {
- int textLen = Math.min(maxCharacterLength, ptext.length());
- int position = 0;
- if (alignment == Element.ALIGN_RIGHT) {
- position = maxCharacterLength - textLen;
- }
- else if (alignment == Element.ALIGN_CENTER) {
- position = (maxCharacterLength - textLen) / 2;
- }
- float step = (box.width() - extraMarginLeft) / maxCharacterLength;
- float start = step / 2 + position * step;
- if (textColor == null)
- app.setGrayFill(0);
- else
- app.setColorFill(textColor);
- app.beginText();
- for (int k = 0; k < phrase.size(); ++k) {
- Chunk ck = (Chunk)phrase.get(k);
- BaseFont bf = ck.font().getBaseFont();
- app.setFontAndSize(bf, usize);
- StringBuffer sb = ck.append("");
- for (int j = 0; j < sb.length(); ++j) {
- String c = sb.substring(j, j + 1);
- float wd = bf.getWidthPoint(c, usize);
- app.setTextMatrix(extraMarginLeft + start - wd / 2, offsetY - extraMarginTop);
- app.showText(c);
- start += step;
- }
- }
- app.endText();
- }
- else {
- if (alignment == Element.ALIGN_RIGHT) {
- ColumnText.showTextAligned(app, Element.ALIGN_RIGHT, phrase, extraMarginLeft + box.width() - 2 * offsetX, offsetY - extraMarginTop, 0, rtl, 0);
- }
- else if (alignment == Element.ALIGN_CENTER) {
- ColumnText.showTextAligned(app, Element.ALIGN_CENTER, phrase, extraMarginLeft + box.width() / 2, offsetY - extraMarginTop, 0, rtl, 0);
- }
- else
- ColumnText.showTextAligned(app, Element.ALIGN_LEFT, phrase, extraMarginLeft + 2 * offsetX, offsetY - extraMarginTop, 0, rtl, 0);
- }
- }
- app.restoreState();
- app.endVariableText();
- return app;
- }
-
- PdfAppearance getListAppearance() throws IOException, DocumentException {
- PdfAppearance app = getBorderAppearance();
- app.beginVariableText();
- if (choices == null || choices.length == 0) {
- app.endVariableText();
- return app;
- }
- int topChoice = choiceSelection;
- if (topChoice >= choices.length) {
- topChoice = choices.length - 1;
- }
- if (topChoice < 0)
- topChoice = 0;
- BaseFont ufont = getRealFont();
- float usize = fontSize;
- if (usize == 0)
- usize = 12;
- boolean borderExtra = borderStyle == PdfBorderDictionary.STYLE_BEVELED || borderStyle == PdfBorderDictionary.STYLE_INSET;
- float h = box.height() - borderWidth * 2;
- if (borderExtra)
- h -= borderWidth * 2;
- float offsetX = (borderExtra ? 2 * borderWidth : borderWidth);
- float leading = ufont.getFontDescriptor(BaseFont.BBOXURY, usize) - ufont.getFontDescriptor(BaseFont.BBOXLLY, usize);
- int maxFit = (int)(h / leading) + 1;
- int first = 0;
- int last = 0;
- last = topChoice + maxFit / 2 + 1;
- first = last - maxFit;
- if (first < 0) {
- last += first;
- first = 0;
- }
-// first = topChoice;
- last = first + maxFit;
- if (last > choices.length)
- last = choices.length;
- topFirst = first;
- app.saveState();
- app.rectangle(offsetX, offsetX, box.width() - 2 * offsetX, box.height() - 2 * offsetX);
- app.clip();
- app.newPath();
- Color fcolor = (textColor == null) ? GrayColor.GRAYBLACK : textColor;
- app.setColorFill(new Color(10, 36, 106));
- app.rectangle(offsetX, offsetX + h - (topChoice - first + 1) * leading, box.width() - 2 * offsetX, leading);
- app.fill();
- float xp = offsetX * 2;
- float yp = offsetX + h - ufont.getFontDescriptor(BaseFont.BBOXURY, usize);
- for (int idx = first; idx < last; ++idx, yp -= leading) {
- String ptext = choices[idx];
- int rtl = checkRTL(ptext) ? PdfWriter.RUN_DIRECTION_LTR : PdfWriter.RUN_DIRECTION_NO_BIDI;
- ptext = removeCRLF(ptext);
- Phrase phrase = composePhrase(ptext, ufont, (idx == topChoice) ? GrayColor.GRAYWHITE : fcolor, usize);
- ColumnText.showTextAligned(app, Element.ALIGN_LEFT, phrase, xp, yp, 0, rtl, 0);
- }
- app.restoreState();
- app.endVariableText();
- return app;
- }
-
- /** Gets a new text field.
- * @throws IOException on error
- * @throws DocumentException on error
- * @return a new text field
- */
- public PdfFormField getTextField() throws IOException, DocumentException {
- if (maxCharacterLength <= 0)
- options &= ~COMB;
- if ((options & COMB) != 0)
- options &= ~MULTILINE;
- PdfFormField field = PdfFormField.createTextField(writer, false, false, maxCharacterLength);
- field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
- switch (alignment) {
- case Element.ALIGN_CENTER:
- field.setQuadding(PdfFormField.Q_CENTER);
- break;
- case Element.ALIGN_RIGHT:
- field.setQuadding(PdfFormField.Q_RIGHT);
- break;
- }
- if (rotation != 0)
- field.setMKRotation(rotation);
- if (fieldName != null) {
- field.setFieldName(fieldName);
- field.setValueAsString(text);
- if (defaultText != null)
- field.setDefaultValueAsString(defaultText);
- if ((options & READ_ONLY) != 0)
- field.setFieldFlags(PdfFormField.FF_READ_ONLY);
- if ((options & REQUIRED) != 0)
- field.setFieldFlags(PdfFormField.FF_REQUIRED);
- if ((options & MULTILINE) != 0)
- field.setFieldFlags(PdfFormField.FF_MULTILINE);
- if ((options & DO_NOT_SCROLL) != 0)
- field.setFieldFlags(PdfFormField.FF_DONOTSCROLL);
- if ((options & PASSWORD) != 0)
- field.setFieldFlags(PdfFormField.FF_PASSWORD);
- if ((options & FILE_SELECTION) != 0)
- field.setFieldFlags(PdfFormField.FF_FILESELECT);
- if ((options & DO_NOT_SPELL_CHECK) != 0)
- field.setFieldFlags(PdfFormField.FF_DONOTSPELLCHECK);
- if ((options & COMB) != 0)
- field.setFieldFlags(PdfFormField.FF_COMB);
- }
- field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3)));
- PdfAppearance tp = getAppearance();
- field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
- PdfAppearance da = (PdfAppearance)tp.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;
- }
-
- /** Gets a new combo field.
- * @throws IOException on error
- * @throws DocumentException on error
- * @return a new combo field
- */
- public PdfFormField getComboField() throws IOException, DocumentException {
- return getChoiceField(false);
- }
-
- /** Gets a new list field.
- * @throws IOException on error
- * @throws DocumentException on error
- * @return a new list field
- */
- public PdfFormField getListField() throws IOException, DocumentException {
- return getChoiceField(true);
- }
-
- protected PdfFormField getChoiceField(boolean isList) throws IOException, DocumentException {
- options &= (~MULTILINE) & (~COMB);
- String uchoices[] = choices;
- if (uchoices == null)
- uchoices = new String[0];
- int topChoice = choiceSelection;
- if (topChoice >= uchoices.length)
- topChoice = uchoices.length - 1;
- if (text == null) text = ""; //fixed by Kazuya Ujihara (ujihara.jp)
- if (topChoice >= 0)
- text = uchoices[topChoice];
- if (topChoice < 0)
- topChoice = 0;
- PdfFormField field = null;
- String mix[][] = null;
- if (choiceExports == null) {
- if (isList)
- field = PdfFormField.createList(writer, uchoices, topChoice);
- else
- field = PdfFormField.createCombo(writer, (options & EDIT) != 0, uchoices, topChoice);
- }
- else {
- mix = new String[uchoices.length][2];
- for (int k = 0; k < mix.length; ++k)
- mix[k][0] = mix[k][1] = uchoices[k];
- int top = Math.min(uchoices.length, choiceExports.length);
- for (int k = 0; k < top; ++k) {
- if (choiceExports[k] != null)
- mix[k][0] = choiceExports[k];
- }
- if (isList)
- field = PdfFormField.createList(writer, mix, topChoice);
- else
- field = PdfFormField.createCombo(writer, (options & EDIT) != 0, mix, topChoice);
- }
- field.setWidget(box, PdfAnnotation.HIGHLIGHT_INVERT);
- if (rotation != 0)
- field.setMKRotation(rotation);
- if (fieldName != null) {
- field.setFieldName(fieldName);
- if (uchoices.length > 0) {
- if (mix != null) {
- field.setValueAsString(mix[topChoice][0]);
- field.setDefaultValueAsString(mix[topChoice][0]);
- }
- else {
- field.setValueAsString(text);
- field.setDefaultValueAsString(text);
- }
- }
- if ((options & READ_ONLY) != 0)
- field.setFieldFlags(PdfFormField.FF_READ_ONLY);
- if ((options & REQUIRED) != 0)
- field.setFieldFlags(PdfFormField.FF_REQUIRED);
- if ((options & DO_NOT_SPELL_CHECK) != 0)
- field.setFieldFlags(PdfFormField.FF_DONOTSPELLCHECK);
- }
- field.setBorderStyle(new PdfBorderDictionary(borderWidth, borderStyle, new PdfDashPattern(3)));
- PdfAppearance tp;
- if (isList) {
- tp = getListAppearance();
- if (topFirst > 0)
- field.put(PdfName.TI, new PdfNumber(topFirst));
- }
- else
- tp = getAppearance();
- field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
- PdfAppearance da = (PdfAppearance)tp.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;
- }
-
- /** Gets the default text.
- * @return the default text
- */
- public String getDefaultText() {
- return this.defaultText;
- }
-
- /** Sets the default text. It is only meaningful for text fields.
- * @param defaultText the default text
- */
- public void setDefaultText(String defaultText) {
- this.defaultText = defaultText;
- }
-
- /** Gets the choices to be presented to the user in list/combo
- * fields.
- * @return the choices to be presented to the user
- */
- public String[] getChoices() {
- return this.choices;
- }
-
- /** Sets the choices to be presented to the user in list/combo
- * fields.
- * @param choices the choices to be presented to the user
- */
- public void setChoices(String[] choices) {
- this.choices = choices;
- }
-
- /** Gets the export values in list/combo fields.
- * @return the export values in list/combo fields
- */
- public String[] getChoiceExports() {
- return this.choiceExports;
- }
-
- /** Sets the export values in list/combo fields. If this array
- * is <CODE>null</CODE> then the choice values will also be used
- * as the export values.
- * @param choiceExports the export values in list/combo fields
- */
- public void setChoiceExports(String[] choiceExports) {
- this.choiceExports = choiceExports;
- }
-
- /** Gets the zero based index of the selected item.
- * @return the zero based index of the selected item
- */
- public int getChoiceSelection() {
- return this.choiceSelection;
- }
-
- /** Sets the zero based index of the selected item.
- * @param choiceSelection the zero based index of the selected item
- */
- public void setChoiceSelection(int choiceSelection) {
- this.choiceSelection = choiceSelection;
- }
-
- int getTopFirst() {
- return topFirst;
- }
-
- /**
- * 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;
- }
-
- /**
- * Holds value of property substitutionFonts.
- */
- private ArrayList substitutionFonts;
-
- /**
- * Gets the list of substitution fonts. The list is composed of <CODE>BaseFont</CODE> and can be <CODE>null</CODE>. 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 this.substitutionFonts;
- }
-
- /**
- * Sets a list of substitution fonts. The list is composed of <CODE>BaseFont</CODE> and can also be <CODE>null</CODE>. 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;
- }
-
- /**
- * Holds value of property extensionFont.
- */
- private BaseFont extensionFont;
-
- /**
- * Gets the extensionFont. This font will be searched before the
- * substitution fonts. It may be <code>null</code>.
- * @return the extensionFont
- */
- public BaseFont getExtensionFont() {
- return this.extensionFont;
- }
-
- /**
- * Sets the extensionFont. This font will be searched before the
- * substitution fonts. It may be <code>null</code>.
- * @param extensionFont New value of property extensionFont.
- */
- public void setExtensionFont(BaseFont extensionFont) {
- this.extensionFont = extensionFont;
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/TrueTypeFont.java b/src/main/java/com/lowagie/text/pdf/TrueTypeFont.java
deleted file mode 100644
index 8551cfc..0000000
--- a/src/main/java/com/lowagie/text/pdf/TrueTypeFont.java
+++ /dev/null
@@ -1,1377 +0,0 @@
-/*
- * $Id: TrueTypeFont.java,v 1.58 2006/02/23 16:45:48 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.*;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-import com.lowagie.text.DocumentException;
-import com.lowagie.text.ExceptionConverter;
-/** Reads a Truetype font
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-class TrueTypeFont extends BaseFont {
-
- /** The code pages possible for a True Type font.
- */
- static final String codePages[] = {
- "1252 Latin 1",
- "1250 Latin 2: Eastern Europe",
- "1251 Cyrillic",
- "1253 Greek",
- "1254 Turkish",
- "1255 Hebrew",
- "1256 Arabic",
- "1257 Windows Baltic",
- "1258 Vietnamese",
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- "874 Thai",
- "932 JIS/Japan",
- "936 Chinese: Simplified chars--PRC and Singapore",
- "949 Korean Wansung",
- "950 Chinese: Traditional chars--Taiwan and Hong Kong",
- "1361 Korean Johab",
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- "Macintosh Character Set (US Roman)",
- "OEM Character Set",
- "Symbol Character Set",
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- "869 IBM Greek",
- "866 MS-DOS Russian",
- "865 MS-DOS Nordic",
- "864 Arabic",
- "863 MS-DOS Canadian French",
- "862 Hebrew",
- "861 MS-DOS Icelandic",
- "860 MS-DOS Portuguese",
- "857 IBM Turkish",
- "855 IBM Cyrillic; primarily Russian",
- "852 Latin 2",
- "775 MS-DOS Baltic",
- "737 Greek; former 437 G",
- "708 Arabic; ASMO 708",
- "850 WE/Latin 1",
- "437 US"};
-
- protected boolean justNames = false;
- /** Contains the location of the several tables. The key is the name of
- * the table and the value is an <CODE>int[2]</CODE> where position 0
- * is the offset from the start of the file and position 1 is the length
- * of the table.
- */
- protected HashMap tables;
- /** The file in use.
- */
- protected RandomAccessFileOrArray rf;
- /** The file name.
- */
- protected String fileName;
-
- protected boolean cff = false;
-
- protected int cffOffset;
-
- protected int cffLength;
-
- /** The offset from the start of the file to the table directory.
- * It is 0 for TTF and may vary for TTC depending on the chosen font.
- */
- protected int directoryOffset;
- /** The index for the TTC font. It is an empty <CODE>String</CODE> for a
- * TTF file.
- */
- protected String ttcIndex;
- /** The style modifier */
- protected String style = "";
- /** The content of table 'head'.
- */
- protected FontHeader head = new FontHeader();
- /** The content of table 'hhea'.
- */
- protected HorizontalHeader hhea = new HorizontalHeader();
- /** The content of table 'OS/2'.
- */
- protected WindowsMetrics os_2 = new WindowsMetrics();
- /** The width of the glyphs. This is essentially the content of table
- * 'hmtx' normalized to 1000 units.
- */
- protected int GlyphWidths[];
-
- protected int bboxes[][];
- /** The map containing the code information for the table 'cmap', encoding 1.0.
- * The key is the code and the value is an <CODE>int[2]</CODE> where position 0
- * is the glyph number and position 1 is the glyph width normalized to 1000
- * units.
- */
- protected HashMap cmap10;
- /** The map containing the code information for the table 'cmap', encoding 3.1
- * in Unicode.
- * <P>
- * The key is the code and the value is an <CODE>int</CODE>[2] where position 0
- * is the glyph number and position 1 is the glyph width normalized to 1000
- * units.
- */
- protected HashMap cmap31;
- /** The map containing the kerning information. It represents the content of
- * table 'kern'. The key is an <CODE>Integer</CODE> where the top 16 bits
- * are the glyph number for the first character and the lower 16 bits are the
- * glyph number for the second character. The value is the amount of kerning in
- * normalized 1000 units as an <CODE>Integer</CODE>. This value is usually negative.
- */
- protected IntHashtable kerning = new IntHashtable();
- /**
- * The font name.
- * This name is usually extracted from the table 'name' with
- * the 'Name ID' 6.
- */
- protected String fontName;
-
- /** The full name of the font
- */
- protected String fullName[][];
-
- /** The family name of the font
- */
- protected String familyName[][];
- /** The italic angle. It is usually extracted from the 'post' table or in it's
- * absence with the code:
- * <P>
- * <PRE>
- * -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI
- * </PRE>
- */
- protected double italicAngle;
- /** <CODE>true</CODE> if all the glyphs have the same width.
- */
- protected boolean isFixedPitch = false;
-
- /** The components of table 'head'.
- */
- protected static class FontHeader {
- /** A variable. */
- int flags;
- /** A variable. */
- int unitsPerEm;
- /** A variable. */
- short xMin;
- /** A variable. */
- short yMin;
- /** A variable. */
- short xMax;
- /** A variable. */
- short yMax;
- /** A variable. */
- int macStyle;
- }
-
- /** The components of table 'hhea'.
- */
- protected static class HorizontalHeader {
- /** A variable. */
- short Ascender;
- /** A variable. */
- short Descender;
- /** A variable. */
- short LineGap;
- /** A variable. */
- int advanceWidthMax;
- /** A variable. */
- short minLeftSideBearing;
- /** A variable. */
- short minRightSideBearing;
- /** A variable. */
- short xMaxExtent;
- /** A variable. */
- short caretSlopeRise;
- /** A variable. */
- short caretSlopeRun;
- /** A variable. */
- int numberOfHMetrics;
- }
-
- /** The components of table 'OS/2'.
- */
- protected static class WindowsMetrics {
- /** A variable. */
- short xAvgCharWidth;
- /** A variable. */
- int usWeightClass;
- /** A variable. */
- int usWidthClass;
- /** A variable. */
- short fsType;
- /** A variable. */
- short ySubscriptXSize;
- /** A variable. */
- short ySubscriptYSize;
- /** A variable. */
- short ySubscriptXOffset;
- /** A variable. */
- short ySubscriptYOffset;
- /** A variable. */
- short ySuperscriptXSize;
- /** A variable. */
- short ySuperscriptYSize;
- /** A variable. */
- short ySuperscriptXOffset;
- /** A variable. */
- short ySuperscriptYOffset;
- /** A variable. */
- short yStrikeoutSize;
- /** A variable. */
- short yStrikeoutPosition;
- /** A variable. */
- short sFamilyClass;
- /** A variable. */
- byte panose[] = new byte[10];
- /** A variable. */
- byte achVendID[] = new byte[4];
- /** A variable. */
- int fsSelection;
- /** A variable. */
- int usFirstCharIndex;
- /** A variable. */
- int usLastCharIndex;
- /** A variable. */
- short sTypoAscender;
- /** A variable. */
- short sTypoDescender;
- /** A variable. */
- short sTypoLineGap;
- /** A variable. */
- int usWinAscent;
- /** A variable. */
- int usWinDescent;
- /** A variable. */
- int ulCodePageRange1;
- /** A variable. */
- int ulCodePageRange2;
- /** A variable. */
- int sCapHeight;
- }
-
- /** This constructor is present to allow extending the class.
- */
- protected TrueTypeFont() {
- }
-
- TrueTypeFont(String ttFile, String enc, boolean emb, byte ttfAfm[]) throws DocumentException, IOException {
- this(ttFile, enc, emb, ttfAfm, false);
- }
-
- /** Creates a new TrueType font.
- * @param ttFile the location of the font on file. The file must end in '.ttf' or
- * '.ttc' but can have modifiers after the name
- * @param enc the encoding to be applied to this font
- * @param emb true if the font is to be embedded in the PDF
- * @param ttfAfm the font as a <CODE>byte</CODE> array
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- TrueTypeFont(String ttFile, String enc, boolean emb, byte ttfAfm[], boolean justNames) throws DocumentException, IOException {
- this.justNames = justNames;
- String nameBase = getBaseName(ttFile);
- String ttcName = getTTCName(nameBase);
- if (nameBase.length() < ttFile.length()) {
- style = ttFile.substring(nameBase.length());
- }
- encoding = enc;
- embedded = emb;
- fileName = ttcName;
- fontType = FONT_TYPE_TT;
- ttcIndex = "";
- if (ttcName.length() < nameBase.length())
- ttcIndex = nameBase.substring(ttcName.length() + 1);
- if (fileName.toLowerCase().endsWith(".ttf") || fileName.toLowerCase().endsWith(".otf") || fileName.toLowerCase().endsWith(".ttc")) {
- process(ttfAfm);
- if (!justNames && embedded && os_2.fsType == 2)
- throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions.");
- }
- else
- throw new DocumentException(fileName + style + " is not a TTF, OTF or TTC font file.");
- PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists
- createEncoding();
- }
-
- /** Gets the name from a composed TTC file name.
- * If I have for input "myfont.ttc,2" the return will
- * be "myfont.ttc".
- * @param name the full name
- * @return the simple file name
- */
- protected static String getTTCName(String name) {
- int idx = name.toLowerCase().indexOf(".ttc,");
- if (idx < 0)
- return name;
- else
- return name.substring(0, idx + 4);
- }
-
-
- /**
- * Reads the tables 'head', 'hhea', 'OS/2' and 'post' filling several variables.
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- void fillTables() throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("head");
- if (table_location == null)
- throw new DocumentException("Table 'head' does not exist in " + fileName + style);
- rf.seek(table_location[0] + 16);
- head.flags = rf.readUnsignedShort();
- head.unitsPerEm = rf.readUnsignedShort();
- rf.skipBytes(16);
- head.xMin = rf.readShort();
- head.yMin = rf.readShort();
- head.xMax = rf.readShort();
- head.yMax = rf.readShort();
- head.macStyle = rf.readUnsignedShort();
-
- table_location = (int[])tables.get("hhea");
- if (table_location == null)
- throw new DocumentException("Table 'hhea' does not exist " + fileName + style);
- rf.seek(table_location[0] + 4);
- hhea.Ascender = rf.readShort();
- hhea.Descender = rf.readShort();
- hhea.LineGap = rf.readShort();
- hhea.advanceWidthMax = rf.readUnsignedShort();
- hhea.minLeftSideBearing = rf.readShort();
- hhea.minRightSideBearing = rf.readShort();
- hhea.xMaxExtent = rf.readShort();
- hhea.caretSlopeRise = rf.readShort();
- hhea.caretSlopeRun = rf.readShort();
- rf.skipBytes(12);
- hhea.numberOfHMetrics = rf.readUnsignedShort();
-
- table_location = (int[])tables.get("OS/2");
- if (table_location == null)
- throw new DocumentException("Table 'OS/2' does not exist in " + fileName + style);
- rf.seek(table_location[0]);
- int version = rf.readUnsignedShort();
- os_2.xAvgCharWidth = rf.readShort();
- os_2.usWeightClass = rf.readUnsignedShort();
- os_2.usWidthClass = rf.readUnsignedShort();
- os_2.fsType = rf.readShort();
- os_2.ySubscriptXSize = rf.readShort();
- os_2.ySubscriptYSize = rf.readShort();
- os_2.ySubscriptXOffset = rf.readShort();
- os_2.ySubscriptYOffset = rf.readShort();
- os_2.ySuperscriptXSize = rf.readShort();
- os_2.ySuperscriptYSize = rf.readShort();
- os_2.ySuperscriptXOffset = rf.readShort();
- os_2.ySuperscriptYOffset = rf.readShort();
- os_2.yStrikeoutSize = rf.readShort();
- os_2.yStrikeoutPosition = rf.readShort();
- os_2.sFamilyClass = rf.readShort();
- rf.readFully(os_2.panose);
- rf.skipBytes(16);
- rf.readFully(os_2.achVendID);
- os_2.fsSelection = rf.readUnsignedShort();
- os_2.usFirstCharIndex = rf.readUnsignedShort();
- os_2.usLastCharIndex = rf.readUnsignedShort();
- os_2.sTypoAscender = rf.readShort();
- os_2.sTypoDescender = rf.readShort();
- if (os_2.sTypoDescender > 0)
- os_2.sTypoDescender = (short)(-os_2.sTypoDescender);
- os_2.sTypoLineGap = rf.readShort();
- os_2.usWinAscent = rf.readUnsignedShort();
- os_2.usWinDescent = rf.readUnsignedShort();
- os_2.ulCodePageRange1 = 0;
- os_2.ulCodePageRange2 = 0;
- if (version > 0) {
- os_2.ulCodePageRange1 = rf.readInt();
- os_2.ulCodePageRange2 = rf.readInt();
- }
- if (version > 1) {
- rf.skipBytes(2);
- os_2.sCapHeight = rf.readShort();
- }
- else
- os_2.sCapHeight = (int)(0.7 * head.unitsPerEm);
-
- table_location = (int[])tables.get("post");
- if (table_location == null) {
- italicAngle = -Math.atan2(hhea.caretSlopeRun, hhea.caretSlopeRise) * 180 / Math.PI;
- return;
- }
- rf.seek(table_location[0] + 4);
- short mantissa = rf.readShort();
- int fraction = rf.readUnsignedShort();
- italicAngle = (double)mantissa + (double)fraction / 16384.0;
- rf.skipBytes(4);
- isFixedPitch = rf.readInt() != 0;
- }
-
- /**
- * Gets the Postscript font name.
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- * @return the Postscript font name
- */
- String getBaseFont() throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("name");
- if (table_location == null)
- throw new DocumentException("Table 'name' does not exist in " + fileName + style);
- rf.seek(table_location[0] + 2);
- int numRecords = rf.readUnsignedShort();
- int startOfStorage = rf.readUnsignedShort();
- for (int k = 0; k < numRecords; ++k) {
- int platformID = rf.readUnsignedShort();
- int platformEncodingID = rf.readUnsignedShort();
- int languageID = rf.readUnsignedShort();
- int nameID = rf.readUnsignedShort();
- int length = rf.readUnsignedShort();
- int offset = rf.readUnsignedShort();
- if (nameID == 6) {
- rf.seek(table_location[0] + startOfStorage + offset);
- if (platformID == 0 || platformID == 3)
- return readUnicodeString(length);
- else
- return readStandardString(length);
- }
- }
- File file = new File(fileName);
- return file.getName().replace(' ', '-');
- }
-
- /** Extracts the names of the font in all the languages available.
- * @param id the name id to retrieve
- * @throws DocumentException on error
- * @throws IOException on error
- */
- String[][] getNames(int id) throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("name");
- if (table_location == null)
- throw new DocumentException("Table 'name' does not exist in " + fileName + style);
- rf.seek(table_location[0] + 2);
- int numRecords = rf.readUnsignedShort();
- int startOfStorage = rf.readUnsignedShort();
- ArrayList names = new ArrayList();
- for (int k = 0; k < numRecords; ++k) {
- int platformID = rf.readUnsignedShort();
- int platformEncodingID = rf.readUnsignedShort();
- int languageID = rf.readUnsignedShort();
- int nameID = rf.readUnsignedShort();
- int length = rf.readUnsignedShort();
- int offset = rf.readUnsignedShort();
- if (nameID == id) {
- int pos = rf.getFilePointer();
- rf.seek(table_location[0] + startOfStorage + offset);
- String name;
- if (platformID == 0 || platformID == 3 || (platformID == 2 && platformEncodingID == 1)){
- name = readUnicodeString(length);
- }
- else {
- name = readStandardString(length);
- }
- names.add(new String[]{String.valueOf(platformID),
- String.valueOf(platformEncodingID), String.valueOf(languageID), name});
- rf.seek(pos);
- }
- }
- String thisName[][] = new String[names.size()][];
- for (int k = 0; k < names.size(); ++k)
- thisName[k] = (String[])names.get(k);
- return thisName;
- }
-
- void checkCff() throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("CFF ");
- if (table_location != null) {
- cff = true;
- cffOffset = table_location[0];
- cffLength = table_location[1];
- }
- }
-
- /** Reads the font data.
- * @param ttfAfm the font as a <CODE>byte</CODE> array, possibly <CODE>null</CODE>
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- void process(byte ttfAfm[]) throws DocumentException, IOException {
- tables = new HashMap();
-
- try {
- if (ttfAfm == null)
- rf = new RandomAccessFileOrArray(fileName);
- else
- rf = new RandomAccessFileOrArray(ttfAfm);
- if (ttcIndex.length() > 0) {
- int dirIdx = Integer.parseInt(ttcIndex);
- if (dirIdx < 0)
- throw new DocumentException("The font index for " + fileName + " must be positive.");
- 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();
- if (dirIdx >= dirCount)
- throw new DocumentException("The font index for " + fileName + " must be between 0 and " + (dirCount - 1) + ". It was " + dirIdx + ".");
- rf.skipBytes(dirIdx * 4);
- directoryOffset = rf.readInt();
- }
- rf.seek(directoryOffset);
- int ttId = rf.readInt();
- if (ttId != 0x00010000 && ttId != 0x4F54544F)
- throw new DocumentException(fileName + " is not a valid TTF or OTF 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);
- }
- checkCff();
- fontName = getBaseFont();
- fullName = getNames(4); //full name
- familyName = getNames(1); //family name
- if (!justNames) {
- fillTables();
- readGlyphWidths();
- readCMaps();
- readKerning();
- readBbox();
- GlyphWidths = null;
- }
- }
- finally {
- if (rf != null) {
- rf.close();
- if (!embedded)
- rf = null;
- }
- }
- }
-
- /** Reads a <CODE>String</CODE> from the font file as bytes using the Cp1252
- * encoding.
- * @param length the length of bytes to read
- * @return the <CODE>String</CODE> read
- * @throws IOException the font file could not be read
- */
- protected String readStandardString(int length) throws IOException {
- byte buf[] = new byte[length];
- rf.readFully(buf);
- try {
- return new String(buf, WINANSI);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- /** Reads a Unicode <CODE>String</CODE> from the font file. Each character is
- * represented by two bytes.
- * @param length the length of bytes to read. The <CODE>String</CODE> will have <CODE>length</CODE>/2
- * characters
- * @return the <CODE>String</CODE> read
- * @throws IOException the font file could not be read
- */
- protected String readUnicodeString(int length) throws IOException {
- StringBuffer buf = new StringBuffer();
- length /= 2;
- for (int k = 0; k < length; ++k) {
- buf.append(rf.readChar());
- }
- return buf.toString();
- }
-
- /** Reads the glyphs widths. The widths are extracted from the table 'hmtx'.
- * The glyphs are normalized to 1000 units.
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- protected void readGlyphWidths() throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("hmtx");
- if (table_location == null)
- throw new DocumentException("Table 'hmtx' does not exist in " + fileName + style);
- rf.seek(table_location[0]);
- GlyphWidths = new int[hhea.numberOfHMetrics];
- for (int k = 0; k < hhea.numberOfHMetrics; ++k) {
- GlyphWidths[k] = (rf.readUnsignedShort() * 1000) / head.unitsPerEm;
- rf.readUnsignedShort();
- }
- }
-
- /** Gets a glyph width.
- * @param glyph the glyph to get the width of
- * @return the width of the glyph in normalized 1000 units
- */
- protected int getGlyphWidth(int glyph) {
- if (glyph >= GlyphWidths.length)
- glyph = GlyphWidths.length - 1;
- return GlyphWidths[glyph];
- }
-
- private void readBbox() throws DocumentException, IOException {
- int tableLocation[];
- tableLocation = (int[])tables.get("head");
- if (tableLocation == null)
- throw new DocumentException("Table 'head' does not exist in " + fileName + style);
- rf.seek(tableLocation[0] + TrueTypeFontSubSet.HEAD_LOCA_FORMAT_OFFSET);
- boolean locaShortTable = (rf.readUnsignedShort() == 0);
- tableLocation = (int[])tables.get("loca");
- if (tableLocation == null)
- return;
- rf.seek(tableLocation[0]);
- int locaTable[];
- if (locaShortTable) {
- int entries = tableLocation[1] / 2;
- locaTable = new int[entries];
- for (int k = 0; k < entries; ++k)
- locaTable[k] = rf.readUnsignedShort() * 2;
- }
- else {
- int entries = tableLocation[1] / 4;
- locaTable = new int[entries];
- for (int k = 0; k < entries; ++k)
- locaTable[k] = rf.readInt();
- }
- tableLocation = (int[])tables.get("glyf");
- if (tableLocation == null)
- throw new DocumentException("Table 'glyf' does not exist in " + fileName + style);
- int tableGlyphOffset = tableLocation[0];
- bboxes = new int[locaTable.length - 1][];
- for (int glyph = 0; glyph < locaTable.length - 1; ++glyph) {
- int start = locaTable[glyph];
- if (start != locaTable[glyph + 1]) {
- rf.seek(tableGlyphOffset + start + 2);
- bboxes[glyph] = new int[]{
- (rf.readShort() * 1000) / head.unitsPerEm,
- (rf.readShort() * 1000) / head.unitsPerEm,
- (rf.readShort() * 1000) / head.unitsPerEm,
- (rf.readShort() * 1000) / head.unitsPerEm};
- }
- }
- }
-
- /** Reads the several maps from the table 'cmap'. The maps of interest are 1.0 for symbolic
- * fonts and 3.1 for all others. A symbolic font is defined as having the map 3.0.
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- void readCMaps() throws DocumentException, IOException {
- int table_location[];
- table_location = (int[])tables.get("cmap");
- if (table_location == null)
- throw new DocumentException("Table 'cmap' does not exist in " + fileName + style);
- rf.seek(table_location[0]);
- rf.skipBytes(2);
- int num_tables = rf.readUnsignedShort();
- fontSpecific = false;
- int map10 = 0;
- int map31 = 0;
- int map30 = 0;
- for (int k = 0; k < num_tables; ++k) {
- int platId = rf.readUnsignedShort();
- int platSpecId = rf.readUnsignedShort();
- int offset = rf.readInt();
- if (platId == 3 && platSpecId == 0) {
- fontSpecific = true;
- map30 = offset;
- }
- else if (platId == 3 && platSpecId == 1) {
- map31 = offset;
- }
- if (platId == 1 && platSpecId == 0) {
- map10 = offset;
- }
- }
- if (map10 > 0) {
- rf.seek(table_location[0] + map10);
- int format = rf.readUnsignedShort();
- switch (format) {
- case 0:
- cmap10 = readFormat0();
- break;
- case 4:
- cmap10 = readFormat4();
- break;
- case 6:
- cmap10 = readFormat6();
- break;
- }
- }
- if (map31 > 0) {
- rf.seek(table_location[0] + map31);
- int format = rf.readUnsignedShort();
- if (format == 4) {
- cmap31 = readFormat4();
- }
- }
- if (map30 > 0) {
- rf.seek(table_location[0] + map30);
- int format = rf.readUnsignedShort();
- if (format == 4) {
- cmap10 = readFormat4();
- }
- }
- }
-
- /** The information in the maps of the table 'cmap' is coded in several formats.
- * Format 0 is the Apple standard character to glyph index mapping table.
- * @return a <CODE>HashMap</CODE> representing this map
- * @throws IOException the font file could not be read
- */
- HashMap readFormat0() throws IOException {
- HashMap h = new HashMap();
- rf.skipBytes(4);
- for (int k = 0; k < 256; ++k) {
- int r[] = new int[2];
- r[0] = rf.readUnsignedByte();
- r[1] = getGlyphWidth(r[0]);
- h.put(new Integer(k), r);
- }
- return h;
- }
-
- /** The information in the maps of the table 'cmap' is coded in several formats.
- * Format 4 is the Microsoft standard character to glyph index mapping table.
- * @return a <CODE>HashMap</CODE> representing this map
- * @throws IOException the font file could not be read
- */
- HashMap readFormat4() throws IOException {
- HashMap h = new HashMap();
- int table_lenght = rf.readUnsignedShort();
- rf.skipBytes(2);
- int segCount = rf.readUnsignedShort() / 2;
- rf.skipBytes(6);
- int endCount[] = new int[segCount];
- for (int k = 0; k < segCount; ++k) {
- endCount[k] = rf.readUnsignedShort();
- }
- rf.skipBytes(2);
- int startCount[] = new int[segCount];
- for (int k = 0; k < segCount; ++k) {
- startCount[k] = rf.readUnsignedShort();
- }
- int idDelta[] = new int[segCount];
- for (int k = 0; k < segCount; ++k) {
- idDelta[k] = rf.readUnsignedShort();
- }
- int idRO[] = new int[segCount];
- for (int k = 0; k < segCount; ++k) {
- idRO[k] = rf.readUnsignedShort();
- }
- int glyphId[] = new int[table_lenght / 2 - 8 - segCount * 4];
- for (int k = 0; k < glyphId.length; ++k) {
- glyphId[k] = rf.readUnsignedShort();
- }
- for (int k = 0; k < segCount; ++k) {
- int glyph;
- for (int j = startCount[k]; j <= endCount[k] && j != 0xFFFF; ++j) {
- if (idRO[k] == 0) {
- glyph = (j + idDelta[k]) & 0xFFFF;
- }
- else {
- int idx = k + idRO[k] / 2 - segCount + j - startCount[k];
- if (idx >= glyphId.length)
- continue;
- glyph = (glyphId[idx] + idDelta[k]) & 0xFFFF;
- }
- int r[] = new int[2];
- r[0] = glyph;
- r[1] = getGlyphWidth(r[0]);
- h.put(new Integer(fontSpecific ? ((j & 0xff00) == 0xf000 ? j & 0xff : j) : j), r);
- }
- }
- return h;
- }
-
- /** The information in the maps of the table 'cmap' is coded in several formats.
- * Format 6 is a trimmed table mapping. It is similar to format 0 but can have
- * less than 256 entries.
- * @return a <CODE>HashMap</CODE> representing this map
- * @throws IOException the font file could not be read
- */
- HashMap readFormat6() throws IOException {
- HashMap h = new HashMap();
- rf.skipBytes(4);
- int start_code = rf.readUnsignedShort();
- int code_count = rf.readUnsignedShort();
- for (int k = 0; k < code_count; ++k) {
- int r[] = new int[2];
- r[0] = rf.readUnsignedShort();
- r[1] = getGlyphWidth(r[0]);
- h.put(new Integer(k + start_code), r);
- }
- return h;
- }
-
- /** Reads the kerning information from the 'kern' table.
- * @throws IOException the font file could not be read
- */
- void readKerning() throws IOException {
- int table_location[];
- table_location = (int[])tables.get("kern");
- if (table_location == null)
- return;
- rf.seek(table_location[0] + 2);
- int nTables = rf.readUnsignedShort();
- int checkpoint = table_location[0] + 4;
- int length = 0;
- for (int k = 0; k < nTables; ++k) {
- checkpoint += length;
- rf.seek(checkpoint);
- rf.skipBytes(2);
- length = rf.readUnsignedShort();
- int coverage = rf.readUnsignedShort();
- if ((coverage & 0xfff7) == 0x0001) {
- int nPairs = rf.readUnsignedShort();
- rf.skipBytes(6);
- for (int j = 0; j < nPairs; ++j) {
- int pair = rf.readInt();
- int value = ((int)rf.readShort() * 1000) / head.unitsPerEm;
- kerning.put(pair, value);
- }
- }
- }
- }
-
- /** 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) {
- int metrics[] = getMetricsTT(char1);
- if (metrics == null)
- return 0;
- int c1 = metrics[0];
- metrics = getMetricsTT(char2);
- if (metrics == null)
- return 0;
- int c2 = metrics[0];
- return kerning.get((c1 << 16) + c2);
- }
-
- /** Gets the width from the font according to the unicode char <CODE>c</CODE>.
- * If the <CODE>name</CODE> 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) {
- HashMap map = null;
- if (name == null || cmap31 == null)
- map = cmap10;
- else
- map = cmap31;
- if (map == null)
- return 0;
- int metric[] = (int[])map.get(new Integer(c));
- if (metric == null)
- return 0;
- return metric[1];
- }
-
- /** Generates the font descriptor for this font.
- * @return the PdfDictionary containing the font descriptor or <CODE>null</CODE>
- * @param subsetPrefix the subset prefix
- * @param fontStream the indirect reference to a PdfStream containing the font or <CODE>null</CODE>
- * @throws DocumentException if there is an error
- */
- protected PdfDictionary getFontDescriptor(PdfIndirectReference fontStream, String subsetPrefix) throws DocumentException {
- PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);
- dic.put(PdfName.ASCENT, new PdfNumber((int)os_2.sTypoAscender * 1000 / head.unitsPerEm));
- dic.put(PdfName.CAPHEIGHT, new PdfNumber((int)os_2.sCapHeight * 1000 / head.unitsPerEm));
- dic.put(PdfName.DESCENT, new PdfNumber((int)os_2.sTypoDescender * 1000 / head.unitsPerEm));
- dic.put(PdfName.FONTBBOX, new PdfRectangle(
- (int)head.xMin * 1000 / head.unitsPerEm,
- (int)head.yMin * 1000 / head.unitsPerEm,
- (int)head.xMax * 1000 / head.unitsPerEm,
- (int)head.yMax * 1000 / head.unitsPerEm));
- if (cff) {
- if (encoding.startsWith("Identity-"))
- dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName+"-"+encoding));
- else
- dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));
- }
- else
- dic.put(PdfName.FONTNAME, new PdfName(subsetPrefix + fontName + style));
- dic.put(PdfName.ITALICANGLE, new PdfNumber(italicAngle));
- dic.put(PdfName.STEMV, new PdfNumber(80));
- if (fontStream != null) {
- if (cff)
- dic.put(PdfName.FONTFILE3, fontStream);
- else
- dic.put(PdfName.FONTFILE2, fontStream);
- }
- int flags = 0;
- if (isFixedPitch)
- flags |= 1;
- flags |= fontSpecific ? 4 : 32;
- if ((head.macStyle & 2) != 0)
- flags |= 64;
- if ((head.macStyle & 1) != 0)
- flags |= 262144;
- dic.put(PdfName.FLAGS, new PdfNumber(flags));
-
- return dic;
- }
-
- /** Generates the font dictionary for this font.
- * @return the PdfDictionary containing the font dictionary
- * @param subsetPrefix the subset prefx
- * @param firstChar the first valid character
- * @param lastChar the last valid character
- * @param shortTag a 256 bytes long <CODE>byte</CODE> array where each unused byte is represented by 0
- * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or <CODE>null</CODE>
- * @throws DocumentException if there is an error
- */
- protected PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, String subsetPrefix, int firstChar, int lastChar, byte shortTag[]) throws DocumentException {
- PdfDictionary dic = new PdfDictionary(PdfName.FONT);
- if (cff) {
- dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
- dic.put(PdfName.BASEFONT, new PdfName(fontName + style));
- }
- else {
- dic.put(PdfName.SUBTYPE, PdfName.TRUETYPE);
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));
- }
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName + style));
- if (!fontSpecific) {
- for (int k = firstChar; k <= lastChar; ++k) {
- if (!differences[k].equals(notdef)) {
- firstChar = k;
- break;
- }
- }
- if (encoding.equals("Cp1252") || encoding.equals("MacRoman"))
- dic.put(PdfName.ENCODING, encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);
- else {
- PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);
- PdfArray dif = new PdfArray();
- boolean gap = true;
- for (int k = firstChar; k <= lastChar; ++k) {
- if (shortTag[k] != 0) {
- if (gap) {
- dif.add(new PdfNumber(k));
- gap = false;
- }
- dif.add(new PdfName(differences[k]));
- }
- else
- gap = true;
- }
- enc.put(PdfName.DIFFERENCES, dif);
- dic.put(PdfName.ENCODING, enc);
- }
- }
- dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
- dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar));
- PdfArray wd = new PdfArray();
- for (int k = firstChar; k <= lastChar; ++k) {
- if (shortTag[k] == 0)
- wd.add(new PdfNumber(0));
- else
- wd.add(new PdfNumber(widths[k]));
- }
- dic.put(PdfName.WIDTHS, wd);
- if (fontDescriptor != null)
- dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor);
- return dic;
- }
-
- protected byte[] getFullFont() throws IOException {
- RandomAccessFileOrArray rf2 = null;
- try {
- rf2 = new RandomAccessFileOrArray(rf);
- rf2.reOpen();
- byte b[] = new byte[rf2.length()];
- rf2.readFully(b);
- return b;
- }
- finally {
- try {rf2.close();} catch (Exception e) {}
- }
- }
-
- protected static int[] compactRanges(ArrayList ranges) {
- ArrayList simp = new ArrayList();
- for (int k = 0; k < ranges.size(); ++k) {
- int[] r = (int[])ranges.get(k);
- for (int j = 0; j < r.length; j += 2) {
- simp.add(new int[]{Math.max(0, Math.min(r[j], r[j + 1])), Math.min(0xffff, Math.max(r[j], r[j + 1]))});
- }
- }
- for (int k1 = 0; k1 < simp.size() - 1; ++k1) {
- for (int k2 = k1 + 1; k2 < simp.size(); ++k2) {
- int[] r1 = (int[])simp.get(k1);
- int[] r2 = (int[])simp.get(k2);
- if ((r1[0] >= r2[0] && r1[0] <= r2[1]) || (r1[1] >= r2[0] && r1[0] <= r2[1])) {
- r1[0] = Math.min(r1[0], r2[0]);
- r1[1] = Math.max(r1[1], r2[1]);
- simp.remove(k2);
- --k2;
- }
- }
- }
- int[] s = new int[simp.size() * 2];
- for (int k = 0; k < simp.size(); ++k) {
- int[] r = (int[])simp.get(k);
- s[k * 2] = r[0];
- s[k * 2 + 1] = r[1];
- }
- return s;
- }
-
- protected void addRangeUni(HashMap longTag, boolean includeMetrics, boolean subsetp) {
- if (!subsetp && (subsetRanges != null || directoryOffset > 0)) {
- int[] rg = (subsetRanges == null && directoryOffset > 0) ? new int[]{0, 0xffff} : compactRanges(subsetRanges);
- HashMap usemap;
- if (!fontSpecific && cmap31 != null)
- usemap = cmap31;
- else if (fontSpecific && cmap10 != null)
- usemap = cmap10;
- else if (cmap31 != null)
- usemap = cmap31;
- else
- usemap = cmap10;
- for (Iterator it = usemap.entrySet().iterator(); it.hasNext();) {
- Map.Entry e = (Map.Entry)it.next();
- int[] v = (int[])e.getValue();
- Integer gi = new Integer(v[0]);
- if (longTag.containsKey(gi))
- continue;
- int c = ((Integer)e.getKey()).intValue();
- boolean skip = true;
- for (int k = 0; k < rg.length; k += 2) {
- if (c >= rg[k] && c <= rg[k + 1]) {
- skip = false;
- break;
- }
- }
- if (!skip)
- longTag.put(gi, includeMetrics ? new int[]{v[0], v[1], c} : null);
- }
- }
- }
-
- /** 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 {
- int firstChar = ((Integer)params[0]).intValue();
- int lastChar = ((Integer)params[1]).intValue();
- byte shortTag[] = (byte[])params[2];
- boolean subsetp = ((Boolean)params[3]).booleanValue() && subset;
-
- if (!subsetp) {
- firstChar = 0;
- lastChar = shortTag.length - 1;
- for (int k = 0; k < shortTag.length; ++k)
- shortTag[k] = 1;
- }
- PdfIndirectReference ind_font = null;
- PdfObject pobj = null;
- PdfIndirectObject obj = null;
- String subsetPrefix = "";
- if (embedded) {
- if (cff) {
- RandomAccessFileOrArray rf2 = new RandomAccessFileOrArray(rf);
- byte b[] = new byte[cffLength];
- try {
- rf2.reOpen();
- rf2.seek(cffOffset);
- rf2.readFully(b);
- }
- finally {
- try {
- rf2.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- pobj = new StreamFont(b, "Type1C");
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- else {
- if (subsetp)
- subsetPrefix = createSubsetPrefix();
- HashMap glyphs = new HashMap();
- for (int k = firstChar; k <= lastChar; ++k) {
- if (shortTag[k] != 0) {
- int metrics[];
- if (fontSpecific)
- metrics = getMetricsTT(k);
- else
- metrics = getMetricsTT(unicodeDifferences[k]);
- if (metrics != null)
- glyphs.put(new Integer(metrics[0]), null);
- }
- }
- addRangeUni(glyphs, false, subsetp);
- byte[] b = null;
- if (subsetp || directoryOffset != 0 || subsetRanges != null) {
- TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), glyphs, directoryOffset, true, !subsetp);
- b = sb.process();
- }
- else {
- b = getFullFont();
- }
- int lengths[] = new int[]{b.length};
- pobj = new StreamFont(b, lengths);
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- }
- pobj = getFontDescriptor(ind_font, subsetPrefix);
- if (pobj != null){
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- pobj = getFontBaseType(ind_font, subsetPrefix, firstChar, lastChar, shortTag);
- writer.addToBody(pobj, ref);
- }
-
- /** Gets the font parameter identified by <CODE>key</CODE>. Valid values
- * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>
- * and <CODE>ITALICANGLE</CODE>.
- * @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 ASCENT:
- return (float)os_2.sTypoAscender * fontSize / (float)head.unitsPerEm;
- case CAPHEIGHT:
- return (float)os_2.sCapHeight * fontSize / (float)head.unitsPerEm;
- case DESCENT:
- return (float)os_2.sTypoDescender * fontSize / (float)head.unitsPerEm;
- case ITALICANGLE:
- return (float)italicAngle;
- case BBOXLLX:
- return fontSize * (int)head.xMin / head.unitsPerEm;
- case BBOXLLY:
- return fontSize * (int)head.yMin / head.unitsPerEm;
- case BBOXURX:
- return fontSize * (int)head.xMax / head.unitsPerEm;
- case BBOXURY:
- return fontSize * (int)head.yMax / head.unitsPerEm;
- case AWT_ASCENT:
- return fontSize * (int)hhea.Ascender / head.unitsPerEm;
- case AWT_DESCENT:
- return fontSize * (int)hhea.Descender / head.unitsPerEm;
- case AWT_LEADING:
- return fontSize * (int)hhea.LineGap / head.unitsPerEm;
- case AWT_MAXADVANCE:
- return fontSize * (int)hhea.advanceWidthMax / head.unitsPerEm;
- }
- return 0;
- }
-
- /** Gets the glyph index and metrics for a character.
- * @param c the character
- * @return an <CODE>int</CODE> array with {glyph index, width}
- */
- public int[] getMetricsTT(int c) {
- if (!fontSpecific && cmap31 != null)
- return (int[])cmap31.get(new Integer(c));
- if (fontSpecific && cmap10 != null)
- return (int[])cmap10.get(new Integer(c));
- if (cmap31 != null)
- return (int[])cmap31.get(new Integer(c));
- if (cmap10 != null)
- return (int[])cmap10.get(new Integer(c));
- return null;
- }
-
- /** Gets the postscript font name.
- * @return the postscript font name
- */
- public String getPostscriptFontName() {
- return fontName;
- }
-
- /** Gets the code pages supported by the font.
- * @return the code pages supported by the font
- */
- public String[] getCodePagesSupported() {
- long cp = (((long)os_2.ulCodePageRange2) << 32) + ((long)os_2.ulCodePageRange1 & 0xffffffffL);
- int count = 0;
- long bit = 1;
- for (int k = 0; k < 64; ++k) {
- if ((cp & bit) != 0 && codePages[k] != null)
- ++count;
- bit <<= 1;
- }
- String ret[] = new String[count];
- count = 0;
- bit = 1;
- for (int k = 0; k < 64; ++k) {
- if ((cp & bit) != 0 && codePages[k] != null)
- ret[count++] = codePages[k];
- bit <<= 1;
- }
- return ret;
- }
-
- /** 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.<br>
- * For the other fonts the array has a single element with {"", "", "",
- * font name}.
- * @return the full name of the font
- */
- public String[][] getFullFontName() {
- return fullName;
- }
-
- /** 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.<br>
- * For the other fonts the array has a single element with {"", "", "",
- * font name}.
- * @return the family name of the font
- */
- public String[][] getFamilyFontName() {
- return familyName;
- }
-
- /** Checks if the font has any kerning pairs.
- * @return <CODE>true</CODE> if the font has any kerning pairs
- */
- public boolean hasKernPairs() {
- return kerning.size() > 0;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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 <code>true</code> if the kerning was applied, <code>false</code> otherwise
- */
- public boolean setKerning(char char1, char char2, int kern) {
- int metrics[] = getMetricsTT(char1);
- if (metrics == null)
- return false;
- int c1 = metrics[0];
- metrics = getMetricsTT(char2);
- if (metrics == null)
- return false;
- int c2 = metrics[0];
- kerning.put((c1 << 16) + c2, kern);
- return true;
- }
-
- protected int[] getRawCharBBox(int c, String name) {
- HashMap map = null;
- if (name == null || cmap31 == null)
- map = cmap10;
- else
- map = cmap31;
- if (map == null)
- return null;
- int metric[] = (int[])map.get(new Integer(c));
- if (metric == null || bboxes == null)
- return null;
- return bboxes[metric[0]];
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/TrueTypeFontSubSet.java b/src/main/java/com/lowagie/text/pdf/TrueTypeFontSubSet.java
deleted file mode 100644
index 5107b75..0000000
--- a/src/main/java/com/lowagie/text/pdf/TrueTypeFontSubSet.java
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * $Id: TrueTypeFontSubSet.java,v 1.48 2006/02/23 16:45: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 java.io.*;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.Arrays;
-import com.lowagie.text.DocumentException;
-import com.lowagie.text.ExceptionConverter;
-
-/** Subsets a True Type font by removing the unneeded glyphs from
- * the font.
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-class TrueTypeFontSubSet {
- static final String tableNamesSimple[] = {"cvt ", "fpgm", "glyf", "head",
- "hhea", "hmtx", "loca", "maxp", "prep"};
- static final String tableNamesCmap[] = {"cmap", "cvt ", "fpgm", "glyf", "head",
- "hhea", "hmtx", "loca", "maxp", "prep"};
- static final String tableNamesExtra[] = {"OS/2", "cmap", "cvt ", "fpgm", "glyf", "head",
- "hhea", "hmtx", "loca", "maxp", "name, prep"};
- static final int entrySelectors[] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4};
- static final int TABLE_CHECKSUM = 0;
- static final int TABLE_OFFSET = 1;
- static final int TABLE_LENGTH = 2;
- static final int HEAD_LOCA_FORMAT_OFFSET = 51;
-
- static final int ARG_1_AND_2_ARE_WORDS = 1;
- static final int WE_HAVE_A_SCALE = 8;
- static final int MORE_COMPONENTS = 32;
- static final int WE_HAVE_AN_X_AND_Y_SCALE = 64;
- static final int WE_HAVE_A_TWO_BY_TWO = 128;
-
-
- /** Contains the location of the several tables. The key is the name of
- * the table and the value is an <CODE>int[3]</CODE> where position 0
- * is the checksum, position 1 is the offset from the start of the file
- * and position 2 is the length of the table.
- */
- protected HashMap tableDirectory;
- /** The file in use.
- */
- protected RandomAccessFileOrArray rf;
- /** The file name.
- */
- protected String fileName;
- protected boolean includeCmap;
- protected boolean includeExtras;
- protected boolean locaShortTable;
- protected int locaTable[];
- protected HashMap glyphsUsed;
- protected ArrayList glyphsInList;
- protected int tableGlyphOffset;
- protected int newLocaTable[];
- protected byte newLocaTableOut[];
- protected byte newGlyfTable[];
- protected int glyfTableRealSize;
- protected int locaTableRealSize;
- protected byte outFont[];
- protected int fontPtr;
- protected int directoryOffset;
-
- /** Creates a new TrueTypeFontSubSet
- * @param directoryOffset The offset from the start of the file to the table directory
- * @param fileName the file name of the font
- * @param glyphsUsed the glyphs used
- * @param includeCmap <CODE>true</CODE> if the table cmap is to be included in the generated font
- */
- TrueTypeFontSubSet(String fileName, RandomAccessFileOrArray rf, HashMap glyphsUsed, int directoryOffset, boolean includeCmap, boolean includeExtras) {
- this.fileName = fileName;
- this.rf = rf;
- this.glyphsUsed = glyphsUsed;
- this.includeCmap = includeCmap;
- this.includeExtras = includeExtras;
- this.directoryOffset = directoryOffset;
- glyphsInList = new ArrayList(glyphsUsed.keySet());
- }
-
- /** Does the actual work of subsetting the font.
- * @throws IOException on error
- * @throws DocumentException on error
- * @return the subset font
- */
- byte[] process() throws IOException, DocumentException {
- try {
- rf.reOpen();
- createTableDirectory();
- readLoca();
- flatGlyphs();
- createNewGlyphTables();
- locaTobytes();
- assembleFont();
- return outFont;
- }
- finally {
- try {
- rf.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
-
- protected void assembleFont() throws IOException, DocumentException {
- int tableLocation[];
- int fullFontSize = 0;
- String tableNames[];
- if (includeExtras)
- tableNames = tableNamesExtra;
- else {
- if (includeCmap)
- tableNames = tableNamesCmap;
- else
- tableNames = tableNamesSimple;
- }
- int tablesUsed = 2;
- int len = 0;
- for (int k = 0; k < tableNames.length; ++k) {
- String name = tableNames[k];
- if (name.equals("glyf") || name.equals("loca"))
- continue;
- tableLocation = (int[])tableDirectory.get(name);
- if (tableLocation == null)
- continue;
- ++tablesUsed;
- fullFontSize += (tableLocation[TABLE_LENGTH] + 3) & (~3);
- }
- fullFontSize += newLocaTableOut.length;
- fullFontSize += newGlyfTable.length;
- int ref = 16 * tablesUsed + 12;
- fullFontSize += ref;
- outFont = new byte[fullFontSize];
- fontPtr = 0;
- writeFontInt(0x00010000);
- writeFontShort(tablesUsed);
- int selector = entrySelectors[tablesUsed];
- writeFontShort((1 << selector) * 16);
- writeFontShort(selector);
- writeFontShort((tablesUsed - (1 << selector)) * 16);
- for (int k = 0; k < tableNames.length; ++k) {
- String name = tableNames[k];
- tableLocation = (int[])tableDirectory.get(name);
- if (tableLocation == null)
- continue;
- writeFontString(name);
- if (name.equals("glyf")) {
- writeFontInt(calculateChecksum(newGlyfTable));
- len = glyfTableRealSize;
- }
- else if (name.equals("loca")) {
- writeFontInt(calculateChecksum(newLocaTableOut));
- len = locaTableRealSize;
- }
- else {
- writeFontInt(tableLocation[TABLE_CHECKSUM]);
- len = tableLocation[TABLE_LENGTH];
- }
- writeFontInt(ref);
- writeFontInt(len);
- ref += (len + 3) & (~3);
- }
- for (int k = 0; k < tableNames.length; ++k) {
- String name = tableNames[k];
- tableLocation = (int[])tableDirectory.get(name);
- if (tableLocation == null)
- continue;
- if (name.equals("glyf")) {
- System.arraycopy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.length);
- fontPtr += newGlyfTable.length;
- newGlyfTable = null;
- }
- else if (name.equals("loca")) {
- System.arraycopy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.length);
- fontPtr += newLocaTableOut.length;
- newLocaTableOut = null;
- }
- else {
- rf.seek(tableLocation[TABLE_OFFSET]);
- rf.readFully(outFont, fontPtr, tableLocation[TABLE_LENGTH]);
- fontPtr += (tableLocation[TABLE_LENGTH] + 3) & (~3);
- }
- }
- }
-
- protected void createTableDirectory() throws IOException, DocumentException {
- tableDirectory = new HashMap();
- rf.seek(directoryOffset);
- int id = rf.readInt();
- if (id != 0x00010000)
- throw new DocumentException(fileName + " is not a true type file.");
- int num_tables = rf.readUnsignedShort();
- rf.skipBytes(6);
- for (int k = 0; k < num_tables; ++k) {
- String tag = readStandardString(4);
- int tableLocation[] = new int[3];
- tableLocation[TABLE_CHECKSUM] = rf.readInt();
- tableLocation[TABLE_OFFSET] = rf.readInt();
- tableLocation[TABLE_LENGTH] = rf.readInt();
- tableDirectory.put(tag, tableLocation);
- }
- }
-
- protected void readLoca() throws IOException, DocumentException {
- int tableLocation[];
- tableLocation = (int[])tableDirectory.get("head");
- if (tableLocation == null)
- throw new DocumentException("Table 'head' does not exist in " + fileName);
- rf.seek(tableLocation[TABLE_OFFSET] + HEAD_LOCA_FORMAT_OFFSET);
- locaShortTable = (rf.readUnsignedShort() == 0);
- tableLocation = (int[])tableDirectory.get("loca");
- if (tableLocation == null)
- throw new DocumentException("Table 'loca' does not exist in " + fileName);
- rf.seek(tableLocation[TABLE_OFFSET]);
- if (locaShortTable) {
- int entries = tableLocation[TABLE_LENGTH] / 2;
- locaTable = new int[entries];
- for (int k = 0; k < entries; ++k)
- locaTable[k] = rf.readUnsignedShort() * 2;
- }
- else {
- int entries = tableLocation[TABLE_LENGTH] / 4;
- locaTable = new int[entries];
- for (int k = 0; k < entries; ++k)
- locaTable[k] = rf.readInt();
- }
- }
-
- protected void createNewGlyphTables() throws IOException {
- newLocaTable = new int[locaTable.length];
- int activeGlyphs[] = new int[glyphsInList.size()];
- for (int k = 0; k < activeGlyphs.length; ++k)
- activeGlyphs[k] = ((Integer)glyphsInList.get(k)).intValue();
- Arrays.sort(activeGlyphs);
- int glyfSize = 0;
- for (int k = 0; k < activeGlyphs.length; ++k) {
- int glyph = activeGlyphs[k];
- glyfSize += locaTable[glyph + 1] - locaTable[glyph];
- }
- glyfTableRealSize = glyfSize;
- glyfSize = (glyfSize + 3) & (~3);
- newGlyfTable = new byte[glyfSize];
- int glyfPtr = 0;
- int listGlyf = 0;
- for (int k = 0; k < newLocaTable.length; ++k) {
- newLocaTable[k] = glyfPtr;
- if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
- ++listGlyf;
- newLocaTable[k] = glyfPtr;
- int start = locaTable[k];
- int len = locaTable[k + 1] - start;
- if (len > 0) {
- rf.seek(tableGlyphOffset + start);
- rf.readFully(newGlyfTable, glyfPtr, len);
- glyfPtr += len;
- }
- }
- }
- }
-
- protected void locaTobytes() {
- if (locaShortTable)
- locaTableRealSize = newLocaTable.length * 2;
- else
- locaTableRealSize = newLocaTable.length * 4;
- newLocaTableOut = new byte[(locaTableRealSize + 3) & (~3)];
- outFont = newLocaTableOut;
- fontPtr = 0;
- for (int k = 0; k < newLocaTable.length; ++k) {
- if (locaShortTable)
- writeFontShort(newLocaTable[k] / 2);
- else
- writeFontInt(newLocaTable[k]);
- }
-
- }
-
- protected void flatGlyphs() throws IOException, DocumentException {
- int tableLocation[];
- tableLocation = (int[])tableDirectory.get("glyf");
- if (tableLocation == null)
- throw new DocumentException("Table 'glyf' does not exist in " + fileName);
- Integer glyph0 = new Integer(0);
- if (!glyphsUsed.containsKey(glyph0)) {
- glyphsUsed.put(glyph0, null);
- glyphsInList.add(glyph0);
- }
- tableGlyphOffset = tableLocation[TABLE_OFFSET];
- for (int k = 0; k < glyphsInList.size(); ++k) {
- int glyph = ((Integer)glyphsInList.get(k)).intValue();
- checkGlyphComposite(glyph);
- }
- }
-
- protected void checkGlyphComposite(int glyph) throws IOException {
- int start = locaTable[glyph];
- if (start == locaTable[glyph + 1]) // no contour
- return;
- rf.seek(tableGlyphOffset + start);
- int numContours = rf.readShort();
- if (numContours >= 0)
- return;
- rf.skipBytes(8);
- for(;;) {
- int flags = rf.readUnsignedShort();
- Integer cGlyph = new Integer(rf.readUnsignedShort());
- if (!glyphsUsed.containsKey(cGlyph)) {
- glyphsUsed.put(cGlyph, null);
- glyphsInList.add(cGlyph);
- }
- if ((flags & MORE_COMPONENTS) == 0)
- return;
- int skip;
- if ((flags & ARG_1_AND_2_ARE_WORDS) != 0)
- skip = 4;
- else
- skip = 2;
- if ((flags & WE_HAVE_A_SCALE) != 0)
- skip += 2;
- else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0)
- skip += 4;
- if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0)
- skip += 8;
- rf.skipBytes(skip);
- }
- }
-
- /** Reads a <CODE>String</CODE> from the font file as bytes using the Cp1252
- * encoding.
- * @param length the length of bytes to read
- * @return the <CODE>String</CODE> read
- * @throws IOException the font file could not be read
- */
- protected String readStandardString(int length) throws IOException {
- byte buf[] = new byte[length];
- rf.readFully(buf);
- try {
- return new String(buf, BaseFont.WINANSI);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- protected void writeFontShort(int n) {
- outFont[fontPtr++] = (byte)(n >> 8);
- outFont[fontPtr++] = (byte)(n);
- }
-
- protected void writeFontInt(int n) {
- outFont[fontPtr++] = (byte)(n >> 24);
- outFont[fontPtr++] = (byte)(n >> 16);
- outFont[fontPtr++] = (byte)(n >> 8);
- outFont[fontPtr++] = (byte)(n);
- }
-
- protected void writeFontString(String s) {
- byte b[] = PdfEncodings.convertToBytes(s, BaseFont.WINANSI);
- System.arraycopy(b, 0, outFont, fontPtr, b.length);
- fontPtr += b.length;
- }
-
- protected int calculateChecksum(byte b[]) {
- int len = b.length / 4;
- int v0 = 0;
- int v1 = 0;
- int v2 = 0;
- int v3 = 0;
- int ptr = 0;
- for (int k = 0; k < len; ++k) {
- v3 += (int)b[ptr++] & 0xff;
- v2 += (int)b[ptr++] & 0xff;
- v1 += (int)b[ptr++] & 0xff;
- v0 += (int)b[ptr++] & 0xff;
- }
- return v0 + (v1 << 8) + (v2 << 16) + (v3 << 24);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/TrueTypeFontUnicode.java b/src/main/java/com/lowagie/text/pdf/TrueTypeFontUnicode.java
deleted file mode 100644
index a05f744..0000000
--- a/src/main/java/com/lowagie/text/pdf/TrueTypeFontUnicode.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * $Id: TrueTypeFontUnicode.java,v 1.53 2006/02/23 16:45:48 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 java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.ArrayList;
-
-import com.lowagie.text.DocumentException;
-/** Represents a True Type font with Unicode encoding. All the character
- * in the font can be used directly by using the encoding Identity-H or
- * Identity-V. This is the only way to represent some character sets such
- * as Thai.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-class TrueTypeFontUnicode extends TrueTypeFont implements Comparator{
-
- /** <CODE>true</CODE> if the encoding is vertical.
- */
- boolean vertical = false;
-
- /** Creates a new TrueType font addressed by Unicode characters. The font
- * will always be embedded.
- * @param ttFile the location of the font on file. The file must end in '.ttf'.
- * The modifiers after the name are ignored.
- * @param enc the encoding to be applied to this font
- * @param emb true if the font is to be embedded in the PDF
- * @param ttfAfm the font as a <CODE>byte</CODE> array
- * @throws DocumentException the font is invalid
- * @throws IOException the font file could not be read
- */
- TrueTypeFontUnicode(String ttFile, String enc, boolean emb, byte ttfAfm[]) throws DocumentException, IOException {
- String nameBase = getBaseName(ttFile);
- String ttcName = getTTCName(nameBase);
- if (nameBase.length() < ttFile.length()) {
- style = ttFile.substring(nameBase.length());
- }
- encoding = enc;
- embedded = emb;
- fileName = ttcName;
- ttcIndex = "";
- if (ttcName.length() < nameBase.length())
- ttcIndex = nameBase.substring(ttcName.length() + 1);
- fontType = FONT_TYPE_TTUNI;
- if ((fileName.toLowerCase().endsWith(".ttf") || fileName.toLowerCase().endsWith(".otf") || fileName.toLowerCase().endsWith(".ttc")) && ((enc.equals(IDENTITY_H) || enc.equals(IDENTITY_V)) && emb)) {
- process(ttfAfm);
- if (os_2.fsType == 2)
- throw new DocumentException(fileName + style + " cannot be embedded due to licensing restrictions.");
- // Sivan
- if ((cmap31 == null && !fontSpecific) || (cmap10 == null && fontSpecific))
- directTextToByte=true;
- //throw new DocumentException(fileName + " " + style + " does not contain an usable cmap.");
- if (fontSpecific) {
- fontSpecific = false;
- String tempEncoding = encoding;
- encoding = "";
- createEncoding();
- encoding = tempEncoding;
- fontSpecific = true;
- }
- }
- else
- throw new DocumentException(fileName + " " + style + " is not a TTF font file.");
- vertical = enc.endsWith("V");
- }
-
-/**
- * Gets the width of a <CODE>String</CODE> in normalized 1000 units.
- * @param text the <CODE>String</CODE> to get the witdth of
- * @return the width in normalized 1000 units
- */
- public int getWidth(String text)
- {
- if (vertical)
- return text.length() * 1000;
- int total = 0;
- if (fontSpecific) {
- char cc[] = text.toCharArray();
- int len = cc.length;
- for (int k = 0; k < len; ++k) {
- char c = cc[k];
- if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
- total += getRawWidth(c & 0xff, null);
- }
- }
- else {
- int len = text.length();
- for (int k = 0; k < len; ++k)
- total += getRawWidth(text.charAt(k), encoding);
- }
- return total;
- }
-
- /** Creates a ToUnicode CMap to allow copy and paste from Acrobat.
- * @param metrics metrics[0] contains the glyph index and metrics[2]
- * contains the Unicode code
- * @throws DocumentException on error
- * @return the stream representing this CMap or <CODE>null</CODE>
- */
- private PdfStream getToUnicode(Object metrics[]) throws DocumentException {
- if (metrics.length == 0)
- return null;
- StringBuffer buf = new StringBuffer(
- "/CIDInit /ProcSet findresource begin\n" +
- "12 dict begin\n" +
- "begincmap\n" +
- "/CIDSystemInfo\n" +
- "<< /Registry (Adobe)\n" +
- "/Ordering (UCS)\n" +
- "/Supplement 0\n" +
- ">> def\n" +
- "/CMapName /Adobe-Identity-UCS def\n" +
- "/CMapType 2 def\n" +
- "1 begincodespacerange\n" +
- "<0000><FFFF>\n" +
- "endcodespacerange\n");
- int size = 0;
- for (int k = 0; k < metrics.length; ++k) {
- if (size == 0) {
- if (k != 0) {
- buf.append("endbfrange\n");
- }
- size = Math.min(100, metrics.length - k);
- buf.append(size).append(" beginbfrange\n");
- }
- --size;
- int metric[] = (int[])metrics[k];
- String fromTo = toHex(metric[0]);
- buf.append(fromTo).append(fromTo).append(toHex(metric[2])).append("\n");
- }
- buf.append(
- "endbfrange\n" +
- "endcmap\n" +
- "CMapName currentdict /CMap defineresource pop\n" +
- "end end\n");
- String s = buf.toString();
- PdfStream stream = new PdfStream(PdfEncodings.convertToBytes(s, null));
- stream.flateCompress();
- return stream;
- }
-
- /** Gets an hex string in the format "&lt;HHHH&gt;".
- * @param n the number
- * @return the hex string
- */
- static String toHex(int n) {
- String s = Integer.toHexString(n);
- return "<0000".substring(0, 5 - s.length()) + s + ">";
- }
-
- /** Generates the CIDFontTyte2 dictionary.
- * @param fontDescriptor the indirect reference to the font descriptor
- * @param subsetPrefix the subset prefix
- * @param metrics the horizontal width metrics
- * @return a stream
- */
- private PdfDictionary getCIDFontType2(PdfIndirectReference fontDescriptor, String subsetPrefix, Object metrics[]) {
- PdfDictionary dic = new PdfDictionary(PdfName.FONT);
- // sivan; cff
- if (cff) {
- dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE0);
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName+"-"+encoding));
- }
- else {
- dic.put(PdfName.SUBTYPE, PdfName.CIDFONTTYPE2);
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName));
- }
- dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor);
- if (!cff)
- dic.put(PdfName.CIDTOGIDMAP,PdfName.IDENTITY);
- PdfDictionary cdic = new PdfDictionary();
- cdic.put(PdfName.REGISTRY, new PdfString("Adobe"));
- cdic.put(PdfName.ORDERING, new PdfString("Identity"));
- cdic.put(PdfName.SUPPLEMENT, new PdfNumber(0));
- dic.put(PdfName.CIDSYSTEMINFO, cdic);
- if (!vertical) {
- dic.put(PdfName.DW, new PdfNumber(1000));
- StringBuffer buf = new StringBuffer("[");
- int lastNumber = -10;
- boolean firstTime = true;
- for (int k = 0; k < metrics.length; ++k) {
- int metric[] = (int[])metrics[k];
- if (metric[1] == 1000)
- continue;
- int m = metric[0];
- if (m == lastNumber + 1) {
- buf.append(" ").append(metric[1]);
- }
- else {
- if (!firstTime) {
- buf.append("]");
- }
- firstTime = false;
- buf.append(m).append("[").append(metric[1]);
- }
- lastNumber = m;
- }
- if (buf.length() > 1) {
- buf.append("]]");
- dic.put(PdfName.W, new PdfLiteral(buf.toString()));
- }
- }
- return dic;
- }
-
- /** Generates the font dictionary.
- * @param descendant the descendant dictionary
- * @param subsetPrefix the subset prefix
- * @param toUnicode the ToUnicode stream
- * @return the stream
- */
- private PdfDictionary getFontBaseType(PdfIndirectReference descendant, String subsetPrefix, PdfIndirectReference toUnicode) {
- PdfDictionary dic = new PdfDictionary(PdfName.FONT);
-
- dic.put(PdfName.SUBTYPE, PdfName.TYPE0);
- // The PDF Reference manual advises to add -encoding to CID font names
- if (cff)
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName+"-"+encoding));
- //dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix+fontName));
- else
- dic.put(PdfName.BASEFONT, new PdfName(subsetPrefix + fontName));
- //dic.put(PdfName.BASEFONT, new PdfName(fontName));
- dic.put(PdfName.ENCODING, new PdfName(encoding));
- dic.put(PdfName.DESCENDANTFONTS, new PdfArray(descendant));
- if (toUnicode != null)
- dic.put(PdfName.TOUNICODE, toUnicode);
- return dic;
- }
-
- /** The method used to sort the metrics array.
- * @param o1 the first element
- * @param o2 the second element
- * @return the comparisation
- */
- public int compare(Object o1, Object o2) {
- int m1 = ((int[])o1)[0];
- int m2 = ((int[])o2)[0];
- if (m1 < m2)
- return -1;
- if (m1 == m2)
- return 0;
- return 1;
- }
-
- /** 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 {
- HashMap longTag = (HashMap)params[0];
- addRangeUni(longTag, true, subset);
- Object metrics[] = longTag.values().toArray();
- Arrays.sort(metrics, this);
- PdfIndirectReference ind_font = null;
- PdfObject pobj = null;
- PdfIndirectObject obj = null;
- // sivan: cff
- if (cff) {
- RandomAccessFileOrArray rf2 = new RandomAccessFileOrArray(rf);
- byte b[] = new byte[cffLength];
- try {
- rf2.reOpen();
- rf2.seek(cffOffset);
- rf2.readFully(b);
- } finally {
- try {
- rf2.close();
- } catch (Exception e) {
- // empty on purpose
- }
- }
- if (subset || subsetRanges != null) {
- CFFFontSubset cff = new CFFFontSubset(new RandomAccessFileOrArray(b),longTag);
- b = cff.Process( (cff.getNames())[0] );
- }
- pobj = new StreamFont(b, "CIDFontType0C");
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- } else {
- byte[] b;
- if (subset || directoryOffset != 0) {
- TrueTypeFontSubSet sb = new TrueTypeFontSubSet(fileName, new RandomAccessFileOrArray(rf), longTag, directoryOffset, false, false);
- b = sb.process();
- }
- else {
- b = getFullFont();
- }
- int lengths[] = new int[]{b.length};
- pobj = new StreamFont(b, lengths);
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- String subsetPrefix = "";
- if (subset)
- subsetPrefix = createSubsetPrefix();
- PdfDictionary dic = getFontDescriptor(ind_font, subsetPrefix);
- obj = writer.addToBody(dic);
- ind_font = obj.getIndirectReference();
-
- pobj = getCIDFontType2(ind_font, subsetPrefix, metrics);
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
-
- pobj = getToUnicode(metrics);
- PdfIndirectReference toUnicodeRef = null;
-
- if (pobj != null) {
- obj = writer.addToBody(pobj);
- toUnicodeRef = obj.getIndirectReference();
- }
-
- pobj = getFontBaseType(ind_font, subsetPrefix, toUnicodeRef);
- writer.addToBody(pobj, ref);
- }
-
- /** A forbidden operation. Will throw a null pointer exception.
- * @param text the text
- * @return always <CODE>null</CODE>
- */
- byte[] convertToBytes(String text)
- {
- return null;
- }
-
- /**
- * Checks if a character exists in this font.
- * @param c the character to check
- * @return <CODE>true</CODE> if the character has a glyph,
- * <CODE>false</CODE> otherwise
- */
- public boolean charExists(char c) {
- HashMap map = null;
- if (fontSpecific)
- map = cmap10;
- else
- map = cmap31;
- if (map == null)
- return false;
- if (fontSpecific) {
- if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
- return map.get(new Integer(c & 0xff)) != null;
- else
- return false;
- }
- else
- return map.get(new Integer(c)) != null;
- }
-
- /**
- * Sets the character advance.
- * @param c the character
- * @param advance the character advance normalized to 1000 units
- * @return <CODE>true</CODE> if the advance was set,
- * <CODE>false</CODE> otherwise
- */
- public boolean setCharAdvance(char c, int advance) {
- HashMap map = null;
- if (fontSpecific)
- map = cmap10;
- else
- map = cmap31;
- if (map == null)
- return false;
- int m[] = null;
- if (fontSpecific) {
- if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
- m = (int[])map.get(new Integer(c & 0xff));
- else
- return false;
- }
- else
- m = (int[])map.get(new Integer(c));
- if (m == null)
- return false;
- else
- m[1] = advance;
- return true;
- }
-
- public int[] getCharBBox(char c) {
- if (bboxes == null)
- return null;
- HashMap map = null;
- if (fontSpecific)
- map = cmap10;
- else
- map = cmap31;
- if (map == null)
- return null;
- int m[] = null;
- if (fontSpecific) {
- if ((c & 0xff00) == 0 || (c & 0xff00) == 0xf000)
- m = (int[])map.get(new Integer(c & 0xff));
- else
- return null;
- }
- else
- m = (int[])map.get(new Integer(c));
- if (m == null)
- return null;
- return bboxes[m[0]];
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/Type1Font.java b/src/main/java/com/lowagie/text/pdf/Type1Font.java
deleted file mode 100644
index d73ce61..0000000
--- a/src/main/java/com/lowagie/text/pdf/Type1Font.java
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * $Id: Type1Font.java,v 1.65 2006/02/23 16:45: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.DocumentException;
-import java.util.HashMap;
-import java.util.StringTokenizer;
-import com.lowagie.text.pdf.fonts.FontsResourceAnchor;
-import java.io.*;
-
-/** Reads a Type1 font
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-class Type1Font extends BaseFont
-{
- private static FontsResourceAnchor resourceAnchor;
-
- /** The PFB file if the input was made with a <CODE>byte</CODE> array.
- */
- protected byte pfb[];
-/** The Postscript font name.
- */
- private String FontName;
-/** The full name of the font.
- */
- private String FullName;
-/** The family name of the font.
- */
- private String FamilyName;
-/** The weight of the font: normal, bold, etc.
- */
- private String Weight = "";
-/** The italic angle of the font, usually 0.0 or negative.
- */
- private float ItalicAngle = 0.0f;
-/** <CODE>true</CODE> if all the characters have the same
- * width.
- */
- private boolean IsFixedPitch = false;
-/** The character set of the font.
- */
- private String CharacterSet;
-/** The llx of the FontBox.
- */
- private int llx = -50;
-/** The lly of the FontBox.
- */
- private int lly = -200;
-/** The lurx of the FontBox.
- */
- private int urx = 1000;
-/** The ury of the FontBox.
- */
- private int ury = 900;
-/** The underline position.
- */
- private int UnderlinePosition = -100;
-/** The underline thickness.
- */
- private int UnderlineThickness = 50;
-/** The font's encoding name. This encoding is 'StandardEncoding' or
- * 'AdobeStandardEncoding' for a font that can be totally encoded
- * according to the characters names. For all other names the
- * font is treated as symbolic.
- */
- private String EncodingScheme = "FontSpecific";
-/** A variable.
- */
- private int CapHeight = 700;
-/** A variable.
- */
- private int XHeight = 480;
-/** A variable.
- */
- private int Ascender = 800;
-/** A variable.
- */
- private int Descender = -200;
-/** A variable.
- */
- private int StdHW;
-/** A variable.
- */
- private int StdVW = 80;
-
-/** Represents the section CharMetrics in the AFM file. Each
- * value of this array contains a <CODE>Object[4]</CODE> with an
- * Integer, Integer, String and int[]. This is the code, width, name and char bbox.
- * The key is the name of the char and also an Integer with the char number.
- */
- private HashMap CharMetrics = new HashMap();
-/** Represents the section KernPairs in the AFM file. The key is
- * the name of the first character and the value is a <CODE>Object[]</CODE>
- * with 2 elements for each kern pair. Position 0 is the name of
- * the second character and position 1 is the kerning distance. This is
- * repeated for all the pairs.
- */
- private HashMap KernPairs = new HashMap();
-/** The file in use.
- */
- private String fileName;
-/** <CODE>true</CODE> if this font is one of the 14 built in fonts.
- */
- private boolean builtinFont = false;
-/** Types of records in a PFB file. ASCII is 1 and BINARY is 2.
- * They have to appear in the PFB file in this sequence.
- */
- private static final int pfbTypes[] = {1, 2, 1};
-
- /** Creates a new Type1 font.
- * @param ttfAfm the AFM file if the input is made with a <CODE>byte</CODE> array
- * @param pfb the PFB file if the input is made with a <CODE>byte</CODE> array
- * @param afmFile the name of one of the 14 built-in fonts or the location of an AFM file. The file must end in '.afm'
- * @param enc the encoding to be applied to this font
- * @param emb true if the font is to be embedded in the PDF
- * @throws DocumentException the AFM file is invalid
- * @throws IOException the AFM file could not be read
- */
- Type1Font(String afmFile, String enc, boolean emb, byte ttfAfm[], byte pfb[]) throws DocumentException, IOException
- {
- if (emb && ttfAfm != null && pfb == null)
- throw new DocumentException("Two byte arrays are needed if the Type1 font is embedded.");
- if (emb && ttfAfm != null)
- this.pfb = pfb;
- encoding = enc;
- embedded = emb;
- fileName = afmFile;
- fontType = FONT_TYPE_T1;
- RandomAccessFileOrArray rf = null;
- InputStream is = null;
- if (BuiltinFonts14.containsKey(afmFile)) {
- embedded = false;
- builtinFont = true;
- byte buf[] = new byte[1024];
- try {
- if (resourceAnchor == null)
- resourceAnchor = new FontsResourceAnchor();
- is = getResourceStream(RESOURCE_PATH + afmFile + ".afm", resourceAnchor.getClass().getClassLoader());
- if (is == null) {
- String msg = afmFile + " not found as resource. (The *.afm files must exist as resources in the package com.lowagie.text.pdf.fonts)";
- System.err.println(msg);
- throw new DocumentException(msg);
- }
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- while (true) {
- int size = is.read(buf);
- if (size < 0)
- break;
- out.write(buf, 0, size);
- }
- buf = out.toByteArray();
- }
- finally {
- if (is != null) {
- try {
- is.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
- try {
- rf = new RandomAccessFileOrArray(buf);
- process(rf);
- }
- finally {
- if (rf != null) {
- try {
- rf.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
- }
- else if (afmFile.toLowerCase().endsWith(".afm")) {
- try {
- if (ttfAfm == null)
- rf = new RandomAccessFileOrArray(afmFile);
- else
- rf = new RandomAccessFileOrArray(ttfAfm);
- process(rf);
- }
- finally {
- if (rf != null) {
- try {
- rf.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
- }
- else if (afmFile.toLowerCase().endsWith(".pfm")) {
- try {
- ByteArrayOutputStream ba = new ByteArrayOutputStream();
- if (ttfAfm == null)
- rf = new RandomAccessFileOrArray(afmFile);
- else
- rf = new RandomAccessFileOrArray(ttfAfm);
- Pfm2afm.convert(rf, ba);
- rf.close();
- rf = new RandomAccessFileOrArray(ba.toByteArray());
- process(rf);
- }
- finally {
- if (rf != null) {
- try {
- rf.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
- }
- else
- throw new DocumentException(afmFile + " is not an AFM or PFM font file.");
- try {
- EncodingScheme = EncodingScheme.trim();
- if (EncodingScheme.equals("AdobeStandardEncoding") || EncodingScheme.equals("StandardEncoding")) {
- fontSpecific = false;
- }
- PdfEncodings.convertToBytes(" ", enc); // check if the encoding exists
- createEncoding();
- }
- catch (RuntimeException re) {
- throw re;
- }
- catch (Exception e) {
- throw new DocumentException(e);
- }
- }
-
-/** Gets the width from the font according to the <CODE>name</CODE> or,
- * if the <CODE>name</CODE> is null, meaning it is a symbolic font,
- * the char <CODE>c</CODE>.
- * @param c the char if the font is symbolic
- * @param name the glyph name
- * @return the width of the char
- */
- int getRawWidth(int c, String name) {
- Object metrics[];
- if (name == null) { // font specific
- metrics = (Object[])CharMetrics.get(new Integer(c));
- }
- else {
- if (name.equals(".notdef"))
- return 0;
- metrics = (Object[])CharMetrics.get(name);
- }
- if (metrics != null)
- return ((Integer)(metrics[1])).intValue();
- return 0;
- }
-
-/** Gets the kerning between two Unicode characters. The characters
- * are converted to names and this names are used to find the kerning
- * pairs in the <CODE>HashMap</CODE> <CODE>KernPairs</CODE>.
- * @param char1 the first char
- * @param char2 the second char
- * @return the kerning to be applied
- */
- public int getKerning(char char1, char char2)
- {
- String first = GlyphList.unicodeToName((int)char1);
- if (first == null)
- return 0;
- String second = GlyphList.unicodeToName((int)char2);
- if (second == null)
- return 0;
- Object obj[] = (Object[])KernPairs.get(first);
- if (obj == null)
- return 0;
- for (int k = 0; k < obj.length; k += 2) {
- if (second.equals(obj[k]))
- return ((Integer)obj[k + 1]).intValue();
- }
- return 0;
- }
-
-
- /** Reads the font metrics
- * @param rf the AFM file
- * @throws DocumentException the AFM file is invalid
- * @throws IOException the AFM file could not be read
- */
- public void process(RandomAccessFileOrArray rf) throws DocumentException, IOException
- {
- String line;
- boolean isMetrics = false;
- while ((line = rf.readLine()) != null)
- {
- StringTokenizer tok = new StringTokenizer(line);
- if (!tok.hasMoreTokens())
- continue;
- String ident = tok.nextToken();
- if (ident.equals("FontName"))
- FontName = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("FullName"))
- FullName = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("FamilyName"))
- FamilyName = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("Weight"))
- Weight = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("ItalicAngle"))
- ItalicAngle = Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("IsFixedPitch"))
- IsFixedPitch = tok.nextToken().equals("true");
- else if (ident.equals("CharacterSet"))
- CharacterSet = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("FontBBox"))
- {
- llx = (int)Float.valueOf(tok.nextToken()).floatValue();
- lly = (int)Float.valueOf(tok.nextToken()).floatValue();
- urx = (int)Float.valueOf(tok.nextToken()).floatValue();
- ury = (int)Float.valueOf(tok.nextToken()).floatValue();
- }
- else if (ident.equals("UnderlinePosition"))
- UnderlinePosition = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("UnderlineThickness"))
- UnderlineThickness = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("EncodingScheme"))
- EncodingScheme = tok.nextToken("\u00ff").substring(1);
- else if (ident.equals("CapHeight"))
- CapHeight = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("XHeight"))
- XHeight = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("Ascender"))
- Ascender = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("Descender"))
- Descender = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("StdHW"))
- StdHW = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("StdVW"))
- StdVW = (int)Float.valueOf(tok.nextToken()).floatValue();
- else if (ident.equals("StartCharMetrics"))
- {
- isMetrics = true;
- break;
- }
- }
- if (!isMetrics)
- throw new DocumentException("Missing StartCharMetrics in " + fileName);
- while ((line = rf.readLine()) != null)
- {
- StringTokenizer tok = new StringTokenizer(line);
- if (!tok.hasMoreTokens())
- continue;
- String ident = tok.nextToken();
- if (ident.equals("EndCharMetrics"))
- {
- isMetrics = false;
- break;
- }
- Integer C = new Integer(-1);
- Integer WX = new Integer(250);
- String N = "";
- int B[] = null;
-
- tok = new StringTokenizer(line, ";");
- while (tok.hasMoreTokens())
- {
- StringTokenizer tokc = new StringTokenizer(tok.nextToken());
- if (!tokc.hasMoreTokens())
- continue;
- ident = tokc.nextToken();
- if (ident.equals("C"))
- C = Integer.valueOf(tokc.nextToken());
- else if (ident.equals("WX"))
- WX = new Integer(Float.valueOf(tokc.nextToken()).intValue());
- else if (ident.equals("N"))
- N = tokc.nextToken();
- else if (ident.equals("B")) {
- B = new int[]{Integer.parseInt(tokc.nextToken()),
- Integer.parseInt(tokc.nextToken()),
- Integer.parseInt(tokc.nextToken()),
- Integer.parseInt(tokc.nextToken())};
- }
- }
- Object metrics[] = new Object[]{C, WX, N, B};
- if (C.intValue() >= 0)
- CharMetrics.put(C, metrics);
- CharMetrics.put(N, metrics);
- }
- if (isMetrics)
- throw new DocumentException("Missing EndCharMetrics in " + fileName);
- while ((line = rf.readLine()) != null)
- {
- StringTokenizer tok = new StringTokenizer(line);
- if (!tok.hasMoreTokens())
- continue;
- String ident = tok.nextToken();
- if (ident.equals("EndFontMetrics"))
- return;
- if (ident.equals("StartKernPairs"))
- {
- isMetrics = true;
- break;
- }
- }
- if (!isMetrics)
- throw new DocumentException("Missing EndFontMetrics in " + fileName);
- while ((line = rf.readLine()) != null)
- {
- StringTokenizer tok = new StringTokenizer(line);
- if (!tok.hasMoreTokens())
- continue;
- String ident = tok.nextToken();
- if (ident.equals("KPX"))
- {
- String first = tok.nextToken();
- String second = tok.nextToken();
- Integer width = new Integer(Float.valueOf(tok.nextToken()).intValue());
- Object relates[] = (Object[])KernPairs.get(first);
- if (relates == null)
- KernPairs.put(first, new Object[]{second, width});
- else
- {
- int n = relates.length;
- Object relates2[] = new Object[n + 2];
- System.arraycopy(relates, 0, relates2, 0, n);
- relates2[n] = second;
- relates2[n + 1] = width;
- KernPairs.put(first, relates2);
- }
- }
- else if (ident.equals("EndKernPairs"))
- {
- isMetrics = false;
- break;
- }
- }
- if (isMetrics)
- throw new DocumentException("Missing EndKernPairs in " + fileName);
- rf.close();
- }
-
-/** If the embedded flag is <CODE>false</CODE> or if the font is
- * one of the 14 built in types, it returns <CODE>null</CODE>,
- * otherwise the font is read and output in a PdfStream object.
- * @return the PdfStream containing the font or <CODE>null</CODE>
- * @throws DocumentException if there is an error reading the font
- */
- private PdfStream getFontStream() throws DocumentException
- {
- if (builtinFont || !embedded)
- return null;
- RandomAccessFileOrArray rf = null;
- try {
- String filePfb = fileName.substring(0, fileName.length() - 3) + "pfb";
- if (pfb == null)
- rf = new RandomAccessFileOrArray(filePfb);
- else
- rf = new RandomAccessFileOrArray(pfb);
- int fileLength = rf.length();
- byte st[] = new byte[fileLength - 18];
- int lengths[] = new int[3];
- int bytePtr = 0;
- for (int k = 0; k < 3; ++k) {
- if (rf.read() != 0x80)
- throw new DocumentException("Start marker missing in " + filePfb);
- if (rf.read() != pfbTypes[k])
- throw new DocumentException("Incorrect segment type in " + filePfb);
- int size = rf.read();
- size += rf.read() << 8;
- size += rf.read() << 16;
- size += rf.read() << 24;
- lengths[k] = size;
- while (size != 0) {
- int got = rf.read(st, bytePtr, size);
- if (got < 0)
- throw new DocumentException("Premature end in " + filePfb);
- bytePtr += got;
- size -= got;
- }
- }
- return new StreamFont(st, lengths);
- }
- catch (Exception e) {
- throw new DocumentException(e);
- }
- finally {
- if (rf != null) {
- try {
- rf.close();
- }
- catch (Exception e) {
- // empty on purpose
- }
- }
- }
- }
-
-/** Generates the font descriptor for this font or <CODE>null</CODE> if it is
- * one of the 14 built in fonts.
- * @param fontStream the indirect reference to a PdfStream containing the font or <CODE>null</CODE>
- * @return the PdfDictionary containing the font descriptor or <CODE>null</CODE>
- */
- private PdfDictionary getFontDescriptor(PdfIndirectReference fontStream)
- {
- if (builtinFont)
- return null;
- PdfDictionary dic = new PdfDictionary(PdfName.FONTDESCRIPTOR);
- dic.put(PdfName.ASCENT, new PdfNumber(Ascender));
- dic.put(PdfName.CAPHEIGHT, new PdfNumber(CapHeight));
- dic.put(PdfName.DESCENT, new PdfNumber(Descender));
- dic.put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury));
- dic.put(PdfName.FONTNAME, new PdfName(FontName));
- dic.put(PdfName.ITALICANGLE, new PdfNumber(ItalicAngle));
- dic.put(PdfName.STEMV, new PdfNumber(StdVW));
- if (fontStream != null)
- dic.put(PdfName.FONTFILE, fontStream);
- int flags = 0;
- if (IsFixedPitch)
- flags |= 1;
- flags |= fontSpecific ? 4 : 32;
- if (ItalicAngle < 0)
- flags |= 64;
- if (FontName.indexOf("Caps") >= 0 || FontName.endsWith("SC"))
- flags |= 131072;
- if (Weight.equals("Bold"))
- flags |= 262144;
- dic.put(PdfName.FLAGS, new PdfNumber(flags));
-
- return dic;
- }
-
- /** Generates the font dictionary for this font.
- * @return the PdfDictionary containing the font dictionary
- * @param firstChar the first valid character
- * @param lastChar the last valid character
- * @param shortTag a 256 bytes long <CODE>byte</CODE> array where each unused byte is represented by 0
- * @param fontDescriptor the indirect reference to a PdfDictionary containing the font descriptor or <CODE>null</CODE>
- */
- private PdfDictionary getFontBaseType(PdfIndirectReference fontDescriptor, int firstChar, int lastChar, byte shortTag[])
- {
- PdfDictionary dic = new PdfDictionary(PdfName.FONT);
- dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
- dic.put(PdfName.BASEFONT, new PdfName(FontName));
- boolean stdEncoding = encoding.equals("Cp1252") || encoding.equals("MacRoman");
- if (!fontSpecific) {
- for (int k = firstChar; k <= lastChar; ++k) {
- if (!differences[k].equals(notdef)) {
- firstChar = k;
- break;
- }
- }
- if (stdEncoding)
- dic.put(PdfName.ENCODING, encoding.equals("Cp1252") ? PdfName.WIN_ANSI_ENCODING : PdfName.MAC_ROMAN_ENCODING);
- else {
- PdfDictionary enc = new PdfDictionary(PdfName.ENCODING);
- PdfArray dif = new PdfArray();
- boolean gap = true;
- for (int k = firstChar; k <= lastChar; ++k) {
- if (shortTag[k] != 0) {
- if (gap) {
- dif.add(new PdfNumber(k));
- gap = false;
- }
- dif.add(new PdfName(differences[k]));
- }
- else
- gap = true;
- }
- enc.put(PdfName.DIFFERENCES, dif);
- dic.put(PdfName.ENCODING, enc);
- }
- }
- if (forceWidthsOutput || !(builtinFont && (fontSpecific || stdEncoding))) {
- dic.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
- dic.put(PdfName.LASTCHAR, new PdfNumber(lastChar));
- PdfArray wd = new PdfArray();
- for (int k = firstChar; k <= lastChar; ++k) {
- if (shortTag[k] == 0)
- wd.add(new PdfNumber(0));
- else
- wd.add(new PdfNumber(widths[k]));
- }
- dic.put(PdfName.WIDTHS, wd);
- }
- if (!builtinFont && fontDescriptor != null)
- dic.put(PdfName.FONTDESCRIPTOR, fontDescriptor);
- return dic;
- }
-
- /** 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 {
- int firstChar = ((Integer)params[0]).intValue();
- int lastChar = ((Integer)params[1]).intValue();
- byte shortTag[] = (byte[])params[2];
- boolean subsetp = ((Boolean)params[3]).booleanValue() && subset;
- if (!subsetp) {
- firstChar = 0;
- lastChar = shortTag.length - 1;
- for (int k = 0; k < shortTag.length; ++k)
- shortTag[k] = 1;
- }
- PdfIndirectReference ind_font = null;
- PdfObject pobj = null;
- PdfIndirectObject obj = null;
- pobj = getFontStream();
- if (pobj != null){
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- pobj = getFontDescriptor(ind_font);
- if (pobj != null){
- obj = writer.addToBody(pobj);
- ind_font = obj.getIndirectReference();
- }
- pobj = getFontBaseType(ind_font, firstChar, lastChar, shortTag);
- writer.addToBody(pobj, ref);
- }
-
- /** Gets the font parameter identified by <CODE>key</CODE>. Valid values
- * for <CODE>key</CODE> are <CODE>ASCENT</CODE>, <CODE>CAPHEIGHT</CODE>, <CODE>DESCENT</CODE>,
- * <CODE>ITALICANGLE</CODE>, <CODE>BBOXLLX</CODE>, <CODE>BBOXLLY</CODE>, <CODE>BBOXURX</CODE>
- * and <CODE>BBOXURY</CODE>.
- * @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 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 postscript font name.
- * @return the postscript font name
- */
- 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.<br>
- * 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[][]{{"", "", "", FullName}};
- }
-
- /** 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.<br>
- * For the other fonts the array has a single element with {"", "", "",
- * font name}.
- * @return the family name of the font
- */
- public String[][] getFamilyFontName() {
- return new String[][]{{"", "", "", FamilyName}};
- }
-
- /** Checks if the font has any kerning pairs.
- * @return <CODE>true</CODE> if the font has any kerning pairs
- */
- public boolean hasKernPairs() {
- return KernPairs.size() > 0;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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 <code>true</code> if the kerning was applied, <code>false</code> otherwise
- */
- public boolean setKerning(char char1, char char2, int kern) {
- String first = GlyphList.unicodeToName((int)char1);
- if (first == null)
- return false;
- String second = GlyphList.unicodeToName((int)char2);
- if (second == null)
- return false;
- Object obj[] = (Object[])KernPairs.get(first);
- if (obj == null) {
- obj = new Object[]{second, new Integer(kern)};
- KernPairs.put(first, obj);
- return true;
- }
- for (int k = 0; k < obj.length; k += 2) {
- if (second.equals(obj[k])) {
- obj[k + 1] = new Integer(kern);
- return true;
- }
- }
- int size = obj.length;
- Object obj2[] = new Object[size + 2];
- System.arraycopy(obj, 0, obj2, 0, size);
- obj2[size] = second;
- obj2[size + 1] = new Integer(kern);
- KernPairs.put(first, obj2);
- return true;
- }
-
- protected int[] getRawCharBBox(int c, String name) {
- Object metrics[];
- if (name == null) { // font specific
- metrics = (Object[])CharMetrics.get(new Integer(c));
- }
- else {
- if (name.equals(".notdef"))
- return null;
- metrics = (Object[])CharMetrics.get(name);
- }
- if (metrics != null)
- return ((int[])(metrics[3]));
- return null;
- }
-
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/Type3Font.java b/src/main/java/com/lowagie/text/pdf/Type3Font.java
deleted file mode 100644
index f1d4e51..0000000
--- a/src/main/java/com/lowagie/text/pdf/Type3Font.java
+++ /dev/null
@@ -1,306 +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.DocumentException;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * A class to support Type3 fonts.
- */
-public class Type3Font extends BaseFont {
-
- private IntHashtable char2byte = new IntHashtable();
- private IntHashtable widths3 = new IntHashtable();
- private HashMap char2glyph = new HashMap();
- private PdfWriter writer;
- private float llx = Float.NaN, lly, urx, ury;
- private PageResources pageResources = new PageResources();
- private boolean colorized;
-
- /**
- * Creates a Type3 font. This implementation assumes that the /FontMatrix is
- * [0.001 0 0 0.001 0 0] or a 1000-unit glyph coordinate system.
- * <p>
- * An example:
- * <p>
- * <pre>
- * Document document = new Document(PageSize.A4);
- * PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("type3.pdf"));
- * document.open();
- * Type3Font t3 = new Type3Font(writer, new char[]{'a', 'b'}, false);
- * PdfContentByte g = t3.defineGlyph('a', 1000, 0, 0, 750, 750);
- * g.rectangle(0, 0, 750, 750);
- * g.fill();
- * g = t3.defineGlyph('b', 1000, 0, 0, 750, 750);
- * g.moveTo(0, 0);
- * g.lineTo(375, 750);
- * g.lineTo(750, 0);
- * g.fill();
- * Font f = new Font(t3, 12);
- * document.add(new Paragraph("ababab", f));
- * document.close();
- * </pre>
- * @param writer the writer
- * @param chars an array of chars corresponding to the glyphs used
- * @param colorized if <CODE>true</CODE> the font may specify color, if <CODE>false</CODE> no color commands are allowed
- * and only images as masks can be used
- */
- public Type3Font(PdfWriter writer, char[] chars, boolean colorized) {
- this.writer = writer;
- this.colorized = colorized;
- fontType = FONT_TYPE_T3;
- if (chars.length == 0 || chars.length > 256)
- throw new IllegalArgumentException("char array size must be > 0 and <= 256");
- int count = 255;
- boolean[] hits = new boolean[chars.length];
- for (int k = 0; k < chars.length; ++k) {
- char c = chars[k];
- if (c >= 32 && c < 256) {
- if (char2byte.containsKey(c))
- throw new IllegalArgumentException("duplicated char - " + (int)c + ", index " + k);
- char2byte.put(c, c);
- hits[k] = true;
- }
- }
- for (int k = 0; k < hits.length; ++k) {
- if (hits[k])
- continue;
- while (char2byte.containsKey(count)) {
- --count;
- }
- char c = chars[k];
- if (char2byte.containsKey(c))
- throw new IllegalArgumentException("duplicated char - " + (int)c + ", index " + k);
- char2byte.put(c, count--);
- }
- }
-
- /**
- * Defines a glyph.
- * @param c the character to match this glyph. It must be one of those defined in the constructor
- * @param wx the advance this character will have
- * @param llx the X lower left corner of the glyph bounding box. If the <CODE>colorize</CODE> option is
- * <CODE>true</CODE> the value is ignored
- * @param lly the Y lower left corner of the glyph bounding box. If the <CODE>colorize</CODE> option is
- * <CODE>true</CODE> the value is ignored
- * @param urx the X upper right corner of the glyph bounding box. If the <CODE>colorize</CODE> option is
- * <CODE>true</CODE> the value is ignored
- * @param ury the Y upper right corner of the glyph bounding box. If the <CODE>colorize</CODE> option is
- * <CODE>true</CODE> the value is ignored
- * @return a content where the glyph can be defined
- */
- public PdfContentByte defineGlyph(char c, float wx, float llx, float lly, float urx, float ury) {
- if (!char2byte.containsKey(c))
- throw new IllegalArgumentException("The char " + (int)c + " doesn't belong in this Type3 font");
- Integer ck = new Integer((int)c);
- Type3Glyph glyph = (Type3Glyph)char2glyph.get(ck);
- if (glyph != null)
- return glyph;
- widths3.put(c, (int)wx);
- if (!colorized) {
- if (Float.isNaN(this.llx)) {
- this.llx = llx;
- this.lly = lly;
- this.urx = urx;
- this.ury = ury;
- }
- else {
- this.llx = Math.min(this.llx, llx);
- this.lly = Math.min(this.lly, lly);
- this.urx = Math.max(this.urx, urx);
- this.ury = Math.max(this.ury, ury);
- }
- }
- glyph = new Type3Glyph(writer, pageResources, wx, llx, lly, urx, ury, colorized);
- char2glyph.put(ck, glyph);
- return glyph;
- }
-
- public String[][] getFamilyFontName() {
- return new String[0][];
- }
-
- public float getFontDescriptor(int key, float fontSize) {
- return 0;
- }
-
- public String[][] getFullFontName() {
- return new String[0][];
- }
-
- public int getKerning(char char1, char char2) {
- return 0;
- }
-
- public String getPostscriptFontName() {
- return "";
- }
-
- protected int[] getRawCharBBox(int c, String name) {
- return null;
- }
-
- int getRawWidth(int c, String name) {
- return 0;
- }
-
- public boolean hasKernPairs() {
- return false;
- }
-
- public boolean setKerning(char char1, char char2, int kern) {
- return false;
- }
-
- public void setPostscriptFontName(String name) {
- }
-
- void writeFont(PdfWriter writer, PdfIndirectReference ref, Object[] params) throws com.lowagie.text.DocumentException, java.io.IOException {
- if (this.writer != writer)
- throw new IllegalArgumentException("Type3 font used with the wrong PdfWriter");
- if (char2byte.size() != widths3.size())
- throw new DocumentException("Not all the glyphs in the Type3 font are defined");
- IntHashtable inv = new IntHashtable();
- for (Iterator it = char2byte.getEntryIterator(); it.hasNext();) {
- IntHashtable.IntHashtableEntry entry = (IntHashtable.IntHashtableEntry)it.next();
- inv.put(entry.getValue(), entry.getKey());
- }
- int[] invOrd = inv.toOrderedKeys();
- int firstChar = invOrd[0];
- int lastChar = invOrd[invOrd.length - 1];
- int[] widths = new int[lastChar - firstChar + 1];
- for (int k = 0; k < widths.length; ++k) {
- if (inv.containsKey(k + firstChar))
- widths[k] = widths3.get(inv.get(k + firstChar));
- }
- PdfArray diffs = new PdfArray();
- PdfDictionary charprocs = new PdfDictionary();
- int last = -1;
- for (int k = 0; k < invOrd.length; ++k) {
- int c = invOrd[k];
- if (c > last) {
- last = c;
- diffs.add(new PdfNumber(last));
- }
- ++last;
- int c2 = inv.get(c);
- String s = GlyphList.unicodeToName(c2);
- if (s == null)
- s = "a" + c2;
- PdfName n = new PdfName(s);
- diffs.add(n);
- Type3Glyph glyph = (Type3Glyph)char2glyph.get(new Integer(c2));
- PdfStream stream = new PdfStream(glyph.toPdf(null));
- stream.flateCompress();
- PdfIndirectReference refp = writer.addToBody(stream).getIndirectReference();
- charprocs.put(n, refp);
- }
- PdfDictionary font = new PdfDictionary(PdfName.FONT);
- font.put(PdfName.SUBTYPE, PdfName.TYPE3);
- if (colorized)
- font.put(PdfName.FONTBBOX, new PdfRectangle(0, 0, 0, 0));
- else
- font.put(PdfName.FONTBBOX, new PdfRectangle(llx, lly, urx, ury));
- font.put(PdfName.FONTMATRIX, new PdfArray(new float[]{0.001f, 0, 0, 0.001f, 0, 0}));
- font.put(PdfName.CHARPROCS, writer.addToBody(charprocs).getIndirectReference());
- PdfDictionary encoding = new PdfDictionary();
- encoding.put(PdfName.DIFFERENCES, diffs);
- font.put(PdfName.ENCODING, writer.addToBody(encoding).getIndirectReference());
- font.put(PdfName.FIRSTCHAR, new PdfNumber(firstChar));
- font.put(PdfName.LASTCHAR, new PdfNumber(lastChar));
- font.put(PdfName.WIDTHS, writer.addToBody(new PdfArray(widths)).getIndirectReference());
- if (pageResources.hasResources())
- font.put(PdfName.RESOURCES, writer.addToBody(pageResources.getResources()).getIndirectReference());
- writer.addToBody(font, ref);
- }
-
- byte[] convertToBytes(String text) {
- char[] cc = text.toCharArray();
- byte[] b = new byte[cc.length];
- int p = 0;
- for (int k = 0; k < cc.length; ++k) {
- char c = cc[k];
- if (char2byte.containsKey(c))
- b[p++] = (byte)char2byte.get(c);
- }
- if (b.length == p)
- return b;
- byte[] b2 = new byte[p];
- System.arraycopy(b, 0, b2, 0, p);
- return b2;
- }
-
- public int getWidth(char char1) {
- if (!widths3.containsKey(char1))
- throw new IllegalArgumentException("The char " + (int)char1 + " is not defined in a Type3 font");
- return widths3.get(char1);
- }
-
- public int getWidth(String text) {
- char[] c = text.toCharArray();
- int total = 0;
- for (int k = 0; k < c.length; ++k)
- total += getWidth(c[k]);
- return total;
- }
-
- public int[] getCharBBox(char c) {
- return null;
- }
-
- public boolean charExists(char c) {
- return char2byte.containsKey(c);
- }
-
- public boolean setCharAdvance(char c, int advance) {
- return false;
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/Type3Glyph.java b/src/main/java/com/lowagie/text/pdf/Type3Glyph.java
deleted file mode 100644
index 4c03a5e..0000000
--- a/src/main/java/com/lowagie/text/pdf/Type3Glyph.java
+++ /dev/null
@@ -1,94 +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.DocumentException;
-import com.lowagie.text.Image;
-/**
- * The content where Type3 glyphs are written to.
- */
-public class Type3Glyph extends PdfContentByte {
-
- private PageResources pageResources;
- private boolean colorized;
-
- private Type3Glyph() {
- super(null);
- }
-
- Type3Glyph(PdfWriter writer, PageResources pageResources, float wx, float llx, float lly, float urx, float ury, boolean colorized) {
- super(writer);
- this.pageResources = pageResources;
- this.colorized = colorized;
- if (colorized) {
- content.append(wx).append(" 0 d0\n");
- }
- else {
- content.append(wx).append(" 0 ").append(llx).append(' ').append(lly).append(' ').append(urx).append(' ').append(ury).append(" d1\n");
- }
- }
-
- PageResources getPageResources() {
- return pageResources;
- }
-
- public void addImage(Image image, float a, float b, float c, float d, float e, float f, boolean inlineImage) throws DocumentException {
- if (!colorized && (!image.isMask() || !(image.bpc() == 1 || image.bpc() > 0xff)))
- throw new DocumentException("Not colorized Typed3 fonts only accept mask images.");
- super.addImage(image, a, b, c, d, e, f, inlineImage);
- }
-
- public PdfContentByte getDuplicate() {
- Type3Glyph dup = new Type3Glyph();
- dup.writer = writer;
- dup.pdf = pdf;
- dup.pageResources = pageResources;
- dup.colorized = colorized;
- return dup;
- }
-
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/VerticalText.java b/src/main/java/com/lowagie/text/pdf/VerticalText.java
deleted file mode 100644
index 8ebc359..0000000
--- a/src/main/java/com/lowagie/text/pdf/VerticalText.java
+++ /dev/null
@@ -1,349 +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 java.util.ArrayList;
-import java.util.Iterator;
-import com.lowagie.text.Phrase;
-import com.lowagie.text.Chunk;
-import com.lowagie.text.Element;
-import com.lowagie.text.DocumentException;
-import java.awt.Color;
-
-/** Writes text vertically. Note that the naming is done according
- * to horizontal text although it referrs to vertical text.
- * A line with the alignment Element.LEFT_ALIGN will actually
- * be top aligned.
- */
-public class VerticalText {
-
-/** Signals that there are 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 chunks that form the text. */
- protected ArrayList chunks = new ArrayList();
-
- /** The <CODE>PdfContent</CODE> where the text will be written to. */
- protected PdfContentByte text;
-
- /** The column alignment. Default is left alignment. */
- protected int alignment = Element.ALIGN_LEFT;
-
- /** Marks the chunks to be eliminated when the line is written. */
- protected int currentChunkMarker = -1;
-
- /** The chunk created by the splitting. */
- protected PdfChunk currentStandbyChunk;
-
- /** The chunk created by the splitting. */
- protected String splittedChunkText;
-
- /** The leading
- */
- protected float leading;
-
- /** The X coordinate.
- */
- protected float startX;
-
- /** The Y coordinate.
- */
- protected float startY;
-
- /** The maximum number of vertical lines.
- */
- protected int maxLines;
-
- /** The height of the text.
- */
- protected float height;
-
- /** Creates new VerticalText
- * @param text the place where the text will be written to. Can
- * be a template.
- */
- public VerticalText(PdfContentByte text) {
- this.text = text;
- }
-
- /**
- * Adds a <CODE>Phrase</CODE> to the current text array.
- * @param phrase the text
- */
- public void addText(Phrase phrase) {
- for (Iterator j = phrase.getChunks().iterator(); j.hasNext();) {
- chunks.add(new PdfChunk((Chunk)j.next(), null));
- }
- }
-
- /**
- * Adds a <CODE>Chunk</CODE> to the current text array.
- * @param chunk the text
- */
- public void addText(Chunk chunk) {
- chunks.add(new PdfChunk(chunk, null));
- }
-
- /** Sets the layout.
- * @param startX the top right X line position
- * @param startY the top right Y line position
- * @param height the height of the lines
- * @param maxLines the maximum number of lines
- * @param leading the separation between the lines
- */
- public void setVerticalLayout(float startX, float startY, float height, int maxLines, float leading) {
- this.startX = startX;
- this.startY = startY;
- this.height = height;
- this.maxLines = maxLines;
- setLeading(leading);
- }
-
- /** Sets the separation between the vertical lines.
- * @param leading the vertical line separation
- */
- public void setLeading(float leading) {
- this.leading = leading;
- }
-
- /** Gets the separation between the vertical lines.
- * @return the vertical line separation
- */
- public float getLeading() {
- return leading;
- }
-
- /**
- * Creates a line from the chunk array.
- * @param width the width of the line
- * @return the line or null if no more chunks
- */
- protected PdfLine createLine(float width) {
- if (chunks.size() == 0)
- return null;
- splittedChunkText = null;
- currentStandbyChunk = null;
- PdfLine line = new PdfLine(0, width, alignment, 0);
- String total;
- for (currentChunkMarker = 0; currentChunkMarker < chunks.size(); ++currentChunkMarker) {
- PdfChunk original = (PdfChunk)(chunks.get(currentChunkMarker));
- total = original.toString();
- currentStandbyChunk = line.add(original);
- if (currentStandbyChunk != null) {
- splittedChunkText = original.toString();
- original.setValue(total);
- return line;
- }
- }
- return line;
- }
-
- /**
- * Normalizes the list of chunks when the line is accepted.
- */
- protected void shortenChunkArray() {
- if (currentChunkMarker < 0)
- return;
- if (currentChunkMarker >= chunks.size()) {
- chunks.clear();
- return;
- }
- PdfChunk split = (PdfChunk)(chunks.get(currentChunkMarker));
- split.setValue(splittedChunkText);
- chunks.set(currentChunkMarker, currentStandbyChunk);
- for (int j = currentChunkMarker - 1; j >= 0; --j)
- chunks.remove(j);
- }
-
- /**
- * Outputs the lines to the document. It is equivalent to <CODE>go(false)</CODE>.
- * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE>
- * and/or <CODE>NO_MORE_COLUMN</CODE>
- * @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 <CODE>true</CODE> to simulate the writting to the document
- * @return returns the result of the operation. It can be <CODE>NO_MORE_TEXT</CODE>
- * and/or <CODE>NO_MORE_COLUMN</CODE>
- * @throws DocumentException on error
- */
- public int go(boolean simulate) throws DocumentException {
- boolean dirty = false;
- PdfContentByte graphics = null;
- if (text != null) {
- graphics = text.getDuplicate();
- }
- else if (simulate == false)
- throw new NullPointerException("VerticalText.go with simulate==false and text==null.");
- int status = 0;
- for (;;) {
- if (maxLines <= 0) {
- status = NO_MORE_COLUMN;
- if (chunks.size() == 0)
- status |= NO_MORE_TEXT;
- break;
- }
- if (chunks.size() == 0) {
- status = NO_MORE_TEXT;
- break;
- }
- PdfLine line = createLine(height);
- if (!simulate && !dirty) {
- text.beginText();
- dirty = true;
- }
- shortenChunkArray();
- if (!simulate) {
- text.setTextMatrix(startX, startY - line.indentLeft());
- writeLine(line, text, graphics);
- }
- --maxLines;
- startX -= leading;
- }
- if (dirty) {
- text.endText();
- text.add(graphics);
- }
- return status;
- }
-
- void writeLine(PdfLine line, PdfContentByte text, PdfContentByte graphics) throws DocumentException {
- PdfFont currentFont = null;
- PdfChunk chunk;
- for (Iterator j = line.iterator(); j.hasNext(); ) {
- chunk = (PdfChunk) j.next();
-
- if (chunk.font().compareTo(currentFont) != 0) {
- currentFont = chunk.font();
- text.setFontAndSize(currentFont.getFont(), currentFont.size());
- }
- Color color = chunk.color();
- if (color != null)
- text.setColorFill(color);
- text.showText(chunk.toString());
- if (color != null)
- text.resetRGBColorFill();
- }
- }
-
- /** Sets the new text origin.
- * @param startX the X coordinate
- * @param startY the Y coordinate
- */
- public void setOrigin(float startX, float startY) {
- this.startX = startX;
- this.startY = startY;
- }
-
- /** Gets the X coordinate where the next line will be writen. This value will change
- * after each call to <code>go()</code>.
- * @return the X coordinate
- */
- public float getOriginX() {
- return startX;
- }
-
- /** Gets the Y coordinate where the next line will be writen.
- * @return the Y coordinate
- */
- public float getOriginY() {
- return startY;
- }
-
- /** Gets the maximum number of available lines. This value will change
- * after each call to <code>go()</code>.
- * @return Value of property maxLines.
- */
- public int getMaxLines() {
- return maxLines;
- }
-
- /** Sets the maximum number of lines.
- * @param maxLines the maximum number of lines
- */
- public void setMaxLines(int maxLines) {
- this.maxLines = maxLines;
- }
-
- /** Gets the height of the line
- * @return the height
- */
- public float getHeight() {
- return height;
- }
-
- /** Sets the height of the line
- * @param height the new height
- */
- public void setHeight(float height) {
- this.height = height;
- }
-
- /**
- * 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;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/XfdfReader.java b/src/main/java/com/lowagie/text/pdf/XfdfReader.java
deleted file mode 100644
index e3a7067..0000000
--- a/src/main/java/com/lowagie/text/pdf/XfdfReader.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *
- * Copyright 2004 by Leonard Rosenthol.
- *
- * 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.IOException;
-import java.io.FileInputStream;
-import java.util.HashMap;
-import java.util.Stack;
-
-/**
- * Reads a XFDF.
- * @author Leonard Rosenthol (leonardr@pdfsages.com)
- */
-public class XfdfReader implements SimpleXMLDocHandler {
- // stuff used during parsing to handle state
- private boolean foundRoot = false;
- private Stack fieldNames = new Stack();
- private Stack fieldValues = new Stack();
-
- // storage for the field list and their values
- HashMap fields;
-
- // storage for the path to referenced PDF, if any
- String fileSpec;
-
- /** Reads an XFDF form.
- * @param filename the file name of the form
- * @throws IOException on error
- */
- public XfdfReader(String filename) throws IOException {
- FileInputStream fin = null;
- try {
- fin = new FileInputStream(filename);
- SimpleXMLParser.parse(this, fin);
- }
- finally {
- try{fin.close();}catch(Exception e){}
- }
- }
-
- /** Reads an XFDF form.
- * @param xfdfIn the byte array with the form
- * @throws IOException on error
- */
- public XfdfReader(byte xfdfIn[]) throws IOException {
- SimpleXMLParser.parse( this, new ByteArrayInputStream(xfdfIn));
- }
-
- /** Gets all the fields. The map is keyed by the fully qualified
- * field name and the value is a merged <CODE>PdfDictionary</CODE>
- * with the field content.
- * @return all the fields
- */
- public HashMap getFields() {
- return fields;
- }
-
- /** Gets the field value.
- * @param name the fully qualified field name
- * @return the field's value
- */
- public String getField(String name) {
- return (String)fields.get(name);
- }
-
- /** Gets the field value or <CODE>null</CODE> if the field does not
- * exist or has no value defined.
- * @param name the fully qualified field name
- * @return the field value or <CODE>null</CODE>
- */
- public String getFieldValue(String name) {
- String field = (String)fields.get(name);
- if (field == null)
- return null;
- else
- return field;
- }
-
- /** Gets the PDF file specification contained in the FDF.
- * @return the PDF file specification contained in the FDF
- */
- public String getFileSpec() {
- return fileSpec;
- }
-
- /**
- * Called when a start tag is found.
- * @param tag the tag name
- * @param h the tag's attributes
- */
- public void startElement(String tag, HashMap h)
- {
- if ( !foundRoot ) {
- if (!tag.equals("xfdf"))
- throw new RuntimeException("Root element is not Bookmark.");
- else
- foundRoot = true;
- }
-
- if ( tag.equals("xfdf") ){
-
- } else if ( tag.equals("f") ) {
- fileSpec = (String)h.get( "href" );
- } else if ( tag.equals("fields") ) {
- fields = new HashMap(); // init it!
- } else if ( tag.equals("field") ) {
- String fName = (String) h.get( "name" );
- fieldNames.push( fName );
- } else if ( tag.equals("value") ) {
- fieldValues.push( "" );
- }
- }
- /**
- * Called when an end tag is found.
- * @param tag the tag name
- */
- public void endElement(String tag) {
- if ( tag.equals("value") ) {
- String fName = "";
- for (int k = 0; k < fieldNames.size(); ++k) {
- fName += "." + (String)fieldNames.elementAt(k);
- }
- if (fName.startsWith("."))
- fName = fName.substring(1);
- String fVal = (String) fieldValues.pop();
- fields.put( fName, fVal );
- }
- else if (tag.equals("field") ) {
- if (!fieldNames.isEmpty())
- fieldNames.pop();
- }
- }
-
- /**
- * Called when the document starts to be parsed.
- */
- public void startDocument()
- {
- fileSpec = new String(""); // and this too...
- }
- /**
- * Called after the document is parsed.
- */
- public void endDocument()
- {
-
- }
- /**
- * Called when a text element is found.
- * @param str the text element, probably a fragment.
- */
- public void text(String str)
- {
- if (fieldNames.isEmpty() || fieldValues.isEmpty())
- return;
-
- String val = (String)fieldValues.pop();
- val += str;
- fieldValues.push(val);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/codec/BmpImage.java b/src/main/java/com/lowagie/text/pdf/codec/BmpImage.java
deleted file mode 100644
index f9f80be..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/BmpImage.java
+++ /dev/null
@@ -1,1282 +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/
- *
- *
- * The original JAI codecs have the following license
- *
- * 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.
- */
-package com.lowagie.text.pdf.codec;
-
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.*;
-import java.io.*;
-import java.util.HashMap;
-import java.net.URL;
-
-/** Reads a BMP image. All types of BMP can be read.
- * <p>
- * It is based in the JAI codec.
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class BmpImage {
-
- // BMP variables
- private InputStream inputStream;
- private long bitmapFileSize;
- private long bitmapOffset;
- private long compression;
- private long imageSize;
- private byte palette[];
- private int imageType;
- private int numBands;
- private boolean isBottomUp;
- private int bitsPerPixel;
- private int redMask, greenMask, blueMask, alphaMask;
- public HashMap properties = new HashMap();
- private long xPelsPerMeter;
- private long yPelsPerMeter;
- // BMP Image types
- private static final int VERSION_2_1_BIT = 0;
- private static final int VERSION_2_4_BIT = 1;
- private static final int VERSION_2_8_BIT = 2;
- private static final int VERSION_2_24_BIT = 3;
-
- private static final int VERSION_3_1_BIT = 4;
- private static final int VERSION_3_4_BIT = 5;
- private static final int VERSION_3_8_BIT = 6;
- private static final int VERSION_3_24_BIT = 7;
-
- private static final int VERSION_3_NT_16_BIT = 8;
- private static final int VERSION_3_NT_32_BIT = 9;
-
- private static final int VERSION_4_1_BIT = 10;
- private static final int VERSION_4_4_BIT = 11;
- private static final int VERSION_4_8_BIT = 12;
- private static final int VERSION_4_16_BIT = 13;
- private static final int VERSION_4_24_BIT = 14;
- private static final int VERSION_4_32_BIT = 15;
-
- // Color space types
- private static final int LCS_CALIBRATED_RGB = 0;
- private static final int LCS_sRGB = 1;
- private static final int LCS_CMYK = 2;
-
- // Compression Types
- private static final int BI_RGB = 0;
- private static final int BI_RLE8 = 1;
- private static final int BI_RLE4 = 2;
- private static final int BI_BITFIELDS = 3;
-
- int width;
- int height;
-
- BmpImage(InputStream is, boolean noHeader, int size) throws IOException {
- bitmapFileSize = size;
- bitmapOffset = 0;
- process(is, noHeader);
- }
-
- /** Reads a BMP from an url.
- * @param url the url
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(URL url) throws IOException {
- InputStream is = null;
- try {
- is = url.openStream();
- Image img = getImage(is);
- img.setUrl(url);
- return img;
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- /** Reads a BMP from a stream. The stream is not closed.
- * @param is the stream
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(InputStream is) throws IOException {
- return getImage(is, false, 0);
- }
-
- /** Reads a BMP from a stream. The stream is not closed.
- * The BMP may not have a header and be considered as a plain DIB.
- * @param is the stream
- * @param noHeader true to process a plain DIB
- * @param size the size of the DIB. Not used for a BMP
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(InputStream is, boolean noHeader, int size) throws IOException {
- BmpImage bmp = new BmpImage(is, noHeader, size);
- try {
- Image img = bmp.getImage();
- img.setDpi((int)((double)bmp.xPelsPerMeter * 0.0254), (int)((double)bmp.yPelsPerMeter * 0.0254));
- img.setOriginalType(Image.ORIGINAL_BMP);
- return img;
- }
- catch (BadElementException be) {
- throw new ExceptionConverter(be);
- }
- }
-
- /** Reads a BMP from a file.
- * @param file the file
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(String file) throws IOException {
- return getImage(Image.toURL(file));
- }
-
- /** Reads a BMP from a byte array.
- * @param data the byte array
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(byte data[]) throws IOException {
- InputStream is = null;
- try {
- is = new ByteArrayInputStream(data);
- Image img = getImage(is);
- img.setOriginalData(data);
- return img;
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
-
- protected void process(InputStream stream, boolean noHeader) throws IOException {
- if (noHeader || stream instanceof BufferedInputStream) {
- inputStream = stream;
- } else {
- inputStream = new BufferedInputStream(stream);
- }
- if (!noHeader) {
- // Start File Header
- if (!(readUnsignedByte(inputStream) == 'B' &&
- readUnsignedByte(inputStream) == 'M')) {
- throw new
- RuntimeException("Invalid magic value for BMP file.");
- }
-
- // Read file size
- bitmapFileSize = readDWord(inputStream);
-
- // Read the two reserved fields
- readWord(inputStream);
- readWord(inputStream);
-
- // Offset to the bitmap from the beginning
- bitmapOffset = readDWord(inputStream);
-
- // End File Header
- }
- // Start BitmapCoreHeader
- long size = readDWord(inputStream);
-
- if (size == 12) {
- width = readWord(inputStream);
- height = readWord(inputStream);
- } else {
- width = readLong(inputStream);
- height = readLong(inputStream);
- }
-
- int planes = readWord(inputStream);
- bitsPerPixel = readWord(inputStream);
-
- properties.put("color_planes", new Integer(planes));
- properties.put("bits_per_pixel", new Integer(bitsPerPixel));
-
- // As BMP always has 3 rgb bands, except for Version 5,
- // which is bgra
- numBands = 3;
- if (bitmapOffset == 0)
- bitmapOffset = size;
- if (size == 12) {
- // Windows 2.x and OS/2 1.x
- properties.put("bmp_version", "BMP v. 2.x");
-
- // Classify the image type
- if (bitsPerPixel == 1) {
- imageType = VERSION_2_1_BIT;
- } else if (bitsPerPixel == 4) {
- imageType = VERSION_2_4_BIT;
- } else if (bitsPerPixel == 8) {
- imageType = VERSION_2_8_BIT;
- } else if (bitsPerPixel == 24) {
- imageType = VERSION_2_24_BIT;
- }
-
- // Read in the palette
- int numberOfEntries = (int)((bitmapOffset-14-size) / 3);
- int sizeOfPalette = numberOfEntries*3;
- if (bitmapOffset == size) {
- switch (imageType) {
- case VERSION_2_1_BIT:
- sizeOfPalette = 2 * 3;
- break;
- case VERSION_2_4_BIT:
- sizeOfPalette = 16 * 3;
- break;
- case VERSION_2_8_BIT:
- sizeOfPalette = 256 * 3;
- break;
- case VERSION_2_24_BIT:
- sizeOfPalette = 0;
- break;
- }
- bitmapOffset = size + sizeOfPalette;
- }
- palette = new byte[sizeOfPalette];
- inputStream.read(palette, 0, sizeOfPalette);
- properties.put("palette", palette);
- } else {
-
- compression = readDWord(inputStream);
- imageSize = readDWord(inputStream);
- xPelsPerMeter = readLong(inputStream);
- yPelsPerMeter = readLong(inputStream);
- long colorsUsed = readDWord(inputStream);
- long colorsImportant = readDWord(inputStream);
-
- switch((int)compression) {
- case BI_RGB:
- properties.put("compression", "BI_RGB");
- break;
-
- case BI_RLE8:
- properties.put("compression", "BI_RLE8");
- break;
-
- case BI_RLE4:
- properties.put("compression", "BI_RLE4");
- break;
-
- case BI_BITFIELDS:
- properties.put("compression", "BI_BITFIELDS");
- break;
- }
-
- properties.put("x_pixels_per_meter", new Long(xPelsPerMeter));
- properties.put("y_pixels_per_meter", new Long(yPelsPerMeter));
- properties.put("colors_used", new Long(colorsUsed));
- properties.put("colors_important", new Long(colorsImportant));
-
- if (size == 40) {
- // Windows 3.x and Windows NT
- switch((int)compression) {
-
- case BI_RGB: // No compression
- case BI_RLE8: // 8-bit RLE compression
- case BI_RLE4: // 4-bit RLE compression
-
- if (bitsPerPixel == 1) {
- imageType = VERSION_3_1_BIT;
- } else if (bitsPerPixel == 4) {
- imageType = VERSION_3_4_BIT;
- } else if (bitsPerPixel == 8) {
- imageType = VERSION_3_8_BIT;
- } else if (bitsPerPixel == 24) {
- imageType = VERSION_3_24_BIT;
- } else if (bitsPerPixel == 16) {
- imageType = VERSION_3_NT_16_BIT;
- redMask = 0x7C00;
- greenMask = 0x3E0;
- blueMask = 0x1F;
- properties.put("red_mask", new Integer(redMask));
- properties.put("green_mask", new Integer(greenMask));
- properties.put("blue_mask", new Integer(blueMask));
- } else if (bitsPerPixel == 32) {
- imageType = VERSION_3_NT_32_BIT;
- redMask = 0x00FF0000;
- greenMask = 0x0000FF00;
- blueMask = 0x000000FF;
- properties.put("red_mask", new Integer(redMask));
- properties.put("green_mask", new Integer(greenMask));
- properties.put("blue_mask", new Integer(blueMask));
- }
-
- // Read in the palette
- int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
- int sizeOfPalette = numberOfEntries*4;
- if (bitmapOffset == size) {
- switch (imageType) {
- case VERSION_3_1_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4;
- break;
- case VERSION_3_4_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4;
- break;
- case VERSION_3_8_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4;
- break;
- default:
- sizeOfPalette = 0;
- break;
- }
- bitmapOffset = size + sizeOfPalette;
- }
- palette = new byte[sizeOfPalette];
- inputStream.read(palette, 0, sizeOfPalette);
- properties.put("palette", palette);
-
- properties.put("bmp_version", "BMP v. 3.x");
- break;
-
- case BI_BITFIELDS:
-
- if (bitsPerPixel == 16) {
- imageType = VERSION_3_NT_16_BIT;
- } else if (bitsPerPixel == 32) {
- imageType = VERSION_3_NT_32_BIT;
- }
-
- // BitsField encoding
- redMask = (int)readDWord(inputStream);
- greenMask = (int)readDWord(inputStream);
- blueMask = (int)readDWord(inputStream);
-
- properties.put("red_mask", new Integer(redMask));
- properties.put("green_mask", new Integer(greenMask));
- properties.put("blue_mask", new Integer(blueMask));
-
- if (colorsUsed != 0) {
- // there is a palette
- sizeOfPalette = (int)colorsUsed*4;
- palette = new byte[sizeOfPalette];
- inputStream.read(palette, 0, sizeOfPalette);
- properties.put("palette", palette);
- }
-
- properties.put("bmp_version", "BMP v. 3.x NT");
- break;
-
- default:
- throw new
- RuntimeException("Invalid compression specified in BMP file.");
- }
- } else if (size == 108) {
- // Windows 4.x BMP
-
- properties.put("bmp_version", "BMP v. 4.x");
-
- // rgb masks, valid only if comp is BI_BITFIELDS
- redMask = (int)readDWord(inputStream);
- greenMask = (int)readDWord(inputStream);
- blueMask = (int)readDWord(inputStream);
- // Only supported for 32bpp BI_RGB argb
- alphaMask = (int)readDWord(inputStream);
- long csType = readDWord(inputStream);
- int redX = readLong(inputStream);
- int redY = readLong(inputStream);
- int redZ = readLong(inputStream);
- int greenX = readLong(inputStream);
- int greenY = readLong(inputStream);
- int greenZ = readLong(inputStream);
- int blueX = readLong(inputStream);
- int blueY = readLong(inputStream);
- int blueZ = readLong(inputStream);
- long gammaRed = readDWord(inputStream);
- long gammaGreen = readDWord(inputStream);
- long gammaBlue = readDWord(inputStream);
-
- if (bitsPerPixel == 1) {
- imageType = VERSION_4_1_BIT;
- } else if (bitsPerPixel == 4) {
- imageType = VERSION_4_4_BIT;
- } else if (bitsPerPixel == 8) {
- imageType = VERSION_4_8_BIT;
- } else if (bitsPerPixel == 16) {
- imageType = VERSION_4_16_BIT;
- if ((int)compression == BI_RGB) {
- redMask = 0x7C00;
- greenMask = 0x3E0;
- blueMask = 0x1F;
- }
- } else if (bitsPerPixel == 24) {
- imageType = VERSION_4_24_BIT;
- } else if (bitsPerPixel == 32) {
- imageType = VERSION_4_32_BIT;
- if ((int)compression == BI_RGB) {
- redMask = 0x00FF0000;
- greenMask = 0x0000FF00;
- blueMask = 0x000000FF;
- }
- }
-
- properties.put("red_mask", new Integer(redMask));
- properties.put("green_mask", new Integer(greenMask));
- properties.put("blue_mask", new Integer(blueMask));
- properties.put("alpha_mask", new Integer(alphaMask));
-
- // Read in the palette
- int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
- int sizeOfPalette = numberOfEntries*4;
- if (bitmapOffset == size) {
- switch (imageType) {
- case VERSION_4_1_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 2 : colorsUsed) * 4;
- break;
- case VERSION_4_4_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 16 : colorsUsed) * 4;
- break;
- case VERSION_4_8_BIT:
- sizeOfPalette = (int)(colorsUsed == 0 ? 256 : colorsUsed) * 4;
- break;
- default:
- sizeOfPalette = 0;
- break;
- }
- bitmapOffset = size + sizeOfPalette;
- }
- palette = new byte[sizeOfPalette];
- inputStream.read(palette, 0, sizeOfPalette);
-
- if (palette != null || palette.length != 0) {
- properties.put("palette", palette);
- }
-
- switch((int)csType) {
- case LCS_CALIBRATED_RGB:
- // All the new fields are valid only for this case
- properties.put("color_space", "LCS_CALIBRATED_RGB");
- properties.put("redX", new Integer(redX));
- properties.put("redY", new Integer(redY));
- properties.put("redZ", new Integer(redZ));
- properties.put("greenX", new Integer(greenX));
- properties.put("greenY", new Integer(greenY));
- properties.put("greenZ", new Integer(greenZ));
- properties.put("blueX", new Integer(blueX));
- properties.put("blueY", new Integer(blueY));
- properties.put("blueZ", new Integer(blueZ));
- properties.put("gamma_red", new Long(gammaRed));
- properties.put("gamma_green", new Long(gammaGreen));
- properties.put("gamma_blue", new Long(gammaBlue));
-
- // break;
- throw new
- RuntimeException("Not implemented yet.");
-
- case LCS_sRGB:
- // Default Windows color space
- properties.put("color_space", "LCS_sRGB");
- break;
-
- case LCS_CMYK:
- properties.put("color_space", "LCS_CMYK");
- // break;
- throw new
- RuntimeException("Not implemented yet.");
- }
-
- } else {
- properties.put("bmp_version", "BMP v. 5.x");
- throw new
- RuntimeException("BMP version 5 not implemented yet.");
- }
- }
-
- if (height > 0) {
- // bottom up image
- isBottomUp = true;
- } else {
- // top down image
- isBottomUp = false;
- height = Math.abs(height);
- }
- // When number of bitsPerPixel is <= 8, we use IndexColorModel.
- if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) {
-
- numBands = 1;
-
-
- // Create IndexColorModel from the palette.
- byte r[], g[], b[];
- int sizep;
- if (imageType == VERSION_2_1_BIT ||
- imageType == VERSION_2_4_BIT ||
- imageType == VERSION_2_8_BIT) {
-
- sizep = palette.length/3;
-
- if (sizep > 256) {
- sizep = 256;
- }
-
- int off;
- r = new byte[sizep];
- g = new byte[sizep];
- b = new byte[sizep];
- for (int i=0; i<sizep; i++) {
- off = 3 * i;
- b[i] = palette[off];
- g[i] = palette[off+1];
- r[i] = palette[off+2];
- }
- } else {
- sizep = palette.length/4;
-
- if (sizep > 256) {
- sizep = 256;
- }
-
- int off;
- r = new byte[sizep];
- g = new byte[sizep];
- b = new byte[sizep];
- for (int i=0; i<sizep; i++) {
- off = 4 * i;
- b[i] = palette[off];
- g[i] = palette[off+1];
- r[i] = palette[off+2];
- }
- }
-
- } else if (bitsPerPixel == 16) {
- numBands = 3;
- } else if (bitsPerPixel == 32) {
- numBands = alphaMask == 0 ? 3 : 4;
-
- // The number of bands in the SampleModel is determined by
- // the length of the mask array passed in.
- } else {
- numBands = 3;
- }
- }
-
- private byte[] getPalette(int group) {
- if (palette == null)
- return null;
- byte np[] = new byte[palette.length / group * 3];
- int e = palette.length / group;
- for (int k = 0; k < e; ++k) {
- int src = k * group;
- int dest = k * 3;
- np[dest + 2] = palette[src++];
- np[dest + 1] = palette[src++];
- np[dest] = palette[src];
- }
- return np;
- }
-
- private Image getImage() throws IOException, BadElementException {
- byte bdata[] = null; // buffer for byte data
-
- // if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE)
- // bdata = (byte[])((DataBufferByte)tile.getDataBuffer()).getData();
- // else if (sampleModel.getDataType() == DataBuffer.TYPE_USHORT)
- // sdata = (short[])((DataBufferUShort)tile.getDataBuffer()).getData();
- // else if (sampleModel.getDataType() == DataBuffer.TYPE_INT)
- // idata = (int[])((DataBufferInt)tile.getDataBuffer()).getData();
-
- // There should only be one tile.
- switch(imageType) {
-
- case VERSION_2_1_BIT:
- // no compression
- return read1Bit(3);
-
- case VERSION_2_4_BIT:
- // no compression
- return read4Bit(3);
-
- case VERSION_2_8_BIT:
- // no compression
- return read8Bit(3);
-
- case VERSION_2_24_BIT:
- // no compression
- bdata = new byte[width * height * 3];
- read24Bit(bdata);
- return new ImgRaw(width, height, 3, 8, bdata);
-
- case VERSION_3_1_BIT:
- // 1-bit images cannot be compressed.
- return read1Bit(4);
-
- case VERSION_3_4_BIT:
- switch((int)compression) {
- case BI_RGB:
- return read4Bit(4);
-
- case BI_RLE4:
- return readRLE4();
-
- default:
- throw new
- RuntimeException("Invalid compression specified for BMP file.");
- }
-
- case VERSION_3_8_BIT:
- switch((int)compression) {
- case BI_RGB:
- return read8Bit(4);
-
- case BI_RLE8:
- return readRLE8();
-
- default:
- throw new
- RuntimeException("Invalid compression specified for BMP file.");
- }
-
- case VERSION_3_24_BIT:
- // 24-bit images are not compressed
- bdata = new byte[width * height * 3];
- read24Bit(bdata);
- return new ImgRaw(width, height, 3, 8, bdata);
-
- case VERSION_3_NT_16_BIT:
- return read1632Bit(false);
-
- case VERSION_3_NT_32_BIT:
- return read1632Bit(true);
-
- case VERSION_4_1_BIT:
- return read1Bit(4);
-
- case VERSION_4_4_BIT:
- switch((int)compression) {
-
- case BI_RGB:
- return read4Bit(4);
-
- case BI_RLE4:
- return readRLE4();
-
- default:
- throw new
- RuntimeException("Invalid compression specified for BMP file.");
- }
-
- case VERSION_4_8_BIT:
- switch((int)compression) {
-
- case BI_RGB:
- return read8Bit(4);
-
- case BI_RLE8:
- return readRLE8();
-
- default:
- throw new
- RuntimeException("Invalid compression specified for BMP file.");
- }
-
- case VERSION_4_16_BIT:
- return read1632Bit(false);
-
- case VERSION_4_24_BIT:
- bdata = new byte[width * height * 3];
- read24Bit(bdata);
- return new ImgRaw(width, height, 3, 8, bdata);
-
- case VERSION_4_32_BIT:
- return read1632Bit(true);
- }
- return null;
- }
-
- private Image indexedModel(byte bdata[], int bpc, int paletteEntries) throws BadElementException {
- Image img = new ImgRaw(width, height, 1, bpc, bdata);
- PdfArray colorspace = new PdfArray();
- colorspace.add(PdfName.INDEXED);
- colorspace.add(PdfName.DEVICERGB);
- byte np[] = getPalette(paletteEntries);
- int len = np.length;
- colorspace.add(new PdfNumber(len / 3 - 1));
- colorspace.add(new PdfString(np));
- PdfDictionary ad = new PdfDictionary();
- ad.put(PdfName.COLORSPACE, colorspace);
- img.setAdditional(ad);
- return img;
- }
-
- // Deal with 1 Bit images using IndexColorModels
- private Image read1Bit(int paletteEntries) throws IOException, BadElementException {
- byte bdata[] = new byte[((width + 7) / 8) * height];
- int padding = 0;
- int bytesPerScanline = (int)Math.ceil((double)width/8.0);
-
- int remainder = bytesPerScanline % 4;
- if (remainder != 0) {
- padding = 4 - remainder;
- }
-
- int imSize = (bytesPerScanline + padding) * height;
-
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- int bytesRead = 0;
- while (bytesRead < imSize) {
- bytesRead += inputStream.read(values, bytesRead,
- imSize - bytesRead);
- }
-
- if (isBottomUp) {
-
- // Convert the bottom up image to a top down format by copying
- // one scanline from the bottom to the top at a time.
-
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- imSize - (i+1)*(bytesPerScanline + padding),
- bdata,
- i*bytesPerScanline, bytesPerScanline);
- }
- } else {
-
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- i * (bytesPerScanline + padding),
- bdata,
- i * bytesPerScanline,
- bytesPerScanline);
- }
- }
- return indexedModel(bdata, 1, paletteEntries);
- }
-
- // Method to read a 4 bit BMP image data
- private Image read4Bit(int paletteEntries) throws IOException, BadElementException {
- byte bdata[] = new byte[((width + 1) / 2) * height];
-
- // Padding bytes at the end of each scanline
- int padding = 0;
-
- int bytesPerScanline = (int)Math.ceil((double)width/2.0);
- int remainder = bytesPerScanline % 4;
- if (remainder != 0) {
- padding = 4 - remainder;
- }
-
- int imSize = (bytesPerScanline + padding) * height;
-
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- int bytesRead = 0;
- while (bytesRead < imSize) {
- bytesRead += inputStream.read(values, bytesRead,
- imSize - bytesRead);
- }
-
- if (isBottomUp) {
-
- // Convert the bottom up image to a top down format by copying
- // one scanline from the bottom to the top at a time.
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- imSize - (i+1)*(bytesPerScanline + padding),
- bdata,
- i*bytesPerScanline,
- bytesPerScanline);
- }
- } else {
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- i * (bytesPerScanline + padding),
- bdata,
- i * bytesPerScanline,
- bytesPerScanline);
- }
- }
- return indexedModel(bdata, 4, paletteEntries);
- }
-
- // Method to read 8 bit BMP image data
- private Image read8Bit(int paletteEntries) throws IOException, BadElementException {
- byte bdata[] = new byte[width * height];
- // Padding bytes at the end of each scanline
- int padding = 0;
-
- // width * bitsPerPixel should be divisible by 32
- int bitsPerScanline = width * 8;
- if ( bitsPerScanline%32 != 0) {
- padding = (bitsPerScanline/32 + 1)*32 - bitsPerScanline;
- padding = (int)Math.ceil(padding/8.0);
- }
-
- int imSize = (width + padding) * height;
-
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- int bytesRead = 0;
- while (bytesRead < imSize) {
- bytesRead += inputStream.read(values, bytesRead, imSize - bytesRead);
- }
-
- if (isBottomUp) {
-
- // Convert the bottom up image to a top down format by copying
- // one scanline from the bottom to the top at a time.
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- imSize - (i+1) * (width + padding),
- bdata,
- i * width,
- width);
- }
- } else {
- for (int i=0; i<height; i++) {
- System.arraycopy(values,
- i * (width + padding),
- bdata,
- i * width,
- width);
- }
- }
- return indexedModel(bdata, 8, paletteEntries);
- }
-
- // Method to read 24 bit BMP image data
- private void read24Bit(byte[] bdata) {
- // Padding bytes at the end of each scanline
- int padding = 0;
-
- // width * bitsPerPixel should be divisible by 32
- int bitsPerScanline = width * 24;
- if ( bitsPerScanline%32 != 0) {
- padding = (bitsPerScanline/32 + 1)*32 - bitsPerScanline;
- padding = (int)Math.ceil(padding/8.0);
- }
-
-
- int imSize = ((width * 3 + 3) / 4 * 4) * height;
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- try {
- int bytesRead = 0;
- while (bytesRead < imSize) {
- int r = inputStream.read(values, bytesRead,
- imSize - bytesRead);
- if (r < 0)
- break;
- bytesRead += r;
- }
- } catch (IOException ioe) {
- throw new ExceptionConverter(ioe);
- }
-
- int l=0, count;
-
- if (isBottomUp) {
- int max = width*height*3-1;
-
- count = -padding;
- for (int i=0; i<height; i++) {
- l = max - (i+1)*width*3 + 1;
- count += padding;
- for (int j=0; j<width; j++) {
- bdata[l + 2] = values[count++];
- bdata[l + 1] = values[count++];
- bdata[l] = values[count++];
- l += 3;
- }
- }
- } else {
- count = -padding;
- for (int i=0; i<height; i++) {
- count += padding;
- for (int j=0; j<width; j++) {
- bdata[l + 2] = values[count++];
- bdata[l + 1] = values[count++];
- bdata[l] = values[count++];
- l += 3;
- }
- }
- }
- }
-
- private int findMask(int mask) {
- int k = 0;
- for (; k < 32; ++k) {
- if ((mask & 1) == 1)
- break;
- mask >>>= 1;
- }
- return mask;
- }
-
- private int findShift(int mask) {
- int k = 0;
- for (; k < 32; ++k) {
- if ((mask & 1) == 1)
- break;
- mask >>>= 1;
- }
- return k;
- }
-
- private Image read1632Bit(boolean is32) throws IOException, BadElementException {
-
- int red_mask = findMask(redMask);
- int red_shift = findShift(redMask);
- int red_factor = red_mask + 1;
- int green_mask = findMask(greenMask);
- int green_shift = findShift(greenMask);
- int green_factor = green_mask + 1;
- int blue_mask = findMask(blueMask);
- int blue_shift = findShift(blueMask);
- int blue_factor = blue_mask + 1;
- byte bdata[] = new byte[width * height * 3];
- // Padding bytes at the end of each scanline
- int padding = 0;
-
- if (!is32) {
- // width * bitsPerPixel should be divisible by 32
- int bitsPerScanline = width * 16;
- if ( bitsPerScanline%32 != 0) {
- padding = (bitsPerScanline/32 + 1)*32 - bitsPerScanline;
- padding = (int)Math.ceil(padding/8.0);
- }
- }
-
- int imSize = (int)imageSize;
- if (imSize == 0) {
- imSize = (int)(bitmapFileSize - bitmapOffset);
- }
-
- int l=0;
- int v;
- if (isBottomUp) {
- for (int i=height - 1; i >= 0; --i) {
- l = width * 3 * i;
- for (int j=0; j<width; j++) {
- if (is32)
- v = (int)readDWord(inputStream);
- else
- v = readWord(inputStream);
- bdata[l++] = (byte)(((v >>> red_shift) & red_mask) * 256 / red_factor);
- bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor);
- bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor);
- }
- for (int m=0; m<padding; m++) {
- inputStream.read();
- }
- }
- } else {
- for (int i=0; i<height; i++) {
- for (int j=0; j<width; j++) {
- if (is32)
- v = (int)readDWord(inputStream);
- else
- v = readWord(inputStream);
- bdata[l++] = (byte)(((v >>> red_shift) & red_mask) * 256 / red_factor);
- bdata[l++] = (byte)(((v >>> green_shift) & green_mask) * 256 / green_factor);
- bdata[l++] = (byte)(((v >>> blue_shift) & blue_mask) * 256 / blue_factor);
- }
- for (int m=0; m<padding; m++) {
- inputStream.read();
- }
- }
- }
- return new ImgRaw(width, height, 3, 8, bdata);
- }
-
- private Image readRLE8() throws IOException, BadElementException {
-
- // If imageSize field is not provided, calculate it.
- int imSize = (int)imageSize;
- if (imSize == 0) {
- imSize = (int)(bitmapFileSize - bitmapOffset);
- }
-
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- int bytesRead = 0;
- while (bytesRead < imSize) {
- bytesRead += inputStream.read(values, bytesRead,
- imSize - bytesRead);
- }
-
- // Since data is compressed, decompress it
- byte val[] = decodeRLE(true, values);
-
- // Uncompressed data does not have any padding
- imSize = width * height;
-
- if (isBottomUp) {
-
- // Convert the bottom up image to a top down format by copying
- // one scanline from the bottom to the top at a time.
- // int bytesPerScanline = (int)Math.ceil((double)width/8.0);
- byte temp[] = new byte[val.length];
- int bytesPerScanline = width;
- for (int i=0; i<height; i++) {
- System.arraycopy(val,
- imSize - (i+1)*(bytesPerScanline),
- temp,
- i*bytesPerScanline, bytesPerScanline);
- }
- val = temp;
- }
- return indexedModel(val, 8, 4);
- }
-
- private Image readRLE4() throws IOException, BadElementException {
-
- // If imageSize field is not specified, calculate it.
- int imSize = (int)imageSize;
- if (imSize == 0) {
- imSize = (int)(bitmapFileSize - bitmapOffset);
- }
-
- // Read till we have the whole image
- byte values[] = new byte[imSize];
- int bytesRead = 0;
- while (bytesRead < imSize) {
- bytesRead += inputStream.read(values, bytesRead,
- imSize - bytesRead);
- }
-
- // Decompress the RLE4 compressed data.
- byte val[] = decodeRLE(false, values);
-
- // Invert it as it is bottom up format.
- if (isBottomUp) {
-
- byte inverted[] = val;
- val = new byte[width * height];
- int l = 0, index, lineEnd;
-
- for (int i = height-1; i >= 0; i--) {
- index = i * width;
- lineEnd = l + width;
- while(l != lineEnd) {
- val[l++] = inverted[index++];
- }
- }
- }
- int stride = ((width + 1) / 2);
- byte bdata[] = new byte[stride * height];
- int ptr = 0;
- int sh = 0;
- for (int h = 0; h < height; ++h) {
- for (int w = 0; w < width; ++w) {
- if ((w & 1) == 0)
- bdata[sh + w / 2] = (byte)(val[ptr++] << 4);
- else
- bdata[sh + w / 2] |= (byte)(val[ptr++] & 0x0f);
- }
- sh += stride;
- }
- return indexedModel(bdata, 4, 4);
- }
-
- private byte[] decodeRLE(boolean is8, byte values[]) {
- byte val[] = new byte[width * height];
- try {
- int ptr = 0;
- int x = 0;
- int q = 0;
- for (int y = 0; y < height && ptr < values.length;) {
- int count = values[ptr++] & 0xff;
- if (count != 0) {
- // encoded mode
- int bt = values[ptr++] & 0xff;
- if (is8) {
- for (int i = count; i != 0; --i) {
- val[q++] = (byte)bt;
- }
- }
- else {
- for (int i = 0; i < count; ++i) {
- val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f));
- }
- }
- x += count;
- }
- else {
- // escape mode
- count = values[ptr++] & 0xff;
- if (count == 1)
- break;
- switch (count) {
- case 0:
- x = 0;
- ++y;
- q = y * width;
- break;
- case 2:
- // delta mode
- x += values[ptr++] & 0xff;
- y += values[ptr++] & 0xff;
- q = y * width + x;
- break;
- default:
- // absolute mode
- if (is8) {
- for (int i = count; i != 0; --i)
- val[q++] = (byte)(values[ptr++] & 0xff);
- }
- else {
- int bt = 0;
- for (int i = 0; i < count; ++i) {
- if ((i & 1) == 0)
- bt = values[ptr++] & 0xff;
- val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >>> 4) & 0x0f));
- }
- }
- x += count;
- // read pad byte
- if (is8) {
- if ((count & 1) == 1)
- ++ptr;
- }
- else {
- if ((count & 3) == 1 || (count & 3) == 2)
- ++ptr;
- }
- break;
- }
- }
- }
- }
- catch (Exception e) {
- //empty on purpose
- }
-
- return val;
- }
-
- // Windows defined data type reading methods - everything is little endian
-
- // Unsigned 8 bits
- private int readUnsignedByte(InputStream stream) throws IOException {
- return (stream.read() & 0xff);
- }
-
- // Unsigned 2 bytes
- private int readUnsignedShort(InputStream stream) throws IOException {
- int b1 = readUnsignedByte(stream);
- int b2 = readUnsignedByte(stream);
- return ((b2 << 8) | b1) & 0xffff;
- }
-
- // Signed 16 bits
- private int readShort(InputStream stream) throws IOException {
- int b1 = readUnsignedByte(stream);
- int b2 = readUnsignedByte(stream);
- return (b2 << 8) | b1;
- }
-
- // Unsigned 16 bits
- private int readWord(InputStream stream) throws IOException {
- return readUnsignedShort(stream);
- }
-
- // Unsigned 4 bytes
- private long readUnsignedInt(InputStream stream) throws IOException {
- int b1 = readUnsignedByte(stream);
- int b2 = readUnsignedByte(stream);
- int b3 = readUnsignedByte(stream);
- int b4 = readUnsignedByte(stream);
- long l = (long)((b4 << 24) | (b3 << 16) | (b2 << 8) | b1);
- return l & 0xffffffff;
- }
-
- // Signed 4 bytes
- private int readInt(InputStream stream) throws IOException {
- int b1 = readUnsignedByte(stream);
- int b2 = readUnsignedByte(stream);
- int b3 = readUnsignedByte(stream);
- int b4 = readUnsignedByte(stream);
- return (b4 << 24) | (b3 << 16) | (b2 << 8) | b1;
- }
-
- // Unsigned 4 bytes
- private long readDWord(InputStream stream) throws IOException {
- return readUnsignedInt(stream);
- }
-
- // 32 bit signed value
- private int readLong(InputStream stream) throws IOException {
- return readInt(stream);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/CCITTG4Encoder.java b/src/main/java/com/lowagie/text/pdf/codec/CCITTG4Encoder.java
deleted file mode 100644
index ae67be1..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/CCITTG4Encoder.java
+++ /dev/null
@@ -1,600 +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/
- *
- * This code is base in the libtiff encoder
- */
-package com.lowagie.text.pdf.codec;
-
-import com.lowagie.text.pdf.ByteBuffer;
-
-/**
- * Encodes data in the CCITT G4 FAX format.
- */
-public class CCITTG4Encoder {
- private int rowbytes;
- private int rowpixels;
- private int bit = 8;
- private int data;
- private byte[] refline;
- private ByteBuffer outBuf = new ByteBuffer(1024);
- private byte[] dataBp;
- private int offsetData;
- private int sizeData;
-
- /**
- * Creates a new encoder.
- * @param width the line width
- */
- public CCITTG4Encoder(int width) {
- rowpixels = width;
- rowbytes = (rowpixels + 7) / 8;
- refline = new byte[rowbytes];
- }
-
- /**
- * Encodes a number of lines.
- * @param data the data to be encoded
- * @param offset the offset into the data
- * @param size the size of the data to be encoded
- */
- public void fax4Encode(byte[] data, int offset, int size) {
- dataBp = data;
- offsetData = offset;
- sizeData = size;
- while (sizeData > 0) {
- Fax3Encode2DRow();
- System.arraycopy(dataBp, offsetData, refline, 0, rowbytes);
- offsetData += rowbytes;
- sizeData -= rowbytes;
- }
- }
-
-
- /**
- * Encodes a full image.
- * @param data the data to encode
- * @param width the image width
- * @param height the image height
- * @return the encoded image
- */
- public static byte[] compress(byte[] data, int width, int height) {
- CCITTG4Encoder g4 = new CCITTG4Encoder(width);
- g4.fax4Encode(data, 0, g4.rowbytes * height);
- return g4.close();
- }
-
- /**
- * Encodes a number of lines.
- * @param data the data to be encoded
- * @param height the number of lines to encode
- */
- public void fax4Encode(byte[] data, int height) {
- fax4Encode(data, 0, rowbytes * height);
- }
-
- private void putcode(int[] table) {
- putBits(table[CODE], table[LENGTH]);
- }
-
- private void putspan(int span, int[][] tab) {
- int code, length;
-
- while (span >= 2624) {
- int[] te = tab[63 + (2560>>6)];
- code = te[CODE];
- length = te[LENGTH];
- putBits(code, length);
- span -= te[RUNLEN];
- }
- if (span >= 64) {
- int[] te = tab[63 + (span>>6)];
- code = te[CODE];
- length = te[LENGTH];
- putBits(code, length);
- span -= te[RUNLEN];
- }
- code = tab[span][CODE];
- length = tab[span][LENGTH];
- putBits(code, length);
- }
-
- private void putBits(int bits, int length) {
- while (length > bit) {
- data |= bits >> (length - bit);
- length -= bit;
- outBuf.append((byte)data);
- data = 0;
- bit = 8;
- }
- data |= (bits & msbmask[length]) << (bit - length);
- bit -= length;
- if (bit == 0) {
- outBuf.append((byte)data);
- data = 0;
- bit = 8;
- }
- }
-
- private void Fax3Encode2DRow() {
- int a0 = 0;
- int a1 = (pixel(dataBp, offsetData, 0) != 0 ? 0 : finddiff(dataBp, offsetData, 0, rowpixels, 0));
- int b1 = (pixel(refline, 0, 0) != 0 ? 0 : finddiff(refline, 0, 0, rowpixels, 0));
- int a2, b2;
-
- for (;;) {
- b2 = finddiff2(refline, 0, b1, rowpixels, pixel(refline, 0,b1));
- if (b2 >= a1) {
- int d = b1 - a1;
- if (!(-3 <= d && d <= 3)) { /* horizontal mode */
- a2 = finddiff2(dataBp, offsetData, a1, rowpixels, pixel(dataBp, offsetData,a1));
- putcode(horizcode);
- if (a0+a1 == 0 || pixel(dataBp, offsetData, a0) == 0) {
- putspan(a1-a0, TIFFFaxWhiteCodes);
- putspan(a2-a1, TIFFFaxBlackCodes);
- } else {
- putspan(a1-a0, TIFFFaxBlackCodes);
- putspan(a2-a1, TIFFFaxWhiteCodes);
- }
- a0 = a2;
- } else { /* vertical mode */
- putcode(vcodes[d+3]);
- a0 = a1;
- }
- } else { /* pass mode */
- putcode(passcode);
- a0 = b2;
- }
- if (a0 >= rowpixels)
- break;
- a1 = finddiff(dataBp, offsetData, a0, rowpixels, pixel(dataBp, offsetData,a0));
- b1 = finddiff(refline, 0, a0, rowpixels, pixel(dataBp, offsetData,a0) ^ 1);
- b1 = finddiff(refline, 0, b1, rowpixels, pixel(dataBp, offsetData,a0));
- }
- }
-
- private void Fax4PostEncode() {
- putBits(EOL, 12);
- putBits(EOL, 12);
- if (bit != 8) {
- outBuf.append((byte)data);
- data = 0;
- bit = 8;
- }
- }
-
- /**
- * Closes the encoder and returns the encoded data.
- * @return the encoded data
- */
- public byte[] close() {
- Fax4PostEncode();
- return outBuf.toByteArray();
- }
-
- private int pixel(byte[] data, int offset, int bit) {
- if (bit >= rowpixels)
- return 0;
- return ((data[offset + (bit >> 3)] & 0xff) >> (7-((bit)&7))) & 1;
- }
-
- private static int find1span(byte[] bp, int offset, int bs, int be) {
- int bits = be - bs;
- int n, span;
-
- int pos = offset + (bs >> 3);
- /*
- * Check partial byte on lhs.
- */
- if (bits > 0 && (n = (bs & 7)) != 0) {
- span = oneruns[((int)bp[pos] << n) & 0xff];
- if (span > 8-n) /* table value too generous */
- span = 8-n;
- if (span > bits) /* constrain span to bit range */
- span = bits;
- if (n+span < 8) /* doesn't extend to edge of byte */
- return (span);
- bits -= span;
- pos++;
- } else
- span = 0;
- /*
- * Scan full bytes for all 1's.
- */
- while (bits >= 8) {
- if (bp[pos] != -1) /* end of run */
- return (span + oneruns[bp[pos] & 0xff]);
- span += 8;
- bits -= 8;
- pos++;
- }
- /*
- * Check partial byte on rhs.
- */
- if (bits > 0) {
- n = oneruns[bp[pos] & 0xff];
- span += (n > bits ? bits : n);
- }
- return (span);
- }
-
- private static int find0span(byte[] bp, int offset, int bs, int be) {
- int bits = be - bs;
- int n, span;
-
- int pos = offset + (bs >> 3);
- /*
- * Check partial byte on lhs.
- */
- if (bits > 0 && (n = (bs & 7)) != 0) {
- span = zeroruns[((int)bp[pos] << n) & 0xff];
- if (span > 8-n) /* table value too generous */
- span = 8-n;
- if (span > bits) /* constrain span to bit range */
- span = bits;
- if (n+span < 8) /* doesn't extend to edge of byte */
- return (span);
- bits -= span;
- pos++;
- } else
- span = 0;
- /*
- * Scan full bytes for all 1's.
- */
- while (bits >= 8) {
- if (bp[pos] != 0) /* end of run */
- return (span + zeroruns[bp[pos] & 0xff]);
- span += 8;
- bits -= 8;
- pos++;
- }
- /*
- * Check partial byte on rhs.
- */
- if (bits > 0) {
- n = zeroruns[bp[pos] & 0xff];
- span += (n > bits ? bits : n);
- }
- return (span);
- }
-
- private static int finddiff(byte[] bp, int offset, int bs, int be, int color) {
- return bs + (color != 0 ? find1span(bp, offset, bs, be) : find0span(bp, offset, bs, be));
- }
-
- private static int finddiff2(byte[] bp, int offset, int bs, int be, int color) {
- return bs < be ? finddiff(bp, offset, bs, be, color) : be;
- }
-
- private static byte zeroruns[] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */
- };
-
- private static byte oneruns[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
- 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8 /* 0xf0 - 0xff */
- };
-
- private static final int LENGTH = 0; /* bit length of g3 code */
- private static final int CODE = 1; /* g3 code */
- private static final int RUNLEN = 2; /* run length in bits */
-
- private static final int EOL = 0x001; /* EOL code value - 0000 0000 0000 1 */
-
- /* status values returned instead of a run length */
- private static final int G3CODE_EOL = -1; /* NB: ACT_EOL - ACT_WRUNT */
- private static final int G3CODE_INVALID = -2; /* NB: ACT_INVALID - ACT_WRUNT */
- private static final int G3CODE_EOF = -3; /* end of input data */
- private static final int G3CODE_INCOMP = -4; /* incomplete run code */
-
- private int[][] TIFFFaxWhiteCodes = {
- { 8, 0x35, 0 }, /* 0011 0101 */
- { 6, 0x7, 1 }, /* 0001 11 */
- { 4, 0x7, 2 }, /* 0111 */
- { 4, 0x8, 3 }, /* 1000 */
- { 4, 0xB, 4 }, /* 1011 */
- { 4, 0xC, 5 }, /* 1100 */
- { 4, 0xE, 6 }, /* 1110 */
- { 4, 0xF, 7 }, /* 1111 */
- { 5, 0x13, 8 }, /* 1001 1 */
- { 5, 0x14, 9 }, /* 1010 0 */
- { 5, 0x7, 10 }, /* 0011 1 */
- { 5, 0x8, 11 }, /* 0100 0 */
- { 6, 0x8, 12 }, /* 0010 00 */
- { 6, 0x3, 13 }, /* 0000 11 */
- { 6, 0x34, 14 }, /* 1101 00 */
- { 6, 0x35, 15 }, /* 1101 01 */
- { 6, 0x2A, 16 }, /* 1010 10 */
- { 6, 0x2B, 17 }, /* 1010 11 */
- { 7, 0x27, 18 }, /* 0100 111 */
- { 7, 0xC, 19 }, /* 0001 100 */
- { 7, 0x8, 20 }, /* 0001 000 */
- { 7, 0x17, 21 }, /* 0010 111 */
- { 7, 0x3, 22 }, /* 0000 011 */
- { 7, 0x4, 23 }, /* 0000 100 */
- { 7, 0x28, 24 }, /* 0101 000 */
- { 7, 0x2B, 25 }, /* 0101 011 */
- { 7, 0x13, 26 }, /* 0010 011 */
- { 7, 0x24, 27 }, /* 0100 100 */
- { 7, 0x18, 28 }, /* 0011 000 */
- { 8, 0x2, 29 }, /* 0000 0010 */
- { 8, 0x3, 30 }, /* 0000 0011 */
- { 8, 0x1A, 31 }, /* 0001 1010 */
- { 8, 0x1B, 32 }, /* 0001 1011 */
- { 8, 0x12, 33 }, /* 0001 0010 */
- { 8, 0x13, 34 }, /* 0001 0011 */
- { 8, 0x14, 35 }, /* 0001 0100 */
- { 8, 0x15, 36 }, /* 0001 0101 */
- { 8, 0x16, 37 }, /* 0001 0110 */
- { 8, 0x17, 38 }, /* 0001 0111 */
- { 8, 0x28, 39 }, /* 0010 1000 */
- { 8, 0x29, 40 }, /* 0010 1001 */
- { 8, 0x2A, 41 }, /* 0010 1010 */
- { 8, 0x2B, 42 }, /* 0010 1011 */
- { 8, 0x2C, 43 }, /* 0010 1100 */
- { 8, 0x2D, 44 }, /* 0010 1101 */
- { 8, 0x4, 45 }, /* 0000 0100 */
- { 8, 0x5, 46 }, /* 0000 0101 */
- { 8, 0xA, 47 }, /* 0000 1010 */
- { 8, 0xB, 48 }, /* 0000 1011 */
- { 8, 0x52, 49 }, /* 0101 0010 */
- { 8, 0x53, 50 }, /* 0101 0011 */
- { 8, 0x54, 51 }, /* 0101 0100 */
- { 8, 0x55, 52 }, /* 0101 0101 */
- { 8, 0x24, 53 }, /* 0010 0100 */
- { 8, 0x25, 54 }, /* 0010 0101 */
- { 8, 0x58, 55 }, /* 0101 1000 */
- { 8, 0x59, 56 }, /* 0101 1001 */
- { 8, 0x5A, 57 }, /* 0101 1010 */
- { 8, 0x5B, 58 }, /* 0101 1011 */
- { 8, 0x4A, 59 }, /* 0100 1010 */
- { 8, 0x4B, 60 }, /* 0100 1011 */
- { 8, 0x32, 61 }, /* 0011 0010 */
- { 8, 0x33, 62 }, /* 0011 0011 */
- { 8, 0x34, 63 }, /* 0011 0100 */
- { 5, 0x1B, 64 }, /* 1101 1 */
- { 5, 0x12, 128 }, /* 1001 0 */
- { 6, 0x17, 192 }, /* 0101 11 */
- { 7, 0x37, 256 }, /* 0110 111 */
- { 8, 0x36, 320 }, /* 0011 0110 */
- { 8, 0x37, 384 }, /* 0011 0111 */
- { 8, 0x64, 448 }, /* 0110 0100 */
- { 8, 0x65, 512 }, /* 0110 0101 */
- { 8, 0x68, 576 }, /* 0110 1000 */
- { 8, 0x67, 640 }, /* 0110 0111 */
- { 9, 0xCC, 704 }, /* 0110 0110 0 */
- { 9, 0xCD, 768 }, /* 0110 0110 1 */
- { 9, 0xD2, 832 }, /* 0110 1001 0 */
- { 9, 0xD3, 896 }, /* 0110 1001 1 */
- { 9, 0xD4, 960 }, /* 0110 1010 0 */
- { 9, 0xD5, 1024 }, /* 0110 1010 1 */
- { 9, 0xD6, 1088 }, /* 0110 1011 0 */
- { 9, 0xD7, 1152 }, /* 0110 1011 1 */
- { 9, 0xD8, 1216 }, /* 0110 1100 0 */
- { 9, 0xD9, 1280 }, /* 0110 1100 1 */
- { 9, 0xDA, 1344 }, /* 0110 1101 0 */
- { 9, 0xDB, 1408 }, /* 0110 1101 1 */
- { 9, 0x98, 1472 }, /* 0100 1100 0 */
- { 9, 0x99, 1536 }, /* 0100 1100 1 */
- { 9, 0x9A, 1600 }, /* 0100 1101 0 */
- { 6, 0x18, 1664 }, /* 0110 00 */
- { 9, 0x9B, 1728 }, /* 0100 1101 1 */
- { 11, 0x8, 1792 }, /* 0000 0001 000 */
- { 11, 0xC, 1856 }, /* 0000 0001 100 */
- { 11, 0xD, 1920 }, /* 0000 0001 101 */
- { 12, 0x12, 1984 }, /* 0000 0001 0010 */
- { 12, 0x13, 2048 }, /* 0000 0001 0011 */
- { 12, 0x14, 2112 }, /* 0000 0001 0100 */
- { 12, 0x15, 2176 }, /* 0000 0001 0101 */
- { 12, 0x16, 2240 }, /* 0000 0001 0110 */
- { 12, 0x17, 2304 }, /* 0000 0001 0111 */
- { 12, 0x1C, 2368 }, /* 0000 0001 1100 */
- { 12, 0x1D, 2432 }, /* 0000 0001 1101 */
- { 12, 0x1E, 2496 }, /* 0000 0001 1110 */
- { 12, 0x1F, 2560 }, /* 0000 0001 1111 */
- { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */
- { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */
- { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */
- { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */
- { 12, 0x0, G3CODE_INVALID } /* 0000 0000 0000 */
- };
-
- private int[][] TIFFFaxBlackCodes = {
- { 10, 0x37, 0 }, /* 0000 1101 11 */
- { 3, 0x2, 1 }, /* 010 */
- { 2, 0x3, 2 }, /* 11 */
- { 2, 0x2, 3 }, /* 10 */
- { 3, 0x3, 4 }, /* 011 */
- { 4, 0x3, 5 }, /* 0011 */
- { 4, 0x2, 6 }, /* 0010 */
- { 5, 0x3, 7 }, /* 0001 1 */
- { 6, 0x5, 8 }, /* 0001 01 */
- { 6, 0x4, 9 }, /* 0001 00 */
- { 7, 0x4, 10 }, /* 0000 100 */
- { 7, 0x5, 11 }, /* 0000 101 */
- { 7, 0x7, 12 }, /* 0000 111 */
- { 8, 0x4, 13 }, /* 0000 0100 */
- { 8, 0x7, 14 }, /* 0000 0111 */
- { 9, 0x18, 15 }, /* 0000 1100 0 */
- { 10, 0x17, 16 }, /* 0000 0101 11 */
- { 10, 0x18, 17 }, /* 0000 0110 00 */
- { 10, 0x8, 18 }, /* 0000 0010 00 */
- { 11, 0x67, 19 }, /* 0000 1100 111 */
- { 11, 0x68, 20 }, /* 0000 1101 000 */
- { 11, 0x6C, 21 }, /* 0000 1101 100 */
- { 11, 0x37, 22 }, /* 0000 0110 111 */
- { 11, 0x28, 23 }, /* 0000 0101 000 */
- { 11, 0x17, 24 }, /* 0000 0010 111 */
- { 11, 0x18, 25 }, /* 0000 0011 000 */
- { 12, 0xCA, 26 }, /* 0000 1100 1010 */
- { 12, 0xCB, 27 }, /* 0000 1100 1011 */
- { 12, 0xCC, 28 }, /* 0000 1100 1100 */
- { 12, 0xCD, 29 }, /* 0000 1100 1101 */
- { 12, 0x68, 30 }, /* 0000 0110 1000 */
- { 12, 0x69, 31 }, /* 0000 0110 1001 */
- { 12, 0x6A, 32 }, /* 0000 0110 1010 */
- { 12, 0x6B, 33 }, /* 0000 0110 1011 */
- { 12, 0xD2, 34 }, /* 0000 1101 0010 */
- { 12, 0xD3, 35 }, /* 0000 1101 0011 */
- { 12, 0xD4, 36 }, /* 0000 1101 0100 */
- { 12, 0xD5, 37 }, /* 0000 1101 0101 */
- { 12, 0xD6, 38 }, /* 0000 1101 0110 */
- { 12, 0xD7, 39 }, /* 0000 1101 0111 */
- { 12, 0x6C, 40 }, /* 0000 0110 1100 */
- { 12, 0x6D, 41 }, /* 0000 0110 1101 */
- { 12, 0xDA, 42 }, /* 0000 1101 1010 */
- { 12, 0xDB, 43 }, /* 0000 1101 1011 */
- { 12, 0x54, 44 }, /* 0000 0101 0100 */
- { 12, 0x55, 45 }, /* 0000 0101 0101 */
- { 12, 0x56, 46 }, /* 0000 0101 0110 */
- { 12, 0x57, 47 }, /* 0000 0101 0111 */
- { 12, 0x64, 48 }, /* 0000 0110 0100 */
- { 12, 0x65, 49 }, /* 0000 0110 0101 */
- { 12, 0x52, 50 }, /* 0000 0101 0010 */
- { 12, 0x53, 51 }, /* 0000 0101 0011 */
- { 12, 0x24, 52 }, /* 0000 0010 0100 */
- { 12, 0x37, 53 }, /* 0000 0011 0111 */
- { 12, 0x38, 54 }, /* 0000 0011 1000 */
- { 12, 0x27, 55 }, /* 0000 0010 0111 */
- { 12, 0x28, 56 }, /* 0000 0010 1000 */
- { 12, 0x58, 57 }, /* 0000 0101 1000 */
- { 12, 0x59, 58 }, /* 0000 0101 1001 */
- { 12, 0x2B, 59 }, /* 0000 0010 1011 */
- { 12, 0x2C, 60 }, /* 0000 0010 1100 */
- { 12, 0x5A, 61 }, /* 0000 0101 1010 */
- { 12, 0x66, 62 }, /* 0000 0110 0110 */
- { 12, 0x67, 63 }, /* 0000 0110 0111 */
- { 10, 0xF, 64 }, /* 0000 0011 11 */
- { 12, 0xC8, 128 }, /* 0000 1100 1000 */
- { 12, 0xC9, 192 }, /* 0000 1100 1001 */
- { 12, 0x5B, 256 }, /* 0000 0101 1011 */
- { 12, 0x33, 320 }, /* 0000 0011 0011 */
- { 12, 0x34, 384 }, /* 0000 0011 0100 */
- { 12, 0x35, 448 }, /* 0000 0011 0101 */
- { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */
- { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */
- { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */
- { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */
- { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */
- { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */
- { 13, 0x72, 896 }, /* 0000 0011 1001 0 */
- { 13, 0x73, 960 }, /* 0000 0011 1001 1 */
- { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */
- { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */
- { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */
- { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */
- { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */
- { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */
- { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */
- { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */
- { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */
- { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */
- { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */
- { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */
- { 11, 0x8, 1792 }, /* 0000 0001 000 */
- { 11, 0xC, 1856 }, /* 0000 0001 100 */
- { 11, 0xD, 1920 }, /* 0000 0001 101 */
- { 12, 0x12, 1984 }, /* 0000 0001 0010 */
- { 12, 0x13, 2048 }, /* 0000 0001 0011 */
- { 12, 0x14, 2112 }, /* 0000 0001 0100 */
- { 12, 0x15, 2176 }, /* 0000 0001 0101 */
- { 12, 0x16, 2240 }, /* 0000 0001 0110 */
- { 12, 0x17, 2304 }, /* 0000 0001 0111 */
- { 12, 0x1C, 2368 }, /* 0000 0001 1100 */
- { 12, 0x1D, 2432 }, /* 0000 0001 1101 */
- { 12, 0x1E, 2496 }, /* 0000 0001 1110 */
- { 12, 0x1F, 2560 }, /* 0000 0001 1111 */
- { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */
- { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */
- { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */
- { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */
- { 12, 0x0, G3CODE_INVALID } /* 0000 0000 0000 */
- };
-
- private int[] horizcode =
- { 3, 0x1, 0 }; /* 001 */
- private int[] passcode =
- { 4, 0x1, 0 }; /* 0001 */
- private int[][] vcodes = {
- { 7, 0x03, 0 }, /* 0000 011 */
- { 6, 0x03, 0 }, /* 0000 11 */
- { 3, 0x03, 0 }, /* 011 */
- { 1, 0x1, 0 }, /* 1 */
- { 3, 0x2, 0 }, /* 010 */
- { 6, 0x02, 0 }, /* 0000 10 */
- { 7, 0x02, 0 } /* 0000 010 */
- };
- private int[] msbmask =
- { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/GifImage.java b/src/main/java/com/lowagie/text/pdf/codec/GifImage.java
deleted file mode 100644
index f6858ac..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/GifImage.java
+++ /dev/null
@@ -1,593 +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.codec;
-
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.*;
-import java.io.*;
-import java.net.URL;
-import java.util.ArrayList;
-
-/** Reads gif images of all types. All the images in a gif are read in the constructors
- * and can be retrieved with other methods.
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class GifImage {
-
- protected DataInputStream in;
- protected int width; // full image width
- protected int height; // full image height
- protected boolean gctFlag; // global color table used
-
- protected int bgIndex; // background color index
- protected int bgColor; // background color
- protected int pixelAspect; // pixel aspect ratio
-
- protected boolean lctFlag; // local color table flag
- protected boolean interlace; // interlace flag
- protected int lctSize; // local color table size
-
- protected int ix, iy, iw, ih; // current image rectangle
-
- protected byte[] block = new byte[256]; // current data block
- protected int blockSize = 0; // block size
-
- // last graphic control extension info
- protected int dispose = 0; // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
- protected boolean transparency = false; // use transparent color
- protected int delay = 0; // delay in milliseconds
- protected int transIndex; // transparent color index
-
- protected static final int MaxStackSize = 4096; // max decoder pixel stack size
-
- // LZW decoder working arrays
- protected short[] prefix;
- protected byte[] suffix;
- protected byte[] pixelStack;
- protected byte[] pixels;
-
- protected byte m_out[];
- protected int m_bpc;
- protected int m_gbpc;
- protected byte m_global_table[];
- protected byte m_local_table[];
- protected byte m_curr_table[];
- protected int m_line_stride;
- protected byte fromData[];
- protected URL fromUrl;
-
-
- protected ArrayList frames = new ArrayList(); // frames read from current file
-
- /** Reads gif images from an URL.
- * @param url the URL
- * @throws IOException on error
- */
- public GifImage(URL url) throws IOException {
- fromUrl = url;
- InputStream is = null;
- try {
- is = url.openStream();
- process(is);
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- /** Reads gif images from a file.
- * @param file the file
- * @throws IOException on error
- */
- public GifImage(String file) throws IOException {
- this(Image.toURL(file));
- }
-
- /** Reads gif images from a byte array.
- * @param data the byte array
- * @throws IOException on error
- */
- public GifImage(byte data[]) throws IOException {
- fromData = data;
- InputStream is = null;
- try {
- is = new ByteArrayInputStream(data);
- process(is);
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- /** Reads gif images from a stream. The stream is not closed.
- * @param is the stream
- * @throws IOException on error
- */
- public GifImage(InputStream is) throws IOException {
- process(is);
- }
-
- /** Gets the number of frames the gif has.
- * @return the number of frames the gif has
- */
- public int getFrameCount() {
- return frames.size();
- }
-
- /** Gets the image from a frame. The first frame is 1.
- * @param frame the frame to get the image from
- * @return the image
- */
- public Image getImage(int frame) {
- GifFrame gf = (GifFrame)frames.get(frame - 1);
- return gf.image;
- }
-
- /** Gets the [x,y] position of the frame in reference to the
- * logical screen.
- * @param frame the frame
- * @return the [x,y] position of the frame
- */
- public int[] getFramePosition(int frame) {
- GifFrame gf = (GifFrame)frames.get(frame - 1);
- return new int[]{gf.ix, gf.iy};
-
- }
-
- /** Gets the logical screen. The images may be smaller and placed
- * in some position in this screen to playback some animation.
- * No image will be be bigger that this.
- * @return the logical screen dimensions as [x,y]
- */
- public int[] getLogicalScreen() {
- return new int[]{width, height};
- }
-
- void process(InputStream is) throws IOException {
- in = new DataInputStream(new BufferedInputStream(is));
- readHeader();
- readContents();
- if (frames.size() == 0)
- throw new IOException("The file does not contain any valid image.");
- }
-
- /**
- * Reads GIF file header information.
- */
- protected void readHeader() throws IOException {
- String id = "";
- for (int i = 0; i < 6; i++)
- id += (char)in.read();
- if (!id.startsWith("GIF8")) {
- throw new IOException("Gif signature nor found.");
- }
-
- readLSD();
- if (gctFlag) {
- m_global_table = readColorTable(m_gbpc);
- }
- }
-
- /**
- * Reads Logical Screen Descriptor
- */
- protected void readLSD() throws IOException {
-
- // logical screen size
- width = readShort();
- height = readShort();
-
- // packed fields
- int packed = in.read();
- gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
- m_gbpc = (packed & 7) + 1;
- bgIndex = in.read(); // background color index
- pixelAspect = in.read(); // pixel aspect ratio
- }
-
- /**
- * Reads next 16-bit value, LSB first
- */
- protected int readShort() throws IOException {
- // read 16-bit value, LSB first
- return in.read() | (in.read() << 8);
- }
-
- /**
- * Reads next variable length block from input.
- *
- * @return number of bytes stored in "buffer"
- */
- protected int readBlock() throws IOException {
- blockSize = in.read();
- if (blockSize <= 0)
- return blockSize = 0;
- for (int k = 0; k < blockSize; ++k) {
- int v = in.read();
- if (v < 0) {
- return blockSize = k;
- }
- block[k] = (byte)v;
- }
- return blockSize;
- }
-
- protected byte[] readColorTable(int bpc) throws IOException {
- int ncolors = 1 << bpc;
- int nbytes = 3*ncolors;
- bpc = newBpc(bpc);
- byte table[] = new byte[(1 << bpc) * 3];
- in.readFully(table, 0, nbytes);
- return table;
- }
-
-
- static protected int newBpc(int bpc) {
- switch (bpc) {
- case 1:
- case 2:
- case 4:
- break;
- case 3:
- return 4;
- default:
- return 8;
- }
- return bpc;
- }
-
- protected void readContents() throws IOException {
- // read GIF file content blocks
- boolean done = false;
- while (!done) {
- int code = in.read();
- switch (code) {
-
- case 0x2C: // image separator
- readImage();
- break;
-
- case 0x21: // extension
- code = in.read();
- switch (code) {
-
- case 0xf9: // graphics control extension
- readGraphicControlExt();
- break;
-
- case 0xff: // application extension
- readBlock();
- skip(); // don't care
- break;
-
- default: // uninteresting extension
- skip();
- }
- break;
-
- default:
- done = true;
- break;
- }
- }
- }
-
- /**
- * Reads next frame image
- */
- protected void readImage() throws IOException {
- ix = readShort(); // (sub)image position & size
- iy = readShort();
- iw = readShort();
- ih = readShort();
-
- int packed = in.read();
- lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
- interlace = (packed & 0x40) != 0; // 2 - interlace flag
- // 3 - sort flag
- // 4-5 - reserved
- lctSize = 2 << (packed & 7); // 6-8 - local color table size
- m_bpc = newBpc(m_gbpc);
- if (lctFlag) {
- m_curr_table = readColorTable((packed & 7) + 1); // read table
- m_bpc = newBpc((packed & 7) + 1);
- }
- else {
- m_curr_table = m_global_table;
- }
- if (transparency && transIndex >= m_curr_table.length / 3)
- transparency = false;
- if (transparency && m_bpc == 1) { // Acrobat 5.05 doesn't like this combination
- byte tp[] = new byte[12];
- System.arraycopy(m_curr_table, 0, tp, 0, 6);
- m_curr_table = tp;
- m_bpc = 2;
- }
- boolean skipZero = decodeImageData(); // decode pixel data
- if (!skipZero)
- skip();
-
- Image img = null;
- try {
- img = new ImgRaw(iw, ih, 1, m_bpc, m_out);
- PdfArray colorspace = new PdfArray();
- colorspace.add(PdfName.INDEXED);
- colorspace.add(PdfName.DEVICERGB);
- int len = m_curr_table.length;
- colorspace.add(new PdfNumber(len / 3 - 1));
- colorspace.add(new PdfString(m_curr_table));
- PdfDictionary ad = new PdfDictionary();
- ad.put(PdfName.COLORSPACE, colorspace);
- img.setAdditional(ad);
- if (transparency) {
- img.setTransparency(new int[]{transIndex, transIndex});
- }
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- img.setOriginalType(Image.ORIGINAL_GIF);
- img.setOriginalData(fromData);
- img.setUrl(fromUrl);
- GifFrame gf = new GifFrame();
- gf.image = img;
- gf.ix = ix;
- gf.iy = iy;
- frames.add(gf); // add image to frame list
-
- //resetFrame();
-
- }
-
- protected boolean decodeImageData() throws IOException {
- int NullCode = -1;
- int npix = iw * ih;
- int available, clear, code_mask, code_size, end_of_information, in_code, old_code,
- bits, code, count, i, datum, data_size, first, top, bi;
- boolean skipZero = false;
-
- if (prefix == null)
- prefix = new short[MaxStackSize];
- if (suffix == null)
- suffix = new byte[MaxStackSize];
- if (pixelStack == null)
- pixelStack = new byte[MaxStackSize+1];
-
- m_line_stride = (iw * m_bpc + 7) / 8;
- m_out = new byte[m_line_stride * ih];
- int pass = 1;
- int inc = interlace ? 8 : 1;
- int line = 0;
- int xpos = 0;
-
- // Initialize GIF data stream decoder.
-
- data_size = in.read();
- clear = 1 << data_size;
- end_of_information = clear + 1;
- available = clear + 2;
- old_code = NullCode;
- code_size = data_size + 1;
- code_mask = (1 << code_size) - 1;
- for (code = 0; code < clear; code++) {
- prefix[code] = 0;
- suffix[code] = (byte) code;
- }
-
- // Decode GIF pixel stream.
-
- datum = bits = count = first = top = bi = 0;
-
- for (i = 0; i < npix; ) {
- if (top == 0) {
- if (bits < code_size) {
- // Load bytes until there are enough bits for a code.
- if (count == 0) {
- // Read a new data block.
- count = readBlock();
- if (count <= 0) {
- skipZero = true;
- break;
- }
- bi = 0;
- }
- datum += (((int) block[bi]) & 0xff) << bits;
- bits += 8;
- bi++;
- count--;
- continue;
- }
-
- // Get the next code.
-
- code = datum & code_mask;
- datum >>= code_size;
- bits -= code_size;
-
- // Interpret the code
-
- if ((code > available) || (code == end_of_information))
- break;
- if (code == clear) {
- // Reset decoder.
- code_size = data_size + 1;
- code_mask = (1 << code_size) - 1;
- available = clear + 2;
- old_code = NullCode;
- continue;
- }
- if (old_code == NullCode) {
- pixelStack[top++] = suffix[code];
- old_code = code;
- first = code;
- continue;
- }
- in_code = code;
- if (code == available) {
- pixelStack[top++] = (byte) first;
- code = old_code;
- }
- while (code > clear) {
- pixelStack[top++] = suffix[code];
- code = prefix[code];
- }
- first = ((int) suffix[code]) & 0xff;
-
- // Add a new string to the string table,
-
- if (available >= MaxStackSize)
- break;
- pixelStack[top++] = (byte) first;
- prefix[available] = (short) old_code;
- suffix[available] = (byte) first;
- available++;
- if (((available & code_mask) == 0) && (available < MaxStackSize)) {
- code_size++;
- code_mask += available;
- }
- old_code = in_code;
- }
-
- // Pop a pixel off the pixel stack.
-
- top--;
- i++;
-
- setPixel(xpos, line, pixelStack[top]);
- ++xpos;
- if (xpos >= iw) {
- xpos = 0;
- line += inc;
- if (line >= ih) {
- if (interlace) {
- do {
- pass++;
- switch (pass) {
- case 2:
- line = 4;
- break;
- case 3:
- line = 2;
- inc = 4;
- break;
- case 4:
- line = 1;
- inc = 2;
- break;
- default: // this shouldn't happen
- line = ih - 1;
- inc = 0;
- }
- } while (line >= ih);
- }
- else {
- line = ih - 1; // this shouldn't happen
- inc = 0;
- }
- }
- }
- }
- return skipZero;
- }
-
-
- protected void setPixel(int x, int y, int v) {
- if (m_bpc == 8) {
- int pos = x + iw * y;
- m_out[pos] = (byte)v;
- }
- else {
- int pos = m_line_stride * y + x / (8 / m_bpc);
- int vout = v << (8 - m_bpc * (x % (8 / m_bpc))- m_bpc);
- m_out[pos] |= vout;
- }
- }
-
- /**
- * Resets frame state for reading next image.
- */
- protected void resetFrame() {
- // it does nothing in the pdf context
- //boolean transparency = false;
- //int delay = 0;
- }
-
- /**
- * Reads Graphics Control Extension values
- */
- protected void readGraphicControlExt() throws IOException {
- in.read(); // block size
- int packed = in.read(); // packed fields
- dispose = (packed & 0x1c) >> 2; // disposal method
- if (dispose == 0)
- dispose = 1; // elect to keep old image if discretionary
- transparency = (packed & 1) != 0;
- delay = readShort() * 10; // delay in milliseconds
- transIndex = in.read(); // transparent color index
- in.read(); // block terminator
- }
-
- /**
- * Skips variable length blocks up to and including
- * next zero length block.
- */
- protected void skip() throws IOException {
- do {
- readBlock();
- } while (blockSize > 0);
- }
-
- static class GifFrame {
- Image image;
- int ix;
- int iy;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/PngImage.java b/src/main/java/com/lowagie/text/pdf/codec/PngImage.java
deleted file mode 100644
index b82e17b..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/PngImage.java
+++ /dev/null
@@ -1,987 +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/
- *
- *
- * The original JAI codecs have the following license
- *
- * 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.
- */
-
-package com.lowagie.text.pdf.codec;
-
-import java.awt.color.ICC_Profile;
-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.zip.Inflater;
-import java.util.zip.InflaterInputStream;
-
-import com.lowagie.text.ExceptionConverter;
-import com.lowagie.text.Image;
-import com.lowagie.text.ImgRaw;
-import com.lowagie.text.pdf.ByteBuffer;
-import com.lowagie.text.pdf.PdfArray;
-import com.lowagie.text.pdf.PdfDictionary;
-import com.lowagie.text.pdf.PdfLiteral;
-import com.lowagie.text.pdf.PdfName;
-import com.lowagie.text.pdf.PdfNumber;
-import com.lowagie.text.pdf.PdfObject;
-import com.lowagie.text.pdf.PdfReader;
-import com.lowagie.text.pdf.PdfString;
-
-/** Reads a PNG image. All types of PNG can be read.
- * <p>
- * It is based in part in the JAI codec.
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class PngImage {
-/** Some PNG specific values. */
- public static final int[] PNGID = {137, 80, 78, 71, 13, 10, 26, 10};
-
-/** A PNG marker. */
- public static final String IHDR = "IHDR";
-
-/** A PNG marker. */
- public static final String PLTE = "PLTE";
-
-/** A PNG marker. */
- public static final String IDAT = "IDAT";
-
-/** A PNG marker. */
- public static final String IEND = "IEND";
-
-/** A PNG marker. */
- public static final String tRNS = "tRNS";
-
-/** A PNG marker. */
- public static final String pHYs = "pHYs";
-
-/** A PNG marker. */
- public static final String gAMA = "gAMA";
-
-/** A PNG marker. */
- public static final String cHRM = "cHRM";
-
-/** A PNG marker. */
- public static final String sRGB = "sRGB";
-
-/** A PNG marker. */
- public static final String iCCP = "iCCP";
-
- private static final int TRANSFERSIZE = 4096;
- private static final int PNG_FILTER_NONE = 0;
- private static final int PNG_FILTER_SUB = 1;
- private static final int PNG_FILTER_UP = 2;
- private static final int PNG_FILTER_AVERAGE = 3;
- private static final int PNG_FILTER_PAETH = 4;
- private static final PdfName intents[] = {PdfName.PERCEPTUAL,
- PdfName.RELATIVECALORIMETRIC,PdfName.SATURATION,PdfName.ABSOLUTECALORIMETRIC};
-
- InputStream is;
- DataInputStream dataStream;
- int width;
- int height;
- int bitDepth;
- int colorType;
- int compressionMethod;
- int filterMethod;
- int interlaceMethod;
- PdfDictionary additional = new PdfDictionary();
- byte image[];
- byte smask[];
- byte trans[];
- NewByteArrayOutputStream idat = new NewByteArrayOutputStream();
- int dpiX;
- int dpiY;
- float XYRatio;
- boolean genBWMask;
- boolean palShades;
- int transRedGray = -1;
- int transGreen = -1;
- int transBlue = -1;
- int inputBands;
- int bytesPerPixel; // number of bytes per input pixel
- byte colorTable[];
- float gamma = 1f;
- boolean hasCHRM = false;
- float xW, yW, xR, yR, xG, yG, xB, yB;
- PdfName intent;
- ICC_Profile icc_profile;
-
-
-
- /** Creates a new instance of PngImage */
- PngImage(InputStream is) {
- this.is = is;
- }
-
- /** Reads a PNG from an url.
- * @param url the url
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(URL url) throws IOException {
- InputStream is = null;
- try {
- is = url.openStream();
- Image img = getImage(is);
- img.setUrl(url);
- return img;
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- /** Reads a PNG from a stream.
- * @param is the stream
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(InputStream is) throws IOException {
- PngImage png = new PngImage(is);
- return png.getImage();
- }
-
- /** Reads a PNG from a file.
- * @param file the file
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(String file) throws IOException {
- return getImage(Image.toURL(file));
- }
-
- /** Reads a PNG from a byte array.
- * @param data the byte array
- * @throws IOException on error
- * @return the image
- */
- public static Image getImage(byte data[]) throws IOException {
- InputStream is = null;
- try {
- is = new ByteArrayInputStream(data);
- Image img = getImage(is);
- img.setOriginalData(data);
- return img;
- }
- finally {
- if (is != null) {
- is.close();
- }
- }
- }
-
- boolean checkMarker(String s) {
- if (s.length() != 4)
- return false;
- for (int k = 0; k < 4; ++k) {
- char c = s.charAt(k);
- if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z'))
- return false;
- }
- return true;
- }
-
- void readPng() throws IOException {
- for (int i = 0; i < PNGID.length; i++) {
- if (PNGID[i] != is.read()) {
- throw new IOException("File is not a valid PNG.");
- }
- }
- byte buffer[] = new byte[TRANSFERSIZE];
- while (true) {
- int len = getInt(is);
- String marker = getString(is);
- if (len < 0 || !checkMarker(marker))
- throw new IOException("Corrupted PNG file.");
- if (IDAT.equals(marker)) {
- int size;
- while (len != 0) {
- size = is.read(buffer, 0, Math.min(len, TRANSFERSIZE));
- if (size < 0)
- return;
- idat.write(buffer, 0, size);
- len -= size;
- }
- }
- else if (tRNS.equals(marker)) {
- switch (colorType) {
- case 0:
- if (len >= 2) {
- len -= 2;
- int gray = getWord(is);
- if (bitDepth == 16)
- transRedGray = gray;
- else
- additional.put(PdfName.MASK, new PdfLiteral("["+gray+" "+gray+"]"));
- }
- break;
- case 2:
- if (len >= 6) {
- len -= 6;
- int red = getWord(is);
- int green = getWord(is);
- int blue = getWord(is);
- if (bitDepth == 16) {
- transRedGray = red;
- transGreen = green;
- transBlue = blue;
- }
- else
- additional.put(PdfName.MASK, new PdfLiteral("["+red+" "+red+" "+green+" "+green+" "+blue+" "+blue+"]"));
- }
- break;
- case 3:
- if (len > 0) {
- trans = new byte[len];
- for (int k = 0; k < len; ++k)
- trans[k] = (byte)is.read();
- len = 0;
- }
- break;
- }
- Image.skip(is, len);
- }
- else if (IHDR.equals(marker)) {
- width = getInt(is);
- height = getInt(is);
-
- bitDepth = is.read();
- colorType = is.read();
- compressionMethod = is.read();
- filterMethod = is.read();
- interlaceMethod = is.read();
- }
- else if (PLTE.equals(marker)) {
- if (colorType == 3) {
- PdfArray colorspace = new PdfArray();
- colorspace.add(PdfName.INDEXED);
- colorspace.add(getColorspace());
- colorspace.add(new PdfNumber(len / 3 - 1));
- ByteBuffer colortable = new ByteBuffer();
- while ((len--) > 0) {
- colortable.append_i(is.read());
- }
- colorspace.add(new PdfString(colorTable = colortable.toByteArray()));
- additional.put(PdfName.COLORSPACE, colorspace);
- }
- else {
- Image.skip(is, len);
- }
- }
- else if (pHYs.equals(marker)) {
- int dx = getInt(is);
- int dy = getInt(is);
- int unit = is.read();
- if (unit == 1) {
- dpiX = (int)((float)dx * 0.0254f);
- dpiY = (int)((float)dy * 0.0254f);
- }
- else {
- if (dy != 0)
- XYRatio = (float)dx / (float)dy;
- }
- }
- else if (cHRM.equals(marker)) {
- xW = (float)getInt(is) / 100000f;
- yW = (float)getInt(is) / 100000f;
- xR = (float)getInt(is) / 100000f;
- yR = (float)getInt(is) / 100000f;
- xG = (float)getInt(is) / 100000f;
- yG = (float)getInt(is) / 100000f;
- xB = (float)getInt(is) / 100000f;
- yB = (float)getInt(is) / 100000f;
- hasCHRM = !(Math.abs(xW)<0.0001f||Math.abs(yW)<0.0001f||Math.abs(xR)<0.0001f||Math.abs(yR)<0.0001f||Math.abs(xG)<0.0001f||Math.abs(yG)<0.0001f||Math.abs(xB)<0.0001f||Math.abs(yB)<0.0001f);
- }
- else if (sRGB.equals(marker)) {
- int ri = is.read();
- intent = intents[ri];
- gamma = 2.2f;
- xW = 0.3127f;
- yW = 0.329f;
- xR = 0.64f;
- yR = 0.33f;
- xG = 0.3f;
- yG = 0.6f;
- xB = 0.15f;
- yB = 0.06f;
- hasCHRM = true;
- }
- else if (gAMA.equals(marker)) {
- int gm = getInt(is);
- if (gm != 0) {
- gamma = 100000f / (float)gm;
- if (!hasCHRM) {
- xW = 0.3127f;
- yW = 0.329f;
- xR = 0.64f;
- yR = 0.33f;
- xG = 0.3f;
- yG = 0.6f;
- xB = 0.15f;
- yB = 0.06f;
- hasCHRM = true;
- }
- }
- }
- else if (iCCP.equals(marker)) {
- do {
- --len;
- } while (is.read() != 0);
- is.read();
- --len;
- byte icccom[] = new byte[len];
- int p = 0;
- while (len > 0) {
- int r = is.read(icccom, p, len);
- if (r < 0)
- throw new IOException("Premature end of file.");
- p += r;
- len -= r;
- }
- byte iccp[] = PdfReader.FlateDecode(icccom, true);
- icccom = null;
- try {
- icc_profile = ICC_Profile.getInstance(iccp);
- }
- catch (Exception e) {
- icc_profile = null;
- }
- }
- else if (IEND.equals(marker)) {
- break;
- }
- else {
- Image.skip(is, len);
- }
- Image.skip(is, 4);
- }
- }
-
- PdfObject getColorspace() {
- if (icc_profile != null) {
- if ((colorType & 2) == 0)
- return PdfName.DEVICEGRAY;
- else
- return PdfName.DEVICERGB;
- }
- if (gamma == 1f && !hasCHRM) {
- if ((colorType & 2) == 0)
- return PdfName.DEVICEGRAY;
- else
- return PdfName.DEVICERGB;
- }
- else {
- PdfArray array = new PdfArray();
- PdfDictionary dic = new PdfDictionary();
- if ((colorType & 2) == 0) {
- if (gamma == 1f)
- return PdfName.DEVICEGRAY;
- array.add(PdfName.CALGRAY);
- dic.put(PdfName.GAMMA, new PdfNumber(gamma));
- dic.put(PdfName.WHITEPOINT, new PdfLiteral("[1 1 1]"));
- array.add(dic);
- }
- else {
- PdfObject wp = new PdfLiteral("[1 1 1]");
- array.add(PdfName.CALRGB);
- if (gamma != 1f) {
- PdfArray gm = new PdfArray();
- PdfNumber n = new PdfNumber(gamma);
- gm.add(n);
- gm.add(n);
- gm.add(n);
- dic.put(PdfName.GAMMA, gm);
- }
- if (hasCHRM) {
- float z = yW*((xG-xB)*yR-(xR-xB)*yG+(xR-xG)*yB);
- float YA = yR*((xG-xB)*yW-(xW-xB)*yG+(xW-xG)*yB)/z;
- float XA = YA*xR/yR;
- float ZA = YA*((1-xR)/yR-1);
- float YB = -yG*((xR-xB)*yW-(xW-xB)*yR+(xW-xR)*yB)/z;
- float XB = YB*xG/yG;
- float ZB = YB*((1-xG)/yG-1);
- float YC = yB*((xR-xG)*yW-(xW-xG)*yW+(xW-xR)*yG)/z;
- float XC = YC*xB/yB;
- float ZC = YC*((1-xB)/yB-1);
- float XW = XA+XB+XC;
- float YW = 1;//YA+YB+YC;
- float ZW = ZA+ZB+ZC;
- PdfArray wpa = new PdfArray();
- wpa.add(new PdfNumber(XW));
- wpa.add(new PdfNumber(YW));
- wpa.add(new PdfNumber(ZW));
- wp = wpa;
- PdfArray matrix = new PdfArray();
- matrix.add(new PdfNumber(XA));
- matrix.add(new PdfNumber(YA));
- matrix.add(new PdfNumber(ZA));
- matrix.add(new PdfNumber(XB));
- matrix.add(new PdfNumber(YB));
- matrix.add(new PdfNumber(ZB));
- matrix.add(new PdfNumber(XC));
- matrix.add(new PdfNumber(YC));
- matrix.add(new PdfNumber(ZC));
- dic.put(PdfName.MATRIX, matrix);
- }
- dic.put(PdfName.WHITEPOINT, wp);
- array.add(dic);
- }
- return array;
- }
- }
-
- Image getImage() throws IOException {
- readPng();
- try {
- int pal0 = 0;
- int palIdx = 0;
- palShades = false;
- if (trans != null) {
- for (int k = 0; k < trans.length; ++k) {
- int n = trans[k] & 0xff;
- if (n == 0) {
- ++pal0;
- palIdx = k;
- }
- if (n != 0 && n != 255) {
- palShades = true;
- break;
- }
- }
- }
- if ((colorType & 4) != 0)
- palShades = true;
- genBWMask = (!palShades && (pal0 > 1 || transRedGray >= 0));
- if (!palShades && !genBWMask && pal0 == 1) {
- additional.put(PdfName.MASK, new PdfLiteral("["+palIdx+" "+palIdx+"]"));
- }
- boolean needDecode = (interlaceMethod == 1) || (bitDepth == 16) || ((colorType & 4) != 0) || palShades || genBWMask;
- switch (colorType) {
- case 0:
- inputBands = 1;
- break;
- case 2:
- inputBands = 3;
- break;
- case 3:
- inputBands = 1;
- break;
- case 4:
- inputBands = 2;
- break;
- case 6:
- inputBands = 4;
- break;
- }
- if (needDecode)
- decodeIdat();
- int components = inputBands;
- if ((colorType & 4) != 0)
- --components;
- int bpc = bitDepth;
- if (bpc == 16)
- bpc = 8;
- Image img;
- if (image != null)
- img = Image.getInstance(width, height, components, bpc, image);
- else {
- img = new ImgRaw(width, height, components, bpc, idat.toByteArray());
- img.setDeflated(true);
- PdfDictionary decodeparms = new PdfDictionary();
- decodeparms.put(PdfName.BITSPERCOMPONENT, new PdfNumber(bitDepth));
- decodeparms.put(PdfName.PREDICTOR, new PdfNumber(15));
- decodeparms.put(PdfName.COLUMNS, new PdfNumber(width));
- decodeparms.put(PdfName.COLORS, new PdfNumber((colorType == 3 || (colorType & 2) == 0) ? 1 : 3));
- additional.put(PdfName.DECODEPARMS, decodeparms);
- }
- if (additional.get(PdfName.COLORSPACE) == null)
- additional.put(PdfName.COLORSPACE, getColorspace());
- if (intent != null)
- additional.put(PdfName.INTENT, intent);
- if (additional.size() > 0)
- img.setAdditional(additional);
- if (icc_profile != null)
- img.tagICC(icc_profile);
- if (palShades) {
- Image im2 = Image.getInstance(width, height, 1, 8, smask);
- im2.makeMask();
- img.setImageMask(im2);
- }
- if (genBWMask) {
- Image im2 = Image.getInstance(width, height, 1, 1, smask);
- im2.makeMask();
- img.setImageMask(im2);
- }
- img.setDpi(dpiX, dpiY);
- img.setXYRatio(XYRatio);
- img.setOriginalType(Image.ORIGINAL_PNG);
- return img;
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- void decodeIdat() {
- int nbitDepth = bitDepth;
- if (nbitDepth == 16)
- nbitDepth = 8;
- int size = -1;
- bytesPerPixel = (bitDepth == 16) ? 2 : 1;
- switch (colorType) {
- case 0:
- size = (nbitDepth * width + 7) / 8 * height;
- break;
- case 2:
- size = width * 3 * height;
- bytesPerPixel *= 3;
- break;
- case 3:
- if (interlaceMethod == 1)
- size = (nbitDepth * width + 7) / 8 * height;
- bytesPerPixel = 1;
- break;
- case 4:
- size = width * height;
- bytesPerPixel *= 2;
- break;
- case 6:
- size = width * 3 * height;
- bytesPerPixel *= 4;
- break;
- }
- if (size >= 0)
- image = new byte[size];
- if (palShades)
- smask = new byte[width * height];
- else if (genBWMask)
- smask = new byte[(width + 7) / 8 * height];
- ByteArrayInputStream bai = new ByteArrayInputStream(idat.getBuf(), 0, idat.size());
- InputStream infStream = new InflaterInputStream(bai, new Inflater());
- dataStream = new DataInputStream(infStream);
-
- if (interlaceMethod != 1) {
- decodePass(0, 0, 1, 1, width, height);
- }
- else {
- decodePass(0, 0, 8, 8, (width + 7)/8, (height + 7)/8);
- decodePass(4, 0, 8, 8, (width + 3)/8, (height + 7)/8);
- decodePass(0, 4, 4, 8, (width + 3)/4, (height + 3)/8);
- decodePass(2, 0, 4, 4, (width + 1)/4, (height + 3)/4);
- decodePass(0, 2, 2, 4, (width + 1)/2, (height + 1)/4);
- decodePass(1, 0, 2, 2, width/2, (height + 1)/2);
- decodePass(0, 1, 1, 2, width, height/2);
- }
-
- }
-
- void decodePass( int xOffset, int yOffset,
- int xStep, int yStep,
- int passWidth, int passHeight) {
- if ((passWidth == 0) || (passHeight == 0)) {
- return;
- }
-
- int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8;
- byte[] curr = new byte[bytesPerRow];
- byte[] prior = new byte[bytesPerRow];
-
- // Decode the (sub)image row-by-row
- int srcY, dstY;
- for (srcY = 0, dstY = yOffset;
- srcY < passHeight;
- srcY++, dstY += yStep) {
- // Read the filter type byte and a row of data
- int filter = 0;
- try {
- filter = dataStream.read();
- dataStream.readFully(curr, 0, bytesPerRow);
- } catch (Exception e) {
- // empty on purpose
- }
-
- switch (filter) {
- case PNG_FILTER_NONE:
- break;
- case PNG_FILTER_SUB:
- decodeSubFilter(curr, bytesPerRow, bytesPerPixel);
- break;
- case PNG_FILTER_UP:
- decodeUpFilter(curr, prior, bytesPerRow);
- break;
- case PNG_FILTER_AVERAGE:
- decodeAverageFilter(curr, prior, bytesPerRow, bytesPerPixel);
- break;
- case PNG_FILTER_PAETH:
- decodePaethFilter(curr, prior, bytesPerRow, bytesPerPixel);
- break;
- default:
- // Error -- uknown filter type
- throw new RuntimeException("PNG filter unknown.");
- }
-
- processPixels(curr, xOffset, xStep, dstY, passWidth);
-
- // Swap curr and prior
- byte[] tmp = prior;
- prior = curr;
- curr = tmp;
- }
- }
-
- void processPixels(byte curr[], int xOffset, int step, int y, int width) {
- int srcX, dstX;
-
- int out[] = getPixel(curr);
- int sizes = 0;
- switch (colorType) {
- case 0:
- case 3:
- case 4:
- sizes = 1;
- break;
- case 2:
- case 6:
- sizes = 3;
- break;
- }
- if (image != null) {
- dstX = xOffset;
- int yStride = (sizes*this.width*(bitDepth == 16 ? 8 : bitDepth)+ 7)/8;
- for (srcX = 0; srcX < width; srcX++) {
- setPixel(image, out, inputBands * srcX, sizes, dstX, y, bitDepth, yStride);
- dstX += step;
- }
- }
- if (palShades) {
- if ((colorType & 4) != 0) {
- if (bitDepth == 16) {
- for (int k = 0; k < width; ++k)
- out[k * inputBands + sizes] >>>= 8;
- }
- int yStride = this.width;
- dstX = xOffset;
- for (srcX = 0; srcX < width; srcX++) {
- setPixel(smask, out, inputBands * srcX + sizes, 1, dstX, y, 8, yStride);
- dstX += step;
- }
- }
- else { //colorType 3
- int yStride = this.width;
- int v[] = new int[1];
- dstX = xOffset;
- for (srcX = 0; srcX < width; srcX++) {
- int idx = out[srcX];
- if (idx < trans.length)
- v[0] = trans[idx];
- setPixel(smask, v, 0, 1, dstX, y, 8, yStride);
- dstX += step;
- }
- }
- }
- else if (genBWMask) {
- switch (colorType) {
- case 3: {
- int yStride = (this.width + 7) / 8;
- int v[] = new int[1];
- dstX = xOffset;
- for (srcX = 0; srcX < width; srcX++) {
- int idx = out[srcX];
- if (idx < trans.length)
- v[0] = (trans[idx] == 0 ? 1 : 0);
- setPixel(smask, v, 0, 1, dstX, y, 1, yStride);
- dstX += step;
- }
- break;
- }
- case 0: {
- int yStride = (this.width + 7) / 8;
- int v[] = new int[1];
- dstX = xOffset;
- for (srcX = 0; srcX < width; srcX++) {
- int g = out[srcX];
- v[0] = (g == transRedGray ? 1 : 0);
- setPixel(smask, v, 0, 1, dstX, y, 1, yStride);
- dstX += step;
- }
- break;
- }
- case 2: {
- int yStride = (this.width + 7) / 8;
- int v[] = new int[1];
- dstX = xOffset;
- for (srcX = 0; srcX < width; srcX++) {
- int markRed = inputBands * srcX;
- v[0] = (out[markRed] == transRedGray && out[markRed + 1] == transGreen
- && out[markRed + 2] == transBlue ? 1 : 0);
- setPixel(smask, v, 0, 1, dstX, y, 1, yStride);
- dstX += step;
- }
- break;
- }
- }
- }
- }
-
- static int getPixel(byte image[], int x, int y, int bitDepth, int bytesPerRow) {
- if (bitDepth == 8) {
- int pos = bytesPerRow * y + x;
- return image[pos] & 0xff;
- }
- else {
- int pos = bytesPerRow * y + x / (8 / bitDepth);
- int v = image[pos] >> (8 - bitDepth * (x % (8 / bitDepth))- bitDepth);
- return v & ((1 << bitDepth) - 1);
- }
- }
-
- static void setPixel(byte image[], int data[], int offset, int size, int x, int y, int bitDepth, int bytesPerRow) {
- if (bitDepth == 8) {
- int pos = bytesPerRow * y + size * x;
- for (int k = 0; k < size; ++k)
- image[pos + k] = (byte)data[k + offset];
- }
- else if (bitDepth == 16) {
- int pos = bytesPerRow * y + size * x;
- for (int k = 0; k < size; ++k)
- image[pos + k] = (byte)(data[k + offset] >>> 8);
- }
- else {
- int pos = bytesPerRow * y + x / (8 / bitDepth);
- int v = data[offset] << (8 - bitDepth * (x % (8 / bitDepth))- bitDepth);
- image[pos] |= v;
- }
- }
-
- int[] getPixel(byte curr[]) {
- switch (bitDepth) {
- case 8: {
- int out[] = new int[curr.length];
- for (int k = 0; k < out.length; ++k)
- out[k] = curr[k] & 0xff;
- return out;
- }
- case 16: {
- int out[] = new int[curr.length / 2];
- for (int k = 0; k < out.length; ++k)
- out[k] = ((curr[k * 2] & 0xff) << 8) + (curr[k * 2 + 1] & 0xff);
- return out;
- }
- default: {
- int out[] = new int[curr.length * 8 / bitDepth];
- int idx = 0;
- int passes = 8 / bitDepth;
- int mask = (1 << bitDepth) - 1;
- for (int k = 0; k < curr.length; ++k) {
- for (int j = passes - 1; j >= 0; --j) {
- out[idx++] = (curr[k] >>> (bitDepth * j)) & mask;
- }
- }
- return out;
- }
- }
- }
-
- private static void decodeSubFilter(byte[] curr, int count, int bpp) {
- for (int i = bpp; i < count; i++) {
- int val;
-
- val = curr[i] & 0xff;
- val += curr[i - bpp] & 0xff;
-
- curr[i] = (byte)val;
- }
- }
-
- private static void decodeUpFilter(byte[] curr, byte[] prev,
- int count) {
- for (int i = 0; i < count; i++) {
- int raw = curr[i] & 0xff;
- int prior = prev[i] & 0xff;
-
- curr[i] = (byte)(raw + prior);
- }
- }
-
- private static void decodeAverageFilter(byte[] curr, byte[] prev,
- int count, int bpp) {
- int raw, priorPixel, priorRow;
-
- for (int i = 0; i < bpp; i++) {
- raw = curr[i] & 0xff;
- priorRow = prev[i] & 0xff;
-
- curr[i] = (byte)(raw + priorRow/2);
- }
-
- for (int i = bpp; i < count; i++) {
- raw = curr[i] & 0xff;
- priorPixel = curr[i - bpp] & 0xff;
- priorRow = prev[i] & 0xff;
-
- curr[i] = (byte)(raw + (priorPixel + priorRow)/2);
- }
- }
-
- private static int paethPredictor(int a, int b, int c) {
- int p = a + b - c;
- int pa = Math.abs(p - a);
- int pb = Math.abs(p - b);
- int pc = Math.abs(p - c);
-
- if ((pa <= pb) && (pa <= pc)) {
- return a;
- } else if (pb <= pc) {
- return b;
- } else {
- return c;
- }
- }
-
- private static void decodePaethFilter(byte[] curr, byte[] prev,
- int count, int bpp) {
- int raw, priorPixel, priorRow, priorRowPixel;
-
- for (int i = 0; i < bpp; i++) {
- raw = curr[i] & 0xff;
- priorRow = prev[i] & 0xff;
-
- curr[i] = (byte)(raw + priorRow);
- }
-
- for (int i = bpp; i < count; i++) {
- raw = curr[i] & 0xff;
- priorPixel = curr[i - bpp] & 0xff;
- priorRow = prev[i] & 0xff;
- priorRowPixel = prev[i - bpp] & 0xff;
-
- curr[i] = (byte)(raw + paethPredictor(priorPixel,
- priorRow,
- priorRowPixel));
- }
- }
-
- static class NewByteArrayOutputStream extends ByteArrayOutputStream {
- public byte[] getBuf() {
- return buf;
- }
- }
-
-/**
- * Gets an <CODE>int</CODE> from an <CODE>InputStream</CODE>.
- *
- * @param is an <CODE>InputStream</CODE>
- * @return the value of an <CODE>int</CODE>
- */
-
- public static final int getInt(InputStream is) throws IOException {
- return (is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read();
- }
-
-/**
- * Gets a <CODE>word</CODE> from an <CODE>InputStream</CODE>.
- *
- * @param is an <CODE>InputStream</CODE>
- * @return the value of an <CODE>int</CODE>
- */
-
- public static final int getWord(InputStream is) throws IOException {
- return (is.read() << 8) + is.read();
- }
-
-/**
- * Gets a <CODE>String</CODE> from an <CODE>InputStream</CODE>.
- *
- * @param is an <CODE>InputStream</CODE>
- * @return the value of an <CODE>int</CODE>
- */
-
- public static final String getString(InputStream is) throws IOException {
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < 4; i++) {
- buf.append((char)is.read());
- }
- return buf.toString();
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/TIFFConstants.java b/src/main/java/com/lowagie/text/pdf/codec/TIFFConstants.java
deleted file mode 100644
index a4ba5d5..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TIFFConstants.java
+++ /dev/null
@@ -1,296 +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.
- */
-package com.lowagie.text.pdf.codec;
-
-/**
- * A baseline TIFF reader. The reader has some functionality in addition to
- * the baseline specifications for Bilevel images, for which the group 3 and
- * group 4 decompression schemes have been implemented. Support for LZW
- * decompression has also been added. Support for Horizontal differencing
- * predictor decoding is also included, when used with LZW compression.
- * However, this support is limited to data with bitsPerSample value of 8.
- * When reading in RGB images, support for alpha and extraSamples being
- * present has been added. Support for reading in images with 16 bit samples
- * has been added. Support for the SampleFormat tag (signed samples as well
- * as floating-point samples) has also been added. In all other cases, support
- * is limited to Baseline specifications.
- *
- *
- */
-public class TIFFConstants {
-
-/*
- * TIFF Tag Definitions (from tifflib).
- */
- public static final int TIFFTAG_SUBFILETYPE = 254; /* subfile data descriptor */
- public static final int FILETYPE_REDUCEDIMAGE = 0x1; /* reduced resolution version */
- public static final int FILETYPE_PAGE = 0x2; /* one page of many */
- public static final int FILETYPE_MASK = 0x4; /* transparency mask */
- public static final int TIFFTAG_OSUBFILETYPE = 255; /* +kind of data in subfile */
- public static final int OFILETYPE_IMAGE = 1; /* full resolution image data */
- public static final int OFILETYPE_REDUCEDIMAGE = 2; /* reduced size image data */
- public static final int OFILETYPE_PAGE = 3; /* one page of many */
- public static final int TIFFTAG_IMAGEWIDTH = 256; /* image width in pixels */
- public static final int TIFFTAG_IMAGELENGTH = 257; /* image height in pixels */
- public static final int TIFFTAG_BITSPERSAMPLE = 258; /* bits per channel (sample) */
- public static final int TIFFTAG_COMPRESSION = 259; /* data compression technique */
- public static final int COMPRESSION_NONE = 1; /* dump mode */
- public static final int COMPRESSION_CCITTRLE = 2; /* CCITT modified Huffman RLE */
- public static final int COMPRESSION_CCITTFAX3 = 3; /* CCITT Group 3 fax encoding */
- public static final int COMPRESSION_CCITTFAX4 = 4; /* CCITT Group 4 fax encoding */
- public static final int COMPRESSION_LZW = 5; /* Lempel-Ziv & Welch */
- public static final int COMPRESSION_OJPEG = 6; /* !6.0 JPEG */
- public static final int COMPRESSION_JPEG = 7; /* %JPEG DCT compression */
- public static final int COMPRESSION_NEXT = 32766; /* NeXT 2-bit RLE */
- public static final int COMPRESSION_CCITTRLEW = 32771; /* #1 w/ word alignment */
- public static final int COMPRESSION_PACKBITS = 32773; /* Macintosh RLE */
- public static final int COMPRESSION_THUNDERSCAN = 32809; /* ThunderScan RLE */
- /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@etsinc.com) */
- public static final int COMPRESSION_IT8CTPAD = 32895; /* IT8 CT w/padding */
- public static final int COMPRESSION_IT8LW = 32896; /* IT8 Linework RLE */
- public static final int COMPRESSION_IT8MP = 32897; /* IT8 Monochrome picture */
- public static final int COMPRESSION_IT8BL = 32898; /* IT8 Binary line art */
- /* compression codes 32908-32911 are reserved for Pixar */
- public static final int COMPRESSION_PIXARFILM = 32908; /* Pixar companded 10bit LZW */
- public static final int COMPRESSION_PIXARLOG = 32909; /* Pixar companded 11bit ZIP */
- public static final int COMPRESSION_DEFLATE = 32946; /* Deflate compression */
- public static final int COMPRESSION_ADOBE_DEFLATE = 8; /* Deflate compression, as recognized by Adobe */
- /* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
- public static final int COMPRESSION_DCS = 32947; /* Kodak DCS encoding */
- public static final int COMPRESSION_JBIG = 34661; /* ISO JBIG */
- public static final int COMPRESSION_SGILOG = 34676; /* SGI Log Luminance RLE */
- public static final int COMPRESSION_SGILOG24 = 34677; /* SGI Log 24-bit packed */
- public static final int TIFFTAG_PHOTOMETRIC = 262; /* photometric interpretation */
- public static final int PHOTOMETRIC_MINISWHITE = 0; /* min value is white */
- public static final int PHOTOMETRIC_MINISBLACK = 1; /* min value is black */
- public static final int PHOTOMETRIC_RGB = 2; /* RGB color model */
- public static final int PHOTOMETRIC_PALETTE = 3; /* color map indexed */
- public static final int PHOTOMETRIC_MASK = 4; /* $holdout mask */
- public static final int PHOTOMETRIC_SEPARATED = 5; /* !color separations */
- public static final int PHOTOMETRIC_YCBCR = 6; /* !CCIR 601 */
- public static final int PHOTOMETRIC_CIELAB = 8; /* !1976 CIE L*a*b* */
- public static final int PHOTOMETRIC_LOGL = 32844; /* CIE Log2(L) */
- public static final int PHOTOMETRIC_LOGLUV = 32845; /* CIE Log2(L) (u',v') */
- public static final int TIFFTAG_THRESHHOLDING = 263; /* +thresholding used on data */
- public static final int THRESHHOLD_BILEVEL = 1; /* b&w art scan */
- public static final int THRESHHOLD_HALFTONE = 2; /* or dithered scan */
- public static final int THRESHHOLD_ERRORDIFFUSE = 3; /* usually floyd-steinberg */
- public static final int TIFFTAG_CELLWIDTH = 264; /* +dithering matrix width */
- public static final int TIFFTAG_CELLLENGTH = 265; /* +dithering matrix height */
- public static final int TIFFTAG_FILLORDER = 266; /* data order within a byte */
- public static final int FILLORDER_MSB2LSB = 1; /* most significant -> least */
- public static final int FILLORDER_LSB2MSB = 2; /* least significant -> most */
- public static final int TIFFTAG_DOCUMENTNAME = 269; /* name of doc. image is from */
- public static final int TIFFTAG_IMAGEDESCRIPTION = 270; /* info about image */
- public static final int TIFFTAG_MAKE = 271; /* scanner manufacturer name */
- public static final int TIFFTAG_MODEL = 272; /* scanner model name/number */
- public static final int TIFFTAG_STRIPOFFSETS = 273; /* offsets to data strips */
- public static final int TIFFTAG_ORIENTATION = 274; /* +image orientation */
- public static final int ORIENTATION_TOPLEFT = 1; /* row 0 top, col 0 lhs */
- public static final int ORIENTATION_TOPRIGHT = 2; /* row 0 top, col 0 rhs */
- public static final int ORIENTATION_BOTRIGHT = 3; /* row 0 bottom, col 0 rhs */
- public static final int ORIENTATION_BOTLEFT = 4; /* row 0 bottom, col 0 lhs */
- public static final int ORIENTATION_LEFTTOP = 5; /* row 0 lhs, col 0 top */
- public static final int ORIENTATION_RIGHTTOP = 6; /* row 0 rhs, col 0 top */
- public static final int ORIENTATION_RIGHTBOT = 7; /* row 0 rhs, col 0 bottom */
- public static final int ORIENTATION_LEFTBOT = 8; /* row 0 lhs, col 0 bottom */
- public static final int TIFFTAG_SAMPLESPERPIXEL = 277; /* samples per pixel */
- public static final int TIFFTAG_ROWSPERSTRIP = 278; /* rows per strip of data */
- public static final int TIFFTAG_STRIPBYTECOUNTS = 279; /* bytes counts for strips */
- public static final int TIFFTAG_MINSAMPLEVALUE = 280; /* +minimum sample value */
- public static final int TIFFTAG_MAXSAMPLEVALUE = 281; /* +maximum sample value */
- public static final int TIFFTAG_XRESOLUTION = 282; /* pixels/resolution in x */
- public static final int TIFFTAG_YRESOLUTION = 283; /* pixels/resolution in y */
- public static final int TIFFTAG_PLANARCONFIG = 284; /* storage organization */
- public static final int PLANARCONFIG_CONTIG = 1; /* single image plane */
- public static final int PLANARCONFIG_SEPARATE = 2; /* separate planes of data */
- public static final int TIFFTAG_PAGENAME = 285; /* page name image is from */
- public static final int TIFFTAG_XPOSITION = 286; /* x page offset of image lhs */
- public static final int TIFFTAG_YPOSITION = 287; /* y page offset of image lhs */
- public static final int TIFFTAG_FREEOFFSETS = 288; /* +byte offset to free block */
- public static final int TIFFTAG_FREEBYTECOUNTS = 289; /* +sizes of free blocks */
- public static final int TIFFTAG_GRAYRESPONSEUNIT = 290; /* $gray scale curve accuracy */
- public static final int GRAYRESPONSEUNIT_10S = 1; /* tenths of a unit */
- public static final int GRAYRESPONSEUNIT_100S = 2; /* hundredths of a unit */
- public static final int GRAYRESPONSEUNIT_1000S = 3; /* thousandths of a unit */
- public static final int GRAYRESPONSEUNIT_10000S = 4; /* ten-thousandths of a unit */
- public static final int GRAYRESPONSEUNIT_100000S = 5; /* hundred-thousandths */
- public static final int TIFFTAG_GRAYRESPONSECURVE = 291; /* $gray scale response curve */
- public static final int TIFFTAG_GROUP3OPTIONS = 292; /* 32 flag bits */
- public static final int GROUP3OPT_2DENCODING = 0x1; /* 2-dimensional coding */
- public static final int GROUP3OPT_UNCOMPRESSED = 0x2; /* data not compressed */
- public static final int GROUP3OPT_FILLBITS = 0x4; /* fill to byte boundary */
- public static final int TIFFTAG_GROUP4OPTIONS = 293; /* 32 flag bits */
- public static final int GROUP4OPT_UNCOMPRESSED = 0x2; /* data not compressed */
- public static final int TIFFTAG_RESOLUTIONUNIT = 296; /* units of resolutions */
- public static final int RESUNIT_NONE = 1; /* no meaningful units */
- public static final int RESUNIT_INCH = 2; /* english */
- public static final int RESUNIT_CENTIMETER = 3; /* metric */
- public static final int TIFFTAG_PAGENUMBER = 297; /* page numbers of multi-page */
- public static final int TIFFTAG_COLORRESPONSEUNIT = 300; /* $color curve accuracy */
- public static final int COLORRESPONSEUNIT_10S = 1; /* tenths of a unit */
- public static final int COLORRESPONSEUNIT_100S = 2; /* hundredths of a unit */
- public static final int COLORRESPONSEUNIT_1000S = 3; /* thousandths of a unit */
- public static final int COLORRESPONSEUNIT_10000S = 4; /* ten-thousandths of a unit */
- public static final int COLORRESPONSEUNIT_100000S = 5; /* hundred-thousandths */
- public static final int TIFFTAG_TRANSFERFUNCTION = 301; /* !colorimetry info */
- public static final int TIFFTAG_SOFTWARE = 305; /* name & release */
- public static final int TIFFTAG_DATETIME = 306; /* creation date and time */
- public static final int TIFFTAG_ARTIST = 315; /* creator of image */
- public static final int TIFFTAG_HOSTCOMPUTER = 316; /* machine where created */
- public static final int TIFFTAG_PREDICTOR = 317; /* prediction scheme w/ LZW */
- public static final int TIFFTAG_WHITEPOINT = 318; /* image white point */
- public static final int TIFFTAG_PRIMARYCHROMATICITIES = 319; /* !primary chromaticities */
- public static final int TIFFTAG_COLORMAP = 320; /* RGB map for pallette image */
- public static final int TIFFTAG_HALFTONEHINTS = 321; /* !highlight+shadow info */
- public static final int TIFFTAG_TILEWIDTH = 322; /* !rows/data tile */
- public static final int TIFFTAG_TILELENGTH = 323; /* !cols/data tile */
- public static final int TIFFTAG_TILEOFFSETS = 324; /* !offsets to data tiles */
- public static final int TIFFTAG_TILEBYTECOUNTS = 325; /* !byte counts for tiles */
- public static final int TIFFTAG_BADFAXLINES = 326; /* lines w/ wrong pixel count */
- public static final int TIFFTAG_CLEANFAXDATA = 327; /* regenerated line info */
- public static final int CLEANFAXDATA_CLEAN = 0; /* no errors detected */
- public static final int CLEANFAXDATA_REGENERATED = 1; /* receiver regenerated lines */
- public static final int CLEANFAXDATA_UNCLEAN = 2; /* uncorrected errors exist */
- public static final int TIFFTAG_CONSECUTIVEBADFAXLINES = 328; /* max consecutive bad lines */
- public static final int TIFFTAG_SUBIFD = 330; /* subimage descriptors */
- public static final int TIFFTAG_INKSET = 332; /* !inks in separated image */
- public static final int INKSET_CMYK = 1; /* !cyan-magenta-yellow-black */
- public static final int TIFFTAG_INKNAMES = 333; /* !ascii names of inks */
- public static final int TIFFTAG_NUMBEROFINKS = 334; /* !number of inks */
- public static final int TIFFTAG_DOTRANGE = 336; /* !0% and 100% dot codes */
- public static final int TIFFTAG_TARGETPRINTER = 337; /* !separation target */
- public static final int TIFFTAG_EXTRASAMPLES = 338; /* !info about extra samples */
- public static final int EXTRASAMPLE_UNSPECIFIED = 0; /* !unspecified data */
- public static final int EXTRASAMPLE_ASSOCALPHA = 1; /* !associated alpha data */
- public static final int EXTRASAMPLE_UNASSALPHA = 2; /* !unassociated alpha data */
- public static final int TIFFTAG_SAMPLEFORMAT = 339; /* !data sample format */
- public static final int SAMPLEFORMAT_UINT = 1; /* !unsigned integer data */
- public static final int SAMPLEFORMAT_INT = 2; /* !signed integer data */
- public static final int SAMPLEFORMAT_IEEEFP = 3; /* !IEEE floating point data */
- public static final int SAMPLEFORMAT_VOID = 4; /* !untyped data */
- public static final int SAMPLEFORMAT_COMPLEXINT = 5; /* !complex signed int */
- public static final int SAMPLEFORMAT_COMPLEXIEEEFP = 6; /* !complex ieee floating */
- public static final int TIFFTAG_SMINSAMPLEVALUE = 340; /* !variable MinSampleValue */
- public static final int TIFFTAG_SMAXSAMPLEVALUE = 341; /* !variable MaxSampleValue */
- public static final int TIFFTAG_JPEGTABLES = 347; /* %JPEG table stream */
-/*
- * Tags 512-521 are obsoleted by Technical Note #2
- * which specifies a revised JPEG-in-TIFF scheme.
- */
- public static final int TIFFTAG_JPEGPROC = 512; /* !JPEG processing algorithm */
- public static final int JPEGPROC_BASELINE = 1; /* !baseline sequential */
- public static final int JPEGPROC_LOSSLESS = 14; /* !Huffman coded lossless */
- public static final int TIFFTAG_JPEGIFOFFSET = 513; /* !pointer to SOI marker */
- public static final int TIFFTAG_JPEGIFBYTECOUNT = 514; /* !JFIF stream length */
- public static final int TIFFTAG_JPEGRESTARTINTERVAL = 515; /* !restart interval length */
- public static final int TIFFTAG_JPEGLOSSLESSPREDICTORS = 517; /* !lossless proc predictor */
- public static final int TIFFTAG_JPEGPOINTTRANSFORM = 518; /* !lossless point transform */
- public static final int TIFFTAG_JPEGQTABLES = 519; /* !Q matrice offsets */
- public static final int TIFFTAG_JPEGDCTABLES = 520; /* !DCT table offsets */
- public static final int TIFFTAG_JPEGACTABLES = 521; /* !AC coefficient offsets */
- public static final int TIFFTAG_YCBCRCOEFFICIENTS = 529; /* !RGB -> YCbCr transform */
- public static final int TIFFTAG_YCBCRSUBSAMPLING = 530; /* !YCbCr subsampling factors */
- public static final int TIFFTAG_YCBCRPOSITIONING = 531; /* !subsample positioning */
- public static final int YCBCRPOSITION_CENTERED = 1; /* !as in PostScript Level 2 */
- public static final int YCBCRPOSITION_COSITED = 2; /* !as in CCIR 601-1 */
- public static final int TIFFTAG_REFERENCEBLACKWHITE = 532; /* !colorimetry info */
- /* tags 32952-32956 are private tags registered to Island Graphics */
- public static final int TIFFTAG_REFPTS = 32953; /* image reference points */
- public static final int TIFFTAG_REGIONTACKPOINT = 32954; /* region-xform tack point */
- public static final int TIFFTAG_REGIONWARPCORNERS = 32955; /* warp quadrilateral */
- public static final int TIFFTAG_REGIONAFFINE = 32956; /* affine transformation mat */
- /* tags 32995-32999 are private tags registered to SGI */
- public static final int TIFFTAG_MATTEING = 32995; /* $use ExtraSamples */
- public static final int TIFFTAG_DATATYPE = 32996; /* $use SampleFormat */
- public static final int TIFFTAG_IMAGEDEPTH = 32997; /* z depth of image */
- public static final int TIFFTAG_TILEDEPTH = 32998; /* z depth/data tile */
- /* tags 33300-33309 are private tags registered to Pixar */
-/*
- * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
- * are set when an image has been cropped out of a larger image.
- * They reflect the size of the original uncropped image.
- * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
- * to determine the position of the smaller image in the larger one.
- */
- public static final int TIFFTAG_PIXAR_IMAGEFULLWIDTH = 33300; /* full image size in x */
- public static final int TIFFTAG_PIXAR_IMAGEFULLLENGTH = 33301; /* full image size in y */
- /* Tags 33302-33306 are used to identify special image modes and data
- * used by Pixar's texture formats.
- */
- public static final int TIFFTAG_PIXAR_TEXTUREFORMAT = 33302; /* texture map format */
- public static final int TIFFTAG_PIXAR_WRAPMODES = 33303; /* s & t wrap modes */
- public static final int TIFFTAG_PIXAR_FOVCOT = 33304; /* cotan(fov) for env. maps */
- public static final int TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN = 33305;
- public static final int TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA = 33306;
- /* tag 33405 is a private tag registered to Eastman Kodak */
- public static final int TIFFTAG_WRITERSERIALNUMBER = 33405; /* device serial number */
- /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
- public static final int TIFFTAG_COPYRIGHT = 33432; /* copyright string */
- /* IPTC TAG from RichTIFF specifications */
- public static final int TIFFTAG_RICHTIFFIPTC = 33723;
- /* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@etsinc.com) */
- public static final int TIFFTAG_IT8SITE = 34016; /* site name */
- public static final int TIFFTAG_IT8COLORSEQUENCE = 34017; /* color seq. [RGB,CMYK,etc] */
- public static final int TIFFTAG_IT8HEADER = 34018; /* DDES Header */
- public static final int TIFFTAG_IT8RASTERPADDING = 34019; /* raster scanline padding */
- public static final int TIFFTAG_IT8BITSPERRUNLENGTH = 34020; /* # of bits in short run */
- public static final int TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH = 34021;/* # of bits in long run */
- public static final int TIFFTAG_IT8COLORTABLE = 34022; /* LW colortable */
- public static final int TIFFTAG_IT8IMAGECOLORINDICATOR = 34023; /* BP/BL image color switch */
- public static final int TIFFTAG_IT8BKGCOLORINDICATOR = 34024; /* BP/BL bg color switch */
- public static final int TIFFTAG_IT8IMAGECOLORVALUE = 34025; /* BP/BL image color value */
- public static final int TIFFTAG_IT8BKGCOLORVALUE = 34026; /* BP/BL bg color value */
- public static final int TIFFTAG_IT8PIXELINTENSITYRANGE = 34027; /* MP pixel intensity value */
- public static final int TIFFTAG_IT8TRANSPARENCYINDICATOR = 34028; /* HC transparency switch */
- public static final int TIFFTAG_IT8COLORCHARACTERIZATION = 34029; /* color character. table */
- /* tags 34232-34236 are private tags registered to Texas Instruments */
- public static final int TIFFTAG_FRAMECOUNT = 34232; /* Sequence Frame Count */
- /* tag 34750 is a private tag registered to Adobe? */
- public static final int TIFFTAG_ICCPROFILE = 34675; /* ICC profile data */
- /* tag 34377 is private tag registered to Adobe for PhotoShop */
- public static final int TIFFTAG_PHOTOSHOP = 34377;
- /* tag 34750 is a private tag registered to Pixel Magic */
- public static final int TIFFTAG_JBIGOPTIONS = 34750; /* JBIG options */
- /* tags 34908-34914 are private tags registered to SGI */
- public static final int TIFFTAG_FAXRECVPARAMS = 34908; /* encoded Class 2 ses. parms */
- public static final int TIFFTAG_FAXSUBADDRESS = 34909; /* received SubAddr string */
- public static final int TIFFTAG_FAXRECVTIME = 34910; /* receive time (secs) */
- /* tags 37439-37443 are registered to SGI <gregl@sgi.com> */
- public static final int TIFFTAG_STONITS = 37439; /* Sample value to Nits */
- /* tag 34929 is a private tag registered to FedEx */
- public static final int TIFFTAG_FEDEX_EDR = 34929; /* unknown use */
- /* tag 65535 is an undefined tag used by Eastman Kodak */
- public static final int TIFFTAG_DCSHUESHIFTVALUES = 65535; /* hue shift correction data */
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/TIFFDirectory.java b/src/main/java/com/lowagie/text/pdf/codec/TIFFDirectory.java
deleted file mode 100644
index abcc0dd..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TIFFDirectory.java
+++ /dev/null
@@ -1,656 +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.
- */
-package com.lowagie.text.pdf.codec;
-import java.io.IOException;
-import java.io.EOFException;
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.ArrayList;
-import com.lowagie.text.pdf.RandomAccessFileOrArray;
-
-/**
- * A class representing an Image File Directory (IFD) from a TIFF 6.0
- * stream. The TIFF file format is described in more detail in the
- * comments for the TIFFDescriptor class.
- *
- * <p> A TIFF IFD consists of a set of TIFFField tags. Methods are
- * provided to query the set of tags and to obtain the raw field
- * array. In addition, convenience methods are provided for acquiring
- * the values of tags that contain a single value that fits into a
- * byte, int, long, float, or double.
- *
- * <p> Every TIFF file is made up of one or more public IFDs that are
- * joined in a linked list, rooted in the file header. A file may
- * also contain so-called private IFDs that are referenced from
- * tag data and do not appear in the main list.
- *
- * <p><b> This class is not a committed part of the JAI API. It may
- * be removed or changed in future releases of JAI.</b>
- *
- * @see TIFFField
- */
-public class TIFFDirectory extends Object implements Serializable {
-
- /** A boolean storing the endianness of the stream. */
- boolean isBigEndian;
-
- /** The number of entries in the IFD. */
- int numEntries;
-
- /** An array of TIFFFields. */
- TIFFField[] fields;
-
- /** A Hashtable indexing the fields by tag number. */
- Hashtable fieldIndex = new Hashtable();
-
- /** The offset of this IFD. */
- long IFDOffset = 8;
-
- /** The offset of the next IFD. */
- long nextIFDOffset = 0;
-
- /** The default constructor. */
- TIFFDirectory() {}
-
- private static boolean isValidEndianTag(int endian) {
- return ((endian == 0x4949) || (endian == 0x4d4d));
- }
-
- /**
- * Constructs a TIFFDirectory from a SeekableStream.
- * The directory parameter specifies which directory to read from
- * the linked list present in the stream; directory 0 is normally
- * read but it is possible to store multiple images in a single
- * TIFF file by maintaing multiple directories.
- *
- * @param stream a SeekableStream to read from.
- * @param directory the index of the directory to read.
- */
- public TIFFDirectory(RandomAccessFileOrArray stream, int directory)
- throws IOException {
-
- long global_save_offset = stream.getFilePointer();
- long ifd_offset;
-
- // Read the TIFF header
- stream.seek(0L);
- int endian = stream.readUnsignedShort();
- if (!isValidEndianTag(endian)) {
- throw new
- IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
- }
- isBigEndian = (endian == 0x4d4d);
-
- int magic = readUnsignedShort(stream);
- if (magic != 42) {
- throw new
- IllegalArgumentException("Bad magic number, should be 42.");
- }
-
- // Get the initial ifd offset as an unsigned int (using a long)
- ifd_offset = readUnsignedInt(stream);
-
- for (int i = 0; i < directory; i++) {
- if (ifd_offset == 0L) {
- throw new
- IllegalArgumentException("Directory number too large.");
- }
-
- stream.seek(ifd_offset);
- int entries = readUnsignedShort(stream);
- stream.skip(12*entries);
-
- ifd_offset = readUnsignedInt(stream);
- }
-
- stream.seek(ifd_offset);
- initialize(stream);
- stream.seek(global_save_offset);
- }
-
- /**
- * Constructs a TIFFDirectory by reading a SeekableStream.
- * The ifd_offset parameter specifies the stream offset from which
- * to begin reading; this mechanism is sometimes used to store
- * private IFDs within a TIFF file that are not part of the normal
- * sequence of IFDs.
- *
- * @param stream a SeekableStream to read from.
- * @param ifd_offset the long byte offset of the directory.
- * @param directory the index of the directory to read beyond the
- * one at the current stream offset; zero indicates the IFD
- * at the current offset.
- */
- public TIFFDirectory(RandomAccessFileOrArray stream, long ifd_offset, int directory)
- throws IOException {
-
- long global_save_offset = stream.getFilePointer();
- stream.seek(0L);
- int endian = stream.readUnsignedShort();
- if (!isValidEndianTag(endian)) {
- throw new
- IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
- }
- isBigEndian = (endian == 0x4d4d);
-
- // Seek to the first IFD.
- stream.seek(ifd_offset);
-
- // Seek to desired IFD if necessary.
- int dirNum = 0;
- while(dirNum < directory) {
- // Get the number of fields in the current IFD.
- int numEntries = readUnsignedShort(stream);
-
- // Skip to the next IFD offset value field.
- stream.seek(ifd_offset + 12*numEntries);
-
- // Read the offset to the next IFD beyond this one.
- ifd_offset = readUnsignedInt(stream);
-
- // Seek to the next IFD.
- stream.seek(ifd_offset);
-
- // Increment the directory.
- dirNum++;
- }
-
- initialize(stream);
- stream.seek(global_save_offset);
- }
-
- private static final int[] sizeOfType = {
- 0, // 0 = n/a
- 1, // 1 = byte
- 1, // 2 = ascii
- 2, // 3 = short
- 4, // 4 = long
- 8, // 5 = rational
- 1, // 6 = sbyte
- 1, // 7 = undefined
- 2, // 8 = sshort
- 4, // 9 = slong
- 8, // 10 = srational
- 4, // 11 = float
- 8 // 12 = double
- };
-
- private void initialize(RandomAccessFileOrArray stream) throws IOException {
- long nextTagOffset = 0L;
- long maxOffset = stream.length();
- int i, j;
-
- IFDOffset = stream.getFilePointer();
-
- numEntries = readUnsignedShort(stream);
- fields = new TIFFField[numEntries];
-
- for (i = 0; (i < numEntries) && (nextTagOffset < maxOffset); i++) {
- int tag = readUnsignedShort(stream);
- int type = readUnsignedShort(stream);
- int count = (int)(readUnsignedInt(stream));
- boolean processTag = true;
-
- // The place to return to to read the next tag
- nextTagOffset = stream.getFilePointer() + 4;
-
- try {
- // If the tag data can't fit in 4 bytes, the next 4 bytes
- // contain the starting offset of the data
- if (count*sizeOfType[type] > 4) {
- long valueOffset = readUnsignedInt(stream);
-
- // bounds check offset for EOF
- if (valueOffset < maxOffset) {
- stream.seek(valueOffset);
- }
- else {
- // bad offset pointer .. skip tag
- processTag = false;
- }
- }
- } catch (ArrayIndexOutOfBoundsException ae) {
- // if the data type is unknown we should skip this TIFF Field
- processTag = false;
- }
-
- if (processTag) {
- fieldIndex.put(new Integer(tag), new Integer(i));
- Object obj = null;
-
- switch (type) {
- case TIFFField.TIFF_BYTE:
- case TIFFField.TIFF_SBYTE:
- case TIFFField.TIFF_UNDEFINED:
- case TIFFField.TIFF_ASCII:
- byte[] bvalues = new byte[count];
- stream.readFully(bvalues, 0, count);
-
- if (type == TIFFField.TIFF_ASCII) {
-
- // Can be multiple strings
- int index = 0, prevIndex = 0;
- ArrayList v = new ArrayList();
-
- while (index < count) {
-
- while ((index < count) && (bvalues[index++] != 0));
-
- // When we encountered zero, means one string has ended
- v.add(new String(bvalues, prevIndex,
- (index - prevIndex)) );
- prevIndex = index;
- }
-
- count = v.size();
- String strings[] = new String[count];
- for (int c = 0 ; c < count; c++) {
- strings[c] = (String)v.get(c);
- }
-
- obj = strings;
- } else {
- obj = bvalues;
- }
-
- break;
-
- case TIFFField.TIFF_SHORT:
- char[] cvalues = new char[count];
- for (j = 0; j < count; j++) {
- cvalues[j] = (char)(readUnsignedShort(stream));
- }
- obj = cvalues;
- break;
-
- case TIFFField.TIFF_LONG:
- long[] lvalues = new long[count];
- for (j = 0; j < count; j++) {
- lvalues[j] = readUnsignedInt(stream);
- }
- obj = lvalues;
- break;
-
- case TIFFField.TIFF_RATIONAL:
- long[][] llvalues = new long[count][2];
- for (j = 0; j < count; j++) {
- llvalues[j][0] = readUnsignedInt(stream);
- llvalues[j][1] = readUnsignedInt(stream);
- }
- obj = llvalues;
- break;
-
- case TIFFField.TIFF_SSHORT:
- short[] svalues = new short[count];
- for (j = 0; j < count; j++) {
- svalues[j] = readShort(stream);
- }
- obj = svalues;
- break;
-
- case TIFFField.TIFF_SLONG:
- int[] ivalues = new int[count];
- for (j = 0; j < count; j++) {
- ivalues[j] = readInt(stream);
- }
- obj = ivalues;
- break;
-
- case TIFFField.TIFF_SRATIONAL:
- int[][] iivalues = new int[count][2];
- for (j = 0; j < count; j++) {
- iivalues[j][0] = readInt(stream);
- iivalues[j][1] = readInt(stream);
- }
- obj = iivalues;
- break;
-
- case TIFFField.TIFF_FLOAT:
- float[] fvalues = new float[count];
- for (j = 0; j < count; j++) {
- fvalues[j] = readFloat(stream);
- }
- obj = fvalues;
- break;
-
- case TIFFField.TIFF_DOUBLE:
- double[] dvalues = new double[count];
- for (j = 0; j < count; j++) {
- dvalues[j] = readDouble(stream);
- }
- obj = dvalues;
- break;
-
- default:
- break;
- }
-
- fields[i] = new TIFFField(tag, type, count, obj);
- }
-
- stream.seek(nextTagOffset);
- }
-
- // Read the offset of the next IFD.
- nextIFDOffset = readUnsignedInt(stream);
- }
-
- /** Returns the number of directory entries. */
- public int getNumEntries() {
- return numEntries;
- }
-
- /**
- * Returns the value of a given tag as a TIFFField,
- * or null if the tag is not present.
- */
- public TIFFField getField(int tag) {
- Integer i = (Integer)fieldIndex.get(new Integer(tag));
- if (i == null) {
- return null;
- } else {
- return fields[i.intValue()];
- }
- }
-
- /**
- * Returns true if a tag appears in the directory.
- */
- public boolean isTagPresent(int tag) {
- return fieldIndex.containsKey(new Integer(tag));
- }
-
- /**
- * Returns an ordered array of ints indicating the tag
- * values.
- */
- public int[] getTags() {
- int[] tags = new int[fieldIndex.size()];
- Enumeration e = fieldIndex.keys();
- int i = 0;
-
- while (e.hasMoreElements()) {
- tags[i++] = ((Integer)e.nextElement()).intValue();
- }
-
- return tags;
- }
-
- /**
- * Returns an array of TIFFFields containing all the fields
- * in this directory.
- */
- public TIFFField[] getFields() {
- return fields;
- }
-
- /**
- * Returns the value of a particular index of a given tag as a
- * byte. The caller is responsible for ensuring that the tag is
- * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or
- * TIFF_UNDEFINED.
- */
- public byte getFieldAsByte(int tag, int index) {
- Integer i = (Integer)fieldIndex.get(new Integer(tag));
- byte [] b = (fields[i.intValue()]).getAsBytes();
- return b[index];
- }
-
- /**
- * Returns the value of index 0 of a given tag as a
- * byte. The caller is responsible for ensuring that the tag is
- * present and has type TIFFField.TIFF_SBYTE, TIFF_BYTE, or
- * TIFF_UNDEFINED.
- */
- public byte getFieldAsByte(int tag) {
- return getFieldAsByte(tag, 0);
- }
-
- /**
- * Returns the value of a particular index of a given tag as a
- * long. The caller is responsible for ensuring that the tag is
- * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
- * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
- */
- public long getFieldAsLong(int tag, int index) {
- Integer i = (Integer)fieldIndex.get(new Integer(tag));
- return (fields[i.intValue()]).getAsLong(index);
- }
-
- /**
- * Returns the value of index 0 of a given tag as a
- * long. The caller is responsible for ensuring that the tag is
- * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
- * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
- */
- public long getFieldAsLong(int tag) {
- return getFieldAsLong(tag, 0);
- }
-
- /**
- * Returns the value of a particular index of a given tag as a
- * float. The caller is responsible for ensuring that the tag is
- * present and has numeric type (all but TIFF_UNDEFINED and
- * TIFF_ASCII).
- */
- public float getFieldAsFloat(int tag, int index) {
- Integer i = (Integer)fieldIndex.get(new Integer(tag));
- return fields[i.intValue()].getAsFloat(index);
- }
-
- /**
- * Returns the value of index 0 of a given tag as a float. The
- * caller is responsible for ensuring that the tag is present and
- * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
- */
- public float getFieldAsFloat(int tag) {
- return getFieldAsFloat(tag, 0);
- }
-
- /**
- * Returns the value of a particular index of a given tag as a
- * double. The caller is responsible for ensuring that the tag is
- * present and has numeric type (all but TIFF_UNDEFINED and
- * TIFF_ASCII).
- */
- public double getFieldAsDouble(int tag, int index) {
- Integer i = (Integer)fieldIndex.get(new Integer(tag));
- return fields[i.intValue()].getAsDouble(index);
- }
-
- /**
- * Returns the value of index 0 of a given tag as a double. The
- * caller is responsible for ensuring that the tag is present and
- * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
- */
- public double getFieldAsDouble(int tag) {
- return getFieldAsDouble(tag, 0);
- }
-
- // Methods to read primitive data types from the stream
-
- private short readShort(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readShort();
- } else {
- return stream.readShortLE();
- }
- }
-
- private int readUnsignedShort(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readUnsignedShort();
- } else {
- return stream.readUnsignedShortLE();
- }
- }
-
- private int readInt(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readInt();
- } else {
- return stream.readIntLE();
- }
- }
-
- private long readUnsignedInt(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readUnsignedInt();
- } else {
- return stream.readUnsignedIntLE();
- }
- }
-
- private long readLong(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readLong();
- } else {
- return stream.readLongLE();
- }
- }
-
- private float readFloat(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readFloat();
- } else {
- return stream.readFloatLE();
- }
- }
-
- private double readDouble(RandomAccessFileOrArray stream)
- throws IOException {
- if (isBigEndian) {
- return stream.readDouble();
- } else {
- return stream.readDoubleLE();
- }
- }
-
- private static int readUnsignedShort(RandomAccessFileOrArray stream,
- boolean isBigEndian)
- throws IOException {
- if (isBigEndian) {
- return stream.readUnsignedShort();
- } else {
- return stream.readUnsignedShortLE();
- }
- }
-
- private static long readUnsignedInt(RandomAccessFileOrArray stream,
- boolean isBigEndian)
- throws IOException {
- if (isBigEndian) {
- return stream.readUnsignedInt();
- } else {
- return stream.readUnsignedIntLE();
- }
- }
-
- // Utilities
-
- /**
- * Returns the number of image directories (subimages) stored in a
- * given TIFF file, represented by a <code>SeekableStream</code>.
- */
- public static int getNumDirectories(RandomAccessFileOrArray stream)
- throws IOException{
- long pointer = stream.getFilePointer(); // Save stream pointer
-
- stream.seek(0L);
- int endian = stream.readUnsignedShort();
- if (!isValidEndianTag(endian)) {
- throw new
- IllegalArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d).");
- }
- boolean isBigEndian = (endian == 0x4d4d);
- int magic = readUnsignedShort(stream, isBigEndian);
- if (magic != 42) {
- throw new
- IllegalArgumentException("Bad magic number, should be 42.");
- }
-
- stream.seek(4L);
- long offset = readUnsignedInt(stream, isBigEndian);
-
- int numDirectories = 0;
- while (offset != 0L) {
- ++numDirectories;
-
- // EOFException means IFD was probably not properly terminated.
- try {
- stream.seek(offset);
- int entries = readUnsignedShort(stream, isBigEndian);
- stream.skip(12*entries);
- offset = readUnsignedInt(stream, isBigEndian);
- } catch(EOFException eof) {
- numDirectories--;
- break;
- }
- }
-
- stream.seek(pointer); // Reset stream pointer
- return numDirectories;
- }
-
- /**
- * Returns a boolean indicating whether the byte order used in the
- * the TIFF file is big-endian (i.e. whether the byte order is from
- * the most significant to the least significant)
- */
- public boolean isBigEndian() {
- return isBigEndian;
- }
-
- /**
- * Returns the offset of the IFD corresponding to this
- * <code>TIFFDirectory</code>.
- */
- public long getIFDOffset() {
- return IFDOffset;
- }
-
- /**
- * Returns the offset of the next IFD after the IFD corresponding to this
- * <code>TIFFDirectory</code>.
- */
- public long getNextIFDOffset() {
- return nextIFDOffset;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java b/src/main/java/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java
deleted file mode 100644
index 7a7b61c..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TIFFFaxDecoder.java
+++ /dev/null
@@ -1,1477 +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.
- */
-package com.lowagie.text.pdf.codec;
-
-public class TIFFFaxDecoder {
-
- private int bitPointer, bytePointer;
- private byte[] data;
- private int w, h;
- private int fillOrder;
-
- // Data structures needed to store changing elements for the previous
- // and the current scanline
- private int changingElemSize = 0;
- private int prevChangingElems[];
- private int currChangingElems[];
-
- // Element at which to start search in getNextChangingElement
- private int lastChangingElement = 0;
-
- private int compression = 2;
-
- // Variables set by T4Options
- private int uncompressedMode = 0;
- private int fillBits = 0;
- private int oneD;
-
- static int table1[] = {
- 0x00, // 0 bits are left in first byte - SHOULD NOT HAPPEN
- 0x01, // 1 bits are left in first byte
- 0x03, // 2 bits are left in first byte
- 0x07, // 3 bits are left in first byte
- 0x0f, // 4 bits are left in first byte
- 0x1f, // 5 bits are left in first byte
- 0x3f, // 6 bits are left in first byte
- 0x7f, // 7 bits are left in first byte
- 0xff // 8 bits are left in first byte
- };
-
- static int table2[] = {
- 0x00, // 0
- 0x80, // 1
- 0xc0, // 2
- 0xe0, // 3
- 0xf0, // 4
- 0xf8, // 5
- 0xfc, // 6
- 0xfe, // 7
- 0xff // 8
- };
-
- // Table to be used when fillOrder = 2, for flipping bytes.
- static byte flipTable[] = {
- 0, -128, 64, -64, 32, -96, 96, -32,
- 16, -112, 80, -48, 48, -80, 112, -16,
- 8, -120, 72, -56, 40, -88, 104, -24,
- 24, -104, 88, -40, 56, -72, 120, -8,
- 4, -124, 68, -60, 36, -92, 100, -28,
- 20, -108, 84, -44, 52, -76, 116, -12,
- 12, -116, 76, -52, 44, -84, 108, -20,
- 28, -100, 92, -36, 60, -68, 124, -4,
- 2, -126, 66, -62, 34, -94, 98, -30,
- 18, -110, 82, -46, 50, -78, 114, -14,
- 10, -118, 74, -54, 42, -86, 106, -22,
- 26, -102, 90, -38, 58, -70, 122, -6,
- 6, -122, 70, -58, 38, -90, 102, -26,
- 22, -106, 86, -42, 54, -74, 118, -10,
- 14, -114, 78, -50, 46, -82, 110, -18,
- 30, -98, 94, -34, 62, -66, 126, -2,
- 1, -127, 65, -63, 33, -95, 97, -31,
- 17, -111, 81, -47, 49, -79, 113, -15,
- 9, -119, 73, -55, 41, -87, 105, -23,
- 25, -103, 89, -39, 57, -71, 121, -7,
- 5, -123, 69, -59, 37, -91, 101, -27,
- 21, -107, 85, -43, 53, -75, 117, -11,
- 13, -115, 77, -51, 45, -83, 109, -19,
- 29, -99, 93, -35, 61, -67, 125, -3,
- 3, -125, 67, -61, 35, -93, 99, -29,
- 19, -109, 83, -45, 51, -77, 115, -13,
- 11, -117, 75, -53, 43, -85, 107, -21,
- 27, -101, 91, -37, 59, -69, 123, -5,
- 7, -121, 71, -57, 39, -89, 103, -25,
- 23, -105, 87, -41, 55, -73, 119, -9,
- 15, -113, 79, -49, 47, -81, 111, -17,
- 31, -97, 95, -33, 63, -65, 127, -1,
- };
-
- // The main 10 bit white runs lookup table
- static short white[] = {
- // 0 - 7
- 6430, 6400, 6400, 6400, 3225, 3225, 3225, 3225,
- // 8 - 15
- 944, 944, 944, 944, 976, 976, 976, 976,
- // 16 - 23
- 1456, 1456, 1456, 1456, 1488, 1488, 1488, 1488,
- // 24 - 31
- 718, 718, 718, 718, 718, 718, 718, 718,
- // 32 - 39
- 750, 750, 750, 750, 750, 750, 750, 750,
- // 40 - 47
- 1520, 1520, 1520, 1520, 1552, 1552, 1552, 1552,
- // 48 - 55
- 428, 428, 428, 428, 428, 428, 428, 428,
- // 56 - 63
- 428, 428, 428, 428, 428, 428, 428, 428,
- // 64 - 71
- 654, 654, 654, 654, 654, 654, 654, 654,
- // 72 - 79
- 1072, 1072, 1072, 1072, 1104, 1104, 1104, 1104,
- // 80 - 87
- 1136, 1136, 1136, 1136, 1168, 1168, 1168, 1168,
- // 88 - 95
- 1200, 1200, 1200, 1200, 1232, 1232, 1232, 1232,
- // 96 - 103
- 622, 622, 622, 622, 622, 622, 622, 622,
- // 104 - 111
- 1008, 1008, 1008, 1008, 1040, 1040, 1040, 1040,
- // 112 - 119
- 44, 44, 44, 44, 44, 44, 44, 44,
- // 120 - 127
- 44, 44, 44, 44, 44, 44, 44, 44,
- // 128 - 135
- 396, 396, 396, 396, 396, 396, 396, 396,
- // 136 - 143
- 396, 396, 396, 396, 396, 396, 396, 396,
- // 144 - 151
- 1712, 1712, 1712, 1712, 1744, 1744, 1744, 1744,
- // 152 - 159
- 846, 846, 846, 846, 846, 846, 846, 846,
- // 160 - 167
- 1264, 1264, 1264, 1264, 1296, 1296, 1296, 1296,
- // 168 - 175
- 1328, 1328, 1328, 1328, 1360, 1360, 1360, 1360,
- // 176 - 183
- 1392, 1392, 1392, 1392, 1424, 1424, 1424, 1424,
- // 184 - 191
- 686, 686, 686, 686, 686, 686, 686, 686,
- // 192 - 199
- 910, 910, 910, 910, 910, 910, 910, 910,
- // 200 - 207
- 1968, 1968, 1968, 1968, 2000, 2000, 2000, 2000,
- // 208 - 215
- 2032, 2032, 2032, 2032, 16, 16, 16, 16,
- // 216 - 223
- 10257, 10257, 10257, 10257, 12305, 12305, 12305, 12305,
- // 224 - 231
- 330, 330, 330, 330, 330, 330, 330, 330,
- // 232 - 239
- 330, 330, 330, 330, 330, 330, 330, 330,
- // 240 - 247
- 330, 330, 330, 330, 330, 330, 330, 330,
- // 248 - 255
- 330, 330, 330, 330, 330, 330, 330, 330,
- // 256 - 263
- 362, 362, 362, 362, 362, 362, 362, 362,
- // 264 - 271
- 362, 362, 362, 362, 362, 362, 362, 362,
- // 272 - 279
- 362, 362, 362, 362, 362, 362, 362, 362,
- // 280 - 287
- 362, 362, 362, 362, 362, 362, 362, 362,
- // 288 - 295
- 878, 878, 878, 878, 878, 878, 878, 878,
- // 296 - 303
- 1904, 1904, 1904, 1904, 1936, 1936, 1936, 1936,
- // 304 - 311
- -18413, -18413, -16365, -16365, -14317, -14317, -10221, -10221,
- // 312 - 319
- 590, 590, 590, 590, 590, 590, 590, 590,
- // 320 - 327
- 782, 782, 782, 782, 782, 782, 782, 782,
- // 328 - 335
- 1584, 1584, 1584, 1584, 1616, 1616, 1616, 1616,
- // 336 - 343
- 1648, 1648, 1648, 1648, 1680, 1680, 1680, 1680,
- // 344 - 351
- 814, 814, 814, 814, 814, 814, 814, 814,
- // 352 - 359
- 1776, 1776, 1776, 1776, 1808, 1808, 1808, 1808,
- // 360 - 367
- 1840, 1840, 1840, 1840, 1872, 1872, 1872, 1872,
- // 368 - 375
- 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,
- // 376 - 383
- 6157, 6157, 6157, 6157, 6157, 6157, 6157, 6157,
- // 384 - 391
- -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,
- // 392 - 399
- -12275, -12275, -12275, -12275, -12275, -12275, -12275, -12275,
- // 400 - 407
- 14353, 14353, 14353, 14353, 16401, 16401, 16401, 16401,
- // 408 - 415
- 22547, 22547, 24595, 24595, 20497, 20497, 20497, 20497,
- // 416 - 423
- 18449, 18449, 18449, 18449, 26643, 26643, 28691, 28691,
- // 424 - 431
- 30739, 30739, -32749, -32749, -30701, -30701, -28653, -28653,
- // 432 - 439
- -26605, -26605, -24557, -24557, -22509, -22509, -20461, -20461,
- // 440 - 447
- 8207, 8207, 8207, 8207, 8207, 8207, 8207, 8207,
- // 448 - 455
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 456 - 463
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 464 - 471
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 472 - 479
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 480 - 487
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 488 - 495
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 496 - 503
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 504 - 511
- 72, 72, 72, 72, 72, 72, 72, 72,
- // 512 - 519
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 520 - 527
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 528 - 535
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 536 - 543
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 544 - 551
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 552 - 559
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 560 - 567
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 568 - 575
- 104, 104, 104, 104, 104, 104, 104, 104,
- // 576 - 583
- 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
- // 584 - 591
- 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
- // 592 - 599
- 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
- // 600 - 607
- 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,
- // 608 - 615
- 266, 266, 266, 266, 266, 266, 266, 266,
- // 616 - 623
- 266, 266, 266, 266, 266, 266, 266, 266,
- // 624 - 631
- 266, 266, 266, 266, 266, 266, 266, 266,
- // 632 - 639
- 266, 266, 266, 266, 266, 266, 266, 266,
- // 640 - 647
- 298, 298, 298, 298, 298, 298, 298, 298,
- // 648 - 655
- 298, 298, 298, 298, 298, 298, 298, 298,
- // 656 - 663
- 298, 298, 298, 298, 298, 298, 298, 298,
- // 664 - 671
- 298, 298, 298, 298, 298, 298, 298, 298,
- // 672 - 679
- 524, 524, 524, 524, 524, 524, 524, 524,
- // 680 - 687
- 524, 524, 524, 524, 524, 524, 524, 524,
- // 688 - 695
- 556, 556, 556, 556, 556, 556, 556, 556,
- // 696 - 703
- 556, 556, 556, 556, 556, 556, 556, 556,
- // 704 - 711
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 712 - 719
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 720 - 727
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 728 - 735
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 736 - 743
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 744 - 751
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 752 - 759
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 760 - 767
- 136, 136, 136, 136, 136, 136, 136, 136,
- // 768 - 775
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 776 - 783
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 784 - 791
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 792 - 799
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 800 - 807
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 808 - 815
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 816 - 823
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 824 - 831
- 168, 168, 168, 168, 168, 168, 168, 168,
- // 832 - 839
- 460, 460, 460, 460, 460, 460, 460, 460,
- // 840 - 847
- 460, 460, 460, 460, 460, 460, 460, 460,
- // 848 - 855
- 492, 492, 492, 492, 492, 492, 492, 492,
- // 856 - 863
- 492, 492, 492, 492, 492, 492, 492, 492,
- // 864 - 871
- 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
- // 872 - 879
- 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
- // 880 - 887
- 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
- // 888 - 895
- 2059, 2059, 2059, 2059, 2059, 2059, 2059, 2059,
- // 896 - 903
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 904 - 911
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 912 - 919
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 920 - 927
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 928 - 935
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 936 - 943
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 944 - 951
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 952 - 959
- 200, 200, 200, 200, 200, 200, 200, 200,
- // 960 - 967
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 968 - 975
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 976 - 983
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 984 - 991
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 992 - 999
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 1000 - 1007
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 1008 - 1015
- 232, 232, 232, 232, 232, 232, 232, 232,
- // 1016 - 1023
- 232, 232, 232, 232, 232, 232, 232, 232,
- };
-
- // Additional make up codes for both White and Black runs
- static short additionalMakeup[] = {
- 28679, 28679, 31752, (short)32777,
- (short)33801, (short)34825, (short)35849, (short)36873,
- (short)29703, (short)29703, (short)30727, (short)30727,
- (short)37897, (short)38921, (short)39945, (short)40969
- };
-
- // Initial black run look up table, uses the first 4 bits of a code
- static short initBlack[] = {
- // 0 - 7
- 3226, 6412, 200, 168, 38, 38, 134, 134,
- // 8 - 15
- 100, 100, 100, 100, 68, 68, 68, 68
- };
-
- //
- static short twoBitBlack[] = {292, 260, 226, 226}; // 0 - 3
-
- // Main black run table, using the last 9 bits of possible 13 bit code
- static short black[] = {
- // 0 - 7
- 62, 62, 30, 30, 0, 0, 0, 0,
- // 8 - 15
- 0, 0, 0, 0, 0, 0, 0, 0,
- // 16 - 23
- 0, 0, 0, 0, 0, 0, 0, 0,
- // 24 - 31
- 0, 0, 0, 0, 0, 0, 0, 0,
- // 32 - 39
- 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
- // 40 - 47
- 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
- // 48 - 55
- 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
- // 56 - 63
- 3225, 3225, 3225, 3225, 3225, 3225, 3225, 3225,
- // 64 - 71
- 588, 588, 588, 588, 588, 588, 588, 588,
- // 72 - 79
- 1680, 1680, 20499, 22547, 24595, 26643, 1776, 1776,
- // 80 - 87
- 1808, 1808, -24557, -22509, -20461, -18413, 1904, 1904,
- // 88 - 95
- 1936, 1936, -16365, -14317, 782, 782, 782, 782,
- // 96 - 103
- 814, 814, 814, 814, -12269, -10221, 10257, 10257,
- // 104 - 111
- 12305, 12305, 14353, 14353, 16403, 18451, 1712, 1712,
- // 112 - 119
- 1744, 1744, 28691, 30739, -32749, -30701, -28653, -26605,
- // 120 - 127
- 2061, 2061, 2061, 2061, 2061, 2061, 2061, 2061,
- // 128 - 135
- 424, 424, 424, 424, 424, 424, 424, 424,
- // 136 - 143
- 424, 424, 424, 424, 424, 424, 424, 424,
- // 144 - 151
- 424, 424, 424, 424, 424, 424, 424, 424,
- // 152 - 159
- 424, 424, 424, 424, 424, 424, 424, 424,
- // 160 - 167
- 750, 750, 750, 750, 1616, 1616, 1648, 1648,
- // 168 - 175
- 1424, 1424, 1456, 1456, 1488, 1488, 1520, 1520,
- // 176 - 183
- 1840, 1840, 1872, 1872, 1968, 1968, 8209, 8209,
- // 184 - 191
- 524, 524, 524, 524, 524, 524, 524, 524,
- // 192 - 199
- 556, 556, 556, 556, 556, 556, 556, 556,
- // 200 - 207
- 1552, 1552, 1584, 1584, 2000, 2000, 2032, 2032,
- // 208 - 215
- 976, 976, 1008, 1008, 1040, 1040, 1072, 1072,
- // 216 - 223
- 1296, 1296, 1328, 1328, 718, 718, 718, 718,
- // 224 - 231
- 456, 456, 456, 456, 456, 456, 456, 456,
- // 232 - 239
- 456, 456, 456, 456, 456, 456, 456, 456,
- // 240 - 247
- 456, 456, 456, 456, 456, 456, 456, 456,
- // 248 - 255
- 456, 456, 456, 456, 456, 456, 456, 456,
- // 256 - 263
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 264 - 271
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 272 - 279
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 280 - 287
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 288 - 295
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 296 - 303
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 304 - 311
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 312 - 319
- 326, 326, 326, 326, 326, 326, 326, 326,
- // 320 - 327
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 328 - 335
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 336 - 343
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 344 - 351
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 352 - 359
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 360 - 367
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 368 - 375
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 376 - 383
- 358, 358, 358, 358, 358, 358, 358, 358,
- // 384 - 391
- 490, 490, 490, 490, 490, 490, 490, 490,
- // 392 - 399
- 490, 490, 490, 490, 490, 490, 490, 490,
- // 400 - 407
- 4113, 4113, 6161, 6161, 848, 848, 880, 880,
- // 408 - 415
- 912, 912, 944, 944, 622, 622, 622, 622,
- // 416 - 423
- 654, 654, 654, 654, 1104, 1104, 1136, 1136,
- // 424 - 431
- 1168, 1168, 1200, 1200, 1232, 1232, 1264, 1264,
- // 432 - 439
- 686, 686, 686, 686, 1360, 1360, 1392, 1392,
- // 440 - 447
- 12, 12, 12, 12, 12, 12, 12, 12,
- // 448 - 455
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 456 - 463
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 464 - 471
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 472 - 479
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 480 - 487
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 488 - 495
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 496 - 503
- 390, 390, 390, 390, 390, 390, 390, 390,
- // 504 - 511
- 390, 390, 390, 390, 390, 390, 390, 390,
- };
-
- static byte twoDCodes[] = {
- // 0 - 7
- 80, 88, 23, 71, 30, 30, 62, 62,
- // 8 - 15
- 4, 4, 4, 4, 4, 4, 4, 4,
- // 16 - 23
- 11, 11, 11, 11, 11, 11, 11, 11,
- // 24 - 31
- 11, 11, 11, 11, 11, 11, 11, 11,
- // 32 - 39
- 35, 35, 35, 35, 35, 35, 35, 35,
- // 40 - 47
- 35, 35, 35, 35, 35, 35, 35, 35,
- // 48 - 55
- 51, 51, 51, 51, 51, 51, 51, 51,
- // 56 - 63
- 51, 51, 51, 51, 51, 51, 51, 51,
- // 64 - 71
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 72 - 79
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 80 - 87
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 88 - 95
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 96 - 103
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 104 - 111
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 112 - 119
- 41, 41, 41, 41, 41, 41, 41, 41,
- // 120 - 127
- 41, 41, 41, 41, 41, 41, 41, 41,
- };
-
- /**
- * @param fillOrder The fill order of the compressed data bytes.
- * @param w
- * @param h
- */
- public TIFFFaxDecoder(int fillOrder, int w, int h) {
- this.fillOrder = fillOrder;
- this.w = w;
- this.h = h;
-
- this.bitPointer = 0;
- this.bytePointer = 0;
- this.prevChangingElems = new int[w];
- this.currChangingElems = new int[w];
- }
-
- // One-dimensional decoding methods
-
- public void decode1D(byte[] buffer, byte[] compData,
- int startX, int height) {
- this.data = compData;
-
- int lineOffset = 0;
- int scanlineStride = (w + 7)/8;
-
- bitPointer = 0;
- bytePointer = 0;
-
- for (int i = 0; i < height; i++) {
- decodeNextScanline(buffer, lineOffset, startX);
- lineOffset += scanlineStride;
- }
- }
-
- public void decodeNextScanline(byte[] buffer,
- int lineOffset, int bitOffset) {
- int bits = 0, code = 0, isT = 0;
- int current, entry, twoBits;
- boolean isWhite = true;
-
- // Initialize starting of the changing elements array
- changingElemSize = 0;
-
- // While scanline not complete
- while (bitOffset < w) {
- while (isWhite) {
- // White run
- current = nextNBits(10);
- entry = white[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x0f;
-
- if (bits == 12) { // Additional Make up code
- // Get the next 2 bits
- twoBits = nextLesserThan8Bits(2);
- // Consolidate the 2 new bits and last 2 bits into 4 bits
- current = ((current << 2) & 0x000c) | twoBits;
- entry = additionalMakeup[current];
- bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
- code = (entry >>> 4) & 0x0fff; // 12 bits
- bitOffset += code; // Skip white run
-
- updatePointer(4 - bits);
- } else if (bits == 0) { // ERROR
- throw new RuntimeException("Invalid code encountered.");
- } else if (bits == 15) { // EOL
- throw new RuntimeException("EOL code word encountered in White run.");
- } else {
- // 11 bits - 0000 0111 1111 1111 = 0x07ff
- code = (entry >>> 5) & 0x07ff;
- bitOffset += code;
-
- updatePointer(10 - bits);
- if (isT == 0) {
- isWhite = false;
- currChangingElems[changingElemSize++] = bitOffset;
- }
- }
- }
-
- // Check whether this run completed one width, if so
- // advance to next byte boundary for compression = 2.
- if (bitOffset == w) {
- if (compression == 2) {
- advancePointer();
- }
- break;
- }
-
- while (isWhite == false) {
- // Black run
- current = nextLesserThan8Bits(4);
- entry = initBlack[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x000f;
- code = (entry >>> 5) & 0x07ff;
-
- if (code == 100) {
- current = nextNBits(9);
- entry = black[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x000f;
- code = (entry >>> 5) & 0x07ff;
-
- if (bits == 12) {
- // Additional makeup codes
- updatePointer(5);
- current = nextLesserThan8Bits(4);
- entry = additionalMakeup[current];
- bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
- code = (entry >>> 4) & 0x0fff; // 12 bits
-
- setToBlack(buffer, lineOffset, bitOffset, code);
- bitOffset += code;
-
- updatePointer(4 - bits);
- } else if (bits == 15) {
- // EOL code
- throw new RuntimeException("EOL code word encountered in Black run.");
- } else {
- setToBlack(buffer, lineOffset, bitOffset, code);
- bitOffset += code;
-
- updatePointer(9 - bits);
- if (isT == 0) {
- isWhite = true;
- currChangingElems[changingElemSize++] = bitOffset;
- }
- }
- } else if (code == 200) {
- // Is a Terminating code
- current = nextLesserThan8Bits(2);
- entry = twoBitBlack[current];
- code = (entry >>> 5) & 0x07ff;
- bits = (entry >>> 1) & 0x0f;
-
- setToBlack(buffer, lineOffset, bitOffset, code);
- bitOffset += code;
-
- updatePointer(2 - bits);
- isWhite = true;
- currChangingElems[changingElemSize++] = bitOffset;
- } else {
- // Is a Terminating code
- setToBlack(buffer, lineOffset, bitOffset, code);
- bitOffset += code;
-
- updatePointer(4 - bits);
- isWhite = true;
- currChangingElems[changingElemSize++] = bitOffset;
- }
- }
-
- // Check whether this run completed one width
- if (bitOffset == w) {
- if (compression == 2) {
- advancePointer();
- }
- break;
- }
- }
-
- currChangingElems[changingElemSize++] = bitOffset;
- }
-
- // Two-dimensional decoding methods
-
- public void decode2D(byte[] buffer,
- byte compData[],
- int startX,
- int height,
- long tiffT4Options) {
- this.data = compData;
- compression = 3;
-
- bitPointer = 0;
- bytePointer = 0;
-
- int scanlineStride = (w + 7)/8;
-
- int a0, a1, b1, b2;
- int[] b = new int[2];
- int entry, code, bits;
- boolean isWhite;
- int currIndex = 0;
- int temp[];
-
- // fillBits - dealt with this in readEOL
- // 1D/2D encoding - dealt with this in readEOL
-
- // uncompressedMode - haven't dealt with this yet.
-
-
- oneD = (int)(tiffT4Options & 0x01);
- uncompressedMode = (int)((tiffT4Options & 0x02) >> 1);
- fillBits = (int)((tiffT4Options & 0x04) >> 2);
-
- // The data must start with an EOL code
- if (readEOL(true) != 1) {
- throw new RuntimeException("First scanline must be 1D encoded.");
- }
-
- int lineOffset = 0;
- int bitOffset;
-
- // Then the 1D encoded scanline data will occur, changing elements
- // array gets set.
- decodeNextScanline(buffer, lineOffset, startX);
- lineOffset += scanlineStride;
-
- for (int lines = 1; lines < height; lines++) {
-
- // Every line must begin with an EOL followed by a bit which
- // indicates whether the following scanline is 1D or 2D encoded.
- if (readEOL(false) == 0) {
- // 2D encoded scanline follows
-
- // Initialize previous scanlines changing elements, and
- // initialize current scanline's changing elements array
- temp = prevChangingElems;
- prevChangingElems = currChangingElems;
- currChangingElems = temp;
- currIndex = 0;
-
- // a0 has to be set just before the start of this scanline.
- a0 = -1;
- isWhite = true;
- bitOffset = startX;
-
- lastChangingElement = 0;
-
- while (bitOffset < w) {
- // Get the next changing element
- getNextChangingElement(a0, isWhite, b);
-
- b1 = b[0];
- b2 = b[1];
-
- // Get the next seven bits
- entry = nextLesserThan8Bits(7);
-
- // Run these through the 2DCodes table
- entry = (int)(twoDCodes[entry] & 0xff);
-
- // Get the code and the number of bits used up
- code = (entry & 0x78) >>> 3;
- bits = entry & 0x07;
-
- if (code == 0) {
- if (!isWhite) {
- setToBlack(buffer, lineOffset, bitOffset,
- b2 - bitOffset);
- }
- bitOffset = a0 = b2;
-
- // Set pointer to consume the correct number of bits.
- updatePointer(7 - bits);
- } else if (code == 1) {
- // Horizontal
- updatePointer(7 - bits);
-
- // identify the next 2 codes.
- int number;
- if (isWhite) {
- number = decodeWhiteCodeWord();
- bitOffset += number;
- currChangingElems[currIndex++] = bitOffset;
-
- number = decodeBlackCodeWord();
- setToBlack(buffer, lineOffset, bitOffset, number);
- bitOffset += number;
- currChangingElems[currIndex++] = bitOffset;
- } else {
- number = decodeBlackCodeWord();
- setToBlack(buffer, lineOffset, bitOffset, number);
- bitOffset += number;
- currChangingElems[currIndex++] = bitOffset;
-
- number = decodeWhiteCodeWord();
- bitOffset += number;
- currChangingElems[currIndex++] = bitOffset;
- }
-
- a0 = bitOffset;
- } else if (code <= 8) {
- // Vertical
- a1 = b1 + (code - 5);
-
- currChangingElems[currIndex++] = a1;
-
- // We write the current color till a1 - 1 pos,
- // since a1 is where the next color starts
- if (!isWhite) {
- setToBlack(buffer, lineOffset, bitOffset,
- a1 - bitOffset);
- }
- bitOffset = a0 = a1;
- isWhite = !isWhite;
-
- updatePointer(7 - bits);
- } else {
- throw new RuntimeException("Invalid code encountered while decoding 2D group 3 compressed data.");
- }
- }
-
- // Add the changing element beyond the current scanline for the
- // other color too
- currChangingElems[currIndex++] = bitOffset;
- changingElemSize = currIndex;
- } else {
- // 1D encoded scanline follows
- decodeNextScanline(buffer, lineOffset, startX);
- }
-
- lineOffset += scanlineStride;
- }
- }
-
- public synchronized void decodeT6(byte[] buffer,
- byte[] compData,
- int startX,
- int height,
- long tiffT6Options) {
- this.data = compData;
- compression = 4;
-
- bitPointer = 0;
- bytePointer = 0;
-
- int scanlineStride = (w + 7)/8;
-
- int a0, a1, b1, b2;
- int entry, code, bits;
- boolean isWhite;
- int currIndex;
- int temp[];
-
- // Return values from getNextChangingElement
- int[] b = new int[2];
-
- // uncompressedMode - have written some code for this, but this
- // has not been tested due to lack of test images using this optional
-
- uncompressedMode = (int)((tiffT6Options & 0x02) >> 1);
-
- // Local cached reference
- int[] cce = currChangingElems;
-
- // Assume invisible preceding row of all white pixels and insert
- // both black and white changing elements beyond the end of this
- // imaginary scanline.
- changingElemSize = 0;
- cce[changingElemSize++] = w;
- cce[changingElemSize++] = w;
-
- int lineOffset = 0;
- int bitOffset;
-
- for (int lines = 0; lines < height; lines++) {
- // a0 has to be set just before the start of the scanline.
- a0 = -1;
- isWhite = true;
-
- // Assign the changing elements of the previous scanline to
- // prevChangingElems and start putting this new scanline's
- // changing elements into the currChangingElems.
- temp = prevChangingElems;
- prevChangingElems = currChangingElems;
- cce = currChangingElems = temp;
- currIndex = 0;
-
- // Start decoding the scanline at startX in the raster
- bitOffset = startX;
-
- // Reset search start position for getNextChangingElement
- lastChangingElement = 0;
-
- // Till one whole scanline is decoded
- while (bitOffset < w) {
- // Get the next changing element
- getNextChangingElement(a0, isWhite, b);
- b1 = b[0];
- b2 = b[1];
-
- // Get the next seven bits
- entry = nextLesserThan8Bits(7);
- // Run these through the 2DCodes table
- entry = (int)(twoDCodes[entry] & 0xff);
-
- // Get the code and the number of bits used up
- code = (entry & 0x78) >>> 3;
- bits = entry & 0x07;
-
- if (code == 0) { // Pass
- // We always assume WhiteIsZero format for fax.
- if (!isWhite) {
- setToBlack(buffer, lineOffset, bitOffset,
- b2 - bitOffset);
- }
- bitOffset = a0 = b2;
-
- // Set pointer to only consume the correct number of bits.
- updatePointer(7 - bits);
- } else if (code == 1) { // Horizontal
- // Set pointer to only consume the correct number of bits.
- updatePointer(7 - bits);
-
- // identify the next 2 alternating color codes.
- int number;
- if (isWhite) {
- // Following are white and black runs
- number = decodeWhiteCodeWord();
- bitOffset += number;
- cce[currIndex++] = bitOffset;
-
- number = decodeBlackCodeWord();
- setToBlack(buffer, lineOffset, bitOffset, number);
- bitOffset += number;
- cce[currIndex++] = bitOffset;
- } else {
- // First a black run and then a white run follows
- number = decodeBlackCodeWord();
- setToBlack(buffer, lineOffset, bitOffset, number);
- bitOffset += number;
- cce[currIndex++] = bitOffset;
-
- number = decodeWhiteCodeWord();
- bitOffset += number;
- cce[currIndex++] = bitOffset;
- }
-
- a0 = bitOffset;
- } else if (code <= 8) { // Vertical
- a1 = b1 + (code - 5);
- cce[currIndex++] = a1;
-
- // We write the current color till a1 - 1 pos,
- // since a1 is where the next color starts
- if (!isWhite) {
- setToBlack(buffer, lineOffset, bitOffset,
- a1 - bitOffset);
- }
- bitOffset = a0 = a1;
- isWhite = !isWhite;
-
- updatePointer(7 - bits);
- } else if (code == 11) {
- if (nextLesserThan8Bits(3) != 7) {
- throw new RuntimeException("Invalid code encountered while decoding 2D group 4 compressed data.");
- }
-
- int zeros = 0;
- boolean exit = false;
-
- while (!exit) {
- while (nextLesserThan8Bits(1) != 1) {
- zeros++;
- }
-
- if (zeros > 5) {
- // Exit code
-
- // Zeros before exit code
- zeros = zeros - 6;
-
- if (!isWhite && (zeros > 0)) {
- cce[currIndex++] = bitOffset;
- }
-
- // Zeros before the exit code
- bitOffset += zeros;
- if (zeros > 0) {
- // Some zeros have been written
- isWhite = true;
- }
-
- // Read in the bit which specifies the color of
- // the following run
- if (nextLesserThan8Bits(1) == 0) {
- if (!isWhite) {
- cce[currIndex++] = bitOffset;
- }
- isWhite = true;
- } else {
- if (isWhite) {
- cce[currIndex++] = bitOffset;
- }
- isWhite = false;
- }
-
- exit = true;
- }
-
- if (zeros == 5) {
- if (!isWhite) {
- cce[currIndex++] = bitOffset;
- }
- bitOffset += zeros;
-
- // Last thing written was white
- isWhite = true;
- } else {
- bitOffset += zeros;
-
- cce[currIndex++] = bitOffset;
- setToBlack(buffer, lineOffset, bitOffset, 1);
- ++bitOffset;
-
- // Last thing written was black
- isWhite = false;
- }
-
- }
- } else {
- throw new RuntimeException("Invalid code encountered while decoding 2D group 4 compressed data.");
- }
- }
-
- // Add the changing element beyond the current scanline for the
- // other color too
- //make sure that the index does not exceed the bounds of the array
- if(currIndex < cce.length)
- cce[currIndex++] = bitOffset;
-
- // Number of changing elements in this scanline.
- changingElemSize = currIndex;
-
- lineOffset += scanlineStride;
- }
- }
-
- private void setToBlack(byte[] buffer,
- int lineOffset, int bitOffset,
- int numBits) {
- int bitNum = 8*lineOffset + bitOffset;
- int lastBit = bitNum + numBits;
-
- int byteNum = bitNum >> 3;
-
- // Handle bits in first byte
- int shift = bitNum & 0x7;
- if (shift > 0) {
- int maskVal = 1 << (7 - shift);
- byte val = buffer[byteNum];
- while (maskVal > 0 && bitNum < lastBit) {
- val |= maskVal;
- maskVal >>= 1;
- ++bitNum;
- }
- buffer[byteNum] = val;
- }
-
- // Fill in 8 bits at a time
- byteNum = bitNum >> 3;
- while (bitNum < lastBit - 7) {
- buffer[byteNum++] = (byte)255;
- bitNum += 8;
- }
-
- // Fill in remaining bits
- while (bitNum < lastBit) {
- byteNum = bitNum >> 3;
- buffer[byteNum] |= 1 << (7 - (bitNum & 0x7));
- ++bitNum;
- }
- }
-
- // Returns run length
- private int decodeWhiteCodeWord() {
- int current, entry, bits, isT, twoBits, code = -1;
- int runLength = 0;
- boolean isWhite = true;
-
- while (isWhite) {
- current = nextNBits(10);
- entry = white[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x0f;
-
- if (bits == 12) { // Additional Make up code
- // Get the next 2 bits
- twoBits = nextLesserThan8Bits(2);
- // Consolidate the 2 new bits and last 2 bits into 4 bits
- current = ((current << 2) & 0x000c) | twoBits;
- entry = additionalMakeup[current];
- bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
- code = (entry >>> 4) & 0x0fff; // 12 bits
- runLength += code;
- updatePointer(4 - bits);
- } else if (bits == 0) { // ERROR
- throw new RuntimeException("Invalid code encountered.");
- } else if (bits == 15) { // EOL
- throw new RuntimeException("EOL code word encountered in White run.");
- } else {
- // 11 bits - 0000 0111 1111 1111 = 0x07ff
- code = (entry >>> 5) & 0x07ff;
- runLength += code;
- updatePointer(10 - bits);
- if (isT == 0) {
- isWhite = false;
- }
- }
- }
-
- return runLength;
- }
-
- // Returns run length
- private int decodeBlackCodeWord() {
- int current, entry, bits, isT, code = -1;
- int runLength = 0;
- boolean isWhite = false;
-
- while (!isWhite) {
- current = nextLesserThan8Bits(4);
- entry = initBlack[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x000f;
- code = (entry >>> 5) & 0x07ff;
-
- if (code == 100) {
- current = nextNBits(9);
- entry = black[current];
-
- // Get the 3 fields from the entry
- isT = entry & 0x0001;
- bits = (entry >>> 1) & 0x000f;
- code = (entry >>> 5) & 0x07ff;
-
- if (bits == 12) {
- // Additional makeup codes
- updatePointer(5);
- current = nextLesserThan8Bits(4);
- entry = additionalMakeup[current];
- bits = (entry >>> 1) & 0x07; // 3 bits 0000 0111
- code = (entry >>> 4) & 0x0fff; // 12 bits
- runLength += code;
-
- updatePointer(4 - bits);
- } else if (bits == 15) {
- // EOL code
- throw new RuntimeException("EOL code word encountered in Black run.");
- } else {
- runLength += code;
- updatePointer(9 - bits);
- if (isT == 0) {
- isWhite = true;
- }
- }
- } else if (code == 200) {
- // Is a Terminating code
- current = nextLesserThan8Bits(2);
- entry = twoBitBlack[current];
- code = (entry >>> 5) & 0x07ff;
- runLength += code;
- bits = (entry >>> 1) & 0x0f;
- updatePointer(2 - bits);
- isWhite = true;
- } else {
- // Is a Terminating code
- runLength += code;
- updatePointer(4 - bits);
- isWhite = true;
- }
- }
-
- return runLength;
- }
-
- private int readEOL(boolean isFirstEOL) {
- if (fillBits == 0) {
- int next12Bits = nextNBits(12);
- if (isFirstEOL && next12Bits == 0) {
-
- // Might have the case of EOL padding being used even
- // though it was not flagged in the T4Options field.
- // This was observed to be the case in TIFFs produced
- // by a well known vendor who shall remain nameless.
-
- if(nextNBits(4) == 1) {
-
- // EOL must be padded: reset the fillBits flag.
-
- fillBits = 1;
- return 1;
- }
- }
- if(next12Bits != 1) {
- throw new RuntimeException("Scanline must begin with EOL code word.");
- }
- } else if (fillBits == 1) {
-
- // First EOL code word xxxx 0000 0000 0001 will occur
- // As many fill bits will be present as required to make
- // the EOL code of 12 bits end on a byte boundary.
-
- int bitsLeft = 8 - bitPointer;
-
- if (nextNBits(bitsLeft) != 0) {
- throw new RuntimeException("All fill bits preceding EOL code must be 0.");
- }
-
- // If the number of bitsLeft is less than 8, then to have a 12
- // bit EOL sequence, two more bytes are certainly going to be
- // required. The first of them has to be all zeros, so ensure
- // that.
- if (bitsLeft < 4) {
- if (nextNBits(8) != 0) {
- throw new RuntimeException("All fill bits preceding EOL code must be 0.");
- }
- }
-
- // There might be a random number of fill bytes with 0s, so
- // loop till the EOL of 0000 0001 is found, as long as all
- // the bytes preceding it are 0's.
- int n;
- while ((n = nextNBits(8)) != 1) {
-
- // If not all zeros
- if (n != 0) {
- throw new RuntimeException("All fill bits preceding EOL code must be 0.");
- }
- }
- }
-
- // If one dimensional encoding mode, then always return 1
- if (oneD == 0) {
- return 1;
- } else {
- // Otherwise for 2D encoding mode,
- // The next one bit signifies 1D/2D encoding of next line.
- return nextLesserThan8Bits(1);
- }
- }
-
- private void getNextChangingElement(int a0, boolean isWhite, int[] ret) {
- // Local copies of instance variables
- int[] pce = this.prevChangingElems;
- int ces = this.changingElemSize;
-
- // If the previous match was at an odd element, we still
- // have to search the preceeding element.
- // int start = lastChangingElement & ~0x1;
- int start = lastChangingElement > 0 ? lastChangingElement - 1 : 0;
- if (isWhite) {
- start &= ~0x1; // Search even numbered elements
- } else {
- start |= 0x1; // Search odd numbered elements
- }
-
- int i = start;
- for (; i < ces; i += 2) {
- int temp = pce[i];
- if (temp > a0) {
- lastChangingElement = i;
- ret[0] = temp;
- break;
- }
- }
-
- if (i + 1 < ces) {
- ret[1] = pce[i + 1];
- }
- }
-
- private int nextNBits(int bitsToGet) {
- byte b, next, next2next;
- int l = data.length - 1;
- int bp = this.bytePointer;
-
- if (fillOrder == 1) {
- b = data[bp];
-
- if (bp == l) {
- next = 0x00;
- next2next = 0x00;
- } else if ((bp + 1) == l) {
- next = data[bp + 1];
- next2next = 0x00;
- } else {
- next = data[bp + 1];
- next2next = data[bp + 2];
- }
- } else if (fillOrder == 2) {
- b = flipTable[data[bp] & 0xff];
-
- if (bp == l) {
- next = 0x00;
- next2next = 0x00;
- } else if ((bp + 1) == l) {
- next = flipTable[data[bp + 1] & 0xff];
- next2next = 0x00;
- } else {
- next = flipTable[data[bp + 1] & 0xff];
- next2next = flipTable[data[bp + 2] & 0xff];
- }
- } else {
- throw new RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2.");
- }
-
- int bitsLeft = 8 - bitPointer;
- int bitsFromNextByte = bitsToGet - bitsLeft;
- int bitsFromNext2NextByte = 0;
- if (bitsFromNextByte > 8) {
- bitsFromNext2NextByte = bitsFromNextByte - 8;
- bitsFromNextByte = 8;
- }
-
- bytePointer++;
-
- int i1 = (b & table1[bitsLeft]) << (bitsToGet - bitsLeft);
- int i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte);
-
- int i3 = 0;
- if (bitsFromNext2NextByte != 0) {
- i2 <<= bitsFromNext2NextByte;
- i3 = (next2next & table2[bitsFromNext2NextByte]) >>>
- (8 - bitsFromNext2NextByte);
- i2 |= i3;
- bytePointer++;
- bitPointer = bitsFromNext2NextByte;
- } else {
- if (bitsFromNextByte == 8) {
- bitPointer = 0;
- bytePointer++;
- } else {
- bitPointer = bitsFromNextByte;
- }
- }
-
- int i = i1 | i2;
- return i;
- }
-
- private int nextLesserThan8Bits(int bitsToGet) {
- byte b, next;
- int l = data.length - 1;
- int bp = this.bytePointer;
-
- if (fillOrder == 1) {
- b = data[bp];
- if (bp == l) {
- next = 0x00;
- } else {
- next = data[bp + 1];
- }
- } else if (fillOrder == 2) {
- b = flipTable[data[bp] & 0xff];
- if (bp == l) {
- next = 0x00;
- } else {
- next = flipTable[data[bp + 1] & 0xff];
- }
- } else {
- throw new RuntimeException("TIFF_FILL_ORDER tag must be either 1 or 2.");
- }
-
- int bitsLeft = 8 - bitPointer;
- int bitsFromNextByte = bitsToGet - bitsLeft;
-
- int shift = bitsLeft - bitsToGet;
- int i1, i2;
- if (shift >= 0) {
- i1 = (b & table1[bitsLeft]) >>> shift;
- bitPointer += bitsToGet;
- if (bitPointer == 8) {
- bitPointer = 0;
- bytePointer++;
- }
- } else {
- i1 = (b & table1[bitsLeft]) << (-shift);
- i2 = (next & table2[bitsFromNextByte]) >>> (8 - bitsFromNextByte);
-
- i1 |= i2;
- bytePointer++;
- bitPointer = bitsFromNextByte;
- }
-
- return i1;
- }
-
- // Move pointer backwards by given amount of bits
- private void updatePointer(int bitsToMoveBack) {
- int i = bitPointer - bitsToMoveBack;
-
- if (i < 0) {
- bytePointer--;
- bitPointer = 8 + i;
- } else {
- bitPointer = i;
- }
- }
-
- // Move to the next byte boundary
- private boolean advancePointer() {
- if (bitPointer != 0) {
- bytePointer++;
- bitPointer = 0;
- }
-
- return true;
- }
-}
-
diff --git a/src/main/java/com/lowagie/text/pdf/codec/TIFFField.java b/src/main/java/com/lowagie/text/pdf/codec/TIFFField.java
deleted file mode 100644
index ac3b068..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TIFFField.java
+++ /dev/null
@@ -1,472 +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.
- */
-package com.lowagie.text.pdf.codec;
-
-import java.io.Serializable;
-
-/**
- * A class representing a field in a TIFF 6.0 Image File Directory.
- *
- * <p> The TIFF file format is described in more detail in the
- * comments for the TIFFDescriptor class.
- *
- * <p> A field in a TIFF Image File Directory (IFD). A field is defined
- * as a sequence of values of identical data type. TIFF 6.0 defines
- * 12 data types, which are mapped internally onto the Java datatypes
- * byte, int, long, float, and double.
- *
- * <p><b> This class is not a committed part of the JAI API. It may
- * be removed or changed in future releases of JAI.</b>
- *
- * @see TIFFDirectory
- */
-public class TIFFField extends Object implements Comparable, Serializable {
-
- /** Flag for 8 bit unsigned integers. */
- public static final int TIFF_BYTE = 1;
-
- /** Flag for null-terminated ASCII strings. */
- public static final int TIFF_ASCII = 2;
-
- /** Flag for 16 bit unsigned integers. */
- public static final int TIFF_SHORT = 3;
-
- /** Flag for 32 bit unsigned integers. */
- public static final int TIFF_LONG = 4;
-
- /** Flag for pairs of 32 bit unsigned integers. */
- public static final int TIFF_RATIONAL = 5;
-
- /** Flag for 8 bit signed integers. */
- public static final int TIFF_SBYTE = 6;
-
- /** Flag for 8 bit uninterpreted bytes. */
- public static final int TIFF_UNDEFINED = 7;
-
- /** Flag for 16 bit signed integers. */
- public static final int TIFF_SSHORT = 8;
-
- /** Flag for 32 bit signed integers. */
- public static final int TIFF_SLONG = 9;
-
- /** Flag for pairs of 32 bit signed integers. */
- public static final int TIFF_SRATIONAL = 10;
-
- /** Flag for 32 bit IEEE floats. */
- public static final int TIFF_FLOAT = 11;
-
- /** Flag for 64 bit IEEE doubles. */
- public static final int TIFF_DOUBLE = 12;
-
- /** The tag number. */
- int tag;
-
- /** The tag type. */
- int type;
-
- /** The number of data items present in the field. */
- int count;
-
- /** The field data. */
- Object data;
-
- /** The default constructor. */
- TIFFField() {}
-
- /**
- * Constructs a TIFFField with arbitrary data. The data
- * parameter must be an array of a Java type appropriate for the
- * type of the TIFF field. Since there is no available 32-bit
- * unsigned datatype, long is used. The mapping between types is
- * as follows:
- *
- * <table border=1>
- * <tr>
- * <th> TIFF type </th> <th> Java type </th>
- * <tr>
- * <td><tt>TIFF_BYTE</tt></td> <td><tt>byte</tt></td>
- * <tr>
- * <td><tt>TIFF_ASCII</tt></td> <td><tt>String</tt></td>
- * <tr>
- * <td><tt>TIFF_SHORT</tt></td> <td><tt>char</tt></td>
- * <tr>
- * <td><tt>TIFF_LONG</tt></td> <td><tt>long</tt></td>
- * <tr>
- * <td><tt>TIFF_RATIONAL</tt></td> <td><tt>long[2]</tt></td>
- * <tr>
- * <td><tt>TIFF_SBYTE</tt></td> <td><tt>byte</tt></td>
- * <tr>
- * <td><tt>TIFF_UNDEFINED</tt></td> <td><tt>byte</tt></td>
- * <tr>
- * <td><tt>TIFF_SSHORT</tt></td> <td><tt>short</tt></td>
- * <tr>
- * <td><tt>TIFF_SLONG</tt></td> <td><tt>int</tt></td>
- * <tr>
- * <td><tt>TIFF_SRATIONAL</tt></td> <td><tt>int[2]</tt></td>
- * <tr>
- * <td><tt>TIFF_FLOAT</tt></td> <td><tt>float</tt></td>
- * <tr>
- * <td><tt>TIFF_DOUBLE</tt></td> <td><tt>double</tt></td>
- * </table>
- */
- public TIFFField(int tag, int type, int count, Object data) {
- this.tag = tag;
- this.type = type;
- this.count = count;
- this.data = data;
- }
-
- /**
- * Returns the tag number, between 0 and 65535.
- */
- public int getTag() {
- return tag;
- }
-
- /**
- * Returns the type of the data stored in the IFD.
- * For a TIFF6.0 file, the value will equal one of the
- * TIFF_ constants defined in this class. For future
- * revisions of TIFF, higher values are possible.
- *
- */
- public int getType() {
- return type;
- }
-
- /**
- * Returns the number of elements in the IFD.
- */
- public int getCount() {
- return count;
- }
-
- /**
- * Returns the data as an uninterpreted array of bytes.
- * The type of the field must be one of TIFF_BYTE, TIFF_SBYTE,
- * or TIFF_UNDEFINED;
- *
- * <p> For data in TIFF_BYTE format, the application must take
- * care when promoting the data to longer integral types
- * to avoid sign extension.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_BYTE, TIFF_SBYTE, or TIFF_UNDEFINED.
- */
- public byte[] getAsBytes() {
- return (byte[])data;
- }
-
- /**
- * Returns TIFF_SHORT data as an array of chars (unsigned 16-bit
- * integers).
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_SHORT.
- */
- public char[] getAsChars() {
- return (char[])data;
- }
-
- /**
- * Returns TIFF_SSHORT data as an array of shorts (signed 16-bit
- * integers).
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_SSHORT.
- */
- public short[] getAsShorts() {
- return (short[])data;
- }
-
- /**
- * Returns TIFF_SLONG data as an array of ints (signed 32-bit
- * integers).
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_SLONG.
- */
- public int[] getAsInts() {
- return (int[])data;
- }
-
- /**
- * Returns TIFF_LONG data as an array of longs (signed 64-bit
- * integers).
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_LONG.
- */
- public long[] getAsLongs() {
- return (long[])data;
- }
-
- /**
- * Returns TIFF_FLOAT data as an array of floats.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_FLOAT.
- */
- public float[] getAsFloats() {
- return (float[])data;
- }
-
- /**
- * Returns TIFF_DOUBLE data as an array of doubles.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_DOUBLE.
- */
- public double[] getAsDoubles() {
- return (double[])data;
- }
-
- /**
- * Returns TIFF_SRATIONAL data as an array of 2-element arrays of ints.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_SRATIONAL.
- */
- public int[][] getAsSRationals() {
- return (int[][])data;
- }
-
- /**
- * Returns TIFF_RATIONAL data as an array of 2-element arrays of longs.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_RATTIONAL.
- */
- public long[][] getAsRationals() {
- return (long[][])data;
- }
-
- /**
- * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
- * TIFF_SSHORT, or TIFF_SLONG format as an int.
- *
- * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
- * that is, no sign extension will take place and the returned
- * value will be in the range [0, 255]. TIFF_SBYTE data will
- * be returned in the range [-128, 127].
- *
- * <p> A ClassCastException will be thrown if the field is not of
- * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
- * TIFF_SSHORT, or TIFF_SLONG.
- */
- public int getAsInt(int index) {
- switch (type) {
- case TIFF_BYTE: case TIFF_UNDEFINED:
- return ((byte[])data)[index] & 0xff;
- case TIFF_SBYTE:
- return ((byte[])data)[index];
- case TIFF_SHORT:
- return ((char[])data)[index] & 0xffff;
- case TIFF_SSHORT:
- return ((short[])data)[index];
- case TIFF_SLONG:
- return ((int[])data)[index];
- default:
- throw new ClassCastException();
- }
- }
-
- /**
- * Returns data in TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
- * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG format as a long.
- *
- * <p> TIFF_BYTE and TIFF_UNDEFINED data are treated as unsigned;
- * that is, no sign extension will take place and the returned
- * value will be in the range [0, 255]. TIFF_SBYTE data will
- * be returned in the range [-128, 127].
- *
- * <p> A ClassCastException will be thrown if the field is not of
- * type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED, TIFF_SHORT,
- * TIFF_SSHORT, TIFF_SLONG, or TIFF_LONG.
- */
- public long getAsLong(int index) {
- switch (type) {
- case TIFF_BYTE: case TIFF_UNDEFINED:
- return ((byte[])data)[index] & 0xff;
- case TIFF_SBYTE:
- return ((byte[])data)[index];
- case TIFF_SHORT:
- return ((char[])data)[index] & 0xffff;
- case TIFF_SSHORT:
- return ((short[])data)[index];
- case TIFF_SLONG:
- return ((int[])data)[index];
- case TIFF_LONG:
- return ((long[])data)[index];
- default:
- throw new ClassCastException();
- }
- }
-
- /**
- * Returns data in any numerical format as a float. Data in
- * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
- * dividing the numerator into the denominator using
- * double-precision arithmetic and then truncating to single
- * precision. Data in TIFF_SLONG, TIFF_LONG, or TIFF_DOUBLE
- * format may suffer from truncation.
- *
- * <p> A ClassCastException will be thrown if the field is
- * of type TIFF_UNDEFINED or TIFF_ASCII.
- */
- public float getAsFloat(int index) {
- switch (type) {
- case TIFF_BYTE:
- return ((byte[])data)[index] & 0xff;
- case TIFF_SBYTE:
- return ((byte[])data)[index];
- case TIFF_SHORT:
- return ((char[])data)[index] & 0xffff;
- case TIFF_SSHORT:
- return ((short[])data)[index];
- case TIFF_SLONG:
- return ((int[])data)[index];
- case TIFF_LONG:
- return ((long[])data)[index];
- case TIFF_FLOAT:
- return ((float[])data)[index];
- case TIFF_DOUBLE:
- return (float)((double[])data)[index];
- case TIFF_SRATIONAL:
- int[] ivalue = getAsSRational(index);
- return (float)((double)ivalue[0]/ivalue[1]);
- case TIFF_RATIONAL:
- long[] lvalue = getAsRational(index);
- return (float)((double)lvalue[0]/lvalue[1]);
- default:
- throw new ClassCastException();
- }
- }
-
- /**
- * Returns data in any numerical format as a float. Data in
- * TIFF_SRATIONAL or TIFF_RATIONAL format are evaluated by
- * dividing the numerator into the denominator using
- * double-precision arithmetic.
- *
- * <p> A ClassCastException will be thrown if the field is of
- * type TIFF_UNDEFINED or TIFF_ASCII.
- */
- public double getAsDouble(int index) {
- switch (type) {
- case TIFF_BYTE:
- return ((byte[])data)[index] & 0xff;
- case TIFF_SBYTE:
- return ((byte[])data)[index];
- case TIFF_SHORT:
- return ((char[])data)[index] & 0xffff;
- case TIFF_SSHORT:
- return ((short[])data)[index];
- case TIFF_SLONG:
- return ((int[])data)[index];
- case TIFF_LONG:
- return ((long[])data)[index];
- case TIFF_FLOAT:
- return ((float[])data)[index];
- case TIFF_DOUBLE:
- return ((double[])data)[index];
- case TIFF_SRATIONAL:
- int[] ivalue = getAsSRational(index);
- return (double)ivalue[0]/ivalue[1];
- case TIFF_RATIONAL:
- long[] lvalue = getAsRational(index);
- return (double)lvalue[0]/lvalue[1];
- default:
- throw new ClassCastException();
- }
- }
-
- /**
- * Returns a TIFF_ASCII data item as a String.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_ASCII.
- */
- public String getAsString(int index) {
- return ((String[])data)[index];
- }
-
- /**
- * Returns a TIFF_SRATIONAL data item as a two-element array
- * of ints.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_SRATIONAL.
- */
- public int[] getAsSRational(int index) {
- return ((int[][])data)[index];
- }
-
- /**
- * Returns a TIFF_RATIONAL data item as a two-element array
- * of ints.
- *
- * <p> A ClassCastException will be thrown if the field is not
- * of type TIFF_RATIONAL.
- */
- public long[] getAsRational(int index) {
- return ((long[][])data)[index];
- }
-
- /**
- * Compares this <code>TIFFField</code> with another
- * <code>TIFFField</code> by comparing the tags.
- *
- * <p><b>Note: this class has a natural ordering that is inconsistent
- * with <code>equals()</code>.</b>
- *
- * @throws IllegalArgumentException if the parameter is <code>null</code>.
- * @throws ClassCastException if the parameter is not a
- * <code>TIFFField</code>.
- */
- public int compareTo(Object o) {
- if(o == null) {
- throw new IllegalArgumentException();
- }
-
- int oTag = ((TIFFField)o).getTag();
-
- if(tag < oTag) {
- return -1;
- } else if(tag > oTag) {
- return 1;
- } else {
- return 0;
- }
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java b/src/main/java/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java
deleted file mode 100644
index ca0f91a..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TIFFLZWDecoder.java
+++ /dev/null
@@ -1,255 +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.
- */
-package com.lowagie.text.pdf.codec;
-
-/**
- * A class for performing LZW decoding.
- *
- *
- */
-public class TIFFLZWDecoder {
-
- byte stringTable[][];
- byte data[] = null, uncompData[];
- int tableIndex, bitsToGet = 9;
- int bytePointer, bitPointer;
- int dstIndex;
- int w, h;
- int predictor, samplesPerPixel;
- int nextData = 0;
- int nextBits = 0;
-
- int andTable[] = {
- 511,
- 1023,
- 2047,
- 4095
- };
-
- public TIFFLZWDecoder(int w, int predictor, int samplesPerPixel) {
- this.w = w;
- this.predictor = predictor;
- this.samplesPerPixel = samplesPerPixel;
- }
-
- /**
- * Method to decode LZW compressed data.
- *
- * @param data The compressed data.
- * @param uncompData Array to return the uncompressed data in.
- * @param h The number of rows the compressed data contains.
- */
- public byte[] decode(byte data[], byte uncompData[], int h) {
-
- if(data[0] == (byte)0x00 && data[1] == (byte)0x01) {
- throw new UnsupportedOperationException("TIFF 5.0-style LZW codes are not supported.");
- }
-
- initializeStringTable();
-
- this.data = data;
- this.h = h;
- this.uncompData = uncompData;
-
- // Initialize pointers
- bytePointer = 0;
- bitPointer = 0;
- dstIndex = 0;
-
-
- nextData = 0;
- nextBits = 0;
-
- int code, oldCode = 0;
- byte string[];
-
- while ( ((code = getNextCode()) != 257) &&
- dstIndex < uncompData.length) {
-
- 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;
- }
-
- }
-
- }
-
- // Horizontal Differencing Predictor
- if (predictor == 2) {
-
- int count;
- for (int j = 0; j < h; j++) {
-
- count = samplesPerPixel * (j * w + 1);
-
- for (int i = samplesPerPixel; i < w * samplesPerPixel; i++) {
-
- uncompData[count] += uncompData[count - samplesPerPixel];
- count++;
- }
- }
- }
-
- return uncompData;
- }
-
-
- /**
- * Initialize the string table.
- */
- public void initializeStringTable() {
-
- stringTable = new byte[4096][];
-
- 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[]) {
-
- for (int i=0; i<string.length; i++) {
- uncompData[dstIndex++] = string[i];
- }
- }
-
- /**
- * 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 <code>newString</code> to the end of <code>oldString</code>.
- */
- 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/codec/TiffImage.java b/src/main/java/com/lowagie/text/pdf/codec/TiffImage.java
deleted file mode 100644
index cc812d7..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/TiffImage.java
+++ /dev/null
@@ -1,522 +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.codec;
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.Image;
-import com.lowagie.text.Jpeg;
-import com.lowagie.text.ExceptionConverter;
-import java.io.*;
-import java.util.zip.*;
-import java.awt.color.ICC_Profile;
-
-/** Reads TIFF images
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class TiffImage {
-
- /** Gets the number of pages the TIFF document has.
- * @param s the file source
- * @return the number of pages
- */
- public static int getNumberOfPages(RandomAccessFileOrArray s) {
- try {
- return TIFFDirectory.getNumDirectories(s);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- static int getDpi(TIFFField fd, int resolutionUnit) {
- if (fd == null)
- return 0;
- long res[] = fd.getAsRational(0);
- float frac = (float)res[0] / (float)res[1];
- int dpi = 0;
- switch (resolutionUnit) {
- case TIFFConstants.RESUNIT_INCH:
- case TIFFConstants.RESUNIT_NONE:
- dpi = (int)frac;
- break;
- case TIFFConstants.RESUNIT_CENTIMETER:
- dpi = (int)(frac * 2.54);
- break;
- }
- return dpi;
- }
-
- /** Reads a page from a TIFF image. Direct mode is not used.
- * @param s the file source
- * @param page the page to get. The first page is 1
- * @return the <CODE>Image</CODE>
- */
- public static Image getTiffImage(RandomAccessFileOrArray s, int page) {
- return getTiffImage(s, page, false);
- }
-
- /** Reads a page from a TIFF image.
- * @param s the file source
- * @param page the page to get. The first page is 1
- * @param direct for single strip, CCITT images, generate the image
- * by direct byte copying. It's faster but may not work
- * every time
- * @return the <CODE>Image</CODE>
- */
- public static Image getTiffImage(RandomAccessFileOrArray s, int page, boolean direct) {
- if (page < 1)
- throw new IllegalArgumentException("The page number must be >= 1.");
- try {
- TIFFDirectory dir = new TIFFDirectory(s, page - 1);
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
- throw new IllegalArgumentException("Tiles are not supported.");
- int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
- switch (compression) {
- case TIFFConstants.COMPRESSION_CCITTRLEW:
- case TIFFConstants.COMPRESSION_CCITTRLE:
- case TIFFConstants.COMPRESSION_CCITTFAX3:
- case TIFFConstants.COMPRESSION_CCITTFAX4:
- break;
- default:
- return getTiffImageColor(dir, s);
- }
- float rotation = 0;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
- int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
- if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
- rotation = (float)Math.PI;
- else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
- rotation = (float)(Math.PI / 2.0);
- else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
- rotation = -(float)(Math.PI / 2.0);
- }
-
- Image img = null;
- long tiffT4Options = 0;
- long tiffT6Options = 0;
- int fillOrder = 1;
- int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
- int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
- int dpiX = 0;
- int dpiY = 0;
- float XYRatio = 0;
- int resolutionUnit = TIFFConstants.RESUNIT_INCH;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
- resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
- dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
- dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
- if (resolutionUnit == TIFFConstants.RESUNIT_NONE) {
- if (dpiY != 0)
- XYRatio = (float)dpiX / (float)dpiY;
- dpiX = 0;
- dpiY = 0;
- }
- long tstrip = 0xFFFFFFFFL;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
- tstrip = dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
- int rowsStrip = (int)Math.min(h, tstrip);
- long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
- long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
- if (size == null && h == rowsStrip) { // some TIFF producers are really lousy, so...
- size = new long[]{s.length() - (int)offset[0]};
- }
- boolean reverse = false;
- TIFFField fillOrderField = dir.getField(TIFFConstants.TIFFTAG_FILLORDER);
- if (fillOrderField != null)
- fillOrder = fillOrderField.getAsInt(0);
- reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
- int params = 0;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) {
- long photo = dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
- if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
- params |= Image.CCITT_BLACKIS1;
- }
- int imagecomp = 0;
- switch (compression) {
- case TIFFConstants.COMPRESSION_CCITTRLEW:
- case TIFFConstants.COMPRESSION_CCITTRLE:
- imagecomp = Image.CCITTG3_1D;
- params |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK;
- break;
- case TIFFConstants.COMPRESSION_CCITTFAX3:
- imagecomp = Image.CCITTG3_1D;
- params |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK;
- TIFFField t4OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
- if (t4OptionsField != null) {
- tiffT4Options = t4OptionsField.getAsLong(0);
- if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
- imagecomp = Image.CCITTG3_2D;
- if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
- params |= Image.CCITT_ENCODEDBYTEALIGN;
- }
- break;
- case TIFFConstants.COMPRESSION_CCITTFAX4:
- imagecomp = Image.CCITTG4;
- TIFFField t6OptionsField = dir.getField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
- if (t6OptionsField != null)
- tiffT6Options = t6OptionsField.getAsLong(0);
- break;
- }
- if (direct && rowsStrip == h) { //single strip, direct
- byte im[] = new byte[(int)size[0]];
- s.seek(offset[0]);
- s.readFully(im);
- img = Image.getInstance(w, h, reverse, imagecomp, params, im);
- img.setInverted(true);
- }
- else {
- int rowsLeft = h;
- CCITTG4Encoder g4 = new CCITTG4Encoder(w);
- for (int k = 0; k < offset.length; ++k) {
- byte im[] = new byte[(int)size[k]];
- s.seek(offset[k]);
- s.readFully(im);
- int height = Math.min(rowsStrip, rowsLeft);
- TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
- byte outBuf[] = new byte[(w + 7) / 8 * height];
- switch (compression) {
- case TIFFConstants.COMPRESSION_CCITTRLEW:
- case TIFFConstants.COMPRESSION_CCITTRLE:
- decoder.decode1D(outBuf, im, 0, height);
- g4.fax4Encode(outBuf,height);
- break;
- case TIFFConstants.COMPRESSION_CCITTFAX3:
- try {
- decoder.decode2D(outBuf, im, 0, height, tiffT4Options);
- }
- catch (Exception e) {
- // let's flip the fill bits and try again...
- tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
- try {
- decoder.decode2D(outBuf, im, 0, height, tiffT4Options);
- }
- catch (Exception e2) {
- throw e;
- }
- }
- g4.fax4Encode(outBuf, height);
- break;
- case TIFFConstants.COMPRESSION_CCITTFAX4:
- decoder.decodeT6(outBuf, im, 0, height, tiffT6Options);
- g4.fax4Encode(outBuf, height);
- break;
- }
- rowsLeft -= rowsStrip;
- }
- byte g4pic[] = g4.close();
- img = Image.getInstance(w, h, false, Image.CCITTG4, params & Image.CCITT_BLACKIS1, g4pic);
- }
- img.setDpi(dpiX, dpiY);
- img.setXYRatio(XYRatio);
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
- try {
- TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE);
- ICC_Profile icc_prof = ICC_Profile.getInstance(fd.getAsBytes());
- if (icc_prof.getNumComponents() == 1)
- img.tagICC(icc_prof);
- }
- catch (Exception e) {
- //empty
- }
- }
- img.setOriginalType(Image.ORIGINAL_TIFF);
- if (rotation != 0)
- img.setInitialRotation(rotation);
- return img;
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- protected static Image getTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) {
- try {
- int compression = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
- int predictor = 1;
- TIFFLZWDecoder lzwDecoder = null;
- switch (compression) {
- case TIFFConstants.COMPRESSION_NONE:
- case TIFFConstants.COMPRESSION_LZW:
- case TIFFConstants.COMPRESSION_PACKBITS:
- case TIFFConstants.COMPRESSION_DEFLATE:
- case TIFFConstants.COMPRESSION_OJPEG:
- break;
- default:
- throw new IllegalArgumentException("The compression " + compression + " is not supported.");
- }
- int photometric = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
- switch (photometric) {
- case TIFFConstants.PHOTOMETRIC_MINISWHITE:
- case TIFFConstants.PHOTOMETRIC_MINISBLACK:
- case TIFFConstants.PHOTOMETRIC_RGB:
- case TIFFConstants.PHOTOMETRIC_SEPARATED:
- case TIFFConstants.PHOTOMETRIC_PALETTE:
- break;
- default:
- throw new IllegalArgumentException("The photometric " + photometric + " is not supported.");
- }
- float rotation = 0;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
- int rot = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
- if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
- rotation = (float)Math.PI;
- else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
- rotation = (float)(Math.PI / 2.0);
- else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
- rotation = -(float)(Math.PI / 2.0);
- }
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG)
- && dir.getFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
- throw new IllegalArgumentException("Planar images are not supported.");
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
- throw new IllegalArgumentException("Extra samples are not supported.");
- int samplePerPixel = 1;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
- samplePerPixel = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
- int bitsPerSample = 1;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
- bitsPerSample = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
- switch (bitsPerSample) {
- case 1:
- case 2:
- case 4:
- case 8:
- break;
- default:
- throw new IllegalArgumentException("Bits per sample " + bitsPerSample + " is not supported.");
- }
- Image img = null;
-
- int h = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
- int w = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
- int dpiX = 0;
- int dpiY = 0;
- int resolutionUnit = TIFFConstants.RESUNIT_INCH;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
- resolutionUnit = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
- dpiX = getDpi(dir.getField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
- dpiY = getDpi(dir.getField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
- int rowsStrip = h;
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
- rowsStrip = (int)dir.getFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
- long offset[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
- long size[] = getArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
- if (size == null && h == rowsStrip) { // some TIFF producers are really lousy, so...
- size = new long[]{s.length() - (int)offset[0]};
- }
- if (compression == TIFFConstants.COMPRESSION_LZW) {
- TIFFField predictorField = dir.getField(TIFFConstants.TIFFTAG_PREDICTOR);
- if (predictorField != null) {
- predictor = predictorField.getAsInt(0);
- if (predictor != 1 && predictor != 2) {
- throw new RuntimeException("Illegal value for Predictor in TIFF file.");
- }
- if (predictor == 2 && bitsPerSample != 8) {
- throw new RuntimeException(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor.");
- }
- }
- lzwDecoder = new TIFFLZWDecoder(w, predictor,
- samplePerPixel);
- }
- int rowsLeft = h;
- ByteArrayOutputStream stream = null;
- DeflaterOutputStream zip = null;
- CCITTG4Encoder g4 = null;
- if (bitsPerSample == 1 && samplePerPixel == 1) {
- g4 = new CCITTG4Encoder(w);
- }
- else {
- stream = new ByteArrayOutputStream();
- if (compression != TIFFConstants.COMPRESSION_OJPEG)
- zip = new DeflaterOutputStream(stream);
- }
- for (int k = 0; k < offset.length; ++k) {
- byte im[] = new byte[(int)size[k]];
- s.seek(offset[k]);
- s.readFully(im);
- int height = Math.min(rowsStrip, rowsLeft);
- byte outBuf[] = null;
- if (compression != TIFFConstants.COMPRESSION_NONE)
- outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
- switch (compression) {
- case TIFFConstants.COMPRESSION_DEFLATE:
- inflate(im, outBuf);
- break;
- case TIFFConstants.COMPRESSION_NONE:
- outBuf = im;
- break;
- case TIFFConstants.COMPRESSION_PACKBITS:
- decodePackbits(im, outBuf);
- break;
- case TIFFConstants.COMPRESSION_LZW:
- lzwDecoder.decode(im, outBuf, height);
- break;
- case TIFFConstants.COMPRESSION_OJPEG:
- stream.write(im);
- break;
- }
- if (bitsPerSample == 1 && samplePerPixel == 1) {
- g4.fax4Encode(outBuf, height);
- }
- else if (compression != TIFFConstants.COMPRESSION_OJPEG) {
- zip.write(outBuf);
- }
- rowsLeft -= rowsStrip;
- }
- if (bitsPerSample == 1 && samplePerPixel == 1) {
- img = Image.getInstance(w, h, false, Image.CCITTG4,
- photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.close());
- }
- else {
- if (compression == TIFFConstants.COMPRESSION_OJPEG) {
- img = new Jpeg(stream.toByteArray());
- }
- else {
- zip.close();
- img = Image.getInstance(w, h, samplePerPixel, bitsPerSample, stream.toByteArray());
- img.setDeflated(true);
- }
- }
- img.setDpi(dpiX, dpiY);
- if (compression != TIFFConstants.COMPRESSION_OJPEG) {
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
- try {
- TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_ICCPROFILE);
- ICC_Profile icc_prof = ICC_Profile.getInstance(fd.getAsBytes());
- if (samplePerPixel == icc_prof.getNumComponents())
- img.tagICC(icc_prof);
- }
- catch (Exception e) {
- //empty
- }
- }
- if (dir.isTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) {
- TIFFField fd = dir.getField(TIFFConstants.TIFFTAG_COLORMAP);
- char rgb[] = fd.getAsChars();
- byte palette[] = new byte[rgb.length];
- int gColor = rgb.length / 3;
- int bColor = gColor * 2;
- for (int k = 0; k < gColor; ++k) {
- palette[k * 3] = (byte)(rgb[k] >>> 8);
- palette[k * 3 + 1] = (byte)(rgb[k + gColor] >>> 8);
- palette[k * 3 + 2] = (byte)(rgb[k + bColor] >>> 8);
- }
- PdfArray indexed = new PdfArray();
- indexed.add(PdfName.INDEXED);
- indexed.add(PdfName.DEVICERGB);
- indexed.add(new PdfNumber(gColor - 1));
- indexed.add(new PdfString(palette));
- PdfDictionary additional = new PdfDictionary();
- additional.put(PdfName.COLORSPACE, indexed);
- img.setAdditional(additional);
- }
- img.setOriginalType(Image.ORIGINAL_TIFF);
- }
- if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
- img.setInverted(true);
- if (rotation != 0)
- img.setInitialRotation(rotation);
- return img;
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
-
- static long[] getArrayLongShort(TIFFDirectory dir, int tag) {
- TIFFField field = dir.getField(tag);
- if (field == null)
- return null;
- long offset[];
- if (field.getType() == TIFFField.TIFF_LONG)
- offset = field.getAsLongs();
- else { // must be short
- char temp[] = field.getAsChars();
- offset = new long[temp.length];
- for (int k = 0; k < temp.length; ++k)
- offset[k] = temp[k];
- }
- return offset;
- }
-
- // Uncompress packbits compressed image data.
- public static void decodePackbits(byte data[], byte[] dst) {
- int srcCount = 0, dstCount = 0;
- byte repeat, b;
-
- while (dstCount < dst.length) {
- b = data[srcCount++];
- if (b >= 0 && b <= 127) {
- // literal run packet
- for (int i=0; i<(b + 1); i++) {
- dst[dstCount++] = data[srcCount++];
- }
-
- } else if (b <= -1 && b >= -127) {
- // 2 byte encoded run packet
- repeat = data[srcCount++];
- for (int i=0; i<(-b + 1); i++) {
- dst[dstCount++] = repeat;
- }
- } else {
- // no-op packet. Do nothing
- srcCount++;
- }
- }
- }
-
- public static void inflate(byte[] deflated, byte[] inflated) {
- Inflater inflater = new Inflater();
- inflater.setInput(deflated);
- try {
- inflater.inflate(inflated);
- }
- catch(DataFormatException dfe) {
- throw new ExceptionConverter(dfe);
- }
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/JavaCharStream.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/JavaCharStream.java
deleted file mode 100644
index da52458..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/JavaCharStream.java
+++ /dev/null
@@ -1,547 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 2.1 */
-package com.lowagie.text.pdf.codec.postscript;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (with java-like unicode escape processing).
- */
-
-public final class JavaCharStream
-{
- public static final boolean staticFlag = false;
- static final int hexval(char c) throws java.io.IOException {
- switch(c)
- {
- case '0' :
- return 0;
- case '1' :
- return 1;
- case '2' :
- return 2;
- case '3' :
- return 3;
- case '4' :
- return 4;
- case '5' :
- return 5;
- case '6' :
- return 6;
- case '7' :
- return 7;
- case '8' :
- return 8;
- case '9' :
- return 9;
-
- case 'a' :
- case 'A' :
- return 10;
- case 'b' :
- case 'B' :
- return 11;
- case 'c' :
- case 'C' :
- return 12;
- case 'd' :
- case 'D' :
- return 13;
- case 'e' :
- case 'E' :
- return 14;
- case 'f' :
- case 'F' :
- return 15;
- }
-
- throw new java.io.IOException(); // Should never come here
- }
-
- public int bufpos = -1;
- int bufsize;
- int available;
- int tokenBegin;
- private int bufline[];
- private int bufcolumn[];
-
- private int column = 0;
- private int line = 1;
-
- private boolean prevCharIsCR = false;
- private boolean prevCharIsLF = false;
-
- private java.io.Reader inputStream;
-
- private char[] nextCharBuf;
- private char[] buffer;
- private int maxNextCharInd = 0;
- private int nextCharInd = -1;
- private int inBuf = 0;
-
- private final void ExpandBuff(boolean wrapAround)
- {
- char[] newbuffer = new char[bufsize + 2048];
- int newbufline[] = new int[bufsize + 2048];
- int newbufcolumn[] = new int[bufsize + 2048];
-
- try
- {
- if (wrapAround)
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- System.arraycopy(buffer, 0, newbuffer,
- bufsize - tokenBegin, bufpos);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
- bufcolumn = newbufcolumn;
-
- bufpos += (bufsize - tokenBegin);
- }
- else
- {
- System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
- buffer = newbuffer;
-
- System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
- bufline = newbufline;
-
- System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
- bufcolumn = newbufcolumn;
-
- bufpos -= tokenBegin;
- }
- }
- catch (Throwable t)
- {
- throw new Error(t.getMessage());
- }
-
- available = (bufsize += 2048);
- tokenBegin = 0;
- }
-
- private final void FillBuff() throws java.io.IOException
- {
- int i;
- if (maxNextCharInd == 4096)
- maxNextCharInd = nextCharInd = 0;
-
- try {
- if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
- 4096 - maxNextCharInd)) == -1)
- {
- inputStream.close();
- throw new java.io.IOException();
- }
- else
- maxNextCharInd += i;
- return;
- }
- catch(java.io.IOException e) {
- if (bufpos != 0)
- {
- --bufpos;
- backup(0);
- }
- else
- {
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
- throw e;
- }
- }
-
- private final char ReadByte() throws java.io.IOException
- {
- if (++nextCharInd >= maxNextCharInd)
- FillBuff();
-
- return nextCharBuf[nextCharInd];
- }
-
- public final char BeginToken() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
-
- if (++bufpos == bufsize)
- bufpos = 0;
-
- tokenBegin = bufpos;
- return buffer[bufpos];
- }
-
- tokenBegin = 0;
- bufpos = -1;
-
- return readChar();
- }
-
- private final void AdjustBuffSize()
- {
- if (available == bufsize)
- {
- if (tokenBegin > 2048)
- {
- bufpos = 0;
- available = tokenBegin;
- }
- else
- ExpandBuff(false);
- }
- else if (available > tokenBegin)
- available = bufsize;
- else if ((tokenBegin - available) < 2048)
- ExpandBuff(true);
- else
- available = tokenBegin;
- }
-
- private final void UpdateLineColumn(char c)
- {
- column++;
-
- if (prevCharIsLF)
- {
- prevCharIsLF = false;
- line += (column = 1);
- }
- else if (prevCharIsCR)
- {
- prevCharIsCR = false;
- if (c == '\n')
- {
- prevCharIsLF = true;
- }
- else
- line += (column = 1);
- }
-
- switch (c)
- {
- case '\r' :
- prevCharIsCR = true;
- break;
- case '\n' :
- prevCharIsLF = true;
- break;
- case '\t' :
- column--;
- column += (8 - (column & 07));
- break;
- default :
- break;
- }
-
- bufline[bufpos] = line;
- bufcolumn[bufpos] = column;
- }
-
- public final char readChar() throws java.io.IOException
- {
- if (inBuf > 0)
- {
- --inBuf;
-
- if (++bufpos == bufsize)
- bufpos = 0;
-
- return buffer[bufpos];
- }
-
- char c;
-
- if (++bufpos == available)
- AdjustBuffSize();
-
- if ((buffer[bufpos] = c = ReadByte()) == '\\')
- {
- UpdateLineColumn(c);
-
- int backSlashCnt = 1;
-
- for (;;) // Read all the backslashes
- {
- if (++bufpos == available)
- AdjustBuffSize();
-
- try
- {
- if ((buffer[bufpos] = c = ReadByte()) != '\\')
- {
- UpdateLineColumn(c);
- // found a non-backslash char.
- if ((c == 'u') && ((backSlashCnt & 1) == 1))
- {
- if (--bufpos < 0)
- bufpos = bufsize - 1;
-
- break;
- }
-
- backup(backSlashCnt);
- return '\\';
- }
- }
- catch(java.io.IOException e)
- {
- if (backSlashCnt > 1)
- backup(backSlashCnt);
-
- return '\\';
- }
-
- UpdateLineColumn(c);
- backSlashCnt++;
- }
-
- // Here, we have seen an odd number of backslash's followed by a 'u'
- try
- {
- while ((c = ReadByte()) == 'u')
- ++column;
-
- buffer[bufpos] = c = (char)(hexval(c) << 12 |
- hexval(ReadByte()) << 8 |
- hexval(ReadByte()) << 4 |
- hexval(ReadByte()));
-
- column += 4;
- }
- catch(java.io.IOException e)
- {
- throw new Error("Invalid escape character at line " + line +
- " column " + column + ".");
- }
-
- if (backSlashCnt == 1)
- return c;
- else
- {
- backup(backSlashCnt - 1);
- return '\\';
- }
- }
- else
- {
- UpdateLineColumn(c);
- return (c);
- }
- }
-
- /**
- * @deprecated
- * @see #getEndColumn
- */
-
- public final int getColumn() {
- return bufcolumn[bufpos];
- }
-
- /**
- * @deprecated
- * @see #getEndLine
- */
-
- public final int getLine() {
- return bufline[bufpos];
- }
-
- public final int getEndColumn() {
- return bufcolumn[bufpos];
- }
-
- public final int getEndLine() {
- return bufline[bufpos];
- }
-
- public final int getBeginColumn() {
- return bufcolumn[tokenBegin];
- }
-
- public final int getBeginLine() {
- return bufline[tokenBegin];
- }
-
- public final void backup(int amount) {
-
- inBuf += amount;
- if ((bufpos -= amount) < 0)
- bufpos += bufsize;
- }
-
- public JavaCharStream(java.io.Reader dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new char[4096];
- }
-
- public JavaCharStream(java.io.Reader dstream,
- int startline, int startcolumn)
- {
- this(dstream, startline, startcolumn, 4096);
- }
-
- public JavaCharStream(java.io.Reader dstream)
- {
- this(dstream, 1, 1, 4096);
- }
- public void ReInit(java.io.Reader dstream,
- int startline, int startcolumn, int buffersize)
- {
- inputStream = dstream;
- line = startline;
- column = startcolumn - 1;
-
- if (buffer == null || buffersize != buffer.length)
- {
- available = bufsize = buffersize;
- buffer = new char[buffersize];
- bufline = new int[buffersize];
- bufcolumn = new int[buffersize];
- nextCharBuf = new char[4096];
- }
- prevCharIsLF = prevCharIsCR = false;
- tokenBegin = inBuf = maxNextCharInd = 0;
- nextCharInd = bufpos = -1;
- }
-
- public void ReInit(java.io.Reader dstream,
- int startline, int startcolumn)
- {
- ReInit(dstream, startline, startcolumn, 4096);
- }
-
- public void ReInit(java.io.Reader dstream)
- {
- ReInit(dstream, 1, 1, 4096);
- }
- public JavaCharStream(java.io.InputStream dstream, int startline,
- int startcolumn, int buffersize)
- {
- this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
- }
-
- public JavaCharStream(java.io.InputStream dstream, int startline,
- int startcolumn)
- {
- this(dstream, startline, startcolumn, 4096);
- }
-
- public JavaCharStream(java.io.InputStream dstream)
- {
- this(dstream, 1, 1, 4096);
- }
-
- public void ReInit(java.io.InputStream dstream, int startline,
- int startcolumn, int buffersize)
- {
- ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
- }
- public void ReInit(java.io.InputStream dstream, int startline,
- int startcolumn)
- {
- ReInit(dstream, startline, startcolumn, 4096);
- }
- public void ReInit(java.io.InputStream dstream)
- {
- ReInit(dstream, 1, 1, 4096);
- }
-
- public final String GetImage()
- {
- if (bufpos >= tokenBegin)
- return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
- else
- return new String(buffer, tokenBegin, bufsize - tokenBegin) +
- new String(buffer, 0, bufpos + 1);
- }
-
- public final char[] GetSuffix(int len)
- {
- char[] ret = new char[len];
-
- if ((bufpos + 1) >= len)
- System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
- else
- {
- System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
- len - bufpos - 1);
- System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
- }
-
- return ret;
- }
-
- public void Done()
- {
- nextCharBuf = null;
- buffer = null;
- bufline = null;
- bufcolumn = null;
- }
-
- /**
- * Method to adjust line and column numbers for the start of a token.<BR>
- */
- public void adjustBeginLineColumn(int newLine, int newCol)
- {
- int start = tokenBegin;
- int len;
-
- if (bufpos >= tokenBegin)
- {
- len = bufpos - tokenBegin + inBuf + 1;
- }
- else
- {
- len = bufsize - tokenBegin + bufpos + 1 + inBuf;
- }
-
- int i = 0, j = 0, k = 0;
- int nextColDiff = 0, columnDiff = 0;
-
- while (i < len &&
- bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
- {
- bufline[j] = newLine;
- nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
- bufcolumn[j] = newCol + columnDiff;
- columnDiff = nextColDiff;
- i++;
- }
-
- if (i < len)
- {
- bufline[j] = newLine++;
- bufcolumn[j] = newCol + columnDiff;
-
- while (i++ < len)
- {
- if (bufline[j = start % bufsize] != bufline[++start % bufsize])
- bufline[j] = newLine++;
- else
- bufline[j] = newLine;
- }
- }
-
- line = bufline[j];
- column = bufcolumn[j];
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/MetaDoPS.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/MetaDoPS.java
deleted file mode 100644
index a160e6b..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/MetaDoPS.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * $Id: MetaDoPS.java,v 1.4 2006/04/22 16:56:39 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.codec.postscript;
-
-import java.io.*;
-import java.awt.*;
-import com.lowagie.text.*;
-import com.lowagie.text.pdf.*;
-
-public class MetaDoPS {
-
- public PdfContentByte cb;
- InputStream in;
- int left;
- int top;
- int right;
- int bottom;
- int inch;
-
- public MetaDoPS(InputStream in, PdfContentByte cb) {
- this.cb = cb;
- this.in = in;
- }
-
- public void readAll() throws IOException, DocumentException {
-
- cb.saveState();
- java.awt.Graphics2D g2 = cb.createGraphicsShapes(PageSize.A4.
- width(), PageSize.A4.height());
- try {
- PAContext context = new PAContext( (Graphics2D) g2,
- new Dimension( (int) PageSize.A4.width(),
- (int) PageSize.A4.height()));
- context.draw(in);
-// context.draw(new BufferedInputStream(in));
- // ( (Graphics2D) backBuffer.getGraphics()).dispose();
- in.close();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
- catch (PainterException ex) {
- ex.printStackTrace();
- }
- g2.dispose();
- cb.restoreState();
-
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PACommand.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PACommand.java
deleted file mode 100644
index 91b2e18..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PACommand.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-public interface PACommand {
-
- public void execute(PAContext context) throws PainterException;
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAContext.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAContext.java
deleted file mode 100644
index 863d82a..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAContext.java
+++ /dev/null
@@ -1,2772 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-import java.util.*;
-import java.io.*;
-import java.awt.*;
-import java.awt.geom.*;
-import com.lowagie.text.pdf.PdfGraphics2D;
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfName;
-import com.lowagie.text.*;
-import com.lowagie.text.pdf.RandomAccessFileOrArray;
-
-public class PAContext {
-
- public PAPencil pencil;
- public Stack dictionaries;
- public Stack operands;
- public PAEngine engine;
- PAParser poorscript = null;
- protected Random randomNumberGenerator;
- InputStream is=null;
-
- protected Object lastUnknownIdentifier;
- public static boolean IgnoreUnknownCommands = false;
- public static boolean DebugExecution = false;
-
- public PAContext(Component component) {
- this(new PAPencil(component));
- }
-
- public PAContext(Graphics2D g, Dimension size) {
- this(new PAPencil(g, size));
- }
-
- public PAContext(PAPencil pencil) {
- super();
- this.pencil = pencil;
- this.dictionaries = new Stack();
- this.operands = new Stack();
- this.engine = new PAEngine(this);
- HashMap systemDict = this.constructSystemDict();
- this.dictionaries.push(systemDict);
- HashMap globalDict = this.constructGlobalDict();
- this.dictionaries.push(globalDict);
- HashMap userDict = this.constructUserDict();
- systemDict.put("userdict", userDict);
- this.dictionaries.push(userDict);
- this.randomNumberGenerator = new Random();
- this.lastUnknownIdentifier = null;
- }
-
- /**
- * draw
- *
- * @param inputStream InputStream
- * @throws PainterException
- */
- public void draw(InputStream inputStream) throws PainterException {
- try {
- String filename="init.ps";
-// poorscript = new PAParser(new NamedInputStream(PAContext.class.getResourceAsStream(filename),filename));
- InputStream inpstr=PAContext.class.getResourceAsStream(filename);
- poorscript = new PAParser(inpstr);
- poorscript.parse(this);
- try {
- inpstr.close();
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
-// poorscript.enable_tracing();
-// poorscript.token_source.setDebugStream(System.err);
-// byte[] b=null;
-// try {
-// b = RandomAccessFileOrArray.InputStreamToArray(inputStream);
-// }
-// catch (IOException ex) {
-// ex.printStackTrace();
-// }
-// ByteArrayInputStream bar=new ByteArrayInputStream(b);
-// is = bar;
- poorscript.ReInit(inputStream);
- poorscript.parse(this);
- // pencil.graphics.dispose();
- }
- catch (ParseException e) {
- e.printStackTrace();
- throw new PainterException(e.toString());
- }
- }
-
-
-
- public Object getLastUnknownIdentifier() {
- return this.lastUnknownIdentifier;
- }
-
- public double[] popNumberOperands(int n) throws PainterException {
- double[] result = new double[n];
- Object objectValue;
- double doubleValue;
-
- for (int i = n - 1; i >= 0; i--) {
- try {
- objectValue = this.operands.pop();
- }
- catch (EmptyStackException e) {
- throw new PainterException("Operand stack is empty poping " + n +
- " number operands");
- }
- if (objectValue instanceof Number) {
- doubleValue = ( (Number) objectValue).doubleValue();
- }
- else {
- throw new PainterException("Number expected on operand stack poping " +
- n + " number operands, found " +
- objectValue.getClass().getName());
- }
- result[i] = doubleValue;
- }
- return result;
- }
-
- public Object[] popOperands(int n) throws PainterException {
- Object[] result = new Object[n];
- Object objectValue;
-
- for (int i = n - 1; i >= 0; i--) {
- try {
- objectValue = this.operands.pop();
- }
- catch (EmptyStackException e) {
- throw new PainterException("Operand stack is empty poping " + n +
- " operands");
- }
- result[i] = objectValue;
- }
- return result;
- }
-
- public Object peekOperand() throws PainterException {
- Object objectValue;
-
- try {
- objectValue = this.operands.peek();
- }
- catch (EmptyStackException e) {
- throw new PainterException("Operand stack is empty peeking operand");
- }
- return objectValue;
- }
-
- public Object findIdentifier(Object identifier) {
- Object result = null;
- int i, n;
-
- n = this.dictionaries.size();
- i = n - 1;
- while (i >= 0 && result == null) {
- HashMap dictionary = (HashMap)this.dictionaries.elementAt(i);
- result = dictionary.get(identifier);
- i--;
- }
- if (result == null) {
- this.lastUnknownIdentifier = identifier;
- }
- return result;
- }
-
- public Object findDictionary(Object identifier) {
- Object result = null;
- HashMap dictionary = null;
- int i, n;
-
- n = this.dictionaries.size();
- i = n - 1;
- while (i >= 0 && result == null) {
- dictionary = (HashMap)this.dictionaries.elementAt(i);
- result = dictionary.get(identifier);
- i--;
- }
- if (result == null) {
- return result;
- }
- else {
- return dictionary;
- }
- }
-
- public void collectArray() throws PainterException {
- ArrayList result;
- Object objectValue;
- int i, n;
- boolean found = false;
-
- n = this.operands.size();
- for (i = n - 1; i >= 0; i--) {
- objectValue = this.operands.elementAt(i);
- if (objectValue instanceof PAToken &&
- ( (PAToken) objectValue).type == PAToken.START_ARRAY) {
- found = true;
- break;
- }
- }
- if (!found) {
- throw new PainterException("No array was started");
- }
- result = new ArrayList(n - i - 1);
- for (int j = 0; j < n - i - 1; j++) {
- result.add(null);
- }
- for (int j = n - 1; j > i; j--) {
- try {
- objectValue = this.operands.pop();
- }
- catch (EmptyStackException e) {
- throw new PainterException(
- "Operand stack is empty collecting array elements");
- }
- result.set(j - i - 1, objectValue);
- }
- try {
- this.operands.pop(); // the start array mark itself
- }
- catch (EmptyStackException e) {
- throw new PainterException(
- "Operand stack is empty removing begin array mark");
- }
- this.operands.push(result);
- }
-
- public void collectDict() throws PainterException {
- HashMap result; // = new HashMap();
- Object objectValue;
- int i, n;
- boolean found = false;
-
- n = this.operands.size();
- for (i = n - 1; i >= 0; i--) {
- objectValue = this.operands.elementAt(i);
- if (objectValue instanceof PAToken &&
- ( (PAToken) objectValue).type == PAToken.START_DICT) {
- found = true;
- break;
- }
- }
- if (!found) {
- throw new PainterException("No dict was started");
- }
-// result = new ArrayList(n - i - 1);
- result = new HashMap();
-// for (int j = 0; j < n - i - 1; j++) {
-// result.add(null);
-// }
- for (int j = n - 1; j > i; j -= 2) {
- Object targetValue;
- try {
- targetValue = this.operands.pop();
- objectValue = this.operands.pop();
- }
- catch (EmptyStackException e) {
- throw new PainterException(
- "Operand stack is empty collecting hashmap elements");
- }
- result.put(objectValue, targetValue);
- }
- try {
- this.operands.pop(); // the start array mark itself
- }
- catch (EmptyStackException e) {
- throw new PainterException(
- "Operand stack is empty removing begin array mark");
- }
- this.operands.push(result);
- }
-
- protected HashMap constructGlobalDict() {
- HashMap globalDict = new HashMap();
- return globalDict;
- }
-
- protected HashMap constructUserDict() {
- HashMap userDict = new HashMap();
-
- return userDict;
- }
-
- public static void main(String[] args) {
- javax.swing.JFrame jf = new javax.swing.JFrame();
- jf.setVisible(true);
- jf.setDefaultCloseOperation(jf.DISPOSE_ON_CLOSE);
- PAContext pac = new PAContext(new PAPencil(jf));
- HashMap hm = (HashMap) pac.findDictionary("systemdict");
- Iterator it = new TreeSet(hm.keySet()).iterator();
- while (it.hasNext()) {
-
- String obname = it.next().toString();
- Object ob = hm.get(obname);
- String typname = ob.getClass().getName();
- System.out.println(obname + ":" + typname);
- }
- System.exit(0);
- }
-
- protected HashMap constructSystemDict() {
- HashMap systemDict = new HashMap();
-
- // newpath
- systemDict.put("newpath", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.newpath();
- }
- });
-
- // moveto
- systemDict.put("moveto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(2);
- context.pencil.moveto(data[0], data[1]);
- }
- });
-
- // rmoveto
- systemDict.put("rmoveto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.pencil.rmoveto(data[0], data[1]);
- }
- });
-
- // lineto
- systemDict.put("lineto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.pencil.lineto(data[0], data[1]);
- }
- });
-
- // rlineto
- systemDict.put("rlineto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.pencil.rlineto(data[0], data[1]);
- }
- });
-
- // arc
- systemDict.put("arc", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(5);
- context.pencil.arc(data[0], data[1], data[2], data[3], data[4]);
- }
- });
-
- // arcn
- systemDict.put("arcn", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(5);
- context.pencil.arcn(data[0], data[1], data[2], data[3], data[4]);
- }
- });
-
- // curveto
- systemDict.put("curveto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(6);
- context.pencil.curveto(data[0], data[1], data[2], data[3], data[4],
- data[5]);
- }
- });
-
- // rcurveto
- systemDict.put("rcurveto", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(6);
- context.pencil.rcurveto(data[0], data[1], data[2], data[3], data[4],
- data[5]);
- }
- });
-
- // closepath
- systemDict.put("closepath", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.closepath();
- }
- });
-
- // gsave
- systemDict.put("gsave", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.gsave();
- }
- });
-
- // grestore
- systemDict.put("grestore", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.grestore();
- }
- });
-
- // translate
- systemDict.put("translate", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (context.peekOperand() instanceof Number) {
- double data[];
- AffineTransform at = new AffineTransform();
- AffineTransform ctm = context.pencil.graphics.getTransform();
-
- data = context.popNumberOperands(2);
- at.translate(data[0], data[1]);
- ctm.concatenate(at);
- context.pencil.graphics.setTransform(ctm);
- }
- else {
- Object data[];
-
- data = context.popOperands(3);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("translate: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("translate: wrong arguments");
- }
- if (! (data[2] instanceof ArrayList)) {
- throw new PainterException("translate: wrong arguments");
- }
-
- ArrayList array = (ArrayList) data[2];
-
- if (! (array.size() == 6)) {
- throw new PainterException("translate: wrong arguments");
- }
-
- AffineTransform at = new AffineTransform();
-
- at.translate( ( (Number) data[0]).doubleValue(),
- ( (Number) data[1]).doubleValue());
-
- double[] entries = new double[6];
-
- at.getMatrix(entries);
-
- for (int i = 0; i < 6; i++) {
- array.set(i, new Double(entries[i]));
- }
- context.operands.push(array);
- }
- }
- });
-
- // rotate
- systemDict.put("rotate", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (context.peekOperand() instanceof Number) {
- double data[];
- AffineTransform at = new AffineTransform();
- AffineTransform ctm = context.pencil.graphics.getTransform();
-
- data = context.popNumberOperands(1);
- at.rotate(data[0] * Math.PI / 180.0d);
- ctm.concatenate(at);
- context.pencil.graphics.setTransform(ctm);
- }
- else {
- Object data[];
- AffineTransform at = new AffineTransform();
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("rotate: wrong arguments");
- }
- if (! (data[1] instanceof ArrayList)) {
- throw new PainterException("rotate: wrong arguments");
- }
-
- ArrayList array = (ArrayList) data[1];
-
- if (! (array.size() == 6)) {
- throw new PainterException("rotate: wrong arguments");
- }
-
- at.rotate( ( (Number) data[0]).doubleValue());
-
- double[] entries = new double[6];
-
- at.getMatrix(entries);
-
- for (int i = 0; i < 6; i++) {
- array.set(i, new Double(entries[i]));
- }
- context.operands.push(array);
- }
- }
- });
-
- // scale
- systemDict.put("scale", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (context.peekOperand() instanceof Number) {
- double data[];
- AffineTransform at = new AffineTransform();
- AffineTransform ctm = context.pencil.graphics.getTransform();
-
- data = context.popNumberOperands(2);
- at.scale(data[0], data[1]);
- ctm.concatenate(at);
- context.pencil.graphics.setTransform(ctm);
- }
- else {
- Object data[];
-
- data = context.popOperands(3);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("scale: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("scale: wrong arguments");
- }
- if (! (data[2] instanceof ArrayList)) {
- throw new PainterException("scale: wrong arguments");
- }
-
- ArrayList array = (ArrayList) data[2];
-
- double[] entries = new double[6];
-
- if (! (array.size() == 6)) {
- throw new PainterException("scale: wrong arguments");
- }
-
- entries[0] = ( (Number) data[0]).doubleValue();
- entries[1] = 0.0d;
- entries[2] = 0.0d;
- entries[3] = ( (Number) data[1]).doubleValue();
- entries[4] = 0.0d;
- entries[5] = 0.0d;
-
- for (int i = 0; i < 6; i++) {
- array.set(i, new Double(entries[i]));
- }
- context.operands.push(array);
- }
- }
- });
- // currentmatrix
- systemDict.put("currentmatrix", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof ArrayList)) {
- throw new PainterException("currentmatrix: wrong argument");
- }
- ArrayList array = (ArrayList) data[0];
-
- double[] entries = new double[6];
-
- if (! (array.size() == 6)) {
- throw new PainterException("currentmatrix: wrong arguments");
- }
-
-
- AffineTransform ctm = context.pencil.graphics.getTransform();
- ctm.getMatrix(entries);
-
- for (int i = 0; i < 6; i++) {
- array.set(i, new Double(entries[i]));
- }
- context.operands.push(array);
- }
- });
-
- // setmatrix
- systemDict.put("setmatrix", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof ArrayList)) {
- throw new PainterException("setmatrix: wrong argument");
- }
- ArrayList array = (ArrayList) data[0];
-
- double[] entries = new double[6];
-
- if (! (array.size() == 6)) {
- throw new PainterException("setmatrix: wrong arguments");
- }
- entries[0] = ((Number)array.get(0)).doubleValue();
- entries[1] = ((Number)array.get(1)).doubleValue();
- entries[2] = ((Number)array.get(2)).doubleValue();
- entries[3] = ((Number)array.get(3)).doubleValue();
- entries[4] = ((Number)array.get(4)).doubleValue();
- entries[5] = ((Number)array.get(5)).doubleValue();
-
- AffineTransform at = new AffineTransform(entries);
- context.pencil.graphics.setTransform(at);
- }
- });
-
- // stroke
- systemDict.put("stroke", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.stroke();
- }
- });
-
- // fill
- systemDict.put("fill", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.fill();
- }
- });
-
- // eofill
- systemDict.put("eofill", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.eofill();
- }
- });
-
- // show
- systemDict.put("show", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(1);
- if (! (data[0] instanceof String)) {
- throw new PainterException("show: wrong arguments");
- }
- context.pencil.show( (String) data[0]);
- }
- });
-
- // stringwidth
- systemDict.put("stringwidth", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- float[] result;
- java.awt.Font font;
-
- data = context.popOperands(1);
- if (! (data[0] instanceof String)) {
- throw new PainterException("stringwidth: wrong arguments");
- }
- font = context.pencil.graphics.getFont();
- Rectangle2D rect = font.getStringBounds( (String) data[0],
- context.pencil.graphics.
- getFontRenderContext());
- context.operands.push(new Float(rect.getWidth()));
- context.operands.push(new Float(rect.getHeight()));
- }
- });
-
- // showpage
- systemDict.put("showpage", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.showpage();
- }
- });
-
- // findfont
- systemDict.put("findfont", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("findfont: wrong arguments");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("findfont: wrong arguments");
- }
- context.operands.push(context.pencil.findFont( (String) patoken.value));
- }
- });
-
- // makefont
- systemDict.put("makefont", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(2);
- if (! (data[0] instanceof java.awt.Font)) {
- throw new PainterException("makefont: wrong arguments");
- }
- if (! (data[1] instanceof ArrayList)) {
- throw new PainterException("makefont: wrong arguments");
- }
- // @TODO implement!!!
- context.operands.push(data[0]);
- }
- });
-
- // scalefont
- systemDict.put("scalefont", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(2);
- if (! (data[0] instanceof java.awt.Font)) {
- throw new PainterException("scalefont: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("scalefont: wrong arguments");
- }
- java.awt.Font fn=( (java.awt.Font) data[0]).deriveFont( ( (Number)
- data[1]).
- floatValue());
- System.out.println("Fonthoehe:"+fn.getSize2D());
- context.operands.push(fn );
- }
- });
-
- // setfont
- systemDict.put("setfont", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof java.awt.Font)) {
- throw new PainterException("setfont: wrong arguments");
- }
- java.awt.Font fn=(java.awt.Font)data[0];
- System.out.println("Fonthoehe:"+fn.getSize2D());
- /**
- * @todo two times the same?
- */
- context.pencil.graphics.setFont( fn);
- context.pencil.state.font=fn;
- }
- });
-
- // def
- systemDict.put("def", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(2);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("def: wrong arguments");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("def: wrong arguments");
- }
- try {
- ( (HashMap) context.dictionaries.peek()).put(patoken.value, data[1]);
- }
- catch (EmptyStackException e) {
- throw new PainterException(e.toString());
- }
- }
- });
-
- // bind
- systemDict.put("bind", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("bind: wrong arguments, not PAToken");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("bind: wrong arguments, not Procedure " +
- patoken.value);
- }
- context.engine.bindProcedure(patoken);
- context.operands.push(patoken);
- }
- });
-
- // mul
- systemDict.put("mul", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.operands.push(new Double(data[0] * data[1]));
- }
- });
-
- // div
- systemDict.put("div", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.operands.push(new Double(data[0] / data[1]));
- }
- });
-
- // mod
- systemDict.put("mod", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- int a, b, m;
- a = (int) data[0];
- b = (int) data[1];
- m = a % b;
- context.operands.push(new Integer(m));
- }
- });
-
- // add
- systemDict.put("add", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.operands.push(new Double(data[0] + data[1]));
- }
- });
-
- // neg
- systemDict.put("neg", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Double( -data[0]));
- }
- });
- // ceiling
- systemDict.put("ceiling", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.ceil(data[0])));
- }
- });
- // sub
- systemDict.put("sub", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(2);
- context.operands.push(new Double(data[0] - data[1]));
- }
- });
-
- // atan
- systemDict.put("atan", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(2);
- context.operands.push(new Double(Math.atan2(data[0], data[1])));
- }
- });
-
- // sin
- systemDict.put("sin", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.sin(data[0] * Math.PI / 180.0)));
- }
- });
-
- // cos
- systemDict.put("cos", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.cos(data[0] * Math.PI / 180.0)));
- }
- });
-
- // sqrt
- systemDict.put("sqrt", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.sqrt(data[0])));
- }
- });
- // ln
- systemDict.put("log", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.log(data[0])));
- }
- });
- // exp
- systemDict.put("exp", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(2);
- context.operands.push(new Double(Math.pow(data[0], data[1])));
- }
- });
-
- // exch
- systemDict.put("exch", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- context.operands.push(data[1]);
- context.operands.push(data[0]);
- }
- });
-
- // dup
- systemDict.put("dup", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(1);
- context.operands.push(data[0]);
- context.operands.push(data[0]);
- }
- });
-
- // roll
- systemDict.put("roll", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- Object rollData[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("roll: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("roll: wrong arguments");
- }
- int numberOfElements, numberOfPositions, i;
-
- numberOfElements = ( (Number) data[0]).intValue();
- numberOfPositions = ( (Number) data[1]).intValue();
-
- if (numberOfPositions == 0 || numberOfElements <= 0) {
- return;
- }
-
- rollData = context.popOperands(numberOfElements);
-
- if (numberOfPositions < 0) {
- numberOfPositions = -numberOfPositions;
- numberOfPositions = numberOfPositions % numberOfElements;
-
- // downward roll
- for (i = numberOfPositions; i < numberOfElements; i++) {
- context.operands.push(rollData[i]);
- }
- for (i = 0; i < numberOfPositions; i++) {
- context.operands.push(rollData[i]);
- }
- }
- else {
- numberOfPositions = numberOfPositions % numberOfElements;
-
- // upward roll
- for (i = numberOfElements - numberOfPositions; i < numberOfElements;
- i++) {
- context.operands.push(rollData[i]);
- }
- for (i = 0; i < numberOfElements - numberOfPositions; i++) {
- context.operands.push(rollData[i]);
- }
- }
- }
- });
-
- // pop
- systemDict.put("pop", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.popOperands(1);
- }
- });
-
- // index
- systemDict.put("index", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("index: wrong arguments");
- }
- int index = ( (Number) data[0]).intValue();
- try {
- context.operands.push(context.operands.elementAt(index));
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new PainterException(e.toString());
- }
- }
- });
-
- // mark
- systemDict.put("mark", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(new PAToken(null, PAToken.MARK));
- }
- });
-
- // cvx
- systemDict.put("cvx", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data;
- data = context.operands.pop();
- ArrayList ar = (ArrayList) data;
- Stack stack = new Stack();
- for (int i = ar.size() - 1; i >= 0; i--) {
- stack.add(ar.get(i));
- }
- PAToken patoken = new PAToken(stack, PAToken.PROCEDURE);
-// patoken.type=PAToken.PROCEDURE;
- context.operands.push(patoken);
- }
- });
- // cleartomark
- systemDict.put("cleartomark", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data;
- boolean finished = false;
-
- while (!finished) {
- try {
- data = context.operands.pop();
- if (data instanceof PAToken) {
- if ( ( (PAToken) data).type == PAToken.MARK) {
- finished = true;
- }
- }
- }
- catch (EmptyStackException e) {
- throw new PainterException(e.toString());
- }
- }
- }
- });
-
- // copy
- systemDict.put("copy", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(2);
-
- // decide if it's a simple copy or a composite object copy
- if ( (data[0] instanceof PAToken) && (data[1] instanceof PAToken)) {
- // composite object copy
- if ( ( (PAToken) data[0]).type == ( (PAToken) data[1]).type) {
- // our tokens are immutable so a copy is easy
- context.operands.push(data[0]);
- context.operands.push(data[0]);
- }
- else {
- throw new PainterException(
- "copy operation failed because composite objects on stack are not of same type");
- }
- }
- else {
- // restore first arg, we're not interested in it in this simple case
- context.operands.push(data[0]);
-
- if (data[1] instanceof Number) {
- int index = ( (Number) data[1]).intValue();
- int i, n;
- n = context.operands.size();
- Object[] copyData = new Object[index];
- for (i = n - index; i < n; i++) {
- try {
- copyData[i - n + index] = context.operands.elementAt(i);
- }
- catch (ArrayIndexOutOfBoundsException e) {
- throw new PainterException(e.toString());
- }
- }
- for (i = 0; i < index; i++) {
- context.operands.push(copyData[i]);
- }
- }
- else {
- throw new PainterException("I expect a number on stack, dude");
- }
- }
- }
- });
-
- // setgray
- systemDict.put("setgray", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(1);
- context.pencil.graphics.setPaint(new Color( (float) data[0],
- (float) data[0], (float) data[0]));
- }
- });
-
- // setrgbcolor
- systemDict.put("setrgbcolor", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(3);
- float[] fv = new float[3];
- fv[0] = (float) Math.max(Math.min(data[0], 1.0d), 0.0d);
- fv[1] = (float) Math.max(Math.min(data[1], 1.0d), 0.0d);
- fv[2] = (float) Math.max(Math.min(data[2], 1.0d), 0.0d);
- context.pencil.graphics.setPaint(new Color(fv[0], fv[1], fv[2]));
- }
- });
-
- // currentrgbcolor
-systemDict.put("currentrgbcolor", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Color cl=context.pencil.graphics.getColor();
- float[] fv = cl.getRGBComponents(null);
- context.operands.push(new Float(fv[0]));
- context.operands.push(new Float(fv[1]));
- context.operands.push(new Float(fv[2]));
- }
-});
-
-
- // PENDING(uweh): color stuff still shaky
- // sethsbcolor
- systemDict.put("sethsbcolor", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(3);
- float[] fv = new float[3];
- fv[0] = (float) Math.max(Math.min(data[0], 1.0d), 0.0d);
- fv[1] = (float) Math.max(Math.min(data[1], 1.0d), 0.0d);
- fv[2] = (float) Math.max(Math.min(data[2], 1.0d), 0.0d);
- context.pencil.graphics.setPaint(new Color(fv[0], fv[1], fv[2]));
- }
- });
-
- // PENDING(uweh): I have to convert these puppies myself to rgb ?
- // setcmykcolor
- systemDict.put("setcmykcolor", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- int rd, gr, bl;
-
- data = context.popNumberOperands(4);
- float[] fv = new float[4];
- fv[0] = (float) data[0];
- fv[1] = (float) data[1];
- fv[2] = (float) data[2];
- fv[3] = (float) data[3];
- rd = (int) (255 * Math.max(0, 1 - fv[0] - fv[3]));
- gr = (int) (255 * Math.max(0, 1 - fv[1] - fv[3]));
- bl = (int) (255 * Math.max(0, 1 - fv[2] - fv[3]));
- context.pencil.graphics.setPaint(new Color(rd, gr, bl));
- }
- });
-
- // setlinewidth
- systemDict.put("setlinewidth", new PACommand() {
- private double minLineWidth(double w, AffineTransform at) {
- double matrix[] = new double[4];
- at.getMatrix(matrix);
- double scale = matrix[0] * matrix[3] - matrix[1] * matrix[2];
- double minlw = .25 / Math.sqrt(Math.abs(scale));
- if (w < minlw) {
- w = minlw;
- }
- return w;
- }
-
- public void execute(PAContext context) throws PainterException {
- double data[];
- BasicStroke newStroke;
- Stroke oldStroke = context.pencil.graphics.getStroke();
- data = context.popNumberOperands(1);
- data[0] = this.minLineWidth(data[0],
- context.pencil.graphics.getTransform());
- if (oldStroke instanceof BasicStroke) {
- newStroke = new BasicStroke( (float) data[0],
- ( (BasicStroke) oldStroke).getEndCap(),
- ( (BasicStroke) oldStroke).getLineJoin(),
- ( (BasicStroke) oldStroke).getMiterLimit(),
- ( (BasicStroke) oldStroke).getDashArray(),
- ( (BasicStroke) oldStroke).getDashPhase());
- }
- else {
- newStroke = new BasicStroke( (float) data[0], BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_ROUND);
- }
- /**
- * @todo two times the same?
- */
- context.pencil.graphics.setStroke(newStroke);
-// context.pencil.state.stroke=newStroke;
- }
- });
-
- // setlinecap
- systemDict.put("setlinecap", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- BasicStroke newStroke;
- Stroke oldStroke = context.pencil.graphics.getStroke();
- data = context.popNumberOperands(1);
- if (oldStroke instanceof BasicStroke) {
- newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
- (int) data[0],
- ( (BasicStroke) oldStroke).getLineJoin(),
- ( (BasicStroke) oldStroke).getMiterLimit(),
- ( (BasicStroke) oldStroke).getDashArray(),
- ( (BasicStroke) oldStroke).getDashPhase());
- }
- else {
- newStroke = new BasicStroke(1.0f, (int) data[0],
- BasicStroke.JOIN_ROUND);
- }
- context.pencil.graphics.setStroke(newStroke);
- }
- });
-
- // setmiterlimit
- systemDict.put("setmiterlimit", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- BasicStroke newStroke;
- Stroke oldStroke = context.pencil.graphics.getStroke();
- data = context.popNumberOperands(1);
- if (oldStroke instanceof BasicStroke) {
- newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
- ( (BasicStroke) oldStroke).getEndCap(),
- ( (BasicStroke) oldStroke).getLineJoin(),
- (float) data[0],
- ( (BasicStroke) oldStroke).getDashArray(),
- ( (BasicStroke) oldStroke).getDashPhase());
- }
- else {
- newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_ROUND, (float) data[0]);
- }
- context.pencil.graphics.setStroke(newStroke);
- }
- });
-
- // setdash
- systemDict.put("setdash", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- BasicStroke newStroke;
- Stroke oldStroke = context.pencil.graphics.getStroke();
- data = context.popOperands(2);
- if (! (data[0] instanceof ArrayList)) {
- throw new PainterException("setdash: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("setdash: wrong arguments");
- }
-
- ArrayList list = (ArrayList) data[0];
-
- if (list.size() == 0) {
- return;
- }
- float[] dashpattern = new float[list.size()];
- for (int i = 0; i < dashpattern.length; i++) {
- dashpattern[i] = ( (Number) list.get(i)).floatValue();
- }
- float dashoffset = ( (Number) data[1]).floatValue();
- if (oldStroke instanceof BasicStroke) {
- newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
- ( (BasicStroke) oldStroke).getEndCap(),
- ( (BasicStroke) oldStroke).getLineJoin(),
- ( (BasicStroke) oldStroke).getMiterLimit(),
- dashpattern,
- dashoffset);
- }
- else {
- newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
- BasicStroke.JOIN_ROUND, 1.0f, dashpattern,
- dashoffset);
- }
- context.pencil.graphics.setStroke(newStroke);
- }
- });
-
- // setlinejoin
- systemDict.put("setlinejoin", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- BasicStroke newStroke;
- Stroke oldStroke = context.pencil.graphics.getStroke();
- data = context.popNumberOperands(1);
- if (oldStroke instanceof BasicStroke) {
- newStroke = new BasicStroke( ( (BasicStroke) oldStroke).getLineWidth(),
- ( (BasicStroke) oldStroke).getEndCap(),
- (int) data[0],
- ( (BasicStroke) oldStroke).getMiterLimit(),
- ( (BasicStroke) oldStroke).getDashArray(),
- ( (BasicStroke) oldStroke).getDashPhase());
- }
- else {
- newStroke = new BasicStroke(1.0f, BasicStroke.CAP_ROUND, (int) data[0]);
- }
- context.pencil.graphics.setStroke(newStroke);
- }
- });
-
- // dumpstack
- systemDict.put("dumpstack", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Enumeration enumx = context.operands.elements();
- System.out.println("-------------Stack--------------");
- while (enumx.hasMoreElements()) {
- System.out.println(enumx.nextElement());
- }
- System.out.println("--------------------------------");
- }
- });
-
- // for
- systemDict.put("for", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
-
- data = context.popOperands(4);
- if (! (data[3] instanceof PAToken)) {
- throw new PainterException("for: wrong arguments");
- }
- if (! (data[0] instanceof Number)) {
- throw new PainterException("for: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("for: wrong arguments");
- }
- if (! (data[2] instanceof Number)) {
- throw new PainterException("for: wrong arguments");
- }
- patoken = (PAToken) data[3];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("for: wrong arguments");
- }
- int i0, i1, i2;
- i0 = ( (Number) data[0]).intValue();
- i1 = ( (Number) data[1]).intValue();
- i2 = ( (Number) data[2]).intValue();
-
- if (i1 > 0) {
- for (int i = i0; i <= i2; i += i1) {
- context.operands.push(new Integer(i));
- context.engine.process(patoken);
- }
- }
- else {
- for (int i = i0; i >= i2; i -= i1) {
- context.operands.push(new Integer(i));
- context.engine.process(patoken);
- }
- }
- }
- });
-
- // repeat
- systemDict.put("repeat", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(2);
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("repeat: wrong arguments");
- }
- if (! (data[0] instanceof Number)) {
- throw new PainterException("repeat: wrong arguments");
- }
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("repeat: wrong arguments");
- }
- int n = ( (Number) data[0]).intValue();
- for (int i = 0; i < n; i++) {
- context.engine.process(patoken);
- }
- }
- });
-
- // true
- systemDict.put("true", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(new Boolean(true));
- }
- });
-
- // false
- systemDict.put("false", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(new Boolean(false));
- }
- });
-
- // lt
- systemDict.put("lt", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("lt: wrong arguments");
- }
- if (data[0] instanceof Number) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("lt: wrong arguments");
- }
- double d0, d1;
- d0 = ( (Number) data[0]).doubleValue();
- d1 = ( (Number) data[1]).doubleValue();
- if (d0 < d1) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- else {
- if (! (data[1] instanceof String)) {
- throw new PainterException("lt: wrong arguments");
- }
- String s0, s1;
- s0 = (String) data[0];
- s1 = (String) data[1];
- if (s0.compareTo(s1) < 0) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- }
- });
-
- // gt
- systemDict.put("gt", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("gt: wrong arguments");
- }
- if (data[0] instanceof Number) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("gt: wrong arguments");
- }
- double d0, d1;
- d0 = ( (Number) data[0]).doubleValue();
- d1 = ( (Number) data[1]).doubleValue();
- if (d0 > d1) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- else {
- if (! (data[1] instanceof String)) {
- throw new PainterException("gt: wrong arguments");
- }
- String s0, s1;
- s0 = (String) data[0];
- s1 = (String) data[1];
- if (s0.compareTo(s1) > 0) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- }
- });
- // ge
- systemDict.put("ge", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("ge: wrong arguments");
- }
- if (data[0] instanceof Number) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("ge: wrong arguments");
- }
- double d0, d1;
- d0 = ( (Number) data[0]).doubleValue();
- d1 = ( (Number) data[1]).doubleValue();
- if (d0 >= d1) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- else {
- if (! (data[1] instanceof String)) {
- throw new PainterException("ge: wrong arguments");
- }
- String s0, s1;
- s0 = (String) data[0];
- s1 = (String) data[1];
- if (s0.compareTo(s1) >= 0) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- }
- });
- // ne
- systemDict.put("ne", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("ne: wrong arguments");
- }
- if (data[0] instanceof Number) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("ne: wrong arguments");
- }
- double d0, d1;
- d0 = ( (Number) data[0]).doubleValue();
- d1 = ( (Number) data[1]).doubleValue();
- if (d0 != d1) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- else {
- if (! (data[1] instanceof String)) {
- throw new PainterException("ne: wrong arguments");
- }
- String s0, s1;
- s0 = (String) data[0];
- s1 = (String) data[1];
- if (s0.equals(s1)) {
- context.operands.push(new Boolean(false));
- }
- else {
- context.operands.push(new Boolean(true));
- }
- }
- }
- });
-
- // eq
- systemDict.put("eq", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("eq: wrong arguments");
- }
- if (data[0] instanceof Number) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("eq: wrong arguments");
- }
- double d0, d1;
- d0 = ( (Number) data[0]).doubleValue();
- d1 = ( (Number) data[1]).doubleValue();
- if (d0 == d1) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- else {
- if (! (data[1] instanceof String)) {
- throw new PainterException("eq: wrong arguments");
- }
- String s0, s1;
- s0 = (String) data[0];
- s1 = (String) data[1];
- if (s0.compareTo(s1) == 0) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- }
- });
-
- // if
- systemDict.put("if", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(2);
- if (! (data[0] instanceof Boolean)) {
- throw new PainterException("if: wrong arguments");
- }
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("if: wrong arguments");
- }
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("if: wrong arguments");
- }
- if ( ( (Boolean) data[0]).booleanValue()) {
- context.engine.process(patoken);
- }
- }
- });
-
- // ifelse
- systemDict.put("ifelse", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken1, patoken2;
- data = context.popOperands(3);
- if (! (data[0] instanceof Boolean)) {
- throw new PainterException("ifelse: wrong arguments");
- }
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("ifelse: wrong arguments");
- }
- if (! (data[2] instanceof PAToken)) {
- throw new PainterException("ifelse: wrong arguments");
- }
- patoken1 = (PAToken) data[1];
- patoken2 = (PAToken) data[2];
- if (! (patoken1.type == PAToken.PROCEDURE)) {
- throw new PainterException("ifelse: wrong arguments");
- }
- if (! (patoken2.type == PAToken.PROCEDURE)) {
- throw new PainterException("ifelse: wrong arguments");
- }
- if ( ( (Boolean) data[0]).booleanValue()) {
- context.engine.process(patoken1);
- }
- else {
- context.engine.process(patoken2);
- }
- }
- });
-
- // dict
- systemDict.put("dict", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new HashMap( (int) data[0]));
- }
- });
-
- // put
- systemDict.put("put", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(3);
- if ( (data[0] instanceof HashMap) && (data[1] instanceof PAToken)) {
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("put: wrong arguments");
- }
- ( (HashMap) data[0]).put(patoken.value, data[2]);
- }
- else
- if ( (data[0] instanceof ArrayList) && (data[1] instanceof Number)) {
- ArrayList ar = (ArrayList) data[0];
- Number nr = (Number) data[1];
- ar.set(nr.intValue(), data[2]);
- }
- else
- if ( (data[0] instanceof StringBuffer) && (data[1] instanceof Number) &&
- (data[2] instanceof Number)) {
- StringBuffer text = (StringBuffer) data[0];
- Number nr = (Number) data[1];
- Number ch = (Number) data[2];
- text.setCharAt(nr.intValue(), (char) (ch.intValue()));
- }
- else {
- throw new PainterException("put: wrong arguments");
- }
- }
- });
-
- // get
- systemDict.put("get", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(2);
- if (! (data[0] instanceof HashMap) && ! (data[0] instanceof ArrayList)) {
- throw new PainterException("get: wrong arguments");
- }
- if (data[0] instanceof HashMap) {
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("get: wrong arguments");
- }
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("get: wrong arguments");
- }
- context.operands.push( ( (HashMap) data[0]).get(patoken.value));
- }
- else if (data[0] instanceof ArrayList) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("get: wrong arguments");
- }
- context.operands.push( ( (ArrayList) data[0]).get( ( (Number) data[1]).
- intValue()));
- }
- }
- });
- // getinterval
- systemDict.put("getinterval", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(3);
- if (! (data[0] instanceof HashMap) && ! (data[0] instanceof ArrayList)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- if (data[0] instanceof HashMap) {
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- if (! (data[2] instanceof Number)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- HashMap target = new HashMap();
- context.operands.push( ( (HashMap) data[0]).get(patoken.value));
- }
- else if (data[0] instanceof ArrayList) {
- if (! (data[1] instanceof Number)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- if (! (data[2] instanceof Number)) {
- throw new PainterException("getinterval: wrong arguments");
- }
- ArrayList source = ( (ArrayList) data[0]);
- int from = ( (Number) data[1]).intValue();
- int to = from + ( (Number) data[2]).intValue();
- ArrayList target = new ArrayList(source.subList(from, to));
- context.operands.push(target);
- }
- }
- });
- // load
- systemDict.put("load", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("load: wrong arguments");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("load: wrong arguments");
- }
- context.operands.push(context.findIdentifier(patoken.value));
- }
- });
-
- // length
- systemDict.put("length", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- int size = 0;
- data = context.popOperands(1);
- if (data[0] instanceof PAToken) {
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("length: wrong arguments");
- }
- size = ( (String) patoken.value).length();
- }
- else if (data[0] instanceof HashMap) {
- size = ( (HashMap) data[0]).size();
- }
- else if (data[0] instanceof ArrayList) {
- size = ( (ArrayList) data[0]).size();
- }
- else if (data[0] instanceof String) {
- size = ( (String) data[0]).length();
- }
- else {
- throw new PainterException("length: wrong arguments");
- }
-
- context.operands.push(new Integer(size));
- }
- });
-
- // begin
- systemDict.put("begin", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof HashMap)) {
- throw new PainterException("begin: wrong arguments");
- }
- context.dictionaries.push(data[0]);
- }
- });
-
- // end
- systemDict.put("end", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- try {
- context.dictionaries.pop();
- }
- catch (EmptyStackException e) {
- throw new PainterException("Dictionary stack is empty");
- }
- }
- });
-
- // undef
- systemDict.put("undef", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(2);
- if (! (data[0] instanceof HashMap)) {
- throw new PainterException("undef: wrong arguments");
- }
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("undef: wrong arguments");
- }
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("undef: wrong arguments");
- }
- // we don't do an actual undef because we don't care
- }
- });
-
- // known
- systemDict.put("known", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[], foundObject;
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("known: wrong arguments");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("known: wrong arguments");
- }
- foundObject = context.findIdentifier(patoken.value);
- if (foundObject != null) {
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- });
-
- // where
- systemDict.put("where", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[], foundObject;
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("where: wrong arguments");
- }
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.KEY)) {
- throw new PainterException("where: wrong arguments");
- }
- foundObject = context.findDictionary(patoken.value);
- if (foundObject != null) {
- context.operands.push(foundObject);
- context.operands.push(new Boolean(true));
- }
- else {
- context.operands.push(new Boolean(false));
- }
- }
- });
-
- // aload
- systemDict.put("aload", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object[] data;
- java.util.AbstractList list;
- data = context.popOperands(1);
- if (data[0] instanceof PAToken) {
- data[0] = ( (PAToken) data[0]).value;
- }
- if (! (data[0] instanceof java.util.AbstractList)) {
- throw new PainterException("aload: wrong arguments");
- }
-
- list = (java.util.AbstractList) data[0];
- Iterator iterator = list.iterator();
- while (iterator.hasNext()) {
- context.operands.push(iterator.next());
- }
- context.operands.push(data[0]);
- }
- });
-
- // forall
- systemDict.put("forall", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- ArrayList list;
- PAToken patoken;
-
- data = context.popOperands(2);
- if (! (data[0] instanceof ArrayList)) {
- throw new PainterException("forall: wrong arguments");
- }
- if (! (data[1] instanceof PAToken)) {
- throw new PainterException("forall: wrong arguments");
- }
-
- patoken = (PAToken) data[1];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("forall: wrong arguments");
- }
-
- list = (ArrayList) data[0];
- Iterator iterator = list.iterator();
- while (iterator.hasNext()) {
- context.operands.push(iterator.next());
- context.engine.process(patoken);
- }
-
- }
- });
-
- // currentflat PENDING(uweh):placeholder for now
- systemDict.put("currentflat", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- context.operands.push(new Double(1.0f));
- }
- });
-
- // setflat PENDING(uweh):placeholder for now
- systemDict.put("setflat", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double[] data;
- data = context.popNumberOperands(1);
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- cb.setFlatness( ( (float) data[0]));
- }
- });
-
- // round
- systemDict.put("round", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Long(Math.round(data[0])));
- }
- });
-
- // abs
- systemDict.put("abs", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- data = context.popNumberOperands(1);
- context.operands.push(new Double(Math.abs(data[0])));
- }
- });
-
- // transform
- systemDict.put("transform", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (context.peekOperand() instanceof Number) {
- double data[];
- double[] transformedData = new double[2];
- data = context.popNumberOperands(2);
- AffineTransform at = context.pencil.graphics.getTransform();
- at.transform(data, 0, transformedData, 0, 1);
- context.operands.push(new Double(transformedData[0]));
- context.operands.push(new Double(transformedData[1]));
- }
- else {
- Object data[];
-
- data = context.popOperands(3);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("transform: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("transform: wrong arguments");
- }
- if (! (data[2] instanceof ArrayList)) {
- throw new PainterException("transform: wrong arguments");
- }
-
- ArrayList array = (ArrayList) data[2];
-
- double[] entries = new double[6];
-
- if (! (array.size() == 6)) {
- throw new PainterException("transform: wrong arguments");
- }
-
- for (int i = 0; i < 6; i++) {
- entries[i] = ( (Number) array.get(i)).doubleValue();
- }
-
- AffineTransform at = new AffineTransform(entries);
-
- double numberdata[] = new double[2];
- numberdata[0] = ( (Number) data[0]).doubleValue();
- numberdata[1] = ( (Number) data[1]).doubleValue();
-
- double[] transformedData = new double[2];
-
- at.transform(numberdata, 0, transformedData, 0, 1);
- context.operands.push(new Double(transformedData[0]));
- context.operands.push(new Double(transformedData[1]));
- }
- }
- });
-
- // itransform
- systemDict.put("itransform", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (context.peekOperand() instanceof Number) {
- double data[];
- double[] transformedData = new double[2];
- data = context.popNumberOperands(2);
- AffineTransform at = context.pencil.graphics.getTransform();
- try {
- at.inverseTransform(data, 0, transformedData, 0, 1);
- }
- catch (NoninvertibleTransformException e) {
- throw new PainterException(e.toString());
- }
- context.operands.push(new Double(transformedData[0]));
- context.operands.push(new Double(transformedData[1]));
- }
- else {
- Object data[];
-
- data = context.popOperands(3);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("itransform: wrong arguments");
- }
- if (! (data[1] instanceof Number)) {
- throw new PainterException("itransform: wrong arguments");
- }
- if (! (data[2] instanceof ArrayList)) {
- throw new PainterException("itransform: wrong arguments");
- }
-
- ArrayList array = (ArrayList) data[2];
-
- double[] entries = new double[6];
-
- if (! (array.size() == 6)) {
- throw new PainterException("itransform: wrong arguments");
- }
-
- for (int i = 0; i < 6; i++) {
- entries[i] = ( (Number) array.get(i)).doubleValue();
- }
-
- AffineTransform at = new AffineTransform(entries);
-
- double numberdata[] = new double[2];
- numberdata[0] = ( (Number) data[0]).doubleValue();
- numberdata[1] = ( (Number) data[0]).doubleValue();
-
- double[] transformedData = new double[2];
-
- try {
- at.inverseTransform(numberdata, 0, transformedData, 0, 1);
- }
- catch (NoninvertibleTransformException e) {
- throw new PainterException(e.toString());
- }
- context.operands.push(new Double(transformedData[0]));
- context.operands.push(new Double(transformedData[1]));
- }
- }
- });
-
- // currentpoint
- // PENDING(uweh): what about CTM, same thing when you construct path
- // this is different than ps, might not work in a few instances
- systemDict.put("currentpoint", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Point2D currentPoint = context.pencil.state.path.getCurrentPoint();
- context.operands.push(new Double(currentPoint.getX()));
- context.operands.push(new Double(currentPoint.getY()));
- }
- });
-
- // clippath
- systemDict.put("clippath", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.clippath();
- }
- });
-
- // matrix
- systemDict.put("matrix", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- ArrayList identityMatrix = new ArrayList(6);
-
- identityMatrix.add(new Double(1.0d));
- identityMatrix.add(new Double(0.0d));
- identityMatrix.add(new Double(0.0d));
- identityMatrix.add(new Double(1.0d));
- identityMatrix.add(new Double(0.0d));
- identityMatrix.add(new Double(0.0d));
- context.operands.push(identityMatrix);
- }
- });
-
- // concatmatrix
- systemDict.put("concatmatrix", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(3);
- if (! (data[0] instanceof ArrayList)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
- if (! (data[1] instanceof ArrayList)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
- if (! (data[2] instanceof ArrayList)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
- ArrayList arrayOne, arrayTwo, arrayThree;
- AffineTransform atOne, atTwo;
-
- arrayOne = (ArrayList) data[0];
- arrayTwo = (ArrayList) data[1];
- arrayThree = (ArrayList) data[2];
-
- double[] entries = new double[6];
-
- if (! (arrayOne.size() == 6)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
- if (! (arrayTwo.size() == 6)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
- if (! (arrayThree.size() == 6)) {
- throw new PainterException("concatmatrix: wrong arguments");
- }
-
- for (int i = 0; i < 6; i++) {
- entries[i] = ( (Number) arrayOne.get(i)).doubleValue();
- }
- atOne = new AffineTransform(entries);
- for (int i = 0; i < 6; i++) {
- entries[i] = ( (Number) arrayTwo.get(i)).doubleValue();
- }
- atTwo = new AffineTransform(entries);
-
- atOne.concatenate(atTwo);
-
- atOne.getMatrix(entries);
- for (int i = 0; i < 6; i++) {
- arrayThree.set(i, new Double(entries[i]));
- }
- context.operands.push(arrayThree);
- }
- });
-
- // pathbbox
- systemDict.put("pathbbox", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Rectangle2D pathBounds = context.pencil.state.path.getBounds2D();
-
- context.operands.push(new Double(pathBounds.getMinX()));
- context.operands.push(new Double(pathBounds.getMinY()));
- context.operands.push(new Double(pathBounds.getMaxX()));
- context.operands.push(new Double(pathBounds.getMaxY()));
- }
- });
-
- // initmatrix
- systemDict.put("initmatrix", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
-// cb.transform(Affine);
- }
- });
- // initclip
- systemDict.put("initclip", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- context.pencil.clippath();
-// pdfg2d.setClip(context.);
-// if(!PAContext.IgnoreUnknownCommands)
-// throw new UnsupportedOperationException("initclip");
- }
- });
-
- // truncate
- systemDict.put("truncate", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
- double truncated;
-
- data = context.popNumberOperands(1);
- if (data[0] < 0) {
- truncated = Math.ceil(data[0]);
- }
- else {
- truncated = Math.floor(data[0]);
- }
- context.operands.push(new Double(truncated));
- }
- });
-
- // rand
- systemDict.put("rand", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(new Integer(Math.abs(randomNumberGenerator.
- nextInt( (1 << 31) - 1))));
- }
- });
-
- // srand
- systemDict.put("srand", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- double data[];
-
- data = context.popNumberOperands(1);
- randomNumberGenerator = new Random(Math.round(data[0]));
- }
- });
- // version
- systemDict.put("version", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push("2016");
- }
- });
- // cvi
- systemDict.put("cvi", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(1);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("cvi: wrong arguments");
- }
- if (data[0] instanceof Number) {
- int d;
-
- d = ( (Number) data[0]).intValue();
- context.operands.push(new Integer(d));
- }
- else {
- String s;
- s = (String) data[0];
-
- context.operands.push(new Integer(s));
- }
- }
- });
- // cvr
- systemDict.put("cvr", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(1);
- if (! (data[0] instanceof Number) && ! (data[0] instanceof String)) {
- throw new PainterException("cvr: wrong arguments");
- }
- if (data[0] instanceof Number) {
- int d;
-
- d = ( (Number) data[0]).intValue();
- context.operands.push(new Double(d));
- }
- else {
- String s;
- s = (String) data[0];
-
- context.operands.push(new Double(s));
- }
- }
- });
- // usertime
- systemDict.put("usertime", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(new Long(System.currentTimeMillis()));
- }
- });
-// save
- systemDict.put("save", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- cb.saveState();
- context.operands.push(new Long(0));
- }
- });
-// restore
- systemDict.put("restore", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- cb.restoreState();
- Object data[];
- data = context.popOperands(1);
- }
- });
-// clear
- systemDict.put("clear", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.clear();
- }
- });
- // readonly
- systemDict.put("readonly", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- }
- });
-
-// currentfile
- systemDict.put("currentfile", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- final JavaCharStream jcs=context.poorscript.jj_input_stream;
- InputStream ins=new InputStream(){
- /**
- * Reads the next byte of data from the input stream.
- *
- * @return the next byte of data, or <code>-1</code> if the end of the stream is reached.
- * @throws IOException if an I/O error occurs.
- * @todo Implement this java.io.InputStream method
- */
- public int read() throws IOException {
- return jcs.readChar();
- }
-
- };
- context.operands.push(ins);
- }
- });
- // flushfile
- systemDict.put("flushfile", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof InputStream)) {
- throw new PainterException("flushfile: wrong arguments");
- }
-
- InputStream is = (InputStream) data[0];
- try {
- while (is.read() != -1) {
- }
- }
- catch (IOException ex) {
- }
- }
- });
-
- // closefile
- systemDict.put("closefile", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof InputStream)) {
- throw new PainterException("closefile: wrong arguments");
- }
-
- InputStream is = (InputStream) data[0];
- try {
- is.close();
- }
- catch (IOException ex) {
- }
- }
- });
-
- // string
- systemDict.put("string", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (! (data[0] instanceof Number)) {
- throw new PainterException("string: wrong arguments");
- }
- int d;
- d = ( (Number) data[0]).intValue();
- StringBuffer sb = new StringBuffer(d);
- sb.setLength(d);
- context.operands.push(sb);
- }
- });
- // null
- systemDict.put("null", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(null);
- }
- });
- // currentscreen
- systemDict.put("currentscreen", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- if (!PAContext.IgnoreUnknownCommands) {
- throw new UnsupportedOperationException("currentscreen");
- }
- else {
- context.operands.push(new Double(60));
- context.operands.push(new Double(0));
- context.operands.push(new Double(0));
- }
- }
- });
- // setscreen
- systemDict.put("setscreen", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(3);
-
-// if (!PAContext.IgnoreUnknownCommands)
-// throw new UnsupportedOperationException("setscreen");
-// else {
-//
-// }
- }
- });
-
- // flattenpath
- systemDict.put("flattenpath", new PACommand() {
- public void execute(PAContext context) throws PainterException {
-
- }
- });
- // filter
- systemDict.put("filter", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- String filtername;
- filtername = (String) ( (PAToken) context.popOperands(1)[0]).value;
- Object obj;
- while (! ( (obj = context.peekOperand()) instanceof InputStream)) {
- Object param = context.popOperands(1);
- }
-
- InputStream datasrc;
- datasrc = (InputStream) (context.popOperands(1)[0]);
-
- InputStream dis;
- if (filtername.equals("ASCIIHexDecode")) {
- // dis = new ASCIIHexInputStream(datasrc);
- final InputStream is=datasrc;
- dis=new InputStream(){
-
- /**
- * Reads the next byte of data from the input stream.
- *
- * @return the next byte of data, or <code>-1</code> if the end of the stream is reached.
- * @throws IOException if an I/O error occurs.
- * @todo Implement this java.io.InputStream method
- */
- public int read() throws IOException {
- int firstchar,secondchar;
- for(;;){
- firstchar=is.read();
- if(firstchar==-1)return -1;
- if(firstchar=='>')return -1;
- if(firstchar=='\n')continue;
- if(firstchar=='\r')continue;
- break;
- }
- for(;;){
- secondchar=is.read();
- if(secondchar=='>')return -1;
- if(secondchar==-1)return -1;
- if(secondchar=='\n')continue;
- if(secondchar=='\r')continue;
- break;
- }
- int highbyte=0;
- if(firstchar>=48&&firstchar<=57)highbyte=firstchar-48;
- if(firstchar>=65&&firstchar<=70)highbyte=firstchar-55;
- int lowbyte=0;
- if(secondchar>=48&&secondchar<=57)lowbyte=secondchar-48;
- if(secondchar>=65&&secondchar<=70)lowbyte=secondchar-55;
-
- return(highbyte*16+lowbyte);
- }
- };
- }
-// else
-// if (filtername.equals("DCTDecode")) {
-// dis = new DCTInputStream(datasrc);
-// }
- else {
- dis = datasrc;
- }
-
- context.operands.push(dis);
- }
- });
- // clip
- systemDict.put("clip", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.pencil.clip();
- }
- });
- // setcolorspace
- systemDict.put("setcolorspace", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- Object data[];
- data = context.popOperands(1);
- if (data[0] instanceof PAToken) {
- String colorspace = ( (String) ( (PAToken) data[0]).value);
- cb.setDefaultColorspace(PdfName.COLORSPACE, PdfName.DEVICERGB);
-
- }
- }
- });
- // image
- systemDict.put("image", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- PdfGraphics2D pdfg2d = (PdfGraphics2D) context.pencil.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- Object data[];
- data = context.popOperands(1);
- if (data[0] instanceof Number) {
- /**
- * Level1 image
- */
- int width = ( (Number) data[0]).intValue();
- data = context.popOperands(4);
- int height = ( (Number) data[0]).intValue();
- int bits = ( (Number) data[1]).intValue();
-
- }else if (data[0] instanceof PAToken) {
- PAToken proc = (PAToken) data[0];
-
- data = context.popOperands(4);
- int width = ( (Number) data[0]).intValue();
- int height = ( (Number) data[1]).intValue();
- int bitspercomponent = ( (Number) data[2]).intValue();
- ArrayList ar = (ArrayList) data[3];
- System.out.println("I " + width + "*" + height + " " +
- bitspercomponent + " " + ar);
-
-// context.engine.process(proc);
- }
- else if (data[0] instanceof HashMap){
- HashMap hsm = (HashMap) data[0];
- Iterator it = hsm.keySet().iterator();
- int width = 0, height = 0, bitspercomponent = 0;
- int imagetype = 0;
- InputStream datasrc = null;
- Object decode = null;
- Object imagematrix = null;
- while (it.hasNext()) {
- PAToken token = (PAToken) it.next();
- if (token.value.toString().equals("ImageType")) {
- imagetype = ( (Number) hsm.get(token)).intValue();
- }
- if (token.value.toString().equals("DataSource")) {
- datasrc = (InputStream) hsm.get(token);
- }
-
- if (token.value.toString().equals("BitsPerComponent")) {
- bitspercomponent = ( (Number) hsm.get(token)).intValue();
- }
- if (token.value.toString().equals("Width")) {
- width = ( (Number) hsm.get(token)).intValue();
- }
- if (token.value.toString().equals("Height")) {
- height = ( (Number) hsm.get(token)).intValue();
- }
- if (token.value.toString().equals("Decode")) {
- decode = ( (Object) hsm.get(token));
- }
- if (token.value.toString().equals("ImageMatrix")) {
- imagematrix = ( (Object) hsm.get(token));
- }
- }
-
- try {
- byte[] barr = {};
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- int aByte;
- while ( (aByte = datasrc.read()) >= 0) {
- bout.write(aByte);
-// System.out.print((char)aByte);
- }
- System.out.println("I " + width + "*" + height + " " +
- bitspercomponent + " " + imagetype + " " +
- decode + " " + imagematrix + " " + datasrc);
- barr = bout.toByteArray();
-// com.lowagie.text.Image img = new ImgRaw(width, height, 1,
-// bitspercomponent, barr);
- com.lowagie.text.Image img = new Jpeg(barr);
- try {
- cb.addImage(img,width,0,0,height,0,0);
- }
- catch (DocumentException ex1) {
- ex1.printStackTrace();
- }
- }
- catch (IOException ex) {
- ex.printStackTrace();
- }
- catch (BadElementException ex) {
- ex.printStackTrace();
- }
-
- }
- }
- });
-
- // imagemask
- systemDict.put("imagemask", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(5);
-// if (data[0] instanceof PAToken) {
-// PAToken token = (PAToken) data[0];
-// context.engine.process(token);
-// }
- }
- });
-
-
- // exec
- systemDict.put("exec", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- data = context.popOperands(1);
- if (data[0] instanceof PAToken) {
- PAToken token = (PAToken) data[0];
- context.engine.process(token);
- }
- }
- });
- // currentdict
- systemDict.put("currentdict", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.operands.push(context.dictionaries.peek());
- }
- });
-
-// cleardictstack
- systemDict.put("cleardictstack", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- context.dictionaries.clear();
- HashMap systemDict = context.constructSystemDict();
- context.dictionaries.push(systemDict);
- HashMap globalDict = context.constructGlobalDict();
- context.dictionaries.push(globalDict);
- HashMap userDict = context.constructUserDict();
- systemDict.put("userdict", userDict);
- systemDict.put("globaldict", globalDict);
- context.dictionaries.push(userDict);
- }
- });
-
- // charpath
- systemDict.put("charpath", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
-
- data = context.popOperands(2);
- if (! (data[0] instanceof String)) {
- throw new PainterException("charpath: wrong arguments");
- }
- if (! (data[1] instanceof Boolean)) {
- throw new PainterException("charpath: wrong arguments");
- }
-
- context.pencil.charpath( (String) data[0],
- ( (Boolean) data[1]).booleanValue());
- }
- });
-
- // PENDING(uweh): we only support procedure right now and always push false on the stack
- // stopped
- systemDict.put("stopped", new PACommand() {
- public void execute(PAContext context) throws PainterException {
- Object data[];
- PAToken patoken;
- data = context.popOperands(1);
- if (! (data[0] instanceof PAToken)) {
- throw new PainterException("stopped: wrong arguments");
- }
-
- patoken = (PAToken) data[0];
- if (! (patoken.type == PAToken.PROCEDURE)) {
- throw new PainterException("stopped: wrong arguments");
- }
- context.engine.process(patoken);
- context.operands.push(new Boolean(false));
- }
- });
- systemDict.put("systemdict", systemDict);
- return systemDict;
- }
-
- /**
- * <p>Title: </p>
- *
- * <p>Description: </p>
- *
- * <p>Copyright: Copyright (c) 2006</p>
- *
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
- */
- private class NamedInputStream extends InputStream{
- public String filename;
- InputStream in;
- NamedInputStream(InputStream in,String filename) {
- super();
- this.filename=filename;
- this.in=in;
- }
- public int read() throws IOException {
- return in.read();
- }
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAEngine.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAEngine.java
deleted file mode 100644
index e905402..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAEngine.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-import java.util.*;
-
-
-public class PAEngine extends Object {
-
- static public final int MODE_STACK = 0;
- static public final int MODE_PROCEDURE = 1;
- static public final int MODE_ARRAY = 2;
-
- protected PAContext context;
- protected int mode;
- protected Stack procedure;
- protected int innerProcedures;
-
- public PAEngine(PAContext context){
- super();
- this.context = context;
- this.mode = PAEngine.MODE_STACK;
- }
-
- public void startProcedure() throws PainterException {
- this.procedure = new Stack();
- this.mode = PAEngine.MODE_PROCEDURE;
- this.innerProcedures = 0;
- }
-
- public void endProcedure() throws PainterException {
- this.context.operands.push(new PAToken(this.procedure, PAToken.PROCEDURE));
- this.mode = PAEngine.MODE_STACK;
- }
-
- public void bindProcedure(PAToken patoken){
- Stack oldStack = (Stack) patoken.value;
- Stack newStack = new Stack();
- int i,n;
- n = oldStack.size();
- for(i = 0; i < n; i++){
- Object token = oldStack.elementAt(i);
- if((token instanceof PAToken) && ((PAToken) token).type == PAToken.IDENTIFIER){
- Object foundToken = this.context.findIdentifier(((PAToken) token).value);
- if(foundToken == null){
- newStack.push(token);
- } else {
- newStack.push(foundToken);
- }
- } else {
- newStack.push(token);
- }
- }
- patoken.value = newStack;
- }
-
- public void process(Object token) throws PainterException {
- if(token == null){
- throw new IllegalStateException("Null token encountered; last unknown identifier was " + this.context.getLastUnknownIdentifier()+" at line "+this.context.poorscript.token.beginLine);
- }
- if(PAContext.DebugExecution){
- System.out.print("==>" + token.toString());
-// System.out.flush();
- }
- if(token instanceof PAToken && ((PAToken) token).type == PAToken.IMMEDIATE){
- Object foundValue = this.context.findIdentifier(((PAToken) token).value);
- this.process(foundValue);
- return;
- }
- if(this.mode == MODE_STACK){
- if(token instanceof PACommand){
- ((PACommand) token).execute(this.context);
- } else if(token instanceof PAToken){
- PAToken patoken = (PAToken) token;
-
- switch(patoken.type){
- case PAToken.IDENTIFIER:
- this.process(this.context.findIdentifier(patoken.value));
- break;
- case PAToken.KEY:
- case PAToken.MARK:
- case PAToken.START_ARRAY:
- this.context.operands.push(token);
- break;
- case PAToken.PROCEDURE:
- Enumeration enumx = ((Vector) patoken.value).elements();
- while(enumx.hasMoreElements()){
- this.process(enumx.nextElement());
- }
- break;
- case PAToken.START_PROCEDURE:
- this.startProcedure();
- break;
- case PAToken.END_ARRAY:
- this.context.collectArray();
- break;
- case PAToken.START_DICT:
- this.context.operands.push(token);
- break;
- case PAToken.END_DICT:
- this.context.collectDict();
- break;
- default:
- throw new IllegalStateException("Unknown token encountered" + token);
- }
- } else {
- this.context.operands.push(token);
- }
- } else if(this.mode == MODE_PROCEDURE){
- if(token instanceof PAToken){
- PAToken patoken = (PAToken) token;
-
- switch(patoken.type){
- case PAToken.START_PROCEDURE:
- this.innerProcedures++;
- this.procedure.push(token);
- break;
- case PAToken.END_PROCEDURE:
- if(this.innerProcedures > 0){
- this.innerProcedures--;
- this.procedure.push(token);
- } else {
- this.endProcedure();
- }
- break;
- default:
- this.procedure.push(token);
- }
- } else {
- this.procedure.push(token);
- }
- }
- }
-
- public String litMode(){
- switch(this.mode){
- case MODE_ARRAY: return "Array";
- case MODE_PROCEDURE: return "Proc"+innerProcedures;
- case MODE_STACK: return "Stack";
- default: return "Unknown";
- }
- }
-
-}
-
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParser.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParser.java
deleted file mode 100644
index 3c2c64a..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParser.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. PAParser.java */
-package com.lowagie.text.pdf.codec.postscript;
-
-import java.lang.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.geom.*;
-import java.awt.color.*;
-import java.awt.font.*;
-import java.io.*;
-import java.net.URL;
-
-public class PAParser extends Object implements PAParserConstants {
-
- void error_skipto(int kind) throws ParseException {
-ParseException e=generateParseException();
-Token t;
-String dump="";
-do{
-if(getToken(1).kind==kind)break;
-t=getNextToken();
-dump+=t.image;
-}while(t.kind!=kind);
-System.out.println("Ignoriere >"+dump+"<");
- }
-
- String ExceptionString(String hint,JavaCharStream jj_input_stream,PAContext context,Token t,Exception e) throws ParseException {
- return "\nparser "+hint+" ["+jj_input_stream.bufpos+"]"+context.engine.litMode()+":\""+t.image+"\" in line "+t.beginLine+" column "+t.beginColumn+"\n"+e.toString();
- }
-
- final public void parse(PAContext context) throws ParseException {
- Token x = null;
- try {
- label_1:
- while (true) {
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case KEY_IDENTIFIER:
- case IMMEDIATE_IDENTIFIER:
- case LBRACE:
- case RBRACE:
- case LBRACKET:
- case RBRACKET:
- case LDICT:
- case RDICT:
- case Instring:
- ;
- break;
- default:
- jj_la1[0] = jj_gen;
- break label_1;
- }
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INTEGER_LITERAL:
- case FLOATING_POINT_LITERAL:
- case STRING_LITERAL:
- case IDENTIFIER:
- case KEY_IDENTIFIER:
- case IMMEDIATE_IDENTIFIER:
- case Instring:
- switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
- case INTEGER_LITERAL:
- x = jj_consume_token(INTEGER_LITERAL);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new Integer(x.image));
- } catch(NumberFormatException e) {
- {if (true) throw new ParseException(ExceptionString("int_literal",jj_input_stream,context,token,e));}
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("int_literal",jj_input_stream,context,token,e));}
- }
- break;
- case FLOATING_POINT_LITERAL:
- x = jj_consume_token(FLOATING_POINT_LITERAL);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new Double(x.image));
- } catch(NumberFormatException e) {
- {if (true) throw new ParseException(ExceptionString("float_literal",jj_input_stream,context,token,e));}
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("float_literal",jj_input_stream,context,token,e));}
- }
- break;
- case Instring:
- jj_consume_token(Instring);
- x = jj_consume_token(HEX_STRING_LITERAL);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process((x.image.substring(1, x.image.length() -1)));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("hex_string_literal",jj_input_stream,context,token,e));}
- }
- break;
- case STRING_LITERAL:
- x = jj_consume_token(STRING_LITERAL);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(x.image.substring(1, x.image.length() -1));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("string_literal",jj_input_stream,context,token,e));}
- }
- break;
- case IDENTIFIER:
- x = jj_consume_token(IDENTIFIER);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(x.image, PAToken.IDENTIFIER));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("identifier",jj_input_stream,context,token,e));}
- }
- break;
- case KEY_IDENTIFIER:
- x = jj_consume_token(KEY_IDENTIFIER);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(x.image.substring(1, x.image.length()), PAToken.KEY));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("key_identifier",jj_input_stream,context,token,e));}
- }
- break;
- case IMMEDIATE_IDENTIFIER:
- x = jj_consume_token(IMMEDIATE_IDENTIFIER);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+x.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(x.image.substring(2, x.image.length()), PAToken.IMMEDIATE));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("immediate_identifier",jj_input_stream,context,token,e));}
- }
- break;
- default:
- jj_la1[1] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
- case LBRACE:
- jj_consume_token(LBRACE);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.START_PROCEDURE));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("lbrace",jj_input_stream,context,token,e));}
- }
- break;
- case RBRACE:
- jj_consume_token(RBRACE);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.END_PROCEDURE));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("rbrace",jj_input_stream,context,token,e));}
- }
- break;
- case LBRACKET:
- jj_consume_token(LBRACKET);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.START_ARRAY));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("lbracket",jj_input_stream,context,token,e));}
- }
- break;
- case RBRACKET:
- jj_consume_token(RBRACKET);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.END_ARRAY));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("rbracket",jj_input_stream,context,token,e));}
- }
- break;
- case LDICT:
- jj_consume_token(LDICT);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.START_DICT));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("ldict",jj_input_stream,context,token,e));}
- }
- break;
- case RDICT:
- jj_consume_token(RDICT);
- try {
- {if(PAContext.DebugExecution){System.out.print("\nparser ["+jj_input_stream.getBeginLine()+","+jj_input_stream.getBeginColumn()+"]"+context.engine.litMode()+":\""+token.image+"\"");System.out.flush();System.err.flush();}}
- context.engine.process(new PAToken(null, PAToken.END_DICT));
- } catch(PainterException e) {
- {if (true) throw new ParseException(ExceptionString("rdict",jj_input_stream,context,token,e));}
- }
- break;
- default:
- jj_la1[2] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- } catch (ParseException e) {
- System.out.flush();System.err.flush();
- //System.out.println("Fehlerhaftes Element in Spalte "+e.currentToken.beginColumn+" in Eingabedatei in Zeile="+e.currentToken.next.beginLine+" in Zeichen Nr. "+e.currentToken.next.beginColumn+". >"+e.currentToken.next.image+"< wurde hier nicht erwartet.");
- //System.err.println("Fehler:"+e);
- e.printStackTrace();
- error_skipto(WHITESPACE);
- System.exit(0);
- }
- }
-
- public PAParserTokenManager token_source;
- JavaCharStream jj_input_stream;
- public Token token, jj_nt;
- private int jj_ntk;
- private int jj_gen;
- final private int[] jj_la1 = new int[3];
- final private int[] jj_la1_0 = {0x13f3d20,0x1003d20,0x13f3d20,};
-
- public PAParser(java.io.InputStream stream) {
- jj_input_stream = new JavaCharStream(stream, 1, 1);
- token_source = new PAParserTokenManager(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- public void ReInit(java.io.InputStream stream) {
- jj_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- public PAParser(java.io.Reader stream) {
- jj_input_stream = new JavaCharStream(stream, 1, 1);
- token_source = new PAParserTokenManager(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- public void ReInit(java.io.Reader stream) {
- jj_input_stream.ReInit(stream, 1, 1);
- token_source.ReInit(jj_input_stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- public PAParser(PAParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- public void ReInit(PAParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 3; i++) jj_la1[i] = -1;
- }
-
- final private Token jj_consume_token(int kind) throws ParseException {
- Token oldToken;
- if ((oldToken = token).next != null) token = token.next;
- else token = token.next = token_source.getNextToken();
- jj_ntk = -1;
- if (token.kind == kind) {
- jj_gen++;
- return token;
- }
- token = oldToken;
- jj_kind = kind;
- throw generateParseException();
- }
-
- final public Token getNextToken() {
- if (token.next != null) token = token.next;
- else token = token.next = token_source.getNextToken();
- jj_ntk = -1;
- jj_gen++;
- return token;
- }
-
- final public Token getToken(int index) {
- Token t = token;
- for (int i = 0; i < index; i++) {
- if (t.next != null) t = t.next;
- else t = t.next = token_source.getNextToken();
- }
- return t;
- }
-
- final private int jj_ntk() {
- if ((jj_nt=token.next) == null)
- return (jj_ntk = (token.next=token_source.getNextToken()).kind);
- else
- return (jj_ntk = jj_nt.kind);
- }
-
- private java.util.Vector jj_expentries = new java.util.Vector();
- private int[] jj_expentry;
- private int jj_kind = -1;
-
- final public ParseException generateParseException() {
- jj_expentries.removeAllElements();
- boolean[] la1tokens = new boolean[25];
- for (int i = 0; i < 25; i++) {
- la1tokens[i] = false;
- }
- if (jj_kind >= 0) {
- la1tokens[jj_kind] = true;
- jj_kind = -1;
- }
- for (int i = 0; i < 3; i++) {
- if (jj_la1[i] == jj_gen) {
- for (int j = 0; j < 32; j++) {
- if ((jj_la1_0[i] & (1<<j)) != 0) {
- la1tokens[j] = true;
- }
- }
- }
- }
- for (int i = 0; i < 25; i++) {
- if (la1tokens[i]) {
- jj_expentry = new int[1];
- jj_expentry[0] = i;
- jj_expentries.addElement(jj_expentry);
- }
- }
- int[][] exptokseq = new int[jj_expentries.size()][];
- for (int i = 0; i < jj_expentries.size(); i++) {
- exptokseq[i] = (int[])jj_expentries.elementAt(i);
- }
- return new ParseException(token, exptokseq, tokenImage);
- }
-
- final public void enable_tracing() {
- }
-
- final public void disable_tracing() {
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserConstants.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserConstants.java
deleted file mode 100644
index 828ccfe..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserConstants.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. PAParserConstants.java */
-package com.lowagie.text.pdf.codec.postscript;
-
-public interface PAParserConstants {
-
- int EOF = 0;
- int WHITESPACE = 1;
- int INTEGER_LITERAL = 5;
- int DECIMAL_LITERAL = 6;
- int HEX_LITERAL = 7;
- int FLOATING_POINT_LITERAL = 8;
- int EXPONENT = 9;
- int STRING_LITERAL = 10;
- int IDENTIFIER = 11;
- int KEY_IDENTIFIER = 12;
- int IMMEDIATE_IDENTIFIER = 13;
- int LETTER = 14;
- int DIGIT = 15;
- int LBRACE = 16;
- int RBRACE = 17;
- int LBRACKET = 18;
- int RBRACKET = 19;
- int LDICT = 20;
- int RDICT = 21;
- int Nextchar = 22;
- int HEX_STRING_LITERAL = 23;
- int Instring = 24;
-
- int DEFAULT = 0;
- int WITHINSTRING = 1;
-
- String[] tokenImage = {
- "<EOF>",
- "<WHITESPACE>",
- "<token of kind 2>",
- "<token of kind 3>",
- "<token of kind 4>",
- "<INTEGER_LITERAL>",
- "<DECIMAL_LITERAL>",
- "<HEX_LITERAL>",
- "<FLOATING_POINT_LITERAL>",
- "<EXPONENT>",
- "<STRING_LITERAL>",
- "<IDENTIFIER>",
- "<KEY_IDENTIFIER>",
- "<IMMEDIATE_IDENTIFIER>",
- "<LETTER>",
- "<DIGIT>",
- "\"{\"",
- "\"}\"",
- "\"[\"",
- "\"]\"",
- "\"<<\"",
- "\">>\"",
- "<Nextchar>",
- "\">\"",
- "\"<\"",
- };
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserTokenManager.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserTokenManager.java
deleted file mode 100644
index 9b908ba..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAParserTokenManager.java
+++ /dev/null
@@ -1,1011 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. PAParserTokenManager.java */
-package com.lowagie.text.pdf.codec.postscript;
-import java.lang.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.awt.*;
-import java.awt.geom.*;
-import java.awt.color.*;
-import java.awt.font.*;
-import java.io.*;
-import java.net.URL;
-
-public class PAParserTokenManager implements PAParserConstants
-{
- public java.io.PrintStream debugStream = System.out;
- public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_0(int pos, long active0)
-{
- switch (pos)
- {
- default :
- return -1;
- }
-}
-private final int jjStartNfa_0(int pos, long active0)
-{
- return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-private final int jjStopAtPos(int pos, int kind)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- return pos + 1;
-}
-private final int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return pos + 1; }
- return jjMoveNfa_0(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_0()
-{
- switch(curChar)
- {
- case 60:
- jjmatchedKind = 24;
- return jjMoveStringLiteralDfa1_0(0x100000L);
- case 62:
- return jjMoveStringLiteralDfa1_0(0x200000L);
- case 91:
- return jjStopAtPos(0, 18);
- case 93:
- return jjStopAtPos(0, 19);
- case 123:
- return jjStopAtPos(0, 16);
- case 125:
- return jjStopAtPos(0, 17);
- default :
- return jjMoveNfa_0(0, 0);
- }
-}
-private final int jjMoveStringLiteralDfa1_0(long active0)
-{
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) {
- jjStopStringLiteralDfa_0(0, active0);
- return 1;
- }
- switch(curChar)
- {
- case 60:
- if ((active0 & 0x100000L) != 0L)
- return jjStopAtPos(1, 20);
- break;
- case 62:
- if ((active0 & 0x200000L) != 0L)
- return jjStopAtPos(1, 21);
- break;
- default :
- break;
- }
- return jjStartNfa_0(0, active0);
-}
-private final void jjCheckNAdd(int state)
-{
- if (jjrounds[state] != jjround)
- {
- jjstateSet[jjnewStateCnt++] = state;
- jjrounds[state] = jjround;
- }
-}
-private final void jjAddStates(int start, int end)
-{
- do {
- jjstateSet[jjnewStateCnt++] = jjnextStates[start];
- } while (start++ != end);
-}
-private final void jjCheckNAddTwoStates(int state1, int state2)
-{
- jjCheckNAdd(state1);
- jjCheckNAdd(state2);
-}
-private final void jjCheckNAddStates(int start, int end)
-{
- do {
- jjCheckNAdd(jjnextStates[start]);
- } while (start++ != end);
-}
-private final void jjCheckNAddStates(int start)
-{
- jjCheckNAdd(jjnextStates[start]);
- jjCheckNAdd(jjnextStates[start + 1]);
-}
-static final long[] jjbitVec0 = {
- 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec2 = {
- 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec3 = {
- 0x1ff00000fffffffeL, 0xffffffffffffc000L, 0xffffffffL, 0x600000000000000L
-};
-static final long[] jjbitVec4 = {
- 0x0L, 0x0L, 0x0L, 0xff7fffffff7fffffL
-};
-static final long[] jjbitVec5 = {
- 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-static final long[] jjbitVec6 = {
- 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffL, 0x0L
-};
-static final long[] jjbitVec7 = {
- 0xffffffffffffffffL, 0xffffffffffffffffL, 0x0L, 0x0L
-};
-static final long[] jjbitVec8 = {
- 0x3fffffffffffL, 0x0L, 0x0L, 0x0L
-};
-private final int jjMoveNfa_0(int startState, int curPos)
-{
- int[] nextStates;
- int startsAt = 0;
- jjnewStateCnt = 74;
- int i = 1;
- jjstateSet[0] = startState;
- int j, kind = 0x7fffffff;
- for (;;)
- {
- if (++jjround == 0x7fffffff)
- ReInitRounds();
- if (curChar < 64)
- {
- long l = 1L << curChar;
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if ((0x3ff000000000000L & l) != 0L)
- {
- if (kind > 5)
- kind = 5;
- jjCheckNAddStates(0, 8);
- }
- else if ((0x100003610L & l) != 0L)
- {
- if (kind > 1)
- kind = 1;
- }
- else if ((0x8000281000000000L & l) != 0L)
- {
- if (kind > 11)
- kind = 11;
- jjCheckNAdd(21);
- }
- else if (curChar == 37)
- jjCheckNAddStates(9, 14);
- else if (curChar == 47)
- jjstateSet[jjnewStateCnt++] = 26;
- else if (curChar == 40)
- jjCheckNAddStates(15, 17);
- else if (curChar == 46)
- jjCheckNAdd(6);
- if (curChar == 45)
- jjCheckNAddStates(18, 23);
- else if (curChar == 47)
- jjCheckNAddTwoStates(23, 24);
- else if (curChar == 48)
- jjstateSet[jjnewStateCnt++] = 2;
- break;
- case 1:
- if (curChar == 48)
- jjstateSet[jjnewStateCnt++] = 2;
- break;
- case 3:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 5)
- kind = 5;
- jjCheckNAddTwoStates(3, 4);
- break;
- case 5:
- if (curChar == 46)
- jjCheckNAdd(6);
- break;
- case 6:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(24, 26);
- break;
- case 8:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(9);
- break;
- case 9:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(9, 10);
- break;
- case 11:
- if (curChar == 40)
- jjCheckNAddStates(15, 17);
- break;
- case 12:
- if ((0xfffffdffffffffffL & l) != 0L)
- jjCheckNAddStates(15, 17);
- break;
- case 14:
- if ((0x38000000400L & l) != 0L)
- jjCheckNAddStates(15, 17);
- break;
- case 15:
- if (curChar == 41 && kind > 10)
- kind = 10;
- break;
- case 16:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAddStates(27, 30);
- break;
- case 17:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAddStates(15, 17);
- break;
- case 18:
- if ((0xf000000000000L & l) != 0L)
- jjstateSet[jjnewStateCnt++] = 19;
- break;
- case 19:
- if ((0xff000000000000L & l) != 0L)
- jjCheckNAdd(17);
- break;
- case 20:
- if ((0x8000281000000000L & l) == 0L)
- break;
- if (kind > 11)
- kind = 11;
- jjCheckNAdd(21);
- break;
- case 21:
- if ((0x83ff681000000000L & l) == 0L)
- break;
- if (kind > 11)
- kind = 11;
- jjCheckNAdd(21);
- break;
- case 22:
- if (curChar == 47)
- jjCheckNAddTwoStates(23, 24);
- break;
- case 23:
- if ((0x400800000000L & l) != 0L)
- jjCheckNAdd(24);
- break;
- case 24:
- if ((0x8000281000000000L & l) == 0L)
- break;
- if (kind > 12)
- kind = 12;
- jjCheckNAdd(25);
- break;
- case 25:
- if ((0x83ff681000000000L & l) == 0L)
- break;
- if (kind > 12)
- kind = 12;
- jjCheckNAdd(25);
- break;
- case 26:
- if (curChar == 47)
- jjstateSet[jjnewStateCnt++] = 27;
- break;
- case 27:
- if ((0x8000281000000000L & l) == 0L)
- break;
- if (kind > 13)
- kind = 13;
- jjCheckNAdd(28);
- break;
- case 28:
- if ((0x83ff681000000000L & l) == 0L)
- break;
- if (kind > 13)
- kind = 13;
- jjCheckNAdd(28);
- break;
- case 29:
- if (curChar == 47)
- jjstateSet[jjnewStateCnt++] = 26;
- break;
- case 30:
- if (curChar == 37)
- jjCheckNAddStates(9, 14);
- break;
- case 31:
- if ((0xfffffffffffffbffL & l) != 0L)
- jjCheckNAddTwoStates(31, 32);
- break;
- case 32:
- if (curChar == 10 && kind > 2)
- kind = 2;
- break;
- case 33:
- if ((0xffffffffffffdfffL & l) != 0L)
- jjCheckNAddTwoStates(33, 34);
- break;
- case 34:
- if (curChar == 13 && kind > 3)
- kind = 3;
- break;
- case 35:
- if ((0xffffffffffffdfffL & l) != 0L)
- jjCheckNAddTwoStates(35, 37);
- break;
- case 36:
- if (curChar == 10 && kind > 4)
- kind = 4;
- break;
- case 37:
- if (curChar == 13)
- jjstateSet[jjnewStateCnt++] = 36;
- break;
- case 38:
- if (curChar == 45)
- jjCheckNAddStates(18, 23);
- break;
- case 39:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 5)
- kind = 5;
- jjCheckNAddTwoStates(39, 4);
- break;
- case 40:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(40, 41);
- break;
- case 41:
- if (curChar != 46)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(31, 33);
- break;
- case 42:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(31, 33);
- break;
- case 44:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(45);
- break;
- case 45:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(45, 10);
- break;
- case 46:
- if (curChar == 46)
- jjCheckNAdd(47);
- break;
- case 47:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(34, 36);
- break;
- case 49:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(50);
- break;
- case 50:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(50, 10);
- break;
- case 51:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(51, 52);
- break;
- case 53:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(54);
- break;
- case 54:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(54, 10);
- break;
- case 55:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddStates(37, 39);
- break;
- case 57:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(58);
- break;
- case 58:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(58, 10);
- break;
- case 59:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 5)
- kind = 5;
- jjCheckNAddStates(0, 8);
- break;
- case 60:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(60, 61);
- break;
- case 61:
- if (curChar != 46)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(40, 42);
- break;
- case 62:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddStates(40, 42);
- break;
- case 64:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(65);
- break;
- case 65:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(65, 10);
- break;
- case 66:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(66, 67);
- break;
- case 68:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(69);
- break;
- case 69:
- if ((0x3ff000000000000L & l) == 0L)
- break;
- if (kind > 8)
- kind = 8;
- jjCheckNAddTwoStates(69, 10);
- break;
- case 70:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddStates(43, 45);
- break;
- case 72:
- if ((0x280000000000L & l) != 0L)
- jjCheckNAdd(73);
- break;
- case 73:
- if ((0x3ff000000000000L & l) != 0L)
- jjCheckNAddTwoStates(73, 10);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else if (curChar < 128)
- {
- long l = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- case 21:
- if ((0x7fffffe87fffffeL & l) == 0L)
- break;
- if (kind > 11)
- kind = 11;
- jjCheckNAdd(21);
- break;
- case 2:
- if ((0x100000001000000L & l) != 0L)
- jjCheckNAdd(3);
- break;
- case 3:
- if ((0x7e0000007eL & l) == 0L)
- break;
- if (kind > 5)
- kind = 5;
- jjCheckNAddTwoStates(3, 4);
- break;
- case 4:
- if ((0x100000001000L & l) != 0L && kind > 5)
- kind = 5;
- break;
- case 7:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(46, 47);
- break;
- case 10:
- if ((0x5000000050L & l) != 0L && kind > 8)
- kind = 8;
- break;
- case 12:
- if ((0xffffffffefffffffL & l) != 0L)
- jjCheckNAddStates(15, 17);
- break;
- case 13:
- if (curChar == 92)
- jjAddStates(48, 50);
- break;
- case 14:
- if ((0x14404410000000L & l) != 0L)
- jjCheckNAddStates(15, 17);
- break;
- case 24:
- case 25:
- if ((0x7fffffe87fffffeL & l) == 0L)
- break;
- if (kind > 12)
- kind = 12;
- jjCheckNAdd(25);
- break;
- case 27:
- case 28:
- if ((0x7fffffe87fffffeL & l) == 0L)
- break;
- if (kind > 13)
- kind = 13;
- jjCheckNAdd(28);
- break;
- case 31:
- jjAddStates(51, 52);
- break;
- case 33:
- jjAddStates(53, 54);
- break;
- case 35:
- jjAddStates(55, 56);
- break;
- case 43:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(57, 58);
- break;
- case 48:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(59, 60);
- break;
- case 52:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(61, 62);
- break;
- case 56:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(63, 64);
- break;
- case 63:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(65, 66);
- break;
- case 67:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(67, 68);
- break;
- case 71:
- if ((0x2000000020L & l) != 0L)
- jjAddStates(69, 70);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else
- {
- int hiByte = (int)(curChar >> 8);
- int i1 = hiByte >> 6;
- long l1 = 1L << (hiByte & 077);
- int i2 = (curChar & 0xff) >> 6;
- long l2 = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- case 21:
- if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
- break;
- if (kind > 11)
- kind = 11;
- jjCheckNAdd(21);
- break;
- case 12:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(15, 17);
- break;
- case 24:
- case 25:
- if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
- break;
- if (kind > 12)
- kind = 12;
- jjCheckNAdd(25);
- break;
- case 27:
- case 28:
- if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
- break;
- if (kind > 13)
- kind = 13;
- jjCheckNAdd(28);
- break;
- case 31:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(51, 52);
- break;
- case 33:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(53, 54);
- break;
- case 35:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2))
- jjAddStates(55, 56);
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- if (kind != 0x7fffffff)
- {
- jjmatchedKind = kind;
- jjmatchedPos = curPos;
- kind = 0x7fffffff;
- }
- ++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 74 - (jjnewStateCnt = startsAt)))
- return curPos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return curPos; }
- }
-}
-private final int jjStopStringLiteralDfa_1(int pos, long active0)
-{
- switch (pos)
- {
- default :
- return -1;
- }
-}
-private final int jjStartNfa_1(int pos, long active0)
-{
- return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_1(int pos, int kind, int state)
-{
- jjmatchedKind = kind;
- jjmatchedPos = pos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return pos + 1; }
- return jjMoveNfa_1(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_1()
-{
- switch(curChar)
- {
- case 62:
- return jjStopAtPos(0, 23);
- default :
- return jjMoveNfa_1(0, 0);
- }
-}
-private final int jjMoveNfa_1(int startState, int curPos)
-{
- int[] nextStates;
- int startsAt = 0;
- jjnewStateCnt = 1;
- int i = 1;
- jjstateSet[0] = startState;
- int j, kind = 0x7fffffff;
- for (;;)
- {
- if (++jjround == 0x7fffffff)
- ReInitRounds();
- if (curChar < 64)
- {
- long l = 1L << curChar;
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if ((0xbfffffffffffffffL & l) != 0L)
- kind = 22;
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else if (curChar < 128)
- {
- long l = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- kind = 22;
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- else
- {
- int hiByte = (int)(curChar >> 8);
- int i1 = hiByte >> 6;
- long l1 = 1L << (hiByte & 077);
- int i2 = (curChar & 0xff) >> 6;
- long l2 = 1L << (curChar & 077);
- MatchLoop: do
- {
- switch(jjstateSet[--i])
- {
- case 0:
- if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 22)
- kind = 22;
- break;
- default : break;
- }
- } while(i != startsAt);
- }
- if (kind != 0x7fffffff)
- {
- jjmatchedKind = kind;
- jjmatchedPos = curPos;
- kind = 0x7fffffff;
- }
- ++curPos;
- if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
- return curPos;
- try { curChar = input_stream.readChar(); }
- catch(java.io.IOException e) { return curPos; }
- }
-}
-static final int[] jjnextStates = {
- 39, 4, 60, 61, 66, 67, 70, 71, 10, 31, 32, 33, 34, 35, 37, 12,
- 13, 15, 39, 1, 40, 46, 51, 55, 6, 7, 10, 12, 13, 17, 15, 42,
- 43, 10, 47, 48, 10, 55, 56, 10, 62, 63, 10, 70, 71, 10, 8, 9,
- 14, 16, 18, 31, 32, 33, 34, 35, 37, 44, 45, 49, 50, 53, 54, 57,
- 58, 64, 65, 68, 69, 72, 73,
-};
-private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((jjbitVec2[i2] & l2) != 0L);
- default :
- if ((jjbitVec0[i1] & l1) != 0L)
- return true;
- return false;
- }
-}
-private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
-{
- switch(hiByte)
- {
- case 0:
- return ((jjbitVec4[i2] & l2) != 0L);
- case 48:
- return ((jjbitVec5[i2] & l2) != 0L);
- case 49:
- return ((jjbitVec6[i2] & l2) != 0L);
- case 51:
- return ((jjbitVec7[i2] & l2) != 0L);
- case 61:
- return ((jjbitVec8[i2] & l2) != 0L);
- default :
- if ((jjbitVec3[i1] & l1) != 0L)
- return true;
- return false;
- }
-}
-public static final String[] jjstrLiteralImages = {
-"", null, null, null, null, null, null, null, null, null, null, null, null,
-null, null, null, "\173", "\175", "\133", "\135", "\74\74", "\76\76", null, null,
-"\74", };
-public static final String[] lexStateNames = {
- "DEFAULT",
- "WITHINSTRING",
-};
-public static final int[] jjnewLexState = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
-};
-static final long[] jjtoToken = {
- 0x1bf3d21L,
-};
-static final long[] jjtoSkip = {
- 0x1eL,
-};
-static final long[] jjtoMore = {
- 0x400000L,
-};
-private JavaCharStream input_stream;
-private final int[] jjrounds = new int[74];
-private final int[] jjstateSet = new int[148];
-StringBuffer image;
-int jjimageLen;
-int lengthOfMatch;
-protected char curChar;
-public PAParserTokenManager(JavaCharStream stream)
-{
- if (JavaCharStream.staticFlag)
- throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
- input_stream = stream;
-}
-public PAParserTokenManager(JavaCharStream stream, int lexState)
-{
- this(stream);
- SwitchTo(lexState);
-}
-public void ReInit(JavaCharStream stream)
-{
- jjmatchedPos = jjnewStateCnt = 0;
- curLexState = defaultLexState;
- input_stream = stream;
- ReInitRounds();
-}
-private final void ReInitRounds()
-{
- int i;
- jjround = 0x80000001;
- for (i = 74; i-- > 0;)
- jjrounds[i] = 0x80000000;
-}
-public void ReInit(JavaCharStream stream, int lexState)
-{
- ReInit(stream);
- SwitchTo(lexState);
-}
-public void SwitchTo(int lexState)
-{
- if (lexState >= 2 || lexState < 0)
- throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
- else
- curLexState = lexState;
-}
-
-private final Token jjFillToken()
-{
- Token t = Token.newToken(jjmatchedKind);
- t.kind = jjmatchedKind;
- String im = jjstrLiteralImages[jjmatchedKind];
- t.image = (im == null) ? input_stream.GetImage() : im;
- t.beginLine = input_stream.getBeginLine();
- t.beginColumn = input_stream.getBeginColumn();
- t.endLine = input_stream.getEndLine();
- t.endColumn = input_stream.getEndColumn();
- return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-public final Token getNextToken()
-{
- int kind;
- Token specialToken = null;
- Token matchedToken;
- int curPos = 0;
-
- EOFLoop :
- for (;;)
- {
- try
- {
- curChar = input_stream.BeginToken();
- }
- catch(java.io.IOException e)
- {
- jjmatchedKind = 0;
- matchedToken = jjFillToken();
- return matchedToken;
- }
- image = null;
- jjimageLen = 0;
-
- for (;;)
- {
- switch(curLexState)
- {
- case 0:
- jjmatchedKind = 0x7fffffff;
- jjmatchedPos = 0;
- curPos = jjMoveStringLiteralDfa0_0();
- break;
- case 1:
- jjmatchedKind = 0x7fffffff;
- jjmatchedPos = 0;
- curPos = jjMoveStringLiteralDfa0_1();
- break;
- }
- if (jjmatchedKind != 0x7fffffff)
- {
- if (jjmatchedPos + 1 < curPos)
- input_stream.backup(curPos - jjmatchedPos - 1);
- if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
- {
- matchedToken = jjFillToken();
- TokenLexicalActions(matchedToken);
- if (jjnewLexState[jjmatchedKind] != -1)
- curLexState = jjnewLexState[jjmatchedKind];
- return matchedToken;
- }
- else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
- {
- if (jjnewLexState[jjmatchedKind] != -1)
- curLexState = jjnewLexState[jjmatchedKind];
- continue EOFLoop;
- }
- jjimageLen += jjmatchedPos + 1;
- if (jjnewLexState[jjmatchedKind] != -1)
- curLexState = jjnewLexState[jjmatchedKind];
- curPos = 0;
- jjmatchedKind = 0x7fffffff;
- try {
- curChar = input_stream.readChar();
- continue;
- }
- catch (java.io.IOException e1) { }
- }
- int error_line = input_stream.getEndLine();
- int error_column = input_stream.getEndColumn();
- String error_after = null;
- boolean EOFSeen = false;
- try { input_stream.readChar(); input_stream.backup(1); }
- catch (java.io.IOException e1) {
- EOFSeen = true;
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- if (curChar == '\n' || curChar == '\r') {
- error_line++;
- error_column = 0;
- }
- else
- error_column++;
- }
- if (!EOFSeen) {
- input_stream.backup(1);
- error_after = curPos <= 1 ? "" : input_stream.GetImage();
- }
- throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
- }
- }
-}
-
-final void TokenLexicalActions(Token matchedToken)
-{
- switch(jjmatchedKind)
- {
- case 23 :
- if (image == null)
- image = new StringBuffer(new String(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1))));
- else
- image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
- matchedToken.image=image.toString().substring(0,image.toString().length()-1);
- break;
- default :
- break;
- }
-}
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAPencil.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAPencil.java
deleted file mode 100644
index 5612603..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAPencil.java
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-import java.util.*;
-import java.awt.*;
-import java.awt.font.*;
-import java.awt.geom.*;
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfGraphics2D;
-
-
-public class PAPencil {
-
- static protected class State implements Cloneable {
- public Stroke stroke;
- public Paint paint;
- public AffineTransform at;
- public Shape clipShape;
- public Font font;
- public Composite composite;
- public GeneralPath path;
-
- public State(){
- this(null);
- }
-
- public State(Graphics2D g){
- if(g == null){
- this.stroke = new BasicStroke();
- this.paint = Color.black;
- this.at = new AffineTransform();
- this.font = new Font("SansSerif", Font.PLAIN, 12);
- this.composite = AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f);
- this.clipShape = null;
- } else {
- this.recordState(g);
- }
- this.path = new GeneralPath();
- }
-
- public void recordState(Graphics2D g){
- this.stroke = g.getStroke();
- this.paint = g.getPaint();
- this.at = g.getTransform();
- this.font = g.getFont();
- this.composite = g.getComposite();
- this.clipShape = g.getClip();
- }
-
- public void stampState(Graphics2D g, Dimension size){
- g.setTransform(new AffineTransform());
- g.setClip(new Rectangle(0, 0, size.width, size.height));
- g.setStroke(this.stroke);
- g.setPaint(this.paint);
- g.setTransform(this.at);
- g.setFont(this.font);
- g.setComposite(this.composite);
- if(this.clipShape != null){
- g.clip(this.clipShape);
- }
- }
-
- public Object clone(){
- try {
- State n = (State)super.clone();
-
- n.at = (AffineTransform) this.at.clone();
- n.path = new GeneralPath();
- n.path.append(this.path, false);
- return n;
- } catch(CloneNotSupportedException e){
- throw new InternalError();
- }
- }
-
- }
-
- //
- // Class Variables
- //
-
- //
- // Instance Variables
- //
-
- /**
- * The canvas size.
- */
- protected Dimension size;
-
- /**
- * The current graphics state.
- */
- protected State state;
-
- /**
- * The stack of graphic states.
- */
- protected Stack gStack;
-
- /**
- * The font hashtable with postscript names as keys
- */
- protected HashMap fonts;
-
- /**
- * The current graphics device
- */
- public Graphics2D graphics;
-
- //
- // Constructors
- //
-
- public PAPencil(Component component){
- this.graphics = (Graphics2D) component.getGraphics();
- this.size = component.getSize();
- this.initgraphics();
- }
-
- public PAPencil(Graphics graphics, Dimension size){
- this.graphics = (Graphics2D) graphics;
- this.size = size;
- this.initgraphics();
- }
-
- //
- // Graphics state management
- //
-
- public void gsave(){
- this.state.recordState(this.graphics);
- State next = (State) this.state.clone();
-
- this.gStack.push(this.state);
- this.state = next;
- }
-
- public void grestore(){
- if(this.gStack.empty()){
- this.initgraphics();
- } else {
- this.state = (State) this.gStack.pop();
- this.state.stampState(this.graphics, this.size);
- }
- }
-
- public void grestoreall(){
- this.initgraphics();
- }
-
- public void initgraphics(){
- AffineTransform at = new AffineTransform();
- // turn anti-aliasing and high-quality rendering on
- this.graphics.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
- this.graphics.setRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
-
- // initialize to a postscript coordinate system
- at.translate(0, this.size.getHeight());
- at.scale(1, -1);
- this.graphics.setTransform(at);
- // this.graphics.translate(0, this.size.getHeight());
- // this.graphics.scale(1, -1);
-
- // state, stack and page
- this.state = new State(this.graphics);
- this.gStack = new Stack();
- this.erasepage();
- }
-
- //
- // Path definition
- //
-
- public void newpath(){
- this.state.path.reset();
- }
-
- public void moveto(double x, double y){
- this.state.path.moveTo((float) x, (float) y);
- }
-
- public void moveto(Point2D p) {
- this.moveto(p.getX(), p.getY());
- }
-
- public void rmoveto(double dx, double dy) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- this.state.path.moveTo((float) (currentPoint.getX() + dx) , (float) (currentPoint.getY() + dy));
- }
-
- public void lineto(double x, double y) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- this.state.path.lineTo((float) x, (float) y);
- }
-
- public void lineto(Point2D p) throws PainterException {
- this.lineto(p.getX(), p.getY());
- }
-
- public void rlineto(double dx, double dy) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- this.state.path.lineTo((float) (currentPoint.getX() + dx) , (float) (currentPoint.getY() + dy));
- }
-
- /**
- *
- * @param cx double Centerpoint x
- * @param cy double Centerpoint y
- * @param r double Radius r
- * @param ang1 double first angle
- * @param ang2 double second angle
- */
- public void arc(double cx, double cy, double r, double ang1, double ang2){
- Arc2D.Float arc = new Arc2D.Float((float) ( cx - r ), (float) ( cy
- - r ), (float) r * 2f, (float) r * 2f,- (float) ang1,- (float) ( ang2 -
- ang1 ), Arc2D.OPEN );
- Point2D currentPoint = this.state.path.getCurrentPoint();
- if(currentPoint == null){
- this.state.path.append(arc, false);
- } else {
- this.state.path.append(arc, true);
- }
- }
-
- public void arcn(double cx, double cy, double r, double ang1, double ang2) {
- Arc2D.Float arc = new Arc2D.Float((float) ( cx - r ), (float)
- ( cy - r ), (float) r * 2f, (float) r * 2f,- (float) ang1, -(float) (
- ang2 - ang1 ), Arc2D.OPEN );
- Point2D currentPoint = this.state.path.getCurrentPoint();
- if(currentPoint == null){
- this.state.path.append(arc, false);
- } else {
- this.state.path.append(arc, true);
- }
- }
-
- public void curveto(double x1, double y1, double x2, double y2,
- double x3, double y3) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- this.state.path.curveTo((float) x1, (float) y1, (float) x2, (float) y2,
- (float) x3, (float) y3);
- }
-
- public void rcurveto(double dx1, double dy1, double dx2, double dy2,
- double dx3, double dy3) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- double x0 = currentPoint.getX();
- double y0 = currentPoint.getY();
- this.curveto(x0 + dx1, y0 + dy1, x0 + dx2, y0 + dy2, x0 + dx3,y0 + dy3);
- }
-
- public void closepath(){
- this.state.path.closePath();
- }
-
- // PENDING(uweh): just a placeholder for now
- public void clippath(){
- this.rectpath(0.0d, 0.0d, size.width, size.height);
- }
- public void clip(){
- PdfGraphics2D pdfg2d = (PdfGraphics2D) this.graphics;
- pdfg2d.clip(this.state.path);
- this.newpath();
-// Area currentclip=new Area(this.state.clipShape);
-// Area addclip=new Area(this.state.path.createTransformedShape(AffineTransform.getTranslateInstance(0,0)));
-// currentclip.intersect(addclip);
-// this.graphics.clip(currentclip );
- }
- public void erasepage(){
- this.graphics.clearRect(0, 0, size.width, size.height);
- }
-
- public void charpath(String aString, boolean adjustForStroking)throws PainterException{
- FontRenderContext frc=this.graphics.getFontRenderContext();
- Font fn=this.state.font;
-// System.out.println("Fonthoehe:"+fn.getSize2D());
- GlyphVector glyphVector = fn.createGlyphVector(frc, aString);
- Point2D currentPoint = this.state.path.getCurrentPoint();
- Shape glyphShape = glyphVector.getOutline();
- AffineTransform currentTransform = AffineTransform.getScaleInstance(1,-1);
- glyphShape=currentTransform.createTransformedShape(glyphShape);
- AffineTransform currentTransform2 = AffineTransform.getTranslateInstance((float)currentPoint.getX(),(float)currentPoint.getY());
- glyphShape=currentTransform2.createTransformedShape(glyphShape);
- this.state.path.append(glyphShape, false);
- }
-
- public void showpage(){
- PdfGraphics2D pdfg2d = (PdfGraphics2D) this.graphics;
- PdfContentByte cb = pdfg2d.getContent();
- try {
- cb.getPdfWriter().newPage();
- }
- catch (com.lowagie.text.DocumentException ex) {
- ex.printStackTrace();
- }
- }
-
- public void show(String string) throws PainterException {
- Point2D currentPoint = this.state.path.getCurrentPoint();
- AffineTransform currentTransform = this.graphics.getTransform();
- Point2D tranformedPoint = currentTransform.transform(currentPoint, null);
-
- if(currentPoint == null){
- throw new PainterException("no current point");
- }
- this.graphics.setTransform(new AffineTransform());
- this.graphics.drawString(string, (float) tranformedPoint.getX(), (float) tranformedPoint.getY());
- this.graphics.setTransform(currentTransform);
- }
-
- public void fill(){
- this.graphics.fill(this.state.path);
- this.newpath();
- }
-
- public void eofill(){
- this.state.path.setWindingRule(GeneralPath.WIND_EVEN_ODD);
- this.graphics.fill(this.state.path);
- this.state.path.setWindingRule(GeneralPath.WIND_NON_ZERO);
- this.newpath();
- }
-
- public void stroke()throws PainterException{
- this.graphics.draw(this.state.path);
- this.newpath();
-
- }
-
- public void rectfill(double x, double y, double width, double height){
- this.gsave();
- this.rectpath(x, y, width, height);
- this.fill();
- this.grestore();
- }
-
- public void rectfill(Rectangle2D rect){
- this.rectfill(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
- }
-
- public void rectstroke(double x, double y, double width, double height)throws PainterException{
- this.gsave();
- this.rectpath(x, y, width, height);
- this.stroke();
- this.grestore();
- }
-
- public void rectstroke(Rectangle2D rect)throws PainterException{
- this.rectstroke(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
- }
-
- public void rectpath(double x, double y, double width, double height){
- this.newpath();
- this.moveto(x, y);
- try {
- this.rlineto(width, 0);
- this.rlineto(0, height);
- this.rlineto(-width, 0);
- } catch(PainterException e){
- }
- this.closepath();
- }
-
- // convenience
-
- // this guy tries to find an appropiate font
- // if he fails returns whatever font he wants
- public Font findFont(String fontname){
- Font result;
- StringBuffer buffer = new StringBuffer(fontname);
- int i, n;
- n = buffer.length();
-
- for(i = 0; i < n; i++){
- if(buffer.charAt(i) == '-'){
- buffer.setCharAt(i,' ');
- }
- }
-
- fontname = buffer.toString();
-
- if(this.fonts == null){
- // construct the fonts dictionary
- GraphicsEnvironment genv = GraphicsEnvironment.getLocalGraphicsEnvironment();
- Font[] fontArray = genv.getAllFonts();
- this.fonts = new HashMap();
- for(i = 0; i < fontArray.length; i++){
- String postscriptName = fontArray[i].getPSName();
- this.fonts.put(postscriptName, fontArray[i]);
- }
- }
- result = (Font) this.fonts.get(fontname);
- if(result == null){
-// result = new Font("SansSerif", Font.PLAIN, 12);
- result = new Font("Arial", Font.PLAIN, 12);
- }
- return result;
- }
-}
-
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAToken.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PAToken.java
deleted file mode 100644
index 52f347e..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PAToken.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-public class PAToken {
-
- static public final int IDENTIFIER = 0;
- static public final int KEY = 1;
- static public final int PROCEDURE = 2;
- static public final int MARK = 3;
- static public final int START_PROCEDURE = 4;
- static public final int END_PROCEDURE = 5;
- static public final int IMMEDIATE = 6;
- static public final int START_ARRAY = 7;
- static public final int END_ARRAY = 8;
- static public final int START_DICT = 9;
- static public final int END_DICT = 10;
-
- public Object value;
- public int type;
-
- public PAToken(Object value, int type) {
- super();
- this.value = value;
- this.type = type;
- }
-
- public String toString() {
- switch (this.type) {
- case IDENTIFIER:
- return "IDENTIFIER " + this.value.toString();
- case KEY:
- return "KEY " + this.value.toString();
- case PROCEDURE:
- return "PROCEDURE " + this.value.toString();
- case MARK:
- return "MARK";
- case START_PROCEDURE:
- return "START_PROCEDURE";
- case END_PROCEDURE:
- return "END_PROCEDURE";
- case IMMEDIATE:
- return "IMMEDIATE " + this.value.toString();
- case START_ARRAY:
- return "START_ARRAY";
- case END_ARRAY:
- return "END_ARRAY";
- case START_DICT:
- return "START_DICT";
- case END_DICT:
- return "END_DICT";
- }
- return this.value.toString();
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/PainterException.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/PainterException.java
deleted file mode 100644
index 236eece..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/PainterException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
-package com.lowagie.text.pdf.codec.postscript;
-
-public class PainterException extends Exception {
-
- public PainterException(String msg){
- super(msg);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/ParseException.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/ParseException.java
deleted file mode 100644
index 4bf572e..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/ParseException.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 2.1 */
-package com.lowagie.text.pdf.codec.postscript;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
- /**
- * This constructor is used by the method "generateParseException"
- * in the generated parser. Calling this constructor generates
- * a new object of this type with the fields "currentToken",
- * "expectedTokenSequences", and "tokenImage" set. The boolean
- * flag "specialConstructor" is also set to true to indicate that
- * this constructor was used to create this object.
- * This constructor calls its super class with the empty string
- * to force the "toString" method of parent class "Throwable" to
- * print the error message in the form:
- * ParseException: <result of getMessage>
- */
- public ParseException(Token currentTokenVal,
- int[][] expectedTokenSequencesVal,
- String[] tokenImageVal
- )
- {
- super("");
- specialConstructor = true;
- currentToken = currentTokenVal;
- expectedTokenSequences = expectedTokenSequencesVal;
- tokenImage = tokenImageVal;
- }
-
- /**
- * The following constructors are for use by you for whatever
- * purpose you can think of. Constructing the exception in this
- * manner makes the exception behave in the normal way - i.e., as
- * documented in the class "Throwable". The fields "errorToken",
- * "expectedTokenSequences", and "tokenImage" do not contain
- * relevant information. The JavaCC generated code does not use
- * these constructors.
- */
-
- public ParseException() {
- super();
- specialConstructor = false;
- }
-
- public ParseException(String message) {
- super(message);
- specialConstructor = false;
- }
-
- /**
- * This variable determines which constructor was used to create
- * this object and thereby affects the semantics of the
- * "getMessage" method (see below).
- */
- protected boolean specialConstructor;
-
- /**
- * This is the last token that has been consumed successfully. If
- * this object has been created due to a parse error, the token
- * followng this token will (therefore) be the first error token.
- */
- public Token currentToken;
-
- /**
- * Each entry in this array is an array of integers. Each array
- * of integers represents a sequence of tokens (by their ordinal
- * values) that is expected at this point of the parse.
- */
- public int[][] expectedTokenSequences;
-
- /**
- * This is a reference to the "tokenImage" array of the generated
- * parser within which the parse error occurred. This array is
- * defined in the generated ...Constants interface.
- */
- public String[] tokenImage;
-
- /**
- * This method has the standard behavior when this object has been
- * created using the standard constructors. Otherwise, it uses
- * "currentToken" and "expectedTokenSequences" to generate a parse
- * error message and returns it. If this object has been created
- * due to a parse error, and you do not catch it (it gets thrown
- * from the parser), then this method is called during the printing
- * of the final stack trace, and hence the correct error message
- * gets displayed.
- */
- public String getMessage() {
- if (!specialConstructor) {
- return super.getMessage();
- }
- String expected = "";
- int maxSize = 0;
- for (int i = 0; i < expectedTokenSequences.length; i++) {
- if (maxSize < expectedTokenSequences[i].length) {
- maxSize = expectedTokenSequences[i].length;
- }
- for (int j = 0; j < expectedTokenSequences[i].length; j++) {
- expected += tokenImage[expectedTokenSequences[i][j]] + " ";
- }
- if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
- expected += "...";
- }
- expected += eol + " ";
- }
- String retval = "Encountered \"";
- Token tok = currentToken.next;
- for (int i = 0; i < maxSize; i++) {
- if (i != 0) retval += " ";
- if (tok.kind == 0) {
- retval += tokenImage[0];
- break;
- }
- retval += add_escapes(tok.image);
- tok = tok.next;
- }
- retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
- retval += "." + eol;
- if (expectedTokenSequences.length == 1) {
- retval += "Was expecting:" + eol + " ";
- } else {
- retval += "Was expecting one of:" + eol + " ";
- }
- retval += expected;
- return retval;
- }
-
- /**
- * The end of line string for this machine.
- */
- protected String eol = System.getProperty("line.separator", "\n");
-
- /**
- * Used to convert raw characters to their escaped version
- * when these raw version cannot be used as part of an ASCII
- * string literal.
- */
- protected String add_escapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4, s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/Token.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/Token.java
deleted file mode 100644
index 530e4de..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/Token.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 2.1 */
-package com.lowagie.text.pdf.codec.postscript;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-
- /**
- * An integer that describes the kind of this token. This numbering
- * system is determined by JavaCCParser, and a table of these numbers is
- * stored in the file ...Constants.java.
- */
- public int kind;
-
- /**
- * beginLine and beginColumn describe the position of the first character
- * of this token; endLine and endColumn describe the position of the
- * last character of this token.
- */
- public int beginLine, beginColumn, endLine, endColumn;
-
- /**
- * The string image of the token.
- */
- public String image;
-
- /**
- * A reference to the next regular (non-special) token from the input
- * stream. If this is the last token from the input stream, or if the
- * token manager has not read tokens beyond this one, this field is
- * set to null. This is true only if this token is also a regular
- * token. Otherwise, see below for a description of the contents of
- * this field.
- */
- public Token next;
-
- /**
- * This field is used to access special tokens that occur prior to this
- * token, but after the immediately preceding regular (non-special) token.
- * If there are no such special tokens, this field is set to null.
- * When there are more than one such special token, this field refers
- * to the last of these special tokens, which in turn refers to the next
- * previous special token through its specialToken field, and so on
- * until the first special token (whose specialToken field is null).
- * The next fields of special tokens refer to other special tokens that
- * immediately follow it (without an intervening regular token). If there
- * is no such token, this field is null.
- */
- public Token specialToken;
-
- /**
- * Returns the image.
- */
- public final String toString()
- {
- return image;
- }
-
- /**
- * Returns a new Token object, by default. However, if you want, you
- * can create and return subclass objects based on the value of ofKind.
- * Simply add the cases to the switch for all those special cases.
- * For example, if you have a subclass of Token called IDToken that
- * you want to create if ofKind is ID, simlpy add something like :
- *
- * case MyParserConstants.ID : return new IDToken();
- *
- * to the following switch statement. Then you can cast matchedToken
- * variable to the appropriate type and use it in your lexical actions.
- */
- public static final Token newToken(int ofKind)
- {
- switch(ofKind)
- {
- default : return new Token();
- }
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/postscript/TokenMgrError.java b/src/main/java/com/lowagie/text/pdf/codec/postscript/TokenMgrError.java
deleted file mode 100644
index 6b54bfa..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/postscript/TokenMgrError.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 2.1 */
-package com.lowagie.text.pdf.codec.postscript;
-
-public class TokenMgrError extends Error
-{
- /*
- * Ordinals for various reasons why an Error of this type can be thrown.
- */
-
- /**
- * Lexical error occured.
- */
- static final int LEXICAL_ERROR = 0;
-
- /**
- * An attempt wass made to create a second instance of a static token manager.
- */
- static final int STATIC_LEXER_ERROR = 1;
-
- /**
- * Tried to change to an invalid lexical state.
- */
- static final int INVALID_LEXICAL_STATE = 2;
-
- /**
- * Detected (and bailed out of) an infinite loop in the token manager.
- */
- static final int LOOP_DETECTED = 3;
-
- /**
- * Indicates the reason why the exception is thrown. It will have
- * one of the above 4 values.
- */
- int errorCode;
-
- /**
- * Replaces unprintable characters by their espaced (or unicode escaped)
- * equivalents in the given string
- */
- protected static final String addEscapes(String str) {
- StringBuffer retval = new StringBuffer();
- char ch;
- for (int i = 0; i < str.length(); i++) {
- switch (str.charAt(i))
- {
- case 0 :
- continue;
- case '\b':
- retval.append("\\b");
- continue;
- case '\t':
- retval.append("\\t");
- continue;
- case '\n':
- retval.append("\\n");
- continue;
- case '\f':
- retval.append("\\f");
- continue;
- case '\r':
- retval.append("\\r");
- continue;
- case '\"':
- retval.append("\\\"");
- continue;
- case '\'':
- retval.append("\\\'");
- continue;
- case '\\':
- retval.append("\\\\");
- continue;
- default:
- if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
- String s = "0000" + Integer.toString(ch, 16);
- retval.append("\\u" + s.substring(s.length() - 4, s.length()));
- } else {
- retval.append(ch);
- }
- continue;
- }
- }
- return retval.toString();
- }
-
- /**
- * Returns a detailed message for the Error when it is thrown by the
- * token manager to indicate a lexical error.
- * Parameters :
- * EOFSeen : indicates if EOF caused the lexicl error
- * curLexState : lexical state in which this error occured
- * errorLine : line number when the error occured
- * errorColumn : column number when the error occured
- * errorAfter : prefix that was seen before this error occured
- * curchar : the offending character
- * Note: You can customize the lexical error message by modifying this method.
- */
- private static final String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
- return("Lexical error at line " +
- errorLine + ", column " +
- errorColumn + ". Encountered: " +
- (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
- "after : \"" + addEscapes(errorAfter) + "\"");
- }
-
- /**
- * You can also modify the body of this method to customize your error messages.
- * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
- * of end-users concern, so you can return something like :
- *
- * "Internal Error : Please file a bug report .... "
- *
- * from this method for such cases in the release version of your parser.
- */
- public String getMessage() {
- return super.getMessage();
- }
-
- /*
- * Constructors of various flavors follow.
- */
-
- public TokenMgrError() {
- }
-
- public TokenMgrError(String message, int reason) {
- super(message);
- errorCode = reason;
- }
-
- public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
- this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java
deleted file mode 100644
index 084761f..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * $Id: InputMeta.java,v 1.3 2005/10/06 10:32:47 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.codec.wmf;
-
-import java.io.*;
-import java.awt.Color;
-import com.lowagie.text.Image;
-
-public class InputMeta {
-
- InputStream in;
- int length;
-
- public InputMeta(InputStream in) {
- this.in = in;
- }
-
- public int readWord() throws IOException{
- length += 2;
- int k1 = in.read();
- if (k1 < 0)
- return 0;
- return (k1 + (in.read() << 8)) & 0xffff;
- }
-
- public int readShort() throws IOException{
- int k = readWord();
- if (k > 0x7fff)
- k -= 0x10000;
- return k;
- }
-
- public int readInt() throws IOException{
- length += 4;
- int k1 = in.read();
- if (k1 < 0)
- return 0;
- int k2 = in.read() << 8;
- int k3 = in.read() << 16;
- return k1 + k2 + k3 + (in.read() << 24);
- }
-
- public int readByte() throws IOException{
- ++length;
- return in.read() & 0xff;
- }
-
- public void skip(int len) throws IOException{
- length += len;
- Image.skip(in, len);
- }
-
- public int getLength() {
- return length;
- }
-
- public Color readColor() throws IOException{
- int red = readByte();
- int green = readByte();
- int blue = readByte();
- readByte();
- return new Color(red, green, blue);
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java
deleted file mode 100644
index 430e177..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * $Id: MetaBrush.java,v 1.2 2005/05/04 14:33:19 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.codec.wmf;
-import java.io.IOException;
-import java.awt.Color;
-
-public class MetaBrush extends MetaObject {
-
- public static final int BS_SOLID = 0;
- public static final int BS_NULL = 1;
- public static final int BS_HATCHED = 2;
- public static final int BS_PATTERN = 3;
- public static final int BS_DIBPATTERN = 5;
- public static final int HS_HORIZONTAL = 0;
- public static final int HS_VERTICAL = 1;
- public static final int HS_FDIAGONAL = 2;
- public static final int HS_BDIAGONAL = 3;
- public static final int HS_CROSS = 4;
- public static final int HS_DIAGCROSS = 5;
-
- int style = BS_SOLID;
- int hatch;
- Color color = Color.white;
-
- public MetaBrush() {
- type = META_BRUSH;
- }
-
- public void init(InputMeta in) throws IOException {
- style = in.readWord();
- color = in.readColor();
- hatch = in.readWord();
- }
-
- public int getStyle() {
- return style;
- }
-
- public int getHatch() {
- return hatch;
- }
-
- public Color getColor() {
- return color;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java
deleted file mode 100644
index ca77294..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * $Id: MetaDo.java,v 1.3 2005/12/01 16:57:15 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.codec.wmf;
-import java.io.*;
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.pdf.codec.BmpImage;
-import com.lowagie.text.*;
-import java.awt.Point;
-import java.awt.Color;
-import java.util.ArrayList;
-
-public class MetaDo {
-
- public static final int META_SETBKCOLOR = 0x0201;
- public static final int META_SETBKMODE = 0x0102;
- public static final int META_SETMAPMODE = 0x0103;
- public static final int META_SETROP2 = 0x0104;
- public static final int META_SETRELABS = 0x0105;
- public static final int META_SETPOLYFILLMODE = 0x0106;
- public static final int META_SETSTRETCHBLTMODE = 0x0107;
- public static final int META_SETTEXTCHAREXTRA = 0x0108;
- public static final int META_SETTEXTCOLOR = 0x0209;
- public static final int META_SETTEXTJUSTIFICATION = 0x020A;
- public static final int META_SETWINDOWORG = 0x020B;
- public static final int META_SETWINDOWEXT = 0x020C;
- public static final int META_SETVIEWPORTORG = 0x020D;
- public static final int META_SETVIEWPORTEXT = 0x020E;
- public static final int META_OFFSETWINDOWORG = 0x020F;
- public static final int META_SCALEWINDOWEXT = 0x0410;
- public static final int META_OFFSETVIEWPORTORG = 0x0211;
- public static final int META_SCALEVIEWPORTEXT = 0x0412;
- public static final int META_LINETO = 0x0213;
- public static final int META_MOVETO = 0x0214;
- public static final int META_EXCLUDECLIPRECT = 0x0415;
- public static final int META_INTERSECTCLIPRECT = 0x0416;
- public static final int META_ARC = 0x0817;
- public static final int META_ELLIPSE = 0x0418;
- public static final int META_FLOODFILL = 0x0419;
- public static final int META_PIE = 0x081A;
- public static final int META_RECTANGLE = 0x041B;
- public static final int META_ROUNDRECT = 0x061C;
- public static final int META_PATBLT = 0x061D;
- public static final int META_SAVEDC = 0x001E;
- public static final int META_SETPIXEL = 0x041F;
- public static final int META_OFFSETCLIPRGN = 0x0220;
- public static final int META_TEXTOUT = 0x0521;
- public static final int META_BITBLT = 0x0922;
- public static final int META_STRETCHBLT = 0x0B23;
- public static final int META_POLYGON = 0x0324;
- public static final int META_POLYLINE = 0x0325;
- public static final int META_ESCAPE = 0x0626;
- public static final int META_RESTOREDC = 0x0127;
- public static final int META_FILLREGION = 0x0228;
- public static final int META_FRAMEREGION = 0x0429;
- public static final int META_INVERTREGION = 0x012A;
- public static final int META_PAINTREGION = 0x012B;
- public static final int META_SELECTCLIPREGION = 0x012C;
- public static final int META_SELECTOBJECT = 0x012D;
- public static final int META_SETTEXTALIGN = 0x012E;
- public static final int META_CHORD = 0x0830;
- public static final int META_SETMAPPERFLAGS = 0x0231;
- public static final int META_EXTTEXTOUT = 0x0a32;
- public static final int META_SETDIBTODEV = 0x0d33;
- public static final int META_SELECTPALETTE = 0x0234;
- public static final int META_REALIZEPALETTE = 0x0035;
- public static final int META_ANIMATEPALETTE = 0x0436;
- public static final int META_SETPALENTRIES = 0x0037;
- public static final int META_POLYPOLYGON = 0x0538;
- public static final int META_RESIZEPALETTE = 0x0139;
- public static final int META_DIBBITBLT = 0x0940;
- public static final int META_DIBSTRETCHBLT = 0x0b41;
- public static final int META_DIBCREATEPATTERNBRUSH = 0x0142;
- public static final int META_STRETCHDIB = 0x0f43;
- public static final int META_EXTFLOODFILL = 0x0548;
- public static final int META_DELETEOBJECT = 0x01f0;
- public static final int META_CREATEPALETTE = 0x00f7;
- public static final int META_CREATEPATTERNBRUSH = 0x01F9;
- public static final int META_CREATEPENINDIRECT = 0x02FA;
- public static final int META_CREATEFONTINDIRECT = 0x02FB;
- public static final int META_CREATEBRUSHINDIRECT = 0x02FC;
- public static final int META_CREATEREGION = 0x06FF;
-
- public PdfContentByte cb;
- public InputMeta in;
- int left;
- int top;
- int right;
- int bottom;
- int inch;
- MetaState state = new MetaState();
-
- public MetaDo(InputStream in, PdfContentByte cb) {
- this.cb = cb;
- this.in = new InputMeta(in);
- }
-
- public void readAll() throws IOException, DocumentException{
- if (in.readInt() != 0x9AC6CDD7) {
- throw new DocumentException("Not a placeable windows metafile");
- }
- in.readWord();
- left = in.readShort();
- top = in.readShort();
- right = in.readShort();
- bottom = in.readShort();
- inch = in.readWord();
- state.setScalingX((float)(right - left) / (float)inch * 72f);
- state.setScalingY((float)(bottom - top) / (float)inch * 72f);
- state.setOffsetWx(left);
- state.setOffsetWy(top);
- state.setExtentWx(right - left);
- state.setExtentWy(bottom - top);
- in.readInt();
- in.readWord();
- in.skip(18);
-
- int tsize;
- int function;
- cb.setLineCap(1);
- cb.setLineJoin(1);
- for (;;) {
- int lenMarker = in.getLength();
- tsize = in.readInt();
- if (tsize < 3)
- break;
- function = in.readWord();
- switch (function) {
- case 0:
- break;
- case META_CREATEPALETTE:
- case META_CREATEREGION:
- case META_DIBCREATEPATTERNBRUSH:
- state.addMetaObject(new MetaObject());
- break;
- case META_CREATEPENINDIRECT:
- {
- MetaPen pen = new MetaPen();
- pen.init(in);
- state.addMetaObject(pen);
- break;
- }
- case META_CREATEBRUSHINDIRECT:
- {
- MetaBrush brush = new MetaBrush();
- brush.init(in);
- state.addMetaObject(brush);
- break;
- }
- case META_CREATEFONTINDIRECT:
- {
- MetaFont font = new MetaFont();
- font.init(in);
- state.addMetaObject(font);
- break;
- }
- case META_SELECTOBJECT:
- {
- int idx = in.readWord();
- state.selectMetaObject(idx, cb);
- break;
- }
- case META_DELETEOBJECT:
- {
- int idx = in.readWord();
- state.deleteMetaObject(idx);
- break;
- }
- case META_SAVEDC:
- state.saveState(cb);
- break;
- case META_RESTOREDC:
- {
- int idx = in.readShort();
- state.restoreState(idx, cb);
- break;
- }
- case META_SETWINDOWORG:
- state.setOffsetWy(in.readShort());
- state.setOffsetWx(in.readShort());
- break;
- case META_SETWINDOWEXT:
- state.setExtentWy(in.readShort());
- state.setExtentWx(in.readShort());
- break;
- case META_MOVETO:
- {
- int y = in.readShort();
- Point p = new Point(in.readShort(), y);
- state.setCurrentPoint(p);
- break;
- }
- case META_LINETO:
- {
- int y = in.readShort();
- int x = in.readShort();
- Point p = state.getCurrentPoint();
- cb.moveTo(state.transformX(p.x), state.transformY(p.y));
- cb.lineTo(state.transformX(x), state.transformY(y));
- cb.stroke();
- state.setCurrentPoint(new Point(x, y));
- break;
- }
- case META_POLYLINE:
- {
- state.setLineJoinPolygon(cb);
- int len = in.readWord();
- int x = in.readShort();
- int y = in.readShort();
- cb.moveTo(state.transformX(x), state.transformY(y));
- for (int k = 1; k < len; ++k) {
- x = in.readShort();
- y = in.readShort();
- cb.lineTo(state.transformX(x), state.transformY(y));
- }
- cb.stroke();
- break;
- }
- case META_POLYGON:
- {
- if (isNullStrokeFill(false))
- break;
- int len = in.readWord();
- int sx = in.readShort();
- int sy = in.readShort();
- cb.moveTo(state.transformX(sx), state.transformY(sy));
- for (int k = 1; k < len; ++k) {
- int x = in.readShort();
- int y = in.readShort();
- cb.lineTo(state.transformX(x), state.transformY(y));
- }
- cb.lineTo(state.transformX(sx), state.transformY(sy));
- strokeAndFill();
- break;
- }
- case META_POLYPOLYGON:
- {
- if (isNullStrokeFill(false))
- break;
- int numPoly = in.readWord();
- int lens[] = new int[numPoly];
- for (int k = 0; k < lens.length; ++k)
- lens[k] = in.readWord();
- for (int j = 0; j < lens.length; ++j) {
- int len = lens[j];
- int sx = in.readShort();
- int sy = in.readShort();
- cb.moveTo(state.transformX(sx), state.transformY(sy));
- for (int k = 1; k < len; ++k) {
- int x = in.readShort();
- int y = in.readShort();
- cb.lineTo(state.transformX(x), state.transformY(y));
- }
- cb.lineTo(state.transformX(sx), state.transformY(sy));
- }
- strokeAndFill();
- break;
- }
- case META_ELLIPSE:
- {
- if (isNullStrokeFill(state.getLineNeutral()))
- break;
- int b = in.readShort();
- int r = in.readShort();
- int t = in.readShort();
- int l = in.readShort();
- cb.arc(state.transformX(l), state.transformY(b), state.transformX(r), state.transformY(t), 0, 360);
- strokeAndFill();
- break;
- }
- case META_ARC:
- {
- if (isNullStrokeFill(state.getLineNeutral()))
- break;
- float yend = state.transformY(in.readShort());
- float xend = state.transformX(in.readShort());
- float ystart = state.transformY(in.readShort());
- float xstart = state.transformX(in.readShort());
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- float cx = (r + l) / 2;
- float cy = (t + b) / 2;
- float arc1 = getArc(cx, cy, xstart, ystart);
- float arc2 = getArc(cx, cy, xend, yend);
- arc2 -= arc1;
- if (arc2 <= 0)
- arc2 += 360;
- cb.arc(l, b, r, t, arc1, arc2);
- cb.stroke();
- break;
- }
- case META_PIE:
- {
- if (isNullStrokeFill(state.getLineNeutral()))
- break;
- float yend = state.transformY(in.readShort());
- float xend = state.transformX(in.readShort());
- float ystart = state.transformY(in.readShort());
- float xstart = state.transformX(in.readShort());
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- float cx = (r + l) / 2;
- float cy = (t + b) / 2;
- float arc1 = getArc(cx, cy, xstart, ystart);
- float arc2 = getArc(cx, cy, xend, yend);
- arc2 -= arc1;
- if (arc2 <= 0)
- arc2 += 360;
- ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2);
- if (ar.size() == 0)
- break;
- float pt[] = (float [])ar.get(0);
- cb.moveTo(cx, cy);
- cb.lineTo(pt[0], pt[1]);
- for (int k = 0; k < ar.size(); ++k) {
- pt = (float [])ar.get(k);
- cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]);
- }
- cb.lineTo(cx, cy);
- strokeAndFill();
- break;
- }
- case META_CHORD:
- {
- if (isNullStrokeFill(state.getLineNeutral()))
- break;
- float yend = state.transformY(in.readShort());
- float xend = state.transformX(in.readShort());
- float ystart = state.transformY(in.readShort());
- float xstart = state.transformX(in.readShort());
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- float cx = (r + l) / 2;
- float cy = (t + b) / 2;
- float arc1 = getArc(cx, cy, xstart, ystart);
- float arc2 = getArc(cx, cy, xend, yend);
- arc2 -= arc1;
- if (arc2 <= 0)
- arc2 += 360;
- ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2);
- if (ar.size() == 0)
- break;
- float pt[] = (float [])ar.get(0);
- cx = pt[0];
- cy = pt[1];
- cb.moveTo(cx, cy);
- for (int k = 0; k < ar.size(); ++k) {
- pt = (float [])ar.get(k);
- cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]);
- }
- cb.lineTo(cx, cy);
- strokeAndFill();
- break;
- }
- case META_RECTANGLE:
- {
- if (isNullStrokeFill(true))
- break;
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- cb.rectangle(l, b, r - l, t - b);
- strokeAndFill();
- break;
- }
- case META_ROUNDRECT:
- {
- if (isNullStrokeFill(true))
- break;
- float h = state.transformY(0) - state.transformY(in.readShort());
- float w = state.transformX(in.readShort()) - state.transformX(0);
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- cb.roundRectangle(l, b, r - l, t - b, (h + w) / 4);
- strokeAndFill();
- break;
- }
- case META_INTERSECTCLIPRECT:
- {
- float b = state.transformY(in.readShort());
- float r = state.transformX(in.readShort());
- float t = state.transformY(in.readShort());
- float l = state.transformX(in.readShort());
- cb.rectangle(l, b, r - l, t - b);
- cb.eoClip();
- cb.newPath();
- break;
- }
- case META_EXTTEXTOUT:
- {
- int y = in.readShort();
- int x = in.readShort();
- int count = in.readWord();
- int flag = in.readWord();
- int x1 = 0;
- int y1 = 0;
- int x2 = 0;
- int y2 = 0;
- if ((flag & (MetaFont.ETO_CLIPPED | MetaFont.ETO_OPAQUE)) != 0) {
- x1 = in.readShort();
- y1 = in.readShort();
- x2 = in.readShort();
- y2 = in.readShort();
- }
- byte text[] = new byte[count];
- int k;
- for (k = 0; k < count; ++k) {
- byte c = (byte)in.readByte();
- if (c == 0)
- break;
- text[k] = c;
- }
- String s;
- try {
- s = new String(text, 0, k, "Cp1252");
- }
- catch (UnsupportedEncodingException e) {
- s = new String(text, 0, k);
- }
- outputText(x, y, flag, x1, y1, x2, y2, s);
- break;
- }
- case META_TEXTOUT:
- {
- int count = in.readWord();
- byte text[] = new byte[count];
- int k;
- for (k = 0; k < count; ++k) {
- byte c = (byte)in.readByte();
- if (c == 0)
- break;
- text[k] = c;
- }
- String s;
- try {
- s = new String(text, 0, k, "Cp1252");
- }
- catch (UnsupportedEncodingException e) {
- s = new String(text, 0, k);
- }
- count = (count + 1) & 0xfffe;
- in.skip(count - k);
- int y = in.readShort();
- int x = in.readShort();
- outputText(x, y, 0, 0, 0, 0, 0, s);
- break;
- }
- case META_SETBKCOLOR:
- state.setCurrentBackgroundColor(in.readColor());
- break;
- case META_SETTEXTCOLOR:
- state.setCurrentTextColor(in.readColor());
- break;
- case META_SETTEXTALIGN:
- state.setTextAlign(in.readWord());
- break;
- case META_SETBKMODE:
- state.setBackgroundMode(in.readWord());
- break;
- case META_SETPOLYFILLMODE:
- state.setPolyFillMode(in.readWord());
- break;
- case META_SETPIXEL:
- {
- Color color = in.readColor();
- int y = in.readShort();
- int x = in.readShort();
- cb.saveState();
- cb.setColorFill(color);
- cb.rectangle(state.transformX(x), state.transformY(y), .2f, .2f);
- cb.fill();
- cb.restoreState();
- break;
- }
- case META_DIBSTRETCHBLT:
- case META_STRETCHDIB: {
- int rop = in.readInt();
- if (function == META_STRETCHDIB) {
- /*int usage = */ in.readWord();
- }
- int srcHeight = in.readShort();
- int srcWidth = in.readShort();
- int ySrc = in.readShort();
- int xSrc = in.readShort();
- float destHeight = state.transformY(in.readShort()) - state.transformY(0);
- float destWidth = state.transformX(in.readShort()) - state.transformX(0);
- float yDest = state.transformY(in.readShort());
- float xDest = state.transformX(in.readShort());
- byte b[] = new byte[(tsize * 2) - (in.getLength() - lenMarker)];
- for (int k = 0; k < b.length; ++k)
- b[k] = (byte)in.readByte();
- try {
- ByteArrayInputStream inb = new ByteArrayInputStream(b);
- Image bmp = BmpImage.getImage(inb, true, b.length);
- cb.saveState();
- cb.rectangle(xDest, yDest, destWidth, destHeight);
- cb.clip();
- cb.newPath();
- bmp.scaleAbsolute(destWidth * bmp.width() / srcWidth, -destHeight * bmp.height() / srcHeight);
- bmp.setAbsolutePosition(xDest - destWidth * xSrc / srcWidth, yDest + destHeight * ySrc / srcHeight - bmp.scaledHeight());
- cb.addImage(bmp);
- cb.restoreState();
- }
- catch (Exception e) {
- // empty on purpose
- }
- break;
- }
- }
- in.skip((tsize * 2) - (in.getLength() - lenMarker));
- }
- state.cleanup(cb);
- }
-
- public void outputText(int x, int y, int flag, int x1, int y1, int x2, int y2, String text) throws IOException {
- MetaFont font = state.getCurrentFont();
- float refX = state.transformX(x);
- float refY = state.transformY(y);
- float angle = state.transformAngle(font.getAngle());
- float sin = (float)Math.sin(angle);
- float cos = (float)Math.cos(angle);
- float fontSize = font.getFontSize(state);
- BaseFont bf = font.getFont();
- int align = state.getTextAlign();
- float textWidth = bf.getWidthPoint(text, fontSize);
- float tx = 0;
- float ty = 0;
- float descender = bf.getFontDescriptor(BaseFont.DESCENT, fontSize);
- float ury = bf.getFontDescriptor(BaseFont.BBOXURY, fontSize);
- cb.saveState();
- cb.concatCTM(cos, sin, -sin, cos, refX, refY);
- if ((align & MetaState.TA_CENTER) == MetaState.TA_CENTER)
- tx = -textWidth / 2;
- else if ((align & MetaState.TA_RIGHT) == MetaState.TA_RIGHT)
- tx = -textWidth;
- if ((align & MetaState.TA_BASELINE) == MetaState.TA_BASELINE)
- ty = 0;
- else if ((align & MetaState.TA_BOTTOM) == MetaState.TA_BOTTOM)
- ty = -descender;
- else
- ty = -ury;
- Color textColor;
- if (state.getBackgroundMode() == MetaState.OPAQUE) {
- textColor = state.getCurrentBackgroundColor();
- cb.setColorFill(textColor);
- cb.rectangle(tx, ty + descender, textWidth, ury - descender);
- cb.fill();
- }
- textColor = state.getCurrentTextColor();
- cb.setColorFill(textColor);
- cb.beginText();
- cb.setFontAndSize(bf, fontSize);
- cb.setTextMatrix(tx, ty);
- cb.showText(text);
- cb.endText();
- if (font.isUnderline()) {
- cb.rectangle(tx, ty - fontSize / 4, textWidth, fontSize / 15);
- cb.fill();
- }
- if (font.isStrikeout()) {
- cb.rectangle(tx, ty + fontSize / 3, textWidth, fontSize / 15);
- cb.fill();
- }
- cb.restoreState();
- }
-
- public boolean isNullStrokeFill(boolean isRectangle) {
- MetaPen pen = state.getCurrentPen();
- MetaBrush brush = state.getCurrentBrush();
- boolean noPen = (pen.getStyle() == MetaPen.PS_NULL);
- int style = brush.getStyle();
- boolean isBrush = (style == MetaBrush.BS_SOLID || (style == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE));
- boolean result = noPen && !isBrush;
- if (!noPen) {
- if (isRectangle)
- state.setLineJoinRectangle(cb);
- else
- state.setLineJoinPolygon(cb);
- }
- return result;
- }
-
- public void strokeAndFill(){
- MetaPen pen = state.getCurrentPen();
- MetaBrush brush = state.getCurrentBrush();
- int penStyle = pen.getStyle();
- int brushStyle = brush.getStyle();
- if (penStyle == MetaPen.PS_NULL) {
- cb.closePath();
- if (state.getPolyFillMode() == MetaState.ALTERNATE) {
- cb.eoFill();
- }
- else {
- cb.fill();
- }
- }
- else {
- boolean isBrush = (brushStyle == MetaBrush.BS_SOLID || (brushStyle == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE));
- if (isBrush) {
- if (state.getPolyFillMode() == MetaState.ALTERNATE)
- cb.closePathEoFillStroke();
- else
- cb.closePathFillStroke();
- }
- else {
- cb.closePathStroke();
- }
- }
- }
-
- static float getArc(float xCenter, float yCenter, float xDot, float yDot) {
- double s = Math.atan2(yDot - yCenter, xDot - xCenter);
- if (s < 0)
- s += Math.PI * 2;
- return (float)(s / Math.PI * 180);
- }
-
- public static byte[] wrapBMP(Image image) throws IOException {
- if (image.getOriginalType() != Image.ORIGINAL_BMP)
- throw new IOException("Only BMP can be wrapped in WMF.");
- InputStream imgIn;
- byte data[] = null;
- if (image.getOriginalData() == null) {
- imgIn = image.url().openStream();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- int b = 0;
- while ((b = imgIn.read()) != -1)
- out.write(b);
- imgIn.close();
- data = out.toByteArray();
- }
- else
- data = image.getOriginalData();
- int sizeBmpWords = (data.length - 14 + 1) >>> 1;
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- // write metafile header
- writeWord(os, 1);
- writeWord(os, 9);
- writeWord(os, 0x0300);
- writeDWord(os, 9 + 4 + 5 + 5 + (13 + sizeBmpWords) + 3); // total metafile size
- writeWord(os, 1);
- writeDWord(os, 14 + sizeBmpWords); // max record size
- writeWord(os, 0);
- // write records
- writeDWord(os, 4);
- writeWord(os, META_SETMAPMODE);
- writeWord(os, 8);
-
- writeDWord(os, 5);
- writeWord(os, META_SETWINDOWORG);
- writeWord(os, 0);
- writeWord(os, 0);
-
- writeDWord(os, 5);
- writeWord(os, META_SETWINDOWEXT);
- writeWord(os, (int)image.height());
- writeWord(os, (int)image.width());
-
- writeDWord(os, 13 + sizeBmpWords);
- writeWord(os, META_DIBSTRETCHBLT);
- writeDWord(os, 0x00cc0020);
- writeWord(os, (int)image.height());
- writeWord(os, (int)image.width());
- writeWord(os, 0);
- writeWord(os, 0);
- writeWord(os, (int)image.height());
- writeWord(os, (int)image.width());
- writeWord(os, 0);
- writeWord(os, 0);
- os.write(data, 14, data.length - 14);
- if ((data.length & 1) == 1)
- os.write(0);
-// writeDWord(os, 14 + sizeBmpWords);
-// writeWord(os, META_STRETCHDIB);
-// writeDWord(os, 0x00cc0020);
-// writeWord(os, 0);
-// writeWord(os, (int)image.height());
-// writeWord(os, (int)image.width());
-// writeWord(os, 0);
-// writeWord(os, 0);
-// writeWord(os, (int)image.height());
-// writeWord(os, (int)image.width());
-// writeWord(os, 0);
-// writeWord(os, 0);
-// os.write(data, 14, data.length - 14);
-// if ((data.length & 1) == 1)
-// os.write(0);
-
- writeDWord(os, 3);
- writeWord(os, 0);
- os.close();
- return os.toByteArray();
- }
-
- public static void writeWord(OutputStream os, int v) throws IOException {
- os.write(v & 0xff);
- os.write((v >>> 8) & 0xff);
- }
-
- public static void writeDWord(OutputStream os, int v) throws IOException {
- writeWord(os, v & 0xffff);
- writeWord(os, (v >>> 16) & 0xffff);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java
deleted file mode 100644
index 70da31d..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * $Id: MetaFont.java,v 1.3 2005/11/02 18:03:45 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.codec.wmf;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.Font;
-import com.lowagie.text.FontFactory;
-import com.lowagie.text.ExceptionConverter;
-
-public class MetaFont extends MetaObject {
- static final String fontNames[] = {
- "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
- "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
- "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
- "Symbol", "ZapfDingbats"};
-
- static final int MARKER_BOLD = 1;
- static final int MARKER_ITALIC = 2;
- static final int MARKER_COURIER = 0;
- static final int MARKER_HELVETICA = 4;
- static final int MARKER_TIMES = 8;
- static final int MARKER_SYMBOL = 12;
-
- static final int DEFAULT_PITCH = 0;
- static final int FIXED_PITCH = 1;
- static final int VARIABLE_PITCH = 2;
- static final int FF_DONTCARE = 0;
- static final int FF_ROMAN = 1;
- static final int FF_SWISS = 2;
- static final int FF_MODERN = 3;
- static final int FF_SCRIPT = 4;
- static final int FF_DECORATIVE = 5;
- static final int BOLDTHRESHOLD = 600;
- static final int nameSize = 32;
- static final int ETO_OPAQUE = 2;
- static final int ETO_CLIPPED = 4;
-
- int height;
- float angle;
- int bold;
- int italic;
- boolean underline;
- boolean strikeout;
- int charset;
- int pitchAndFamily;
- String faceName = "arial";
- BaseFont font = null;
-
- public MetaFont() {
- type = META_FONT;
- }
-
- public void init(InputMeta in) throws IOException {
- height = Math.abs(in.readShort());
- in.skip(2);
- angle = (float)(in.readShort() / 1800.0 * Math.PI);
- in.skip(2);
- bold = (in.readShort() >= BOLDTHRESHOLD ? MARKER_BOLD : 0);
- italic = (in.readByte() != 0 ? MARKER_ITALIC : 0);
- underline = (in.readByte() != 0);
- strikeout = (in.readByte() != 0);
- charset = in.readByte();
- in.skip(3);
- pitchAndFamily = in.readByte();
- byte name[] = new byte[nameSize];
- int k;
- for (k = 0; k < nameSize; ++k) {
- int c = in.readByte();
- if (c == 0) {
- break;
- }
- name[k] = (byte)c;
- }
- try {
- faceName = new String(name, 0, k, "Cp1252");
- }
- catch (UnsupportedEncodingException e) {
- faceName = new String(name, 0, k);
- }
- faceName = faceName.toLowerCase();
- }
-
- public BaseFont getFont() {
- if (font != null)
- return font;
- Font ff2 = FontFactory.getFont(faceName, BaseFont.CP1252, true, 10, ((italic != 0) ? Font.ITALIC : 0) | ((bold != 0) ? Font.BOLD : 0));
- font = ff2.getBaseFont();
- if (font != null)
- return font;
- String fontName;
- if (faceName.indexOf("courier") != -1 || faceName.indexOf("terminal") != -1
- || faceName.indexOf("fixedsys") != -1) {
- fontName = fontNames[MARKER_COURIER + italic + bold];
- }
- else if (faceName.indexOf("ms sans serif") != -1 || faceName.indexOf("arial") != -1
- || faceName.indexOf("system") != -1) {
- fontName = fontNames[MARKER_HELVETICA + italic + bold];
- }
- else if (faceName.indexOf("arial black") != -1) {
- fontName = fontNames[MARKER_HELVETICA + italic + MARKER_BOLD];
- }
- else if (faceName.indexOf("times") != -1 || faceName.indexOf("ms serif") != -1
- || faceName.indexOf("roman") != -1) {
- fontName = fontNames[MARKER_TIMES + italic + bold];
- }
- else if (faceName.indexOf("symbol") != -1) {
- fontName = fontNames[MARKER_SYMBOL];
- }
- else {
- int pitch = pitchAndFamily & 3;
- int family = (pitchAndFamily >> 4) & 7;
- switch (family) {
- case FF_MODERN:
- fontName = fontNames[MARKER_COURIER + italic + bold];
- break;
- case FF_ROMAN:
- fontName = fontNames[MARKER_TIMES + italic + bold];
- break;
- case FF_SWISS:
- case FF_SCRIPT:
- case FF_DECORATIVE:
- fontName = fontNames[MARKER_HELVETICA + italic + bold];
- break;
- default:
- {
- switch (pitch) {
- case FIXED_PITCH:
- fontName = fontNames[MARKER_COURIER + italic + bold];
- break;
- default:
- fontName = fontNames[MARKER_HELVETICA + italic + bold];
- break;
- }
- }
- }
- }
- try {
- font = BaseFont.createFont(fontName, "Cp1252", false);
- }
- catch (Exception e) {
- throw new ExceptionConverter(e);
- }
-
- return font;
- }
-
- public float getAngle() {
- return angle;
- }
-
- public boolean isUnderline() {
- return underline;
- }
-
- public boolean isStrikeout() {
- return strikeout;
- }
-
- public float getFontSize(MetaState state) {
- return Math.abs(state.transformY(height) - state.transformY(0)) * 0.86f;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java
deleted file mode 100644
index d31fb02..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * $Id: MetaObject.java,v 1.2 2005/05/04 14:33:18 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.codec.wmf;
-
-public class MetaObject {
- public static final int META_NOT_SUPPORTED = 0;
- public static final int META_PEN = 1;
- public static final int META_BRUSH = 2;
- public static final int META_FONT = 3;
- public int type = META_NOT_SUPPORTED;
-
- public MetaObject() {
- }
-
- public MetaObject(int type) {
- this.type = type;
- }
-
- public int getType() {
- return type;
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java
deleted file mode 100644
index 29b85ca..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * $Id: MetaPen.java,v 1.2 2005/05/04 14:33:19 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.codec.wmf;
-import java.io.IOException;
-import java.awt.Color;
-
-public class MetaPen extends MetaObject {
-
- public static final int PS_SOLID = 0;
- public static final int PS_DASH = 1;
- public static final int PS_DOT = 2;
- public static final int PS_DASHDOT = 3;
- public static final int PS_DASHDOTDOT = 4;
- public static final int PS_NULL = 5;
- public static final int PS_INSIDEFRAME = 6;
-
- int style = PS_SOLID;
- int penWidth = 1;
- Color color = Color.black;
-
- public MetaPen() {
- type = META_PEN;
- }
-
- public void init(InputMeta in) throws IOException {
- style = in.readWord();
- penWidth = in.readShort();
- in.readWord();
- color = in.readColor();
- }
-
- public int getStyle() {
- return style;
- }
-
- public int getPenWidth() {
- return penWidth;
- }
-
- public Color getColor() {
- return color;
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java
deleted file mode 100644
index 97f18f4..0000000
--- a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * $Id: MetaState.java,v 1.5 2005/12/01 16:57:15 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.codec.wmf;
-
-import java.util.ArrayList;
-import java.util.Stack;
-import java.awt.Point;
-import java.awt.Color;
-import com.lowagie.text.pdf.*;
-
-public class MetaState {
-
- public static final int TA_NOUPDATECP = 0;
- public static final int TA_UPDATECP = 1;
- public static final int TA_LEFT = 0;
- public static final int TA_RIGHT = 2;
- public static final int TA_CENTER = 6;
- public static final int TA_TOP = 0;
- public static final int TA_BOTTOM = 8;
- public static final int TA_BASELINE = 24;
-
- public static final int TRANSPARENT = 1;
- public static final int OPAQUE = 2;
-
- public static final int ALTERNATE = 1;
- public static final int WINDING = 2;
-
- public Stack savedStates;
- public ArrayList MetaObjects;
- public Point currentPoint;
- public MetaPen currentPen;
- public MetaBrush currentBrush;
- public MetaFont currentFont;
- public Color currentBackgroundColor = Color.white;
- public Color currentTextColor = Color.black;
- public int backgroundMode = OPAQUE;
- public int polyFillMode = ALTERNATE;
- public int lineJoin = 1;
- public int textAlign;
- public int offsetWx;
- public int offsetWy;
- public int extentWx;
- public int extentWy;
- public float scalingX;
- public float scalingY;
-
-
- /** Creates new MetaState */
- public MetaState() {
- savedStates = new Stack();
- MetaObjects = new ArrayList();
- currentPoint = new Point(0, 0);
- currentPen = new MetaPen();
- currentBrush = new MetaBrush();
- currentFont = new MetaFont();
- }
-
- public MetaState(MetaState state) {
- setMetaState(state);
- }
-
- public void setMetaState(MetaState state) {
- savedStates = state.savedStates;
- MetaObjects = state.MetaObjects;
- currentPoint = state.currentPoint;
- currentPen = state.currentPen;
- currentBrush = state.currentBrush;
- currentFont = state.currentFont;
- currentBackgroundColor = state.currentBackgroundColor;
- currentTextColor = state.currentTextColor;
- backgroundMode = state.backgroundMode;
- polyFillMode = state.polyFillMode;
- textAlign = state.textAlign;
- lineJoin = state.lineJoin;
- offsetWx = state.offsetWx;
- offsetWy = state.offsetWy;
- extentWx = state.extentWx;
- extentWy = state.extentWy;
- scalingX = state.scalingX;
- scalingY = state.scalingY;
- }
-
- public void addMetaObject(MetaObject object) {
- for (int k = 0; k < MetaObjects.size(); ++k) {
- if (MetaObjects.get(k) == null) {
- MetaObjects.set(k, object);
- return;
- }
- }
- MetaObjects.add(object);
- }
-
- public void selectMetaObject(int index, PdfContentByte cb) {
- MetaObject obj = (MetaObject)MetaObjects.get(index);
- if (obj == null)
- return;
- int style;
- switch (obj.getType()) {
- case MetaObject.META_BRUSH:
- currentBrush = (MetaBrush)obj;
- style = currentBrush.getStyle();
- if (style == MetaBrush.BS_SOLID) {
- Color color = currentBrush.getColor();
- cb.setColorFill(color);
- }
- else if (style == MetaBrush.BS_HATCHED) {
- Color color = currentBackgroundColor;
- cb.setColorFill(color);
- }
- break;
- case MetaObject.META_PEN:
- {
- currentPen = (MetaPen)obj;
- style = currentPen.getStyle();
- if (style != MetaPen.PS_NULL) {
- Color color = currentPen.getColor();
- cb.setColorStroke(color);
- cb.setLineWidth(Math.abs((float)currentPen.getPenWidth() * scalingX / extentWx));
- switch (style) {
- case MetaPen.PS_DASH:
- cb.setLineDash(18, 6, 0);
- break;
- case MetaPen.PS_DASHDOT:
- cb.setLiteral("[9 6 3 6]0 d\n");
- break;
- case MetaPen.PS_DASHDOTDOT:
- cb.setLiteral("[9 3 3 3 3 3]0 d\n");
- break;
- case MetaPen.PS_DOT:
- cb.setLineDash(3, 0);
- break;
- default:
- cb.setLineDash(0);
- break;
- }
- }
- break;
- }
- case MetaObject.META_FONT:
- {
- currentFont = (MetaFont)obj;
- break;
- }
- }
- }
-
- public void deleteMetaObject(int index) {
- MetaObjects.set(index, null);
- }
-
- public void saveState(PdfContentByte cb) {
- cb.saveState();
- MetaState state = new MetaState(this);
- savedStates.push(state);
- }
-
- public void restoreState(int index, PdfContentByte cb) {
- int pops;
- if (index < 0)
- pops = Math.min(-index, savedStates.size());
- else
- pops = Math.max(savedStates.size() - index, 0);
- if (pops == 0)
- return;
- MetaState state = null;
- while (pops-- != 0) {
- cb.restoreState();
- state = (MetaState)savedStates.pop();
- }
- setMetaState(state);
- }
-
- public void cleanup(PdfContentByte cb) {
- int k = savedStates.size();
- while (k-- > 0)
- cb.restoreState();
- }
-
- public float transformX(int x) {
- return ((float)x - offsetWx) * scalingX / extentWx;
- }
-
- public float transformY(int y) {
- return (1f - ((float)y - offsetWy) / extentWy) * scalingY;
- }
-
- public void setScalingX(float scalingX) {
- this.scalingX = scalingX;
- }
-
- public void setScalingY(float scalingY) {
- this.scalingY = scalingY;
- }
-
- public void setOffsetWx(int offsetWx) {
- this.offsetWx = offsetWx;
- }
-
- public void setOffsetWy(int offsetWy) {
- this.offsetWy = offsetWy;
- }
-
- public void setExtentWx(int extentWx) {
- this.extentWx = extentWx;
- }
-
- public void setExtentWy(int extentWy) {
- this.extentWy = extentWy;
- }
-
- public float transformAngle(float angle) {
- float ta = scalingY < 0 ? -angle : angle;
- return (float)(scalingX < 0 ? Math.PI - ta : ta);
- }
-
- public void setCurrentPoint(Point p) {
- currentPoint = p;
- }
-
- public Point getCurrentPoint() {
- return currentPoint;
- }
-
- public MetaBrush getCurrentBrush() {
- return currentBrush;
- }
-
- public MetaPen getCurrentPen() {
- return currentPen;
- }
-
- public MetaFont getCurrentFont() {
- return currentFont;
- }
-
- /** Getter for property currentBackgroundColor.
- * @return Value of property currentBackgroundColor.
- */
- public Color getCurrentBackgroundColor() {
- return currentBackgroundColor;
- }
-
- /** Setter for property currentBackgroundColor.
- * @param currentBackgroundColor New value of property currentBackgroundColor.
- */
- public void setCurrentBackgroundColor(Color currentBackgroundColor) {
- this.currentBackgroundColor = currentBackgroundColor;
- }
-
- /** Getter for property currentTextColor.
- * @return Value of property currentTextColor.
- */
- public Color getCurrentTextColor() {
- return currentTextColor;
- }
-
- /** Setter for property currentTextColor.
- * @param currentTextColor New value of property currentTextColor.
- */
- public void setCurrentTextColor(Color currentTextColor) {
- this.currentTextColor = currentTextColor;
- }
-
- /** Getter for property backgroundMode.
- * @return Value of property backgroundMode.
- */
- public int getBackgroundMode() {
- return backgroundMode;
- }
-
- /** Setter for property backgroundMode.
- * @param backgroundMode New value of property backgroundMode.
- */
- public void setBackgroundMode(int backgroundMode) {
- this.backgroundMode = backgroundMode;
- }
-
- /** Getter for property textAlign.
- * @return Value of property textAlign.
- */
- public int getTextAlign() {
- return textAlign;
- }
-
- /** Setter for property textAlign.
- * @param textAlign New value of property textAlign.
- */
- public void setTextAlign(int textAlign) {
- this.textAlign = textAlign;
- }
-
- /** Getter for property polyFillMode.
- * @return Value of property polyFillMode.
- */
- public int getPolyFillMode() {
- return polyFillMode;
- }
-
- /** Setter for property polyFillMode.
- * @param polyFillMode New value of property polyFillMode.
- */
- public void setPolyFillMode(int polyFillMode) {
- this.polyFillMode = polyFillMode;
- }
-
- public void setLineJoinRectangle(PdfContentByte cb) {
- if (lineJoin != 0) {
- lineJoin = 0;
- cb.setLineJoin(0);
- }
- }
-
- public void setLineJoinPolygon(PdfContentByte cb) {
- if (lineJoin == 0) {
- lineJoin = 1;
- cb.setLineJoin(1);
- }
- }
-
- public boolean getLineNeutral() {
- return (lineJoin == 0);
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/events/FieldPositioningEvents.java b/src/main/java/com/lowagie/text/pdf/events/FieldPositioningEvents.java
deleted file mode 100644
index 144ebcc..0000000
--- a/src/main/java/com/lowagie/text/pdf/events/FieldPositioningEvents.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2005 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-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.events;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-import com.lowagie.text.Document;
-import com.lowagie.text.DocumentException;
-import com.lowagie.text.ExceptionConverter;
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfFormField;
-import com.lowagie.text.pdf.PdfName;
-import com.lowagie.text.pdf.PdfPCell;
-import com.lowagie.text.pdf.PdfPCellEvent;
-import com.lowagie.text.pdf.PdfPageEventHelper;
-import com.lowagie.text.pdf.PdfRectangle;
-import com.lowagie.text.pdf.PdfWriter;
-import com.lowagie.text.pdf.TextField;
-
-/**
- * Class for an index.
- *
- * @author Michael Niedermair
- */
-public class FieldPositioningEvents extends PdfPageEventHelper implements PdfPCellEvent {
-
- /**
- * Keeps a map with fields that are to be positioned in inGenericTag.
- */
- protected HashMap genericChunkFields = new HashMap();
-
- /**
- * Keeps the form field that is to be positioned in a cellLayout event.
- */
- protected PdfFormField cellField = null;
-
- /**
- * The PdfWriter to use when a field has to added in a cell event.
- */
- protected PdfWriter fieldWriter = null;
- /**
- * The PdfFormField that is the parent of the field added in a cell event.
- */
- protected PdfFormField parent = null;
-
- /** Creates a new event. This constructor will be used if you need to position fields with Chunk objects. */
- public FieldPositioningEvents() {}
-
- /** Some extra padding that will be taken into account when defining the widget. */
- public float padding;
-
- /**
- * Add a PdfFormField that has to be tied to a generic Chunk.
- */
- public void addField(String text, PdfFormField field) {
- genericChunkFields.put(text, field);
- }
-
- /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. */
- public FieldPositioningEvents(PdfWriter writer, PdfFormField field) {
- this.cellField = field;
- this.fieldWriter = writer;
- }
-
- /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event. */
- public FieldPositioningEvents(PdfFormField parent, PdfFormField field) {
- this.cellField = field;
- this.parent = parent;
- }
-
- /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event.
- * @throws DocumentException
- * @throws IOException*/
- public FieldPositioningEvents(PdfWriter writer, String text) throws IOException, DocumentException {
- this.fieldWriter = writer;
- TextField tf = new TextField(writer, new Rectangle(0, 0), text);
- tf.setFontSize(14);
- cellField = tf.getTextField();
- }
-
- /** Creates a new event. This constructor will be used if you need to position fields with a Cell Event.
- * @throws DocumentException
- * @throws IOException*/
- public FieldPositioningEvents(PdfWriter writer, PdfFormField parent, String text) throws IOException, DocumentException {
- this.parent = parent;
- TextField tf = new TextField(writer, new Rectangle(0, 0), text);
- tf.setFontSize(14);
- cellField = tf.getTextField();
- }
-
- /**
- * @param padding The padding to set.
- */
- public void setPadding(float padding) {
- this.padding = padding;
- }
-
- /**
- * @param parent The parent to set.
- */
- public void setParent(PdfFormField parent) {
- this.parent = parent;
- }
- /**
- * @see com.lowagie.text.pdf.PdfPageEvent#onGenericTag(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document, com.lowagie.text.Rectangle, java.lang.String)
- */
- public void onGenericTag(PdfWriter writer, Document document,
- Rectangle rect, String text) {
- rect.setBottom(rect.bottom() - 3);
- PdfFormField field = (PdfFormField) genericChunkFields.get(text);
- if (field == null) {
- TextField tf = new TextField(writer, new Rectangle(rect.left(padding), rect.bottom(padding), rect.right(padding), rect.top(padding)), text);
- tf.setFontSize(14);
- try {
- field = tf.getTextField();
- } catch (Exception e) {
- throw new ExceptionConverter(e);
- }
- }
- else {
- field.put(PdfName.RECT, new PdfRectangle(rect.left(padding), rect.bottom(padding), rect.right(padding), rect.top(padding)));
- }
- if (parent == null)
- writer.addAnnotation(field);
- else
- parent.addKid(field);
- }
-
- /**
- * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell, com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[])
- */
- public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvases) {
- if (cellField == null || (fieldWriter == null && parent == null)) throw new ExceptionConverter(new IllegalArgumentException("You have used the wrong constructor for this FieldPositioningEvents class."));
- cellField.put(PdfName.RECT, new PdfRectangle(rect.left(padding), rect.bottom(padding), rect.right(padding), rect.top(padding)));
- if (parent == null)
- fieldWriter.addAnnotation(cellField);
- else
- parent.addKid(cellField);
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/events/IndexEvents.java b/src/main/java/com/lowagie/text/pdf/events/IndexEvents.java
deleted file mode 100644
index 13925a5..0000000
--- a/src/main/java/com/lowagie/text/pdf/events/IndexEvents.java
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright 2005 by Michael Niedermair.
- *
- * 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.events;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.lowagie.text.Chunk;
-import com.lowagie.text.Document;
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.PdfPageEventHelper;
-import com.lowagie.text.pdf.PdfWriter;
-
-/**
- * Class for an index.
- *
- * @author Michael Niedermair
- */
-public class IndexEvents extends PdfPageEventHelper {
-
- /**
- * keeps the indextag with the pagenumber
- */
- private Map indextag = new TreeMap();
-
- /**
- * All the text that is passed to this event, gets registered in the indexentry.
- *
- * @see com.lowagie.text.pdf.PdfPageEventHelper#onGenericTag(
- * com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document,
- * com.lowagie.text.Rectangle, java.lang.String)
- */
- public void onGenericTag(PdfWriter writer, Document document,
- Rectangle rect, String text) {
- indextag.put(text, new Integer(writer.getPageNumber()));
- }
-
- // --------------------------------------------------------------------
- /**
- * indexcounter
- */
- private long indexcounter = 0;
-
- /**
- * the list for the index entry
- */
- private List indexentry = new ArrayList();
-
- /**
- * Create an index entry.
- *
- * @param text The text for the Chunk.
- * @param in1 The first level.
- * @param in2 The second level.
- * @param in3 The third level.
- * @return Returns the Chunk.
- */
- public Chunk create(final String text, final String in1, final String in2,
- final String in3) {
-
- Chunk chunk = new Chunk(text);
- String tag = "idx_" + String.valueOf(indexcounter++);
- chunk.setGenericTag(tag);
- chunk.setLocalDestination(tag);
- Entry entry = new Entry(in1, in2, in3, tag);
- indexentry.add(entry);
- return chunk;
- }
-
- /**
- * Create an index entry.
- *
- * @param text The text for the Chunk.
- * @param in1 The first level.
- * @return Returns the Chunk.
- */
- public Chunk create(final String text, final String in1) {
- return create(text, in1, "", "");
- }
-
- /**
- * Create an index entry.
- *
- * @param text The text for the Chunk.
- * @param in1 The first level.
- * @param in2 The second level.
- * @return Returns the Chunk.
- */
- public Chunk create(final String text, final String in1, final String in2) {
- return create(text, in1, in2, "");
- }
-
- /**
- * Create an index entry.
- *
- * @param text The text.
- * @param in1 The first level.
- * @param in2 The second level.
- * @param in3 The third level.
- */
- public void create(final Chunk text, final String in1, final String in2,
- final String in3) {
-
- String tag = "idx_" + String.valueOf(indexcounter++);
- text.setGenericTag(tag);
- text.setLocalDestination(tag);
- Entry entry = new Entry(in1, in2, in3, tag);
- indexentry.add(entry);
- }
-
- /**
- * Create an index entry.
- *
- * @param text The text.
- * @param in1 The first level.
- */
- public void create(final Chunk text, final String in1) {
- create(text, in1, "", "");
- }
-
- /**
- * Create an index entry.
- *
- * @param text The text.
- * @param in1 The first level.
- * @param in2 The second level.
- */
- public void create(final Chunk text, final String in1, final String in2) {
- create(text, in1, in2, "");
- }
-
- /**
- * Comparator for sorting the index
- */
- private Comparator comparator = new Comparator() {
-
- public int compare(Object arg0, Object arg1) {
- Entry en1 = (Entry) arg0;
- Entry en2 = (Entry) arg1;
-
- int rt = 0;
- if (en1.getIn1() != null && en2.getIn1() != null) {
- if ((rt = en1.getIn1().compareToIgnoreCase(en2.getIn1())) == 0) {
- // in1 equals
- if (en1.getIn2() != null && en2.getIn2() != null) {
- if ((rt = en1.getIn2()
- .compareToIgnoreCase(en2.getIn2())) == 0) {
- // in2 equals
- if (en1.getIn3() != null && en2.getIn3() != null) {
- rt = en1.getIn3().compareToIgnoreCase(
- en2.getIn3());
- }
- }
- }
- }
- }
- return rt;
- }
- };
-
- /**
- * Set the comparator.
- * @param aComparator The comparator to set.
- */
- public void setComparator(Comparator aComparator) {
- comparator = aComparator;
- }
-
- /**
- * Returns the sorted list with the entries and the collected page numbers.
- * @return Returns the sorted list with the entries and teh collected page numbers.
- */
- public List getSortedEntries() {
-
- Map grouped = new HashMap();
-
- for (int i = 0; i < indexentry.size(); i++) {
- Entry e = (Entry) indexentry.get(i);
- String key = e.getKey();
-
- Entry master = (Entry) grouped.get(key);
- if (master != null) {
- master.addPageNumberAndTag(e.getPageNumber(), e.getTag());
- } else {
- e.addPageNumberAndTag(e.getPageNumber(), e.getTag());
- grouped.put(key, e);
- }
- }
-
- // copy to a list and sort it
- List sorted = new ArrayList(grouped.size());
- Iterator it = grouped.keySet().iterator();
- while (it.hasNext()) {
- String key = (String) it.next();
- Entry e = (Entry) grouped.get(key);
- sorted.add(e);
- }
- Collections.sort(sorted, comparator);
- return sorted;
- }
-
- // --------------------------------------------------------------------
- /**
- * Class for an index entry.
- * <p>
- * In the first step, only in1, in2,in3 and tag are used.
- * After the collections of the index entries, pagenumbers are used.
- * </p>
- */
- public class Entry {
-
- /**
- * first level
- */
- private String in1;
-
- /**
- * second level
- */
- private String in2;
-
- /**
- * third level
- */
- private String in3;
-
- /**
- * the tag
- */
- private String tag;
-
- /**
- * the lsit of all page numbers.
- */
- private List pagenumbers = new ArrayList();
-
- /**
- * the lsit of all tags.
- */
- private List tags = new ArrayList();
-
- /**
- * Create a new object.
- * @param aIn1 The first level.
- * @param aIn2 The second level.
- * @param aIn3 The third level.
- * @param aTag The tag.
- */
- public Entry(final String aIn1, final String aIn2, final String aIn3,
- final String aTag) {
- in1 = aIn1;
- in2 = aIn2;
- in3 = aIn3;
- tag = aTag;
- }
-
- /**
- * Returns the in1.
- * @return Returns the in1.
- */
- public String getIn1() {
- return in1;
- }
-
- /**
- * Returns the in2.
- * @return Returns the in2.
- */
- public String getIn2() {
- return in2;
- }
-
- /**
- * Returns the in3.
- * @return Returns the in3.
- */
- public String getIn3() {
- return in3;
- }
-
- /**
- * Returns the tag.
- * @return Returns the tag.
- */
- public String getTag() {
- return tag;
- }
-
- /**
- * Returns the pagenumer for this entry.
- * @return Returns the pagenumer for this entry.
- */
- public int getPageNumber() {
- int rt = -1;
- Integer i = (Integer) indextag.get(tag);
- if (i != null) {
- rt = i.intValue();
- }
- return rt;
- }
-
- /**
- * Add a pagenumber.
- * @param number The page number.
- * @param tag
- */
- public void addPageNumberAndTag(final int number, final String tag) {
- pagenumbers.add(new Integer(number));
- tags.add(tag);
- }
-
- /**
- * Returns the key for the map-entry.
- * @return Returns the key for the map-entry.
- */
- public String getKey() {
- return in1 + "!" + in2 + "!" + in3;
- }
-
- /**
- * Returns the pagenumbers.
- * @return Returns the pagenumbers.
- */
- public List getPagenumbers() {
- return pagenumbers;
- }
-
- /**
- * Returns the tags.
- * @return Returns the tags.
- */
- public List getTags() {
- return tags;
- }
-
- /**
- * print the entry (only for test)
- * @return the toString implementation of the entry
- */
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append(in1).append(" ");
- buf.append(in2).append(" ");
- buf.append(in3).append(" ");
- for (int i = 0; i < pagenumbers.size(); i++) {
- buf.append(pagenumbers.get(i)).append(" ");
- }
- return buf.toString();
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java b/src/main/java/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java
deleted file mode 100644
index 080f380..0000000
--- a/src/main/java/com/lowagie/text/pdf/events/PdfPCellEventForwarder.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * $Id: PdfPCellEventForwarder.java,v 1.1 2005/10/27 15:57:53 blowagie Exp $
- * $Name: $
- *
- * Copyright 2005 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.events;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfPCell;
-import com.lowagie.text.pdf.PdfPCellEvent;
-
-/**
- * If you want to add more than one event to a cell,
- * you have to construct a PdfPCellEventForwarder, add the
- * different events to this object and add the forwarder to
- * the PdfPCell.
- */
-
-public class PdfPCellEventForwarder implements PdfPCellEvent {
-
- /** ArrayList containing all the PageEvents that have to be executed. */
- protected ArrayList events = new ArrayList();
-
- /**
- * Add a page event to the forwarder.
- * @param event an event that has to be added to the forwarder.
- */
- public void addCellEvent(PdfPCellEvent event) {
- events.add(event);
- }
-
- /**
- * @see com.lowagie.text.pdf.PdfPCellEvent#cellLayout(com.lowagie.text.pdf.PdfPCell, com.lowagie.text.Rectangle, com.lowagie.text.pdf.PdfContentByte[])
- */
- public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
- PdfPCellEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPCellEvent)i.next();
- event.cellLayout(cell, position, canvases);
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java b/src/main/java/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java
deleted file mode 100644
index 8645385..0000000
--- a/src/main/java/com/lowagie/text/pdf/events/PdfPTableEventForwarder.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * $Id: PdfPTableEventForwarder.java,v 1.1 2005/10/27 15:57:52 blowagie Exp $
- * $Name: $
- *
- * Copyright 2005 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.events;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import com.lowagie.text.pdf.PdfContentByte;
-import com.lowagie.text.pdf.PdfPTable;
-import com.lowagie.text.pdf.PdfPTableEvent;
-
-/**
- * If you want to add more than one page event to a PdfPTable,
- * you have to construct a PdfPTableEventForwarder, add the
- * different events to this object and add the forwarder to
- * the PdfWriter.
- */
-
-public class PdfPTableEventForwarder implements PdfPTableEvent {
-
- /** ArrayList containing all the PageEvents that have to be executed. */
- protected ArrayList events = new ArrayList();
-
- /**
- * Add a page event to the forwarder.
- * @param event an event that has to be added to the forwarder.
- */
- public void addTableEvent(PdfPTableEvent event) {
- events.add(event);
- }
-
- /**
- * @see com.lowagie.text.pdf.PdfPTableEvent#tableLayout(com.lowagie.text.pdf.PdfPTable, float[][], float[], int, int, com.lowagie.text.pdf.PdfContentByte[])
- */
- public void tableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases) {
- PdfPTableEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPTableEvent)i.next();
- event.tableLayout(table, widths, heights, headerRows, rowStart, canvases);
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/events/PdfPageEventForwarder.java b/src/main/java/com/lowagie/text/pdf/events/PdfPageEventForwarder.java
deleted file mode 100644
index 58bf3c2..0000000
--- a/src/main/java/com/lowagie/text/pdf/events/PdfPageEventForwarder.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * $Id: PdfPageEventForwarder.java,v 1.1 2005/10/07 07:14:18 blowagie Exp $
- * $Name: $
- *
- * Copyright 2005 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.events;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import com.lowagie.text.Document;
-import com.lowagie.text.Rectangle;
-import com.lowagie.text.Paragraph;
-import com.lowagie.text.pdf.PdfPageEvent;
-import com.lowagie.text.pdf.PdfWriter;
-
-/**
- * If you want to add more than one page event to a PdfWriter,
- * you have to construct a PdfPageEventForwarder, add the
- * different events to this object and add the forwarder to
- * the PdfWriter.
- */
-
-public class PdfPageEventForwarder implements PdfPageEvent {
-
- /** ArrayList containing all the PageEvents that have to be executed. */
- protected ArrayList events = new ArrayList();
-
- /**
- * Add a page event to the forwarder.
- * @param event an event that has to be added to the forwarder.
- */
- public void addPageEvent(PdfPageEvent event) {
- events.add(event);
- }
-
- /**
- * Called when the document is opened.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> for this document
- * @param document
- * the document
- */
- public void onOpenDocument(PdfWriter writer, Document document) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onOpenDocument(writer, document);
- }
- }
-
- /**
- * Called when a page is initialized.
- * <P>
- * Note that if even if a page is not written this method is still called.
- * It is preferable to use <CODE>onEndPage</CODE> to avoid infinite loops.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> for this document
- * @param document
- * the document
- */
- public void onStartPage(PdfWriter writer, Document document) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onStartPage(writer, document);
- }
- }
-
- /**
- * Called when a page is finished, just before being written to the
- * document.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> for this document
- * @param document
- * the document
- */
- public void onEndPage(PdfWriter writer, Document document) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onEndPage(writer, document);
- }
- }
-
- /**
- * Called when the document is closed.
- * <P>
- * Note that this method is called with the page number equal to the last
- * page plus one.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> for this document
- * @param document
- * the document
- */
- public void onCloseDocument(PdfWriter writer, Document document) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onCloseDocument(writer, document);
- }
- }
-
- /**
- * Called when a Paragraph is written.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height at which the
- * paragraph will be written to. This is useful to insert bookmarks with
- * more control.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onParagraph(writer, document, paragraphPosition);
- }
- }
-
- /**
- * Called when a Paragraph is written.
- * <P>
- * <CODE>paragraphPosition</CODE> will hold the height of the end of the
- * paragraph.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onParagraphEnd(writer, document, paragraphPosition);
- }
- }
-
- /**
- * Called when a Chapter is written.
- * <P>
- * <CODE>position</CODE> will hold the height at which the chapter will be
- * written to.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onChapter(writer, document, paragraphPosition, title);
- }
- }
-
- /**
- * Called when the end of a Chapter is reached.
- * <P>
- * <CODE>position</CODE> will hold the height of the end of the chapter.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onChapterEnd(writer, document, position);
- }
- }
-
- /**
- * Called when a Section is written.
- * <P>
- * <CODE>position</CODE> will hold the height at which the section will be
- * written to.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onSection(writer, document, paragraphPosition, depth, title);
- }
- }
-
- /**
- * Called when the end of a Section is reached.
- * <P>
- * <CODE>position</CODE> will hold the height of the section end.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> 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) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onSectionEnd(writer, document, position);
- }
- }
-
- /**
- * Called when a <CODE>Chunk</CODE> with a generic tag is written.
- * <P>
- * It is usefull to pinpoint the <CODE>Chunk</CODE> location to generate
- * bookmarks, for example.
- *
- * @param writer
- * the <CODE>PdfWriter</CODE> for this document
- * @param document
- * the document
- * @param rect
- * the <CODE>Rectangle</CODE> containing the <CODE>Chunk
- * </CODE>
- * @param text
- * the text of the tag
- */
- public void onGenericTag(PdfWriter writer, Document document,
- Rectangle rect, String text) {
- PdfPageEvent event;
- for (Iterator i = events.iterator(); i.hasNext(); ) {
- event = (PdfPageEvent)i.next();
- event.onGenericTag(writer, document, rect, text);
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java b/src/main/java/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java
deleted file mode 100644
index 57cb502..0000000
--- a/src/main/java/com/lowagie/text/pdf/fonts/FontsResourceAnchor.java
+++ /dev/null
@@ -1,62 +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.fonts;
-
-/**
- * A class to facilitate the loading of resources
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class FontsResourceAnchor {
-
- /**
- * Creates a FontsResourceAnchor
- */
- public FontsResourceAnchor() {
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/ByteVector.java b/src/main/java/com/lowagie/text/pdf/hyphenation/ByteVector.java
deleted file mode 100644
index f3a83ec..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/ByteVector.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.io.Serializable;
-
-/**
- * This class implements a simple byte vector with access to the
- * underlying array.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class ByteVector implements Serializable {
-
- /**
- * Capacity increment size
- */
- private static final int DEFAULT_BLOCK_SIZE = 2048;
- private int blockSize;
-
- /**
- * The encapsulated array
- */
- private byte[] array;
-
- /**
- * Points to next free item
- */
- private int n;
-
- public ByteVector() {
- this(DEFAULT_BLOCK_SIZE);
- }
-
- public ByteVector(int capacity) {
- if (capacity > 0) {
- blockSize = capacity;
- } else {
- blockSize = DEFAULT_BLOCK_SIZE;
- }
- array = new byte[blockSize];
- n = 0;
- }
-
- public ByteVector(byte[] a) {
- blockSize = DEFAULT_BLOCK_SIZE;
- array = a;
- n = 0;
- }
-
- public ByteVector(byte[] a, int capacity) {
- if (capacity > 0) {
- blockSize = capacity;
- } else {
- blockSize = DEFAULT_BLOCK_SIZE;
- }
- array = a;
- n = 0;
- }
-
- public byte[] getArray() {
- return array;
- }
-
- /**
- * return number of items in array
- */
- public int length() {
- return n;
- }
-
- /**
- * returns current capacity of array
- */
- public int capacity() {
- return array.length;
- }
-
- public void put(int index, byte val) {
- array[index] = val;
- }
-
- public byte get(int index) {
- return array[index];
- }
-
- /**
- * This is to implement memory allocation in the array. Like malloc().
- */
- public int alloc(int size) {
- int index = n;
- int len = array.length;
- if (n + size >= len) {
- byte[] aux = new byte[len + blockSize];
- System.arraycopy(array, 0, aux, 0, len);
- array = aux;
- }
- n += size;
- return index;
- }
-
- public void trimToSize() {
- if (n < array.length) {
- byte[] aux = new byte[n];
- System.arraycopy(array, 0, aux, 0, n);
- array = aux;
- }
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/CharVector.java b/src/main/java/com/lowagie/text/pdf/hyphenation/CharVector.java
deleted file mode 100644
index 777cc7a..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/CharVector.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.io.Serializable;
-
-/**
- * This class implements a simple char vector with access to the
- * underlying array.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class CharVector implements Cloneable, Serializable {
-
- /**
- * Capacity increment size
- */
- private static final int DEFAULT_BLOCK_SIZE = 2048;
- private int blockSize;
-
- /**
- * The encapsulated array
- */
- private char[] array;
-
- /**
- * Points to next free item
- */
- private int n;
-
- public CharVector() {
- this(DEFAULT_BLOCK_SIZE);
- }
-
- public CharVector(int capacity) {
- if (capacity > 0) {
- blockSize = capacity;
- } else {
- blockSize = DEFAULT_BLOCK_SIZE;
- }
- array = new char[blockSize];
- n = 0;
- }
-
- public CharVector(char[] a) {
- blockSize = DEFAULT_BLOCK_SIZE;
- array = a;
- n = a.length;
- }
-
- public CharVector(char[] a, int capacity) {
- if (capacity > 0) {
- blockSize = capacity;
- } else {
- blockSize = DEFAULT_BLOCK_SIZE;
- }
- array = a;
- n = a.length;
- }
-
- /**
- * Reset Vector but don't resize or clear elements
- */
- public void clear() {
- n = 0;
- }
-
- public Object clone() {
- CharVector cv = new CharVector((char[])array.clone(), blockSize);
- cv.n = this.n;
- return cv;
- }
-
- public char[] getArray() {
- return array;
- }
-
- /**
- * return number of items in array
- */
- public int length() {
- return n;
- }
-
- /**
- * returns current capacity of array
- */
- public int capacity() {
- return array.length;
- }
-
- public void put(int index, char val) {
- array[index] = val;
- }
-
- public char get(int index) {
- return array[index];
- }
-
- public int alloc(int size) {
- int index = n;
- int len = array.length;
- if (n + size >= len) {
- char[] aux = new char[len + blockSize];
- System.arraycopy(array, 0, aux, 0, len);
- array = aux;
- }
- n += size;
- return index;
- }
-
- public void trimToSize() {
- if (n < array.length) {
- char[] aux = new char[n];
- System.arraycopy(array, 0, aux, 0, n);
- array = aux;
- }
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphen.java b/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphen.java
deleted file mode 100644
index 7e2522c..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphen.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.io.Serializable;
-
-/**
- * This class represents a hyphen. A 'full' hyphen is made of 3 parts:
- * the pre-break text, post-break text and no-break. If no line-break
- * is generated at this position, the no-break text is used, otherwise,
- * pre-break and post-break are used. Typically, pre-break is equal to
- * the hyphen character and the others are empty. However, this general
- * scheme allows support for cases in some languages where words change
- * spelling if they're split across lines, like german's 'backen' which
- * hyphenates 'bak-ken'. BTW, this comes from TeX.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-
-public class Hyphen implements Serializable {
- public String preBreak;
- public String noBreak;
- public String postBreak;
-
- Hyphen(String pre, String no, String post) {
- preBreak = pre;
- noBreak = no;
- postBreak = post;
- }
-
- Hyphen(String pre) {
- preBreak = pre;
- noBreak = null;
- postBreak = null;
- }
-
- public String toString() {
- if (noBreak == null
- && postBreak == null
- && preBreak != null
- && preBreak.equals("-")) {
- return "-";
- }
- StringBuffer res = new StringBuffer("{");
- res.append(preBreak);
- res.append("}{");
- res.append(postBreak);
- res.append("}{");
- res.append(noBreak);
- res.append('}');
- return res.toString();
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenation.java b/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenation.java
deleted file mode 100644
index c86ab87..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenation.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-/**
- * This class represents a hyphenated word.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class Hyphenation {
-
- private int[] hyphenPoints;
- private String word;
-
- /**
- * number of hyphenation points in word
- */
- private int len;
-
- /**
- * rawWord as made of alternating strings and {@link Hyphen Hyphen}
- * instances
- */
- Hyphenation(String word, int[] points) {
- this.word = word;
- hyphenPoints = points;
- len = points.length;
- }
-
- /**
- * @return the number of hyphenation points in the word
- */
- public int length() {
- return len;
- }
-
- /**
- * @return the pre-break text, not including the hyphen character
- */
- public String getPreHyphenText(int index) {
- return word.substring(0, hyphenPoints[index]);
- }
-
- /**
- * @return the post-break text
- */
- public String getPostHyphenText(int index) {
- return word.substring(hyphenPoints[index]);
- }
-
- /**
- * @return the hyphenation points
- */
- public int[] getHyphenationPoints() {
- return hyphenPoints;
- }
-
- public String toString() {
- StringBuffer str = new StringBuffer();
- int start = 0;
- for (int i = 0; i < len; i++) {
- str.append(word.substring(start, hyphenPoints[i]) + "-");
- start = hyphenPoints[i];
- }
- str.append(word.substring(start));
- return str.toString();
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationException.java b/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationException.java
deleted file mode 100644
index 575e18d..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-/**
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class HyphenationException extends Exception {
-
- public HyphenationException(String msg) {
- super(msg);
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationTree.java b/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationTree.java
deleted file mode 100644
index b0d4c0b..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/HyphenationTree.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id: HyphenationTree.java,v 1.40 2005/07/16 16:49:34 blowagie Exp $ */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.io.InputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * This tree structure stores the hyphenation patterns in an efficient
- * way for fast lookup. It provides the provides the method to
- * hyphenate a word.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class HyphenationTree extends TernaryTree
- implements PatternConsumer, Serializable {
-
- /**
- * value space: stores the inteletter values
- */
- protected ByteVector vspace;
-
- /**
- * This map stores hyphenation exceptions
- */
- protected HashMap stoplist;
-
- /**
- * This map stores the character classes
- */
- protected TernaryTree classmap;
-
- /**
- * Temporary map to store interletter values on pattern loading.
- */
- private transient TernaryTree ivalues;
-
- public HyphenationTree() {
- stoplist = new HashMap(23); // usually a small table
- classmap = new TernaryTree();
- vspace = new ByteVector();
- vspace.alloc(1); // this reserves index 0, which we don't use
- }
-
- /**
- * Packs the values by storing them in 4 bits, two values into a byte
- * Values range is from 0 to 9. We use zero as terminator,
- * so we'll add 1 to the value.
- * @param values a string of digits from '0' to '9' representing the
- * interletter values.
- * @return the index into the vspace array where the packed values
- * are stored.
- */
- protected int packValues(String values) {
- int i, n = values.length();
- int m = (n & 1) == 1 ? (n >> 1) + 2 : (n >> 1) + 1;
- int offset = vspace.alloc(m);
- byte[] va = vspace.getArray();
- for (i = 0; i < n; i++) {
- int j = i >> 1;
- byte v = (byte)((values.charAt(i) - '0' + 1) & 0x0f);
- if ((i & 1) == 1) {
- va[j + offset] = (byte)(va[j + offset] | v);
- } else {
- va[j + offset] = (byte)(v << 4); // big endian
- }
- }
- va[m - 1 + offset] = 0; // terminator
- return offset;
- }
-
- protected String unpackValues(int k) {
- StringBuffer buf = new StringBuffer();
- byte v = vspace.get(k++);
- while (v != 0) {
- char c = (char)((v >>> 4) - 1 + '0');
- buf.append(c);
- c = (char)(v & 0x0f);
- if (c == 0) {
- break;
- }
- c = (char)(c - 1 + '0');
- buf.append(c);
- v = vspace.get(k++);
- }
- return buf.toString();
- }
-
- public void loadSimplePatterns(InputStream stream) throws HyphenationException {
- SimplePatternParser pp = new SimplePatternParser();
- ivalues = new TernaryTree();
-
- pp.parse(stream, this);
-
- // patterns/values should be now in the tree
- // let's optimize a bit
- trimToSize();
- vspace.trimToSize();
- classmap.trimToSize();
-
- // get rid of the auxiliary map
- ivalues = null;
- }
-
-
- public String findPattern(String pat) {
- int k = super.find(pat);
- if (k >= 0) {
- return unpackValues(k);
- }
- return "";
- }
-
- /**
- * String compare, returns 0 if equal or
- * t is a substring of s
- */
- protected int hstrcmp(char[] s, int si, char[] t, int ti) {
- for (; s[si] == t[ti]; si++, ti++) {
- if (s[si] == 0) {
- return 0;
- }
- }
- if (t[ti] == 0) {
- return 0;
- }
- return s[si] - t[ti];
- }
-
- protected byte[] getValues(int k) {
- StringBuffer buf = new StringBuffer();
- byte v = vspace.get(k++);
- while (v != 0) {
- char c = (char)((v >>> 4) - 1);
- buf.append(c);
- c = (char)(v & 0x0f);
- if (c == 0) {
- break;
- }
- c = (char)(c - 1);
- buf.append(c);
- v = vspace.get(k++);
- }
- byte[] res = new byte[buf.length()];
- for (int i = 0; i < res.length; i++) {
- res[i] = (byte)buf.charAt(i);
- }
- return res;
- }
-
- /**
- * <p>Search for all possible partial matches of word starting
- * at index an update interletter values. In other words, it
- * does something like:</p>
- * <code>
- * for(i=0; i<patterns.length; i++) {
- * if ( word.substring(index).startsWidth(patterns[i]) )
- * update_interletter_values(patterns[i]);
- * }
- * </code>
- * <p>But it is done in an efficient way since the patterns are
- * stored in a ternary tree. In fact, this is the whole purpose
- * of having the tree: doing this search without having to test
- * every single pattern. The number of patterns for languages
- * such as English range from 4000 to 10000. Thus, doing thousands
- * of string comparisons for each word to hyphenate would be
- * really slow without the tree. The tradeoff is memory, but
- * using a ternary tree instead of a trie, almost halves the
- * the memory used by Lout or TeX. It's also faster than using
- * a hash table</p>
- * @param word null terminated word to match
- * @param index start index from word
- * @param il interletter values array to update
- */
- protected void searchPatterns(char[] word, int index, byte[] il) {
- byte[] values;
- int i = index;
- char p, q;
- char sp = word[i];
- p = root;
-
- while (p > 0 && p < sc.length) {
- if (sc[p] == 0xFFFF) {
- if (hstrcmp(word, i, kv.getArray(), lo[p]) == 0) {
- values = getValues(eq[p]); // data pointer is in eq[]
- int j = index;
- for (int k = 0; k < values.length; k++) {
- if (j < il.length && values[k] > il[j]) {
- il[j] = values[k];
- }
- j++;
- }
- }
- return;
- }
- int d = sp - sc[p];
- if (d == 0) {
- if (sp == 0) {
- break;
- }
- sp = word[++i];
- p = eq[p];
- q = p;
-
- // look for a pattern ending at this position by searching for
- // the null char ( splitchar == 0 )
- while (q > 0 && q < sc.length) {
- if (sc[q] == 0xFFFF) { // stop at compressed branch
- break;
- }
- if (sc[q] == 0) {
- values = getValues(eq[q]);
- int j = index;
- for (int k = 0; k < values.length; k++) {
- if (j < il.length && values[k] > il[j]) {
- il[j] = values[k];
- }
- j++;
- }
- break;
- } else {
- q = lo[q];
-
- /**
- * actually the code should be:
- * q = sc[q] < 0 ? hi[q] : lo[q];
- * but java chars are unsigned
- */
- }
- }
- } else {
- p = d < 0 ? lo[p] : hi[p];
- }
- }
- }
-
- /**
- * Hyphenate word and return a Hyphenation object.
- * @param word the word to be hyphenated
- * @param remainCharCount Minimum number of characters allowed
- * before the hyphenation point.
- * @param pushCharCount Minimum number of characters allowed after
- * the hyphenation point.
- * @return a {@link Hyphenation Hyphenation} object representing
- * the hyphenated word or null if word is not hyphenated.
- */
- public Hyphenation hyphenate(String word, int remainCharCount,
- int pushCharCount) {
- char[] w = word.toCharArray();
- return hyphenate(w, 0, w.length, remainCharCount, pushCharCount);
- }
-
- /**
- * w = "****nnllllllnnn*****",
- * where n is a non-letter, l is a letter,
- * all n may be absent, the first n is at offset,
- * the first l is at offset + iIgnoreAtBeginning;
- * word = ".llllll.'\0'***",
- * where all l in w are copied into word.
- * In the first part of the routine len = w.length,
- * in the second part of the routine len = word.length.
- * Three indices are used:
- * index(w), the index in w,
- * index(word), the index in word,
- * letterindex(word), the index in the letter part of word.
- * The following relations exist:
- * index(w) = offset + i - 1
- * index(word) = i - iIgnoreAtBeginning
- * letterindex(word) = index(word) - 1
- * (see first loop).
- * It follows that:
- * index(w) - index(word) = offset - 1 + iIgnoreAtBeginning
- * index(w) = letterindex(word) + offset + iIgnoreAtBeginning
- */
-
- /**
- * Hyphenate word and return an array of hyphenation points.
- * @param w char array that contains the word
- * @param offset Offset to first character in word
- * @param len Length of word
- * @param remainCharCount Minimum number of characters allowed
- * before the hyphenation point.
- * @param pushCharCount Minimum number of characters allowed after
- * the hyphenation point.
- * @return a {@link Hyphenation Hyphenation} object representing
- * the hyphenated word or null if word is not hyphenated.
- */
- public Hyphenation hyphenate(char[] w, int offset, int len,
- int remainCharCount, int pushCharCount) {
- int i;
- char[] word = new char[len + 3];
-
- // normalize word
- char[] c = new char[2];
- int iIgnoreAtBeginning = 0;
- int iLength = len;
- boolean bEndOfLetters = false;
- for (i = 1; i <= len; i++) {
- c[0] = w[offset + i - 1];
- int nc = classmap.find(c, 0);
- if (nc < 0) { // found a non-letter character ...
- if (i == (1 + iIgnoreAtBeginning)) {
- // ... before any letter character
- iIgnoreAtBeginning ++;
- } else {
- // ... after a letter character
- bEndOfLetters = true;
- }
- iLength --;
- } else {
- if (!bEndOfLetters) {
- word[i - iIgnoreAtBeginning] = (char)nc;
- } else {
- return null;
- }
- }
- }
- len = iLength;
- if (len < (remainCharCount + pushCharCount)) {
- // word is too short to be hyphenated
- return null;
- }
- int[] result = new int[len + 1];
- int k = 0;
-
- // check exception list first
- String sw = new String(word, 1, len);
- if (stoplist.containsKey(sw)) {
- // assume only simple hyphens (Hyphen.pre="-", Hyphen.post = Hyphen.no = null)
- ArrayList hw = (ArrayList)stoplist.get(sw);
- int j = 0;
- for (i = 0; i < hw.size(); i++) {
- Object o = hw.get(i);
- // j = index(sw) = letterindex(word)?
- // result[k] = corresponding index(w)
- if (o instanceof String) {
- j += ((String)o).length();
- if (j >= remainCharCount && j < (len - pushCharCount)) {
- result[k++] = j + iIgnoreAtBeginning;
- }
- }
- }
- } else {
- // use algorithm to get hyphenation points
- word[0] = '.'; // word start marker
- word[len + 1] = '.'; // word end marker
- word[len + 2] = 0; // null terminated
- byte[] il = new byte[len + 3]; // initialized to zero
- for (i = 0; i < len + 1; i++) {
- searchPatterns(word, i, il);
- }
-
- // hyphenation points are located where interletter value is odd
- // i is letterindex(word),
- // i + 1 is index(word),
- // result[k] = corresponding index(w)
- for (i = 0; i < len; i++) {
- if (((il[i + 1] & 1) == 1) && i >= remainCharCount
- && i <= (len - pushCharCount)) {
- result[k++] = i + iIgnoreAtBeginning;
- }
- }
- }
-
-
- if (k > 0) {
- // trim result array
- int[] res = new int[k];
- System.arraycopy(result, 0, res, 0, k);
- return new Hyphenation(new String(w, offset, len), res);
- } else {
- return null;
- }
- }
-
- /**
- * Add a character class to the tree. It is used by
- * {@link SimplePatternParser SimplePatternParser} as callback to
- * add character classes. Character classes define the
- * valid word characters for hyphenation. If a word contains
- * a character not defined in any of the classes, it is not hyphenated.
- * It also defines a way to normalize the characters in order
- * to compare them with the stored patterns. Usually pattern
- * files use only lower case characters, in this case a class
- * for letter 'a', for example, should be defined as "aA", the first
- * character being the normalization char.
- */
- public void addClass(String chargroup) {
- if (chargroup.length() > 0) {
- char equivChar = chargroup.charAt(0);
- char[] key = new char[2];
- key[1] = 0;
- for (int i = 0; i < chargroup.length(); i++) {
- key[0] = chargroup.charAt(i);
- classmap.insert(key, 0, equivChar);
- }
- }
- }
-
- /**
- * Add an exception to the tree. It is used by
- * {@link SimplePatternParser SimplePatternParser} class as callback to
- * store the hyphenation exceptions.
- * @param word normalized word
- * @param hyphenatedword a vector of alternating strings and
- * {@link Hyphen hyphen} objects.
- */
- public void addException(String word, ArrayList hyphenatedword) {
- stoplist.put(word, hyphenatedword);
- }
-
- /**
- * Add a pattern to the tree. Mainly, to be used by
- * {@link SimplePatternParser SimplePatternParser} class as callback to
- * add a pattern to the tree.
- * @param pattern the hyphenation pattern
- * @param ivalue interletter weight values indicating the
- * desirability and priority of hyphenating at a given point
- * within the pattern. It should contain only digit characters.
- * (i.e. '0' to '9').
- */
- public void addPattern(String pattern, String ivalue) {
- int k = ivalues.find(ivalue);
- if (k <= 0) {
- k = packValues(ivalue);
- ivalues.insert(ivalue, (char)k);
- }
- insert(pattern, (char)k);
- }
-
- public void printStats() {
- System.out.println("Value space size = "
- + Integer.toString(vspace.length()));
- super.printStats();
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenator.java b/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenator.java
deleted file mode 100644
index bdd34b9..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/Hyphenator.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.Hashtable;
-
-import com.lowagie.text.pdf.BaseFont;
-
-/**
- * This class is the main entry point to the hyphenation package.
- * You can use only the static methods or create an instance.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public class Hyphenator {
-
- /** TODO: Don't use statics */
- private static Hashtable hyphenTrees = new Hashtable();
-
- private HyphenationTree hyphenTree = null;
- private int remainCharCount = 2;
- private int pushCharCount = 2;
- private static boolean errorDump = false;
- private static final String defaultHyphLocation = "com/lowagie/text/pdf/hyphenation/hyph/";
-
- /** Holds value of property hyphenDir. */
- private static String hyphenDir = "";
-
- /**
- * @param lang
- * @param country
- * @param leftMin
- * @param rightMin
- */
- public Hyphenator(String lang, String country, int leftMin,
- int rightMin) {
- hyphenTree = getHyphenationTree(lang, country);
- remainCharCount = leftMin;
- pushCharCount = rightMin;
- }
-
- /**
- * @param lang
- * @param country
- * @return the hyphenation tree
- */
- public static HyphenationTree getHyphenationTree(String lang,
- String country) {
- String key = lang;
- // check whether the country code has been used
- if (country != null && !country.equals("none")) {
- key += "_" + country;
- }
- // first try to find it in the cache
- if (hyphenTrees.containsKey(key)) {
- return (HyphenationTree)hyphenTrees.get(key);
- }
- if (hyphenTrees.containsKey(lang)) {
- return (HyphenationTree)hyphenTrees.get(lang);
- }
-
- HyphenationTree hTree = getResourceHyphenationTree(key);
- if (hTree == null)
- hTree = getFileHyphenationTree(key);
- // put it into the pattern cache
- if (hTree != null) {
- hyphenTrees.put(key, hTree);
- }
- return hTree;
- }
-
- /**
- * @param key
- * @return a hyphenation tree
- */
- public static HyphenationTree getResourceHyphenationTree(String key) {
- try {
- InputStream stream = BaseFont.getResourceStream(defaultHyphLocation + key + ".xml");
- if (stream == null && key.length() > 2)
- stream = BaseFont.getResourceStream(defaultHyphLocation + key.substring(0, 2) + ".xml");
- if (stream == null)
- return null;
- HyphenationTree hTree = new HyphenationTree();
- hTree.loadSimplePatterns(stream);
- return hTree;
- }
- catch (Exception e) {
- return null;
- }
- }
-
- /**
- * @param key
- * @return a hyphenation tree
- */
- public static HyphenationTree getFileHyphenationTree(String key) {
- try {
- if (hyphenDir == null)
- return null;
- InputStream stream = null;
- File hyphenFile = new File(hyphenDir, key + ".xml");
- if (hyphenFile.canRead())
- stream = new FileInputStream(hyphenFile);
- if (stream == null && key.length() > 2) {
- hyphenFile = new File(hyphenDir, key.substring(0, 2) + ".xml");
- if (hyphenFile.canRead())
- stream = new FileInputStream(hyphenFile);
- }
- if (stream == null)
- return null;
- HyphenationTree hTree = new HyphenationTree();
- hTree.loadSimplePatterns(stream);
- return hTree;
- }
- catch (Exception e) {
- return null;
- }
- }
-
- /**
- * @param lang
- * @param country
- * @param word
- * @param leftMin
- * @param rightMin
- * @return a hyphenation object
- */
- public static Hyphenation hyphenate(String lang, String country,
- String word, int leftMin,
- int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country);
- if (hTree == null) {
- //log.error("Error building hyphenation tree for language "
- // + lang);
- return null;
- }
- return hTree.hyphenate(word, leftMin, rightMin);
- }
-
- /**
- * @param lang
- * @param country
- * @param word
- * @param offset
- * @param len
- * @param leftMin
- * @param rightMin
- * @return a hyphenation object
- */
- public static Hyphenation hyphenate(String lang, String country,
- char[] word, int offset, int len,
- int leftMin, int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country);
- if (hTree == null) {
- //log.error("Error building hyphenation tree for language "
- // + lang);
- return null;
- }
- return hTree.hyphenate(word, offset, len, leftMin, rightMin);
- }
-
- /**
- * @param min
- */
- public void setMinRemainCharCount(int min) {
- remainCharCount = min;
- }
-
- /**
- * @param min
- */
- public void setMinPushCharCount(int min) {
- pushCharCount = min;
- }
-
- /**
- * @param lang
- * @param country
- */
- public void setLanguage(String lang, String country) {
- hyphenTree = getHyphenationTree(lang, country);
- }
-
- /**
- * @param word
- * @param offset
- * @param len
- * @return a hyphenation object
- */
- public Hyphenation hyphenate(char[] word, int offset, int len) {
- if (hyphenTree == null) {
- return null;
- }
- return hyphenTree.hyphenate(word, offset, len, remainCharCount,
- pushCharCount);
- }
-
- /**
- * @param word
- * @return a hyphenation object
- */
- public Hyphenation hyphenate(String word) {
- if (hyphenTree == null) {
- return null;
- }
- return hyphenTree.hyphenate(word, remainCharCount, pushCharCount);
- }
-
- /** Getter for property hyphenDir.
- * @return Value of property hyphenDir.
- */
- public static String getHyphenDir() {
- return hyphenDir;
- }
-
- /** Setter for property hyphenDir.
- * @param _hyphenDir New value of property hyphenDir.
- */
- public static void setHyphenDir(String _hyphenDir) {
- hyphenDir = _hyphenDir;
- }
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/PatternConsumer.java b/src/main/java/com/lowagie/text/pdf/hyphenation/PatternConsumer.java
deleted file mode 100644
index d7c6b63..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/PatternConsumer.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.util.ArrayList;
-
-/**
- * This interface is used to connect the XML pattern file parser to
- * the hyphenation tree.
- *
- * @author Carlos Villegas <cav@uniscope.co.jp>
- */
-public interface PatternConsumer {
-
- /**
- * Add a character class.
- * A character class defines characters that are considered
- * equivalent for the purpose of hyphenation (e.g. "aA"). It
- * usually means to ignore case.
- * @param chargroup character group
- */
- void addClass(String chargroup);
-
- /**
- * Add a hyphenation exception. An exception replaces the
- * result obtained by the algorithm for cases for which this
- * fails or the user wants to provide his own hyphenation.
- * A hyphenatedword is a vector of alternating String's and
- * {@link Hyphen Hyphen} instances
- */
- void addException(String word, ArrayList hyphenatedword);
-
- /**
- * Add hyphenation patterns.
- * @param pattern the pattern
- * @param values interletter values expressed as a string of
- * digit characters.
- */
- void addPattern(String pattern, String values);
-
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java b/src/main/java/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java
deleted file mode 100644
index ade8885..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/SimplePatternParser.java
+++ /dev/null
@@ -1,278 +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.hyphenation;
-
-import com.lowagie.text.pdf.*;
-import com.lowagie.text.ExceptionConverter;
-import java.util.ArrayList;
-import java.util.StringTokenizer;
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.FileInputStream;
-
-/** Parses the xml hyphenation pattern.
- *
- * @author Paulo Soares (psoares@consiste.pt)
- */
-public class SimplePatternParser implements SimpleXMLDocHandler, PatternConsumer {
- int currElement;
- PatternConsumer consumer;
- StringBuffer token;
- ArrayList exception;
- char hyphenChar;
- SimpleXMLParser parser;
-
- static final int ELEM_CLASSES = 1;
- static final int ELEM_EXCEPTIONS = 2;
- static final int ELEM_PATTERNS = 3;
- static final int ELEM_HYPHEN = 4;
-
- /** Creates a new instance of PatternParser2 */
- public SimplePatternParser() {
- token = new StringBuffer();
- hyphenChar = '-'; // default
- }
-
- public void parse(InputStream stream, PatternConsumer consumer) {
- this.consumer = consumer;
- try {
- SimpleXMLParser.parse(this, stream);
- }
- catch (IOException e) {
- throw new ExceptionConverter(e);
- }
- finally {
- try{stream.close();}catch(Exception e){}
- }
- }
-
- protected static String getPattern(String word) {
- StringBuffer pat = new StringBuffer();
- int len = word.length();
- for (int i = 0; i < len; i++) {
- if (!Character.isDigit(word.charAt(i))) {
- pat.append(word.charAt(i));
- }
- }
- return pat.toString();
- }
-
- protected ArrayList normalizeException(ArrayList ex) {
- ArrayList res = new ArrayList();
- for (int i = 0; i < ex.size(); i++) {
- Object item = ex.get(i);
- if (item instanceof String) {
- String str = (String)item;
- StringBuffer buf = new StringBuffer();
- for (int j = 0; j < str.length(); j++) {
- char c = str.charAt(j);
- if (c != hyphenChar) {
- buf.append(c);
- } else {
- res.add(buf.toString());
- buf.setLength(0);
- char[] h = new char[1];
- h[0] = hyphenChar;
- // we use here hyphenChar which is not necessarily
- // the one to be printed
- res.add(new Hyphen(new String(h), null, null));
- }
- }
- if (buf.length() > 0) {
- res.add(buf.toString());
- }
- } else {
- res.add(item);
- }
- }
- return res;
- }
-
- protected String getExceptionWord(ArrayList ex) {
- StringBuffer res = new StringBuffer();
- for (int i = 0; i < ex.size(); i++) {
- Object item = ex.get(i);
- if (item instanceof String) {
- res.append((String)item);
- } else {
- if (((Hyphen)item).noBreak != null) {
- res.append(((Hyphen)item).noBreak);
- }
- }
- }
- return res.toString();
- }
-
- protected static String getInterletterValues(String pat) {
- StringBuffer il = new StringBuffer();
- String word = pat + "a"; // add dummy letter to serve as sentinel
- int len = word.length();
- for (int i = 0; i < len; i++) {
- char c = word.charAt(i);
- if (Character.isDigit(c)) {
- il.append(c);
- i++;
- } else {
- il.append('0');
- }
- }
- return il.toString();
- }
-
- public void endDocument() {
- }
-
- public void endElement(String tag) {
- if (token.length() > 0) {
- String word = token.toString();
- switch (currElement) {
- case ELEM_CLASSES:
- consumer.addClass(word);
- break;
- case ELEM_EXCEPTIONS:
- exception.add(word);
- exception = normalizeException(exception);
- consumer.addException(getExceptionWord(exception),
- (ArrayList)exception.clone());
- break;
- case ELEM_PATTERNS:
- consumer.addPattern(getPattern(word),
- getInterletterValues(word));
- break;
- case ELEM_HYPHEN:
- // nothing to do
- break;
- }
- if (currElement != ELEM_HYPHEN) {
- token.setLength(0);
- }
- }
- if (currElement == ELEM_HYPHEN) {
- currElement = ELEM_EXCEPTIONS;
- } else {
- currElement = 0;
- }
- }
-
- public void startDocument() {
- }
-
- public void startElement(String tag, java.util.HashMap h) {
- if (tag.equals("hyphen-char")) {
- String hh = (String)h.get("value");
- if (hh != null && hh.length() == 1) {
- hyphenChar = hh.charAt(0);
- }
- } else if (tag.equals("classes")) {
- currElement = ELEM_CLASSES;
- } else if (tag.equals("patterns")) {
- currElement = ELEM_PATTERNS;
- } else if (tag.equals("exceptions")) {
- currElement = ELEM_EXCEPTIONS;
- exception = new ArrayList();
- } else if (tag.equals("hyphen")) {
- if (token.length() > 0) {
- exception.add(token.toString());
- }
- exception.add(new Hyphen((String)h.get("pre"),
- (String)h.get("no"),
- (String)h.get("post")));
- currElement = ELEM_HYPHEN;
- }
- token.setLength(0);
- }
-
- public void text(String str) {
- StringTokenizer tk = new StringTokenizer(str);
- while (tk.hasMoreTokens()) {
- String word = tk.nextToken();
- // System.out.println("\"" + word + "\"");
- switch (currElement) {
- case ELEM_CLASSES:
- consumer.addClass(word);
- break;
- case ELEM_EXCEPTIONS:
- exception.add(word);
- exception = normalizeException(exception);
- consumer.addException(getExceptionWord(exception),
- (ArrayList)exception.clone());
- exception.clear();
- break;
- case ELEM_PATTERNS:
- consumer.addPattern(getPattern(word),
- getInterletterValues(word));
- break;
- }
- }
- }
-
- // PatternConsumer implementation for testing purposes
- public void addClass(String c) {
- System.out.println("class: " + c);
- }
-
- public void addException(String w, ArrayList e) {
- System.out.println("exception: " + w + " : " + e.toString());
- }
-
- public void addPattern(String p, String v) {
- System.out.println("pattern: " + p + " : " + v);
- }
-
- public static void main(String[] args) throws Exception {
- try {
- if (args.length > 0) {
- SimplePatternParser pp = new SimplePatternParser();
- pp.parse(new FileInputStream(args[0]), pp);
- }
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/main/java/com/lowagie/text/pdf/hyphenation/TernaryTree.java b/src/main/java/com/lowagie/text/pdf/hyphenation/TernaryTree.java
deleted file mode 100644
index 0dc16e5..0000000
--- a/src/main/java/com/lowagie/text/pdf/hyphenation/TernaryTree.java
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.lowagie.text.pdf.hyphenation;
-
-import java.util.Enumeration;
-import java.util.Stack;
-import java.io.Serializable;
-
-/**
- * <h2>Ternary Search Tree.</h2>
- *
- * <p>A ternary search tree is a hibrid between a binary tree and
- * a digital search tree (trie). Keys are limited to strings.
- * A data value of type char is stored in each leaf node.
- * It can be used as an index (or pointer) to the data.
- * Branches that only contain one key are compressed to one node
- * by storing a pointer to the trailer substring of the key.
- * This class is intended to serve as base class or helper class
- * to implement Dictionary collections or the like. Ternary trees
- * have some nice properties as the following: the tree can be
- * traversed in sorted order, partial matches (wildcard) can be
- * implemented, retrieval of all keys within a given distance
- * from the target, etc. The storage requirements are higher than
- * a binary tree but a lot less than a trie. Performance is
- * comparable with a hash table, sometimes it outperforms a hash
- * function (most of the time can determine a miss faster than a hash).</p>
- *
- * <p>The main purpose of this java port is to serve as a base for
- * implementing TeX's hyphenation algorithm (see The TeXBook,
- * appendix H). Each language requires from 5000 to 15000 hyphenation
- * patterns which will be keys in this tree. The strings patterns
- * are usually small (from 2 to 5 characters), but each char in the
- * tree is stored in a node. Thus memory usage is the main concern.
- * We will sacrify 'elegance' to keep memory requirenments to the
- * minimum. Using java's char type as pointer (yes, I know pointer
- * it is a forbidden word in java) we can keep the size of the node
- * to be just 8 bytes (3 pointers and the data char). This gives
- * room for about 65000 nodes. In my tests the english patterns
- * took 7694 nodes and the german patterns 10055 nodes,
- * so I think we are safe.</p>
- *
- * <p>All said, this is a map with strings as keys and char as value.
- * Pretty limited!. It can be extended to a general map by
- * using the string representation of an object and using the
- * char value as an index to an array that contains the object
- * values.</p>
- *
- * @author cav@uniscope.co.jp
- */
-
-public class TernaryTree implements Cloneable, Serializable {
-
- /**
- * We use 4 arrays to represent a node. I guess I should have created
- * a proper node class, but somehow Knuth's pascal code made me forget
- * we now have a portable language with virtual memory management and
- * automatic garbage collection! And now is kind of late, furthermore,
- * if it ain't broken, don't fix it.
- */
-
- /**
- * Pointer to low branch and to rest of the key when it is
- * stored directly in this node, we don't have unions in java!
- */
- protected char[] lo;
-
- /**
- * Pointer to high branch.
- */
- protected char[] hi;
-
- /**
- * Pointer to equal branch and to data when this node is a string terminator.
- */
- protected char[] eq;
-
- /**
- * <P>The character stored in this node: splitchar.
- * Two special values are reserved:</P>
- * <ul><li>0x0000 as string terminator</li>
- * <li>0xFFFF to indicate that the branch starting at
- * this node is compressed</li></ul>
- * <p>This shouldn't be a problem if we give the usual semantics to
- * strings since 0xFFFF is garanteed not to be an Unicode character.</p>
- */
- protected char[] sc;
-
- /**
- * This vector holds the trailing of the keys when the branch is compressed.
- */
- protected CharVector kv;
-
- protected char root;
- protected char freenode;
- protected int length; // number of items in tree
-
- protected static final int BLOCK_SIZE = 2048; // allocation size for arrays
-
- TernaryTree() {
- init();
- }
-
- protected void init() {
- root = 0;
- freenode = 1;
- length = 0;
- lo = new char[BLOCK_SIZE];
- hi = new char[BLOCK_SIZE];
- eq = new char[BLOCK_SIZE];
- sc = new char[BLOCK_SIZE];
- kv = new CharVector();
- }
-
- /**
- * Branches are initially compressed, needing
- * one node per key plus the size of the string
- * key. They are decompressed as needed when
- * another key with same prefix
- * is inserted. This saves a lot of space,
- * specially for long keys.
- */
- public void insert(String key, char val) {
- // make sure we have enough room in the arrays
- int len = key.length()
- + 1; // maximum number of nodes that may be generated
- if (freenode + len > eq.length) {
- redimNodeArrays(eq.length + BLOCK_SIZE);
- }
- char strkey[] = new char[len--];
- key.getChars(0, len, strkey, 0);
- strkey[len] = 0;
- root = insert(root, strkey, 0, val);
- }
-
- public void insert(char[] key, int start, char val) {
- int len = strlen(key) + 1;
- if (freenode + len > eq.length) {
- redimNodeArrays(eq.length + BLOCK_SIZE);
- }
- root = insert(root, key, start, val);
- }
-
- /**
- * The actual insertion function, recursive version.
- */
- private char insert(char p, char[] key, int start, char val) {
- int len = strlen(key, start);
- if (p == 0) {
- // this means there is no branch, this node will start a new branch.
- // Instead of doing that, we store the key somewhere else and create
- // only one node with a pointer to the key
- p = freenode++;
- eq[p] = val; // holds data
- length++;
- hi[p] = 0;
- if (len > 0) {
- sc[p] = 0xFFFF; // indicates branch is compressed
- lo[p] = (char)kv.alloc(len
- + 1); // use 'lo' to hold pointer to key
- strcpy(kv.getArray(), lo[p], key, start);
- } else {
- sc[p] = 0;
- lo[p] = 0;
- }
- return p;
- }
-
- if (sc[p] == 0xFFFF) {
- // branch is compressed: need to decompress
- // this will generate garbage in the external key array
- // but we can do some garbage collection later
- char pp = freenode++;
- lo[pp] = lo[p]; // previous pointer to key
- eq[pp] = eq[p]; // previous pointer to data
- lo[p] = 0;
- if (len > 0) {
- sc[p] = kv.get(lo[pp]);
- eq[p] = pp;
- lo[pp]++;
- if (kv.get(lo[pp]) == 0) {
- // key completly decompressed leaving garbage in key array
- lo[pp] = 0;
- sc[pp] = 0;
- hi[pp] = 0;
- } else {
- // we only got first char of key, rest is still there
- sc[pp] = 0xFFFF;
- }
- } else {
- // In this case we can save a node by swapping the new node
- // with the compressed node
- sc[pp] = 0xFFFF;
- hi[p] = pp;
- sc[p] = 0;
- eq[p] = val;
- length++;
- return p;
- }
- }
- char s = key[start];
- if (s < sc[p]) {
- lo[p] = insert(lo[p], key, start, val);
- } else if (s == sc[p]) {
- if (s != 0) {
- eq[p] = insert(eq[p], key, start + 1, val);
- } else {
- // key already in tree, overwrite data
- eq[p] = val;
- }
- } else {
- hi[p] = insert(hi[p], key, start, val);
- }
- return p;
- }
-
- /**
- * Compares 2 null terminated char arrays
- */
- public static int strcmp(char[] a, int startA, char[] b, int startB) {
- for (; a[startA] == b[startB]; startA++, startB++) {
- if (a[startA] == 0) {
- return 0;
- }
- }
- return a[startA] - b[startB];
- }
-
- /**
- * Compares a string with null terminated char array
- */
- public static int strcmp(String str, char[] a, int start) {
- int i, d, len = str.length();
- for (i = 0; i < len; i++) {
- d = (int)str.charAt(i) - a[start + i];
- if (d != 0) {
- return d;
- }
- if (a[start + i] == 0) {
- return d;
- }
- }
- if (a[start + i] != 0) {
- return (int)-a[start + i];
- }
- return 0;
-
- }
-
- public static void strcpy(char[] dst, int di, char[] src, int si) {
- while (src[si] != 0) {
- dst[di++] = src[si++];
- }
- dst[di] = 0;
- }
-
- public static int strlen(char[] a, int start) {
- int len = 0;
- for (int i = start; i < a.length && a[i] != 0; i++) {
- len++;
- }
- return len;
- }
-
- public static int strlen(char[] a) {
- return strlen(a, 0);
- }
-
- public int find(String key) {
- int len = key.length();
- char strkey[] = new char[len + 1];
- key.getChars(0, len, strkey, 0);
- strkey[len] = 0;
-
- return find(strkey, 0);
- }
-
- public int find(char[] key, int start) {
- int d;
- char p = root;
- int i = start;
- char c;
-
- while (p != 0) {
- if (sc[p] == 0xFFFF) {
- if (strcmp(key, i, kv.getArray(), lo[p]) == 0) {
- return eq[p];
- } else {
- return -1;
- }
- }
- c = key[i];
- d = c - sc[p];
- if (d == 0) {
- if (c == 0) {
- return eq[p];
- }
- i++;
- p = eq[p];
- } else if (d < 0) {
- p = lo[p];
- } else {
- p = hi[p];
- }
- }
- return -1;
- }
-
- public boolean knows(String key) {
- return (find(key) >= 0);
- }
-
- // redimension the arrays
- private void redimNodeArrays(int newsize) {
- int len = newsize < lo.length ? newsize : lo.length;
- char[] na = new char[newsize];
- System.arraycopy(lo, 0, na, 0, len);
- lo = na;
- na = new char[newsize];
- System.arraycopy(hi, 0, na, 0, len);
- hi = na;
- na = new char[newsize];
- System.arraycopy(eq, 0, na, 0, len);
- eq = na;
- na = new char[newsize];
- System.arraycopy(sc, 0, na, 0, len);
- sc = na;
- }
-
- public int size() {
- return length;
- }
-
- public Object clone() {
- TernaryTree t = new TernaryTree();
- t.lo = (char[])this.lo.clone();
- t.hi = (char[])this.hi.clone();
- t.eq = (char[])this.eq.clone();
- t.sc = (char[])this.sc.clone();
- t.kv = (CharVector)this.kv.clone();
- t.root = this.root;
- t.freenode = this.freenode;
- t.length = this.length;
-
- return t;
- }
-
- /**
- * Recursively insert the median first and then the median of the
- * lower and upper halves, and so on in order to get a balanced
- * tree. The array of keys is assumed to be sorted in ascending
- * order.
- */
- protected void insertBalanced(String[] k, char[] v, int offset, int n) {
- int m;
- if (n < 1) {
- return;
- }
- m = n >> 1;
-
- insert(k[m + offset], v[m + offset]);
- insertBalanced(k, v, offset, m);
-
- insertBalanced(k, v, offset + m + 1, n - m - 1);
- }
-
-
- /**
- * Balance the tree for best search performance
- */
- public void balance() {
- // System.out.print("Before root splitchar = "); System.out.println(sc[root]);
-
- int i = 0, n = length;
- String[] k = new String[n];
- char[] v = new char[n];
- Iterator iter = new Iterator();
- while (iter.hasMoreElements()) {
- v[i] = iter.getValue();
- k[i++] = (String)iter.nextElement();
- }
- init();
- insertBalanced(k, v, 0, n);
-
- // With uniform letter distribution sc[root] should be around 'm'
- // System.out.print("After root splitchar = "); System.out.println(sc[root]);
- }
-
- /**
- * Each node stores a character (splitchar) which is part of
- * some key(s). In a compressed branch (one that only contain
- * a single string key) the trailer of the key which is not
- * already in nodes is stored externally in the kv array.
- * As items are inserted, key substrings decrease.
- * Some substrings may completely disappear when the whole
- * branch is totally decompressed.
- * The tree is traversed to find the key substrings actually
- * used. In addition, duplicate substrings are removed using
- * a map (implemented with a TernaryTree!).
- *
- */
- public void trimToSize() {
- // first balance the tree for best performance
- balance();
-
- // redimension the node arrays
- redimNodeArrays(freenode);
-
- // ok, compact kv array
- CharVector kx = new CharVector();
- kx.alloc(1);
- TernaryTree map = new TernaryTree();
- compact(kx, map, root);
- kv = kx;
- kv.trimToSize();
- }
-
- private void compact(CharVector kx, TernaryTree map, char p) {
- int k;
- if (p == 0) {
- return;
- }
- if (sc[p] == 0xFFFF) {
- k = map.find(kv.getArray(), lo[p]);
- if (k < 0) {
- k = kx.alloc(strlen(kv.getArray(), lo[p]) + 1);
- strcpy(kx.getArray(), k, kv.getArray(), lo[p]);
- map.insert(kx.getArray(), k, (char)k);
- }
- lo[p] = (char)k;
- } else {
- compact(kx, map, lo[p]);
- if (sc[p] != 0) {
- compact(kx, map, eq[p]);
- }
- compact(kx, map, hi[p]);
- }
- }
-
-
- public Enumeration keys() {
- return new Iterator();
- }
-
- public class Iterator implements Enumeration {
-
- /**
- * current node index
- */
- int cur;
-
- /**
- * current key
- */
- String curkey;
-
- private class Item implements Cloneable {
- char parent;
- char child;
-
- public Item() {
- parent = 0;
- child = 0;
- }
-
- public Item(char p, char c) {
- parent = p;
- child = c;
- }
-
- public Object clone() {
- return new Item(parent, child);
- }
-
- }
-
- /**
- * Node stack
- */
- Stack ns;
-
- /**
- * key stack implemented with a StringBuffer
- */
- StringBuffer ks;
-
- public Iterator() {
- cur = -1;
- ns = new Stack();
- ks = new StringBuffer();
- rewind();
- }
-
- public void rewind() {
- ns.removeAllElements();
- ks.setLength(0);
- cur = root;
- run();
- }
-
- public Object nextElement() {
- String res = new String(curkey);
- cur = up();
- run();
- return res;
- }
-
- public char getValue() {
- if (cur >= 0) {
- return eq[cur];
- }
- return 0;
- }
-
- public boolean hasMoreElements() {
- return (cur != -1);
- }
-
- /**
- * traverse upwards
- */
- private int up() {
- Item i = new Item();
- int res = 0;
-
- if (ns.empty()) {
- return -1;
- }
-
- if (cur != 0 && sc[cur] == 0) {
- return lo[cur];
- }
-
- boolean climb = true;
-
- while (climb) {
- i = (Item)ns.pop();
- i.child++;
- switch (i.child) {
- case 1:
- if (sc[i.parent] != 0) {
- res = eq[i.parent];
- ns.push(i.clone());
- ks.append(sc[i.parent]);
- } else {
- i.child++;
- ns.push(i.clone());
- res = hi[i.parent];
- }
- climb = false;
- break;
-
- case 2:
- res = hi[i.parent];
- ns.push(i.clone());
- if (ks.length() > 0) {
- ks.setLength(ks.length() - 1); // pop
- }
- climb = false;
- break;
-
- default:
- if (ns.empty()) {
- return -1;
- }
- climb = true;
- break;
- }
- }
- return res;
- }
-
- /**
- * traverse the tree to find next key
- */
- private int run() {
- if (cur == -1) {
- return -1;
- }
-
- boolean leaf = false;
- while (true) {
- // first go down on low branch until leaf or compressed branch
- while (cur != 0) {
- if (sc[cur] == 0xFFFF) {
- leaf = true;
- break;
- }
- ns.push(new Item((char)cur, '\u0000'));
- if (sc[cur] == 0) {
- leaf = true;
- break;
- }
- cur = lo[cur];
- }
- if (leaf) {
- break;
- }
- // nothing found, go up one node and try again
- cur = up();
- if (cur == -1) {
- return -1;
- }
- }
- // The current node should be a data node and
- // the key should be in the key stack (at least partially)
- StringBuffer buf = new StringBuffer(ks.toString());
- if (sc[cur] == 0xFFFF) {
- int p = lo[cur];
- while (kv.get(p) != 0) {
- buf.append(kv.get(p++));
- }
- }
- curkey = buf.toString();
- return 0;
- }
-
- }
-
- public void printStats() {
- System.out.println("Number of keys = " + Integer.toString(length));
- System.out.println("Node count = " + Integer.toString(freenode));
- // System.out.println("Array length = " + Integer.toString(eq.length));
- System.out.println("Key Array length = "
- + Integer.toString(kv.length()));
-
- /*
- * for(int i=0; i<kv.length(); i++)
- * if ( kv.get(i) != 0 )
- * System.out.print(kv.get(i));
- * else
- * System.out.println("");
- * System.out.println("Keys:");
- * for(Enumeration enum = keys(); enum.hasMoreElements(); )
- * System.out.println(enum.nextElement());
- */
-
- }
-
-/* public static void main(String[] args) throws Exception {
- TernaryTree tt = new TernaryTree();
- tt.insert("Carlos", 'C');
- tt.insert("Car", 'r');
- tt.insert("palos", 'l');
- tt.insert("pa", 'p');
- tt.trimToSize();
- System.out.println((char)tt.find("Car"));
- System.out.println((char)tt.find("Carlos"));
- System.out.println((char)tt.find("alto"));
- tt.printStats();
- }*/
-
-}
-