+++ /dev/null
-/*
- * $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:
- * <UL>
- * <LI>image width
- * <LI>image height
- * </UL>
- * 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:
- * <UL>
- * <LI>image width
- * <LI>image height
- * </UL>
- * 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;
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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();
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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);
- }
-
-}
+++ /dev/null
-/*
- * $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 <FopImage implementing class>
- 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;
- }
-
-}
-
+++ /dev/null
-/*
- * $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);
- }
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-
-
-}
-
-
+++ /dev/null
-/*
- * $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());
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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);
- }
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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();
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-}
-
+++ /dev/null
-/*
- * $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
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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 <code>Area</code> instance.
- *
- * @param fontState a <code>FontState</code> 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;
- }
-
-}
+++ /dev/null
-/*
- * $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 + "'");
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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);
- }
-
-}
+++ /dev/null
-/*
- * $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 <i>may</i> 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);
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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<padding.length; i++) {
- if (padding[i] != null) {
- bp.padding[i]=(ResolvedCondLength)padding[i].clone();
- }
- if (borderInfo[i] != null) {
- bp.borderInfo[i]=(BorderInfo)borderInfo[i].clone();
- }
- }
- return bp;
- }
-
- public static class BorderInfo implements Cloneable {
- private int mStyle; // Enum for border style
- private ColorType mColor; // Border color
- private ResolvedCondLength mWidth;
-
- BorderInfo(int style, CondLength width, ColorType color) {
- mStyle = style;
- mWidth = new ResolvedCondLength(width);
- mColor = color;
- }
-
- public Object clone() throws CloneNotSupportedException {
- BorderInfo bi = (BorderInfo) super.clone();
- bi.mWidth = (ResolvedCondLength)mWidth.clone();
- // do we need to clone the Color too???
- return bi;
- }
- }
-
- private BorderInfo[] borderInfo = new BorderInfo[4];
- private ResolvedCondLength[] padding = new ResolvedCondLength[4];
-
- public BorderAndPadding() {}
-
- public void setBorder(int side, int style, CondLength width,
- ColorType color) {
- borderInfo[side] = new BorderInfo(style, width, color);
- }
-
- public void setPadding(int side, CondLength width) {
- padding[side] = new ResolvedCondLength(width);
- }
-
- public void setPaddingLength(int side, int iLength) {
- padding[side].iLength = iLength;
- }
-
- public void setBorderLength(int side, int iLength) {
- borderInfo[side].mWidth.iLength = iLength;
- }
-
- public int getBorderLeftWidth(boolean bDiscard) {
- return getBorderWidth(LEFT, bDiscard);
- }
-
- public int getBorderRightWidth(boolean bDiscard) {
- return getBorderWidth(RIGHT, bDiscard);
- }
-
- public int getBorderTopWidth(boolean bDiscard) {
- return getBorderWidth(TOP, bDiscard);
- }
-
- public int getBorderBottomWidth(boolean bDiscard) {
- return getBorderWidth(BOTTOM, bDiscard);
- }
-
- public int getPaddingLeft(boolean bDiscard) {
- return getPadding(LEFT, bDiscard);
- }
-
- public int getPaddingRight(boolean bDiscard) {
- return getPadding(RIGHT, bDiscard);
- }
-
- public int getPaddingBottom(boolean bDiscard) {
- return getPadding(BOTTOM, bDiscard);
- }
-
- public int getPaddingTop(boolean bDiscard) {
- return getPadding(TOP, bDiscard);
- }
-
-
- private int getBorderWidth(int side, boolean bDiscard) {
- if ((borderInfo[side] == null)
- || (bDiscard && borderInfo[side].mWidth.bDiscard)) {
- return 0;
- } else
- return borderInfo[side].mWidth.iLength;
- }
-
- public ColorType getBorderColor(int side) {
- if (borderInfo[side] != null) {
- return borderInfo[side].mColor;
- } else
- return null;
- }
-
- public int getBorderStyle(int side) {
- if (borderInfo[side] != null) {
- return borderInfo[side].mStyle;
- } else
- return 0;
- }
-
- private int getPadding(int side, boolean bDiscard) {
- if ((padding[side] == null) || (bDiscard && padding[side].bDiscard)) {
- return 0;
- } else
- return padding[side].iLength;
- }
-
-}
+++ /dev/null
-/*
- * $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.render.Renderer;
-
-abstract public class Box {
- protected Area parent;
- protected AreaTree areaTree;
- abstract public void render(Renderer renderer);
-}
+++ /dev/null
-/*
- * $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 ColumnArea extends AreaContainer {
-
- private int columnIndex;
- private int maxColumns;
-
- public ColumnArea(FontState fontState, int xPosition, int yPosition,
- int allocationWidth, int maxHeight, int columnCount) {
- super(fontState, xPosition, yPosition, allocationWidth, maxHeight,
- Position.ABSOLUTE);
- this.maxColumns = columnCount;
- this.setAreaName("normal-flow-ref.-area");
- }
-
- public void render(Renderer renderer) {
- renderer.renderAreaContainer(this);
- }
-
- public void end() {}
-
- public void start() {}
-
- public int spaceLeft() {
- return maxHeight - currentHeight;
- }
-
- public int getColumnIndex() {
- return columnIndex;
- }
-
- public void setColumnIndex(int columnIndex) {
- this.columnIndex = columnIndex;
- }
-
- public void incrementSpanIndex() {
- SpanArea span = (SpanArea)this.parent;
- span.setCurrentColumn(span.getCurrentColumn() + 1);
- }
-
-}
+++ /dev/null
-/*
- * $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.render.Renderer;
-
-public class DisplaySpace extends Space {
- private int size;
-
- public DisplaySpace(int size) {
- this.size = size;
- }
-
- public int getSize() {
- return size;
- }
-
- public void render(Renderer renderer) {
- renderer.renderDisplaySpace(this);
- }
-
-}
+++ /dev/null
-/*
- * $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.*;
-
-import org.apache.fop.extensions.*;
-import org.apache.fop.render.*;
-
-public class ExtensionArea extends Area {
- private ExtensionObj _extensionObj;
-
- public ExtensionArea(ExtensionObj obj) {
- super(null);
- _extensionObj = obj;
- }
-
- public FObj getExtensionObj() {
- return _extensionObj;
- }
-
- public void render(Renderer renderer) {
- // renderer.renderExtensionArea(this);
- }
-
-
-}
+++ /dev/null
-/*
- * $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 interface FontDescriptor {
-
- // Required
- public int getAscender(); // Ascent in pdf spec
- public int getCapHeight();
- public int getDescender(); // Descent in pdf spec
- public int getFlags();
- public int[] getFontBBox();
- public String fontName(); // should be getFontName(). not?
- public int getItalicAngle();
- public int getStemV();
-
- public boolean hasKerningInfo();
- public java.util.Hashtable getKerningInfo();
- public boolean isEmbeddable();
- public byte getSubType();
- public org.apache.fop.pdf.PDFStream getFontFile(int objNum);
- // Optional - but needed to calculate font-size-adjust...
- // public int getXHeight();
-
-}
-
-
+++ /dev/null
-/*
- * $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.messaging.MessageHandler;
-import java.util.Enumeration;
-
-import org.apache.fop.apps.FOPException;
-
-public class FontInfo {
- Hashtable usedFonts;
- Hashtable triplets; // look up a font-triplet to find a font-name
- Hashtable fonts; // look up a font-name to get a font (that implements FontMetric at least)
-
- public FontInfo() {
- this.triplets = new Hashtable();
- this.fonts = new Hashtable();
- this.usedFonts = new Hashtable();
- }
-
- public void addFontProperties(String name, String family, String style,
- String weight) {
- /*
- * add the given family, style and weight as a lookup for the font
- * with the given name
- */
-
- String key = createFontKey(family, style, weight);
- this.triplets.put(key, name);
- }
-
- public void addMetrics(String name, FontMetric metrics) {
- // add the given metrics as a font with the given name
-
- this.fonts.put(name, metrics);
- }
-
- public String fontLookup(String family, String style,
- String weight) throws FOPException {
- return fontLookup(createFontKey(family, style, weight));
- }
-
- public String fontLookup(String key) throws FOPException {
-
- String f = (String)this.triplets.get(key);
- if (f == null) {
- int i = key.indexOf(',');
- String s = "any" + key.substring(i);
- f = (String)this.triplets.get(s);
- if (f == null) {
- f = (String)this.triplets.get("any,normal,normal");
- if (f == null) {
- throw new FOPException("no default font defined by OutputConverter");
- }
- MessageHandler.errorln("WARNING: defaulted font to any,normal,normal");
- }
- MessageHandler.errorln("WARNING: unknown font " + key
- + " so defaulted font to any");
- }
-
- usedFonts.put(f, fonts.get(f));
- return f;
- }
-
- public boolean hasFont(String family, String style, String weight) {
- String key = createFontKey(family, style, weight);
- return this.triplets.get(key) != null;
- }
-
- /**
- * Creates a key from the given strings
- */
- public static String createFontKey(String family, String style,
- String weight) {
- int i;
-
- try {
- i = Integer.parseInt(weight);
- } catch (NumberFormatException e) {
- i = 0;
- }
-
- if (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);
- }
-
-}
+++ /dev/null
-/*
- * $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);
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
-
-
-
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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. <br>
- * 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);
- }
- }
- }
- }
-
-}
-
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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() {}
-
-}
+++ /dev/null
-/*
- * $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 {}
+++ /dev/null
-/*
- * $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);
- }
-
-}
+++ /dev/null
-/*
- * $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;
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-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;
- }
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-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;
- }
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-
-public class Hyphen implements Serializable {
- public String preBreak;
- public String noBreak;
- public String postBreak;
-
- Hyphen(String pre, String no, String post) {
- preBreak = pre;
- noBreak = no;
- postBreak = post;
- }
-
- Hyphen(String pre) {
- preBreak = pre;
- noBreak = null;
- postBreak = null;
- }
-
- public String toString() {
- if (noBreak == null && postBreak == null && preBreak != null
- && preBreak.equals("-"))
- return "-";
- StringBuffer res = new StringBuffer("{");
- res.append(preBreak);
- res.append("}{");
- res.append(postBreak);
- res.append("}{");
- res.append(noBreak);
- res.append('}');
- return res.toString();
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-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();
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-public class HyphenationException extends Exception {
-
- public HyphenationException(String msg) {
- super(msg);
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-public class HyphenationTree extends TernaryTree implements PatternConsumer,
- Serializable {
-
- /**
- * value space: stores the inteletter values
- */
- protected ByteVector vspace;
-
- /**
- * This map stores hyphenation exceptions
- */
- protected 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;
- }
-
- /**
- * <p>Search for all possible partial matches of word starting
- * at index an update interletter values. In other words, it
- * does something like:</p>
- * <code>
- * for(i=0; i<patterns.length; i++) {
- * if ( word.substring(index).startsWidth(patterns[i]) )
- * update_interletter_values(patterns[i]);
- * }
- * </code>
- * <p>But it is done in an efficient way since the patterns are
- * stored in a ternary tree. In fact, this is the whole purpose
- * of having the tree: doing this search without having to test
- * every single pattern. The number of patterns for languages
- * such as English range from 4000 to 10000. Thus, doing thousands
- * of string comparisons for each word to hyphenate would be
- * really slow without the tree. The tradeoff is memory, but
- * using a ternary tree instead of a trie, almost halves the
- * the memory used by Lout or TeX. It's also faster than using
- * a hash table</p>
- * @param word null terminated word to match
- * @param index start index from word
- * @param il interletter values array to update
- */
- protected void searchPatterns(char[] word, int index, byte[] il) {
- byte[] values;
- int i = index;
- char p, q;
- char sp = word[i];
- p = root;
-
- while (p > 0 && p < sc.length) {
- if (sc[p] == 0xFFFF) {
- if (hstrcmp(word, i, kv.getArray(), lo[p]) == 0) {
- values = getValues(eq[p]); // data pointer is in eq[]
- int j = index;
- for (int k = 0; k < values.length; k++) {
- if (j < il.length && values[k] > il[j])
- il[j] = values[k];
- j++;
- }
- }
- return;
- }
- int d = sp - sc[p];
- if (d == 0) {
- if (sp == 0) {
- break;
- }
- sp = word[++i];
- p = eq[p];
- q = p;
-
- // look for a pattern ending at this position by searching for
- // the null char ( splitchar == 0 )
- while (q > 0 && q < sc.length) {
- if (sc[q] == 0xFFFF) { // stop at compressed branch
- break;
- }
- if (sc[q] == 0) {
- values = getValues(eq[q]);
- int j = index;
- for (int k = 0; k < values.length; k++) {
- if (j < il.length && values[k] > il[j]) {
- il[j] = values[k];
- }
- j++;
- }
- break;
- } else {
- q = lo[q];
-
- /**
- * actually the code should be:
- * q = sc[q] < 0 ? hi[q] : lo[q];
- * but java chars are unsigned
- */
- }
- }
- } else
- p = d < 0 ? lo[p] : hi[p];
- }
- }
-
- /**
- * Hyphenate word and return a Hyphenation object.
- * @param word the word to be hyphenated
- * @param remainCharCount Minimum number of characters allowed
- * before the hyphenation point.
- * @param pushCharCount Minimum number of characters allowed after
- * the hyphenation point.
- * @return a {@link Hyphenation Hyphenation} object representing
- * the hyphenated word or null if word is not hyphenated.
- */
- public Hyphenation hyphenate(String word, int remainCharCount,
- int pushCharCount) {
- char[] w = word.toCharArray();
- return hyphenate(w, 0, w.length, remainCharCount, pushCharCount);
- }
-
- /**
- * 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;
- }
-
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-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);
- }
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-public interface PatternConsumer {
-
- /**
- * Add a character class.
- * A character class defines characters that are considered
- * equivalent for the purpose of hyphenation (e.g. "aA"). It
- * usually means to ignore case.
- */
- 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);
-
-}
+++ /dev/null
-/*
- * $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 <cav@uniscope.co.jp>
- */
-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]);
- }
- }
-
-}
+++ /dev/null
-/*
- * $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;
-
-/**
- * <h2>Ternary Search Tree</h2>
- *
- * <p>A ternary search tree is a hibrid between a binary tree and
- * a digital search tree (trie). Keys are limited to strings.
- * A data value of type char is stored in each leaf node.
- * It can be used as an index (or pointer) to the data.
- * Branches that only contain one key are compressed to one node
- * by storing a pointer to the trailer substring of the key.
- * This class is intended to serve as base class or helper class
- * to implement Dictionary collections or the like. Ternary trees
- * have some nice properties as the following: the tree can be
- * traversed in sorted order, partial matches (wildcard) can be
- * implemented, retrieval of all keys within a given distance
- * from the target, etc. The storage requirements are higher than
- * a binary tree but a lot less than a trie. Performance is
- * comparable with a hash table, sometimes it outperforms a hash
- * function (most of the time can determine a miss faster than a hash).</p>
- *
- * <p>The main purpose of this java port is to serve as a base for
- * implementing TeX's hyphenation algorithm (see The TeXBook,
- * appendix H). Each language requires from 5000 to 15000 hyphenation
- * patterns which will be keys in this tree. The strings patterns
- * are usually small (from 2 to 5 characters), but each char in the
- * tree is stored in a node. Thus memory usage is the main concern.
- * We will sacrify 'elegance' to keep memory requirenments to the
- * minimum. Using java's char type as pointer (yes, I know pointer
- * it is a forbidden word in java) we can keep the size of the node
- * to be just 8 bytes (3 pointers and the data char). This gives
- * room for about 65000 nodes. In my tests the english patterns
- * took 7694 nodes and the german patterns 10055 nodes,
- * so I think we are safe.</p>
- *
- * <p>All said, this is a map with strings as keys and char as value.
- * Pretty limited!. It can be extended to a general map by
- * using the string representation of an object and using the
- * char value as an index to an array that contains the object
- * values.</p>
- *
- * @author cav@uniscope.co.jp
- */
-
-public class TernaryTree implements Cloneable, Serializable {
-
- /**
- * We use 4 arrays to represent a node. I guess I should have created
- * a proper node class, but somehow Knuth's pascal code made me forget
- * we now have a portable language with virtual memory management and
- * automatic garbage collection! And now is kind of late, furthermore,
- * if it ain't broken, don't fix it.
- */
-
- /**
- * Pointer to low branch and to rest of the key when it is
- * stored directly in this node, we don't have unions in java!
- */
- protected char[] lo;
-
- /**
- * Pointer to high branch.
- */
- protected char[] hi;
-
- /**
- * Pointer to equal branch and to data when this node is a string terminator.
- */
- protected char[] eq;
-
- /**
- * <P>The character stored in this node: splitchar
- * Two special values are reserved:</P>
- * <ul><li>0x0000 as string terminator</li>
- * <li>0xFFFF to indicate that the branch starting at
- * this node is compressed</li></ul>
- * <p>This shouldn't be a problem if we give the usual semantics to
- * strings since 0xFFFF is garanteed not to be an Unicode character.</p>
- */
- protected char[] sc;
-
- /**
- * This vector holds the trailing of the keys when the branch is compressed.
- */
- protected CharVector kv;
-
- protected char root;
- protected char freenode;
- protected int length; // number of items in tree
-
- protected 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<kv.length(); i++)
- * if ( kv.get(i) != 0 )
- * System.out.print(kv.get(i));
- * else
- * System.out.println("");
- * System.out.println("Keys:");
- * for(Enumeration enum = keys(); enum.hasMoreElements(); )
- * System.out.println(enum.nextElement());
- */
-
- }
-
- public static void main(String[] args) throws Exception {
- TernaryTree tt = new TernaryTree();
- tt.insert("Carlos", 'C');
- tt.insert("Car", 'r');
- tt.insert("palos", 'l');
- tt.insert("pa", 'p');
- tt.trimToSize();
- System.out.println((char)tt.find("Car"));
- System.out.println((char)tt.find("Carlos"));
- System.out.println((char)tt.find("alto"));
- tt.printStats();
- }
-
-}
-
+++ /dev/null
-/*
- * $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.inline;
-
-// FOP
-import org.apache.fop.render.Renderer;
-import org.apache.fop.layout.*;
-
-// Java
-import java.util.Vector;
-import java.util.Enumeration;
-
-public class ForeignObjectArea extends InlineArea {
-
- protected int xOffset = 0;
- /* text-align of contents */
- protected int align;
- /* vertical align of contents */
- protected int valign;
- /* scaling method */
- protected int scaling;
- protected Area foreignObject;
- /* height according to the instream-foreign-object */
- protected int cheight;
- /* width according to the instream-foreign-object */
- protected int cwidth;
- /* width of the content */
- protected int awidth;
- /* height of the content */
- protected int aheight;
- /* width */
- protected int width;
- boolean wauto;
- boolean hauto;
- boolean cwauto;
- boolean chauto;
- int overflow;
-
- public ForeignObjectArea(FontState fontState, int width) {
- super(fontState, width, 0, 0, 0);
- }
-
- public void render(Renderer renderer) {
- if (foreignObject != null)
- renderer.renderForeignObjectArea(this);
- }
-
- /**
- * This is NOT the content width of the instream-foreign-object.
- * This is the content width for a Box.
- */
- public int getContentWidth() {
- return getEffectiveWidth();
- }
-
- /**
- * This is NOT the content height of the instream-foreign-object.
- * This is the content height for a Box.
- */
- public int getHeight() {
- return getEffectiveHeight();
- }
-
- public int getXOffset() {
- return this.xOffset;
- }
-
- public void setStartIndent(int startIndent) {
- xOffset = startIndent;
- }
-
- public void setObject(Area fobject) {
- foreignObject = fobject;
- }
-
- public Area getObject() {
- return foreignObject;
- }
-
- public void setSizeAuto(boolean wa, boolean ha) {
- wauto = wa;
- hauto = ha;
- }
-
- public void setContentSizeAuto(boolean wa, boolean ha) {
- cwauto = wa;
- chauto = ha;
- }
-
- 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 setOverflow(int o) {
- this.overflow = o;
- }
-
- public int getOverflow() {
- return this.overflow;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public void setWidth(int width) {
- this.width = width;
- }
-
- public void setContentHeight(int cheight) {
- this.cheight = cheight;
- }
-
- public void setContentWidth(int cwidth) {
- this.cwidth = cwidth;
- }
-
- public void setScaling(int scaling) {
- this.scaling = scaling;
- }
-
- public int scalingMethod() {
- return this.scaling;
- }
-
- public void setIntrinsicWidth(int w) {
- awidth = w;
- }
-
- public void setIntrinsicHeight(int h) {
- aheight = h;
- }
-
- public int getIntrinsicHeight() {
- return aheight;
- }
-
- public int getIntrinsicWidth() {
- return awidth;
- }
-
- public int getEffectiveHeight() {
- if (this.hauto) {
- if (this.chauto) {
- return aheight;
- } else {
- // need to handle percentages, this would be a scaling factor on the
- // instrinsic height (content determined height)
- // if(this.properties.get("content-height").getLength().isPercentage()) {
- // switch(scaling) {
- // case Scaling.UNIFORM:
- // break;
- // case Scaling.NON_UNIFORM:
- // break;
- // }
- // } else {
- return this.cheight;
- }
- } else {
- return this.height;
- }
- }
-
- public int getEffectiveWidth() {
- if (this.wauto) {
- if (this.cwauto) {
- return awidth;
- } else {
- // need to handle percentages, this would be a scaling factor on the
- // instrinsic height (content determined height)
- // if(this.properties.get("content-width").getLength().isPercentage()) {
- // switch(scaling) {
- // case Scaling.UNIFORM:
- // break;
- // case Scaling.NON_UNIFORM:
- // break;
- // }
- // } else {
- return this.cwidth;
- }
- } else {
- return this.width;
- }
- }
-
-}
+++ /dev/null
-/*
- * $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.inline;
-
-import org.apache.fop.render.Renderer;
-import org.apache.fop.layout.Area;
-import org.apache.fop.layout.FontState;
-import org.apache.fop.layout.*;
-
-public abstract class InlineArea extends Area {
-
- private int yOffset = 0;
-
- /**
- * amount of space added since the original layout - needed by links
- */
- private int xOffset = 0;
- protected int height = 0;
- private int verticalAlign = 0;
- protected String pageNumberId = null;
- private float red, green, blue;
-
- // Textdecoration
- protected boolean underlined = false;
- protected boolean overlined = false;
- protected boolean lineThrough = false;
-
-
- public InlineArea(FontState fontState, int width, float red, float green,
- float blue) {
- super(fontState);
- this.contentRectangleWidth = width;
- this.red = red;
- this.green = green;
- this.blue = blue;
- }
-
- public float getBlue() {
- return this.blue;
- }
-
- public float getGreen() {
- return this.green;
- }
-
- public float getRed() {
- return this.red;
- }
-
- public void setHeight(int height) {
- this.height = height;
- }
-
- public int getHeight() {
- return this.height;
- }
-
- public void setVerticalAlign(int align) {
- this.verticalAlign = align;
- }
-
- public int getVerticalAlign() {
- return this.verticalAlign;
- }
-
- public void setYOffset(int yOffset) {
- this.yOffset = yOffset;
- }
-
- public int getYOffset() {
- return this.yOffset;
- }
-
- public void setXOffset(int xOffset) {
- this.xOffset = xOffset;
- }
-
- public int getXOffset() {
- return this.xOffset;
- }
-
- public String getPageNumberID() {
- return pageNumberId;
- }
-
- public void setUnderlined(boolean ul) {
- this.underlined = ul;
- }
-
- public boolean getUnderlined() {
- return this.underlined;
- }
-
- public void setOverlined(boolean ol) {
- this.overlined = ol;
- }
-
- public boolean getOverlined() {
- return this.overlined;
- }
-
- public void setLineThrough(boolean lt) {
- this.lineThrough = lt;
- }
-
- public boolean getLineThrough() {
- return this.lineThrough;
- }
-
-}
+++ /dev/null
-/*
- * $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.inline;
-
-import org.apache.fop.render.Renderer;
-import org.apache.fop.layout.*;
-
-public class InlineSpace extends Space {
- private int size; // in millipoints
- private boolean resizeable =
- true; // to disallow size changes during justification of a line
- // Used to discard some pending spaces in LineArea
- private boolean eatable = false;
-
- // Textdecoration
- protected boolean underlined = false;
- protected boolean overlined = false;
- protected boolean lineThrough = false;
-
-
- public InlineSpace(int amount) {
- this.size = amount;
- }
-
- public InlineSpace(int amount, boolean resizeable) {
- this.resizeable = resizeable;
- this.size = amount;
- }
-
- /**
- * @param ul true if text should be underlined
- */
- public void setUnderlined(boolean ul) {
- this.underlined = ul;
- }
-
- public boolean getUnderlined() {
- return this.underlined;
- }
-
- public void setOverlined(boolean ol) {
- this.overlined = ol;
- }
-
- public boolean getOverlined() {
- return this.overlined;
- }
-
- public void setLineThrough(boolean lt) {
- this.lineThrough = lt;
- }
-
- public boolean getLineThrough() {
- return this.lineThrough;
- }
-
- public int getSize() {
- return size;
- }
-
- public void setSize(int amount) {
- this.size = amount;
- }
-
- public boolean getResizeable() {
- return resizeable;
- }
-
- public void setResizeable(boolean resizeable) {
- this.resizeable = resizeable;
- }
-
- /**
- * And eatable InlineSpace is discarded if it occurs
- * as the first pending element in a LineArea
- */
- public void setEatable(boolean eatable) {
- this.eatable = eatable;
- }
-
- public boolean isEatable() {
- return eatable;
- }
-
- public void render(Renderer renderer) {
- renderer.renderInlineSpace(this);
- }
-
-}
+++ /dev/null
-/*
- * $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.inline;
-
-import org.apache.fop.render.Renderer;
-import org.apache.fop.layout.*;
-
-import java.util.Vector;
-import java.util.Enumeration;
-
-public class LeaderArea extends InlineArea {
-
- int ruleThickness;
- int leaderLengthOptimum;
- int leaderPattern;
- int ruleStyle;
-
- float red, green, blue;
- public LeaderArea(FontState fontState, float red, float green,
- float blue, String text, int leaderLengthOptimum,
- int leaderPattern, int ruleThickness, int ruleStyle) {
- super(fontState, leaderLengthOptimum, red, green, blue);
-
- this.leaderPattern = leaderPattern;
- this.leaderLengthOptimum = leaderLengthOptimum;
- this.ruleStyle = ruleStyle;
- // following the xsl spec rule: if rule-style="none" set thickness to 0;
- // actually in pdf this doesn't work, because a very thin line is still shown
- // this is handled in the pdf renderer
- if (ruleStyle == org.apache.fop.fo.properties.RuleStyle.NONE) {
- ruleThickness = 0;
- }
- this.ruleThickness = ruleThickness;
- }
-
- public void render(Renderer renderer) {
- renderer.renderLeaderArea(this);
- }
-
- public int getRuleThickness() {
- return this.ruleThickness;
- }
-
- public int getRuleStyle() {
- return this.ruleStyle;
- }
-
- public int getLeaderPattern() {
- return this.leaderPattern;
- }
-
- public int getLeaderLength() {
- return this.contentRectangleWidth;
- }
-
-
-
-}
+++ /dev/null
-/*
- * $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.inline;
-
-import org.apache.fop.render.Renderer;
-import org.apache.fop.datatypes.IDNode;
-import org.apache.fop.layout.*;
-
-public class PageNumberInlineArea extends WordArea {
-
-
- public PageNumberInlineArea(FontState fontState, float red, float green,
- float blue, String refid, int width) {
- super(fontState, red, green, blue, "?", width);
- this.pageNumberId = refid;
- }
-
-}
+++ /dev/null
-/*
- * $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.inline;
-
-import org.apache.fop.render.Renderer;
-import org.apache.fop.layout.FontState;
-
-public class WordArea extends InlineArea {
-
- private String text;
-
- // Textdecoration
- protected boolean underlined = false;
- protected boolean overlined = false;
- protected boolean lineThrough = false;
-
-
- public WordArea(FontState fontState, float red, float green, float blue,
- String text, int width) {
- super(fontState, width, red, green, blue);
- this.text = text;
- this.contentRectangleWidth = width;
- }
-
- public void render(Renderer renderer) {
- renderer.renderWordArea(this);
- }
-
- public String getText() {
- return this.text;
- }
-
- public void setUnderlined(boolean ul) {
- this.underlined = ul;
- }
-
- public boolean getUnderlined() {
- return this.underlined;
- }
-
-}