From 03c0fa8920fc53893ff5a84237f8e12bd88419ba Mon Sep 17 00:00:00 2001 From: Peter Bernard West Date: Tue, 7 May 2002 16:28:08 +0000 Subject: [PATCH] Stripped down experimental environment. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/FOP_0-20-0_Alt-Design@194797 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/image/AbstractFopImage.java | 278 ---- src/org/apache/fop/image/BmpImage.java | 204 --- src/org/apache/fop/image/FopImage.java | 62 - .../apache/fop/image/FopImageConsumer.java | 136 -- .../apache/fop/image/FopImageException.java | 23 - src/org/apache/fop/image/FopImageFactory.java | 171 --- src/org/apache/fop/image/GifJpegImage.java | 141 -- src/org/apache/fop/image/ImageArea.java | 99 -- src/org/apache/fop/image/JAIImage.java | 151 -- src/org/apache/fop/image/JimiImage.java | 157 -- src/org/apache/fop/image/SVGImage.java | 70 - .../image/analyser/AbstractImageReader.java | 55 - .../apache/fop/image/analyser/BMPReader.java | 73 - .../apache/fop/image/analyser/GIFReader.java | 68 - .../fop/image/analyser/ImageReader.java | 54 - .../image/analyser/ImageReaderFactory.java | 65 - .../apache/fop/image/analyser/JPEGReader.java | 129 -- .../apache/fop/image/analyser/PNGReader.java | 79 - .../apache/fop/image/analyser/SVGReader.java | 68 - .../apache/fop/image/analyser/TIFFReader.java | 98 -- .../fop/layout/AbsolutePositionProps.java | 25 - .../apache/fop/layout/AccessibilityProps.java | 20 - src/org/apache/fop/layout/Area.java | 414 ------ src/org/apache/fop/layout/AreaClass.java | 33 - src/org/apache/fop/layout/AreaContainer.java | 79 - src/org/apache/fop/layout/AuralProps.java | 36 - .../apache/fop/layout/BackgroundProps.java | 28 - src/org/apache/fop/layout/BlockArea.java | 223 --- .../apache/fop/layout/BodyAreaContainer.java | 394 ----- src/org/apache/fop/layout/BodyRegionArea.java | 49 - .../apache/fop/layout/BorderAndPadding.java | 158 -- src/org/apache/fop/layout/Box.java | 16 - src/org/apache/fop/layout/ColumnArea.java | 57 - src/org/apache/fop/layout/DisplaySpace.java | 27 - src/org/apache/fop/layout/ExtensionArea.java | 32 - src/org/apache/fop/layout/FontDescriptor.java | 32 - src/org/apache/fop/layout/FontInfo.java | 110 -- src/org/apache/fop/layout/FontMetric.java | 29 - src/org/apache/fop/layout/FontState.java | 127 -- .../apache/fop/layout/HyphenationProps.java | 24 - src/org/apache/fop/layout/LineArea.java | 1317 ----------------- src/org/apache/fop/layout/LinkSet.java | 163 -- .../apache/fop/layout/LinkedRectangle.java | 107 -- .../apache/fop/layout/MarginInlineProps.java | 26 - src/org/apache/fop/layout/MarginProps.java | 26 - src/org/apache/fop/layout/Page.java | 225 --- src/org/apache/fop/layout/PageMaster.java | 75 - src/org/apache/fop/layout/RegionArea.java | 46 - .../fop/layout/RelativePositionProps.java | 26 - src/org/apache/fop/layout/Space.java | 10 - src/org/apache/fop/layout/SpanArea.java | 124 -- src/org/apache/fop/layout/TextState.java | 57 - .../fop/layout/hyphenation/ByteVector.java | 113 -- .../fop/layout/hyphenation/CharVector.java | 123 -- .../apache/fop/layout/hyphenation/Hyphen.java | 56 - .../fop/layout/hyphenation/Hyphenation.java | 75 - .../hyphenation/HyphenationException.java | 19 - .../layout/hyphenation/HyphenationTree.java | 495 ------- .../fop/layout/hyphenation/Hyphenator.java | 254 ---- .../layout/hyphenation/PatternConsumer.java | 45 - .../fop/layout/hyphenation/PatternParser.java | 410 ----- .../fop/layout/hyphenation/TernaryTree.java | 634 -------- .../fop/layout/inline/ForeignObjectArea.java | 203 --- .../apache/fop/layout/inline/InlineArea.java | 115 -- .../apache/fop/layout/inline/InlineSpace.java | 94 -- .../apache/fop/layout/inline/LeaderArea.java | 63 - .../layout/inline/PageNumberInlineArea.java | 23 - .../apache/fop/layout/inline/WordArea.java | 46 - 68 files changed, 9064 deletions(-) delete mode 100644 src/org/apache/fop/image/AbstractFopImage.java delete mode 100644 src/org/apache/fop/image/BmpImage.java delete mode 100644 src/org/apache/fop/image/FopImage.java delete mode 100644 src/org/apache/fop/image/FopImageConsumer.java delete mode 100644 src/org/apache/fop/image/FopImageException.java delete mode 100644 src/org/apache/fop/image/FopImageFactory.java delete mode 100644 src/org/apache/fop/image/GifJpegImage.java delete mode 100644 src/org/apache/fop/image/ImageArea.java delete mode 100644 src/org/apache/fop/image/JAIImage.java delete mode 100644 src/org/apache/fop/image/JimiImage.java delete mode 100644 src/org/apache/fop/image/SVGImage.java delete mode 100644 src/org/apache/fop/image/analyser/AbstractImageReader.java delete mode 100644 src/org/apache/fop/image/analyser/BMPReader.java delete mode 100644 src/org/apache/fop/image/analyser/GIFReader.java delete mode 100644 src/org/apache/fop/image/analyser/ImageReader.java delete mode 100644 src/org/apache/fop/image/analyser/ImageReaderFactory.java delete mode 100644 src/org/apache/fop/image/analyser/JPEGReader.java delete mode 100644 src/org/apache/fop/image/analyser/PNGReader.java delete mode 100644 src/org/apache/fop/image/analyser/SVGReader.java delete mode 100644 src/org/apache/fop/image/analyser/TIFFReader.java delete mode 100644 src/org/apache/fop/layout/AbsolutePositionProps.java delete mode 100644 src/org/apache/fop/layout/AccessibilityProps.java delete mode 100644 src/org/apache/fop/layout/Area.java delete mode 100644 src/org/apache/fop/layout/AreaClass.java delete mode 100644 src/org/apache/fop/layout/AreaContainer.java delete mode 100644 src/org/apache/fop/layout/AuralProps.java delete mode 100644 src/org/apache/fop/layout/BackgroundProps.java delete mode 100644 src/org/apache/fop/layout/BlockArea.java delete mode 100644 src/org/apache/fop/layout/BodyAreaContainer.java delete mode 100644 src/org/apache/fop/layout/BodyRegionArea.java delete mode 100644 src/org/apache/fop/layout/BorderAndPadding.java delete mode 100644 src/org/apache/fop/layout/Box.java delete mode 100644 src/org/apache/fop/layout/ColumnArea.java delete mode 100644 src/org/apache/fop/layout/DisplaySpace.java delete mode 100644 src/org/apache/fop/layout/ExtensionArea.java delete mode 100644 src/org/apache/fop/layout/FontDescriptor.java delete mode 100644 src/org/apache/fop/layout/FontInfo.java delete mode 100644 src/org/apache/fop/layout/FontMetric.java delete mode 100644 src/org/apache/fop/layout/FontState.java delete mode 100644 src/org/apache/fop/layout/HyphenationProps.java delete mode 100644 src/org/apache/fop/layout/LineArea.java delete mode 100644 src/org/apache/fop/layout/LinkSet.java delete mode 100644 src/org/apache/fop/layout/LinkedRectangle.java delete mode 100644 src/org/apache/fop/layout/MarginInlineProps.java delete mode 100644 src/org/apache/fop/layout/MarginProps.java delete mode 100644 src/org/apache/fop/layout/Page.java delete mode 100644 src/org/apache/fop/layout/PageMaster.java delete mode 100644 src/org/apache/fop/layout/RegionArea.java delete mode 100644 src/org/apache/fop/layout/RelativePositionProps.java delete mode 100644 src/org/apache/fop/layout/Space.java delete mode 100644 src/org/apache/fop/layout/SpanArea.java delete mode 100644 src/org/apache/fop/layout/TextState.java delete mode 100644 src/org/apache/fop/layout/hyphenation/ByteVector.java delete mode 100644 src/org/apache/fop/layout/hyphenation/CharVector.java delete mode 100644 src/org/apache/fop/layout/hyphenation/Hyphen.java delete mode 100644 src/org/apache/fop/layout/hyphenation/Hyphenation.java delete mode 100644 src/org/apache/fop/layout/hyphenation/HyphenationException.java delete mode 100644 src/org/apache/fop/layout/hyphenation/HyphenationTree.java delete mode 100644 src/org/apache/fop/layout/hyphenation/Hyphenator.java delete mode 100644 src/org/apache/fop/layout/hyphenation/PatternConsumer.java delete mode 100644 src/org/apache/fop/layout/hyphenation/PatternParser.java delete mode 100644 src/org/apache/fop/layout/hyphenation/TernaryTree.java delete mode 100644 src/org/apache/fop/layout/inline/ForeignObjectArea.java delete mode 100644 src/org/apache/fop/layout/inline/InlineArea.java delete mode 100644 src/org/apache/fop/layout/inline/InlineSpace.java delete mode 100644 src/org/apache/fop/layout/inline/LeaderArea.java delete mode 100644 src/org/apache/fop/layout/inline/PageNumberInlineArea.java delete mode 100644 src/org/apache/fop/layout/inline/WordArea.java diff --git a/src/org/apache/fop/image/AbstractFopImage.java b/src/org/apache/fop/image/AbstractFopImage.java deleted file mode 100644 index 9617a7ca6..000000000 --- a/src/org/apache/fop/image/AbstractFopImage.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.util.Hashtable; -import java.net.URL; - -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.pdf.PDFFilter; -import org.apache.fop.image.analyser.ImageReaderFactory; -import org.apache.fop.image.analyser.ImageReader; - -/** - * Base class to implement the FopImage interface. - * @author Eric SCHAEFFER - * @see FopImage - */ -public abstract class AbstractFopImage implements FopImage { - - /** - * Image width (in pixel). - */ - protected int m_width = 0; - - /** - * Image height (in pixel). - */ - protected int m_height = 0; - - /** - * Image URL. - */ - protected URL m_href = null; - - /** - * ImageReader object (to obtain image header informations). - */ - protected ImageReader m_imageReader = null; - - /** - * Image color space (org.apache.fop.datatypes.ColorSpace). - */ - protected ColorSpace m_colorSpace = null; - - /** - * Bits per pixel. - */ - protected int m_bitsPerPixel = 0; - - /** - * Image data (uncompressed). - */ - protected byte[] m_bitmaps = null; - - /** - * Image data size. - */ - protected int m_bitmapsSize = 0; - - /** - * Image transparency. - */ - protected boolean m_isTransparent = false; - - /** - * Transparent color (org.apache.fop.pdf.PDFColor). - */ - protected PDFColor m_transparentColor = null; - - /** - * Constructor. - * Construct a new FopImage object and initialize its default properties: - * - * The image data isn't kept in memory. - * @param href image URL - * @return a new FopImage object - * @exception FopImageException an error occured during initialization - */ - public AbstractFopImage(URL href) throws FopImageException { - this.m_href = href; - try { - this.m_imageReader = - ImageReaderFactory.Make(this.m_href.toExternalForm(), - this.m_href.openStream()); - } catch (Exception e) { - throw new FopImageException(e.getMessage()); - } - this.m_width = this.m_imageReader.getWidth(); - this.m_height = this.m_imageReader.getHeight(); - } - - /** - * Constructor. - * Construct a new FopImage object and initialize its default properties: - * - * The image data isn't kept in memory. - * @param href image URL - * imgReader ImageReader object - * @return a new FopImage object - * @exception FopImageException an error occured during initialization - */ - public AbstractFopImage(URL href, - ImageReader imgReader) throws FopImageException { - this.m_href = href; - this.m_imageReader = imgReader; - this.m_width = this.m_imageReader.getWidth(); - this.m_height = this.m_imageReader.getHeight(); - } - - /** - * Load image data and initialize its properties. - * Subclasses need to implement this method. - * @exception FopImageException an error occured during loading - */ - abstract protected void loadImage() throws FopImageException; - - /** - * Return the image URL. - * @return the image URL (as String) - */ - public String getURL() { - return this.m_href.toString(); - } - - /** - * Return the image width. - * @return the image width - * @exception FopImageException an error occured during property retriaval - */ - public int getWidth() throws FopImageException { - if (this.m_width == 0) - this.loadImage(); - - return this.m_width; - } - - /** - * Return the image height. - * @return the image height - * @exception FopImageException an error occured during property retriaval - */ - public int getHeight() throws FopImageException { - if (this.m_height == 0) - this.loadImage(); - - return this.m_height; - } - - /** - * Return the image color space. - * @return the image color space (org.apache.fop.datatypes.ColorSpace) - * @exception FopImageException an error occured during property retriaval - */ - public ColorSpace getColorSpace() throws FopImageException { - if (this.m_colorSpace == null) - this.loadImage(); - - return this.m_colorSpace; - } - - /** - * Return the number of bits per pixel. - * @return number of bits per pixel - * @exception FopImageException an error occured during property retriaval - */ - public int getBitsPerPixel() throws FopImageException { - if (this.m_bitsPerPixel == 0) - this.loadImage(); - - return this.m_bitsPerPixel; - } - - /** - * Return the image transparency. - * @return true if the image is transparent - * @exception FopImageException an error occured during property retriaval - */ - public boolean isTransparent() throws FopImageException { - return this.m_isTransparent; - } - - /** - * Return the transparent color. - * @return the transparent color (org.apache.fop.pdf.PDFColor) - * @exception FopImageException an error occured during property retriaval - */ - public PDFColor getTransparentColor() throws FopImageException { - return this.m_transparentColor; - } - - /** - * Return the image data (uncompressed). - * @return the image data - * @exception FopImageException an error occured during loading - */ - public byte[] getBitmaps() throws FopImageException { - if (this.m_bitmaps == null) - this.loadImage(); - - return this.m_bitmaps; - } - - /** - * Return the image data size (uncompressed). - * @return the image data size - * @exception FopImageException an error occured during loading - */ - public int getBitmapsSize() throws FopImageException { - if (this.m_bitmapsSize == 0) - this.loadImage(); - - return this.m_bitmapsSize; - } - - /** - * Return the original image data (compressed). - * @return the original image data - * @exception FopImageException an error occured during loading - */ - public byte[] getRessourceBytes() throws FopImageException { - return null; - } - - /** - * Return the original image data size (compressed). - * @return the original image data size - * @exception FopImageException an error occured during loading - */ - public int getRessourceBytesSize() throws FopImageException { - return 0; - } - - /** - * Return the original image compression type. - * @return the original image compression type (org.apache.fop.pdf.PDFFilter) - * @exception FopImageException an error occured during loading - */ - public PDFFilter getPDFFilter() throws FopImageException { - return null; - } - - /** - * Free all ressource. - */ - public void close() { - /* - * For the moment, only release the bitmaps (image areas - * can share the same FopImage object) - * Thus, even if it had been called, other properties - * are still available. - */ - // this.m_width = 0; - // this.m_height = 0; - // this.m_href = null; - // this.m_colorSpace = null; - // this.m_bitsPerPixel = 0; - this.m_bitmaps = null; - this.m_bitmapsSize = 0; - // this.m_isTransparent = false; - // this.m_transparentColor = null; - } - -} - diff --git a/src/org/apache/fop/image/BmpImage.java b/src/org/apache/fop/image/BmpImage.java deleted file mode 100644 index 6918d2604..000000000 --- a/src/org/apache/fop/image/BmpImage.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -/** - * FopImage object for BMP images. - * @author Art WELCH - * @see AbstractFopImage - * @see FopImage - */ - -package org.apache.fop.image; - -// Java -import java.net.URL; -import java.io.InputStream; -import java.io.IOException; - -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.image.analyser.ImageReader; - -public class BmpImage extends AbstractFopImage { - public BmpImage(URL href) throws FopImageException { - super(href); - } - - public BmpImage(URL href, - ImageReader imgReader) throws FopImageException { - super(href, imgReader); - } - - protected void loadImage() throws FopImageException { - int wpos = 18; - int hpos = 22; // offset positioning for w and height in bmp files - int[] headermap = new int[54]; - int filepos = 0; - InputStream file = null; - byte palette[] = null; - try { - file = this.m_href.openStream(); - boolean eof = false; - while ((!eof) && (filepos < 54)) { - int input = file.read(); - if (input == -1) - eof = true; - else - headermap[filepos++] = input; - } - - if (headermap[28] == 4 || headermap[28] == 8) { - int palettesize = 1 << headermap[28]; - palette = new byte[palettesize * 3]; - int countr = 0; - while (!eof && countr < palettesize) { - int count2 = 2; - while (!eof && count2 >= -1) { - int input = file.read(); - if (input == -1) - eof = true; - else if (count2 >= 0) { - palette[countr * 3 + count2] = (byte)(input - & 0xFF); - } - count2--; - filepos++; - } - countr++; - } - } - } catch (IOException e) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + e.getClass() + " - " - + e.getMessage()); - } - // gets h & w from headermap - this.m_width = headermap[wpos] + headermap[wpos + 1] * 256 - + headermap[wpos + 2] * 256 * 256 - + headermap[wpos + 3] * 256 * 256 * 256; - this.m_height = headermap[hpos] + headermap[hpos + 1] * 256 - + headermap[hpos + 2] * 256 * 256 - + headermap[hpos + 3] * 256 * 256 * 256; - - int imagestart = headermap[10] + headermap[11] * 256 - + headermap[12] * 256 * 256 - + headermap[13] * 256 * 256 * 256; - this.m_bitsPerPixel = headermap[28]; - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - int bytes; - if (this.m_bitsPerPixel == 1) - bytes = (this.m_width + 7) / 8; - else if (this.m_bitsPerPixel == 24) - bytes = this.m_width * 3; - else if (this.m_bitsPerPixel == 4 || this.m_bitsPerPixel == 8) - bytes = this.m_width / (8 / this.m_bitsPerPixel); - else - throw new FopImageException("Image (" + this.m_href.toString() - + ") has " + this.m_bitsPerPixel - + " which is not a supported BMP format."); - if ((bytes & 0x03) != 0) { - bytes |= 0x03; - bytes++; - } - - // Should take care of the ColorSpace and bitsPerPixel - this.m_bitmapsSize = this.m_width * this.m_height * 3; - this.m_bitmaps = new byte[this.m_bitmapsSize]; - - int[] temp = new int[bytes * this.m_height]; - try { - int input; - int count = 0; - file.skip((long)(imagestart - filepos)); - while ((input = file.read()) != -1) - temp[count++] = input; - file.close(); - } catch (IOException e) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + e.getClass() + " - " - + e.getMessage()); - } - - for (int i = 0; i < this.m_height; i++) { - int x = 0; - int j = 0; - while (j < bytes) { - int p = temp[(this.m_height - i - 1) * bytes + j]; - - if (this.m_bitsPerPixel == 24 && x < this.m_width) { - int countr = 2; - do { - this.m_bitmaps[3 * (i * this.m_width + x) + countr] = - (byte)(temp[(this.m_height - i - 1) * bytes + j] - & 0xFF); - j++; - } while (--countr >= 0); - x++; - } else if (this.m_bitsPerPixel == 1) { - for (int countr = 0; countr < 8 && x < this.m_width; - countr++) { - if ((p & 0x80) != 0) { - this.m_bitmaps[3 * (i * this.m_width + x)] = - (byte)0xFF; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - (byte)0xFF; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - (byte)0xFF; - } else { - this.m_bitmaps[3 * (i * this.m_width + x)] = - (byte)0; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - (byte)0; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - (byte)0; - } - p <<= 1; - x++; - } - j++; - } else if (this.m_bitsPerPixel == 4) { - for (int countr = 0; countr < 2 && x < this.m_width; - countr++) { - int pal = ((p & 0xF0) >> 4) * 3; - this.m_bitmaps[3 * (i * this.m_width + x)] = - palette[pal]; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - palette[pal + 1]; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - palette[pal + 2]; - p <<= 4; - x++; - } - j++; - } else if (this.m_bitsPerPixel == 8) { - if (x < this.m_width) { - p *= 3; - this.m_bitmaps[3 * (i * this.m_width + x)] = - palette[p]; - this.m_bitmaps[3 * (i * this.m_width + x) + 1] = - palette[p + 1]; - this.m_bitmaps[3 * (i * this.m_width + x) + 2] = - palette[p + 2]; - j++; - x++; - } else - j = bytes; - } else - j++; - } - } - - // This seems really strange to me, but I noticed that JimiImage hardcodes - // m_bitsPerPixel to 8. If I do not do this Acrobat is unable to read the resultant PDF, - // so we will hardcode this... - this.m_bitsPerPixel = 8; - } - -} diff --git a/src/org/apache/fop/image/FopImage.java b/src/org/apache/fop/image/FopImage.java deleted file mode 100644 index 2cbcc45c5..000000000 --- a/src/org/apache/fop/image/FopImage.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -// Author: Eric SCHAEFFER -// Description: represent an image object - -package org.apache.fop.image; - -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.pdf.PDFFilter; - -public interface FopImage { - // Init the object. - // If href protocol isn't file://, can load the entire image - // and keep it in memory. - // Should cache the input stream, and load data when needed. - // public FopImage(URL href) throws FopImageException; - - // Get image general properties. - // Methods throw exception because they can retrieve data - // when needed. - - // Ressource location - public String getURL(); - - // image size - public int getWidth() throws FopImageException; - public int getHeight() throws FopImageException; - - // DeviceGray, DeviceRGB, or DeviceCMYK - public ColorSpace getColorSpace() throws FopImageException; - - // bits per pixel - public int getBitsPerPixel() throws FopImageException; - - // For transparent images - public boolean isTransparent() throws FopImageException; - public PDFColor getTransparentColor() throws FopImageException; - - // get the image bytes, and bytes properties - - // get uncompressed image bytes - public byte[] getBitmaps() throws FopImageException; - // width * (bitsPerPixel / 8) * height, no ? - public int getBitmapsSize() throws FopImageException; - - // get compressed image bytes - // I don't know if we really need it, nor if it - // should be changed... - public byte[] getRessourceBytes() throws FopImageException; - public int getRessourceBytesSize() throws FopImageException; - // return null if no corresponding PDFFilter - public PDFFilter getPDFFilter() throws FopImageException; - - // release memory - public void close(); -} diff --git a/src/org/apache/fop/image/FopImageConsumer.java b/src/org/apache/fop/image/FopImageConsumer.java deleted file mode 100644 index 696f1bdd1..000000000 --- a/src/org/apache/fop/image/FopImageConsumer.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -// Author: Eric SCHAEFFER -// Description: implement ImageConsumer for FopImage classes - -package org.apache.fop.image; - -// Java -import java.util.Hashtable; -import org.apache.fop.messaging.MessageHandler; -import java.awt.image.*; -import java.awt.*; - -import java.lang.reflect.Array; - -// CONSUMER CLASS -public class FopImageConsumer implements ImageConsumer { - protected int width = -1; - protected int height = -1; - protected Integer imageStatus = new Integer(-1); - protected int hints = 0; - protected Hashtable properties = null; - protected ColorModel cm = null; - protected ImageProducer ip = null; - - public FopImageConsumer(ImageProducer iprod) { - this.ip = iprod; - } - - public void imageComplete(int status) { - /* - * MessageHandler.error("Status "); - * if (status == ImageConsumer.COMPLETESCANLINES) { - * MessageHandler.errorln("CompleteScanLines"); - * } else if (status == ImageConsumer.IMAGEABORTED) { - * MessageHandler.errorln("ImageAborted"); - * } else if (status == ImageConsumer.IMAGEERROR) { - * MessageHandler.errorln("ImageError"); - * } else if (status == ImageConsumer.RANDOMPIXELORDER) { - * MessageHandler.errorln("RandomPixelOrder"); - * } else if (status == ImageConsumer.SINGLEFRAME) { - * MessageHandler.errorln("SingleFrame"); - * } else if (status == ImageConsumer.SINGLEFRAMEDONE) { - * MessageHandler.errorln("SingleFrameDone"); - * } else if (status == ImageConsumer.SINGLEPASS) { - * MessageHandler.errorln("SinglePass"); - * } else if (status == ImageConsumer.STATICIMAGEDONE) { - * MessageHandler.errorln("StaticImageDone"); - * } else if (status == ImageConsumer.TOPDOWNLEFTRIGHT) { - * MessageHandler.errorln("TopDownLeftRight"); - * } - */ - synchronized (this.imageStatus) { - // Need to stop status if image done - if (this.imageStatus.intValue() != ImageConsumer.STATICIMAGEDONE) - this.imageStatus = new Integer(status); - } - } - - public void setColorModel(ColorModel model) { - // MessageHandler.errorln("setColorModel: " + model); - this.cm = model; - } - - public void setDimensions(int width, int height) { - // MessageHandler.errorln("setDimension: w=" + width + " h=" + height); - this.width = width; - this.height = height; - } - - public void setHints(int hintflags) { - // MessageHandler.errorln("setHints: " + hintflags); - this.hints = hintflags; - } - - public void setProperties(Hashtable props) { - // MessageHandler.errorln("setProperties: " + props); - this.properties = props; - } - - public void setPixels(int x, int y, int w, int h, ColorModel model, - byte[] pixels, int off, int scansize) {} - - public void setPixels(int x, int y, int w, int h, ColorModel model, - int[] pixels, int off, int scansize) {} - - public boolean isImageReady() throws Exception { - synchronized (this.imageStatus) { - if (this.imageStatus.intValue() == ImageConsumer.IMAGEABORTED) - throw new Exception("Image aborted"); - if (this.imageStatus.intValue() == ImageConsumer.IMAGEERROR) - throw new Exception("Image error"); - - if (this.imageStatus.intValue() == ImageConsumer.STATICIMAGEDONE) - return true; - - return false; - } - } - - public int getWidth() { - return this.width; - } - - public int getHeight() { - return this.height; - } - - public ColorModel getColorModel() { - return this.cm; - } - - public int[] getImage() throws Exception { - int tmpMap[] = new int[this.width * this.height]; - PixelGrabber pg = new PixelGrabber(this.ip, 0, 0, this.width, - this.height, tmpMap, 0, - this.width); - pg.setDimensions(this.width, this.height); - pg.setColorModel(this.cm); - pg.setHints(this.hints); - pg.setProperties(this.properties); - try { - pg.grabPixels(); - } catch (InterruptedException intex) { - throw new Exception("Image grabbing interrupted : " - + intex.getMessage()); - } - return tmpMap; - } - -} diff --git a/src/org/apache/fop/image/FopImageException.java b/src/org/apache/fop/image/FopImageException.java deleted file mode 100644 index c85ecb73d..000000000 --- a/src/org/apache/fop/image/FopImageException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -// Author: Eric SCHAEFFER -// Description: Image Exception - -package org.apache.fop.image; - -public class FopImageException extends Exception { - - public FopImageException() { - super(); - } - - public FopImageException(String message) { - super(message); - } - -} diff --git a/src/org/apache/fop/image/FopImageFactory.java b/src/org/apache/fop/image/FopImageFactory.java deleted file mode 100644 index 7255ca011..000000000 --- a/src/org/apache/fop/image/FopImageFactory.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.io.IOException; -import java.io.InputStream; -import java.io.File; -import java.net.URL; -import java.net.MalformedURLException; -import java.lang.reflect.Constructor; -import java.util.Hashtable; - -// FOP -import org.apache.fop.messaging.MessageHandler; -import org.apache.fop.image.analyser.ImageReaderFactory; -import org.apache.fop.image.analyser.ImageReader; -import org.apache.fop.configuration.Configuration; - -/** - * create FopImage objects (with a configuration file - not yet implemented). - * @author Eric SCHAEFFER - */ -public class FopImageFactory { - - private static Hashtable m_urlMap = new Hashtable(); - - /** - * create an FopImage objects. - * @param href image URL as a String - * @return a new FopImage object - * @exception java.net.MalformedURLException bad URL - * @exception FopImageException an error occured during construction - */ - public static FopImage Make(String href) - throws MalformedURLException, FopImageException { - - // Get the absolute URL - URL absoluteURL = null; - InputStream imgIS = null; - try { - try { - absoluteURL = new URL(href); - } catch (MalformedURLException mue) { - // if the href contains onl a path then file is assumed - absoluteURL = new URL("file:" + href); - } - imgIS = absoluteURL.openStream(); - } catch (MalformedURLException e_context) { - throw new FopImageException("Error with image URL: " - + e_context.getMessage()); - } catch (Exception e) { - // maybe relative - URL context_url = null; - try { - absoluteURL = new URL(Configuration.getStringValue("baseDir") - + absoluteURL.getFile()); - } catch (MalformedURLException e_context) { - // pb context url - throw new FopImageException("Invalid Image URL - error on relative URL : " - + e_context.getMessage()); - } - } - - // check if already created - FopImage imageObject = (FopImage)m_urlMap.get(absoluteURL.toString()); - if (imageObject != null) - return imageObject; - - // If not, check image type - ImageReader imgReader = null; - try { - if (imgIS == null) { - imgIS = absoluteURL.openStream(); - } - imgReader = ImageReaderFactory.Make(absoluteURL.toExternalForm(), - imgIS); - } catch (Exception e) { - throw new FopImageException("Error while recovering Image Informations (" - + absoluteURL.toString() + ") : " - + e.getMessage()); - } - finally { - if (imgIS != null) { - try { - imgIS.close(); - } catch (IOException e) {} - } - } - if (imgReader == null) - throw new FopImageException("No ImageReader for this type of image (" - + absoluteURL.toString() + ")"); - // Associate mime-type to FopImage class - String imgMimeType = imgReader.getMimeType(); - String imgClassName = null; - if ("image/gif".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.GifJpegImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/jpeg".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.GifJpegImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/bmp".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.BmpImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/png".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/tga".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/tiff".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.JimiImage"; - // imgClassName = "org.apache.fop.image.JAIImage"; - } else if ("image/svg+xml".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.SVGImage"; - } - if (imgClassName == null) - throw new FopImageException("Unsupported image type (" - + absoluteURL.toString() + ") : " - + imgMimeType); - - // load the right image class - // return new - Object imageInstance = null; - Class imageClass = null; - try { - imageClass = Class.forName(imgClassName); - Class[] imageConstructorParameters = new Class[2]; - imageConstructorParameters[0] = Class.forName("java.net.URL"); - imageConstructorParameters[1] = - Class.forName("org.apache.fop.image.analyser.ImageReader"); - Constructor imageConstructor = - imageClass.getDeclaredConstructor(imageConstructorParameters); - Object[] initArgs = new Object[2]; - initArgs[0] = absoluteURL; - initArgs[1] = imgReader; - imageInstance = imageConstructor.newInstance(initArgs); - } catch (java.lang.reflect.InvocationTargetException ex) { - Throwable t = ex.getTargetException(); - String msg; - if (t != null) { - msg = t.getMessage(); - } else { - msg = ex.getMessage(); - } - throw new FopImageException("Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + msg); - } catch (Exception ex) { - throw new FopImageException("Error creating FopImage object (" - + "Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + ex.getMessage()); - } - if (!(imageInstance instanceof org.apache.fop.image.FopImage)) { - throw new FopImageException("Error creating FopImage object (" - + absoluteURL.toString() + ") : " - + "class " + imageClass.getName() - + " doesn't implement org.apache.fop.image.FopImage interface"); - } - m_urlMap.put(absoluteURL.toString(), imageInstance); - return (FopImage)imageInstance; - } - -} - diff --git a/src/org/apache/fop/image/GifJpegImage.java b/src/org/apache/fop/image/GifJpegImage.java deleted file mode 100644 index 77d591544..000000000 --- a/src/org/apache/fop/image/GifJpegImage.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.net.URL; -import java.awt.image.ImageProducer; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; - -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.image.analyser.ImageReader; - -/** - * FopImage object for GIF or JPEG images, using Java native classes. - * @author Eric SCHAEFFER - * @see AbstractFopImage - * @see FopImage - */ -public class GifJpegImage extends AbstractFopImage { - public GifJpegImage(URL href) throws FopImageException { - super(href); - } - - public GifJpegImage(URL href, - ImageReader imgReader) throws FopImageException { - super(href, imgReader); - } - - protected void loadImage() throws FopImageException { - int[] tmpMap = null; - try { - ImageProducer ip = (ImageProducer)this.m_href.getContent(); - FopImageConsumer consumer = new FopImageConsumer(ip); - ip.startProduction(consumer); - - while (!consumer.isImageReady()) { - Thread.sleep(500); - } - this.m_height = consumer.getHeight(); - this.m_width = consumer.getWidth(); - - try { - tmpMap = consumer.getImage(); - } catch (Exception ex) { - throw new FopImageException("Image grabbing interrupted : " - + ex.getMessage()); - } - - ColorModel cm = consumer.getColorModel(); - this.m_bitsPerPixel = 8; - // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT - if (transparencyType == java.awt.Transparency.OPAQUE) { - this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { - if (cm instanceof IndexColorModel) { - this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); - for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { - if ((alphas[i] & 0xFF) == 0) { - this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); - break; - } - } - } else { - // TRANSLUCENT - /* - * this.m_isTransparent = false; - * for (int i = 0; i < this.m_width * this.m_height; i++) { - * if (cm.getAlpha(tmpMap[i]) == 0) { - * this.m_isTransparent = true; - * this.m_transparentColor = new PDFColor(cm.getRed(tmpMap[i]), cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); - * break; - * } - * } - */ - // use special API... - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); - } - - - // Should take care of the ColorSpace and bitsPerPixel - this.m_bitmapsSize = this.m_width * this.m_height * 3; - this.m_bitmaps = new byte[this.m_bitmapsSize]; - for (int i = 0; i < this.m_height; i++) { - for (int j = 0; j < this.m_width; j++) { - int p = tmpMap[i * this.m_width + j]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; - int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); - } - } - } - -} - diff --git a/src/org/apache/fop/image/ImageArea.java b/src/org/apache/fop/image/ImageArea.java deleted file mode 100644 index 509ba92d4..000000000 --- a/src/org/apache/fop/image/ImageArea.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -import org.apache.fop.fo.properties.TextAlign; -import org.apache.fop.layout.*; -import org.apache.fop.layout.inline.*; - -import org.apache.fop.render.Renderer; - -import java.util.Vector; -import java.util.Enumeration; - -public class ImageArea extends InlineArea { - - protected int xOffset = 0; - protected int align; - protected int valign; - protected FopImage image; - - - public ImageArea(FontState fontState, FopImage img, int AllocationWidth, - int width, int height, int startIndent, int endIndent, - int align) { - super(fontState, width, 0, 0, 0); - this.currentHeight = height; - this.contentRectangleWidth = width; - this.height = height; - this.image = img; - this.align = align; - - /* - * switch (align) { - * case TextAlign.START: - * xOffset = startIndent; - * break; - * case TextAlign.END: - * if (endIndent == 0) - * endIndent = AllocationWidth; - * xOffset = (endIndent - width); - * break; - * case TextAlign.JUSTIFY: - * xOffset = startIndent; - * break; - * case TextAlign.CENTER: - * if (endIndent == 0) - * endIndent = AllocationWidth; - * xOffset = startIndent + ((endIndent - startIndent) - width)/2; - * break; - * } - */ - } - - public int getXOffset() { - return this.xOffset; - } - - public FopImage getImage() { - return this.image; - } - - public void render(Renderer renderer) { - renderer.renderImageArea(this); - } - - public int getImageHeight() { - return currentHeight; - } - - public void setAlign(int align) { - this.align = align; - } - - public int getAlign() { - return this.align; - } - - public void setVerticalAlign(int align) { - this.valign = align; - } - - public int getVerticalAlign() { - return this.valign; - } - - public void setStartIndent(int startIndent) { - xOffset = startIndent; - } - - - -} - - diff --git a/src/org/apache/fop/image/JAIImage.java b/src/org/apache/fop/image/JAIImage.java deleted file mode 100644 index 0e8524759..000000000 --- a/src/org/apache/fop/image/JAIImage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.net.URL; -import java.io.InputStream; -import java.io.BufferedInputStream; - -// AWT -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.BufferedImage; - -// JAI -import javax.media.jai.JAI; -import javax.media.jai.RenderedOp; -// Sun codec -import com.sun.media.jai.codec.FileCacheSeekableStream; -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.image.analyser.ImageReader; - -/** - * FopImage object using JAI. - * @author Eric SCHAEFFER - * @see AbstractFopImage - * @see FopImage - */ -public class JAIImage extends AbstractFopImage { - public JAIImage(URL href) throws FopImageException { - super(href); - } - - public JAIImage(URL href, - ImageReader imgReader) throws FopImageException { - super(href, imgReader); - } - - protected void loadImage() throws FopImageException { - try { - InputStream inputStream = this.m_href.openStream(); - /* - * BufferedInputStream inputStream = this.m_imageReader.getInputStream(); - * inputStream.reset(); - */ - com.sun.media.jai.codec.FileCacheSeekableStream seekableInput = - new FileCacheSeekableStream(inputStream); - RenderedOp imageOp = JAI.create("stream", seekableInput); - - this.m_height = imageOp.getHeight(); - this.m_width = imageOp.getWidth(); - - ColorModel cm = imageOp.getColorModel(); - this.m_bitsPerPixel = 8; - // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - - BufferedImage imageData = imageOp.getAsBufferedImage(); - int[] tmpMap = imageData.getRGB(0, 0, this.m_width, - this.m_height, null, 0, - this.m_width); - - if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT - if (transparencyType == java.awt.Transparency.OPAQUE) { - this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { - if (cm instanceof IndexColorModel) { - this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); - for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { - if ((alphas[i] & 0xFF) == 0) { - this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); - break; - } - } - } else { - // TRANSLUCENT - /* - * this.m_isTransparent = false; - * for (int i = 0; i < this.m_width * this.m_height; i++) { - * if (cm.getAlpha(tmpMap[i]) == 0) { - * this.m_isTransparent = true; - * this.m_transparentColor = new PDFColor(cm.getRed(tmpMap[i]), cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); - * break; - * } - * } - * // or use special API... - */ - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - - // Should take care of the ColorSpace and bitsPerPixel - this.m_bitmapsSize = this.m_width * this.m_height * 3; - this.m_bitmaps = new byte[this.m_bitmapsSize]; - for (int i = 0; i < this.m_height; i++) { - for (int j = 0; j < this.m_width; j++) { - int p = tmpMap[i * this.m_width + j]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; - int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); - } - } - - } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); - } - } - -} - diff --git a/src/org/apache/fop/image/JimiImage.java b/src/org/apache/fop/image/JimiImage.java deleted file mode 100644 index ddd2c49ea..000000000 --- a/src/org/apache/fop/image/JimiImage.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.net.URL; -import java.awt.image.ImageProducer; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; - -// Jimi -import com.sun.jimi.core.*; - -// FOP -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.image.analyser.ImageReader; - -/** - * FopImage object for several images types, using Jimi. - * See Jimi documentation for supported image types. - * @author Eric SCHAEFFER - * @see AbstractFopImage - * @see FopImage - */ -public class JimiImage extends AbstractFopImage { - public JimiImage(URL href) throws FopImageException { - super(href); - try { - Class c = Class.forName("com.sun.jimi.core.Jimi"); - } catch (ClassNotFoundException e) { - throw new FopImageException("Jimi image library not available"); - } - } - - public JimiImage(URL href, - ImageReader imgReader) throws FopImageException { - super(href, imgReader); - try { - Class c = Class.forName("com.sun.jimi.core.Jimi"); - } catch (ClassNotFoundException e) { - throw new FopImageException("Jimi image library not available"); - } - } - - protected void loadImage() throws FopImageException { - int[] tmpMap = null; - try { - ImageProducer ip = Jimi.getImageProducer(this.m_href.openStream(), - Jimi.SYNCHRONOUS - | Jimi.IN_MEMORY); - FopImageConsumer consumer = new FopImageConsumer(ip); - ip.startProduction(consumer); - - while (!consumer.isImageReady()) { - Thread.sleep(500); - } - this.m_height = consumer.getHeight(); - this.m_width = consumer.getWidth(); - - try { - tmpMap = consumer.getImage(); - } catch (Exception ex) { - throw new FopImageException("Image grabbing interrupted : " - + ex.getMessage()); - } - - ColorModel cm = consumer.getColorModel(); - this.m_bitsPerPixel = 8; - // this.m_bitsPerPixel = cm.getPixelSize(); - this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); - if (cm.hasAlpha()) { - int transparencyType = - cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT - if (transparencyType == java.awt.Transparency.OPAQUE) { - this.m_isTransparent = false; - } else if (transparencyType - == java.awt.Transparency.BITMASK) { - if (cm instanceof IndexColorModel) { - this.m_isTransparent = false; - byte[] alphas = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] reds = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] greens = - new byte[((IndexColorModel)cm).getMapSize()]; - byte[] blues = - new byte[((IndexColorModel)cm).getMapSize()]; - ((IndexColorModel)cm).getAlphas(alphas); - ((IndexColorModel)cm).getReds(reds); - ((IndexColorModel)cm).getGreens(greens); - ((IndexColorModel)cm).getBlues(blues); - for (int i = 0; - i < ((IndexColorModel)cm).getMapSize(); i++) { - if ((alphas[i] & 0xFF) == 0) { - this.m_isTransparent = true; - this.m_transparentColor = - new PDFColor((int)(reds[i] & 0xFF), - (int)(greens[i] & 0xFF), - (int)(blues[i] & 0xFF)); - break; - } - } - } else { - // TRANSLUCENT - /* - * this.m_isTransparent = false; - * for (int i = 0; i < this.m_width * this.m_height; i++) { - * if (cm.getAlpha(tmpMap[i]) == 0) { - * this.m_isTransparent = true; - * this.m_transparentColor = new PDFColor(cm.getRed(tmpMap[i]), cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); - * break; - * } - * } - */ - // use special API... - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - } else { - this.m_isTransparent = false; - } - } catch (Exception ex) { - throw new FopImageException("Error while loading image " - + this.m_href.toString() + " : " - + ex.getClass() + " - " - + ex.getMessage()); - } - - - // Should take care of the ColorSpace and bitsPerPixel - this.m_bitmapsSize = this.m_width * this.m_height * 3; - this.m_bitmaps = new byte[this.m_bitmapsSize]; - for (int i = 0; i < this.m_height; i++) { - for (int j = 0; j < this.m_width; j++) { - int p = tmpMap[i * this.m_width + j]; - int r = (p >> 16) & 0xFF; - int g = (p >> 8) & 0xFF; - int b = (p) & 0xFF; - this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g - & 0xFF); - this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b - & 0xFF); - } - } - } - -} - diff --git a/src/org/apache/fop/image/SVGImage.java b/src/org/apache/fop/image/SVGImage.java deleted file mode 100644 index ecc08aa1a..000000000 --- a/src/org/apache/fop/image/SVGImage.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image; - -// Java -import java.net.URL; -import org.w3c.dom.svg.SVGDocument; - -// FOP -import org.apache.fop.apps.Driver; -import org.apache.fop.messaging.*; -import org.apache.fop.datatypes.ColorSpace; -import org.apache.fop.pdf.PDFColor; -import org.apache.fop.image.analyser.ImageReader; - -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; - -import org.apache.batik.dom.svg.SAXSVGDocumentFactory; - -/** - * @see AbstractFopImage - * @see FopImage - */ -public class SVGImage extends AbstractFopImage { - SVGDocument doc; - - public SVGImage(URL href) throws FopImageException { - super(href); - } - - public SVGImage(URL href, - ImageReader imgReader) throws FopImageException { - super(href, imgReader); - } - - /** - * creates a SAX parser, using the value of org.xml.sax.parser - * defaulting to org.apache.xerces.parsers.SAXParser - * - * @return the created SAX parser - */ - public static String getParserName() { - String parserClassName = Driver.getParserClassName(); - return parserClassName; - } - - protected void loadImage() throws FopImageException { - try { - SAXSVGDocumentFactory factory = - new SAXSVGDocumentFactory(SVGImage.getParserName()); - doc = factory.createDocument(this.m_href.toExternalForm()); - } catch (Exception e) { - MessageHandler.errorln("ERROR LOADING EXTERNAL SVG: " - + e.getMessage()); - } - } - - public SVGDocument getSVGDocument() throws FopImageException { - if (doc == null) - this.loadImage(); - return doc; - } - -} diff --git a/src/org/apache/fop/image/analyser/AbstractImageReader.java b/src/org/apache/fop/image/analyser/AbstractImageReader.java deleted file mode 100644 index aeb6e02b9..000000000 --- a/src/org/apache/fop/image/analyser/AbstractImageReader.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * Base class implementing ImageReader. - * @author Pankaj Narula - * @version 1.0 - * @see ImageReader - */ -public abstract class AbstractImageReader implements ImageReader { - - /** - * Image width. - */ - protected int width = 0; - - /** - * Image height. - */ - protected int height = 0; - - /** - * Image stream. - */ - protected BufferedInputStream imageStream = null; - - public abstract boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException; - - public int getHeight() { - return this.height; - } - - public int getWidth() { - return this.width; - } - - public abstract String getMimeType(); - - public BufferedInputStream getInputStream() { - return this.imageStream; - } - -} - diff --git a/src/org/apache/fop/image/analyser/BMPReader.java b/src/org/apache/fop/image/analyser/BMPReader.java deleted file mode 100644 index c09a6238e..000000000 --- a/src/org/apache/fop/image/analyser/BMPReader.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader object for BMP image type. - * @author Pankaj Narula - * @version 1.0 - */ -public class BMPReader extends AbstractImageReader { - static protected final int BMP_SIG_LENGTH = 26; - - protected byte[] header; - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0x42) - && (header[1] == (byte)0x4d)); - if (supported) { - setDimension(); - return true; - } else - return false; - } - - public String getMimeType() { - return "image/bmp"; - } - - protected void setDimension() { - // little endian notation - int byte1 = header[18] & 0xff; - int byte2 = header[19] & 0xff; - int byte3 = header[20] & 0xff; - int byte4 = header[21] & 0xff; - long l = (long)((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); - this.width = (int)(l & 0xffffffff); - - byte1 = header[22] & 0xff; - byte2 = header[23] & 0xff; - byte3 = header[24] & 0xff; - byte4 = header[25] & 0xff; - l = (long)((byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1); - this.height = (int)(l & 0xffffffff); - } - - protected void setDefaultHeader() throws IOException { - this.header = new byte[BMP_SIG_LENGTH]; - try { - this.imageStream.mark(BMP_SIG_LENGTH + 1); - this.imageStream.read(header); - this.imageStream.reset(); - } catch (IOException ex) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ex; - } - } - -} - diff --git a/src/org/apache/fop/image/analyser/GIFReader.java b/src/org/apache/fop/image/analyser/GIFReader.java deleted file mode 100644 index b3b8edd23..000000000 --- a/src/org/apache/fop/image/analyser/GIFReader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader object for GIF image type. - * @author Pankaj Narula - * @version 1.0 - */ -public class GIFReader extends AbstractImageReader { - static protected final int GIF_SIG_LENGTH = 10; - protected byte[] header; - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - this.setDefaultHeader(); - boolean supported = ((header[0] == 'G') && (header[1] == 'I') - && (header[2] == 'F') && (header[3] == '8') - && (header[4] == '7' || header[4] == '9') - && (header[5] == 'a')); - if (supported) { - setDimension(); - return true; - } else - return false; - } - - public String getMimeType() { - return "image/gif"; - } - - protected void setDimension() { - // little endian notation - int byte1 = header[6] & 0xff; - int byte2 = header[7] & 0xff; - this.width = ((byte2 << 8) | byte1) & 0xffff; - - byte1 = header[8] & 0xff; - byte2 = header[9] & 0xff; - this.height = ((byte2 << 8) | byte1) & 0xffff; - } - - protected void setDefaultHeader() throws IOException { - this.header = new byte[GIF_SIG_LENGTH]; - try { - this.imageStream.mark(GIF_SIG_LENGTH + 1); - this.imageStream.read(header); - this.imageStream.reset(); - } catch (IOException ex) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ex; - } - } - -} - diff --git a/src/org/apache/fop/image/analyser/ImageReader.java b/src/org/apache/fop/image/analyser/ImageReader.java deleted file mode 100644 index 52f43bff4..000000000 --- a/src/org/apache/fop/image/analyser/ImageReader.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader objects read image headers to determine the image size. - * @author Pankaj Narula - * @version 1.0 - */ -public interface ImageReader { - - /** - * Verify image type. - * @param bis Image buffered input stream - * @return true if image type is the handled one - * @exception IOException io error - */ - public boolean verifySignature(String uri, BufferedInputStream bis) - throws IOException; - - /** - * Return the used InputStream. - * @return BufferedInputStream used to verify image type - */ - public BufferedInputStream getInputStream(); - - /** - * Return correspondig mime type. - * @return image mime type - */ - public String getMimeType(); - - /** - * Return the image height. - * @return image height - */ - public int getHeight(); - - /** - * Return the image width. - * @return image width - */ - public int getWidth(); -} - diff --git a/src/org/apache/fop/image/analyser/ImageReaderFactory.java b/src/org/apache/fop/image/analyser/ImageReaderFactory.java deleted file mode 100644 index e9b5ce3f0..000000000 --- a/src/org/apache/fop/image/analyser/ImageReaderFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.InputStream; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.util.Enumeration; -import java.util.Vector; - -// FOP -import org.apache.fop.image.FopImageException; - -/** - * Factory for ImageReader objects. - * @author Pankaj Narula - * @version 1.0 - */ -public class ImageReaderFactory { - static protected Vector formats = null; - - /** - * ImageReader maker. - * @param in image input stream - * @return ImageReader object - * @exception FopImageException an error occured during creation or - * image type is not supported - */ - static public ImageReader Make(String uri, - InputStream in) throws FopImageException { - - // need to use a config file and remove static methods - formats = new Vector(); - formats.addElement(new JPEGReader()); - formats.addElement(new BMPReader()); - formats.addElement(new GIFReader()); - formats.addElement(new PNGReader()); - formats.addElement(new TIFFReader()); - formats.addElement(new SVGReader()); - // - - ImageReader reader; - BufferedInputStream bis = new BufferedInputStream(in); - Enumeration itr = formats.elements(); - try { - while (itr.hasMoreElements()) { - reader = (ImageReader)itr.nextElement(); - if (reader.verifySignature(uri, bis)) { - return reader; - } - } - } catch (IOException ex) { - throw new FopImageException(ex.getMessage()); - } - return null; - } - -} - diff --git a/src/org/apache/fop/image/analyser/JPEGReader.java b/src/org/apache/fop/image/analyser/JPEGReader.java deleted file mode 100644 index 0e1412a8b..000000000 --- a/src/org/apache/fop/image/analyser/JPEGReader.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader object for JPEG image type. - * @author Pankaj Narula - * @version 1.0 - */ -public class JPEGReader extends AbstractImageReader { - - /** - * Only SOFn and APPn markers are defined as SOFn is needed for the height and - * width search. APPn is also defined because if the JPEG contains thumbnails - * the dimensions of the thumnail would also be after the SOFn marker enclosed - * inside the APPn marker. And we don't want to confuse those dimensions with - * the image dimensions. - */ - static protected final int MARK = 0xff; // Beginneing of a Marker - static protected final int NULL = 0x00; // Special case for 0xff00 - static protected final int SOF1 = 0xc0; // Baseline DCT - static protected final int SOF2 = 0xc1; // Extended Sequential DCT - static protected final int SOF3 = 0xc2; // Progrssive DCT only PDF 1.3 - static protected final int SOFA = 0xca; // Progressice DCT only PDF 1.3 - static protected final int APP0 = 0xe0; // Application marker, JFIF - static protected final int APPF = 0xef; // Application marker - static protected final int SOS = 0xda; // Start of Scan - static protected final int SOI = 0xd8; // start of Image - static protected final int JPG_SIG_LENGTH = 2; - - protected byte[] header; - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0xff) - && (header[1] == (byte)0xd8)); - if (supported) { - setDimension(); - return true; - } else - return false; - } - - public String getMimeType() { - return "image/jpeg"; - } - - protected void setDefaultHeader() throws IOException { - this.header = new byte[JPG_SIG_LENGTH]; - try { - this.imageStream.mark(JPG_SIG_LENGTH + 1); - this.imageStream.read(header); - this.imageStream.reset(); - } catch (IOException ex) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ex; - } - } - - protected void setDimension() throws IOException { - try { - int marker = NULL; - long length, skipped; - outer: - while (imageStream.available() > 0) { - while ((marker = imageStream.read()) != MARK) { - ; - } - do { - marker = imageStream.read(); - } while (marker == MARK); - switch (marker) { - case SOI: - break; - case NULL: - break; - case SOF1: - case SOF2: - case SOF3: // SOF3 and SOFA are only supported by PDF 1.3 - case SOFA: - this.skip(3); - this.height = this.read2bytes(); - this.width = this.read2bytes(); - break outer; - default: - length = this.read2bytes(); - skipped = this.skip(length - 2); - if (skipped != length - 2) - throw new IOException("Skipping Error"); - } - } - } catch (IOException ioe) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ioe; - } - } - - protected int read2bytes() throws IOException { - int byte1 = imageStream.read(); - int byte2 = imageStream.read(); - return (int)((byte1 << 8) | byte2); - } - - protected long skip(long n) throws IOException { - long discarded = 0; - while (discarded != n) { - imageStream.read(); - discarded++; - } - return discarded; // scope for exception - } - -} - diff --git a/src/org/apache/fop/image/analyser/PNGReader.java b/src/org/apache/fop/image/analyser/PNGReader.java deleted file mode 100644 index 64f175b2e..000000000 --- a/src/org/apache/fop/image/analyser/PNGReader.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader object for PNG image type. - * @author Pankaj Narula - * @version 1.0 - */ -public class PNGReader extends AbstractImageReader { - static protected final int PNG_SIG_LENGTH = 24; - protected byte[] header; - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - this.setDefaultHeader(); - boolean supported = ((header[0] == (byte)0x89) - && (header[1] == (byte)0x50) - && (header[2] == (byte)0x4e) - && (header[3] == (byte)0x47) - && (header[4] == (byte)0x0d) - && (header[5] == (byte)0x0a) - && (header[6] == (byte)0x1a) - && (header[7] == (byte)0x0a)); - if (supported) { - setDimension(); - return true; - } else - return false; - } - - public String getMimeType() { - return "image/png"; - } - - protected void setDimension() { - // png is always big endian - int byte1 = header[16] & 0xff; - int byte2 = header[17] & 0xff; - int byte3 = header[18] & 0xff; - int byte4 = header[19] & 0xff; - long l = (long)((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); - this.width = (int)(l); - - byte1 = header[20] & 0xff; - byte2 = header[21] & 0xff; - byte3 = header[22] & 0xff; - byte4 = header[23] & 0xff; - l = (long)((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4); - this.height = (int)(l); - - } - - protected void setDefaultHeader() throws IOException { - this.header = new byte[PNG_SIG_LENGTH]; - try { - this.imageStream.mark(PNG_SIG_LENGTH + 1); - this.imageStream.read(header); - this.imageStream.reset(); - } catch (IOException ex) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ex; - } - } - -} - diff --git a/src/org/apache/fop/image/analyser/SVGReader.java b/src/org/apache/fop/image/analyser/SVGReader.java deleted file mode 100644 index eedf04014..000000000 --- a/src/org/apache/fop/image/analyser/SVGReader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -import org.w3c.dom.svg.SVGDocument; -import org.w3c.dom.svg.SVGSVGElement; - -// FOP -import org.apache.fop.messaging.*; -import org.apache.fop.image.SVGImage; - -import org.xml.sax.InputSource; -import org.xml.sax.XMLReader; - -import org.apache.batik.dom.svg.SAXSVGDocumentFactory; - -/** - * ImageReader object for SVG document image type. - */ -public class SVGReader extends AbstractImageReader { - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - return loadImage(uri); - } - - public String getMimeType() { - return "image/svg+xml"; - } - - /** - * This means the external svg document will be loaded twice. - * Possibly need a slightly different design for the image stuff. - */ - protected boolean loadImage(String uri) { - // parse document and get the size attributes of the svg element - try { - SAXSVGDocumentFactory factory = - new SAXSVGDocumentFactory(SVGImage.getParserName()); - SVGDocument doc = factory.createDocument(uri, imageStream); - // should check the stream contains text data - SVGSVGElement svg = doc.getRootElement(); - this.width = (int)svg.getWidth().getBaseVal().getValue(); - this.height = (int)svg.getHeight().getBaseVal().getValue(); - return true; - } catch (NoClassDefFoundError ncdfe) { - MessageHandler.errorln("Batik not in class path"); - return false; - } catch (Exception e) { - MessageHandler.errorln("ERROR LOADING EXTERNAL SVG: " - + e.getMessage()); - // assuming any exception means this document is not svg - // or could not be loaded for some reason - return false; - } - } - -} - diff --git a/src/org/apache/fop/image/analyser/TIFFReader.java b/src/org/apache/fop/image/analyser/TIFFReader.java deleted file mode 100644 index 9434ac3ff..000000000 --- a/src/org/apache/fop/image/analyser/TIFFReader.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.image.analyser; - -// Java -import java.io.BufferedInputStream; -import java.io.IOException; - -/** - * ImageReader object for TIFF image type. - * @author Pankaj Narula, Michael Lee - * @version 1.0 - */ -public class TIFFReader extends AbstractImageReader { - static protected final int TIFF_SIG_LENGTH = 8; - protected byte[] header; - - public boolean verifySignature(String uri, BufferedInputStream fis) - throws IOException { - this.imageStream = fis; - this.setDefaultHeader(); - boolean supported = false; - - if (header[0] == (byte)0x49 - && header[1] - == (byte)0x49) // first 2 bytes = II (little endian encoding) - { - // look for '42' in byte 3 and '0' in byte 4 - if (header[2] == 42 && header[3] == 0) - supported = true; - } - - if (header[0] == (byte)0x4D - && header[1] - == (byte)0x4D) // first 2 bytes == MM (big endian encoding) - { - // look for '42' in byte 4 and '0' in byte 3 - if (header[2] == 0 && header[3] == 42) - supported = true; - } - - if (supported) { - setDimension(); - return true; - } else - return false; - } - - public String getMimeType() { - return "image/tiff"; - } - - protected void setDimension() { - // currently not setting the width and height - // these are set again by the Jimi image reader. - // I suppose I'll do it one day to be complete. Or - // someone else will. - // Note: bytes 4,5,6,7 contain the byte offset in the stream of the first IFD block - /* - * //png is always big endian - * int byte1 = header[ 16 ] & 0xff; - * int byte2 = header[ 17 ] & 0xff; - * int byte3 = header[ 18 ] & 0xff; - * int byte4 = header[ 19 ] & 0xff; - * long l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) | - * ( byte3 << 8 ) | byte4 ); - * this.width = ( int ) ( l ); - * byte1 = header[ 20 ] & 0xff; - * byte2 = header[ 21 ] & 0xff; - * byte3 = header[ 22 ] & 0xff; - * byte4 = header[ 23 ] & 0xff; - * l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) | ( byte3 << 8 ) | - * byte4 ); - * this.height = ( int ) ( l ); - */ - } - - protected void setDefaultHeader() throws IOException { - this.header = new byte[TIFF_SIG_LENGTH]; - try { - this.imageStream.mark(TIFF_SIG_LENGTH + 1); - this.imageStream.read(header); - this.imageStream.reset(); - } catch (IOException ex) { - try { - this.imageStream.reset(); - } catch (IOException exbis) {} - throw ex; - } - } - -} - diff --git a/src/org/apache/fop/layout/AbsolutePositionProps.java b/src/org/apache/fop/layout/AbsolutePositionProps.java deleted file mode 100644 index e8e5d1a56..000000000 --- a/src/org/apache/fop/layout/AbsolutePositionProps.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.datatypes.Length; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class AbsolutePositionProps { - public int absolutePosition; - public Length top; - public Length right; - public Length bottom; - public Length left; - - public AbsolutePositionProps() {} - -} diff --git a/src/org/apache/fop/layout/AccessibilityProps.java b/src/org/apache/fop/layout/AccessibilityProps.java deleted file mode 100644 index a7bd4dd5f..000000000 --- a/src/org/apache/fop/layout/AccessibilityProps.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class AccessibilityProps { - public String sourceDoc = null; - public String role = null; - - public AccessibilityProps() {} - -} diff --git a/src/org/apache/fop/layout/Area.java b/src/org/apache/fop/layout/Area.java deleted file mode 100644 index 4ac0c935d..000000000 --- a/src/org/apache/fop/layout/Area.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.datatypes.*; -import org.apache.fop.fo.flow.Marker; -import org.apache.fop.layout.inline.InlineSpace; - -// Java -import java.util.Vector; -import java.util.Hashtable; - -abstract public class Area extends Box { - - /* - * nominal font size and nominal font family incorporated in - * fontState - */ - protected FontState fontState; - protected BorderAndPadding bp = null; - - protected Vector children = new Vector(); - - /* max size in line-progression-direction */ - protected int maxHeight; - - /** - * Total height of content of this area. - */ - protected int currentHeight = 0; - - // used to keep track of the current x position within a table. Required for drawing rectangle links. - protected int tableCellXOffset = 0; - - // used to keep track of the absolute height on the page. Required for drawing rectangle links. - private int absoluteHeight = 0; - - protected int contentRectangleWidth; - - protected int allocationWidth; - - /* the page this area is on */ - protected Page page; - - protected ColorType backgroundColor; - - private IDReferences idReferences; - - protected Vector markers; - - // as defined in Section 6.1.1 - protected org.apache.fop.fo.FObj generatedBy; // corresponds to 'generated-by' trait - protected Hashtable returnedBy; - - // as defined in Section 6.1.1 - protected String areaClass; - - // as defined in Section 4.2.2 - protected boolean isFirst = false; - protected boolean isLast = false; - - /* - * author : Seshadri G - * * the fo which created it - */ - // This is deprecated and should be phased out in - // favour of using 'generatedBy' - public org.apache.fop.fo.FObj foCreator; - - public Area(FontState fontState) { - setFontState(fontState); - this.markers = new Vector(); - this.returnedBy = new Hashtable(); - } - - /** - * Creates a new Area instance. - * - * @param fontState a FontState value - * @param allocationWidth the inline-progression dimension of the content - * rectangle of the Area - * @param maxHeight the maximum block-progression dimension available - * for this Area (its allocation rectangle) - */ - public Area(FontState fontState, int allocationWidth, int maxHeight) { - setFontState(fontState); - this.allocationWidth = allocationWidth; - this.contentRectangleWidth = allocationWidth; - this.maxHeight = maxHeight; - this.markers = new Vector(); - this.returnedBy = new Hashtable(); - } - - private void setFontState(FontState fontState) { - // fontState.setFontInfo(this.page.getFontInfo()); - this.fontState = fontState; - } - - public void addChild(Box child) { - this.children.addElement(child); - child.parent = this; - } - - public void addChildAtStart(Box child) { - this.children.insertElementAt(child, 0); - child.parent = this; - } - - public void addDisplaySpace(int size) { - this.addChild(new DisplaySpace(size)); - this.absoluteHeight += size; - this.currentHeight += size; - } - - public void addInlineSpace(int size) { - this.addChild(new InlineSpace(size)); - // other adjustments... - } - - public FontInfo getFontInfo() { - return this.page.getFontInfo(); - } - - public void end() {} - - public int getAllocationWidth() { - /* - * ATTENTION: this may change your output!! (Karen Lease, 4mar2001) - * return this.allocationWidth - getPaddingLeft() - getPaddingRight() - * - getBorderLeftWidth() - getBorderRightWidth(); - */ - return this.allocationWidth; - } - - /** - * Set the allocation width. - * @param w The new allocation width. - * This sets content width to the same value. - * Currently only called during layout of Table to set the width - * to the total width of all the columns. Note that this assumes the - * column widths are explicitly specified. - */ - public void setAllocationWidth(int w) { - this.allocationWidth = w; - this.contentRectangleWidth = this.allocationWidth; - } - - public Vector getChildren() { - return this.children; - } - - public boolean hasChildren() { - return (this.children.size() != 0); - } - - public int getContentWidth() { - /* - * ATTENTION: this may change your output!! (Karen Lease, 4mar2001) - * return contentRectangleWidth - getPaddingLeft() - getPaddingRight() - * - getBorderLeftWidth() - getBorderRightWidth(); - */ - return contentRectangleWidth; - } - - public FontState getFontState() { - return this.fontState; - } - - /** - * Returns content height of the area. - * - * @return Content height in millipoints - */ - public int getContentHeight() { - return this.currentHeight; - } - - /** - * Returns allocation height of this area. - * The allocation height is the sum of the content height plus border - * and padding in the vertical direction. - * - * @return allocation height in millipoints - */ - public int getHeight() { - return this.currentHeight + getPaddingTop() + getPaddingBottom() - + getBorderTopWidth() + getBorderBottomWidth(); - } - - public int getMaxHeight() { - // Change KDL: return max height of content rectangle - return this.maxHeight; - /* - * return this.maxHeight - getPaddingTop() - getPaddingBottom() - - * getBorderTopWidth() - getBorderBottomWidth(); - */ - } - - public Page getPage() { - return this.page; - } - - public ColorType getBackgroundColor() { - return this.backgroundColor; - } - - // Must handle conditionality here, depending on isLast/isFirst - public int getPaddingTop() { - return (bp == null ? 0 : bp.getPaddingTop(false)); - } - - public int getPaddingLeft() { - return (bp == null ? 0 : bp.getPaddingLeft(false)); - } - - public int getPaddingBottom() { - return (bp == null ? 0 : bp.getPaddingBottom(false)); - } - - public int getPaddingRight() { - return (bp == null ? 0 : bp.getPaddingRight(false)); - } - - // Handle border-width, including conditionality - // For now, just pass false everywhere! - public int getBorderTopWidth() { - return (bp == null ? 0 : bp.getBorderTopWidth(false)); - } - - public int getBorderRightWidth() { - return (bp == null ? 0 : bp.getBorderRightWidth(false)); - } - - public int getBorderLeftWidth() { - return (bp == null ? 0 : bp.getBorderLeftWidth(false)); - } - - public int getBorderBottomWidth() { - return (bp == null ? 0 : bp.getBorderBottomWidth(false)); - } - - public int getTableCellXOffset() { - return tableCellXOffset; - } - - public void setTableCellXOffset(int offset) { - tableCellXOffset = offset; - } - - public int getAbsoluteHeight() { - return absoluteHeight; - } - - public void setAbsoluteHeight(int value) { - absoluteHeight = value; - } - - public void increaseAbsoluteHeight(int value) { - absoluteHeight += value; - } - - public void increaseHeight(int amount) { - this.currentHeight += amount; - this.absoluteHeight += amount; - } - - // Remove allocation height of child - public void removeChild(Area area) { - this.currentHeight -= area.getHeight(); - this.absoluteHeight -= area.getHeight(); - this.children.removeElement(area); - } - - public void removeChild(DisplaySpace spacer) { - this.currentHeight -= spacer.getSize(); - this.absoluteHeight -= spacer.getSize(); - this.children.removeElement(spacer); - } - - public void remove() { - this.parent.removeChild(this); - } - - public void setPage(Page page) { - this.page = page; - } - - public void setBackgroundColor(ColorType bgColor) { - this.backgroundColor = bgColor; - } - - public void setBorderAndPadding(BorderAndPadding bp) { - this.bp = bp; - } - - /** - * Return space remaining in the vertical direction (height). - * This returns maximum available space - current content height - * Note: content height should be based on allocation height of content! - * @return space remaining in base units (millipoints) - */ - public int spaceLeft() { - return maxHeight - currentHeight; - } - - public void start() {} - - - /** - * Set the content height to the passed value if that value is - * larger than current content height. If the new content height - * is greater than the maximum available height, set the content height - * to the max. available (!!!) - * - * @param height allocation height of content in millipoints - */ - public void setHeight(int height) { - int prevHeight = currentHeight; - if (height > currentHeight) { - currentHeight = height; - } - - if (currentHeight > getMaxHeight()) { - currentHeight = getMaxHeight(); - } - absoluteHeight += (currentHeight - prevHeight); - } - - public void setMaxHeight(int height) { - this.maxHeight = height; - } - - public Area getParent() { - return this.parent; - } - - public void setParent(Area parent) { - this.parent = parent; - } - - public void setIDReferences(IDReferences idReferences) { - this.idReferences = idReferences; - } - - public IDReferences getIDReferences() { - return idReferences; - } - - /* Author seshadri */ - public org.apache.fop.fo.FObj getfoCreator() { - return this.foCreator; - } - - // Function not currently used! (KLease, 16mar01) - - public AreaContainer getNearestAncestorAreaContainer() { - Area area = this.getParent(); - while (!(area instanceof AreaContainer)) { - area = area.getParent(); - } - return (AreaContainer)area; - } - - public BorderAndPadding getBorderAndPadding() { - return bp; - } - - public void addMarker(Marker marker) { - markers.addElement(marker); - } - - public void addMarkers(Vector markers) { - markers.addAll(markers); - } - - public void addLineagePair(org.apache.fop.fo.FObj fo, int areaPosition) { - returnedBy.put(fo, new Integer(areaPosition)); - } - - public Vector getMarkers() { - return markers; - } - - public void setGeneratedBy(org.apache.fop.fo.FObj generatedBy) { - this.generatedBy = generatedBy; - } - - public org.apache.fop.fo.FObj getGeneratedBy() { - return generatedBy; - } - - public void isFirst(boolean isFirst) { - this.isFirst = isFirst; - } - - public boolean isFirst() { - return isFirst; - } - - public void isLast(boolean isLast) { - this.isLast = isLast; - } - - public boolean isLast() { - return isLast; - } - -} diff --git a/src/org/apache/fop/layout/AreaClass.java b/src/org/apache/fop/layout/AreaClass.java deleted file mode 100644 index 7af180a90..000000000 --- a/src/org/apache/fop/layout/AreaClass.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.apps.FOPException; - -public class AreaClass { - public static String UNASSIGNED = "unassigned"; - - public static String XSL_NORMAL = "xsl-normal"; - public static String XSL_ABSOLUTE = "xsl-absolute"; - public static String XSL_FOOTNOTE = "xsl-footnote"; - public static String XSL_SIDE_FLOAT = "xsl-side-float"; - public static String XSL_BEFORE_FLOAT = "xsl-before-float"; - - // checker method - public static String setAreaClass(String areaClass) throws FOPException { - if (areaClass.equals(XSL_NORMAL) || areaClass.equals(XSL_ABSOLUTE) - || areaClass.equals(XSL_FOOTNOTE) - || areaClass.equals(XSL_SIDE_FLOAT) - || areaClass.equals(XSL_BEFORE_FLOAT)) - return areaClass; - else - throw new FOPException("Unknown area class '" + areaClass + "'"); - } - -} - diff --git a/src/org/apache/fop/layout/AreaContainer.java b/src/org/apache/fop/layout/AreaContainer.java deleted file mode 100644 index 53da72fda..000000000 --- a/src/org/apache/fop/layout/AreaContainer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.render.Renderer; -import org.apache.fop.fo.properties.*; - -// Java -import java.util.Vector; -import java.util.Enumeration; - -public class AreaContainer extends Area { - - private int xPosition; // should be able to take value 'left' and 'right' too - private int yPosition; // should be able to take value 'top' and 'bottom' too - private int position; - - // use this for identifying the general usage of the area, - // like 'main-reference-area' or 'region-before' - private String areaName; - - public AreaContainer(FontState fontState, int xPosition, int yPosition, - int allocationWidth, int maxHeight, int position) { - super(fontState, allocationWidth, maxHeight); - this.xPosition = xPosition; - this.yPosition = yPosition; - this.position = position; - // setIsReferenceArea(true); // Should always be true! - } - - public void render(Renderer renderer) { - renderer.renderAreaContainer(this); - } - - public int getPosition() { - return position; - } - - public int getXPosition() { - // return xPosition + getPaddingLeft() + getBorderLeftWidth(); - return xPosition; - } - - public void setXPosition(int value) { - xPosition = value; - } - - public int getYPosition() { - // return yPosition + getPaddingTop() + getBorderTopWidth(); - return yPosition; - } - - public int getCurrentYPosition() { - return yPosition; - } - - public void setYPosition(int value) { - yPosition = value; - } - - public void shiftYPosition(int value) { - yPosition += value; - } - - public String getAreaName() { - return areaName; - } - - public void setAreaName(String areaName) { - this.areaName = areaName; - } - -} diff --git a/src/org/apache/fop/layout/AuralProps.java b/src/org/apache/fop/layout/AuralProps.java deleted file mode 100644 index 4daf89ab4..000000000 --- a/src/org/apache/fop/layout/AuralProps.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class AuralProps { - public int azimuth; - public String cueAfter; - public String cueBefore; - public int elevation; - public int pauseAfter; - public int pauseBefore; - public int pitch; - public int pitchRange; - public int playDuring; - public int richness; - public int speak; - public int speakHeader; - public int speakNumeral; - public int speakPunctuation; - public int speechRate; - public int stress; - public int voiceFamily; - public int volume; - - public AuralProps() {} - -} diff --git a/src/org/apache/fop/layout/BackgroundProps.java b/src/org/apache/fop/layout/BackgroundProps.java deleted file mode 100644 index 6c2d47cda..000000000 --- a/src/org/apache/fop/layout/BackgroundProps.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.datatypes.Length; - -import java.awt.Color; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class BackgroundProps { - public int backAttachment; - public Color backColor; - public String backImage; - public int backRepeat; - public Length backPosHorizontal; - public Length backPosVertical; - - public BackgroundProps() {} - -} diff --git a/src/org/apache/fop/layout/BlockArea.java b/src/org/apache/fop/layout/BlockArea.java deleted file mode 100644 index 44f6f0c22..000000000 --- a/src/org/apache/fop/layout/BlockArea.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.render.Renderer; -import org.apache.fop.fo.flow.*; -import org.apache.fop.fo.*; -import org.apache.fop.apps.*; -import org.apache.fop.fo.properties.*; - -// Java -import java.util.Vector; -import java.util.Enumeration; -import org.apache.fop.messaging.MessageHandler; - -/** - * This class represents a Block Area. - * A block area is made up of a sequence of Line Areas. - * - * This class is used to organise the sequence of line areas as - * inline areas are added to this block it creates and ands line areas - * to hold the inline areas. - * This uses the line-height and line-stacking-strategy to work - * out how to stack the lines. - */ -public class BlockArea extends Area { - - /* relative to area container */ - protected int startIndent; - protected int endIndent; - - /* first line startIndent modifier */ - protected int textIndent; - - protected int lineHeight; - - protected int halfLeading; - - - /* text-align of all but the last line */ - protected int align; - - /* text-align of the last line */ - protected int alignLastLine; - - protected LineArea currentLineArea; - protected LinkSet currentLinkSet; - - /* have any line areas been used? */ - protected boolean hasLines = false; - - /* hyphenation */ - protected HyphenationProps hyphProps; - - protected Vector pendingFootnotes = null; - - public BlockArea(FontState fontState, int allocationWidth, int maxHeight, - int startIndent, int endIndent, int textIndent, - int align, int alignLastLine, int lineHeight) { - super(fontState, allocationWidth, maxHeight); - - this.startIndent = startIndent; - this.endIndent = endIndent; - this.textIndent = textIndent; - this.contentRectangleWidth = allocationWidth - startIndent - - endIndent; - this.align = align; - this.alignLastLine = alignLastLine; - this.lineHeight = lineHeight; - - if (fontState != null) - this.halfLeading = (lineHeight - fontState.getFontSize()) / 2; - } - - public void render(Renderer renderer) { - renderer.renderBlockArea(this); - } - - /** - * Add a Line Area to this block area. - * Used internally to add a completed line area to this block area - * when either a new line area is created or this block area is - * completed. - * - * @param la the LineArea to add - */ - protected void addLineArea(LineArea la) { - if (!la.isEmpty()) { - la.verticalAlign(); - this.addDisplaySpace(this.halfLeading); - int size = la.getHeight(); - this.addChild(la); - this.increaseHeight(size); - this.addDisplaySpace(this.halfLeading); - } - // add pending footnotes - if (pendingFootnotes != null) { - for (Enumeration e = pendingFootnotes.elements(); - e.hasMoreElements(); ) { - FootnoteBody fb = (FootnoteBody)e.nextElement(); - Page page = getPage(); - if (!Footnote.layoutFootnote(page, fb, this)) { - page.addPendingFootnote(fb); - } - } - pendingFootnotes = null; - } - } - - /** - * Get the current line area in this block area. - * This is used to get the current line area for adding - * inline objects to. - * This will return null if there is not enough room left - * in the block area to accomodate the line area. - * - * @return the line area to be used to add inlie objects - */ - public LineArea getCurrentLineArea() { - if (currentHeight + lineHeight > maxHeight) { - return null; - } - this.currentLineArea.changeHyphenation(hyphProps); - this.hasLines = true; - return this.currentLineArea; - } - - /** - * Create a new line area to add inline objects. - * This should be called after getting the current line area - * and discovering that the inline object will not fit inside the current - * line. This method will create a new line area to place the inline - * object into. - * This will return null if the new line cannot fit into the block area. - * - * @return the new current line area, which will be empty. - */ - public LineArea createNextLineArea() { - if (this.hasLines) { - this.currentLineArea.align(this.align); - this.addLineArea(this.currentLineArea); - } - this.currentLineArea = new LineArea(fontState, lineHeight, - halfLeading, allocationWidth, - startIndent, endIndent, - currentLineArea); - this.currentLineArea.changeHyphenation(hyphProps); - if (currentHeight + lineHeight > maxHeight) { - return null; - } - return this.currentLineArea; - } - - public void setupLinkSet(LinkSet ls) { - if (ls != null) { - this.currentLinkSet = ls; - ls.setYOffset(currentHeight); - } - } - - /** - * Notify this block that the area has completed layout. - * Indicates the the block has been fully laid out, this will - * add (if any) the current line area. - */ - public void end() { - if (this.hasLines) { - this.currentLineArea.addPending(); - this.currentLineArea.align(this.alignLastLine); - this.addLineArea(this.currentLineArea); - } - } - - public void start() { - currentLineArea = new LineArea(fontState, lineHeight, halfLeading, - allocationWidth, - startIndent + textIndent, endIndent, - null); - } - - public int getEndIndent() { - return endIndent; - } - - // KL: I think we should just return startIndent here! - public int getStartIndent() { - // return startIndent + paddingLeft + borderWidthLeft; - return startIndent; - } - - public void setIndents(int startIndent, int endIndent) { - this.startIndent = startIndent; - this.endIndent = endIndent; - this.contentRectangleWidth = allocationWidth - startIndent - - endIndent; - } - - public int spaceLeft() { - return maxHeight - currentHeight; - } - - public int getHalfLeading() { - return halfLeading; - } - - public void setHyphenation(HyphenationProps hyphProps) { - this.hyphProps = hyphProps; - } - - public void addFootnote(FootnoteBody fb) { - if (pendingFootnotes == null) { - pendingFootnotes = new Vector(); - } - pendingFootnotes.addElement(fb); - } - -} diff --git a/src/org/apache/fop/layout/BodyAreaContainer.java b/src/org/apache/fop/layout/BodyAreaContainer.java deleted file mode 100644 index 9fd6122af..000000000 --- a/src/org/apache/fop/layout/BodyAreaContainer.java +++ /dev/null @@ -1,394 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.render.Renderer; -import org.apache.fop.fo.properties.*; -import org.apache.fop.datatypes.IDReferences; -import org.apache.fop.apps.FOPException; -import org.apache.fop.fo.FObj; -import org.apache.fop.fo.flow.Block; -import org.apache.fop.fo.flow.BlockContainer; - -// Java -import java.util.Vector; -import java.util.Enumeration; - -public class BodyAreaContainer extends Area { - - // dimensions for the 'region-reference-area' - private int xPosition; // should be able to take value 'left' and 'right' too - private int yPosition; // should be able to take value 'top' and 'bottom' too - private int position; - - // the column-count and column-gap - private int columnCount; - private int columnGap; - - // the 3 primary reference areas - private AreaContainer mainReferenceArea; - private AreaContainer beforeFloatReferenceArea; - private AreaContainer footnoteReferenceArea; - - // current heights - private int mainRefAreaHeight; - private int beforeFloatRefAreaHeight; - private int footnoteRefAreaHeight; - - // reference area yPositions - private int mainYPosition; - private int beforeFloatYPosition; - private int footnoteYPosition; - - // the start FO in case of rollback - private FObj startFO; - private boolean isNewSpanArea; - - // keeps track of footnote state for multiple layouts - private int footnoteState = 0; - - public BodyAreaContainer(FontState fontState, int xPosition, - int yPosition, int allocationWidth, - int maxHeight, int position, int columnCount, - int columnGap) { - super(fontState, allocationWidth, maxHeight); - this.xPosition = xPosition; - this.yPosition = yPosition; - this.position = position; - this.columnCount = columnCount; - this.columnGap = columnGap; - - // create the primary reference areas - beforeFloatRefAreaHeight = 0; - footnoteRefAreaHeight = 0; - mainRefAreaHeight = maxHeight - beforeFloatRefAreaHeight - - footnoteRefAreaHeight; - beforeFloatReferenceArea = new AreaContainer(fontState, xPosition, - yPosition, allocationWidth, beforeFloatRefAreaHeight, - Position.ABSOLUTE); - beforeFloatReferenceArea.setAreaName("before-float-reference-area"); - this.addChild(beforeFloatReferenceArea); - mainReferenceArea = new AreaContainer(fontState, xPosition, - yPosition, allocationWidth, - mainRefAreaHeight, - Position.ABSOLUTE); - mainReferenceArea.setAreaName("main-reference-area"); - this.addChild(mainReferenceArea); - int footnoteRefAreaYPosition = yPosition - mainRefAreaHeight; - footnoteReferenceArea = new AreaContainer(fontState, xPosition, - footnoteRefAreaYPosition, - allocationWidth, - footnoteRefAreaHeight, - Position.ABSOLUTE); - footnoteReferenceArea.setAreaName("footnote-reference-area"); - this.addChild(footnoteReferenceArea); - - // all padding and border-width must be 0 - // setBorderAndPadding(new BorderAndPadding()); - // setPadding(0, 0, 0, 0); - // setBorderWidth(0, 0, 0, 0); - } - - public void render(Renderer renderer) { - renderer.renderBodyAreaContainer(this); - } - - public int getPosition() { - return position; - } - - public int getXPosition() { - return xPosition + getPaddingLeft() + getBorderLeftWidth(); - } - - public void setXPosition(int value) { - xPosition = value; - } - - public int getYPosition() { - return yPosition + getPaddingTop() + getBorderTopWidth(); - } - - public void setYPosition(int value) { - yPosition = value; - } - - public AreaContainer getMainReferenceArea() { - return mainReferenceArea; - } - - public AreaContainer getBeforeFloatReferenceArea() { - return beforeFloatReferenceArea; - } - - public AreaContainer getFootnoteReferenceArea() { - return footnoteReferenceArea; - } - - public void setIDReferences(IDReferences idReferences) { - mainReferenceArea.setIDReferences(idReferences); - } - - public IDReferences getIDReferences() { - return mainReferenceArea.getIDReferences(); - } - - /** - * Depending on the column-count of the next FO, determine whether - * a new span area needs to be constructed or not, and return the - * appropriate ColumnArea. - * The next cut of this method should also inspect the FO to see - * whether the area to be returned ought not to be the footnote - * or before-float reference area. - * @param fo The next formatting object - * @returns the next column area (possibly the current one) - */ - public AreaContainer getNextArea(FObj fo) throws FOPException { - isNewSpanArea = false; - - int span = Span.NONE; - if (fo instanceof Block) - span = ((Block)fo).getSpan(); - else if (fo instanceof BlockContainer) - span = ((BlockContainer)fo).getSpan(); - - if (this.mainReferenceArea.getChildren().isEmpty()) { - if (span == Span.ALL) - return addSpanArea(1); - else - return addSpanArea(columnCount); - } - - Vector spanAreas = this.mainReferenceArea.getChildren(); - SpanArea spanArea = (SpanArea)spanAreas.elementAt(spanAreas.size() - - 1); - - if ((span == Span.ALL) && (spanArea.getColumnCount() == 1)) { - // return the single column area in the same span area - return spanArea.getCurrentColumnArea(); - } else if ((span == Span.NONE) - && (spanArea.getColumnCount() == columnCount)) { - // return the current column area in the same span area - return spanArea.getCurrentColumnArea(); - } else if (span == Span.ALL) { - // create new span area with one column; return column area - return addSpanArea(1); - } else if (span == Span.NONE) { - // create new span area with multiple columns; return first column area - return addSpanArea(columnCount); - } else { - throw new FOPException("BodyAreaContainer::getNextArea(): Span attribute messed up"); - } - } - - /** - * Add a new span area with specified number of column areas. - * @param numColumns The number of column areas - * @returns AreaContainer The next column area - */ - private AreaContainer addSpanArea(int numColumns) { - resetHeights(); - // create span area and child column-areas, using whatever - // height remains after existing span areas (in the main - // reference area). - int spanAreaYPosition = getYPosition() - - this.mainReferenceArea.getContentHeight(); - - SpanArea spanArea = new SpanArea(fontState, getXPosition(), - spanAreaYPosition, allocationWidth, - getRemainingHeight(), numColumns, - columnGap); - this.mainReferenceArea.addChild(spanArea); - spanArea.setPage(this.getPage()); - this.isNewSpanArea = true; - return spanArea.getCurrentColumnArea(); - } - - /** - * This almost does what getNewArea() does, without actually - * returning an area. These 2 methods can be reworked. - * @param fo The next formatting object - * @returns boolean True if we need to balance. - */ - public boolean isBalancingRequired(FObj fo) { - if (this.mainReferenceArea.getChildren().isEmpty()) - return false; - - Vector spanAreas = this.mainReferenceArea.getChildren(); - SpanArea spanArea = (SpanArea)spanAreas.elementAt(spanAreas.size() - - 1); - - if (spanArea.isBalanced()) - return false; - - int span = Span.NONE; - if (fo instanceof Block) - span = ((Block)fo).getSpan(); - else if (fo instanceof BlockContainer) - span = ((BlockContainer)fo).getSpan(); - - if ((span == Span.ALL) && (spanArea.getColumnCount() == 1)) - return false; - else if ((span == Span.NONE) - && (spanArea.getColumnCount() == columnCount)) - return false; - else if (span == Span.ALL) - return true; - else if (span == Span.NONE) - return false; - else - return false; - } - - /** - * This is where the balancing algorithm lives, or gets called. - * Right now it's primitive: get the total content height in all - * columns, divide by the column count, and add a heuristic - * safety factor. - * Then the previous (unbalanced) span area is removed, and a new - * one added with the computed max height. - */ - public void resetSpanArea() { - Vector spanAreas = this.mainReferenceArea.getChildren(); - SpanArea spanArea = (SpanArea)spanAreas.elementAt(spanAreas.size() - - 1); - - if (!spanArea.isBalanced()) { - // span area maintains a record of the total height of - // laid-out content in the previous (first) attempt - int newHeight = spanArea.getTotalContentHeight() - / spanArea.getColumnCount(); - newHeight += 2 * 15600; // ??? - - this.mainReferenceArea.removeChild(spanArea); - resetHeights(); - SpanArea newSpanArea = new SpanArea(fontState, getXPosition(), - spanArea.getYPosition(), - allocationWidth, newHeight, - spanArea.getColumnCount(), - columnGap); - this.mainReferenceArea.addChild(newSpanArea); - newSpanArea.setPage(this.getPage()); - newSpanArea.setIsBalanced(); - this.isNewSpanArea = true; - } else { - throw new IllegalStateException("Trying to balance balanced area"); - } - } - - /** - * Determine remaining height for new span area. Needs to be - * modified for footnote and before-float reference areas when - * those are supported. - * @returns int The remaining available height in millipoints. - */ - public int getRemainingHeight() { - return this.mainReferenceArea.getMaxHeight() - - this.mainReferenceArea.getContentHeight(); - } - - /** - * Used by resetSpanArea() and addSpanArea() to adjust the main - * reference area height before creating a new span. - */ - private void resetHeights() { - int totalHeight = 0; - for (Enumeration e = this.mainReferenceArea.getChildren().elements(); - e.hasMoreElements(); ) { - SpanArea spanArea = (SpanArea)e.nextElement(); - int spanContentHeight = spanArea.getMaxContentHeight(); - int spanMaxHeight = spanArea.getMaxHeight(); - - totalHeight += (spanContentHeight < spanMaxHeight) - ? spanContentHeight : spanMaxHeight; - } - this.mainReferenceArea.setHeight(totalHeight); - } - - /** - * Used in Flow when layout returns incomplete. - * @returns boolean Is this the last column in this span? - */ - public boolean isLastColumn() { - Vector spanAreas = this.mainReferenceArea.getChildren(); - SpanArea spanArea = (SpanArea)spanAreas.elementAt(spanAreas.size() - - 1); - return spanArea.isLastColumn(); - } - - /** - * This variable is unset by getNextArea(), is set by addSpanArea(), - * and may be set by resetSpanArea(). - * @returns boolean Is the span area new or not? - */ - public boolean isNewSpanArea() { - return isNewSpanArea; - } - - public AreaContainer getCurrentColumnArea() { - Vector spanAreas = this.mainReferenceArea.getChildren(); - SpanArea spanArea = (SpanArea)spanAreas.elementAt(spanAreas.size() - - 1); - return spanArea.getCurrentColumnArea(); - } - - public int getFootnoteState() { - return footnoteState; - } - - public boolean needsFootnoteAdjusting() { - footnoteYPosition = footnoteReferenceArea.getYPosition(); - switch (footnoteState) { - case 0: - resetHeights(); - if (footnoteReferenceArea.getHeight() > 0 - && mainYPosition + mainReferenceArea.getHeight() - > footnoteYPosition) { - return true; - } - case 1: - break; - } - return false; - } - - public void adjustFootnoteArea() { - footnoteState++; - if (footnoteState == 1) { - mainReferenceArea.setMaxHeight(footnoteReferenceArea.getYPosition() - - mainYPosition); - footnoteYPosition = footnoteReferenceArea.getYPosition(); - footnoteReferenceArea.setMaxHeight(footnoteReferenceArea.getHeight()); - - Vector childs = footnoteReferenceArea.getChildren(); - for (Enumeration en = childs.elements(); en.hasMoreElements(); ) { - Object obj = en.nextElement(); - if (obj instanceof Area) { - Area childArea = (Area)obj; - footnoteReferenceArea.removeChild(childArea); - } - } - - getPage().setPendingFootnotes(null); - } - } - - protected static void resetMaxHeight(Area ar, int change) { - ar.setMaxHeight(change); - Vector childs = ar.getChildren(); - for (Enumeration en = childs.elements(); en.hasMoreElements(); ) { - Object obj = en.nextElement(); - if (obj instanceof Area) { - Area childArea = (Area)obj; - resetMaxHeight(childArea, change); - } - } - } - -} diff --git a/src/org/apache/fop/layout/BodyRegionArea.java b/src/org/apache/fop/layout/BodyRegionArea.java deleted file mode 100644 index 98d46a873..000000000 --- a/src/org/apache/fop/layout/BodyRegionArea.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.fo.properties.*; - -// Represents region-body viewport/reference areas. -// The areas generated by fo:region-body are sufficiently dissimilar to -// the other 4 regions that we employ a different class - -public class BodyRegionArea extends RegionArea { - - // the column count and column-gap - private int columnCount; - private int columnGap; - - public BodyRegionArea(int xPosition, int yPosition, int width, - int height) { - super(xPosition, yPosition, width, height); - } - - public BodyAreaContainer makeBodyAreaContainer() { - return new BodyAreaContainer(null, xPosition, yPosition, width, - height, Position.ABSOLUTE, columnCount, - columnGap); - } - - public void setColumnCount(int columnCount) { - this.columnCount = columnCount; - } - - public int getColumnCount() { - return columnCount; - } - - public void setColumnGap(int columnGap) { - this.columnGap = columnGap; - } - - public int getColumnGap() { - return columnGap; - } - -} diff --git a/src/org/apache/fop/layout/BorderAndPadding.java b/src/org/apache/fop/layout/BorderAndPadding.java deleted file mode 100644 index ace036800..000000000 --- a/src/org/apache/fop/layout/BorderAndPadding.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.datatypes.ColorType; -import org.apache.fop.datatypes.CondLength; - -public class BorderAndPadding implements Cloneable { - - public static final int TOP = 0; - public static final int RIGHT = 1; - public static final int BOTTOM = 2; - public static final int LEFT = 3; - - private static class ResolvedCondLength implements Cloneable { - int iLength; // Resolved length value - boolean bDiscard; - - ResolvedCondLength(CondLength length) { - bDiscard = length.isDiscard(); - iLength = length.mvalue(); - } - - public Object clone() throws CloneNotSupportedException { - return super.clone(); - } - - } - - /** - * Return a full copy of the BorderAndPadding information. This clones all - * padding and border information. - * @return The copy. - */ - public Object clone() throws CloneNotSupportedException { - BorderAndPadding bp = (BorderAndPadding) super.clone(); - bp.padding = (ResolvedCondLength[])padding.clone(); - bp.borderInfo = (BorderInfo[])borderInfo.clone(); - for (int i=0; i 600) - weight = "bold"; - else if (i > 0) - weight = "normal"; - - return family + "," + style + "," + weight; - } - - public Hashtable getFonts() { - return this.fonts; - } - - public Hashtable getUsedFonts() { - return this.usedFonts; - } - - public FontMetric getMetricsFor(String fontName) throws FOPException { - usedFonts.put(fontName, fonts.get(fontName)); - return (FontMetric)fonts.get(fontName); - } - -} diff --git a/src/org/apache/fop/layout/FontMetric.java b/src/org/apache/fop/layout/FontMetric.java deleted file mode 100644 index 93b60ae92..000000000 --- a/src/org/apache/fop/layout/FontMetric.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * interface for font metric classes - */ -public interface FontMetric { - - public int getAscender(int size); - public int getCapHeight(int size); - public int getDescender(int size); - public int getXHeight(int size); - - public int getFirstChar(); - public int getLastChar(); - - /** - * return width (in 1/1000ths of point size) of character at - * code point i - */ - public int width(int i, int size); - public int[] getWidths(int size); -} diff --git a/src/org/apache/fop/layout/FontState.java b/src/org/apache/fop/layout/FontState.java deleted file mode 100644 index 498db1000..000000000 --- a/src/org/apache/fop/layout/FontState.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import java.util.Hashtable; - -import org.apache.fop.apps.FOPException; -import org.apache.fop.fo.properties.FontVariant; - -public class FontState { - - private FontInfo _fontInfo; - private String _fontName; - private int _fontSize; - private String _fontFamily; - private String _fontStyle; - private String _fontWeight; - private int _fontVariant; - - private FontMetric _metric; - - private static Hashtable EMPTY_HASHTABLE = new Hashtable(); - - - public FontState(FontInfo fontInfo, String fontFamily, String fontStyle, - String fontWeight, int fontSize, - int fontVariant) throws FOPException { - _fontInfo = fontInfo; - _fontFamily = fontFamily; - _fontStyle = fontStyle; - _fontWeight = fontWeight; - _fontSize = fontSize; - _fontName = fontInfo.fontLookup(fontFamily, fontStyle, fontWeight); - _metric = fontInfo.getMetricsFor(_fontName); - _fontVariant = fontVariant; - } - - public int getAscender() { - return _metric.getAscender(_fontSize) / 1000; - } - - public int getCapHeight() { - return _metric.getCapHeight(_fontSize) / 1000; - } - - public int getDescender() { - return _metric.getDescender(_fontSize) / 1000; - } - - public String getFontName() { - return _fontName; - } - - public int getFontSize() { - return _fontSize; - } - - public String getFontWeight() { - return _fontWeight; - } - - public String getFontFamily() { - return _fontFamily; - } - - public String getFontStyle() { - return _fontStyle; - } - - public int getFontVariant() { - return _fontVariant; - } - - public FontInfo getFontInfo() { - return _fontInfo; - } - - public int getXHeight() { - return _metric.getXHeight(_fontSize) / 1000; - } - - public Hashtable getKerning() { - if (_metric instanceof FontDescriptor) { - Hashtable ret = ((FontDescriptor)_metric).getKerningInfo(); - if (ret != null) - return ret; - } - return EMPTY_HASHTABLE; - } - - public int width(int charnum) { - // returns width of given character number in millipoints - return (_metric.width(charnum, _fontSize) / 1000); - } - - /** - * Map a java character (unicode) to a font character - * Default uses CodePointMapping - */ - public char mapChar(char c) { - - if (_metric instanceof org.apache.fop.render.pdf.Font) { - return ((org.apache.fop.render.pdf.Font)_metric).mapChar(c); - } - - // Use default CodePointMapping - if (c > 127) { - char d = org.apache.fop.render.pdf.CodePointMapping.map[c]; - if (d != 0) { - c = d; - } else { - c = '#'; - } - } - - return c; - } - -} - - - diff --git a/src/org/apache/fop/layout/HyphenationProps.java b/src/org/apache/fop/layout/HyphenationProps.java deleted file mode 100644 index c241feb72..000000000 --- a/src/org/apache/fop/layout/HyphenationProps.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class HyphenationProps { - public int hyphenate; // Enum true or false: store as boolean! - public char hyphenationChar; - public int hyphenationPushCharacterCount; - public int hyphenationRemainCharacterCount; - public String language; // Language code or enum "NONE" - public String country; // Country code or enum "NONE" - - public HyphenationProps() {} - -} diff --git a/src/org/apache/fop/layout/LineArea.java b/src/org/apache/fop/layout/LineArea.java deleted file mode 100644 index 6510e93f9..000000000 --- a/src/org/apache/fop/layout/LineArea.java +++ /dev/null @@ -1,1317 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// fop -import org.apache.fop.render.Renderer; -import org.apache.fop.messaging.MessageHandler; -import org.apache.fop.layout.inline.*; -import org.apache.fop.datatypes.IDNode; -import org.apache.fop.fo.properties.WrapOption; -import org.apache.fop.fo.properties.WhiteSpaceCollapse; -import org.apache.fop.fo.properties.TextAlign; -import org.apache.fop.fo.properties.TextAlignLast; -import org.apache.fop.fo.properties.LeaderPattern; -import org.apache.fop.fo.properties.Hyphenate; -import org.apache.fop.fo.properties.CountryMaker; -import org.apache.fop.fo.properties.LanguageMaker; -import org.apache.fop.fo.properties.LeaderAlignment; -import org.apache.fop.fo.properties.VerticalAlign; -import org.apache.fop.layout.hyphenation.Hyphenation; -import org.apache.fop.layout.hyphenation.Hyphenator; -import org.apache.fop.configuration.Configuration; - -// java -import java.util.Vector; -import java.util.Enumeration; -import java.util.StringTokenizer; -import java.awt.Rectangle; - -public class LineArea extends Area { - - protected int lineHeight; - protected int halfLeading; - protected int nominalFontSize; - protected int nominalGlyphHeight; - - protected int allocationHeight; - protected int startIndent; - protected int endIndent; - - private int placementOffset; - - private FontState currentFontState; // not the nominal, which is - // in this.fontState - private float red, green, blue; - private int wrapOption; - private int whiteSpaceCollapse; - int vAlign; - - /* hyphenation */ - HyphenationProps hyphProps; - - /* - * the width of text that has definitely made it into the line - * area - */ - protected int finalWidth = 0; - - /* the position to shift a link rectangle in order to compensate for links embedded within a word */ - protected int embeddedLinkStart = 0; - - /* the width of the current word so far */ - // protected int wordWidth = 0; - - /* values that prev (below) may take */ - protected static final int NOTHING = 0; - protected static final int WHITESPACE = 1; - protected static final int TEXT = 2; - - /* the character type of the previous character */ - protected int prev = NOTHING; - - /* the position in data[] of the start of the current word */ - // protected int wordStart; - - /* the length (in characters) of the current word */ - // protected int wordLength = 0; - - /* width of spaces before current word */ - protected int spaceWidth = 0; - - /* - * the inline areas that have not yet been added to the line - * because subsequent characters to come (in a different addText) - * may be part of the same word - */ - protected Vector pendingAreas = new Vector(); - - /* the width of the pendingAreas */ - protected int pendingWidth = 0; - - /* text-decoration of the previous text */ - protected boolean prevUlState = false; - protected boolean prevOlState = false; - protected boolean prevLTState = false; - - public LineArea(FontState fontState, int lineHeight, int halfLeading, - int allocationWidth, int startIndent, int endIndent, - LineArea prevLineArea) { - super(fontState); - - this.currentFontState = fontState; - this.lineHeight = lineHeight; - this.nominalFontSize = fontState.getFontSize(); - this.nominalGlyphHeight = fontState.getAscender() - - fontState.getDescender(); - - this.placementOffset = fontState.getAscender(); - this.contentRectangleWidth = allocationWidth - startIndent - - endIndent; - this.fontState = fontState; - - this.allocationHeight = this.nominalGlyphHeight; - this.halfLeading = this.lineHeight - this.allocationHeight; - - this.startIndent = startIndent; - this.endIndent = endIndent; - - if (prevLineArea != null) { - Enumeration e = prevLineArea.pendingAreas.elements(); - Box b = null; - // There might be InlineSpaces at the beginning - // that should not be there - eat them - boolean eatMoreSpace = true; - int eatenWidth = 0; - - while (eatMoreSpace) { - if (e.hasMoreElements()) { - b = (Box)e.nextElement(); - if (b instanceof InlineSpace) { - InlineSpace is = (InlineSpace)b; - if (is.isEatable()) - eatenWidth += is.getSize(); - else - eatMoreSpace = false; - } else { - eatMoreSpace = false; - } - } else { - eatMoreSpace = false; - b = null; - } - } - - while (b != null) { - pendingAreas.addElement(b); - if (e.hasMoreElements()) - b = (Box)e.nextElement(); - else - b = null; - } - pendingWidth = prevLineArea.getPendingWidth() - eatenWidth; - } - } - - public void render(Renderer renderer) { - renderer.renderLineArea(this); - } - - public int addPageNumberCitation(String refid, LinkSet ls) { - - /* - * We should add code here to handle the case where the page number doesn't fit on the current line - */ - - // Space must be alloted to the page number, so currently we give it 3 spaces - - int width = currentFontState.width(currentFontState.mapChar(' ')); - - - PageNumberInlineArea pia = new PageNumberInlineArea(currentFontState, - this.red, this.green, this.blue, refid, width); - - pia.setYOffset(placementOffset); - pendingAreas.addElement(pia); - pendingWidth += width; - prev = TEXT; - - return -1; - } - - - /** - * adds text to line area - * - * @return int character position - */ - public int addText(char odata[], int start, int end, LinkSet ls, - TextState textState) { - // this prevents an array index out of bounds - // which occurs when some text is laid out again. - if (start == -1) - return -1; - boolean overrun = false; - - int wordStart = start; - int wordLength = 0; - int wordWidth = 0; - // With CID fonts, space isn't neccesary currentFontState.width(32) - int whitespaceWidth = getCharWidth(' '); - - char[] data = new char[odata.length]; - char[] dataCopy = new char[odata.length]; - System.arraycopy(odata, 0, data, 0, odata.length); - System.arraycopy(odata, 0, dataCopy, 0, odata.length); - - boolean isText = false; - - /* iterate over each character */ - for (int i = start; i < end; i++) { - int charWidth; - /* get the character */ - char c = data[i]; - if (!(isSpace(c) || (c == '\n') || (c == '\r') || (c == '\t') - || (c == '\u2028'))) { - charWidth = getCharWidth(c); - isText = true; - // Add support for zero-width spaces - if (charWidth <= 0 && c != '\u200B' && c != '\uFEFF') - charWidth = whitespaceWidth; - } else { - if ((c == '\n') || (c == '\r') || (c == '\t')) - charWidth = whitespaceWidth; - else - charWidth = getCharWidth(c); - - isText = false; - - if (prev == WHITESPACE) { - - // if current & previous are WHITESPACE - - if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { - if (isSpace(c)) { - spaceWidth += getCharWidth(c); - } else if (c == '\n' || c == '\u2028') { - // force line break - if (spaceWidth > 0) { - InlineSpace is = new InlineSpace(spaceWidth); - is.setUnderlined(textState.getUnderlined()); - is.setOverlined(textState.getOverlined()); - is.setLineThrough(textState.getLineThrough()); - addChild(is); - finalWidth += spaceWidth; - spaceWidth = 0; - } - return i + 1; - } else if (c == '\t') { - spaceWidth += 8 * whitespaceWidth; - } - } else if (c == '\u2028') { - // Line separator - // Breaks line even if WhiteSpaceCollapse = True - if (spaceWidth > 0) { - InlineSpace is = new InlineSpace(spaceWidth); - is.setUnderlined(textState.getUnderlined()); - is.setOverlined(textState.getOverlined()); - is.setLineThrough(textState.getLineThrough()); - addChild(is); - finalWidth += spaceWidth; - spaceWidth = 0; - } - return i + 1; - } - - } else if (prev == TEXT) { - - // if current is WHITESPACE and previous TEXT - // the current word made it, so - // add the space before the current word (if there - // was some) - - if (spaceWidth > 0) { - InlineSpace is = new InlineSpace(spaceWidth); - if (prevUlState) { - is.setUnderlined(textState.getUnderlined()); - } - if (prevOlState) { - is.setOverlined(textState.getOverlined()); - } - if (prevLTState) { - is.setLineThrough(textState.getLineThrough()); - } - addChild(is); - finalWidth += spaceWidth; - spaceWidth = 0; - } - - // add any pending areas - - Enumeration e = pendingAreas.elements(); - while (e.hasMoreElements()) { - Box box = (Box)e.nextElement(); - if (box instanceof InlineArea) { - if (ls != null) { - Rectangle lr = - new Rectangle(finalWidth, 0, - ((InlineArea)box).getContentWidth(), - fontState.getFontSize()); - ls.addRect(lr, this, (InlineArea)box); - } - } - addChild(box); - } - - finalWidth += pendingWidth; - - // reset pending areas array - pendingWidth = 0; - pendingAreas = new Vector(); - - // add the current word - - if (wordLength > 0) { - // The word might contain nonbreaking - // spaces. Split the word and add InlineSpace - // as necessary. All spaces inside the word - // Have a fixed width. - addSpacedWord(new String(data, wordStart, wordLength), - ls, finalWidth, 0, textState, false); - finalWidth += wordWidth; - - // reset word width - wordWidth = 0; - } - - // deal with this new whitespace following the - // word we just added - prev = WHITESPACE; - - embeddedLinkStart = - 0; // reset embeddedLinkStart since a space was encountered - - spaceWidth = getCharWidth(c); - - /* - * here is the place for space-treatment value 'ignore': - * if (this.spaceTreatment == - * SpaceTreatment.IGNORE) { - * // do nothing - * } else { - * spaceWidth = currentFontState.width(32); - * } - */ - - - if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { - if (c == '\n' || c == '\u2028') { - // force a line break - return i + 1; - } else if (c == '\t') { - spaceWidth = whitespaceWidth; - } - } else if (c == '\u2028') { - return i + 1; - } - } else { - - // if current is WHITESPACE and no previous - - if (this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE) { - if (isSpace(c)) { - prev = WHITESPACE; - spaceWidth = getCharWidth(c); - } else if (c == '\n') { - // force line break - // textdecoration not used because spaceWidth is 0 - InlineSpace is = new InlineSpace(spaceWidth); - addChild(is); - return i + 1; - } else if (c == '\t') { - prev = WHITESPACE; - spaceWidth = 8 * whitespaceWidth; - } - - } else { - // skip over it - wordStart++; - } - } - - } - - if (isText) { // current is TEXT - - if (prev == WHITESPACE) { - - // if current is TEXT and previous WHITESPACE - - wordWidth = charWidth; - if ((finalWidth + spaceWidth + wordWidth) - > this.getContentWidth()) { - if (overrun) - MessageHandler.error(">"); - if (this.wrapOption == WrapOption.WRAP) { - return i; - } - } - prev = TEXT; - wordStart = i; - wordLength = 1; - } else if (prev == TEXT) { - wordLength++; - wordWidth += charWidth; - } else { // nothing previous - - prev = TEXT; - wordStart = i; - wordLength = 1; - wordWidth = charWidth; - } - - if ((finalWidth + spaceWidth + pendingWidth + wordWidth) - > this.getContentWidth()) { - - // BREAK MID WORD - if (canBreakMidWord()) { - addSpacedWord(new String(data, wordStart, wordLength - 1), - ls, - finalWidth + spaceWidth - + embeddedLinkStart, spaceWidth, - textState, false); - finalWidth += wordWidth; - wordWidth = 0; - return i; - } - if (wordStart == start) { // if couldn't even fit - // first word - overrun = true; - // if not at start of line, return word start - // to try again on a new line - if (finalWidth > 0) { - return wordStart; - } - } else if (this.wrapOption == WrapOption.WRAP) { - if (hyphProps.hyphenate == Hyphenate.TRUE) { - return this.doHyphenation(dataCopy, i, wordStart, - this.getContentWidth() - - (finalWidth - + spaceWidth - + pendingWidth)); - } else { - return wordStart; - } - } - } - - } - } // end of iteration over text - - - if (prev == TEXT) { - - if (spaceWidth > 0) { - InlineSpace pis = new InlineSpace(spaceWidth); - // Make sure that this space doesn't occur as - // first thing in the next line - pis.setEatable(true); - if (prevUlState) { - pis.setUnderlined(textState.getUnderlined()); - } - if (prevOlState) { - pis.setOverlined(textState.getOverlined()); - } - if (prevLTState) { - pis.setLineThrough(textState.getLineThrough()); - } - pendingAreas.addElement(pis); - pendingWidth += spaceWidth; - spaceWidth = 0; - } - - addSpacedWord(new String(data, wordStart, wordLength), ls, - finalWidth + spaceWidth + embeddedLinkStart, - spaceWidth, textState, true); - - embeddedLinkStart += wordWidth; - wordWidth = 0; - } - - if (overrun) - MessageHandler.error(">"); - return -1; - } - - /** - * adds a Leader; actually the method receives the leader properties - * and creates a leader area or an inline area which is appended to - * the children of the containing line area.
- * leader pattern use-content is not implemented. - */ - public void addLeader(int leaderPattern, int leaderLengthMinimum, - int leaderLengthOptimum, int leaderLengthMaximum, - int ruleStyle, int ruleThickness, - int leaderPatternWidth, int leaderAlignment) { - WordArea leaderPatternArea; - int leaderLength = 0; - char dotIndex = '.'; // currentFontState.mapChar('.'); - int dotWidth = - currentFontState.width(currentFontState.mapChar(dotIndex)); - char whitespaceIndex = ' '; // currentFontState.mapChar(' '); - int whitespaceWidth = - currentFontState.width(currentFontState.mapChar(whitespaceIndex)); - - int remainingWidth = this.getContentWidth() - - this.getCurrentXPosition(); - - /** - * checks whether leaderLenghtOptimum fits into rest of line; - * should never overflow, as it has been checked already in BlockArea - * first check: use remaining width if it smaller than optimum oder maximum - */ - if ((remainingWidth <= leaderLengthOptimum) - || (remainingWidth <= leaderLengthMaximum)) { - leaderLength = remainingWidth; - } else if ((remainingWidth > leaderLengthOptimum) - && (remainingWidth > leaderLengthMaximum)) { - leaderLength = leaderLengthMaximum; - } else if ((leaderLengthOptimum > leaderLengthMaximum) - && (leaderLengthOptimum < remainingWidth)) { - leaderLength = leaderLengthOptimum; - } - - // stop if leader-length is too small - if (leaderLength <= 0) { - return; - } - - switch (leaderPattern) { - case LeaderPattern.SPACE: - InlineSpace spaceArea = new InlineSpace(leaderLength); - pendingAreas.addElement(spaceArea); - break; - case LeaderPattern.RULE: - LeaderArea leaderArea = new LeaderArea(fontState, red, green, - blue, "", leaderLength, - leaderPattern, - ruleThickness, ruleStyle); - leaderArea.setYOffset(placementOffset); - pendingAreas.addElement(leaderArea); - break; - case LeaderPattern.DOTS: - // if the width of a dot is larger than leader-pattern-width - // ignore this property - if (leaderPatternWidth < dotWidth) { - leaderPatternWidth = 0; - } - // if value of leader-pattern-width is 'use-font-metrics' (0) - if (leaderPatternWidth == 0) { - pendingAreas.addElement(this.buildSimpleLeader(dotIndex, - leaderLength)); - } else { - // if leader-alignment is used, calculate space to insert before leader - // so that all dots will be parallel. - if (leaderAlignment == LeaderAlignment.REFERENCE_AREA) { - int spaceBeforeLeader = - this.getLeaderAlignIndent(leaderLength, - leaderPatternWidth); - // appending indent space leader-alignment - // setting InlineSpace to false, so it is not used in line justification - if (spaceBeforeLeader != 0) { - pendingAreas.addElement(new InlineSpace(spaceBeforeLeader, - false)); - pendingWidth += spaceBeforeLeader; - // shorten leaderLength, otherwise - in case of - // leaderLength=remaining length - it will cut off the end of - // leaderlength - leaderLength -= spaceBeforeLeader; - } - } - - // calculate the space to insert between the dots and create a - // inline area with this width - InlineSpace spaceBetweenDots = - new InlineSpace(leaderPatternWidth - dotWidth, false); - - leaderPatternArea = new WordArea(currentFontState, this.red, - this.green, this.blue, - new String("."), dotWidth); - leaderPatternArea.setYOffset(placementOffset); - int dotsFactor = - (int)Math.floor(((double)leaderLength) - / ((double)leaderPatternWidth)); - - // add combination of dot + space to fill leader - // is there a way to do this in a more effective way? - for (int i = 0; i < dotsFactor; i++) { - pendingAreas.addElement(leaderPatternArea); - pendingAreas.addElement(spaceBetweenDots); - } - // append at the end some space to fill up to leader length - pendingAreas.addElement(new InlineSpace(leaderLength - - dotsFactor - * leaderPatternWidth)); - } - break; - // leader pattern use-content not implemented. - case LeaderPattern.USECONTENT: - MessageHandler.errorln("leader-pattern=\"use-content\" not " - + "supported by this version of Fop"); - return; - } - // adds leader length to length of pending inline areas - pendingWidth += leaderLength; - // sets prev to TEXT and makes so sure, that also blocks only - // containing leaders are processed - prev = TEXT; - } - - /** - * adds pending inline areas to the line area - * normally done, when the line area is filled and - * added as child to the parent block area - */ - public void addPending() { - if (spaceWidth > 0) { - addChild(new InlineSpace(spaceWidth)); - finalWidth += spaceWidth; - spaceWidth = 0; - } - - Enumeration e = pendingAreas.elements(); - while (e.hasMoreElements()) { - Box box = (Box)e.nextElement(); - addChild(box); - } - - finalWidth += pendingWidth; - - // reset pending areas array - pendingWidth = 0; - pendingAreas = new Vector(); - } - - /** - * aligns line area - * - */ - public void align(int type) { - int padding = 0; - - switch (type) { - case TextAlign.START: // left - padding = this.getContentWidth() - finalWidth; - endIndent += padding; - break; - case TextAlign.END: // right - padding = this.getContentWidth() - finalWidth; - startIndent += padding; - break; - case TextAlign.CENTER: // center - padding = (this.getContentWidth() - finalWidth) / 2; - startIndent += padding; - endIndent += padding; - break; - case TextAlign.JUSTIFY: // justify - // first pass - count the spaces - int spaceCount = 0; - Enumeration e = children.elements(); - while (e.hasMoreElements()) { - Box b = (Box)e.nextElement(); - if (b instanceof InlineSpace) { - InlineSpace space = (InlineSpace)b; - if (space.getResizeable()) { - spaceCount++; - } - } - } - if (spaceCount > 0) { - padding = (this.getContentWidth() - finalWidth) / spaceCount; - } else { // no spaces - padding = 0; - } - // second pass - add additional space - spaceCount = 0; - e = children.elements(); - while (e.hasMoreElements()) { - Box b = (Box)e.nextElement(); - if (b instanceof InlineSpace) { - InlineSpace space = (InlineSpace)b; - if (space.getResizeable()) { - space.setSize(space.getSize() + padding); - spaceCount++; - } - } else if (b instanceof InlineArea) { - ((InlineArea)b).setXOffset(spaceCount * padding); - } - - } - } - } - - /** - * Balance (vertically) the inline areas within this line. - */ - public void verticalAlign() { - int superHeight = -this.placementOffset; - int maxHeight = this.allocationHeight; - Enumeration e = children.elements(); - while (e.hasMoreElements()) { - Box b = (Box)e.nextElement(); - if (b instanceof InlineArea) { - InlineArea ia = (InlineArea)b; - if (ia instanceof WordArea) { - ia.setYOffset(placementOffset); - } - if (ia.getHeight() > maxHeight) { - maxHeight = ia.getHeight(); - } - int vert = ia.getVerticalAlign(); - if (vert == VerticalAlign.SUPER) { - int fh = fontState.getAscender(); - ia.setYOffset((int)(placementOffset - (2 * fh / 3.0))); - } else if (vert == VerticalAlign.SUB) { - int fh = fontState.getAscender(); - ia.setYOffset((int)(placementOffset + (2 * fh / 3.0))); - } - } else {} - } - // adjust the height of this line to the - // resulting alignment height. - this.allocationHeight = maxHeight; - } - - public void changeColor(float red, float green, float blue) { - this.red = red; - this.green = green; - this.blue = blue; - } - - public void changeFont(FontState fontState) { - this.currentFontState = fontState; - } - - public void changeWhiteSpaceCollapse(int whiteSpaceCollapse) { - this.whiteSpaceCollapse = whiteSpaceCollapse; - } - - public void changeWrapOption(int wrapOption) { - this.wrapOption = wrapOption; - } - - public void changeVerticalAlign(int vAlign) { - this.vAlign = vAlign; - } - - public int getEndIndent() { - return endIndent; - } - - public int getHeight() { - return this.allocationHeight; - } - - public int getPlacementOffset() { - return this.placementOffset; - } - - public int getStartIndent() { - return startIndent; - } - - public boolean isEmpty() { - return !(pendingAreas.size() > 0 || children.size() > 0); - // return (prev == NOTHING); - } - - public Vector getPendingAreas() { - return pendingAreas; - } - - public int getPendingWidth() { - return pendingWidth; - } - - public void setPendingAreas(Vector areas) { - pendingAreas = areas; - } - - public void setPendingWidth(int width) { - pendingWidth = width; - } - - /** - * sets hyphenation related traits: language, country, hyphenate, hyphenation-character - * and minimum number of character to remain one the previous line and to be on the - * next line. - */ - public void changeHyphenation(HyphenationProps hyphProps) { - this.hyphProps = hyphProps; - } - - - /** - * creates a leader as String out of the given char and the leader length - * and wraps it in an InlineArea which is returned - */ - private InlineArea buildSimpleLeader(char c, int leaderLength) { - int width = this.currentFontState.width(currentFontState.mapChar(c)); - if (width == 0) { - MessageHandler.errorln("char " + c - + " has width 0. Using width 100 instead."); - width = 100; - } - int factor = (int)Math.floor(leaderLength / width); - char[] leaderChars = new char[factor]; - for (int i = 0; i < factor; i++) { - leaderChars[i] = c; // currentFontState.mapChar(c); - } - WordArea leaderPatternArea = new WordArea(currentFontState, this.red, - this.green, this.blue, - new String(leaderChars), - leaderLength); - leaderPatternArea.setYOffset(placementOffset); - return leaderPatternArea; - } - - /** - * calculates the width of space which has to be inserted before the - * start of the leader, so that all leader characters are aligned. - * is used if property leader-align is set. At the moment only the value - * for leader-align="reference-area" is supported. - * - */ - private int getLeaderAlignIndent(int leaderLength, - int leaderPatternWidth) { - // calculate position of used space in line area - double position = getCurrentXPosition(); - // calculate factor of next leader pattern cycle - double nextRepeatedLeaderPatternCycle = Math.ceil(position - / leaderPatternWidth); - // calculate difference between start of next leader - // pattern cycle and already used space - double difference = - (leaderPatternWidth * nextRepeatedLeaderPatternCycle) - position; - return (int)difference; - } - - /** - * calculates the used space in this line area - */ - private int getCurrentXPosition() { - return finalWidth + spaceWidth + startIndent + pendingWidth; - } - - /** - * extracts a complete word from the character data - */ - private String getHyphenationWord(char[] characters, int wordStart) { - boolean wordendFound = false; - int counter = 0; - char[] newWord = new char[100]; // create a buffer - while ((!wordendFound) - && ((wordStart + counter) < characters.length)) { - char tk = characters[wordStart + counter]; - if (Character.isLetter(tk)) { - newWord[counter] = tk; - counter++; - } else { - wordendFound = true; - } - } - return new String(newWord, 0, counter); - } - - - /** - * extracts word for hyphenation and calls hyphenation package, - * handles cases of inword punctuation and quotation marks at the beginning - * of words, but not in a internationalized way - */ - public int doHyphenation(char[] characters, int position, int wordStart, - int remainingWidth) { - // check whether the language property has been set - if (this.hyphProps.language.equalsIgnoreCase("none")) { - MessageHandler.errorln("if property 'hyphenate' is used, a language must be specified"); - return wordStart; - } - - /** - * remaining part string of hyphenation - */ - StringBuffer remainingString = new StringBuffer(); - - /** - * for words with some inword punctuation like / or - - */ - StringBuffer preString = null; - - /** - * char before the word, probably whitespace - */ - char startChar = ' '; // characters[wordStart-1]; - - /** - * in word punctuation character - */ - char inwordPunctuation; - - /** - * the complete word handed to the hyphenator - */ - String wordToHyphenate; - - // width of hyphenation character - int hyphCharWidth = - this.currentFontState.width(currentFontState.mapChar(this.hyphProps.hyphenationChar)); - remainingWidth -= hyphCharWidth; - - // handles ' or " at the beginning of the word - if (characters[wordStart] == '"' || characters[wordStart] == '\'') { - remainingString.append(characters[wordStart]); - // extracts whole word from string - wordToHyphenate = getHyphenationWord(characters, wordStart + 1); - } else { - wordToHyphenate = getHyphenationWord(characters, wordStart); - } - - // if the extracted word is smaller than the remaining width - // we have a non letter character inside the word. at the moment - // we will only handle hard hyphens and slashes - if (getWordWidth(wordToHyphenate) < remainingWidth) { - inwordPunctuation = - characters[wordStart + wordToHyphenate.length()]; - if (inwordPunctuation == '-' || inwordPunctuation == '/') { - preString = new StringBuffer(wordToHyphenate); - preString = preString.append(inwordPunctuation); - wordToHyphenate = - getHyphenationWord(characters, - wordStart + wordToHyphenate.length() - + 1); - remainingWidth -= - (getWordWidth(wordToHyphenate) - + this.currentFontState.width(currentFontState.mapChar(inwordPunctuation))); - } - } - - // are there any hyphenation points - Hyphenation hyph = - Hyphenator.hyphenate(hyphProps.language, hyphProps.country, - wordToHyphenate, - hyphProps.hyphenationRemainCharacterCount, - hyphProps.hyphenationPushCharacterCount); - // no hyphenation points and no inword non letter character - if (hyph == null && preString == null) { - if (remainingString.length() > 0) { - return wordStart - 1; - } else { - return wordStart; - } - - // no hyphenation points, but a inword non-letter character - } else if (hyph == null && preString != null) { - remainingString.append(preString); - // is.addMapWord(startChar,remainingString); - this.addWord(startChar, remainingString); - return wordStart + remainingString.length(); - // hyphenation points and no inword non-letter character - } else if (hyph != null && preString == null) { - int index = getFinalHyphenationPoint(hyph, remainingWidth); - if (index != -1) { - remainingString.append(hyph.getPreHyphenText(index)); - remainingString.append(this.hyphProps.hyphenationChar); - // is.addMapWord(startChar,remainingString); - this.addWord(startChar, remainingString); - return wordStart + remainingString.length() - 1; - } - // hyphenation points and a inword non letter character - } else if (hyph != null && preString != null) { - int index = getFinalHyphenationPoint(hyph, remainingWidth); - if (index != -1) { - remainingString.append(preString.append(hyph.getPreHyphenText(index))); - remainingString.append(this.hyphProps.hyphenationChar); - // is.addMapWord(startChar,remainingString); - this.addWord(startChar, remainingString); - return wordStart + remainingString.length() - 1; - } else { - remainingString.append(preString); - // is.addMapWord(startChar,remainingString); - this.addWord(startChar, remainingString); - return wordStart + remainingString.length(); - } - } - return wordStart; - } - - - /** - * Calculates the wordWidth using the actual fontstate - */ - private int getWordWidth(String word) { - if (word == null) - return 0; - int wordLength = word.length(); - int width = 0; - char[] characters = new char[wordLength]; - word.getChars(0, wordLength, characters, 0); - - for (int i = 0; i < wordLength; i++) { - width += getCharWidth(characters[i]); - } - return width; - } - - public int getRemainingWidth() { - return this.getContentWidth() - this.getCurrentXPosition(); - } - - public void setLinkSet(LinkSet ls) {} - - public void addInlineArea(Area box) { - addPending(); - addChild(box); - prev = TEXT; - finalWidth += box.getContentWidth(); - } - - public void addInlineSpace(InlineSpace is, int spaceWidth) { - addChild(is); - finalWidth += spaceWidth; - // spaceWidth = 0; - } - - /** - * adds a single character to the line area tree - */ - public int addCharacter(char data, LinkSet ls, boolean ul) { - WordArea ia = null; - int remainingWidth = this.getContentWidth() - - this.getCurrentXPosition(); - int width = - this.currentFontState.width(currentFontState.mapChar(data)); - // if it doesn't fit, return - if (width > remainingWidth) { - return org.apache.fop.fo.flow.Character.DOESNOT_FIT; - } else { - // if whitespace-collapse == true, discard character - if (Character.isSpaceChar(data) - && whiteSpaceCollapse == WhiteSpaceCollapse.TRUE) { - return org.apache.fop.fo.flow.Character.OK; - } - // create new InlineArea - ia = new WordArea(currentFontState, this.red, this.green, - this.blue, new Character(data).toString(), - width); - ia.setYOffset(placementOffset); - ia.setUnderlined(ul); - pendingAreas.addElement(ia); - if (Character.isSpaceChar(data)) { - this.spaceWidth = +width; - prev = LineArea.WHITESPACE; - } else { - pendingWidth += width; - prev = LineArea.TEXT; - } - return org.apache.fop.fo.flow.Character.OK; - } - } - - - /** - * Same as addWord except that characters in wordBuf is mapped - * to the current fontstate's encoding - */ - private void addMapWord(char startChar, StringBuffer wordBuf) { - StringBuffer mapBuf = new StringBuffer(wordBuf.length()); - for (int i = 0; i < wordBuf.length(); i++) { - mapBuf.append(currentFontState.mapChar(wordBuf.charAt(i))); - } - - addWord(startChar, mapBuf); - } - - /** - * adds a InlineArea containing the String startChar+wordBuf to the line area children. - */ - private void addWord(char startChar, StringBuffer wordBuf) { - String word = (wordBuf != null) ? wordBuf.toString() : ""; - WordArea hia; - int startCharWidth = getCharWidth(startChar); - - if (isAnySpace(startChar)) { - this.addChild(new InlineSpace(startCharWidth)); - } else { - hia = new WordArea(currentFontState, this.red, this.green, - this.blue, - new Character(startChar).toString(), 1); - hia.setYOffset(placementOffset); - this.addChild(hia); - } - int wordWidth = this.getWordWidth(word); - hia = new WordArea(currentFontState, this.red, this.green, this.blue, - word, word.length()); - hia.setYOffset(placementOffset); - this.addChild(hia); - - // calculate the space needed - finalWidth += startCharWidth + wordWidth; - } - - - /** - * extracts from a hyphenated word the best (most greedy) fit - */ - private int getFinalHyphenationPoint(Hyphenation hyph, - int remainingWidth) { - int[] hyphenationPoints = hyph.getHyphenationPoints(); - int numberOfHyphenationPoints = hyphenationPoints.length; - - int index = -1; - String wordBegin = ""; - int wordBeginWidth = 0; - - for (int i = 0; i < numberOfHyphenationPoints; i++) { - wordBegin = hyph.getPreHyphenText(i); - if (this.getWordWidth(wordBegin) > remainingWidth) { - break; - } - index = i; - } - return index; - } - - /** - * Checks if it's legal to break a word in the middle - * based on the current language property. - * @return true if legal to break word in the middle - */ - private boolean canBreakMidWord() { - boolean ret = false; - if (hyphProps != null && hyphProps.language != null - &&!hyphProps.language.equals("NONE")) { - String lang = hyphProps.language.toLowerCase(); - if ("zh".equals(lang) || "ja".equals(lang) || "ko".equals(lang) - || "vi".equals(lang)) - ret = true; - } - return ret; - } - - /** - * Helper method for getting the width of a unicode char - * from the current fontstate. - * This also performs some guessing on widths on various - * versions of space that might not exists in the font. - */ - private int getCharWidth(char c) { - int width = currentFontState.width(currentFontState.mapChar(c)); - if (width <= 0) { - // Estimate the width of spaces not represented in - // the font - int em = currentFontState.width(currentFontState.mapChar('m')); - int en = currentFontState.width(currentFontState.mapChar('n')); - if (em <= 0) - em = 500 * currentFontState.getFontSize(); - if (en <= 0) - en = em - 10; - - if (c == ' ') - width = em; - if (c == '\u2000') - width = en; - if (c == '\u2001') - width = em; - if (c == '\u2002') - width = em / 2; - if (c == '\u2003') - width = currentFontState.getFontSize(); - if (c == '\u2004') - width = em / 3; - if (c == '\u2005') - width = em / 4; - if (c == '\u2006') - width = em / 6; - if (c == '\u2007') - width = getCharWidth(' '); - if (c == '\u2008') - width = getCharWidth('.'); - if (c == '\u2009') - width = em / 5; - if (c == '\u200A') - width = 5; - if (c == '\u200B') - width = 100; - if (c == '\u00A0') - width = getCharWidth(' '); - if (c == '\u202F') - width = getCharWidth(' ') / 2; - if (c == '\u3000') - width = getCharWidth(' ') * 2; - if ((c == '\n') || (c == '\r') || (c == '\t')) - width = getCharWidth(' '); - } - - return width; - } - - - /** - * Helper method to determine if the character is a - * space with normal behaviour. Normal behaviour means that - * it's not non-breaking - */ - private boolean isSpace(char c) { - if (c == ' ' || c == '\u2000' || // en quad - c == '\u2001' || // em quad - c == '\u2002' || // en space - c == '\u2003' || // em space - c == '\u2004' || // three-per-em space - c == '\u2005' || // four--per-em space - c == '\u2006' || // six-per-em space - c == '\u2007' || // figure space - c == '\u2008' || // punctuation space - c == '\u2009' || // thin space - c == '\u200A' || // hair space - c == '\u200B') // zero width space - return true; - else - return false; - } - - - /** - * Method to determine if the character is a nonbreaking - * space. - */ - private boolean isNBSP(char c) { - if (c == '\u00A0' || c == '\u202F' || // narrow no-break space - c == '\u3000' || // ideographic space - c == '\uFEFF') { // zero width no-break space - return true; - } else - return false; - } - - /** - * @return true if the character represents any kind of space - */ - private boolean isAnySpace(char c) { - boolean ret = (isSpace(c) || isNBSP(c)); - return ret; - } - - /** - * Add a word that might contain non-breaking spaces. - * Split the word into WordArea and InlineSpace and add it. - * If addToPending is true, add to pending areas. - */ - private void addSpacedWord(String word, LinkSet ls, int startw, - int spacew, TextState textState, - boolean addToPending) { - StringTokenizer st = new StringTokenizer(word, "\u00A0\u202F\u3000\uFEFF", true); - int extraw = 0; - while (st.hasMoreTokens()) { - String currentWord = st.nextToken(); - - if (currentWord.length() == 1 - && (isNBSP(currentWord.charAt(0)))) { - // Add an InlineSpace - int spaceWidth = getCharWidth(currentWord.charAt(0)); - if (spaceWidth > 0) { - InlineSpace is = new InlineSpace(spaceWidth); - extraw += spaceWidth; - if (prevUlState) { - is.setUnderlined(textState.getUnderlined()); - } - if (prevOlState) { - is.setOverlined(textState.getOverlined()); - } - if (prevLTState) { - is.setLineThrough(textState.getLineThrough()); - } - - if (addToPending) { - pendingAreas.addElement(is); - pendingWidth += spaceWidth; - } else { - addChild(is); - } - } - } else { - WordArea ia = new WordArea(currentFontState, this.red, - this.green, this.blue, - currentWord, - getWordWidth(currentWord)); - ia.setYOffset(placementOffset); - ia.setUnderlined(textState.getUnderlined()); - prevUlState = textState.getUnderlined(); - ia.setOverlined(textState.getOverlined()); - prevOlState = textState.getOverlined(); - ia.setLineThrough(textState.getLineThrough()); - prevLTState = textState.getLineThrough(); - ia.setVerticalAlign(vAlign); - - if (addToPending) { - pendingAreas.addElement(ia); - pendingWidth += getWordWidth(currentWord); - } else { - addChild(ia); - } - if (ls != null) { - Rectangle lr = new Rectangle(startw + extraw, spacew, - ia.getContentWidth(), - fontState.getFontSize()); - ls.addRect(lr, this, ia); - } - } - } - } - -} - diff --git a/src/org/apache/fop/layout/LinkSet.java b/src/org/apache/fop/layout/LinkSet.java deleted file mode 100644 index 30d58ca8d..000000000 --- a/src/org/apache/fop/layout/LinkSet.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// Java -import java.util.Vector; -import java.util.Enumeration; -import java.awt.Rectangle; - -import org.apache.fop.layout.inline.InlineArea; - -import org.apache.fop.fo.properties.WrapOption; // for enumerated -// values -// import org.apache.fop.fo.properties.WhiteSpaceCollapse; // for -// enumerated values -import org.apache.fop.fo.properties.TextAlign; // for enumerated -// values -import org.apache.fop.fo.properties.TextAlignLast; // for enumerated -// values - -/** - * a set of rectangles on a page that are linked to a common - * destination - */ -public class LinkSet { - - /** - * the destination of the links - */ - String destination; - - /** - * the set of rectangles - */ - Vector rects = new Vector(); - - private int xoffset = 0; - private int yoffset = 0; - - /* the maximum Y offset value encountered for this LinkSet */ - private int maxY = 0; - - protected int startIndent; - protected int endIndent; - - private int linkType; - - private Area area; - - public final static int INTERNAL = 0, // represents internal link - EXTERNAL = 1; // represents external link - - // property required for alignment adjustments - int contentRectangleWidth = 0; - - public LinkSet(String destination, Area area, int linkType) { - this.destination = destination; - this.area = area; - this.linkType = linkType; - } - - public void addRect(Rectangle r, LineArea lineArea, - InlineArea inlineArea) { - LinkedRectangle linkedRectangle = new LinkedRectangle(r, lineArea, - inlineArea); - linkedRectangle.setY(this.yoffset); - if (this.yoffset > maxY) { - maxY = this.yoffset; - } - rects.addElement(linkedRectangle); - } - - public void setYOffset(int y) { - this.yoffset = y; - } - - public void setXOffset(int x) { - this.xoffset = x; - } - - public void setContentRectangleWidth(int contentRectangleWidth) { - this.contentRectangleWidth = contentRectangleWidth; - } - - public void applyAreaContainerOffsets(AreaContainer ac, Area area) { - int height = area.getAbsoluteHeight(); - BlockArea ba = (BlockArea)area; - Enumeration re = rects.elements(); - while (re.hasMoreElements()) { - LinkedRectangle r = (LinkedRectangle)re.nextElement(); - r.setX(r.getX() + ac.getXPosition() + area.getTableCellXOffset()); - r.setY(ac.getYPosition() - height + (maxY - r.getY()) - - ba.getHalfLeading()); - } - } - - // intermediate implementation for joining all sublinks on same line - public void mergeLinks() { - int numRects = rects.size(); - if (numRects == 1) - return; - - LinkedRectangle curRect = - new LinkedRectangle((LinkedRectangle)rects.elementAt(0)); - Vector nv = new Vector(); - - for (int ri = 1; ri < numRects; ri++) { - LinkedRectangle r = (LinkedRectangle)rects.elementAt(ri); - - // yes, I'm really happy with comparing refs... - if (r.getLineArea() == curRect.getLineArea()) { - curRect.setWidth(r.getX() + r.getWidth() - curRect.getX()); - } else { - nv.addElement(curRect); - curRect = new LinkedRectangle(r); - } - - if (ri == numRects - 1) - nv.addElement(curRect); - } - - rects = nv; - } - - public void align() { - Enumeration re = rects.elements(); - while (re.hasMoreElements()) { - LinkedRectangle r = (LinkedRectangle)re.nextElement(); - r.setX(r.getX() + r.getLineArea().getStartIndent() - + r.getInlineArea().getXOffset()); - } - } - - public String getDest() { - return this.destination; - } - - public Vector getRects() { - return this.rects; - } - - public int getEndIndent() { - return endIndent; - } - - public int getStartIndent() { - return startIndent; - } - - public Area getArea() { - return area; - } - - public int getLinkType() { - return linkType; - } - -} diff --git a/src/org/apache/fop/layout/LinkedRectangle.java b/src/org/apache/fop/layout/LinkedRectangle.java deleted file mode 100644 index cca659596..000000000 --- a/src/org/apache/fop/layout/LinkedRectangle.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// Java -import java.awt.Rectangle; - -import org.apache.fop.layout.inline.InlineArea; - -/** - * an object that stores a rectangle that is linked, and the LineArea - * that it is logically associated with - * @author Arved Sandstrom - * @author James Tauber - */ -public class LinkedRectangle { - - /** - * the linked Rectangle - */ - protected Rectangle link; - - /** - * the associated LineArea - */ - protected LineArea lineArea; - - /** - * the associated InlineArea - */ - protected InlineArea inlineArea; - - public LinkedRectangle(Rectangle link, LineArea lineArea, - InlineArea inlineArea) { - this.link = link; - this.lineArea = lineArea; - this.inlineArea = inlineArea; - } - - public LinkedRectangle(LinkedRectangle lr) { - this.link = new Rectangle(lr.getRectangle()); - this.lineArea = lr.getLineArea(); - this.inlineArea = lr.getInlineArea(); - } - - public void setRectangle(Rectangle link) { - this.link = link; - } - - public Rectangle getRectangle() { - return this.link; - } - - public LineArea getLineArea() { - return this.lineArea; - } - - public void setLineArea(LineArea lineArea) { - this.lineArea = lineArea; - } - - public InlineArea getInlineArea() { - return this.inlineArea; - } - - public void setLineArea(InlineArea inlineArea) { - this.inlineArea = inlineArea; - } - - public void setX(int x) { - this.link.x = x; - } - - public void setY(int y) { - this.link.y = y; - } - - public void setWidth(int width) { - this.link.width = width; - } - - public void setHeight(int height) { - this.link.height = height; - } - - public int getX() { - return this.link.x; - } - - public int getY() { - return this.link.y; - } - - public int getWidth() { - return this.link.width; - } - - public int getHeight() { - return this.link.height; - } - -} diff --git a/src/org/apache/fop/layout/MarginInlineProps.java b/src/org/apache/fop/layout/MarginInlineProps.java deleted file mode 100644 index 8dc6da07b..000000000 --- a/src/org/apache/fop/layout/MarginInlineProps.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class MarginInlineProps { - public int marginTop; - public int marginBottom; - public int marginLeft; - public int marginRight; - public int spaceBefore; - public int spaceAfter; - public int startIndent; - public int endIndent; - - public MarginInlineProps() {} - -} diff --git a/src/org/apache/fop/layout/MarginProps.java b/src/org/apache/fop/layout/MarginProps.java deleted file mode 100644 index 2d8bfcf32..000000000 --- a/src/org/apache/fop/layout/MarginProps.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class MarginProps { - public int marginTop; - public int marginBottom; - public int marginLeft; - public int marginRight; - public int spaceBefore; - public int spaceAfter; - public int startIndent; - public int endIndent; - - public MarginProps() {} - -} diff --git a/src/org/apache/fop/layout/Page.java b/src/org/apache/fop/layout/Page.java deleted file mode 100644 index f543c6a0b..000000000 --- a/src/org/apache/fop/layout/Page.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.render.Renderer; -import org.apache.fop.fo.flow.*; -import org.apache.fop.fo.*; -import org.apache.fop.apps.*; -import org.apache.fop.datatypes.IDReferences; -import org.apache.fop.fo.pagination.PageSequence; - -// Java -import java.util.Vector; -import java.util.Enumeration; - -/*Modified by Mark Lillywhite mark-fop@inomial.com. Added getIDReferences. - This is just a convenience method for renderers who no longer have access - to the AreaTree when rendering. - */ - -public class Page { - - private int height; - private int width; - - private BodyAreaContainer body; - private AreaContainer before; - private AreaContainer after; - private AreaContainer start; - private AreaContainer end; - - private AreaTree areaTree; - - private Vector rootExtensions; - - private PageSequence pageSequence; - - protected int pageNumber = 0; - protected String formattedPageNumber; - - protected Vector linkSets = new Vector(); - - private Vector idList = new Vector(); - - private Vector footnotes = null; - - private Vector markers = null; - - Page(AreaTree areaTree, int height, int width) { - this.areaTree = areaTree; - this.height = height; - this.width = width; - markers = new Vector(); - } - - public IDReferences getIDReferences() { - return areaTree.getIDReferences(); - } - - public void setPageSequence(PageSequence pageSequence) { - this.pageSequence = pageSequence; - } - - public PageSequence getPageSequence() { - return pageSequence; - } - - public AreaTree getAreaTree() { - return areaTree; - } - - public void setNumber(int number) { - this.pageNumber = number; - } - - public int getNumber() { - return this.pageNumber; - } - - public void setFormattedNumber(String number) { - this.formattedPageNumber = number; - } - - public String getFormattedNumber() { - return this.formattedPageNumber; - } - - void addAfter(AreaContainer area) { - this.after = area; - area.setPage(this); - } - - void addBefore(AreaContainer area) { - this.before = area; - area.setPage(this); - } - - /** - * Ensure that page is set not only on B.A.C. but also on the - * three top-level reference areas. - * @param area The region-body area container (special) - */ - public void addBody(BodyAreaContainer area) { - this.body = area; - area.setPage(this); - ((BodyAreaContainer)area).getMainReferenceArea().setPage(this); - ((BodyAreaContainer)area).getBeforeFloatReferenceArea().setPage(this); - ((BodyAreaContainer)area).getFootnoteReferenceArea().setPage(this); - } - - void addEnd(AreaContainer area) { - this.end = area; - area.setPage(this); - } - - void addStart(AreaContainer area) { - this.start = area; - area.setPage(this); - } - - public void render(Renderer renderer) { - renderer.renderPage(this); - } - - public AreaContainer getAfter() { - return this.after; - } - - public AreaContainer getBefore() { - return this.before; - } - - public AreaContainer getStart() { - return this.start; - } - - public AreaContainer getEnd() { - return this.end; - } - - public BodyAreaContainer getBody() { - return this.body; - } - - public int getHeight() { - return this.height; - } - - public int getWidth() { - return this.width; - } - - public FontInfo getFontInfo() { - return this.areaTree.getFontInfo(); - } - - public void addLinkSet(LinkSet linkSet) { - this.linkSets.addElement(linkSet); - } - - public Vector getLinkSets() { - return this.linkSets; - } - - public boolean hasLinks() { - return (!this.linkSets.isEmpty()); - } - - public void addToIDList(String id) { - idList.addElement(id); - } - - public Vector getIDList() { - return idList; - } - - public Vector getPendingFootnotes() { - return footnotes; - } - - public Vector getExtensions() { - return rootExtensions; - } - - public void setExtensions(Vector extensions) { - this.rootExtensions = extensions; - } - - public void setPendingFootnotes(Vector v) { - footnotes = v; - if (footnotes != null) { - for (Enumeration e = footnotes.elements(); - e.hasMoreElements(); ) { - FootnoteBody fb = (FootnoteBody)e.nextElement(); - if (!Footnote.layoutFootnote(this, fb, null)) { - // footnotes are too large to fit on empty page - } - - } - footnotes = null; - } - } - - public void addPendingFootnote(FootnoteBody fb) { - if (footnotes == null) { - footnotes = new Vector(); - } - footnotes.addElement(fb); - } - - public void registerMarker(Marker marker) { - markers.addElement(marker); - } - - public Vector getMarkers() { - return this.markers; - } - -} diff --git a/src/org/apache/fop/layout/PageMaster.java b/src/org/apache/fop/layout/PageMaster.java deleted file mode 100644 index 7034bf238..000000000 --- a/src/org/apache/fop/layout/PageMaster.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -public class PageMaster { - - private int width; - private int height; - - private BodyRegionArea body; - private RegionArea before; - private RegionArea after; - private RegionArea start; - private RegionArea end; - - public PageMaster(int pageWidth, int pageHeight) { - this.width = pageWidth; - this.height = pageHeight; - } - - public void addAfter(RegionArea region) { - this.after = region; - } - - public void addBefore(RegionArea region) { - this.before = region; - } - - public void addBody(BodyRegionArea region) { - this.body = region; - } - - public void addEnd(RegionArea region) { - this.end = region; - } - - public void addStart(RegionArea region) { - this.start = region; - } - - public int getHeight() { - return this.height; - } - - public int getWidth() { - return this.width; - } - - public Page makePage(AreaTree areaTree) { - Page p = new Page(areaTree, this.height, this.width); - if (this.body != null) { - p.addBody(body.makeBodyAreaContainer()); - } - if (this.before != null) { - p.addBefore(before.makeAreaContainer()); - } - if (this.after != null) { - p.addAfter(after.makeAreaContainer()); - } - if (this.start != null) { - p.addStart(start.makeAreaContainer()); - } - if (this.end != null) { - p.addEnd(end.makeAreaContainer()); - } - - return p; - } - -} diff --git a/src/org/apache/fop/layout/RegionArea.java b/src/org/apache/fop/layout/RegionArea.java deleted file mode 100644 index 7e7465448..000000000 --- a/src/org/apache/fop/layout/RegionArea.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.fo.properties.*; -import org.apache.fop.datatypes.ColorType; - -public class RegionArea { - - protected int xPosition; - protected int yPosition; - protected int width; - protected int height; - - protected ColorType backgroundColor; - - public RegionArea(int xPosition, int yPosition, int width, int height) { - this.xPosition = xPosition; - this.yPosition = yPosition; - this.width = width; - this.height = height; - } - - public AreaContainer makeAreaContainer() { - return new AreaContainer(null, xPosition, yPosition, width, height, - Position.ABSOLUTE); - } - - public ColorType getBackgroundColor() { - return this.backgroundColor; - } - - public void setBackgroundColor(ColorType bgColor) { - this.backgroundColor = bgColor; - } - - public int getHeight() { - return height; - } - -} diff --git a/src/org/apache/fop/layout/RelativePositionProps.java b/src/org/apache/fop/layout/RelativePositionProps.java deleted file mode 100644 index 4b0f2c1a5..000000000 --- a/src/org/apache/fop/layout/RelativePositionProps.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -/** - * Store all hyphenation related properties on an FO. - * Public "structure" allows direct member access. - */ -public class RelativePositionProps { - public int marginTop; - public int marginBottom; - public int marginLeft; - public int marginRight; - public int spaceBefore; - public int spaceAfter; - public int startIndent; - public int endIndent; - - public RelativePositionProps() {} - -} diff --git a/src/org/apache/fop/layout/Space.java b/src/org/apache/fop/layout/Space.java deleted file mode 100644 index d49b4be4a..000000000 --- a/src/org/apache/fop/layout/Space.java +++ /dev/null @@ -1,10 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -abstract public class Space extends Box {} diff --git a/src/org/apache/fop/layout/SpanArea.java b/src/org/apache/fop/layout/SpanArea.java deleted file mode 100644 index 6ba58db1b..000000000 --- a/src/org/apache/fop/layout/SpanArea.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -// FOP -import org.apache.fop.render.Renderer; -import org.apache.fop.fo.properties.Position; -import org.apache.fop.datatypes.IDReferences; - -// Java -import java.util.Vector; -import java.util.Enumeration; - -public class SpanArea extends AreaContainer { - - private int columnCount; - private int currentColumn = 1; - private int columnGap = 0; - - // has the area been balanced? - private boolean isBalanced = false; - - public SpanArea(FontState fontState, int xPosition, int yPosition, - int allocationWidth, int maxHeight, int columnCount, - int columnGap) { - super(fontState, xPosition, yPosition, allocationWidth, maxHeight, - Position.ABSOLUTE); - - this.contentRectangleWidth = allocationWidth; - this.columnCount = columnCount; - this.columnGap = columnGap; - - int columnWidth = (allocationWidth - columnGap * (columnCount - 1)) - / columnCount; - for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) { - int colXPosition = (xPosition - + columnIndex * (columnWidth + columnGap)); - int colYPosition = yPosition; - ColumnArea colArea = new ColumnArea(fontState, colXPosition, - colYPosition, columnWidth, - maxHeight, columnCount); - addChild(colArea); - colArea.setColumnIndex(columnIndex + 1); - } - } - - public void render(Renderer renderer) { - renderer.renderSpanArea(this); - } - - public void end() {} - - public void start() {} - - public int spaceLeft() { - return maxHeight - currentHeight; - } - - public int getColumnCount() { - return columnCount; - } - - public int getCurrentColumn() { - return currentColumn; - } - - public void setCurrentColumn(int currentColumn) { - if (currentColumn <= columnCount) - this.currentColumn = currentColumn; - else - this.currentColumn = columnCount; - } - - public AreaContainer getCurrentColumnArea() { - return (AreaContainer)getChildren().elementAt(currentColumn - 1); - } - - public boolean isBalanced() { - return isBalanced; - } - - public void setIsBalanced() { - this.isBalanced = true; - } - - public int getTotalContentHeight() { - int totalContentHeight = 0; - for (Enumeration e = getChildren().elements(); - e.hasMoreElements(); ) { - totalContentHeight += - ((AreaContainer)e.nextElement()).getContentHeight(); - } - return totalContentHeight; - } - - public int getMaxContentHeight() { - int maxContentHeight = 0; - for (Enumeration e = getChildren().elements(); - e.hasMoreElements(); ) { - AreaContainer nextElm = (AreaContainer)e.nextElement(); - if (nextElm.getContentHeight() > maxContentHeight) - maxContentHeight = nextElm.getContentHeight(); - } - return maxContentHeight; - } - - public void setPage(Page page) { - this.page = page; - for (Enumeration e = getChildren().elements(); - e.hasMoreElements(); ) { - ((AreaContainer)e.nextElement()).setPage(page); - } - } - - public boolean isLastColumn() { - return (currentColumn == columnCount); - } - -} diff --git a/src/org/apache/fop/layout/TextState.java b/src/org/apache/fop/layout/TextState.java deleted file mode 100644 index 3774facf0..000000000 --- a/src/org/apache/fop/layout/TextState.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout; - -import org.apache.fop.apps.FOPException; - -/** - * This class holds information about text-decoration - * - */ -public class TextState { - - protected boolean underlined; - protected boolean overlined; - protected boolean linethrough; - - public TextState() throws FOPException {} - - /** - * @return true if text should be underlined - */ - public boolean getUnderlined() { - return underlined; - } - - /** - * set text as underlined - */ - public void setUnderlined(boolean ul) { - this.underlined = ul; - } - - /** - * @return true if text should be overlined - */ - public boolean getOverlined() { - return overlined; - } - - public void setOverlined(boolean ol) { - this.overlined = ol; - } - - public boolean getLineThrough() { - return linethrough; - } - - public void setLineThrough(boolean lt) { - this.linethrough = lt; - } - -} diff --git a/src/org/apache/fop/layout/hyphenation/ByteVector.java b/src/org/apache/fop/layout/hyphenation/ByteVector.java deleted file mode 100644 index 66ce5fa9b..000000000 --- a/src/org/apache/fop/layout/hyphenation/ByteVector.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.io.Serializable; - -/** - * This class implements a simple byte vector with access to the - * underlying array. - * - * @author Carlos Villegas - */ -public class ByteVector implements Serializable { - - /** - * Capacity increment size - */ - private final static int DEFAULT_BLOCK_SIZE = 2048; - private int BLOCK_SIZE; - - /** - * 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) - BLOCK_SIZE = capacity; - else - BLOCK_SIZE = DEFAULT_BLOCK_SIZE; - array = new byte[BLOCK_SIZE]; - n = 0; - } - - public ByteVector(byte[] a) { - BLOCK_SIZE = DEFAULT_BLOCK_SIZE; - array = a; - n = 0; - } - - public ByteVector(byte[] a, int capacity) { - if (capacity > 0) - BLOCK_SIZE = capacity; - else - BLOCK_SIZE = 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 + BLOCK_SIZE]; - 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/org/apache/fop/layout/hyphenation/CharVector.java b/src/org/apache/fop/layout/hyphenation/CharVector.java deleted file mode 100644 index e2993a0b6..000000000 --- a/src/org/apache/fop/layout/hyphenation/CharVector.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.io.Serializable; - -/** - * This class implements a simple char vector with access to the - * underlying array. - * - * @author Carlos Villegas - */ -public class CharVector implements Cloneable, Serializable { - - /** - * Capacity increment size - */ - private final static int DEFAULT_BLOCK_SIZE = 2048; - private int BLOCK_SIZE; - - /** - * 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) - BLOCK_SIZE = capacity; - else - BLOCK_SIZE = DEFAULT_BLOCK_SIZE; - array = new char[BLOCK_SIZE]; - n = 0; - } - - public CharVector(char[] a) { - BLOCK_SIZE = DEFAULT_BLOCK_SIZE; - array = a; - n = a.length; - } - - public CharVector(char[] a, int capacity) { - if (capacity > 0) - BLOCK_SIZE = capacity; - else - BLOCK_SIZE = 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(), BLOCK_SIZE); - 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 + BLOCK_SIZE]; - 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/org/apache/fop/layout/hyphenation/Hyphen.java b/src/org/apache/fop/layout/hyphenation/Hyphen.java deleted file mode 100644 index d93c3dd85..000000000 --- a/src/org/apache/fop/layout/hyphenation/Hyphen.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.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 - */ - -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/org/apache/fop/layout/hyphenation/Hyphenation.java b/src/org/apache/fop/layout/hyphenation/Hyphenation.java deleted file mode 100644 index 016091a4c..000000000 --- a/src/org/apache/fop/layout/hyphenation/Hyphenation.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.util.Vector; - -/** - * This class represents a hyphenated word. - * - * @author Carlos Villegas - */ -public class Hyphenation { - int[] hyphenPoints; - String word; - - /** - * number of hyphenation points in word - */ - 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/org/apache/fop/layout/hyphenation/HyphenationException.java b/src/org/apache/fop/layout/hyphenation/HyphenationException.java deleted file mode 100644 index 442673512..000000000 --- a/src/org/apache/fop/layout/hyphenation/HyphenationException.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -/** - * @author Carlos Villegas - */ -public class HyphenationException extends Exception { - - public HyphenationException(String msg) { - super(msg); - } - -} diff --git a/src/org/apache/fop/layout/hyphenation/HyphenationTree.java b/src/org/apache/fop/layout/hyphenation/HyphenationTree.java deleted file mode 100644 index d2c0f16bf..000000000 --- a/src/org/apache/fop/layout/hyphenation/HyphenationTree.java +++ /dev/null @@ -1,495 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.io.*; -import java.util.Vector; -import java.util.Hashtable; - -/** - * 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 - */ -public class HyphenationTree extends TernaryTree implements PatternConsumer, - Serializable { - - /** - * value space: stores the inteletter values - */ - protected ByteVector vspace; - - /** - * This map stores hyphenation exceptions - */ - protected Hashtable 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 Hashtable(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(); - } - - /** - * Read hyphenation patterns from an XML file. - */ - public void loadPatterns(String filename) throws HyphenationException { - PatternParser pp = new PatternParser(this); - ivalues = new TernaryTree(); - - pp.parse(filename); - - // 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; - } - - /** - *

Search for all possible partial matches of word starting - * at index an update interletter values. In other words, it - * does something like:

- * - * for(i=0; i - *

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

- * @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); - } - - /** - * 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]; - 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, abort - return null; - } - word[i] = (char)nc; - } - 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) - Vector hw = (Vector)stoplist.get(sw); - int j = 0; - for (i = 0; i < hw.size(); i++) { - Object o = hw.elementAt(i); - if (o instanceof String) { - j += ((String)o).length(); - if (j >= remainCharCount && j < (len - pushCharCount)) - result[k++] = j; - } - } - } 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 - for (i = 0; i < len; i++) { - if (((il[i + 1] & 1) == 1) && i >= remainCharCount - && i < (len - pushCharCount)) { - result[k++] = i; - } - } - } - - - 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 PatternParser PatternParser} 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 PatternParser PatternParser} 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, Vector hyphenatedword) { - stoplist.put(word, hyphenatedword); - } - - /** - * Add a pattern to the tree. Mainly, to be used by - * {@link PatternParser PatternParser} 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(); - - } - - public static void main(String[] argv) throws Exception { - HyphenationTree ht = null; - int minCharCount = 2; - BufferedReader in = - new BufferedReader(new InputStreamReader(System.in)); - for (; ; ) { - System.out.print("l:\tload patterns from XML\nL:\tload patterns from serialized object\ns:\tset minimun character count\nw:\twrite hyphenation tree to object file\nh:\thyphenate\nf:\tfind pattern\nb:\tbenchmark\nq:\tquit\n\nCommand:"); - String token = in.readLine().trim(); - if (token.equals("f")) { - System.out.print("Pattern: "); - token = in.readLine().trim(); - System.out.println("Values: " + ht.findPattern(token)); - } else if (token.equals("s")) { - System.out.print("Minimun value: "); - token = in.readLine().trim(); - minCharCount = Integer.parseInt(token); - } else if (token.equals("l")) { - ht = new HyphenationTree(); - System.out.print("XML file name: "); - token = in.readLine().trim(); - ht.loadPatterns(token); - } else if (token.equals("L")) { - ObjectInputStream ois = null; - System.out.print("Object file name: "); - token = in.readLine().trim(); - try { - ois = new ObjectInputStream(new FileInputStream(token)); - ht = (HyphenationTree)ois.readObject(); - } catch (Exception e) { - e.printStackTrace(); - } - finally { - if (ois != null) { - try { - ois.close(); - } catch (IOException e) {} - } - } - } else if (token.equals("w")) { - System.out.print("Object file name: "); - token = in.readLine().trim(); - ObjectOutputStream oos = null; - try { - oos = new ObjectOutputStream(new FileOutputStream(token)); - oos.writeObject(ht); - } catch (Exception e) { - e.printStackTrace(); - } - finally { - if (oos != null) { - try { - oos.flush(); - } catch (IOException e) {} - try { - oos.close(); - } catch (IOException e) {} - } - } - } else if (token.equals("h")) { - System.out.print("Word: "); - token = in.readLine().trim(); - System.out.print("Hyphenation points: "); - System.out.println(ht.hyphenate(token, minCharCount, - minCharCount)); - } else if (token.equals("b")) { - if (ht == null) { - System.out.println("No patterns has been loaded."); - break; - } - System.out.print("Word list filename: "); - token = in.readLine().trim(); - long starttime = 0; - int counter = 0; - ; - try { - BufferedReader reader = - new BufferedReader(new FileReader(token)); - String line; - - starttime = System.currentTimeMillis(); - while ((line = reader.readLine()) != null) { - // System.out.print("\nline: "); - Hyphenation hyp = ht.hyphenate(line, minCharCount, - minCharCount); - if (hyp != null) { - String hword = hyp.toString(); - // System.out.println(line); - // System.out.println(hword); - } else { - // System.out.println("No hyphenation"); - } - counter++; - } - } catch (Exception ioe) { - System.out.println("Exception " + ioe); - ioe.printStackTrace(); - } - long endtime = System.currentTimeMillis(); - long result = endtime - starttime; - System.out.println(counter + " words in " + result - + " Millisekunden hyphenated"); - - } else if (token.equals("q")) - break; - } - - } - -} diff --git a/src/org/apache/fop/layout/hyphenation/Hyphenator.java b/src/org/apache/fop/layout/hyphenation/Hyphenator.java deleted file mode 100644 index 9d70dd72d..000000000 --- a/src/org/apache/fop/layout/hyphenation/Hyphenator.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.io.*; -import java.util.Hashtable; -import org.apache.fop.configuration.*; -import org.apache.fop.messaging.MessageHandler; - -/** - * 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 - */ -public class Hyphenator { - static Hashtable hyphenTrees = new Hashtable(); - - private HyphenationTree hyphenTree = null; - private int remainCharCount = 2; - private int pushCharCount = 2; - private static boolean errorDump = false; - - public Hyphenator(String lang, String country, int leftMin, - int rightMin) { - hyphenTree = getHyphenationTree(lang, country); - remainCharCount = leftMin; - pushCharCount = rightMin; - } - - 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 = getFopHyphenationTree(key); - if (hTree == null) { - String hyphenDir = - Configuration.getStringValue("hyphenation-dir"); - if (hyphenDir != null) { - hTree = getUserHyphenationTree(key, hyphenDir); - } - } - // put it into the pattern cache - if (hTree != null) { - hyphenTrees.put(key, hTree); - } else { - MessageHandler.errorln("Couldn't find hyphenation pattern " - + key); - } - return hTree; - } - - private static InputStream getResourceStream(String key) { - InputStream is = null; - // 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]); - is = contextClassLoader.getResourceAsStream("hyph/" + key - + ".hyp"); - } - } catch (Exception e) {} - - if (is == null) { - is = Hyphenator.class.getResourceAsStream("/hyph/" + key - + ".hyp"); - } - - return is; - } - - public static HyphenationTree getFopHyphenationTree(String key) { - HyphenationTree hTree = null; - ObjectInputStream ois = null; - InputStream is = null; - try { - is = getResourceStream(key); - if (is == null) { - if (key.length() == 5) { - is = getResourceStream(key.substring(0, 2)); - if (is != null) { - MessageHandler.errorln("Couldn't find hyphenation pattern " - + key - + "\nusing general language pattern " - + key.substring(0, 2) - + " instead."); - } else { - if (errorDump) { - MessageHandler.errorln("Couldn't find precompiled " - + "fop hyphenation pattern " - + key + ".hyp"); - } - return null; - } - } else { - if (errorDump) { - MessageHandler.errorln("Couldn't find precompiled " - + "fop hyphenation pattern " - + key + ".hyp"); - } - return null; - } - } - ois = new ObjectInputStream(is); - hTree = (HyphenationTree)ois.readObject(); - } catch (Exception e) { - e.printStackTrace(); - } - finally { - if (ois != null) { - try { - ois.close(); - } catch (IOException e) { - MessageHandler.errorln("can't close hyphenation object stream"); - } - } - } - return hTree; - } - - /** - * load tree from serialized file or xml file - * using configuration settings - */ - public static HyphenationTree getUserHyphenationTree(String key, - String hyphenDir) { - HyphenationTree hTree = null; - // I use here the following convention. The file name specified in - // the configuration is taken as the base name. First we try - // name + ".hyp" assuming a serialized HyphenationTree. If that fails - // we try name + ".xml", assumming a raw hyphenation pattern file. - - // first try serialized object - File hyphenFile = new File(hyphenDir, key + ".hyp"); - if (hyphenFile.exists()) { - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(new FileInputStream(hyphenFile)); - hTree = (HyphenationTree)ois.readObject(); - } catch (Exception e) { - e.printStackTrace(); - } - finally { - if (ois != null) { - try { - ois.close(); - } catch (IOException e) {} - } - } - return hTree; - } else { - - // try the raw XML file - hyphenFile = new File(hyphenDir, key + ".xml"); - if (hyphenFile.exists()) { - hTree = new HyphenationTree(); - if (errorDump) { - MessageHandler.errorln("reading " + hyphenDir + key - + ".xml"); - } - try { - hTree.loadPatterns(hyphenFile.getPath()); - if (errorDump) { - System.out.println("Stats: "); - hTree.printStats(); - } - return hTree; - } catch (HyphenationException ex) { - if (errorDump) { - MessageHandler.errorln("Can't load user patterns " - + "from xml file " + hyphenDir - + key + ".xml"); - } - return null; - } - } else { - if (errorDump) { - MessageHandler.errorln("Tried to load " - + hyphenFile.toString() - + "\nCannot find compiled nor xml file for " - + "hyphenation pattern" + key); - } - return null; - } - } - } - - public static Hyphenation hyphenate(String lang, String country, - String word, int leftMin, - int rightMin) { - HyphenationTree hTree = getHyphenationTree(lang, country); - if (hTree == null) { - MessageHandler.errorln("Error building hyphenation tree for language " - + lang); - return null; - } - return hTree.hyphenate(word, leftMin, rightMin); - } - - 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) { - MessageHandler.errorln("Error building hyphenation tree for language " - + lang); - return null; - } - return hTree.hyphenate(word, offset, len, leftMin, rightMin); - } - - public void setMinRemainCharCount(int min) { - remainCharCount = min; - } - - public void setMinPushCharCount(int min) { - pushCharCount = min; - } - - public void setLanguage(String lang, String country) { - hyphenTree = getHyphenationTree(lang, country); - } - - public Hyphenation hyphenate(char[] word, int offset, int len) { - if (hyphenTree == null) - return null; - return hyphenTree.hyphenate(word, offset, len, remainCharCount, - pushCharCount); - } - - public Hyphenation hyphenate(String word) { - if (hyphenTree == null) - return null; - return hyphenTree.hyphenate(word, remainCharCount, pushCharCount); - } - -} diff --git a/src/org/apache/fop/layout/hyphenation/PatternConsumer.java b/src/org/apache/fop/layout/hyphenation/PatternConsumer.java deleted file mode 100644 index 2eacd16a7..000000000 --- a/src/org/apache/fop/layout/hyphenation/PatternConsumer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.util.Vector; - -/** - * This interface is used to connect the XML pattern file parser to - * the hyphenation tree. - * - * @author Carlos Villegas - */ -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. - */ - public 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 - */ - public void addException(String word, Vector hyphenatedword); - - /** - * Add hyphenation patterns. - * @param pattern - * @param values interletter values expressed as a string of - * digit characters. - */ - public void addPattern(String pattern, String values); - -} diff --git a/src/org/apache/fop/layout/hyphenation/PatternParser.java b/src/org/apache/fop/layout/hyphenation/PatternParser.java deleted file mode 100644 index 76d0d36f7..000000000 --- a/src/org/apache/fop/layout/hyphenation/PatternParser.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -// SAX -import org.xml.sax.XMLReader; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; -import org.xml.sax.Attributes; - -// Java -import java.io.FileReader; -import java.io.File; -import java.io.FileWriter; -import java.io.PrintWriter; -import java.io.IOException; -import java.io.FileNotFoundException; -import java.util.Vector; -import java.net.URL; - -/** - * A SAX document handler to read and parse hyphenation patterns - * from a XML file. - * - * @author Carlos Villegas - */ -public class PatternParser extends DefaultHandler implements PatternConsumer { - - XMLReader parser; - int currElement; - PatternConsumer consumer; - StringBuffer token; - Vector exception; - char hyphenChar; - String errMsg; - - static final int ELEM_CLASSES = 1; - static final int ELEM_EXCEPTIONS = 2; - static final int ELEM_PATTERNS = 3; - static final int ELEM_HYPHEN = 4; - - public PatternParser() throws HyphenationException { - token = new StringBuffer(); - parser = createParser(); - parser.setContentHandler(this); - parser.setErrorHandler(this); - hyphenChar = '-'; // default - - } - - public PatternParser(PatternConsumer consumer) - throws HyphenationException { - this(); - this.consumer = consumer; - } - - public void setConsumer(PatternConsumer consumer) { - this.consumer = consumer; - } - - public void parse(String filename) throws HyphenationException { - InputSource uri = fileInputSource(filename); - - try { - parser.parse(uri); - } catch (SAXException e) { - throw new HyphenationException(errMsg); - } catch (IOException e) { - throw new HyphenationException(e.getMessage()); - } catch (NullPointerException e) { - throw new HyphenationException("SAX parser not available"); - } - } - - /** - * creates a SAX parser, using the value of org.xml.sax.parser - * defaulting to org.apache.xerces.parsers.SAXParser - * - * @return the created SAX parser - */ - static XMLReader createParser() throws HyphenationException { - String parserClassName = System.getProperty("org.xml.sax.parser"); - if (parserClassName == null) { - parserClassName = "org.apache.xerces.parsers.SAXParser"; - } - // System.out.println("using SAX parser " + parserClassName); - - try { - return (XMLReader)Class.forName(parserClassName).newInstance(); - } catch (ClassNotFoundException e) { - throw new HyphenationException("Could not find " - + parserClassName); - } catch (InstantiationException e) { - throw new HyphenationException("Could not instantiate " - + parserClassName); - } catch (IllegalAccessException e) { - throw new HyphenationException("Could not access " - + parserClassName); - } catch (ClassCastException e) { - throw new HyphenationException(parserClassName - + " is not a SAX driver"); - } - } - - /** - * create an InputSource from a file name - * - * @param filename the name of the file - * @return the InputSource created - */ - protected static InputSource fileInputSource(String filename) - throws HyphenationException { - - /* this code adapted from James Clark's in XT */ - File file = new File(filename); - String path = file.getAbsolutePath(); - String fSep = System.getProperty("file.separator"); - if (fSep != null && fSep.length() == 1) - path = path.replace(fSep.charAt(0), '/'); - if (path.length() > 0 && path.charAt(0) != '/') - path = '/' + path; - try { - return new InputSource(new URL("file", null, path).toString()); - } catch (java.net.MalformedURLException e) { - throw new HyphenationException("unexpected MalformedURLException"); - } - } - - protected String readToken(StringBuffer chars) { - String word; - boolean space = false; - int i; - for (i = 0; i < chars.length(); i++) - if (Character.isWhitespace(chars.charAt(i))) - space = true; - else - break; - if (space) { - // chars.delete(0,i); - for (int countr = i; countr < chars.length(); countr++) - chars.setCharAt(countr - i, chars.charAt(countr)); - chars.setLength(chars.length() - i); - if (token.length() > 0) { - word = token.toString(); - token.setLength(0); - return word; - } - } - space = false; - for (i = 0; i < chars.length(); i++) { - if (Character.isWhitespace(chars.charAt(i))) { - space = true; - break; - } - } - token.append(chars.toString().substring(0, i)); - // chars.delete(0,i); - for (int countr = i; countr < chars.length(); countr++) - chars.setCharAt(countr - i, chars.charAt(countr)); - chars.setLength(chars.length() - i); - if (space) { - word = token.toString(); - token.setLength(0); - return word; - } - token.append(chars); - return null; - } - - 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 Vector normalizeException(Vector ex) { - Vector res = new Vector(); - for (int i = 0; i < ex.size(); i++) { - Object item = ex.elementAt(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.addElement(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.addElement(new Hyphen(new String(h), null, null)); - } - } - if (buf.length() > 0) - res.addElement(buf.toString()); - } else - res.addElement(item); - } - return res; - } - - protected String getExceptionWord(Vector ex) { - StringBuffer res = new StringBuffer(); - for (int i = 0; i < ex.size(); i++) { - Object item = ex.elementAt(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(); - } - - // - // DocumentHandler methods - // - - /** - * Start element. - */ - public void startElement(String uri, String local, String raw, - Attributes attrs) { - if (local.equals("hyphen-char")) { - String h = attrs.getValue("value"); - if (h != null && h.length() == 1) - hyphenChar = h.charAt(0); - } else if (local.equals("classes")) - currElement = ELEM_CLASSES; - else if (local.equals("patterns")) - currElement = ELEM_PATTERNS; - else if (local.equals("exceptions")) { - currElement = ELEM_EXCEPTIONS; - exception = new Vector(); - } else if (local.equals("hyphen")) { - if (token.length() > 0) { - exception.addElement(token.toString()); - } - exception.addElement(new Hyphen(attrs.getValue("pre"), - attrs.getValue("no"), - attrs.getValue("post"))); - currElement = ELEM_HYPHEN; - } - token.setLength(0); - } - - public void endElement(String uri, String local, String raw) { - - if (token.length() > 0) { - String word = token.toString(); - switch (currElement) { - case ELEM_CLASSES: - consumer.addClass(word); - break; - case ELEM_EXCEPTIONS: - exception.addElement(word); - exception = normalizeException(exception); - consumer.addException(getExceptionWord(exception), - (Vector)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; - - } - - /** - * Characters. - */ - public void characters(char ch[], int start, int length) { - StringBuffer chars = new StringBuffer(length); - chars.append(ch, start, length); - String word = readToken(chars); - while (word != null) { - // System.out.println("\"" + word + "\""); - switch (currElement) { - case ELEM_CLASSES: - consumer.addClass(word); - break; - case ELEM_EXCEPTIONS: - exception.addElement(word); - exception = normalizeException(exception); - consumer.addException(getExceptionWord(exception), - (Vector)exception.clone()); - exception.removeAllElements(); - break; - case ELEM_PATTERNS: - consumer.addPattern(getPattern(word), - getInterletterValues(word)); - break; - } - word = readToken(chars); - } - - } - - // - // ErrorHandler methods - // - - /** - * Warning. - */ - public void warning(SAXParseException ex) { - errMsg = "[Warning] " + getLocationString(ex) + ": " - + ex.getMessage(); - } - - /** - * Error. - */ - public void error(SAXParseException ex) { - errMsg = "[Error] " + getLocationString(ex) + ": " + ex.getMessage(); - } - - /** - * Fatal error. - */ - public void fatalError(SAXParseException ex) throws SAXException { - errMsg = "[Fatal Error] " + getLocationString(ex) + ": " - + ex.getMessage(); - throw ex; - } - - /** - * Returns a string of the location. - */ - private String getLocationString(SAXParseException ex) { - StringBuffer str = new StringBuffer(); - - String systemId = ex.getSystemId(); - if (systemId != null) { - int index = systemId.lastIndexOf('/'); - if (index != -1) - systemId = systemId.substring(index + 1); - str.append(systemId); - } - str.append(':'); - str.append(ex.getLineNumber()); - str.append(':'); - str.append(ex.getColumnNumber()); - - return str.toString(); - - } // getLocationString(SAXParseException):String - - - // PatternConsumer implementation for testing purposes - public void addClass(String c) { - System.out.println("class: " + c); - } - - public void addException(String w, Vector 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 { - if (args.length > 0) { - PatternParser pp = new PatternParser(); - pp.setConsumer(pp); - pp.parse(args[0]); - } - } - -} diff --git a/src/org/apache/fop/layout/hyphenation/TernaryTree.java b/src/org/apache/fop/layout/hyphenation/TernaryTree.java deleted file mode 100644 index 25dd7005c..000000000 --- a/src/org/apache/fop/layout/hyphenation/TernaryTree.java +++ /dev/null @@ -1,634 +0,0 @@ -/* - * $Id$ - * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. - * For details on use and redistribution please refer to the - * LICENSE file included with these sources. - */ - -package org.apache.fop.layout.hyphenation; - -import java.util.Enumeration; -import java.util.Stack; -import java.io.Serializable; - -/** - *

Ternary Search Tree

- * - *

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).

- * - *

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.

- * - *

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.

- * - * @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; - - /** - *

The character stored in this node: splitchar - * Two special values are reserved:

- *
  • 0x0000 as string terminator
  • - *
  • 0xFFFF to indicate that the branch starting at - * this node is compressed
- *

This shouldn't be a problem if we give the usual semantics to - * strings since 0xFFFF is garanteed not to be an Unicode character.

- */ - 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 final static 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 - sc[pp] = - 0xFFFF; // we only got first char of key, rest is still there - } 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; - for (; ; ) { - // 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