--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * This class encapsulates the font atributes that need to be included
+ * in the AFP data stream. This class does not assist in converting the
+ * font attributes to AFP code pages and character set values.
+ *
+ */
+public class AFPFontAttributes {
+
+ /**
+ * The font reference byte
+ */
+ private byte _fontReference;
+
+ /**
+ * The font key
+ */
+ private String _fontKey;
+
+ /**
+ * The font
+ */
+ private AFPFont _font;
+
+ /**
+ * The point size
+ */
+ private int _pointSize;
+
+ /**
+ * Constructor for the AFPFontAttributes
+ * @param fontKey the font key
+ * @param font the font
+ * @param pointSize the point size
+ */
+ public AFPFontAttributes(
+
+ String fontKey,
+ AFPFont font,
+ int pointSize) {
+
+ _fontKey = fontKey;
+ _font = font;
+ _pointSize = pointSize;
+
+ }
+ /**
+ * @return the font
+ */
+ public AFPFont getFont() {
+ return _font;
+ }
+
+ /**
+ * @return the FontKey attribute
+ */
+ public String getFontKey() {
+
+ return _fontKey + _pointSize;
+
+ }
+
+ /**
+ * @return the point size attribute
+ */
+ public int getPointSize() {
+ return _pointSize;
+ }
+
+ /**
+ * @return the FontReference attribute
+ */
+ public byte getFontReference() {
+ return _fontReference;
+ }
+
+ /**
+ * Sets the FontReference attribute
+ * @param fontReference the FontReference to set
+ */
+ public void setFontReference(int fontReference) {
+
+ String id = String.valueOf(fontReference);
+ _fontReference = BinaryUtils.convert(id)[0];
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.fop.render.AbstractGraphics2DAdapter;
+import org.apache.fop.render.Graphics2DImagePainter;
+import org.apache.fop.render.RendererContext;
+
+/**
+ * Graphics2DAdapter implementation for AFP.
+ */
+public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter {
+
+ /**
+ * Main constructor
+ */
+ public AFPGraphics2DAdapter() {
+ }
+
+ /** @see org.apache.fop.render.Graphics2DAdapter */
+ public void paintImage(Graphics2DImagePainter painter,
+ RendererContext context,
+ int x, int y, int width, int height) throws IOException {
+ RendererContext.RendererContextWrapper wrappedContext
+ = new RendererContext.RendererContextWrapper(context);
+ AFPRenderer afp = (AFPRenderer)context.getRenderer();
+ Boolean grayObj = (Boolean)context.getProperty(AFPRendererContextConstants.AFP_GRAYSCALE);
+ boolean gray = (grayObj != null ? grayObj.booleanValue() : false);
+
+ //Paint to a BufferedImage
+ int resolution = (int)Math.round(context.getUserAgent().getTargetResolution());
+ BufferedImage bi = paintToBufferedImage(painter, wrappedContext, resolution, gray, false);
+
+ afp.drawBufferedImage(bi, resolution, x, y, width, height);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.area.Block;
+import org.apache.fop.area.BlockViewport;
+import org.apache.fop.area.BodyRegion;
+import org.apache.fop.area.CTM;
+import org.apache.fop.area.OffDocumentItem;
+import org.apache.fop.area.PageViewport;
+import org.apache.fop.area.RegionReference;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.Leader;
+import org.apache.fop.area.inline.Image;
+import org.apache.fop.area.inline.SpaceArea;
+import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.WordArea;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.fonts.base14.Courier;
+import org.apache.fop.fonts.base14.Helvetica;
+import org.apache.fop.fonts.base14.TimesRoman;
+import org.apache.fop.image.FopImage;
+import org.apache.fop.image.ImageFactory;
+import org.apache.fop.image.TIFFImage;
+import org.apache.fop.image.XMLImage;
+import org.apache.fop.render.AbstractPathOrientedRenderer;
+import org.apache.fop.render.Graphics2DAdapter;
+import org.apache.fop.render.RendererContext;
+import org.apache.fop.render.afp.extensions.AFPElementMapping;
+import org.apache.fop.render.afp.extensions.AFPPageSetup;
+import org.apache.fop.render.afp.fonts.AFPFontInfo;
+import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.fonts.CharacterSet;
+import org.apache.fop.render.afp.fonts.FopCharacterSet;
+import org.apache.fop.render.afp.fonts.OutlineFont;
+import org.apache.fop.render.afp.fonts.RasterFont;
+import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.modca.AFPDataStream;
+import org.apache.fop.render.afp.modca.ImageObject;
+import org.apache.fop.render.afp.modca.PageObject;
+import org.w3c.dom.Document;
+
+
+/**
+ * This is an implementation of a FOP Renderer that renders areas to AFP.
+ * <p>
+ * A renderer is primarily designed to convert a given area tree into the output
+ * document format. It should be able to produce pages and fill the pages with
+ * the text and graphical content. Usually the output is sent to an output
+ * stream. Some output formats may support extra information that is not
+ * available from the area tree or depends on the destination of the document.
+ * Each renderer is given an area tree to render to its output format. The area
+ * tree is simply a representation of the pages and the placement of text and
+ * graphical objects on those pages.
+ * </p>
+ * <p>
+ * The renderer will be given each page as it is ready and an output stream to
+ * write the data out. All pages are supplied in the order they appear in the
+ * document. In order to save memory it is possble to render the pages out of
+ * order. Any page that is not ready to be rendered is setup by the renderer
+ * first so that it can reserve a space or reference for when the page is ready
+ * to be rendered.The renderer is responsible for managing the output format and
+ * associated data and flow.
+ * </p>
+ * <p>
+ * Each renderer is totally responsible for its output format. Because font
+ * metrics (and therefore layout) are obtained in two different ways depending
+ * on the renderer, the renderer actually sets up the fonts being used. The font
+ * metrics are used during the layout process to determine the size of
+ * characters.
+ * </p>
+ * <p>
+ * The render context is used by handlers. It contains information about the
+ * current state of the renderer, such as the page, the position, and any other
+ * miscellanous objects that are required to draw into the page.
+ * </p>
+ * <p>
+ * A renderer is created by implementing the Renderer interface. However, the
+ * AbstractRenderer does most of what is needed, including iterating through the
+ * tree parts, so it is this that is extended. This means that this object only
+ * need to implement the basic functionality such as text, images, and lines.
+ * AbstractRenderer's methods can easily be overridden to handle things in a
+ * different way or do some extra processing.
+ * </p>
+ * <p>
+ * The relevent AreaTree structures that will need to be rendered are Page,
+ * Viewport, Region, Span, Block, Line, Inline. A renderer implementation
+ * renders each individual page, clips and aligns child areas to a viewport,
+ * handle all types of inline area, text, image etc and draws various lines and
+ * rectangles.
+ * </p>
+ *
+ * Note: There are specific extensions that have been added to the
+ * FO. They are specific to their location within the FO and have to be
+ * processed accordingly (ie. at the start or end of the page).
+ *
+ */
+public class AFPRenderer extends AbstractPathOrientedRenderer {
+
+ /**
+ * AFP factor for a 240 resolution = 72000/240 = 300
+ */
+ private static final int DPI_CONVERSION_FACTOR_240 = 300;
+
+ /**
+ * The afp data stream object responsible for generating afp data
+ */
+ private AFPDataStream _afpDataStream = null;
+
+ /**
+ * The map of afp root extensions
+ */
+ private HashMap _rootExtensionMap = null;
+
+ /**
+ * The map of page segments
+ */
+ private HashMap _pageSegmentsMap = null;
+
+ /**
+ * The fonts on the current page
+ */
+ private HashMap _currentPageFonts = null;
+
+ /**
+ * The current color object
+ */
+ private Color _currentColor = null;
+
+ /**
+ * The page font number counter, used to determine the next font reference
+ */
+ private int _pageFontCounter = 0;
+
+ /**
+ * The current font family
+ */
+ private String _currentFontFamily = "";
+
+ /**
+ * The current font size
+ */
+ private int _currentFontSize = 0;
+
+ /**
+ * The Options to be set on the AFPRenderer
+ */
+ private Map _afpOptions = null;
+
+ /**
+ * The page width
+ */
+ private int _pageWidth = 0;
+
+ /**
+ * The page height
+ */
+ private int _pageHeight = 0;
+
+ /**
+ * The current page sequence id
+ */
+ private String _pageSequenceId = null;
+
+ /**
+ * The portrait rotation
+ */
+ private int _portraitRotation = 0;
+
+ /**
+ * The landscape rotation
+ */
+ private int _landscapeRotation = 270;
+
+ /**
+ * The line cache, avoids drawing duplicate lines in tables.
+ */
+ private HashSet _lineCache = null;
+
+ /**
+ * The current x position for line drawing
+ */
+ private float _x;
+
+ /**
+ * The current y position for line drawing
+ */
+ private float _y;
+
+ /**
+ * The map of saved incomplete pages
+ */
+ private Map _pages = null;
+
+ /**
+ * Flag to the set the output object type for images
+ */
+ private boolean colorImages = false;
+
+ /**
+ * Default value for image depth
+ */
+ private int bitsPerPixel = 8;
+
+ /**
+ * Constructor for AFPRenderer.
+ */
+ public AFPRenderer() {
+ super();
+ }
+
+ /**
+ * Set up the font info
+ *
+ * @param inFontInfo font info to set up
+ */
+ public void setupFontInfo(FontInfo inFontInfo) {
+ this.fontInfo = inFontInfo;
+ int num = 1;
+ if (this.fontList != null && this.fontList.size() > 0) {
+ for (Iterator it = this.fontList.iterator(); it.hasNext(); ) {
+ AFPFontInfo afi = (AFPFontInfo)it.next();
+ AFPFont bf = (AFPFont)afi.getAFPFont();
+ for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext(); ) {
+ FontTriplet ft = (FontTriplet)it2.next();
+ this.fontInfo.addFontProperties("F" + num, ft.getName()
+ , ft.getStyle(), ft.getWeight());
+ this.fontInfo.addMetrics("F" + num, bf);
+ num++;
+ }
+ }
+ } else {
+ log.warn("No AFP fonts configured - using default setup");
+ }
+ if (this.fontInfo.fontLookup("sans-serif", "normal", 400) == null) {
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZH200 ", 1, new Helvetica());
+ AFPFont bf = new OutlineFont("Helvetica", cs);
+ this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal", 400);
+ this.fontInfo.addMetrics("F" + num, bf);
+ num++;
+ }
+ if (this.fontInfo.fontLookup("serif", "normal", 400) == null) {
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZN200 ", 1, new TimesRoman());
+ AFPFont bf = new OutlineFont("Helvetica", cs);
+ this.fontInfo.addFontProperties("F" + num, "serif", "normal", 400);
+ this.fontInfo.addMetrics("F" + num, bf);
+ num++;
+ }
+ if (this.fontInfo.fontLookup("monospace", "normal", 400) == null) {
+ CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZ4200 ", 1, new Courier());
+ AFPFont bf = new OutlineFont("Helvetica", cs);
+ this.fontInfo.addFontProperties("F" + num, "monospace", "normal", 400);
+ this.fontInfo.addMetrics("F" + num, bf);
+ num++;
+ }
+ if (this.fontInfo.fontLookup("any", "normal", 400) == null) {
+ FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal", 400);
+ this.fontInfo.addFontProperties(this.fontInfo.getInternalFontKey(ft), "any", "normal", 400);
+ }
+ }
+
+ /**
+ */
+ private AFPFontInfo buildFont(Configuration fontCfg, String _path)
+ throws ConfigurationException {
+
+ Configuration[] triple = fontCfg.getChildren("font-triplet");
+ List tripleList = new java.util.ArrayList();
+ if (triple.length == 0) {
+ log.error("Mandatory font configuration element '<font-triplet...' is missing");
+ return null;
+ }
+ for (int j = 0; j < triple.length; j++) {
+ int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
+ tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
+ triple[j].getAttribute("style"),
+ weight));
+ }
+
+ //build the fonts
+ Configuration afpFontCfg = fontCfg.getChild("afp-font");
+ if (afpFontCfg == null) {
+ log.error("Mandatory font configuration element '<afp-font...' is missing");
+ return null;
+ }
+ String path = afpFontCfg.getAttribute("path", _path);
+ String type = afpFontCfg.getAttribute("type");
+ if (type == null) {
+ log.error("Mandatory afp-font configuration attribute 'type=' is missing");
+ return null;
+ }
+ String codepage = afpFontCfg.getAttribute("codepage");
+ if (codepage == null) {
+ log.error("Mandatory afp-font configuration attribute 'code=' is missing");
+ return null;
+ }
+ String encoding = afpFontCfg.getAttribute("encoding");
+ if (encoding == null) {
+ log.error("Mandatory afp-font configuration attribute 'encoding=' is missing");
+ return null;
+ }
+
+ if ("raster".equalsIgnoreCase(type)) {
+
+ String name = afpFontCfg.getAttribute("name", "Unknown");
+
+ // Create a new font object
+ RasterFont font = new RasterFont(name);
+
+ Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font");
+ if (rasters.length == 0) {
+ log.error("Mandatory font configuration elements '<afp-raster-font...' are missing");
+ return null;
+ }
+ for (int j = 0; j < rasters.length; j++) {
+ Configuration rasterCfg = rasters[j];
+
+ String characterset = rasterCfg.getAttribute("characterset");
+ if (characterset == null) {
+ log.error("Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
+ return null;
+ }
+ int size = rasterCfg.getAttributeAsInteger("size");
+ String base14 = rasterCfg.getAttribute("base14-font", null);
+
+ if (base14 != null) {
+ try {
+ Class clazz = Class.forName("org.apache.fop.fonts.base14."
+ + base14);
+ try {
+ Typeface tf = (Typeface)clazz.newInstance();
+ font.addCharacterSet(size, new FopCharacterSet(
+ codepage, encoding, characterset, size, tf));
+ } catch (Exception ie) {
+ String msg = "The base 14 font class " + clazz.getName()
+ + " could not be instantiated";
+ log.error(msg);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "The base 14 font class for " + characterset
+ + " could not be found";
+ log.error(msg);
+ }
+ } else {
+ font.addCharacterSet(size, new CharacterSet(
+ codepage, encoding, characterset, path));
+ }
+ }
+ return new AFPFontInfo(font, tripleList);
+
+ } else if ("outline".equalsIgnoreCase(type)) {
+
+ String characterset = afpFontCfg.getAttribute("characterset");
+ if (characterset == null) {
+ log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
+ return null;
+ }
+ String name = afpFontCfg.getAttribute("name", characterset);
+
+ CharacterSet characterSet = null;
+
+ String base14 = afpFontCfg.getAttribute("base14-font", null);
+
+ if (base14 != null) {
+ try {
+ Class clazz = Class.forName("org.apache.fop.fonts.base14."
+ + base14);
+ try {
+ Typeface tf = (Typeface)clazz.newInstance();
+ characterSet = new FopCharacterSet(
+ codepage, encoding, characterset, 1, tf);
+ } catch (Exception ie) {
+ String msg = "The base 14 font class " + clazz.getName()
+ + " could not be instantiated";
+ log.error(msg);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "The base 14 font class for " + characterset
+ + " could not be found";
+ log.error(msg);
+ }
+ } else {
+ characterSet = new CharacterSet(codepage, encoding, characterset, path);
+ }
+ // Create a new font object
+ OutlineFont font = new OutlineFont(name, characterSet);
+ return new AFPFontInfo(font, tripleList);
+ } else {
+ log.error("No or incorrect type attribute");
+ }
+ return null;
+ }
+
+ /**
+ * Builds a list of AFPFontInfo objects for use with the setup() method.
+ * @param cfg Configuration object
+ * @return List the newly created list of fonts
+ * @throws ConfigurationException if something's wrong with the config data
+ */
+ public List buildFontListFromConfiguration(Configuration cfg)
+ throws ConfigurationException {
+ List fontList = new java.util.ArrayList();
+ Configuration[] font = cfg.getChild("fonts").getChildren("font");
+ for (int i = 0; i < font.length; i++) {
+ AFPFontInfo afi = buildFont(font[i], null);
+ if (afi != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Adding font " + afi.getAFPFont().getFontName());
+ for (int j = 0; j < afi.getFontTriplets().size(); ++j) {
+ FontTriplet triplet = (FontTriplet) afi.getFontTriplets().get(j);
+ log.debug("Font triplet "
+ + triplet.getName() + ", "
+ + triplet.getStyle() + ", "
+ + triplet.getWeight());
+ }
+ }
+
+ fontList.add(afi);
+ }
+ }
+ return fontList;
+ }
+
+ /**
+ * Configure the AFP renderer.
+ * Get the configuration to be used for fonts etc.
+ * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
+ */
+ public void configure(Configuration cfg) throws ConfigurationException {
+ //Font configuration
+ this.fontList = buildFontListFromConfiguration(cfg);
+ Configuration images = cfg.getChild("images");
+ if (!"color".equalsIgnoreCase(images.getAttribute("mode", "b+w"))) {
+ bitsPerPixel = images.getAttributeAsInteger("bits-per-pixel", 8);
+ switch (bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ break;
+ default:
+ log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
+ bitsPerPixel = 8;
+ break;
+ }
+ } else {
+ colorImages = true;
+ }
+
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
+ */
+ public void setUserAgent(FOUserAgent agent) {
+ super.setUserAgent(agent);
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream)
+ */
+ public void startRenderer(OutputStream outputStream) throws IOException {
+ _currentPageFonts = new HashMap();
+ _currentColor = new Color(255, 255, 255);
+ _afpDataStream = new AFPDataStream();
+ _afpDataStream.setPortraitRotation(_portraitRotation);
+ _afpDataStream.setLandscapeRotation(_landscapeRotation);
+ _afpDataStream.startDocument(outputStream);
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#stopRenderer(java.io.OutputStream)
+ */
+ public void stopRenderer() throws IOException {
+ _afpDataStream.endDocument();
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#supportsOutOfOrder()
+ */
+ public boolean supportsOutOfOrder() {
+ //return false;
+ return true;
+ }
+
+ /**
+ * Prepare a page for rendering. This is called if the renderer supports
+ * out of order rendering. The renderer should prepare the page so that a
+ * page further on in the set of pages can be rendered. The body of the
+ * page should not be rendered. The page will be rendered at a later time
+ * by the call to render page.
+ *
+ * @see org.apache.fop.render.Renderer#preparePage(PageViewport)
+ */
+ public void preparePage(PageViewport page) {
+ // initializeRootExtensions(page);
+
+ _currentFontFamily = "";
+ _currentFontSize = 0;
+ _pageFontCounter = 0;
+ _currentPageFonts.clear();
+ _lineCache = new HashSet();
+
+ Rectangle2D bounds = page.getViewArea();
+
+ _pageWidth = mpts2units(bounds.getWidth());
+ _pageHeight = mpts2units(bounds.getHeight());
+
+ // renderPageGroupExtensions(page);
+
+ _afpDataStream.startPage(_pageWidth, _pageHeight, 0);
+
+ renderPageObjectExtensions(page);
+
+ if (_pages == null) {
+ _pages = new HashMap();
+ }
+ _pages.put(page, _afpDataStream.savePage());
+
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#processOffDocumentItem(OffDocumentItem)
+ */
+ public void processOffDocumentItem(OffDocumentItem odi) {
+ // TODO
+ }
+
+ /** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */
+ public Graphics2DAdapter getGraphics2DAdapter() {
+ return new AFPGraphics2DAdapter();
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM, Rectangle2D)
+ */
+ public void startVParea(CTM ctm, Rectangle2D clippingRect) {
+ // dummy not used
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#endVParea()
+ */
+ public void endVParea() {
+ // dummy not used
+ }
+
+ /**
+ * Renders a region viewport. <p>
+ *
+ * The region may clip the area and it establishes a position from where
+ * the region is placed.</p>
+ *
+ * @param port The region viewport to be rendered
+ */
+ public void renderRegionViewport(RegionViewport port) {
+ if (port != null) {
+ Rectangle2D view = port.getViewArea();
+ // The CTM will transform coordinates relative to
+ // this region-reference area into page coords, so
+ // set origin for the region to 0,0.
+ currentBPPosition = 0;
+ currentIPPosition = 0;
+
+ RegionReference regionReference = port.getRegionReference();
+ handleRegionTraits(port);
+
+ /*
+ _afpDataStream.startOverlay(mpts2units(view.getX())
+ , mpts2units(view.getY())
+ , mpts2units(view.getWidth())
+ , mpts2units(view.getHeight())
+ , rotation);
+ */
+
+ pushViewPortPos(new ViewPortPos(view, regionReference.getCTM()));
+
+ if (regionReference.getRegionClass() == FO_REGION_BODY) {
+ renderBodyRegion((BodyRegion) regionReference);
+ } else {
+ renderRegion(regionReference);
+ }
+ /*
+ _afpDataStream.endOverlay();
+ */
+ popViewPortPos();
+ }
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
+ */
+ protected void renderBlockViewport(BlockViewport bv, List children) {
+ // clip and position viewport if necessary
+
+ // save positions
+ int saveIP = currentIPPosition;
+ int saveBP = currentBPPosition;
+ //String saveFontName = currentFontName;
+
+ CTM ctm = bv.getCTM();
+ int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
+ int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
+ float x, y;
+ x = (float)(bv.getXOffset() + containingIPPosition) / 1000f;
+ y = (float)(bv.getYOffset() + containingBPPosition) / 1000f;
+ //This is the content-rect
+ float width = (float)bv.getIPD() / 1000f;
+ float height = (float)bv.getBPD() / 1000f;
+
+
+ if (bv.getPositioning() == Block.ABSOLUTE
+ || bv.getPositioning() == Block.FIXED) {
+
+ currentIPPosition = bv.getXOffset();
+ currentBPPosition = bv.getYOffset();
+
+ //For FIXED, we need to break out of the current viewports to the
+ //one established by the page. We save the state stack for restoration
+ //after the block-container has been painted. See below.
+ List breakOutList = null;
+ if (bv.getPositioning() == Block.FIXED) {
+ breakOutList = breakOutOfStateStack();
+ }
+
+ CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
+ ctm = tempctm.multiply(ctm);
+
+ //Adjust for spaces (from margin or indirectly by start-indent etc.
+ x += bv.getSpaceStart() / 1000f;
+ currentIPPosition += bv.getSpaceStart();
+
+ y += bv.getSpaceBefore() / 1000f;
+ currentBPPosition += bv.getSpaceBefore();
+
+ float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
+ float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
+
+ drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
+
+ //Now adjust for border/padding
+ currentIPPosition += borderPaddingStart;
+ currentBPPosition += borderPaddingBefore;
+
+ Rectangle2D clippingRect = null;
+ clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
+ bv.getIPD(), bv.getBPD());
+
+ // startVParea(ctm, clippingRect);
+ pushViewPortPos(new ViewPortPos(clippingRect, ctm));
+ currentIPPosition = 0;
+ currentBPPosition = 0;
+ renderBlocks(bv, children);
+ //endVParea();
+ popViewPortPos();
+
+ if (breakOutList != null) {
+ restoreStateStackAfterBreakOut(breakOutList);
+ }
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+ } else {
+
+ currentBPPosition += bv.getSpaceBefore();
+
+ //borders and background in the old coordinate system
+ handleBlockTraits(bv);
+
+ //Advance to start of content area
+ currentIPPosition += bv.getStartIndent();
+
+ CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
+ ctm = tempctm.multiply(ctm);
+
+ //Now adjust for border/padding
+ currentBPPosition += borderPaddingBefore;
+
+ Rectangle2D clippingRect = null;
+ clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
+ bv.getIPD(), bv.getBPD());
+
+ //startVParea(ctm, clippingRect);
+ pushViewPortPos(new ViewPortPos(clippingRect, ctm));
+
+ currentIPPosition = 0;
+ currentBPPosition = 0;
+ renderBlocks(bv, children);
+ //endVParea();
+ popViewPortPos();
+
+ currentIPPosition = saveIP;
+ currentBPPosition = saveBP;
+
+ currentBPPosition += (int)(bv.getAllocBPD());
+ }
+ //currentFontName = saveFontName;
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#renderPage(PageViewport)
+ */
+ public void renderPage(PageViewport page) {
+
+ // initializeRootExtensions(page);
+
+ _currentFontFamily = "";
+ _currentFontSize = 0;
+ _pageFontCounter = 0;
+ _currentPageFonts.clear();
+ _lineCache = new HashSet();
+
+ Rectangle2D bounds = page.getViewArea();
+
+ _pageWidth = mpts2units(bounds.getWidth());
+ _pageHeight = mpts2units(bounds.getHeight());
+
+ if (_pages != null && _pages.containsKey(page)) {
+
+ _afpDataStream.restorePage((PageObject)_pages.remove(page));
+
+ } else {
+ // renderPageGroupExtensions(page);
+
+ _afpDataStream.startPage(_pageWidth, _pageHeight, 0);
+
+ renderPageObjectExtensions(page);
+
+ }
+
+ pushViewPortPos(new ViewPortPos());
+
+ renderPageAreas(page.getPage());
+
+ Iterator i = _currentPageFonts.values().iterator();
+ while (i.hasNext()) {
+ AFPFontAttributes afpFontAttributes = (AFPFontAttributes) i.next();
+
+ _afpDataStream.createFont(
+ afpFontAttributes.getFontReference(),
+ afpFontAttributes.getFont(),
+ afpFontAttributes.getPointSize());
+
+ }
+
+ try {
+ _afpDataStream.endPage();
+ } catch (IOException ioex) {
+ // TODO What shall we do?
+ }
+
+ popViewPortPos();
+
+ }
+
+ /**
+ * Clip using the current path.
+ * @see org.apache.fop.render.AbstractRenderer#clip
+ */
+ public void clip() {
+ // TODO
+ }
+
+ /**
+ * Clip using a rectangular area.
+ * @see org.apache.fop.render.AbstractRenderer#clipRect(float, float, float, float)
+ */
+ public void clipRect(float x, float y, float width, float height) {
+ // TODO
+ }
+
+ /**
+ * Moves the current point to (x, y), omitting any connecting line segment.
+ * @see org.apache.fop.render.AbstractRenderer#moveTo(float, float)
+ */
+ public void moveTo(float x, float y) {
+ // TODO
+ }
+
+ /**
+ * Appends a straight line segment from the current point to (x, y). The
+ * new current point is (x, y).
+ * @see org.apache.fop.render.AbstractRenderer#lineTo(float, float)
+ */
+ public void lineTo(float x, float y) {
+ // TODO
+ }
+
+ /**
+ * Closes the current subpath by appending a straight line segment from
+ * the current point to the starting point of the subpath.
+ * @see org.apache.fop.render.AbstractRenderer#closePath
+ */
+ public void closePath() {
+ // TODO
+ }
+
+ /**
+ * Fill a rectangular area.
+ * @see org.apache.fop.render.AbstractRenderer#fillRect(float, float, float, float)
+ */
+ public void fillRect(float x, float y, float width, float height) {
+ /*
+ _afpDataStream.createShading(
+ pts2units(x),
+ pts2units(y),
+ pts2units(width),
+ pts2units(height),
+ _currentColor.getRed(),
+ _currentColor.getGreen(),
+ _currentColor.getBlue());
+ */
+ _afpDataStream.createLine(
+ pts2units(x),
+ pts2units(y),
+ pts2units(x + width),
+ pts2units(y),
+ pts2units(height),
+ _currentColor);
+ }
+
+ /**
+ * Draw a border segment of an XSL-FO style border.
+ * @see org.apache.fop.render.AbstractRenderer#drawBorderLine(float, float, float, float,
+ * boolean, boolean, int, Color)
+ */
+ public void drawBorderLine(float x1, float y1, float x2, float y2,
+ boolean horz, boolean startOrBefore, int style, Color col) {
+ float w = x2 - x1;
+ float h = y2 - y1;
+ if ((w < 0) || (h < 0)) {
+ log.error("Negative extent received. Border won't be painted.");
+ return;
+ }
+ switch (style) {
+ case Constants.EN_DOUBLE:
+ if (horz) {
+ float h3 = h / 3;
+ float ym1 = y1;
+ float ym2 = ym1 + h3 + h3;
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1),
+ pts2units(x2),
+ pts2units(ym1),
+ pts2units(h3),
+ col
+ );
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym2),
+ pts2units(x2),
+ pts2units(ym2),
+ pts2units(h3),
+ col
+ );
+ } else {
+ float w3 = w / 3;
+ float xm1 = x1;
+ float xm2 = xm1 + w3 + w3;
+ _afpDataStream.createLine(
+ pts2units(xm1),
+ pts2units(y1),
+ pts2units(xm1),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
+ _afpDataStream.createLine(
+ pts2units(xm2),
+ pts2units(y1),
+ pts2units(xm2),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
+ }
+ break;
+ case Constants.EN_DASHED:
+ if (horz) {
+ float w2 = 2 * h;
+ while (x1 + w2 < x2) {
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1 + w2),
+ pts2units(y1),
+ pts2units(h),
+ col
+ );
+ x1 += 2 * w2;
+ }
+ } else {
+ float h2 = 2 * w;
+ while (y1 + h2 < y2) {
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1),
+ pts2units(y1 + h2),
+ pts2units(w),
+ col
+ );
+ y1 += 2 * h2;
+ }
+ }
+ break;
+ case Constants.EN_DOTTED:
+ if (horz) {
+ while (x1 + h < x2) {
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1 + h),
+ pts2units(y1),
+ pts2units(h),
+ col
+ );
+ x1 += 2 * h;
+ }
+ } else {
+ while (y1 + w < y2) {
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(x1),
+ pts2units(y1 + w),
+ pts2units(w),
+ col
+ );
+ y1 += 2 * w;
+ }
+ }
+ break;
+ case Constants.EN_GROOVE:
+ case Constants.EN_RIDGE:
+ {
+ float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
+ if (horz) {
+ Color uppercol = lightenColor(col, -colFactor);
+ Color lowercol = lightenColor(col, colFactor);
+ float h3 = h / 3;
+ float ym1 = y1;
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1),
+ pts2units(x2),
+ pts2units(ym1),
+ pts2units(h3),
+ uppercol
+ );
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1 + h3),
+ pts2units(x2),
+ pts2units(ym1 + h3),
+ pts2units(h3),
+ col
+ );
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(ym1 + h3 + h3),
+ pts2units(x2),
+ pts2units(ym1 + h3 + h3),
+ pts2units(h3),
+ lowercol
+ );
+ } else {
+ Color leftcol = lightenColor(col, -colFactor);
+ Color rightcol = lightenColor(col, colFactor);
+ float w3 = w / 3;
+ float xm1 = x1 + (w3 / 2);
+ _afpDataStream.createLine(
+ pts2units(xm1),
+ pts2units(y1),
+ pts2units(xm1),
+ pts2units(y2),
+ pts2units(w3),
+ leftcol
+ );
+ _afpDataStream.createLine(
+ pts2units(xm1 + w3),
+ pts2units(y1),
+ pts2units(xm1 + w3),
+ pts2units(y2),
+ pts2units(w3),
+ col
+ );
+ _afpDataStream.createLine(
+ pts2units(xm1 + w3 + w3),
+ pts2units(y1),
+ pts2units(xm1 + w3 + w3),
+ pts2units(y2),
+ pts2units(w3),
+ rightcol
+ );
+ }
+ break;
+ }
+ case Constants.EN_HIDDEN:
+ break;
+ case Constants.EN_INSET:
+ case Constants.EN_OUTSET:
+ default:
+ _afpDataStream.createLine(
+ pts2units(x1),
+ pts2units(y1),
+ pts2units(horz ? x2 : x1),
+ pts2units(horz ? y1 : y2),
+ pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))),
+ col
+ );
+ }
+ }
+
+ /**
+ * @see org.apache.fop.render.PrintRenderer#createRendererContext(
+ * int, int, int, int, java.util.Map)
+ */
+ protected RendererContext createRendererContext(int x, int y, int width, int height, Map foreignAttributes) {
+ RendererContext context;
+ context = super.createRendererContext(x, y, width, height, foreignAttributes);
+ context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE,
+ new Boolean(!this.colorImages));
+ return context;
+ }
+
+ /**
+ * Draw an image at the indicated location.
+ * @see org.apache.fop.render.AbstractRenderer#drawImage(String, Rectangle2D, Map)
+ */
+ public void drawImage(String url, Rectangle2D pos, Map foreignAttributes) {
+ String name = null;
+ if (_pageSegmentsMap != null) {
+ name = (String)_pageSegmentsMap.get(url);
+ }
+ if (name != null) {
+ int x = mpts2units(pos.getX() + currentIPPosition);
+ int y = mpts2units(pos.getY() + currentBPPosition);
+ _afpDataStream.createIncludePageSegment(name, x, y);
+ } else {
+ url = ImageFactory.getURL(url);
+ ImageFactory fact = userAgent.getFactory().getImageFactory();
+ FopImage fopimage = fact.getImage(url, userAgent);
+ if (fopimage == null) {
+ return;
+ }
+ if (!fopimage.load(FopImage.DIMENSIONS)) {
+ return;
+ }
+ String mime = fopimage.getMimeType();
+ if ("text/xml".equals(mime) || MimeConstants.MIME_SVG.equals(mime)) {
+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+ return;
+ }
+ Document doc = ((XMLImage) fopimage).getDocument();
+ String ns = ((XMLImage) fopimage).getNameSpace();
+
+ renderDocument(doc, ns, pos, foreignAttributes);
+ } else if (MimeConstants.MIME_EPS.equals(mime)) {
+ log.warn("EPS images are not supported by this renderer");
+ /*
+ } else if (MimeConstants.MIME_JPEG.equals(mime)) {
+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+ return;
+ }
+ fact.releaseImage(url, userAgent);
+
+ int x = mpts2units(pos.getX() + currentIPPosition);
+ int y = mpts2units(pos.getY() + currentBPPosition);
+ int w = mpts2units(pos.getWidth());
+ int h = mpts2units(pos.getHeight());
+ ImageObject io = _afpDataStream.getImageObject();
+ io.setImageViewport(x, y, w, h);
+ io.setImageParameters(
+ (int)(fopimage.getHorizontalResolution() * 10),
+ (int)(fopimage.getVerticalResolution() * 10),
+ fopimage.getWidth(),
+ fopimage.getHeight()
+ );
+ io.setImageIDESize((byte)fopimage.getBitsPerPixel());
+ io.setImageEncoding((byte)0x83);
+ io.setImageData(fopimage.getRessourceBytes());
+ */
+ } else if (MimeConstants.MIME_TIFF.equals(mime)
+ && fopimage instanceof TIFFImage) {
+ TIFFImage tiffImage = (TIFFImage) fopimage;
+ int x = mpts2units(pos.getX() + currentIPPosition);
+ int y = mpts2units(pos.getY() + currentBPPosition);
+ int w = mpts2units(pos.getWidth());
+ int h = mpts2units(pos.getHeight());
+ ImageObject io = _afpDataStream.getImageObject(x, y, w, h);
+ io.setImageParameters(
+ (int)(fopimage.getHorizontalResolution() * 10),
+ (int)(fopimage.getVerticalResolution() * 10),
+ fopimage.getWidth(),
+ fopimage.getHeight()
+ );
+ if (tiffImage.getStripCount() == 1) {
+ int comp = tiffImage.getCompression();
+ if (comp == 3) {
+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+ return;
+ }
+ io.setImageEncoding((byte)0x81);
+ io.setImageData(fopimage.getRessourceBytes());
+ } else if (comp == 4) {
+ if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
+ return;
+ }
+ io.setImageEncoding((byte)0x82);
+ io.setImageData(fopimage.getRessourceBytes());
+ } else {
+ if (!fopimage.load(FopImage.BITMAP)) {
+ return;
+ }
+ convertToGrayScaleImage(io, fopimage.getBitmaps());
+ }
+ } else {
+ if (!fopimage.load(FopImage.BITMAP)) {
+ return;
+ }
+ convertToGrayScaleImage(io, fopimage.getBitmaps());
+ }
+ } else {
+ if (!fopimage.load(FopImage.BITMAP)) {
+ return;
+ }
+ fact.releaseImage(url, userAgent);
+
+ int x = mpts2units(pos.getX() + currentIPPosition);
+ int y = mpts2units(pos.getY() + currentBPPosition);
+ int w = mpts2units(pos.getWidth());
+ int h = mpts2units(pos.getHeight());
+ ImageObject io = _afpDataStream.getImageObject(x, y, w, h);
+ io.setImageParameters(
+ (int)(fopimage.getHorizontalResolution() * 10),
+ (int)(fopimage.getVerticalResolution() * 10),
+ fopimage.getWidth(),
+ fopimage.getHeight()
+ );
+ if (colorImages) {
+ io.setImageIDESize((byte)24);
+ io.setImageData(fopimage.getBitmaps());
+ } else {
+ convertToGrayScaleImage(io, fopimage.getBitmaps());
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes a BufferedImage to an OutputStream as raw sRGB bitmaps.
+ * @param img the BufferedImage
+ * @param out the OutputStream
+ * @throws IOException In case of an I/O error.
+ */
+ public static void writeImage(BufferedImage img, OutputStream out) throws IOException {
+ int w = img.getWidth();
+ int h = img.getHeight();
+ int[] tmpMap = img.getRGB(0, 0, w, h, null, 0, w);
+ for (int i = 0; i < h; i++) {
+ for (int j = 0; j < w; j++) {
+ int p = tmpMap[i * w + j];
+ int r = (p >> 16) & 0xFF;
+ int g = (p >> 8) & 0xFF;
+ int b = (p) & 0xFF;
+ out.write((byte)(r & 0xFF));
+ out.write((byte)(g & 0xFF));
+ out.write((byte)(b & 0xFF));
+ }
+ }
+ }
+
+ /**
+ * Draws a BufferedImage to AFP.
+ * @param bi the BufferedImage
+ * @param resolution the resolution of the BufferedImage
+ * @param x the x coordinate (in mpt)
+ * @param y the y coordinate (in mpt)
+ * @param w the width of the viewport (in mpt)
+ * @param h the height of the viewport (in mpt)
+ */
+ public void drawBufferedImage(BufferedImage bi, int resolution, int x, int y, int w, int h) {
+ int afpx = mpts2units(x);
+ int afpy = mpts2units(y);
+ int afpw = mpts2units(w);
+ int afph = mpts2units(h);
+ ByteArrayOutputStream baout = new ByteArrayOutputStream();
+ try {
+ //Serialize image
+ writeImage(bi, baout);
+ byte[] buf = baout.toByteArray();
+
+ //Generate image
+ ImageObject io = _afpDataStream.getImageObject(afpx, afpy, afpw, afph);
+ io.setImageParameters(
+ resolution, resolution,
+ bi.getWidth(),
+ bi.getHeight()
+ );
+ if (colorImages) {
+ io.setImageIDESize((byte)24);
+ io.setImageData(buf);
+ } else {
+ //TODO Teach it how to handle grayscale BufferedImages directly
+ //because this is pretty inefficient
+ convertToGrayScaleImage(io, buf);
+ }
+ } catch (IOException ioe) {
+ log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
+ }
+ }
+
+ /**
+ * Establishes a new foreground or fill color.
+ * @see org.apache.fop.render.AbstractRenderer#updateColor(Color, boolean)
+ */
+ public void updateColor(Color col, boolean fill) {
+ if (fill) {
+ _currentColor = col;
+ }
+ }
+
+ /**
+ * Restores the state stack after a break out.
+ * @param breakOutList the state stack to restore.
+ */
+ public void restoreStateStackAfterBreakOut(List breakOutList) {
+
+ }
+
+ /**
+ * Breaks out of the state stack to handle fixed block-containers.
+ * @return the saved state stack to recreate later
+ */
+ public List breakOutOfStateStack() {
+ return null;
+ }
+
+ /** Saves the graphics state of the rendering engine. */
+ public void saveGraphicsState() {
+
+ }
+
+ /** Restores the last graphics state of the rendering engine. */
+ public void restoreGraphicsState() {
+
+ }
+
+ /** Indicates the beginning of a text object. */
+ public void beginTextObject() {
+
+ }
+
+ /** Indicates the end of a text object. */
+ public void endTextObject() {
+
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#renderImage(Image, Rectangle2D)
+ */
+ public void renderImage(Image image, Rectangle2D pos) {
+ String url = image.getURL();
+ drawImage(url, pos);
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
+ */
+ public void renderText(TextArea text) {
+ renderInlineAreaBackAndBorders(text);
+
+ String name = getInternalFontNameForArea(text);
+ _currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
+ AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
+
+ Color col = (Color) text.getTrait(Trait.COLOR);
+
+ int vsci = mpts2units(tf.getWidth(' ', _currentFontSize) / 1000
+ + text.getTextWordSpaceAdjust()
+ + text.getTextLetterSpaceAdjust());
+
+ // word.getOffset() = only height of text itself
+ // currentBlockIPPosition: 0 for beginning of line; nonzero
+ // where previous line area failed to take up entire allocated space
+ int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
+ int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
+
+ // Set letterSpacing
+ //float ls = fs.getLetterSpacing() / this.currentFontSize;
+
+ String worddata = text.getText();
+
+ // Create an AFPFontAttributes object from the current font details
+ AFPFontAttributes afpFontAttributes =
+ new AFPFontAttributes(name, tf, _currentFontSize);
+
+ if (!_currentPageFonts.containsKey(afpFontAttributes.getFontKey())) {
+ // Font not found on current page, so add the new one
+ _pageFontCounter++;
+ afpFontAttributes.setFontReference(_pageFontCounter);
+ _currentPageFonts.put(
+ afpFontAttributes.getFontKey(),
+ afpFontAttributes);
+
+ } else {
+ // Use the previously stored font attributes
+ afpFontAttributes =
+ (AFPFontAttributes) _currentPageFonts.get(
+ afpFontAttributes.getFontKey());
+ }
+
+ // Try and get the encoding to use for the font
+ String encoding = null;
+
+ try {
+ encoding = tf.getCharacterSet(_currentFontSize).getEncoding();
+ } catch (Throwable ex) {
+ encoding = AFPConstants.EBCIDIC_ENCODING;
+ log.warn(
+ "renderText():: Error getting encoding for font "
+ + " - using default encoding "
+ + encoding);
+ }
+
+ try {
+ _afpDataStream.createText(
+ afpFontAttributes.getFontReference(),
+ mpts2units(rx),
+ mpts2units(bl),
+ col,
+ vsci,
+ mpts2units(text.getTextLetterSpaceAdjust()),
+ worddata.getBytes(encoding));
+ } catch (UnsupportedEncodingException usee) {
+ log.error(
+ "renderText:: Font "
+ + afpFontAttributes.getFontKey()
+ + " caused UnsupportedEncodingException");
+ }
+
+ super.renderText(text);
+
+ renderTextDecoration(tf, _currentFontSize, text, bl, rx);
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#renderWord(WordArea)
+ */
+ public void renderWord(WordArea word) {
+ String name = getInternalFontNameForArea(word.getParentArea());
+ int size = ((Integer) word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
+ AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
+
+ String s = word.getWord();
+
+ FontMetrics metrics = fontInfo.getMetricsFor(name);
+
+ super.renderWord(word);
+ }
+
+ /**
+ * @see org.apache.fop.render.AbstractRenderer#renderSpace(SpaceArea)
+ */
+ public void renderSpace(SpaceArea space) {
+ String name = getInternalFontNameForArea(space.getParentArea());
+ int size = ((Integer) space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
+ AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
+
+ String s = space.getSpace();
+
+ FontMetrics metrics = fontInfo.getMetricsFor(name);
+
+ super.renderSpace(space);
+ }
+
+ /**
+ * Render leader area.
+ * This renders a leader area which is an area with a rule.
+ * @param area the leader area to render
+ */
+ public void renderLeader(Leader area) {
+ renderInlineAreaBackAndBorders(area);
+
+ int style = area.getRuleStyle();
+ float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
+ float starty = (currentBPPosition + area.getOffset()) / 1000f;
+ float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart()
+ + area.getIPD()) / 1000f;
+ float ruleThickness = area.getRuleThickness() / 1000f;
+ Color col = (Color)area.getTrait(Trait.COLOR);
+
+ switch (style) {
+ case EN_SOLID:
+ case EN_DASHED:
+ case EN_DOUBLE:
+ case EN_DOTTED:
+ case EN_GROOVE:
+ case EN_RIDGE:
+ drawBorderLine(startx, starty, endx, starty + ruleThickness,
+ true, true, style, col);
+ break;
+ default:
+ throw new UnsupportedOperationException("rule style not supported");
+ }
+ super.renderLeader(area);
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#setProducer(String)
+ */
+ public void setProducer(String producer) {
+ _afpDataStream.setProducer(producer);
+ }
+
+ /**
+ * @see org.apache.fop.render.Renderer#setOptions(Map)
+ */
+ public void setOptions(Map options) {
+
+ _afpOptions = options;
+
+ }
+
+ /**
+ * Determines the orientation from the string representation, this method
+ * guarantees to return a value of either 0, 90, 180 or 270.
+ *
+ * @return the orientation
+ */
+ private int getOrientation(String orientationString) {
+
+ int orientation = 0;
+ if (orientationString != null && orientationString.length() > 0) {
+ try {
+ orientation = Integer.parseInt(orientationString);
+ } catch (NumberFormatException nfe) {
+ log.error(
+ "Cannot use orientation of "
+ + orientation
+ + " defaulting to zero.");
+ orientation = 0;
+ }
+ } else {
+ orientation = 0;
+ }
+ switch (orientation) {
+ case 0 :
+ break;
+ case 90 :
+ break;
+ case 180 :
+ break;
+ case 270 :
+ break;
+ default :
+ log.error(
+ "Cannot use orientation of "
+ + orientation
+ + " defaulting to zero.");
+ orientation = 0;
+ break;
+ }
+
+ return orientation;
+
+ }
+
+ /**
+ * Sets the rotation to be used for portrait pages, valid values are 0
+ * (default), 90, 180, 270.
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setPortraitRotation(int rotation) {
+
+ if (rotation == 0
+ || rotation == 90
+ || rotation == 180
+ || rotation == 270) {
+ _portraitRotation = rotation;
+ } else {
+ throw new IllegalArgumentException("The portrait rotation must be one"
+ + " of the values 0, 90, 180, 270");
+
+ }
+
+ }
+
+ /**
+ * Sets the rotation to be used for landsacpe pages, valid values are 0, 90,
+ * 180, 270 (default).
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setLandscapeRotation(int rotation) {
+
+ if (rotation == 0
+ || rotation == 90
+ || rotation == 180
+ || rotation == 270) {
+ _landscapeRotation = rotation;
+ } else {
+ throw new IllegalArgumentException("The landscape rotation must be one"
+ + " of the values 0, 90, 180, 270");
+ }
+
+ }
+
+ /**
+ * Get the MIME type of the renderer.
+ *
+ * @return The MIME type of the renderer
+ */
+ public String getMimeType() {
+ return MimeConstants.MIME_AFP;
+ }
+
+ /**
+ * Method to render the page extension.
+ * <p>
+ *
+ * @param page
+ * the page object
+ */
+ private void renderPageObjectExtensions(PageViewport page) {
+
+ _pageSegmentsMap = null;
+ if (page.getExtensionAttachments() != null
+ && page.getExtensionAttachments().size() > 0) {
+ //Extract all AFPPageSetup instances from the attachment list on the s-p-m
+ Iterator i = page.getExtensionAttachments().iterator();
+ while (i.hasNext()) {
+ ExtensionAttachment attachment = (ExtensionAttachment)i.next();
+ if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) {
+ AFPPageSetup aps = (AFPPageSetup)attachment;
+ String element = aps.getElementName();
+ if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) {
+ String overlay = aps.getName();
+ if (overlay != null) {
+ _afpDataStream.createIncludePageOverlay(overlay);
+ }
+ } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(element)) {
+ String name = aps.getName();
+ String source = aps.getValue();
+ if (_pageSegmentsMap == null) {
+ _pageSegmentsMap = new HashMap();
+ }
+ _pageSegmentsMap.put(source, name);
+ } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(element)) {
+ String name = aps.getName();
+ String value = aps.getValue();
+ if (_pageSegmentsMap == null) {
+ _pageSegmentsMap = new HashMap();
+ }
+ _afpDataStream.createTagLogicalElement(name, value);
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Converts FOP mpt measurement to afp measurement units
+ * @param mpt the millipoints value
+ */
+ private int mpts2units(int mpt) {
+ return mpts2units((double) mpt);
+ }
+
+ /**
+ * Converts FOP pt measurement to afp measurement units
+ * @param mpt the millipoints value
+ */
+ private int pts2units(float mpt) {
+ return mpts2units(mpt * 1000d);
+ }
+
+ /**
+ * Converts FOP mpt measurement to afp measurement units
+ * @param mpt the millipoints value
+ */
+ private int mpts2units(double mpt) {
+ return (int)Math.round(mpt / DPI_CONVERSION_FACTOR_240);
+ }
+
+ private void convertToGrayScaleImage(ImageObject io, byte raw[]) {
+ int pixelsPerByte = 8 / bitsPerPixel;
+ byte bw[] = new byte[raw.length / (3 * pixelsPerByte)];
+ int k = 0;
+ for (int i = 0, j = 0; i < raw.length; i += 3, j++) {
+ if (j == pixelsPerByte) {
+ j = 0;
+ k++;
+ }
+ // see http://www.jguru.com/faq/view.jsp?EID=221919
+ double greyVal = 0.212671d * ((int) raw[i] & 0xff)
+ + 0.715160d * ((int) raw[i + 1] & 0xff)
+ + 0.072169d * ((int) raw[i + 2] & 0xff);
+ switch (bitsPerPixel) {
+ case 1:
+ if (greyVal > 128) {
+ bw[k] |= (byte)(1 << j);
+ }
+ break;
+ case 4:
+ greyVal /= 16;
+ bw[k] |= (byte)((byte)greyVal << (j * 4));
+ break;
+ case 8:
+ bw[k] = (byte)greyVal;
+ break;
+ }
+ }
+ io.setImageIDESize((byte)bitsPerPixel);
+ io.setImageData(bw);
+ }
+
+ private class ViewPortPos {
+ int x = 0;
+ int y = 0;
+ int rot = 0;
+
+ ViewPortPos() {
+ }
+
+ ViewPortPos(Rectangle2D view, CTM ctm) {
+ ViewPortPos currentVP = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
+ int xOrigin;
+ int yOrigin;
+ int width;
+ int height;
+ switch (currentVP.rot) {
+ case 90:
+ width = mpts2units(view.getHeight());
+ height = mpts2units(view.getWidth());
+ xOrigin = _pageWidth - width - mpts2units(view.getY()) - currentVP.y;
+ yOrigin = mpts2units(view.getX()) + currentVP.x;
+ break;
+ case 180:
+ width = mpts2units(view.getWidth());
+ height = mpts2units(view.getHeight());
+ xOrigin = _pageWidth - width - mpts2units(view.getX()) - currentVP.x;
+ yOrigin = _pageHeight - height - mpts2units(view.getY()) - currentVP.y;
+ break;
+ case 270:
+ width = mpts2units(view.getHeight());
+ height = mpts2units(view.getWidth());
+ xOrigin = mpts2units(view.getY()) + currentVP.y;
+ yOrigin = _pageHeight - height - mpts2units(view.getX()) - currentVP.x;
+ break;
+ default:
+ xOrigin = mpts2units(view.getX()) + currentVP.x;
+ yOrigin = mpts2units(view.getY()) + currentVP.y;
+ width = mpts2units(view.getWidth());
+ height = mpts2units(view.getHeight());
+ break;
+ }
+ this.rot = currentVP.rot;
+ double ctmf[] = ctm.toArray();
+ if (ctmf[0] == 0.0d && ctmf[1] == -1.0d && ctmf[2] == 1.0d && ctmf[3] == 0.d) {
+ this.rot += 270;
+ } else if (ctmf[0] == -1.0d && ctmf[1] == 0.0d && ctmf[2] == 0.0d && ctmf[3] == -1.0d) {
+ this.rot += 180;
+ } else if (ctmf[0] == 0.0d && ctmf[1] == 1.0d && ctmf[2] == -1.0d && ctmf[3] == 0.0d) {
+ this.rot += 90;
+ }
+ this.rot %= 360;
+ switch (this.rot) {
+ /*
+ case 0:
+ this.x = mpts2units(view.getX()) + x;
+ this.y = mpts2units(view.getY()) + y;
+ break;
+ case 90:
+ this.x = mpts2units(view.getY()) + y;
+ this.y = _pageWidth - mpts2units(view.getX() + view.getWidth()) - x;
+ break;
+ case 180:
+ this.x = _pageWidth - mpts2units(view.getX() + view.getWidth()) - x;
+ this.y = _pageHeight - mpts2units(view.getY() + view.getHeight()) - y;
+ break;
+ case 270:
+ this.x = _pageHeight - mpts2units(view.getY() + view.getHeight()) - y;
+ this.y = mpts2units(view.getX()) + x;
+ break;
+ */
+ case 0:
+ this.x = xOrigin;
+ this.y = yOrigin;
+ break;
+ case 90:
+ this.x = yOrigin;
+ this.y = _pageWidth - width - xOrigin;
+ break;
+ case 180:
+ this.x = _pageWidth - width - xOrigin;
+ this.y = _pageHeight - height - yOrigin;
+ break;
+ case 270:
+ this.x = _pageHeight - height - yOrigin;
+ this.y = xOrigin;
+ break;
+ }
+ }
+
+ public String toString() {
+ return "x:" + x + " y:" + y + " rot:" + rot;
+ }
+
+ }
+
+ private List viewPortPositions = new ArrayList();
+
+ private void pushViewPortPos(ViewPortPos vpp) {
+ viewPortPositions.add(vpp);
+ _afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
+ }
+
+ private void popViewPortPos() {
+ viewPortPositions.remove(viewPortPositions.size() - 1);
+ if (viewPortPositions.size() > 0) {
+ ViewPortPos vpp = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
+ _afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
+ }
+ }
+
+}
+
--- /dev/null
+/*\r
+ * Copyright 2006 The Apache Software Foundation.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id$ */\r
+\r
+package org.apache.fop.render.afp;\r
+\r
+import org.apache.fop.render.RendererContextConstants;\r
+\r
+/**\r
+ * Defines a number of standard constants (keys) for use by the RendererContext class.\r
+ */\r
+public interface AFPRendererContextConstants extends RendererContextConstants {\r
+\r
+ /**\r
+ * Key for a Boolean value that enables grayscale processing instead of color \r
+ * processing.\r
+ */\r
+ String AFP_GRAYSCALE = "afpGrayscale";\r
+\r
+}\r
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.AbstractRendererMaker;
+import org.apache.fop.render.Renderer;
+
+/**
+ * RendererMaker for the AFP Renderer.
+ */
+public class AFPRendererMaker extends AbstractRendererMaker {
+
+ private static final String[] MIMES = new String[] {
+ MimeConstants.MIME_AFP,
+ MimeConstants.MIME_AFP_ALT};
+
+
+ /**@see org.apache.fop.render.AbstractRendererMaker */
+ public Renderer makeRenderer(FOUserAgent ua) {
+ return new AFPRenderer();
+ }
+
+ /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
+ public boolean needsOutputStream() {
+ return true;
+ }
+
+ /** @see org.apache.fop.render.AbstractRendererMaker#getSupportedMimeTypes() */
+ public String[] getSupportedMimeTypes() {
+ return MIMES;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+// FOP
+import org.apache.fop.render.AbstractGenericSVGHandler;
+import org.apache.fop.render.Renderer;
+
+/**
+ * AFP XML handler for SVG. Uses Apache Batik for SVG processing.
+ * This handler handles XML for foreign objects and delegates to AFPGraphics2DAdapter.
+ * @see AFPGraphics2DAdapter
+ */
+public class AFPSVGHandler extends AbstractGenericSVGHandler {
+
+ /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
+ public boolean supportsRenderer(Renderer renderer) {
+ return (renderer instanceof AFPRenderer);
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.exceptions;
+
+/**
+ * A runtime exception for handling fatal errors in processing fonts.
+ * <p/>
+ */
+public class FontRuntimeException extends NestedRuntimeException {
+
+ /**
+ * Constructs a FontRuntimeException with the specified message.
+ * @param msg the exception mesaage
+ */
+ public FontRuntimeException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a FontRuntimeException with the specified message
+ * wrapping the underlying exception.
+ * @param msg the exception mesaage
+ * @param t the underlying exception
+ */
+ public FontRuntimeException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.exceptions;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * Handy class for wrapping runtime Exceptions with a root cause.
+ * This technique is no longer necessary in Java 1.4, which provides
+ * built-in support for exception nesting. Thus exceptions in applications
+ * written to use Java 1.4 need not extend this class.
+ *
+ */
+public abstract class NestedRuntimeException extends RuntimeException {
+
+ /** Root cause of this nested exception */
+ private Throwable _underlyingException;
+
+ /**
+ * Construct a <code>NestedRuntimeException</code> with the specified detail message.
+ * @param msg The detail message.
+ */
+ public NestedRuntimeException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Construct a <code>NestedRuntimeException</code> with the specified
+ * detail message and nested exception.
+ * @param msg The detail message.
+ * @param t The nested exception.
+ */
+ public NestedRuntimeException(String msg, Throwable t) {
+ super(msg);
+ _underlyingException = t;
+
+ }
+
+ /**
+ * Gets the original triggering exception
+ * @return The original exception as a throwable.
+ */
+ public Throwable getUnderlyingException() {
+
+ return _underlyingException;
+
+ }
+
+ /**
+ * Return the detail message, including the message from the nested
+ * exception if there is one.
+ * @return The detail message.
+ */
+ public String getMessage() {
+
+ if (_underlyingException == null) {
+ return super.getMessage();
+ } else {
+ return super.getMessage()
+ + "; nested exception is "
+ + _underlyingException.getClass().getName();
+ }
+
+ }
+
+ /**
+ * Print the composite message and the embedded stack trace to the specified stream.
+ * @param ps the print stream
+ */
+ public void printStackTrace(PrintStream ps) {
+ if (_underlyingException == null) {
+ super.printStackTrace(ps);
+ } else {
+ ps.println(this);
+ _underlyingException.printStackTrace(ps);
+ }
+ }
+
+ /**
+ * Print the composite message and the embedded stack trace to the specified writer.
+ * @param pw the print writer
+ */
+ public void printStackTrace(PrintWriter pw) {
+ if (_underlyingException == null) {
+ super.printStackTrace(pw);
+ } else {
+ pw.println(this);
+ _underlyingException.printStackTrace(pw);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.exceptions;
+
+/**
+ * A runtime exception for handling fatal errors in rendering.
+ * <p/>
+ */
+public class RendererRuntimeException extends NestedRuntimeException {
+
+ /**
+ * Constructs a RendererRuntimeException with the specified message.
+ * @param msg the exception mesaage
+ */
+ public RendererRuntimeException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * Constructs a RendererRuntimeException with the specified message
+ * wrapping the underlying exception.
+ * @param msg the exception mesaage
+ * @param t the underlying exception
+ */
+ public RendererRuntimeException(String msg, Throwable t) {
+ super(msg, t);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.properties.Property;
+import org.apache.fop.fo.properties.StringProperty;
+
+/**
+ * This class extends the org.apache.fop.fo.StringProperty.Maker inner class
+ * in order to provide a static property maker. The object faciliates
+ * extraction of attributes from formatted objects based on the static list
+ * as defined in the AFPElementMapping implementation.
+ * <p/>
+ */
+public class AFPAttribute extends StringProperty.Maker {
+
+ /**
+ * The attribute property.
+ */
+ private Property _property;
+
+ /**
+ * Constructor for the AFPAttribute.
+ * @param name The attribute name
+ */
+ protected AFPAttribute(String name) {
+ super(0);
+ _property = null;
+ }
+
+ /**
+ * Overide the make method to return the property object
+ * @param propertyList the property list from which to make the property
+ * @return property The property object.
+ */
+ public Property make(PropertyList propertyList) {
+ if (_property == null) {
+ _property = make(propertyList, "", propertyList.getParentFObj());
+ }
+ return _property;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.XMLObj;
+
+/**
+ * This class extends the org.apache.fop.extensions.ExtensionObj class. The
+ * object faciliates extraction of elements from formatted objects based on
+ * the static list as defined in the AFPElementMapping implementation.
+ * <p/>
+ */
+public class AFPElement extends AbstractAFPExtensionObject {
+
+ /**
+ * Constructs an AFP object (called by Maker).
+ *
+ * @param parent the parent formatting object
+ * @param name the name of the afp element
+ */
+ public AFPElement(FONode parent, String name) {
+ super(parent, name);
+ }
+
+ /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
+ public String getNamespaceURI() {
+ return AFPElementMapping.NAMESPACE;
+ }
+
+ /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
+ public String getNormalNamespacePrefix() {
+ return "afp";
+ }
+
+ /** @see org.apache.fop.fo.FONode#startOfNode() */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ //if (!AFPElementMapping.NAMESPACE.equals(parent.getNamespaceURI())
+ // || !AFPElementMapping.PAGE.equals(parent.getLocalName())) {
+ // throw new ValidationException(getName() + " must be a child of afp:page.");
+ //}
+ if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
+ throw new ValidationException(getName() + " must be a child of fo:simple-page-master.");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import java.util.HashMap;
+
+import org.apache.fop.fo.ElementMapping;
+import org.apache.fop.fo.FONode;
+
+
+/**
+ * AFPElementMapping object provides the ability to extract information
+ * from the formatted object that reside in the afp namespace. This is used
+ * for custom AFP extensions not supported by the FO schema. Examples include
+ * adding overlays or indexing a document using the tag logical element
+ * structured field.
+ * <p/>
+ */
+public class AFPElementMapping extends ElementMapping {
+
+ public static final String PAGE = "page";
+
+ public static final String PAGE_GROUP = "page-group";
+
+ public static final String TAG_LOGICAL_ELEMENT = "tag-logical-element";
+
+ public static final String INCLUDE_PAGE_OVERLAY = "include-page-overlay";
+
+ public static final String INCLUDE_PAGE_SEGMENT = "include-page-segment";
+
+ /**
+ * The namespace used for AFP extensions
+ */
+ public static final String NAMESPACE = "http://xmlgraphics.apache.org/fop/extensions/afp";
+
+ /**
+ * The usual namespace prefix used for AFP extensions
+ */
+ public static final String NAMESPACE_PREFIX = "afp";
+
+ /** Main constructor */
+ public AFPElementMapping() {
+ this.namespaceURI = NAMESPACE;
+ }
+
+ /**
+ * Private static synchronized method to set up the element and atribute
+ * HashMaps, this defines what elements and attributes are extracted.
+ */
+ protected void initialize() {
+
+ if (foObjs == null) {
+ foObjs = new HashMap();
+ foObjs.put(PAGE, new AFPPageSetupMaker());
+ // foObjs.put(PAGE_GROUP, new AFPMaker());
+ foObjs.put(
+ TAG_LOGICAL_ELEMENT,
+ new AFPTagLogicalElementMaker());
+ foObjs.put(
+ INCLUDE_PAGE_SEGMENT,
+ new AFPIncludePageSegmentMaker());
+ foObjs.put(
+ INCLUDE_PAGE_OVERLAY,
+ new AFPIncludePageOverlayMaker());
+ }
+
+ }
+
+ static class AFPPageSetupMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new AFPPageSetupElement(parent);
+ }
+ }
+
+ static class AFPIncludePageOverlayMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new AFPElement(parent, INCLUDE_PAGE_OVERLAY);
+ }
+ }
+
+ static class AFPIncludePageSegmentMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new AFPElement(parent, INCLUDE_PAGE_SEGMENT);
+ }
+ }
+
+ static class AFPTagLogicalElementMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new AFPElement(parent, TAG_LOGICAL_ELEMENT);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import java.io.Serializable;
+
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+
+/**
+ * This is the pass-through value object for the PostScript extension.
+ */
+public class AFPPageSetup implements ExtensionAttachment, Serializable {
+
+ /** The category URI for this extension attachment. */
+ public static final String CATEGORY = "apache:fop:extensions:afp";
+
+ private String elementName;
+
+ private String name;
+
+ private String value;
+
+ /**
+ * Default constructor.
+ * @param name the name of the setup code object, may be null
+ */
+ public AFPPageSetup(String name) {
+ this.elementName = name;
+ }
+
+ /** @return the name */
+ public String getElementName() {
+ return elementName;
+ }
+
+ /** @return the name */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the name of the setup code object.
+ * @param name The name to set.
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value
+ * @param source The value name to set.
+ */
+ public void setValue(String source) {
+ this.value = source;
+ }
+
+ /** @see org.apache.fop.fo.extensions.ExtensionAttachment#getCategory() */
+ public String getCategory() {
+ return CATEGORY;
+ }
+
+ /** @see java.lang.Object#toString() */
+ public String toString() {
+ return "AFPPageSetup(element-name=" + getElementName() + " name=" + getName() + ")";
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.ValidationException;
+
+/**
+ * Extension element for fox:ps-page-setup-code.
+ */
+public class AFPPageSetupElement extends AbstractAFPExtensionObject {
+
+ /**
+ * Main constructor
+ * @param parent parent FO node
+ */
+ public AFPPageSetupElement(FONode parent) {
+ super(parent, "page");
+ }
+
+ /** @see org.apache.fop.fo.FONode#startOfNode() */
+ protected void startOfNode() throws FOPException {
+ super.startOfNode();
+ if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
+ throw new ValidationException(getName() + " must be a child of fo:simple-page-master.");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+// FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+/**
+ * Base class for the AFP-specific extension elements.
+ */
+public abstract class AbstractAFPExtensionObject extends FONode {
+
+ private AFPPageSetup setupCode = null;
+
+ private String _name = null;
+
+ /**
+ * @see org.apache.fop.fo.FONode#FONode(FONode)
+ * @param parent the parent formatting object
+ * @param name the name of the afp element
+ */
+ public AbstractAFPExtensionObject(FONode parent, String name) {
+ super(parent);
+ _name = name;
+ setupCode = new AFPPageSetup(name);
+ }
+
+ /**
+ * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+ * here, blocks XSL FO's from having non-FO parents.
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws ValidationException {
+ if (FO_URI.equals(nsURI)) {
+ invalidChildError(loc, nsURI, localName);
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode */
+ protected void addCharacters(char[] data, int start, int length,
+ PropertyList pList, Locator locator) {
+ }
+
+ /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
+ public String getNamespaceURI() {
+ return AFPElementMapping.NAMESPACE;
+ }
+
+ /**@see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
+ public String getNormalNamespacePrefix() {
+ return AFPElementMapping.NAMESPACE_PREFIX;
+ }
+
+ /** @see org.apache.fop.fo.FONode#processNode */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList propertyList)
+ throws FOPException {
+ String name = attlist.getValue("name");
+ if (name != null && name.length() > 0) {
+ setupCode.setName(name);
+ } else {
+ throw new FOPException(elementName + " must have a name attribute.");
+ }
+ if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) {
+ name = attlist.getValue("src");
+ if (name != null && name.length() > 0) {
+ setupCode.setValue(name);
+ } else {
+ throw new FOPException(elementName + " must have a src attribute.");
+ }
+ }
+ if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) {
+ name = attlist.getValue("value");
+ if (name != null && name.length() > 0) {
+ setupCode.setValue(name);
+ } else {
+ throw new FOPException(elementName + " must have a value attribute.");
+ }
+ }
+ }
+
+ /** @see org.apache.fop.fo.FONode#endOfNode() */
+ protected void endOfNode() throws FOPException {
+ super.endOfNode();
+ }
+
+ /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
+ public ExtensionAttachment getExtensionAttachment() {
+ return this.setupCode;
+ }
+
+ /** @see org.apache.fop.fo.FONode#getLocalName() */
+ public String getLocalName() {
+ return _name;
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+import java.util.Map;
+import org.apache.fop.fonts.FontType;
+import org.apache.fop.fonts.Typeface;
+
+
+/**
+ * All implemenations of AFP fonts should extend this base class,
+ * the object implements the FontMetrics information.
+ * <p/>
+ */
+public abstract class AFPFont extends Typeface {
+
+ /** The font name */
+ protected String _name;
+
+ /**
+ * Constructor for the base font requires the name.
+ * @param name the name of the font
+ */
+ public AFPFont(String name) {
+
+ _name = name;
+
+ }
+
+ /**
+ * @return the name of the font.
+ */
+ public String getFontName() {
+ return _name;
+ }
+
+ /**
+ * Returns the type of the font.
+ * @return the font type
+ */
+ public FontType getFontType() {
+ return FontType.OTHER;
+ }
+
+ /**
+ * Indicates if the font has kering information.
+ * @return True, if kerning is available.
+ */
+ public boolean hasKerningInfo() {
+ return false;
+ }
+
+ /**
+ * Returns the kerning map for the font.
+ * @return the kerning map
+ */
+ public Map getKerningInfo() {
+ return null;
+ }
+
+ /**
+ * Returns the character set for a given size
+ * @param size the font size
+ * @return the character set object
+ */
+ public abstract CharacterSet getCharacterSet(int size);
+
+ /**
+ * Determines whether this font contains a particular character/glyph.
+ * @param c character to check
+ * @return True if the character is supported, Falso otherwise
+ */
+ public boolean hasChar(char c) {
+ return true;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+import java.util.List;
+
+/**
+ * FontInfo contains meta information on fonts
+ */
+public class AFPFontInfo {
+
+ private AFPFont font;
+ private List fontTriplets;
+
+ /**
+ * Main constructor
+ * @param afpFont The AFP Font
+ * @param fontTriplets List of font triplets to associate with this font
+ */
+ public AFPFontInfo(AFPFont afpFont, List fontTriplets) {
+ this.font = afpFont;
+ this.fontTriplets = fontTriplets;
+ }
+
+ /**
+ * Returns the afp font
+ * @return the afp font
+ */
+ public AFPFont getAFPFont() {
+ return font;
+ }
+
+ /**
+ * Returns the list of font triplets associated with this font.
+ * @return List of font triplets
+ */
+ public List getFontTriplets() {
+ return fontTriplets;
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.exceptions.FontRuntimeException;
+import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.tools.StructuredFieldReader;
+
+/**
+ * The AFPFontReader is responsible for reading the font attributes from binary
+ * code page files and the character set metric files. In IBM font structure, a
+ * code page maps each character of text to the characters in a character set.
+ * Each character is translated into a code point. When the character is
+ * printed, each code point is matched to a character ID on the code page
+ * specified. The character ID is then matched to the image (raster pattern or
+ * outline pattern) of the character in the character set specified. The image
+ * in the character set is the image that is printed in the document. To be a
+ * valid code page for a particular character set, all character IDs in the code
+ * page must be included in that character set. <p/>This class will read the
+ * font information from the binary code page files and character set metric
+ * files in order to determine the correct metrics to use when rendering the
+ * formatted object. <p/>
+ *
+ * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
+ */
+public final class AFPFontReader {
+
+ /**
+ * Static logging instance
+ */
+ protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
+
+ /**
+ * Template used to convert lists to arrays.
+ */
+ private static final CharacterSetOrientation[] EMPTY_CSO_ARRAY = new CharacterSetOrientation[0];
+
+ /** Codepage MO:DCA structured field. */
+ private static final byte[] CODEPAGE_SF = new byte[] { (byte) 0xD3,
+ (byte) 0xA8, (byte) 0x87 };
+
+ /** Character table MO:DCA structured field. */
+ private static final byte[] CHARACTER_TABLE_SF = new byte[] { (byte) 0xD3,
+ (byte) 0x8C, (byte) 0x87 };
+
+ /** Font control MO:DCA structured field. */
+ private static final byte[] FONT_CONTROL_SF = new byte[] { (byte) 0xD3,
+ (byte) 0xA7, (byte) 0x89 };
+
+ /** Font orientation MO:DCA structured field. */
+ private static final byte[] FONT_ORIENTATION_SF = new byte[] { (byte) 0xD3,
+ (byte) 0xAE, (byte) 0x89 };
+
+ /** Font position MO:DCA structured field. */
+ private static final byte[] FONT_POSITION_SF = new byte[] { (byte) 0xD3,
+ (byte) 0xAC, (byte) 0x89 };
+
+ /** Font index MO:DCA structured field. */
+ private static final byte[] FONT_INDEX_SF = new byte[] { (byte) 0xD3,
+ (byte) 0x8C, (byte) 0x89 };
+
+ /**
+ * The conversion factor to millipoints for 240 dpi
+ */
+ private static final int FOP_100_DPI_FACTOR = 1;
+
+ /**
+ * The conversion factor to millipoints for 240 dpi
+ */
+ private static final int FOP_240_DPI_FACTOR = 300000;
+
+ /**
+ * The conversion factor to millipoints for 300 dpi
+ */
+ private static final int FOP_300_DPI_FACTOR = 240000;
+
+ /**
+ * The encoding to use to convert from EBCIDIC to ASCII
+ */
+ private static final String ASCII_ENCODING = "UTF8";
+
+ /**
+ * The collection of code pages
+ */
+ private static HashMap _codePages = new HashMap();
+
+ /**
+ * Load the font details and metrics into the CharacterSetMetric object,
+ * this will use the actual afp code page and character set files to load
+ * the object with the necessary metrics.
+ *
+ * @param characterSet the CharacterSetMetric object to populate
+ */
+ public static void loadCharacterSetMetric(CharacterSet characterSet) {
+
+ InputStream inputStream = null;
+
+ try {
+
+ /**
+ * Get the code page which contains the character mapping
+ * information to map the unicode character id to the graphic
+ * chracter global identifier.
+ */
+ String cp = new String(characterSet.getCodePage());
+ String path = characterSet.getPath();
+
+ HashMap codepage = (HashMap) _codePages.get(cp);
+
+ if (codepage == null) {
+ codepage = loadCodePage(cp, characterSet.getEncoding(), path);
+ _codePages.put(cp, codepage);
+ }
+
+ /**
+ * Load the character set metric information, no need to cache this
+ * information as it should be cached by the objects that wish to
+ * load character set metric information.
+ */
+ final String characterset = characterSet.getName();
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = AFPFontReader.class.getClassLoader();
+ }
+
+ URL url = classLoader.getResource(path);
+ if (url == null) {
+ try {
+ File file = new File(path);
+ url = file.toURL();
+ if (url == null) {
+ String msg = "CharacterSet file not found for "
+ + characterset + " in classpath: " + path;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+ } catch (MalformedURLException ex) {
+ String msg = "CharacterSet file not found for "
+ + characterset + " in classpath: " + path;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+
+ }
+
+ File directory = new File(url.getPath());
+
+ final String filterpattern = characterset.trim();
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.startsWith(filterpattern);
+ }
+ };
+
+ File[] csfont = directory.listFiles(filter);
+ if (csfont.length < 1) {
+ String msg = "CharacterSet file search for " + characterset
+ + " located " + csfont.length + " files";
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ } else if (csfont.length > 1) {
+ String msg = "CharacterSet file search for " + characterset
+ + " located " + csfont.length + " files";
+ log.warn(msg);
+ }
+
+ inputStream = inputStream = csfont[0].toURL().openStream();
+ if (inputStream == null) {
+ String msg = "Failed to open character set resource "
+ + characterset;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+
+ StructuredFieldReader sfr = new StructuredFieldReader(inputStream);
+
+ // Process D3A789 Font Control
+ FontControl fnc = processFontControl(sfr);
+
+ //process D3AE89 Font Orientation
+ CharacterSetOrientation[] csoArray = processFontOrientation(sfr);
+
+ //process D3AC89 Font Position
+ processFontPosition(sfr, csoArray, fnc.getDpi());
+
+ //process D38C89 Font Index (per orientation)
+ for (int i = 0; i < csoArray.length; i++) {
+ processFontIndex(sfr, csoArray[i], codepage, fnc.getDpi());
+ characterSet.addCharacterSetOrientation(csoArray[i]);
+ }
+
+ } catch (Exception ex) {
+ throw new FontRuntimeException(
+ "Failed to load the character set metrics for code page "
+ + characterSet.getCodePage(), ex);
+ } finally {
+ try {
+ inputStream.close();
+ } catch (Exception ex) {
+ // Ignore
+ }
+ }
+
+ }
+
+ /**
+ * Load the code page information from the appropriate file. The file name
+ * to load is determined by the code page name and the file extension 'CDP'.
+ *
+ * @param codePage
+ * the code page identifier
+ * @param encoding
+ * the encoding to use for the character decoding
+ */
+ private static HashMap loadCodePage(String codePage, String encoding,
+ String path) throws IOException, FileNotFoundException {
+
+ // Create the HashMap to store code page information
+ HashMap codepages = new HashMap();
+
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = AFPFontReader.class.getClassLoader();
+ }
+
+ URL url = classLoader.getResource(path);
+
+ if (url == null) {
+ try {
+ File file = new File(path);
+ url = file.toURL();
+ if (url == null) {
+ String msg = "CodePage file not found for " + codePage
+ + " in classpath: " + path;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+ } catch (MalformedURLException ex) {
+ String msg = "CodePage file not found for " + codePage
+ + " in classpath: " + path;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+
+ }
+
+ File directory = new File(url.getPath());
+
+ final String filterpattern = codePage.trim();
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.startsWith(filterpattern);
+ }
+ };
+
+ File[] codepage = directory.listFiles(filter);
+
+ if (codepage.length < 1) {
+ String msg = "CodePage file search for " + codePage + " located "
+ + codepage.length + " files";
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ } else if (codepage.length > 1) {
+ String msg = "CodePage file search for " + codePage + " located "
+ + codepage.length + " files";
+ log.warn(msg);
+ }
+
+ InputStream is = codepage[0].toURL().openStream();
+
+ if (is == null) {
+ String msg = "AFPFontReader:: loadCodePage(String):: code page file not found for "
+ + codePage;
+ log.error(msg);
+ throw new FileNotFoundException(msg);
+ }
+
+ StructuredFieldReader sfr = new StructuredFieldReader(is);
+ byte[] data = sfr.getNext(CHARACTER_TABLE_SF);
+
+ int position = 0;
+ byte[] gcgiBytes = new byte[8];
+ byte[] charBytes = new byte[1];
+
+ // Read data, ignoring bytes 0 - 2
+ for (int index = 3; index < data.length; index++) {
+ if (position < 8) {
+ // Build the graphic character global identifier key
+ gcgiBytes[position] = data[index];
+ position++;
+ } else if (position == 9) {
+ position = 0;
+ // Set the character
+ charBytes[0] = data[index];
+ String gcgiString = new String(gcgiBytes,
+ AFPConstants.EBCIDIC_ENCODING);
+ String charString = new String(charBytes, encoding);
+ int value = charString.charAt(0);
+ codepages.put(gcgiString, charString);
+ } else {
+ position++;
+ }
+ }
+
+ try {
+ is.close();
+ } catch (Exception ex) {
+ // Ignore
+ }
+
+ return codepages;
+
+ }
+
+ /**
+ * Process the font control details using the structured field reader.
+ *
+ * @param sfr
+ * the structured field reader
+ */
+ private static FontControl processFontControl(StructuredFieldReader sfr)
+ throws IOException {
+
+ byte[] fncData = sfr.getNext(FONT_CONTROL_SF);
+
+ int position = 0;
+
+ FontControl fontControl = new AFPFontReader().new FontControl();
+
+ if (fncData[7] == (byte) 0x02) {
+ fontControl.setRelative(true);
+ }
+
+ int dpi = (((fncData[9] & 0xFF) << 8) + (fncData[10] & 0xFF)) / 10;
+
+ fontControl.setDpi(dpi);
+
+ return fontControl;
+
+ }
+
+ /**
+ * Process the font orientation details from using the structured field
+ * reader.
+ *
+ * @param sfr
+ * the structured field reader
+ */
+ private static CharacterSetOrientation[] processFontOrientation(
+ StructuredFieldReader sfr) throws IOException {
+
+ byte[] data = sfr.getNext(FONT_ORIENTATION_SF);
+
+ int position = 0;
+ byte[] fnoData = new byte[26];
+
+ ArrayList orientations = new ArrayList();
+
+ // Read data, ignoring bytes 0 - 2
+ for (int index = 3; index < data.length; index++) {
+ // Build the font orientation record
+ fnoData[position] = data[index];
+ position++;
+
+ if (position == 26) {
+
+ position = 0;
+
+ int orientation = 0;
+
+ switch (fnoData[2]) {
+ case 0x00:
+ orientation = 0;
+ break;
+ case 0x2D:
+ orientation = 90;
+ break;
+ case 0x5A:
+ orientation = 180;
+ break;
+ case (byte) 0x87:
+ orientation = 270;
+ break;
+ default:
+ System.out.println("ERROR: Oriantation");
+ }
+
+ CharacterSetOrientation cso = new CharacterSetOrientation(
+ orientation);
+ orientations.add(cso);
+
+ }
+ }
+
+ return (CharacterSetOrientation[]) orientations
+ .toArray(EMPTY_CSO_ARRAY);
+ }
+
+ /**
+ * Populate the CharacterSetOrientation object in the suplied array with the
+ * font position details using the supplied structured field reader.
+ *
+ * @param sfr
+ * the structured field reader
+ * @param csoArray
+ * the array of CharacterSetOrientation objects
+ */
+ private static void processFontPosition(StructuredFieldReader sfr,
+ CharacterSetOrientation[] csoArray, int dpi) throws IOException {
+
+ byte[] data = sfr.getNext(FONT_POSITION_SF);
+
+ int position = 0;
+ byte[] fpData = new byte[26];
+
+ int csoIndex = 0;
+ int fopFactor = 0;
+
+ switch (dpi) {
+ case 100:
+ fopFactor = FOP_100_DPI_FACTOR;
+ break;
+ case 240:
+ fopFactor = FOP_240_DPI_FACTOR;
+ break;
+ case 300:
+ fopFactor = FOP_300_DPI_FACTOR;
+ break;
+ default:
+ String msg = "Unsupported font resolution of " + dpi + " dpi.";
+ log.error(msg);
+ throw new IOException(msg);
+ }
+
+ // Read data, ignoring bytes 0 - 2
+ for (int index = 3; index < data.length; index++) {
+ if (position < 22) {
+ // Build the font orientation record
+ fpData[position] = data[index];
+ } else if (position == 22) {
+
+ position = 0;
+
+ CharacterSetOrientation cso = csoArray[csoIndex];
+
+ int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 0xFF);
+ int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 0xFF);
+ int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 0xFF);
+ int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 0xFF);
+
+ dscHeight = dscHeight * -1;
+
+ cso.setXHeight(xHeight * fopFactor);
+ cso.setCapHeight(capHeight * fopFactor);
+ cso.setAscender(ascHeight * fopFactor);
+ cso.setDescender(dscHeight * fopFactor);
+
+ csoIndex++;
+
+ fpData[position] = data[index];
+
+ }
+
+ position++;
+ }
+
+ }
+
+ /**
+ * Process the font index details for the character set orientation.
+ *
+ * @param sfr
+ * the structured field reader
+ * @param cso
+ * the CharacterSetOrientation object to populate
+ * @param codepage
+ * the map of code pages
+ */
+ private static void processFontIndex(StructuredFieldReader sfr,
+ CharacterSetOrientation cso, HashMap codepage, int dpi)
+ throws IOException {
+
+ byte[] data = sfr.getNext(FONT_INDEX_SF);
+
+ int fopFactor = 0;
+
+ switch (dpi) {
+ case 100:
+ fopFactor = FOP_100_DPI_FACTOR;
+ break;
+ case 240:
+ fopFactor = FOP_240_DPI_FACTOR;
+ break;
+ case 300:
+ fopFactor = FOP_300_DPI_FACTOR;
+ break;
+ default:
+ String msg = "Unsupported font resolution of " + dpi + " dpi.";
+ log.error(msg);
+ throw new IOException(msg);
+ }
+
+ int position = 0;
+
+ byte[] gcgid = new byte[8];
+ byte[] fiData = new byte[20];
+
+ int lowest = 255;
+ int highest = 0;
+
+ // Read data, ignoring bytes 0 - 2
+ for (int index = 3; index < data.length; index++) {
+ if (position < 8) {
+ gcgid[position] = (byte) data[index];
+ position++;
+ } else if (position < 27) {
+ fiData[position - 8] = (byte) data[index];
+ position++;
+ } else if (position == 27) {
+
+ fiData[position - 8] = (byte) data[index];
+
+ position = 0;
+
+ String gcgiString = new String(gcgid, AFPConstants.EBCIDIC_ENCODING);
+
+ String idx = (String) codepage.get(gcgiString);
+
+ if (idx != null) {
+
+ int cidx = idx.charAt(0);
+ int width = ((fiData[0] & 0xFF) << 8) + (fiData[1] & 0xFF);
+
+ if (cidx < lowest) {
+ lowest = cidx;
+ }
+
+ if (cidx > highest) {
+ highest = cidx;
+ }
+
+ int a = (width * fopFactor);
+
+ cso.setWidth(cidx, a);
+
+ }
+
+ }
+ }
+
+ cso.setFirstChar(lowest);
+ cso.setLastChar(highest);
+
+ }
+
+ private class FontControl {
+
+ private int _dpi;
+
+ private boolean isRelative = false;
+
+ public int getDpi() {
+ return _dpi;
+ }
+
+ public void setDpi(int i) {
+ _dpi = i;
+ }
+
+ public boolean isRelative() {
+ return isRelative;
+ }
+
+ public void setRelative(boolean b) {
+ isRelative = b;
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.modca.AFPConstants;
+import org.apache.fop.render.afp.tools.StringUtils;
+
+/**
+ * The IBM Font Object Content Architecture (FOCA) supports presentation
+ * of character shapes by defining their characteristics, which include
+ * font description information for identifying the characters, font metric
+ * information for positioning the characters, and character shape information
+ * for presenting the character images.
+ * <p/>
+ * Presenting a graphic character on a presentation surface requires
+ * information on the rotation and position of character on the physical
+ * or logical page.
+ * <p/>
+ * This class proivdes font metric information for a particular font
+ * as identified by the character set name. This information is obtained
+ * directly from the AFP font files which must be installed in the path
+ * specified in the afp-fonts xml definition file.
+ * <p/>
+ */
+public class CharacterSet {
+
+ /**
+ * Static logging instance
+ */
+ protected static final Log log = LogFactory.getLog(CharacterSet.class.getName());
+
+ /**
+ * The code page to which the character set relates
+ */
+ protected String _codePage;
+
+ /**
+ * The encoding used for the code page
+ */
+ protected String _encoding;
+
+ /**
+ * The character set relating to the font
+ */
+ protected String _name;
+
+ /**
+ * The name of the character set as EBCIDIC bytes
+ */
+ private byte[] _nameBytes;
+
+ /**
+ * The path to the installed fonts
+ */
+ protected String _path;
+
+ /**
+ * Indicator as to whether to metrics have been loaded
+ */
+ private boolean _isMetricsLoaded = false;
+
+ /**
+ * The current orientation (currently only 0 is suppoted by FOP)
+ */
+ private String _currentOrientation = "0";
+
+ /**
+ * The collection of objects for each orientation
+ */
+ private HashMap _characterSetOrientations;
+
+ /**
+ * Constructor for the CharacterSetMetric object, the character set is used
+ * to load the font information from the actual AFP font.
+ * @param codePage the code page identifier
+ * @param encoding the encoding of the font
+ * @param name the character set name
+ * @param path the path to the installed afp fonts
+ */
+ public CharacterSet(
+ String codePage,
+ String encoding,
+ String name,
+ String path) {
+
+ if (name.length() > 8) {
+ String msg = "Character set name must be a maximum of 8 characters " + name;
+ log.error("Constructor:: " + msg);
+ throw new IllegalArgumentException(msg);
+ }
+
+ if (name.length() < 8) {
+ _name = StringUtils.rpad(name, ' ', 8);
+ } else {
+ _name = name;
+ }
+
+ try {
+
+ _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
+
+ } catch (UnsupportedEncodingException usee) {
+
+ _nameBytes = name.getBytes();
+ log.warn(
+ "Constructor:: UnsupportedEncodingException translating the name "
+ + name);
+
+ }
+
+ _codePage = codePage;
+ _encoding = encoding;
+ _path = path;
+ _characterSetOrientations = new HashMap(4);
+
+ }
+
+ /**
+ * Add character set metric information for the different orientations
+ * @param cso the metrics for the orientation
+ */
+ public void addCharacterSetOrientation(CharacterSetOrientation cso) {
+
+ _characterSetOrientations.put(
+ String.valueOf(cso.getOrientation()),
+ cso);
+
+ }
+
+ /**
+ * Ascender height is the distance from the character baseline to the
+ * top of the character box. A negative ascender height signifies that
+ * all of the graphic character is below the character baseline. For
+ * a character rotation other than 0, ascender height loses its
+ * meaning when the character is lying on its side or is upside down
+ * with respect to normal viewing orientation. For the general case,
+ * Ascender Height is the character�s most positive y-axis value.
+ * For bounded character boxes, for a given character having an
+ * ascender, ascender height and baseline offset are equal.
+ * @return the ascender value in millipoints
+ */
+ public int getAscender() {
+ load();
+ return getCharacterSetOrientation().getAscender();
+ }
+
+ /**
+ * Cap height is the average height of the uppercase characters in
+ * a font. This value is specified by the designer of a font and is
+ * usually the height of the uppercase M.
+ * @return the cap height value in millipoints
+ */
+ public int getCapHeight() {
+ load();
+ return getCharacterSetOrientation().getCapHeight();
+ }
+
+ /**
+ * Descender depth is the distance from the character baseline to
+ * the bottom of a character box. A negative descender depth signifies
+ * that all of the graphic character is above the character baseline.
+ * @return the descender value in millipoints
+ */
+ public int getDescender() {
+ load();
+ return getCharacterSetOrientation().getDescender();
+ }
+
+ /**
+ * The first character in the character set
+ * @return the first character
+ */
+ public int getFirstChar() {
+ load();
+ return getCharacterSetOrientation().getFirstChar();
+ }
+
+ /**
+ * The last character in the character set
+ * @return the last character
+ */
+ public int getLastChar() {
+ load();
+ return getCharacterSetOrientation().getLastChar();
+ }
+
+ /**
+ * @return the path where the font resources are installed
+ */
+ public String getPath() {
+ return _path;
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of all characters
+ * @return the widths of all characters
+ */
+ public int[] getWidths() {
+ load();
+ return getCharacterSetOrientation().getWidths();
+ }
+
+ /**
+ * XHeight refers to the height of the lower case letters above the baseline.
+ * @return the typical height of characters
+ */
+ public int getXHeight() {
+ load();
+ return getCharacterSetOrientation().getXHeight();
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the character from which the width will be calculated
+ * @return the width of the character
+ */
+ public int width(int character) {
+ load();
+ return getCharacterSetOrientation().width(character);
+ }
+
+ /**
+ * Lazy creation of the character metrics, the afp font file will only
+ * be processed on a method call requiring the metric information.
+ */
+ private void load() {
+
+ if (!_isMetricsLoaded) {
+
+ AFPFontReader.loadCharacterSetMetric(this);
+ _isMetricsLoaded = true;
+
+ }
+
+ }
+
+ /**
+ * Returns the AFP character set identifier
+ * @return String
+ */
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Returns the AFP character set identifier
+ * @return byte[]
+ */
+ public byte[] getNameBytes() {
+ return _nameBytes;
+ }
+
+ /**
+ * Returns the AFP code page identifier
+ * @return String
+ */
+ public String getCodePage() {
+ return _codePage;
+ }
+
+ /**
+ * Returns the AFP code page encoding
+ * @return String
+ */
+ public String getEncoding() {
+ return _encoding;
+ }
+
+ /**
+ * Helper method to return the current CharacterSetOrientation, note
+ * that FOP does not yet implement the "reference-orientation"
+ * attribute therefore we always use the orientation zero degrees,
+ * Other orientation information is captured for use by a future
+ * implementation (whenever FOP implement the mechanism). This is also
+ * the case for landscape prints which use an orientation of 270 degrees,
+ * in 99.9% of cases the font metrics will be the same as the 0 degrees
+ * therefore the implementation currely will always use 0 degrees.
+ * @return characterSetOrentation The current orientation metrics.
+ */
+ private CharacterSetOrientation getCharacterSetOrientation() {
+
+ CharacterSetOrientation c =
+ (CharacterSetOrientation) _characterSetOrientations.get(
+ _currentOrientation);
+ return c;
+
+ }
+
+ /**
+ * Map a Unicode character to a code point in the font.
+ * The code tables are already converted to Unicode therefore
+ * we can use the identity mapping.
+ * @param c character to map
+ * @return the mapped character
+ */
+ public char mapChar(char c) {
+ return c;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+
+/**
+ * The IBM Font Object Content Architecture (FOCA) supports presentation
+ * of character shapes by defining their characteristics, which include
+ * Font-Description information for identifying the characters, Font-Metric
+ * information for positioning the characters, and Character-Shape
+ * information for presenting the character images.
+ *
+ * Presenting a graphic character on a presentation surface requires
+ * that you communicate this information clearly to rotate and position
+ * characters correctly on the physical or logical page.
+ *
+ * This class proivdes font metric information for a particular font
+ * as by the orientation.
+ *
+ * This informtaion is obtained directly from the AFP font files which must
+ * be installed in the classpath under in the location specified by the path
+ * attribute in the afp-font.xml file.
+ * <p/>
+ */
+public class CharacterSetOrientation {
+
+ /**
+ * The code page to which the character set relates
+ */
+ private String _codePage;
+
+ /**
+ * The encoding used for the code page
+ */
+ private String _encoding;
+
+ /**
+ * The ascender height for the character set
+ */
+ private int _ascender;
+
+ /**
+ * The descender depth for the character set
+ */
+ private int _descender;
+
+ /**
+ * The height of capital letters
+ */
+ private int _capHeight;
+
+ /**
+ * The characters in the charcater set
+ */
+ private int[] _characters = new int[256];
+
+ /**
+ * The height of lowercase letters
+ */
+ private int _xHeight;
+
+ /**
+ * The first character
+ */
+ private int _firstCharacter;
+
+ /**
+ * The last character
+ */
+ private int _lastCharacter;
+
+
+ /**
+ * The character set orientation
+ */
+ private int _orientation = 0;
+
+ /**
+ * Constructor for the CharacterSetOrientation, the orientation is
+ * expressed as the degrees rotation (i.e 0, 90, 180, 270)
+ * @param orientation the character set orientation
+ */
+ public CharacterSetOrientation(int orientation) {
+
+ _orientation = orientation;
+
+ }
+
+ /**
+ * Ascender height is the distance from the character baseline to the
+ * top of the character box. A negative ascender height signifies that
+ * all of the graphic character is below the character baseline. For
+ * a character rotation other than 0, ascender height loses its
+ * meaning when the character is lying on its side or is upside down
+ * with respect to normal viewing orientation. For the general case,
+ * Ascender Height is the character�s most positive y-axis value.
+ * For bounded character boxes, for a given character having an
+ * ascender, ascender height and baseline offset are equal.
+ * @return the ascender value in millipoints
+ */
+ public int getAscender() {
+ return _ascender;
+ }
+
+ /**
+ * Cap height is the average height of the uppercase characters in
+ * a font. This value is specified by the designer of a font and is
+ * usually the height of the uppercase M.
+ * @return the cap height value in millipoints
+ */
+ public int getCapHeight() {
+ return _capHeight;
+ }
+
+ /**
+ * Descender depth is the distance from the character baseline to
+ * the bottom of a character box. A negative descender depth signifies
+ * that all of the graphic character is above the character baseline.
+ * @return the descender value in millipoints
+ */
+ public int getDescender() {
+ return _descender;
+ }
+
+ /**
+ * The first character in the character set
+ * @return the first character
+ */
+ public int getFirstChar() {
+ return _firstCharacter;
+ }
+
+ /**
+ * The last character in the character set
+ * @return the last character
+ */
+ public int getLastChar() {
+ return _lastCharacter;
+ }
+
+ /**
+ * The orientation for these metrics in the character set
+ * @return the orientation
+ */
+ public int getOrientation() {
+ return _orientation;
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of all characters
+ * in this character set.
+ * @return the widths of all characters
+ */
+ public int[] getWidths() {
+
+ int arr[] = new int[(getLastChar() - getFirstChar()) + 1];
+ System.arraycopy(_characters, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
+ return arr;
+
+ }
+
+ /**
+ * XHeight refers to the height of the lower case letters above
+ * the baseline.
+ * @return heightX the typical height of characters
+ */
+ public int getXHeight() {
+ return _xHeight;
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the character to evaluate
+ * @return the widths of the character
+ */
+ public int width(int character) {
+ return _characters[character];
+ }
+
+ /**
+ * Ascender height is the distance from the character baseline to the
+ * top of the character box. A negative ascender height signifies that
+ * all of the graphic character is below the character baseline. For
+ * a character rotation other than 0, ascender height loses its
+ * meaning when the character is lying on its side or is upside down
+ * with respect to normal viewing orientation. For the general case,
+ * Ascender Height is the character�s most positive y-axis value.
+ * For bounded character boxes, for a given character having an
+ * ascender, ascender height and baseline offset are equal.
+ * @param ascender the ascender to set
+ */
+ public void setAscender(int ascender) {
+ _ascender = ascender;
+ }
+
+ /**
+ * Cap height is the average height of the uppercase characters in
+ * a font. This value is specified by the designer of a font and is
+ * usually the height of the uppercase M.
+ * @param capHeight the cap height to set
+ */
+ public void setCapHeight(int capHeight) {
+ _capHeight = capHeight;
+ }
+
+ /**
+ * Descender depth is the distance from the character baseline to
+ * the bottom of a character box. A negative descender depth signifies
+ * that all of the graphic character is above the character baseline.
+ * @param descender the descender value in millipoints
+ */
+ public void setDescender(int descender) {
+ _descender = descender;
+ }
+
+ /**
+ * The first character in the character set
+ * @param firstCharacter the first character
+ */
+ public void setFirstChar(int firstCharacter) {
+ _firstCharacter = firstCharacter;
+ }
+
+ /**
+ * The last character in the character set
+ * @param lastCharacter the last character
+ */
+ public void setLastChar(int lastCharacter) {
+ _lastCharacter = lastCharacter;
+ }
+
+ /**
+ * Set the width (in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the character for which the width is being set
+ * @param width the widths of the character
+ */
+ public void setWidth(int character, int width) {
+
+ if (character >= _characters.length) {
+ // Increase the size of the array if necessary
+ int arr[] = new int[(character - _firstCharacter) + 1];
+ System.arraycopy(_characters, 0, arr, 0, _characters.length);
+ _characters = arr;
+ }
+ _characters[character] = width;
+
+ }
+
+ /**
+ * XHeight refers to the height of the lower case letters above
+ * the baseline.
+ * @param xHeight the typical height of characters
+ */
+ public void setXHeight(int xHeight) {
+ _xHeight = xHeight;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+import org.apache.fop.fonts.Typeface;
+
+/**
+ * A Character set for a normal FOP font<p/>
+ */
+public class FopCharacterSet extends CharacterSet {
+
+ /** The character set for this font */
+ private Typeface _characterSet = null;
+ private int _size = 0;
+
+ /**
+ * Constructor for the CharacterSetMetric object, the character set is used
+ * to load the font information from the actual AFP font.
+ * @param codePage the code page identifier
+ * @param encoding the encoding of the font
+ * @param name the character set name
+ * @param size the font size
+ * @param characterSet the fop character set
+ */
+ public FopCharacterSet(
+ String codePage,
+ String encoding,
+ String name,
+ int size,
+ Typeface characterSet) {
+ super(codePage, encoding, name, null);
+ _characterSet = characterSet;
+ _size = size * 1000;
+ }
+
+ /**
+ * Ascender height is the distance from the character baseline to the
+ * top of the character box. A negative ascender height signifies that
+ * all of the graphic character is below the character baseline. For
+ * a character rotation other than 0, ascender height loses its
+ * meaning when the character is lying on its side or is upside down
+ * with respect to normal viewing orientation. For the general case,
+ * Ascender Height is the character�s most positive y-axis value.
+ * For bounded character boxes, for a given character having an
+ * ascender, ascender height and baseline offset are equal.
+ * @return the ascender value in millipoints
+ */
+ public int getAscender() {
+ return _characterSet.getAscender(_size);
+ }
+
+ /**
+ * Cap height is the average height of the uppercase characters in
+ * a font. This value is specified by the designer of a font and is
+ * usually the height of the uppercase M.
+ * @return the cap height value in millipoints
+ */
+ public int getCapHeight() {
+ return _characterSet.getCapHeight(_size);
+ }
+
+ /**
+ * Descender depth is the distance from the character baseline to
+ * the bottom of a character box. A negative descender depth signifies
+ * that all of the graphic character is above the character baseline.
+ * @return the descender value in millipoints
+ */
+ public int getDescender() {
+ return _characterSet.getDescender(_size);
+ }
+
+ /**
+ * The first character in the character set
+ * @return the first character
+ */
+ public int getFirstChar() {
+ return 0;
+ }
+
+ /**
+ * The last character in the character set
+ * @return the last character
+ */
+ public int getLastChar() {
+ return 0;
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of all characters
+ * @return the widths of all characters
+ */
+ public int[] getWidths() {
+ return _characterSet.getWidths();
+ }
+
+ /**
+ * XHeight refers to the height of the lower case letters above the baseline.
+ * @return the typical height of characters
+ */
+ public int getXHeight() {
+ return _characterSet.getXHeight(_size);
+ }
+
+ /**
+ * Get the width (in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the character from which the width will be calculated
+ * @return the width of the character
+ */
+ public int width(int character) {
+ return _characterSet.getWidth(character, _size);
+ }
+
+ /**
+ * Map a Unicode character to a code point in the font.
+ * @param c character to map
+ * @return the mapped character
+ */
+ public char mapChar(char c) {
+ return _characterSet.mapChar(c);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+/**
+ * A font defined as a set of lines and curves as opposed to a bitmap font. An
+ * outline font can be scaled to any size and otherwise transformed more easily
+ * than a bitmap font, and with more attractive results. <p/>
+ *
+ */
+public class OutlineFont extends AFPFont {
+
+ /** The character set for this font */
+ private CharacterSet _characterSet = null;
+
+ /**
+ * Constructor for an outline font.
+ *
+ * @param name
+ * the name of the font
+ * @param characterSet
+ * the chracter set
+ */
+ public OutlineFont(String name, CharacterSet characterSet) {
+ super(name);
+ _characterSet = characterSet;
+ }
+
+ /**
+ * Get the character set metrics.
+ *
+ * @return the character set
+ */
+ public CharacterSet getCharacterSet() {
+
+ return _characterSet;
+
+ }
+
+ /**
+ * Get the character set metrics.
+ * @param size ignored
+ * @return the character set
+ */
+ public CharacterSet getCharacterSet(int size) {
+
+ return _characterSet;
+
+ }
+
+ /**
+ * Get the first character in this font.
+ */
+ public int getFirstChar() {
+
+ return _characterSet.getFirstChar();
+
+ }
+
+ /**
+ * Get the last character in this font.
+ */
+ public int getLastChar() {
+
+ return _characterSet.getLastChar();
+
+ }
+
+ /**
+ * The ascender is the part of a lowercase letter that extends above the
+ * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
+ * used to denote the part of the letter extending above the x-height.
+ *
+ * @param size
+ * the point size
+ */
+ public int getAscender(int size) {
+
+ return _characterSet.getAscender() / 1000 * size;
+
+ }
+
+ /**
+ * Obtains the height of capital letters for the specified point size.
+ *
+ * @param size
+ * the point size
+ */
+ public int getCapHeight(int size) {
+
+ return _characterSet.getCapHeight() / 1000 * size;
+
+ }
+
+ /**
+ * The descender is the part of a lowercase letter that extends below the
+ * base line, such as "g", "j", or "p". Also used to denote the part of the
+ * letter extending below the base line.
+ *
+ * @param size
+ * the point size
+ */
+ public int getDescender(int size) {
+
+ return _characterSet.getDescender() / 1000 * size;
+
+ }
+
+ /**
+ * The "x-height" (the height of the letter "x").
+ *
+ * @param size
+ * the point size
+ */
+ public int getXHeight(int size) {
+
+ return _characterSet.getXHeight() / 1000 * size;
+
+ }
+
+ /**
+ * Obtain the width of the character for the specified point size.
+ */
+ public int getWidth(int character, int size) {
+
+ return _characterSet.width(character) / 1000 * size;
+
+ }
+
+ /**
+ * Get the getWidth (in 1/1000ths of a point size) of all characters in this
+ * character set.
+ *
+ * @param size
+ * the point size
+ * @return the widths of all characters
+ */
+ public int[] getWidths(int size) {
+
+ int[] widths = _characterSet.getWidths();
+ for (int i = 0; i < widths.length; i++) {
+ widths[i] = widths[i] / 1000 * size;
+ }
+ return widths;
+
+ }
+
+ /**
+ * Get the getWidth (in 1/1000ths of a point size) of all characters in this
+ * character set.
+ *
+ * @return the widths of all characters
+ */
+ public int[] getWidths() {
+
+ return getWidths(1000);
+
+ }
+
+ /**
+ * Map a Unicode character to a code point in the font.
+ * @param c character to map
+ * @return the mapped character
+ */
+ public char mapChar(char c) {
+ return _characterSet.mapChar(c);
+ }
+
+ /**
+ * Get the encoding of the font.
+ * @return the encoding
+ */
+ public String getEncoding() {
+ return _characterSet.getEncoding();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.fonts;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.exceptions.FontRuntimeException;
+
+/**
+ * A font where each character is stored as an array of pixels (a bitmap). Such
+ * fonts are not easily scalable, in contrast to vectored fonts. With this type
+ * of font, the font metrics information is held in character set files (one for
+ * each size and style). <p/>
+ *
+ */
+public class RasterFont extends AFPFont {
+
+ /** Static logging instance */
+ protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
+
+ private HashMap _characterSets = new HashMap();
+
+ private CharacterSet _characterSet = null;
+
+ /**
+ * Constructor for the raster font requires the name, weight and style
+ * attribute to be available as this forms the key to the font.
+ *
+ * @param name
+ * the name of the font
+ */
+ public RasterFont(String name) {
+ super(name);
+ }
+
+ public void addCharacterSet(int size, CharacterSet characterSet) {
+
+ _characterSets.put(String.valueOf(size), characterSet);
+
+ _characterSet = characterSet;
+
+ }
+
+ /**
+ * Get the character set metrics for the specified point size.
+ *
+ * @param size the point size
+ * @return the character set metrics
+ */
+ public CharacterSet getCharacterSet(int size) {
+
+ String pointsize = String.valueOf(size / 1000);
+ CharacterSet csm = (CharacterSet) _characterSets.get(pointsize);
+ if (csm == null) {
+ csm = (CharacterSet) _characterSets.get(size + "mpt");
+ }
+ if (csm == null) {
+ // Get char set with nearest font size
+ int distance = Integer.MAX_VALUE;
+ for (Iterator it = _characterSets.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry me = (Map.Entry)it.next();
+ String key = (String)me.getKey();
+ if (!key.endsWith("mpt")) {
+ int mpt = Integer.parseInt(key) * 1000;
+ if (Math.abs(size - mpt) < distance) {
+ distance = Math.abs(size - mpt);
+ pointsize = (String)me.getKey();
+ csm = (CharacterSet)me.getValue();
+ }
+ }
+ }
+ if (csm != null) {
+ _characterSets.put(size + "mpt", csm);
+ String msg = "No " + (size / 1000) + "pt font " + _name
+ + " found, substituted with " + pointsize + "pt font";
+ log.warn(msg);
+ }
+ }
+ if (csm == null) {
+ String msg = "No font found for font " + _name
+ + " with point size " + pointsize;
+ log.error(msg);
+ throw new FontRuntimeException(msg);
+ }
+ return csm;
+
+ }
+
+ /**
+ * Get the first character in this font.
+ */
+ public int getFirstChar() {
+
+ Iterator i = _characterSets.values().iterator();
+ if (i.hasNext()) {
+ CharacterSet csm = (CharacterSet) i.next();
+ return csm.getFirstChar();
+ } else {
+ String msg = "getFirstChar() - No character set found for font:" + _name;
+ log.error(msg);
+ throw new FontRuntimeException(msg);
+ }
+
+ }
+
+ /**
+ * Get the last character in this font.
+ */
+ public int getLastChar() {
+
+ Iterator i = _characterSets.values().iterator();
+ if (i.hasNext()) {
+ CharacterSet csm = (CharacterSet) i.next();
+ return csm.getLastChar();
+ } else {
+ String msg = "getLastChar() - No character set found for font:" + _name;
+ log.error(msg);
+ throw new FontRuntimeException(msg);
+ }
+
+ }
+
+ /**
+ * The ascender is the part of a lowercase letter that extends above the
+ * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
+ * used to denote the part of the letter extending above the x-height.
+ *
+ * @param size the point size
+ */
+ public int getAscender(int size) {
+
+ return getCharacterSet(size).getAscender();
+
+ }
+
+ /**
+ * Obtains the height of capital letters for the specified point size.
+ *
+ * @param size the point size
+ */
+ public int getCapHeight(int size) {
+
+ return getCharacterSet(size).getCapHeight();
+
+ }
+
+ /**
+ * The descender is the part of a lowercase letter that extends below the
+ * base line, such as "g", "j", or "p". Also used to denote the part of the
+ * letter extending below the base line.
+ *
+ * @param size the point size
+ */
+ public int getDescender(int size) {
+
+ return getCharacterSet(size).getDescender();
+
+ }
+
+ /**
+ * The "x-height" (the height of the letter "x").
+ *
+ * @param size the point size
+ */
+ public int getXHeight(int size) {
+
+ return getCharacterSet(size).getXHeight();
+
+ }
+
+ /**
+ * Obtain the width of the character for the specified point size.
+ */
+ public int getWidth(int character, int size) {
+
+ return getCharacterSet(size).width(character);
+
+ }
+
+ /**
+ * Get the getWidth (in 1/1000ths of a point size) of all characters in this
+ * character set.
+ *
+ * @param size
+ * the point size
+ * @return the widths of all characters
+ */
+ public int[] getWidths(int size) {
+
+ return getCharacterSet(size).getWidths();
+
+ }
+
+ /**
+ * Get the getWidth (in 1/1000ths of a point size) of all characters in this
+ * character set.
+ *
+ * @return the widths of all characters
+ */
+ public int[] getWidths() {
+
+ return getWidths(1000);
+
+ }
+
+ /**
+ * Map a Unicode character to a code point in the font.
+ * @param c character to map
+ * @return the mapped character
+ */
+ public char mapChar(char c) {
+ return _characterSet.mapChar(c);
+ }
+
+ /**
+ * Get the encoding of the font.
+ * @return the encoding
+ */
+ public String getEncoding() {
+ return _characterSet.getEncoding();
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+/**
+ * Constants used by the AFP renderer.
+ *
+ */
+public interface AFPConstants {
+
+ /**
+ * The encoding to use to convert to EBCIDIC
+ */
+ public String EBCIDIC_ENCODING = "Cp1146";
+
+ /**
+ * The encoding to use to convert to ASCII
+ */
+ public String ASCII_ENCODING = "Cp1252";
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.tools.StringUtils;
+
+/**
+ * A data stream is a continuous ordered stream of data elements and objects
+ * conforming to a given format. Application programs can generate data streams
+ * destined for a presentation service, archive library, presentation device or
+ * another application program. The strategic presentation data stream
+ * architectures used is Mixed Object Document Content Architecture (MO:DCA�).
+ *
+ * The MO:DCA architecture defines the data stream used by applications to
+ * describe documents and object envelopes for interchange with other
+ * applications and application services. Documents defined in the MO:DCA format
+ * may be archived in a database, then later retrieved, viewed, annotated and
+ * printed in local or distributed systems environments. Presentation fidelity
+ * is accommodated by including resource objects in the documents that reference
+ * them.
+ *
+ */
+public class AFPDataStream {
+
+ /**
+ * Static logging instance
+ */
+ protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
+
+ /**
+ * Boolean completion indicator
+ */
+ private boolean _complete = false;
+
+ /**
+ * The application producing the AFP document
+ */
+ private String _producer = null;
+
+ /**
+ * The AFP document object
+ */
+ private Document _document = null;
+
+ /**
+ * The current page group object
+ */
+ private PageGroup _currentPageGroup = null;
+
+ /**
+ * The current page object
+ */
+ private PageObject _currentPageObject = null;
+
+ /**
+ * The current overlay object
+ */
+ private Overlay _currentOverlay = null;
+
+ /**
+ * The current page
+ */
+ private AbstractPageObject _currentPage = null;
+
+ /**
+ * The page count
+ */
+ private int _pageCount = 0;
+
+ /**
+ * The page group count
+ */
+ private int _pageGroupCount = 0;
+
+ /**
+ * The overlay count
+ */
+ private int _ovlCount = 0;
+
+ /**
+ * The portrait rotation
+ */
+ private int _portraitRotation = 0;
+
+ /**
+ * The landscape rotation
+ */
+ private int _landscapeRotation = 270;
+
+ /**
+ * The x offset
+ */
+ private int _xOffset = 0;
+
+ /**
+ * The y offset
+ */
+ private int _yOffset = 0;
+
+ /**
+ * The rotation
+ */
+ private int _rotation;
+
+ /**
+ * The outputstream for the data stream
+ */
+ private OutputStream _outputStream = null;
+
+ /**
+ * Default constructor for the AFPDataStream.
+ */
+ public AFPDataStream() {
+ }
+
+ /**
+ * The document is started by invoking this method which creates an instance
+ * of the AFP Document object.
+ */
+ public void startDocument(OutputStream outputStream) {
+
+ if (_document != null) {
+ String msg = "Invalid state - document already started.";
+ log.warn("startDocument():: " + msg);
+ throw new IllegalStateException(msg);
+ }
+
+ _document = new Document();
+ _outputStream = outputStream;
+
+ }
+
+ /**
+ * The document is ended by invoking this method which creates an instance
+ * of the AFP Document object and registers the start with a validation map
+ * which ensures that methods are not invoked out of the correct sequence.
+ */
+ public void endDocument()
+ throws IOException {
+
+ if (_complete) {
+ String msg = "Invalid state - document already ended.";
+ log.warn("endDocument():: " + msg);
+ throw new IllegalStateException(msg);
+ }
+
+ if (_currentPageObject != null) {
+ // End the current page if necessary
+ endPage();
+ }
+
+ if (_currentPageGroup != null) {
+ // End the current page group if necessary
+ endPageGroup();
+ }
+
+ _document.endDocument();
+ _document.writeDataStream(_outputStream);
+ _outputStream.flush();
+
+ _complete = true;
+
+ _document = null;
+
+ _outputStream = null;
+ }
+
+ /**
+ * Start a new page. When processing has finished on the current page, the
+ * {@link #endPage()}method must be invoked to mark the page ending.
+ *
+ * @param pageWidth
+ * the width of the page
+ * @param pageHeight
+ * the height of the page
+ * @param pageRotation
+ * the rotation of the page
+ */
+ public void startPage(int pageWidth, int pageHeight, int pageRotation) {
+
+ String pageName = "PGN"
+ + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
+
+ _currentPageObject = new PageObject(pageName, pageWidth, pageHeight, pageRotation);
+ _currentPage = _currentPageObject;
+ _currentOverlay = null;
+ setOffsets(0, 0, 0);
+ }
+
+ /**
+ * Start a new overlay. When processing has finished on the current overlay, the
+ * {@link #endOverlay()}method must be invoked to mark the overlay ending.
+ *
+ * @param overlayX
+ * the x position of the overlay on the page
+ * @param overlayY
+ * the y position of the overlay on the page
+ * @param overlayWidth
+ * the width of the overlay
+ * @param overlayHeight
+ * the height of the overlay
+ * @param overlayRotation
+ * the rotation of the overlay
+ */
+ public void startOverlay(int overlayX, int overlayY, int overlayWidth, int overlayHeight, int overlayRotation) {
+
+ String overlayName = "OVL"
+ + StringUtils.lpad(String.valueOf(_ovlCount++), '0', 5);
+
+ _currentOverlay = new Overlay(overlayName, overlayWidth, overlayHeight, overlayRotation);
+ _currentPageObject.addOverlay(_currentOverlay);
+ _currentPageObject.createIncludePageOverlay(overlayName, overlayX, overlayY, 0);
+ _currentPage = _currentOverlay;
+ setOffsets(0, 0, 0);
+ }
+
+ /**
+ * Helper method to mark the end of the current overlay.
+ */
+ public void endOverlay() {
+
+ _currentOverlay.endPage();
+ _currentOverlay = null;
+ _currentPage = _currentPageObject;
+
+ }
+
+ /**
+ * Helper method to save the current page.
+ */
+ public PageObject savePage() {
+
+ PageObject pageObject = _currentPageObject;
+ if (_currentPageGroup != null) {
+ _currentPageGroup.addPage(_currentPageObject);
+ } else {
+ _document.addPage(_currentPageObject);
+ }
+ _currentPageObject = null;
+ _currentPage = null;
+ return pageObject;
+
+ }
+
+ /**
+ * Helper method to restore the current page.
+ */
+ public void restorePage(PageObject pageObject) {
+
+ _currentPageObject = pageObject;
+ _currentPage = pageObject;
+
+ }
+
+ /**
+ * Helper method to mark the end of the current page.
+ */
+ public void endPage()
+ throws IOException {
+
+ _currentPageObject.endPage();
+ if (_currentPageGroup != null) {
+ _currentPageGroup.addPage(_currentPageObject);
+ } else {
+ _document.addPage(_currentPageObject);
+ _document.writeDataStream(_outputStream);
+ }
+
+ _currentPageObject = null;
+ _currentPage = null;
+
+ }
+
+ /**
+ * Sets the offsets to be used for element positioning
+ *
+ * @param xOffset
+ * the offset in the x direction
+ * @param yOffset
+ * the offset in the y direction
+ * @param rotation
+ * the rotation
+ */
+ public void setOffsets(int xOffset, int yOffset, int rotation) {
+ _xOffset = xOffset;
+ _yOffset = yOffset;
+ _rotation = rotation;
+ }
+
+ /**
+ * Helper method to create a map coded font object on the current page, this
+ * method delegates the construction of the map coded font object to the
+ * active environment group on the current page.
+ *
+ * @param fontReference
+ * the font number used as the resource identifier
+ * @param font
+ * the font
+ * @param size
+ * the point size of the font
+ */
+ public void createFont(byte fontReference, AFPFont font, int size) {
+
+ _currentPage.createFont(fontReference, font, size);
+
+ }
+
+ /**
+ * Helper method to create text on the current page, this method delegates
+ * to the current presentation text object in order to construct the text.
+ *
+ * @param fontNumber
+ * the font number used as the resource identifier
+ * @param x
+ * the x coordinate of the text
+ * @param y
+ * the y coordinate of the text
+ * @param col
+ * the text color
+ * @param vsci
+ * The variable space character increment.
+ * @param ica
+ * The inter character adjustment.
+ * @param data
+ * the text data to create
+ */
+ public void createText(int fontNumber, int x, int y, Color col, int vsci, int ica, byte[] data) {
+
+ _currentPage.createText(fontNumber, x + _xOffset, y + _yOffset, _rotation, col, vsci, ica, data);
+
+ }
+
+ /**
+ * Returns an ImageObject used to create an image in the datastream.
+ *
+ * @param x
+ * the x position of the image
+ * @param y
+ * the y position of the image
+ * @param w
+ * the width of the image
+ * @param h
+ * the height of the image
+ */
+ public ImageObject getImageObject(int x, int y, int w, int h) {
+
+ int xOrigin;
+ int yOrigin;
+ int width;
+ int height;
+ switch (_rotation) {
+ case 90:
+ xOrigin = _currentPage.getWidth() - y - _yOffset;
+ yOrigin = x + _xOffset;
+ width = h;
+ height = w;
+ break;
+ case 180:
+ xOrigin = _currentPage.getWidth() - x - _xOffset;
+ yOrigin = _currentPage.getHeight() - y - _yOffset;
+ width = w;
+ height = h;
+ break;
+ case 270:
+ xOrigin = y + _yOffset;
+ yOrigin = _currentPage.getHeight() - x - _xOffset;
+ width = h;
+ height = w;
+ break;
+ default:
+ xOrigin = x + _xOffset;
+ yOrigin = y + _yOffset;
+ width = w;
+ height = h;
+ break;
+ }
+ ImageObject io = _currentPage.getImageObject();
+ io.setImageViewport(xOrigin, yOrigin, width, height, _rotation);
+ return io;
+
+ }
+
+ /**
+ * Method to create a line on the current page.
+ *
+ * @param x1
+ * the first x coordinate of the line
+ * @param y1
+ * the first y coordinate of the line
+ * @param x2
+ * the second x coordinate of the line
+ * @param y2
+ * the second y coordinate of the line
+ * @param thickness
+ * the thickness of the line
+ * @param col
+ * The text color.
+ */
+ public void createLine(int x1, int y1, int x2, int y2, int thickness, Color col) {
+
+ _currentPage.createLine(x1 + _xOffset, y1 + _yOffset, x2 + _xOffset, y2 + _yOffset, thickness, _rotation, col);
+
+ }
+
+ /**
+ * Sets the application producing the AFP.
+ *
+ * @param producer
+ * the application producing the AFP datastream
+ */
+ public void setProducer(String producer) {
+ _producer = producer;
+ }
+
+ /**
+ * This method will create shading on the page using the specified
+ * coordinates (the shading contrast is controlled via the red, green, blue
+ * parameters, by converting this to grey scale).
+ *
+ * @param x
+ * the x coordinate of the shading
+ * @param y
+ * the y coordinate of the shading
+ * @param w
+ * the width of the shaded area
+ * @param h
+ * the height of the shaded area
+ * @param red
+ * the red value
+ * @param green
+ * the green value
+ * @param blue
+ * the blue value
+ */
+ public void createShading(int x, int y, int w, int h, int red, int green,
+ int blue) {
+
+ _currentPage.createShading(x + _xOffset, y + _xOffset, w, h, red, green, blue);
+
+ }
+
+ /**
+ * Helper method which allows creation of the MPO object, via the AEG. And
+ * the IPO via the Page. (See actual object for descriptions.)
+ *
+ * @param name
+ * the name of the static overlay
+ */
+ public void createIncludePageOverlay(String name) {
+
+ _currentPageObject.createIncludePageOverlay(name, 0, 0, _rotation);
+ ActiveEnvironmentGroup aeg = _currentPageObject.getActiveEnvironmentGroup();
+ aeg.createOverlay(name);
+
+ }
+
+ /**
+ * Helper method which allows creation of the IMM object.
+ *
+ * @param name
+ * the name of the medium map
+ */
+ public void createInvokeMediumMap(String name) {
+
+ if (_currentPageGroup == null) {
+ startPageGroup();
+ }
+ _currentPageGroup.createInvokeMediumMap(name);
+
+ }
+
+ /**
+ * Creates an IncludePageSegment on the current page.
+ *
+ * @param name
+ * the name of the include page segment
+ * @param x
+ * the x coordinate for the overlay
+ * @param y
+ * the y coordinate for the overlay
+ */
+ public void createIncludePageSegment(String name, int x, int y) {
+
+ int xOrigin;
+ int yOrigin;
+ switch (_rotation) {
+ case 90:
+ xOrigin = _currentPage.getWidth() - y - _yOffset;
+ yOrigin = x + _xOffset;
+ break;
+ case 180:
+ xOrigin = _currentPage.getWidth() - x - _xOffset;
+ yOrigin = _currentPage.getHeight() - y - _yOffset;
+ break;
+ case 270:
+ xOrigin = y + _yOffset;
+ yOrigin = _currentPage.getHeight() - x - _xOffset;
+ break;
+ default:
+ xOrigin = x + _xOffset;
+ yOrigin = y + _yOffset;
+ break;
+ }
+ _currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
+
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page.
+ *
+ * @param attributes
+ * the array of key value pairs.
+ */
+ public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
+
+ for (int i = 0; i < attributes.length; i++) {
+ String name = (String) attributes[i].getKey();
+ String value = (String) attributes[i].getValue();
+ _currentPage.createTagLogicalElement(name, value);
+ }
+
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page group.
+ *
+ * @param attributes
+ * the array of key value pairs.
+ */
+ public void createPageGroupTagLogicalElement(
+ TagLogicalElementBean[] attributes) {
+
+ for (int i = 0; i < attributes.length; i++) {
+ String name = (String) attributes[i].getKey();
+ String value = (String) attributes[i].getValue();
+ _currentPageGroup.createTagLogicalElement(name, value);
+ }
+
+ }
+
+ /**
+ * Creates a TagLogicalElement on the current page or page group
+ *
+ * @param name
+ * The tag name
+ * @param value
+ * The tag value
+ */
+ public void createTagLogicalElement(String name, String value) {
+
+ if (_currentPageGroup != null) {
+ _currentPageGroup.createTagLogicalElement(name, value);
+ } else {
+ _currentPage.createTagLogicalElement(name, value);
+ }
+
+ }
+
+ /**
+ * Start a new page group. When processing has finished on the current page
+ * group the {@link #endPageGroup()}method must be invoked to mark the page
+ * group ending.
+ *
+ * @param name
+ * the name of the page group
+ */
+ public void startPageGroup() {
+
+ String pageGroupName = "PGP"
+ + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
+
+ _currentPageGroup = new PageGroup(pageGroupName);
+
+ }
+
+ /**
+ * Helper method to mark the end of the page group.
+ */
+ public void endPageGroup()
+ throws IOException {
+
+ _currentPageGroup.endPageGroup();
+ _document.addPageGroup(_currentPageGroup);
+ _document.writeDataStream(_outputStream);
+ _currentPageGroup = null;
+
+ }
+
+ /**
+ * Sets the rotation to be used for portrait pages, valid values are 0
+ * (default), 90, 180, 270.
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setPortraitRotation(int rotation) {
+
+ if (rotation == 0 || rotation == 90 || rotation == 180
+ || rotation == 270) {
+ _portraitRotation = rotation;
+ } else {
+ throw new IllegalArgumentException(
+ "The portrait rotation must be one of the values 0, 90, 180, 270");
+ }
+
+ }
+
+ /**
+ * Sets the rotation to be used for landscape pages, valid values are 0, 90,
+ * 180, 270 (default).
+ *
+ * @param rotation
+ * The rotation in degrees.
+ */
+ public void setLandscapeRotation(int rotation) {
+
+ if (rotation == 0 || rotation == 90 || rotation == 180
+ || rotation == 270) {
+ _landscapeRotation = rotation;
+ } else {
+ throw new IllegalArgumentException(
+ "The landscape rotation must be one of the values 0, 90, 180, 270");
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This is the base class for all data stream objects. Page objects are
+ * responsible for building and generating the binary datastream in an
+ * AFP format.
+ *
+ */
+public abstract class AbstractAFPObject {
+
+ /**
+ * Static logging instance
+ */
+ protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
+
+ /**
+ * DataStream objects must implement the writeDataStream()
+ * method to write its data to the given OutputStream
+ * @param os The outputsteam stream
+ * @throws java.io.IOException
+ */
+ public abstract void writeDataStream(OutputStream os) throws IOException;
+
+ /**
+ * Help method to write a set of AFPObjects to the AFP datastream.
+ * @afpObjects a list of AFPObjects
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ protected void writeObjectList(List afpObjects, OutputStream os)
+ throws IOException {
+
+ for (Iterator it = afpObjects.iterator(); it.hasNext(); ) {
+ ((AbstractAFPObject)it.next()).writeDataStream(os);
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This is the base class for all named data stream objects.
+ * A named data stream object has an 8 byte EBCIDIC name.
+ *
+ */
+public abstract class AbstractNamedAFPObject extends AbstractAFPObject{
+
+ /**
+ * The actual name of the object
+ */
+ protected String _name = null;
+
+ /**
+ * The name of the object in EBCIDIC bytes
+ */
+ protected byte[] _nameBytes;
+
+ /**
+ * Constructor for the ActiveEnvironmentGroup, this takes a
+ * name parameter which should be 8 characters long.
+ * @param name the object name
+ */
+ public AbstractNamedAFPObject(String name) {
+
+ if (name.length() < 8) {
+ name = (name + " ").substring(0, 8);
+ } else if (name.length() > 8) {
+ log.warn("Constructor:: name truncated to 8 chars"+ name);
+ name = name.substring(0, 8);
+ }
+
+ try {
+
+ _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
+
+ } catch (UnsupportedEncodingException usee) {
+
+ _nameBytes = name.getBytes();
+ log.warn(
+ "Constructor:: UnsupportedEncodingException translating the name "
+ + name);
+
+ }
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.awt.Color;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.tools.StringUtils;
+
+/**
+ * Pages contain the data objects that comprise a presentation document. Each
+ * page has a set of data objects associated with it. Each page within a
+ * document is independent from any other page, and each must establish its own
+ * environment parameters.
+ *
+ * The page is the level in the document component hierarchy that is used for
+ * printing or displaying a document's content. The data objects contained in
+ * the page envelope in the data stream are presented when the page is
+ * presented. Each data object has layout information associated with it that
+ * directs the placement and orientation of the data on the page. In addition,
+ * each page contains layout information that specifies the measurement units,
+ * page width, and page depth.
+ *
+ * A page is initiated by a begin page structured field and terminated by an end
+ * page structured field. Structured fields that define objects and active
+ * environment groups or that specify attributes of the page may be encountered
+ * in page state.
+ *
+ */
+public abstract class AbstractPageObject extends AbstractNamedAFPObject {
+
+ /**
+ * The active environment group for the page
+ */
+ protected ActiveEnvironmentGroup _activeEnvironmentGroup = null;
+
+ /**
+ * The presentation text object, we only have one per page
+ */
+ private PresentationTextObject _presentationTextObject = null;
+
+ /**
+ * The list of objects within the page
+ */
+ protected List _objects = new ArrayList();
+
+ /**
+ * The list of tag logical elements
+ */
+ protected ArrayList _tagLogicalElements = new ArrayList();
+
+ /**
+ * The list of the include page segments
+ */
+ protected ArrayList _segments = new ArrayList();
+
+ /**
+ * The page width
+ */
+ private int _width;
+
+ /**
+ * The page height
+ */
+ private int _height;
+
+ /**
+ * The page rotation
+ */
+ private int _rotation = 0;
+
+ /**
+ * The page state
+ */
+ private boolean _complete = false;
+
+ /**
+ * Construct a new page object for the specified name argument, the page
+ * name should be an 8 character identifier.
+ *
+ * @param name
+ * the name of the page.
+ * @param width
+ * the width of the page.
+ * @param height
+ * the height of the page.
+ * @param rotation
+ * the rotation of the page.
+ */
+ public AbstractPageObject(String name, int width, int height, int rotation) {
+
+ super(name);
+
+ _name = name;
+
+ _rotation = rotation;
+ _width = width;
+ _height = height;
+
+ /**
+ * Every page object must have an ActiveEnvironmentGroup
+ */
+ _activeEnvironmentGroup = new ActiveEnvironmentGroup(_width, _height);
+
+ if (_rotation != 0) {
+ switch (_rotation) {
+ case 90:
+ _activeEnvironmentGroup.setPosition(_width, 0, _rotation);
+ break;
+ case 180:
+ _activeEnvironmentGroup.setPosition(_width, _height, _rotation);
+ break;
+ case 270:
+ _activeEnvironmentGroup.setPosition(0, _height, _rotation);
+ break;
+ }
+ }
+
+ /**
+ * We have a presentation text object per page
+ */
+ _presentationTextObject = new PresentationTextObject();
+ _objects.add(_presentationTextObject);
+
+ }
+
+ /**
+ * Helper method to create a map coded font object on the current page, this
+ * method delegates the construction of the map coded font object to the
+ * active environment group on the page.
+ *
+ * @param fontReference
+ * the font number used as the resource identifier
+ * @param font
+ * the font
+ * @param size
+ * the point size of the font
+ */
+ public void createFont(byte fontReference, AFPFont font, int size) {
+
+ _activeEnvironmentGroup.createFont(fontReference, font, size, 0);
+
+ }
+
+ /**
+ * Helper method to create a line on the current page, this method delegates
+ * to the presentation text object in order to construct the line.
+ *
+ * @param x1
+ * the first x coordinate of the line
+ * @param y1
+ * the first y coordinate of the line
+ * @param x2
+ * the second x coordinate of the line
+ * @param y2
+ * the second y coordinate of the line
+ * @param thickness
+ * the thickness of the line
+ * @param rotation
+ * the rotation of the line
+ * @param col
+ * The text color.
+ */
+ public void createLine(int x1, int y1, int x2, int y2, int thickness, int rotation, Color col) {
+
+ if (_presentationTextObject == null) {
+ _presentationTextObject = new PresentationTextObject();
+ _objects.add(_presentationTextObject);
+ }
+ _presentationTextObject.createLineData(x1, y1, x2, y2, thickness, rotation, col);
+
+ }
+
+ /**
+ * Helper method to create text on the current page, this method delegates
+ * to the presentation text object in order to construct the text.
+ *
+ * @param fontNumber
+ * the font number used as the resource identifier
+ * @param x
+ * the x coordinate of the text data
+ * @param y
+ * the y coordinate of the text data
+ * @param rotation
+ * the rotation of the text data
+ * @param col
+ * the text color
+ * @param vsci
+ * The variable space character increment.
+ * @param ica
+ * The inter character adjustment.
+ * @param data
+ * the text data to create
+ */
+ public void createText(int fontNumber, int x, int y, int rotation, Color col, int vsci, int ica, byte[] data) {
+
+ if (_presentationTextObject == null) {
+ _presentationTextObject = new PresentationTextObject();
+ _objects.add(_presentationTextObject);
+ }
+ _presentationTextObject.createTextData(fontNumber, x, y, rotation, col, vsci, ica, data);
+
+ }
+
+ /**
+ * Helper method to mark the end of the page. This should end the control
+ * sequence on the current presenation text object.
+ */
+ public void endPage() {
+
+ if (_presentationTextObject != null) {
+ _presentationTextObject.endControlSequence();
+ }
+
+ _complete = true;
+
+ }
+
+ /**
+ * This method will create shading on the page using the specified
+ * coordinates (the shading contrast is controlled via the red, green blue
+ * parameters, by converting this to grey scale).
+ *
+ * @param x
+ * the x coordinate of the shading
+ * @param y
+ * the y coordinate of the shading
+ * @param w
+ * the width of the shaded area
+ * @param h
+ * the height of the shaded area
+ * @param red
+ * the red value
+ * @param green
+ * the green value
+ * @param blue
+ * the blue value
+ */
+ public void createShading(int x, int y, int w, int h, int red, int green,
+ int blue) {
+
+ int xCoord = 0;
+ int yCoord = 0;
+ int width = 0;
+ int height = 0;
+
+ switch (_rotation) {
+ case 90:
+ xCoord = _width - y - h;
+ yCoord = x;
+ width = h;
+ height = w;
+ break;
+ case 180:
+ xCoord = _width - x - w;
+ yCoord = _height - y - h;
+ width = w;
+ height = h;
+ break;
+ case 270:
+ xCoord = y;
+ yCoord = _height - x - w;
+ width = h;
+ height = w;
+ break;
+ default:
+ xCoord = x;
+ yCoord = y;
+ width = w;
+ height = h;
+ break;
+ }
+
+ // Convert the color to grey scale
+ float shade = (float) ((red * 0.3) + (green * 0.59) + (blue * 0.11));
+
+ int greyscale = Math.round((shade / 255) * 16);
+
+ String imageName = "IMG"
+ + StringUtils.lpad(String.valueOf(_objects.size() + 1),
+ '0', 5);
+
+ IMImageObject io = new IMImageObject(imageName);
+ ImageOutputControl ioc = new ImageOutputControl(0, 0);
+ ImageInputDescriptor iid = new ImageInputDescriptor();
+ ImageCellPosition icp = new ImageCellPosition(xCoord, yCoord);
+ icp.setXFillSize(width);
+ icp.setYFillSize(height);
+ icp.setXSize(64);
+ icp.setYSize(8);
+
+ //defing this as a resource
+ ImageRasterData ird = new ImageRasterData(ImageRasterPattern
+ .getRasterData(greyscale));
+
+ io.setImageOutputControl(ioc);
+ io.setImageInputDescriptor(iid);
+ io.setImageCellPosition(icp);
+ io.setImageRasterData(ird);
+ _objects.add(io);
+
+ }
+
+ /**
+ * Helper method to create an image on the current page and to return
+ * the object.
+ */
+ public ImageObject getImageObject() {
+
+ if (_presentationTextObject != null) {
+ _presentationTextObject.endControlSequence();
+ }
+ _presentationTextObject = null;
+
+ String imageName = "IMG"
+ + StringUtils.lpad(String.valueOf(_objects.size() + 1),
+ '0', 5);
+
+ ImageObject io = new ImageObject(imageName);
+ _objects.add(io);
+ return io;
+ }
+
+ /**
+ * Creates a TagLogicalElement on the page.
+ *
+ * @param name
+ * the name of the tag
+ * @param value
+ * the value of the tag
+ */
+ public void createTagLogicalElement(String name, String value) {
+
+ TagLogicalElement tle = new TagLogicalElement(name, value);
+ _tagLogicalElements.add(tle);
+
+ }
+
+ /**
+ * Creates an IncludePageSegment on the current page.
+ *
+ * @param name
+ * the name of the page segment
+ * @param xCoor
+ * the x cooridinate of the page segment.
+ * @param yCoor
+ * the y cooridinate of the page segment.
+ */
+ public void createIncludePageSegment(String name, int xCoor, int yCoor) {
+
+ IncludePageSegment ips = new IncludePageSegment(name, xCoor, yCoor);
+ _segments.add(ips);
+
+ }
+
+ /**
+ * Returns the ActiveEnvironmentGroup associated with this page.
+ *
+ * @return the ActiveEnvironmentGroup object
+ */
+ public ActiveEnvironmentGroup getActiveEnvironmentGroup() {
+ return _activeEnvironmentGroup;
+ }
+
+ /**
+ * Returns an indication if the page is complete
+ */
+ public boolean isComplete() {
+ return _complete;
+ }
+
+ /**
+ * Returns the height of the page
+ */
+ public int getHeight() {
+ return _height;
+ }
+
+ /**
+ * Returns the width of the page
+ */
+ public int getWidth() {
+ return _width;
+ }
+
+ /**
+ * Returns the rotation of the page
+ */
+ public int getRotation() {
+ return _rotation;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import org.apache.fop.render.afp.fonts.AFPFont;
+
+/**
+ * An Active Environment Group (AEG) is associated with each page,
+ * and is contained in the page's begin-end envelope in the data stream.
+ * The active environment group contains layout and formatting information
+ * that defines the measurement units and size of the page, and may contain
+ * resource information.
+ *
+ * Any objects that are required for page presentation and that are to be
+ * treated as resource objects must be mapped with a map structured field
+ * in the AEG. The scope of an active environment group is the scope of its
+ * containing page or overlay.
+ *
+ */
+public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
+
+ /**
+ * Default name for the active environment group
+ */
+ private static final String DEFAULT_NAME = "AEG00001";
+
+ /**
+ * The collection of MapCodedFont objects
+ */
+ private ArrayList _mapCodedFonts = new ArrayList();
+
+ /**
+ * The Object Area Descriptor for the active environment group
+ */
+ private ObjectAreaDescriptor _objectAreaDescriptor = null;
+
+ /**
+ * The Object Area Position for the active environment group
+ */
+ private ObjectAreaPosition _objectAreaPosition = null;
+
+ /**
+ * The PresentationTextDescriptor for the active environment group
+ */
+ private PresentationTextDescriptor _presentationTextDataDescriptor = null;
+
+ /**
+ * The PageDescriptor for the active environment group
+ */
+ private PageDescriptor _pageDescriptor = null;
+
+ /**
+ * The collection of MapPageOverlay objects
+ */
+ private ArrayList _mapPageOverlays = new ArrayList();
+
+ /**
+ * Default constructor for the ActiveEnvironmentGroup.
+ * @param width the page width
+ * @param height the page height
+ */
+ public ActiveEnvironmentGroup(int width, int height) {
+
+ this(DEFAULT_NAME, width, height);
+
+ }
+
+ /**
+ * Constructor for the ActiveEnvironmentGroup, this takes a
+ * name parameter which must be 8 characters long.
+ * @param name the active environment group name
+ * @param width the page width
+ * @param height the page height
+ */
+ public ActiveEnvironmentGroup(String name, int width, int height) {
+
+ super(name);
+
+ // Create PageDescriptor
+ _pageDescriptor = new PageDescriptor(width, height);
+
+ // Create ObjectAreaDescriptor
+ _objectAreaDescriptor = new ObjectAreaDescriptor(width, height);
+
+ // Create PresentationTextDataDescriptor
+ _presentationTextDataDescriptor =
+ new PresentationTextDescriptor(width, height);
+
+ }
+
+ /**
+ * Set the position of the object area
+ * @param x the x offset
+ * @param y the y offset
+ * @param rotation the rotation
+ */
+ public void setPosition(int x, int y, int rotation) {
+
+ // Create ObjectAreaPosition
+ _objectAreaPosition = new ObjectAreaPosition(x, y, rotation);
+
+ }
+
+ /**
+ * Accessor method to obtain the PageDescriptor object of the
+ * active environment group.
+ * @return the page descriptor object
+ */
+ public PageDescriptor getPageDescriptor() {
+
+ return _pageDescriptor;
+
+ }
+
+ /**
+ * Accessor method to obtain the PresentationTextDataDescriptor object of
+ * the active environment group.
+ * @return the presentation text descriptor
+ */
+ public PresentationTextDescriptor getPresentationTextDataDescriptor() {
+
+ return _presentationTextDataDescriptor;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the active environment group.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ writeObjectList(_mapCodedFonts, os);
+
+ writeObjectList(_mapPageOverlays, os);
+
+ _pageDescriptor.writeDataStream(os);
+
+ if (_objectAreaDescriptor != null && _objectAreaPosition != null) {
+ _objectAreaDescriptor.writeDataStream(os);
+ _objectAreaPosition.writeDataStream(os);
+ }
+
+ _presentationTextDataDescriptor.writeDataStream(os);
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the active environment group.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xC9; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the active environment group.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xC9; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Method to create a map coded font object
+ * @param fontReference the font number used as the resource identifier
+ * @param font the font
+ * @param size the point size of the font
+ * @param orientation the orientation of the font (e.g. 0, 90, 180, 270)
+ */
+ public void createFont(
+ byte fontReference,
+ AFPFont font,
+ int size,
+ int orientation) {
+
+ MapCodedFont mcf = getCurrentMapCodedFont();
+
+ if (mcf == null) {
+ mcf = new MapCodedFont();
+ _mapCodedFonts.add(mcf);
+ }
+
+ try {
+
+ mcf.addFont(
+ fontReference,
+ font,
+ size,
+ orientation);
+
+ } catch (MaximumSizeExceededException msee) {
+
+ mcf = new MapCodedFont();
+ _mapCodedFonts.add(mcf);
+
+ try {
+
+ mcf.addFont(
+ fontReference,
+ font,
+ size,
+ orientation);
+
+ } catch (MaximumSizeExceededException ex) {
+
+ // Should never happen (but log just in case)
+ log.error("createFont():: resulted in a MaximumSizeExceededException");
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Actually creates the MPO object.
+ * Also creates the supporting object (an IPO)
+ * @param name the name of the overlay to be used
+ */
+ public void createOverlay(String name) {
+
+ MapPageOverlay mpo = getCurrentMapPageOverlay();
+
+ if (mpo == null) {
+ mpo = new MapPageOverlay();
+ _mapPageOverlays.add(mpo);
+ }
+
+ try {
+
+ mpo.addOverlay(name);
+
+ } catch (MaximumSizeExceededException msee) {
+ mpo = new MapPageOverlay();
+ _mapPageOverlays.add(mpo);
+ try {
+ mpo.addOverlay(name);
+ } catch (MaximumSizeExceededException ex) {
+ // Should never happen (but log just in case)
+ log.error("createOverlay():: resulted in a MaximumSizeExceededException");
+ }
+ }
+ }
+
+ /**
+ * Getter method for the most recent MapCodedFont added to the
+ * Active Environment Group (returns null if no MapCodedFonts exist)
+ * @return the most recent Map Coded Font.
+ */
+ private MapCodedFont getCurrentMapCodedFont() {
+
+ int size = _mapCodedFonts.size();
+ if (size > 0) {
+ return (MapCodedFont) _mapCodedFonts.get(_mapCodedFonts.size() - 1);
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Getter method for the most recent MapPageOverlay added to the
+ * Active Environment Group (returns null if no MapPageOverlay exist)
+ * @return the most recent Map Coded Font
+ */
+ private MapPageOverlay getCurrentMapPageOverlay() {
+
+ int size = _mapPageOverlays.size();
+ if (size > 0) {
+ return (MapPageOverlay) _mapPageOverlays.get(
+ _mapPageOverlays.size() - 1);
+ } else {
+ return null;
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * The document is the highest level of the MO:DCA data-stream document
+ * component hierarchy. Documents can be made up of pages, and the pages,
+ * which are at the intermediate level, can be made up of objects. Objects
+ * are at the lowest level, and can be bar codes, graphics, images, and
+ * presentation text.
+ *
+ * At each level of the hierarchy certain sets of MO:DCA data structures,
+ * called structured fields, are permissible. The document, pages and objects
+ * are bounded by structured fields that define their beginnings and their ends.
+ * These structured fields, called begin-end pairs, provide an envelope for the
+ * data-stream components. This feature enables a processor of the data stream
+ * that is not fully compliant with the architecture to bypass those objects
+ * that are beyond its scope, and to process the data stream to the best of its
+ * abilities.
+ *
+ * A presentation document is one that has been formatted and is intended for
+ * presentation, usually on a printer or display device. A data stream containing
+ * a presentation document should produce the same document content in the
+ * same format on different printers or display devices dependent, however,
+ * on the capabilities of each of the printers or display devices. A presentation
+ * document can reference resources that are to be included as part of the
+ * document to be presented.
+ *
+ */
+public final class Document extends AbstractNamedAFPObject {
+
+ /**
+ * Ststic default name reference
+ */
+ private final static String DEFAULT_NAME = "DOC00001";
+
+ /**
+ * A list of the objects in the document
+ */
+ private ArrayList _objects = new ArrayList();
+
+ /**
+ * The document started state
+ */
+ private boolean _started = false;
+
+ /**
+ * The document completion state
+ */
+ private boolean _complete = false;
+
+ /**
+ * Default constructor for the document object.
+ */
+ public Document() {
+ this(DEFAULT_NAME);
+ }
+
+ /**
+ * Constructor for the document object.
+ * @param name The name of the document
+ */
+ public Document(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Adds a page to the document.
+ * @param page - the Page object
+ */
+ public void addPage(PageObject page) {
+ if (!_objects.contains(page)) {
+ _objects.add(page);
+ }
+ }
+
+ /**
+ * Adds a PageGroup to the document.
+ * @param pageGroup the PageGroup object
+ */
+ public void addPageGroup(PageGroup pageGroup) {
+ _objects.add(pageGroup);
+ }
+
+ /**
+ * Method to mark the end of the page group.
+ */
+ public void endDocument() {
+
+ _complete = true;
+
+ }
+
+ /**
+ * Returns an indication if the page group is complete
+ */
+ public boolean isComplete() {
+ return _complete;
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for document.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ if (!_started) {
+ writeStart(os);
+ _started = true;
+ }
+
+ for (Iterator it = _objects.iterator(); it.hasNext(); ) {
+ AbstractAFPObject ao = (AbstractAFPObject)it.next();
+ if (ao instanceof PageObject && ((PageObject)ao).isComplete()
+ || ao instanceof PageGroup && ((PageGroup)ao).isComplete()) {
+ ao.writeDataStream(os);
+ it.remove();
+ } else {
+ break;
+ }
+ }
+
+ if (_complete) {
+ writeEnd(os);
+ }
+
+ }
+
+ /**
+ * Helper method to write the start of the Document
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xA8; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the Document.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xA8; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * The End Named Page Group (ENG) structured field terminates a page group that was
+ * initiated by a Begin Named Page Group structured field.
+ *
+ * Note :This object will be used to represent an ENG
+ * structured field. It is necessary as you can't end
+ * a PageGroup because you don't know where the group
+ * will end (as this is controlled by the tags in the FO).
+ * <p>
+ *
+ */
+public class EndPageGroup extends AbstractNamedAFPObject {
+
+ public EndPageGroup(String groupId) {
+
+ super(groupId);
+
+ log.debug("A ENG is being created for group: " + groupId);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the End Page Group.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xAD; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * An IM image data object specifies the contents of a raster image and
+ * its placement on a page, overlay, or page segment. An IM image can be
+ * either simple or complex. A simple image is composed of one or more Image
+ * Raster Data (IRD) structured fields that define the raster pattern for the
+ * entire image. A complex image is divided into regions called image cells.
+ * Each image cell is composed of one or more IRD structured fields that define
+ * the raster pattern for the image cell, and one Image Cell Position (ICP)
+ * structured field that defines the position of the image cell relative to
+ * the origin of the entire image. Each ICP also specifies the size of the
+ * image cell and a fill rectangle into which the cell is replicated.
+ * <p/>
+ */
+public class IMImageObject extends AbstractNamedAFPObject {
+
+ /**
+ * The image output control
+ */
+ private ImageOutputControl _imageOutputControl = null;
+
+ /**
+ * The image input descriptor
+ */
+ private ImageInputDescriptor _imageInputDescriptor = null;
+
+ /**
+ * The image cell position
+ */
+ private ImageCellPosition _imageCellPosition = null;
+
+ /**
+ * The image rastor data
+ */
+ private ImageRasterData _imageRastorData = null;
+
+ /**
+ * Constructor for the image object with the specified name,
+ * the name must be a fixed length of eight characters.
+ * @param name The name of the image.
+ */
+ public IMImageObject(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Sets the ImageOutputControl.
+ * @param imageOutputControl The imageOutputControl to set
+ */
+ public void setImageOutputControl(ImageOutputControl imageOutputControl) {
+ _imageOutputControl = imageOutputControl;
+ }
+
+ /**
+ * Sets the ImageCellPosition.
+ * @param imageCellPosition The imageCellPosition to set
+ */
+ public void setImageCellPosition(ImageCellPosition imageCellPosition) {
+ _imageCellPosition = imageCellPosition;
+ }
+
+ /**
+ * Sets the ImageInputDescriptor.
+ * @param imageInputDescriptor The imageInputDescriptor to set
+ */
+ public void setImageInputDescriptor(ImageInputDescriptor imageInputDescriptor) {
+ _imageInputDescriptor = imageInputDescriptor;
+ }
+
+ /**
+ * Sets the ImageRastorData.
+ * @param imageRastorData The imageRastorData to set
+ */
+ public void setImageRasterData(ImageRasterData imageRastorData) {
+ _imageRastorData = imageRastorData;
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the IM Image Objetc
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ if (_imageOutputControl != null) {
+ _imageOutputControl.writeDataStream(os);
+ }
+
+ if (_imageInputDescriptor != null) {
+ _imageInputDescriptor.writeDataStream(os);
+ }
+
+ if (_imageCellPosition != null) {
+ _imageCellPosition.writeDataStream(os);
+ }
+
+ if (_imageRastorData != null) {
+ _imageRastorData.writeDataStream(os);
+ }
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the IM Image Object.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0x7B; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the IM Image Object.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0x7B; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The IM Image Cell Position structured field specifies the placement,
+ * size, and replication of IM image cells.
+ */
+public class ImageCellPosition extends AbstractAFPObject {
+
+ /**
+ * Offset of image cell in X direction
+ */
+ private int _XcoSet = 0;
+
+ /**
+ * Offset of image cell in Y direction
+ */
+ private int _YcoSet = 0;
+
+ /**
+ * Size of image cell in X direction
+ */
+ private byte[] _XcSize = new byte[] { (byte)0xFF, (byte)0xFF };
+
+ /**
+ * Size of image cell in Y direction
+ */
+ private byte[] _YcSize = new byte[] { (byte)0xFF, (byte)0xFF };
+
+ /**
+ * Size of fill rectangle in X direction
+ */
+ private byte[] _XFillSize = new byte[] { (byte)0xFF, (byte)0xFF };
+
+ /**
+ * Size of fill rectangle in Y direction
+ */
+ private byte[] _YFillSize = new byte[] { (byte)0xFF, (byte)0xFF };
+
+ /**
+ * Constructor for the ImageCellPosition
+ * @param x The offset of image cell in X direction
+ * @param y The offset of image cell in Y direction
+ */
+ public ImageCellPosition(int x, int y) {
+
+ _XcoSet = x;
+ _YcoSet = y;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Cell Position
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[21];
+
+ data[0] = 0x5A;
+
+ data[1] = 0x00;
+ data[2] = 0x14;
+
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAC;
+ data[5] = (byte) 0x7B;
+ data[6] = 0x00;
+ data[7] = 0x00;
+ data[8] = 0x00;
+
+ /**
+ * Specifies the offset along the Xp direction, in image points,
+ * of this image cell from the IM image object area origin.
+ */
+ byte[] x1 = BinaryUtils.convert(_XcoSet, 2);
+ data[9] = x1[0];
+ data[10] = x1[1];
+
+ /**
+ * Specifies the offset along the Yp direction, in image points,
+ * of this image cell from the IM image object area origin.
+ */
+ byte[] x2 = BinaryUtils.convert(_YcoSet, 2);
+ data[11] = x2[0];
+ data[12] = x2[1];
+
+ data[13] = _XcSize[0];
+ data[14] = _XcSize[1];
+
+ data[15] = _YcSize[0];
+ data[16] = _YcSize[1];
+
+ data[17] = _XFillSize[0];
+ data[18] = _XFillSize[1];
+
+ data[19] = _YFillSize[0];
+ data[20] = _YFillSize[1];
+
+ os.write(data);
+
+ }
+
+ /**
+ * Specifies the extent in the X direction, in image points,
+ * of this image cell. A value of X'FFFF' indicates that the
+ * default extent specified in bytes 28 and 29 of the Image
+ * Input Descriptor (IID) is to be used.
+ * @param xcSize The size to set.
+ */
+ public void setXSize(int xcSize) {
+
+ byte[] x = BinaryUtils.convert(xcSize, 2);
+ _XcSize[0] = x[0];
+ _XcSize[1] = x[1];
+
+ }
+
+ /**
+ * Specifies the extent of the fill rectangle in the X direction,
+ * in image points. This value can be smaller than, equal to, or
+ * larger than the image cell extent in the X direction (XCSize).
+ * A value of X'FFFF' indicates that the image cell X-extent should
+ * be used as the fill rectangle X-extent. The fill rectangle is
+ * filled in the X direction by repeating the image cell in the
+ * X direction. The image cell can be truncated to fit the rectangle.
+ * @param xFillSize The size to set.
+ */
+ public void setXFillSize(int xFillSize) {
+
+ byte[] x = BinaryUtils.convert(xFillSize, 2);
+ _XFillSize[0] = x[0];
+ _XFillSize[1] = x[1];
+
+ }
+
+ /**
+ * Specifies the extent in the Y direction, in image points,
+ * of this image cell. A value of X'FFFF' indicates that the
+ * default extent specified in bytes 30 and 31 of the Image
+ * Input Descriptor (IID) is to be used.
+ * @param ycSize The size to set.
+ */
+ public void setYSize(int ycSize) {
+
+ byte[] x = BinaryUtils.convert(ycSize, 2);
+ _YcSize[0] = x[0];
+ _YcSize[1] = x[1];
+
+ }
+
+ /**
+ * Specifies the extent of the fill rectangle in the Y direction,
+ * in image points. This value can be smaller than, equal to, or
+ * larger than the image cell extent in the Y direction (YCSize).
+ * A value of X'FFFF' indicates that the image cell Y-extent should
+ * be used as the fill rectangle Y-extent. The fill rectangle is
+ * filled in the Y direction by repeating the image cell in the
+ * Y direction. The image cell can be truncated to fit the rectangle.
+ * @param yFillSize The size to set.
+ */
+ public void setYFillSize(int yFillSize) {
+
+ byte[] x = BinaryUtils.convert(yFillSize, 2);
+ _YFillSize[0] = x[0];
+ _YFillSize[1] = x[1];
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ */
+public class ImageContent extends AbstractAFPObject {
+
+ /**
+ * The image size parameter
+ */
+ private ImageSizeParameter _imageSizeParameter = null;
+
+ /**
+ * The image encoding
+ */
+ private byte _encoding = 0x03;
+
+ /**
+ * The image ide size
+ */
+ private byte _size = 1;
+
+ /**
+ * The image compression
+ */
+ private byte _compression = (byte)0xC0;
+
+ /**
+ * The image color model
+ */
+ private byte _colorModel = 0x01;
+
+ /**
+ * The image data
+ */
+ private byte _data[] = null;
+
+ /**
+ * Constructor for the image content
+ */
+ public ImageContent() {
+
+ }
+
+ /**
+ * Sets the image size parameters
+ * resolution, hsize and vsize.
+ * @param hresol The horizontal resolution of the image.
+ * @param vresol The vertical resolution of the image.
+ * @param hsize The horizontal size of the image.
+ * @param vsize The vertival size of the image.
+ */
+ public void setImageSize(int hresol, int vresol, int hsize, int vsize) {
+ _imageSizeParameter = new ImageSizeParameter(hresol, vresol, hsize, vsize);
+ }
+
+ /**
+ * Sets the image encoding.
+ * @param encoding The image encoding.
+ */
+ public void setImageEncoding(byte encoding) {
+ _encoding = encoding;
+ }
+
+ /**
+ * Sets the image compression.
+ * @param compression The image compression.
+ */
+ public void setImageCompression(byte compression) {
+ _compression = compression;
+ }
+
+ /**
+ * Sets the image IDE size.
+ * @param size The IDE size.
+ */
+ public void setImageIDESize(byte size) {
+ _size = size;
+ }
+
+ /**
+ * Sets the image IDE color model.
+ * @param size The IDE color model.
+ */
+ public void setImageIDEColorModel(byte colorModel) {
+ _colorModel = colorModel;
+ }
+
+ /**
+ * Set the data of the image.
+ */
+ public void setImageData(byte data[]) {
+ _data = data;
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Content
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ if (_imageSizeParameter != null) {
+ _imageSizeParameter.writeDataStream(os);
+ }
+
+ os.write(getImageEncodingParameter());
+
+ os.write(getImageIDESizeParameter());
+
+ os.write(getIDEStructureParameter());
+
+ os.write(getExternalAlgorithmParameter());
+
+ if (_data != null) {
+ int off = 0;
+ while (off < _data.length) {
+ int len = Math.min(30000, _data.length - off);
+ os.write(getImageDataStart(len));
+ os.write(_data, off, len);
+ off += len;
+ }
+ }
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the Image Content.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ (byte)0x91, // ID
+ 0x01, // Length
+ (byte)0xff, // Object Type = IOCA Image Object
+ };
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the Image Content.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ (byte)0x93, // ID
+ 0x00, // Length
+ };
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to return the start of the image segment.
+ * @return byte[] The data stream.
+ */
+ private byte[] getImageDataStart(int len) {
+
+ byte[] data = new byte[] {
+ (byte)0xFE, // ID
+ (byte)0x92, // ID
+ 0x00, // Length
+ 0x00, // Length
+ };
+
+ byte[] l = BinaryUtils.convert(len, 2);
+ data[2] = l[0];
+ data[3] = l[1];
+
+
+ return data;
+
+ }
+
+ /**
+ * Helper method to return the image encoding parameter.
+ * @return byte[] The data stream.
+ */
+ private byte[] getImageEncodingParameter() {
+
+ byte[] data = new byte[] {
+ (byte)0x95, // ID
+ 0x02, // Length
+ _encoding,
+ 0x01, // RECID
+ };
+
+ return data;
+
+ }
+
+ /**
+ * Helper method to return the external algorithm parameter.
+ * @return byte[] The data stream.
+ */
+ private byte[] getExternalAlgorithmParameter() {
+
+ if (_encoding == (byte)0x83 && _compression != 0) {
+ byte[] data = new byte[] {
+ (byte)0x95, // ID
+ 0x00, // Length
+ 0x10, // ALGTYPE = Compression Algorithm
+ 0x00, // Reserved
+ (byte)0x83, // COMPRID = JPEG
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ _compression, // MARKER
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ };
+ data[1] = (byte)(data.length - 2);
+ return data;
+ }
+ return new byte[0];
+ }
+
+ /**
+ * Helper method to return the image encoding parameter.
+ * @return byte[] The data stream.
+ */
+ private byte[] getImageIDESizeParameter() {
+
+ byte[] data = new byte[] {
+ (byte)0x96, // ID
+ 0x01, // Length
+ _size,
+ };
+
+ return data;
+
+ }
+
+ /**
+ * Helper method to return the external algorithm parameter.
+ * @return byte[] The data stream.
+ */
+ private byte[] getIDEStructureParameter() {
+
+ if (_colorModel != 0 && _size == 24) {
+ byte bits = (byte)(_size / 3);
+ byte[] data = new byte[] {
+ (byte)0x9B, // ID
+ 0x00, // Length
+ 0x00, // FLAGS
+ 0x00, // Reserved
+ _colorModel, // COLOR MODEL
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Reserved
+ bits,
+ bits,
+ bits,
+ };
+ data[1] = (byte)(data.length - 2);
+ return data;
+ }
+ return new byte[0];
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ */
+public class ImageDataDescriptor extends AbstractAFPObject {
+
+ private int _xresol = 0;
+ private int _yresol = 0;
+ private int _width = 0;
+ private int _height = 0;
+
+ /**
+ * Constructor for a ImageDataDescriptor for the specified
+ * resolution, width and height.
+ * @param xresol The horizontal resolution of the image.
+ * @param yresol The vertical resolution of the image.
+ * @param width The width of the image.
+ * @param height The height of the height.
+ */
+ public ImageDataDescriptor(int xresol, int yresol, int width, int height) {
+
+ _xresol = xresol;
+ _yresol = yresol;
+ _width = width;
+ _height = height;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Data Descriptor
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A,
+ 0x00,
+ 0x20,
+ (byte) 0xD3,
+ (byte) 0xA6,
+ (byte) 0xFB,
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Unit base - 10 Inches
+ 0x00, // XRESOL
+ 0x00, //
+ 0x00, // YRESOL
+ 0x00, //
+ 0x00, // XSIZE
+ 0x00, //
+ 0x00, // YSIZE
+ 0x00, //
+ (byte)0xF7, // ID = Set IOCA Function Set
+ 0x02, // Length
+ 0x01, // Category = Function set identifier
+ 0x0B, // FCNSET = IOCA FS 11
+ };
+
+ byte[] l = BinaryUtils.convert(data.length - 1, 2);
+ data[1] = l[0];
+ data[2] = l[1];
+
+ byte[] x = BinaryUtils.convert(_xresol, 2);
+ data[10] = x[0];
+ data[11] = x[1];
+
+ byte[] y = BinaryUtils.convert(_yresol, 2);
+ data[12] = y[0];
+ data[13] = y[1];
+
+ byte[] w = BinaryUtils.convert(_width, 2);
+ data[14] = w[0];
+ data[15] = w[1];
+
+ byte[] h = BinaryUtils.convert(_height, 2);
+ data[16] = h[0];
+ data[17] = h[1];
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The IM Image Input Descriptor structured field contains the
+ * descriptor data for an IM image data object. This data specifies
+ * the resolution, size, and color of the IM image.
+ */
+public class ImageInputDescriptor extends AbstractAFPObject {
+
+ /**
+ * The resolution of the raster image (default 240)
+ */
+ private int _resolution = 240;
+
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Input Descriptor
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[45];
+
+ data[0] = 0x5A;
+ data[1] = 0x00;
+ data[2] = 0x2C;
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xA6;
+ data[5] = (byte) 0x7B;
+ data[6] = 0x00;
+ data[7] = 0x00;
+ data[8] = 0x00;
+
+ // Constant data.
+ data[9] = 0x00;
+ data[10] = 0x00;
+ data[11] = 0x09;
+ data[12] = 0x60;
+ data[13] = 0x09;
+ data[14] = 0x60;
+ data[15] = 0x00;
+ data[16] = 0x00;
+ data[17] = 0x00;
+ data[18] = 0x00;
+ data[19] = 0x00;
+ data[20] = 0x00;
+
+ // X Base (Fixed x00)
+ data[21] = 0x00;
+ // Y Base (Fixed x00)
+ data[22] = 0x00;
+
+ byte[] imagepoints = BinaryUtils.convert(_resolution * 10, 2);
+
+ /**
+ * Specifies the number of image points per unit base for the X axis
+ * of the image. This value is ten times the resolution of the image
+ * in the X direction.
+ */
+ data[23] = imagepoints[0];
+ data[24] = imagepoints[1];
+
+ /**
+ * Specifies the number of image points per unit base for the Y axis
+ * of the image. This value is ten times the resolution of the image
+ * in the Y direction.
+ */
+ data[25] = imagepoints[0];
+ data[26] = imagepoints[1];
+
+ /**
+ * Specifies the extent in the X direction, in image points, of an
+ * non-celled (simple) image.
+ */
+ data[27] = 0x00;
+ data[28] = 0x01;
+
+ /**
+ * Specifies the extent in the Y direction, in image points, of an
+ * non-celled (simple) image.
+ */
+ data[29] = 0x00;
+ data[30] = 0x01;
+
+ // Constant Data
+ data[31] = 0x00;
+ data[32] = 0x00;
+ data[33] = 0x00;
+ data[34] = 0x00;
+ data[35] = 0x2D;
+ data[36] = 0x00;
+
+ // Default size of image cell in X direction
+ data[37] = 0x00;
+ data[38] = 0x01;
+
+ // Default size of image cell in Y direction
+ data[39] = 0x00;
+ data[40] = 0x01;
+
+ // Constant Data
+ data[41] = 0x00;
+ data[42] = 0x01;
+
+ // Image Color
+ data[43] = (byte)0xFF;
+ data[44] = (byte)0xFF;
+
+ os.write(data);
+
+ }
+
+ /**
+ * Sets the resolution information for the raster image
+ * the default value is a resolution of 240 dpi.
+ * @param resolution The resolution value
+ */
+ public void setResolution(int resolution) {
+ _resolution = resolution;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * An IOCA Image Data Object
+ */
+public class ImageObject extends AbstractNamedAFPObject {
+
+ /**
+ * The object environment group
+ */
+ private ObjectEnvironmentGroup _objectEnvironmentGroup = null;
+
+ /**
+ * The image segment
+ */
+ private ImageSegment _imageSegment = null;
+
+ /**
+ * Constructor for the image object with the specified name,
+ * the name must be a fixed length of eight characters.
+ * @param name The name of the image.
+ */
+ public ImageObject(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Sets the image display area position and size.
+ *
+ * @param x
+ * the x position of the image
+ * @param y
+ * the y position of the image
+ * @param w
+ * the width of the image
+ * @param h
+ * the height of the image
+ * @param r
+ * the rotation of the image
+ */
+ public void setImageViewport(int x, int y, int w, int h, int r) {
+ if (_objectEnvironmentGroup == null) {
+ _objectEnvironmentGroup = new ObjectEnvironmentGroup();
+ }
+ _objectEnvironmentGroup.setObjectArea(x, y, w, h, r);
+ }
+
+ /**
+ * Set the dimensions of the image.
+ * @param xresol the x resolution of the image
+ * @param yresol the y resolution of the image
+ * @param width the image width
+ * @param height the image height
+ */
+ public void setImageParameters(int xresol, int yresol, int width, int height) {
+ if (_objectEnvironmentGroup == null) {
+ _objectEnvironmentGroup = new ObjectEnvironmentGroup();
+ }
+ _objectEnvironmentGroup.setImageData(xresol, yresol, width, height);
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageSize(xresol, yresol, width, height);
+ }
+
+ /**
+ * Sets the image encoding.
+ * @param encoding The image encoding.
+ */
+ public void setImageEncoding(byte encoding) {
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageEncoding(encoding);
+ }
+
+ /**
+ * Sets the image compression.
+ * @param compression The image compression.
+ */
+ public void setImageCompression(byte compression) {
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageCompression(compression);
+ }
+
+ /**
+ * Sets the image IDE size.
+ * @param size The IDE size.
+ */
+ public void setImageIDESize(byte size) {
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageIDESize(size);
+ }
+
+ /**
+ * Sets the image IDE color model.
+ * @param size The IDE color model.
+ */
+ public void setImageIDEColorModel(byte colorModel) {
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageIDEColorModel(colorModel);
+ }
+
+ /**
+ * Set the data of the image.
+ * @param data The image data
+ */
+ public void setImageData(byte data[]) {
+ if (_imageSegment == null) {
+ _imageSegment = new ImageSegment();
+ }
+ _imageSegment.setImageData(data);
+ }
+
+ /**
+ * Sets the ObjectEnvironmentGroup.
+ * @param objectEnvironmentGroup The objectEnvironmentGroup to set
+ */
+ public void setObjectEnvironmentGroup(ObjectEnvironmentGroup objectEnvironmentGroup) {
+ _objectEnvironmentGroup = objectEnvironmentGroup;
+ }
+
+ /**
+ * Helper method to return the start of the image object.
+ * @return byte[] The data stream.
+ */
+ private byte[] getIPDStart(int len) {
+
+ byte[] data = new byte[] {
+
+ 0x5A, // Structured field identifier
+ 0x00, // Length byte 1
+ 0x10, // Length byte 2
+ (byte) 0xD3, // Structured field id byte 1
+ (byte) 0xEE, // Structured field id byte 2
+ (byte) 0xFB, // Structured field id byte 3
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ };
+
+ byte[] l = BinaryUtils.convert(len + 8, 2);
+ data[1] = l[0];
+ data[2] = l[1];
+
+ return data;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Object
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ if (_objectEnvironmentGroup != null) {
+ _objectEnvironmentGroup.writeDataStream(os);
+ }
+
+ if (_imageSegment != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ _imageSegment.writeDataStream(baos);
+ byte b[] = baos.toByteArray();
+ int off = 0;
+ while (off < b.length) {
+ int len = Math.min(30000, b.length - off);
+ os.write(getIPDStart(len));
+ os.write(b, off, len);
+ off += len;
+ }
+ }
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the Image Object.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xFB; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the Image Object.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xFB; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The IM Image Output Control structured field specifies the position and
+ * orientation of the IM image object area and the mapping of the image points
+ * to presentation device pels.
+ *
+ */
+public class ImageOutputControl extends AbstractAFPObject {
+
+ /**
+ * The orientation of the image
+ */
+ private int _orientation = 0;
+
+ /**
+ * Specifies the offset, along the X-axis, of the IM image object area
+ * origin to the origin of the including page
+ */
+ private int _Xcoordinate = 0;
+
+ /**
+ * Specifies the offset, along the Y-axis, of the IM image object area
+ * origin to the origin of the including page
+ */
+ private int _Ycoordinate = 0;
+
+ /**
+ * Map an image point to a single presentation device pel
+ */
+ private boolean _singlepoint = true;
+
+ /**
+ * Constructor for the ImageOutputControl The x parameter specifies the
+ * offset, along the X-axis, of the IM image object area origin to the
+ * origin of the including page and the y parameter specifies the offset
+ * along the Y-axis. The offset is specified in image points and is resolved
+ * using the units of measure specified for the image in the IID structured
+ * field.
+ *
+ * @param x
+ * The X-axis offset.
+ * @param y
+ * The Y-axis offset.
+ */
+ public ImageOutputControl(int x, int y) {
+
+ _Xcoordinate = x;
+ _Ycoordinate = y;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Output Control
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[33];
+
+ data[0] = 0x5A;
+ data[1] = 0x00;
+ data[2] = 0x20;
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xA7;
+ data[5] = (byte) 0x7B;
+ data[6] = 0x00;
+ data[7] = 0x00;
+ data[8] = 0x00;
+
+ // XoaOset
+ byte[] x1 = BinaryUtils.convert(_Xcoordinate, 3);
+ data[9] = x1[0];
+ data[10] = x1[1];
+ data[11] = x1[2];
+
+ // YoaOset
+ byte[] x2 = BinaryUtils.convert(_Ycoordinate, 3);
+ data[12] = x2[0];
+ data[13] = x2[1];
+ data[14] = x2[2];
+
+ switch (_orientation) {
+ case 0:
+ // 0 and 90 degrees respectively
+ data[15] = 0x00;
+ data[16] = 0x00;
+ data[17] = 0x2D;
+ data[18] = 0x00;
+ break;
+ case 90:
+ // 90 and 180 degrees respectively
+ data[15] = 0x2D;
+ data[16] = 0x00;
+ data[17] = 0x5A;
+ data[18] = 0x00;
+ break;
+ case 180:
+ // 180 and 270 degrees respectively
+ data[15] = 0x5A;
+ data[16] = 0x00;
+ data[17] = (byte) 0x87;
+ data[18] = 0x00;
+ break;
+ case 270:
+ // 270 and 0 degrees respectively
+ data[15] = (byte) 0x87;
+ data[16] = 0x00;
+ data[17] = 0x00;
+ data[18] = 0x00;
+ break;
+ default:
+ // 0 and 90 degrees respectively
+ data[15] = 0x00;
+ data[16] = 0x00;
+ data[17] = 0x2D;
+ data[18] = 0x00;
+ break;
+
+ }
+
+ // Constant Data
+ data[19] = 0x00;
+ data[20] = 0x00;
+ data[21] = 0x00;
+ data[22] = 0x00;
+ data[23] = 0x00;
+ data[24] = 0x00;
+ data[25] = 0x00;
+ data[26] = 0x00;
+
+ if (_singlepoint) {
+ data[27] = 0x03;
+ data[28] = (byte) 0xE8;
+ data[29] = 0x03;
+ data[30] = (byte) 0xE8;
+ } else {
+ data[27] = 0x07;
+ data[28] = (byte) 0xD0;
+ data[29] = 0x07;
+ data[30] = (byte) 0xD0;
+ }
+
+ // Constant Data
+ data[31] = (byte) 0xFF;
+ data[32] = (byte) 0xFF;
+
+ os.write(data);
+
+ }
+
+ /**
+ * Sets the orientation which specifies the amount of clockwise rotation of
+ * the IM image object area.
+ *
+ * @param orientation
+ * The orientation to set.
+ */
+ public void setOrientation(int orientation) {
+
+ if (orientation == 0 || orientation == 90 || orientation == 180
+ || orientation == 270) {
+ _orientation = orientation;
+ } else {
+ throw new IllegalArgumentException(
+ "The orientation must be one of the values 0, 90, 180, 270");
+ }
+
+ }
+
+ /**
+ * Sets the singlepoint, if true map an image point to a single presentation
+ * device pel in the IM image object area. If false map an image point to
+ * two presentation device pels in the IM image object area (double-dot)
+ *
+ * @param singlepoint
+ * Use the singlepoint basis when true.
+ */
+ public void setSinglepoint(boolean singlepoint) {
+ _singlepoint = singlepoint;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * Contains the image points that define the IM image raster pattern.
+ *
+ * A raster pattern is the array of presentation device pels that forms
+ * the image. The image data is uncompressed. Bits are grouped into
+ * bytes and are ordered from left to right within each byte. Each bit
+ * in the image data represents an image point and is mapped to
+ * presentation device pels as specified in the IOC structured field.
+ * A bit with value B'1' indicates a significant image point; a bit
+ * with value B'0' indicates an insignificant image point.
+ * Image points are recorded from left to right in rows that represents
+ * scan lines (X direction), and rows representing scan lines are
+ * recorded from top to bottom (Y direction). When the image is
+ * presented, all image points in a row are presented before any
+ * image points in the next sequential row are presented, and all rows
+ * have the same number of image points. If the total number of image
+ * points is not a multiple of 8, the last byte of the image data is
+ * padded to a byte boundary. The padding bits do not represent image
+ * points and are ignored by presentation devices.
+ */
+public class ImageRasterData extends AbstractAFPObject {
+
+ /**
+ * The image raster data
+ */
+ private byte[] _rasterdata;
+
+ /**
+ * Constructor for the image raster data object
+ * @param rasterdata The raster image data
+ */
+ public ImageRasterData(byte[] rasterdata) {
+
+ _rasterdata = rasterdata;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Raster Data
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[9];
+
+ data[0] = 0x5A;
+
+ // The size of the structured field
+ byte[] x = BinaryUtils.convert(_rasterdata.length + 8, 2);
+ data[1] = x[0];
+ data[2] = x[1];
+
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xEE;
+ data[5] = (byte) 0x7B;
+ data[6] = 0x00;
+ data[7] = 0x00;
+ data[8] = 0x00;
+
+ os.write(data);
+ os.write(_rasterdata);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+/**
+ * Raster data is a grid of cells covering an area of interest.
+ * Each pixel, the smallest unit of information in the grid, displays
+ * a unique attribute. This static class generates raster data for different
+ * shades of grey (betweeen 0 and 16) the lower the number being the
+ * darker the shade. The image data dimensions are 64 x 8.
+ */
+public class ImageRasterPattern {
+
+ /**
+ * The Raster Pattern for Greyscale 16
+ */
+ private static final byte[] GREYSCALE16 = new byte[] {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 15
+ */
+ private static final byte[] GREYSCALE15 = new byte[] {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 14
+ */
+ private static final byte[] GREYSCALE14 = new byte[] {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 13
+ */
+ private static final byte[] GREYSCALE13 = new byte[] {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 12
+ */
+ private static final byte[] GREYSCALE12 = new byte[] {
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 11
+ */
+ private static final byte[] GREYSCALE11 = new byte[] {
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 10
+ */
+ private static final byte[] GREYSCALE10 = new byte[] {
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ 0x44,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 9
+ */
+ private static final byte[] GREYSCALE09 = new byte[] {
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 8
+ */
+ private static final byte[] GREYSCALE08 = new byte[] {
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 7
+ */
+ private static final byte[] GREYSCALE07 = new byte[] {
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 6
+ */
+ private static final byte[] GREYSCALE06 = new byte[] {
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 5
+ */
+ private static final byte[] GREYSCALE05 = new byte[] {
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xEE,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 4
+ */
+ private static final byte[] GREYSCALE04 = new byte[] {
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xAA,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 3
+ */
+ private static final byte[] GREYSCALE03 = new byte[] {
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ 0x55,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xBB,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ };
+
+ /**
+ * The Raster Pattern for Greyscale 2
+ */
+ private static final byte[] GREYSCALE02 = new byte[] {
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xDD,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 1
+ */
+ private static final byte[] GREYSCALE01 = new byte[] {
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ 0x77,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ };
+
+
+ /**
+ * The Raster Pattern for Greyscale 00
+ */
+ private static final byte[] GREYSCALE00 = new byte[] {
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ (byte)0xFF,
+ };
+
+ /**
+ * Static method to return the raster image data for the
+ * grey scale specified. The scale should be between 0 (darkest)
+ * and 16 (lightest).
+ * @param greyscale The grey scale value (0 - 16)
+ */
+ public static byte[] getRasterData(int greyscale) {
+
+ int repeat = 16;
+
+ byte[] greypattern = new byte[32];
+ byte[] rasterdata = new byte[32 * repeat];
+
+ switch (greyscale) {
+ case 0:
+ System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32);
+ break;
+ case 1:
+ System.arraycopy(GREYSCALE01, 0, greypattern, 0, 32);
+ break;
+ case 2:
+ System.arraycopy(GREYSCALE02, 0, greypattern, 0, 32);
+ break;
+ case 3:
+ System.arraycopy(GREYSCALE03, 0, greypattern, 0, 32);
+ break;
+ case 4:
+ System.arraycopy(GREYSCALE04, 0, greypattern, 0, 32);
+ break;
+ case 5:
+ System.arraycopy(GREYSCALE05, 0, greypattern, 0, 32);
+ break;
+ case 6:
+ System.arraycopy(GREYSCALE06, 0, greypattern, 0, 32);
+ break;
+ case 7:
+ System.arraycopy(GREYSCALE07, 0, greypattern, 0, 32);
+ break;
+ case 8:
+ System.arraycopy(GREYSCALE08, 0, greypattern, 0, 32);
+ break;
+ case 9:
+ System.arraycopy(GREYSCALE09, 0, greypattern, 0, 32);
+ break;
+ case 10:
+ System.arraycopy(GREYSCALE10, 0, greypattern, 0, 32);
+ break;
+ case 11:
+ System.arraycopy(GREYSCALE11, 0, greypattern, 0, 32);
+ break;
+ case 12:
+ System.arraycopy(GREYSCALE12, 0, greypattern, 0, 32);
+ break;
+ case 13:
+ System.arraycopy(GREYSCALE13, 0, greypattern, 0, 32);
+ break;
+ case 14:
+ System.arraycopy(GREYSCALE14, 0, greypattern, 0, 32);
+ break;
+ case 15:
+ System.arraycopy(GREYSCALE15, 0, greypattern, 0, 32);
+ break;
+ case 16:
+ System.arraycopy(GREYSCALE16, 0, greypattern, 0, 32);
+ break;
+ default :
+ System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32);
+ break;
+ }
+
+ for (int i = 0; i < repeat; i++) {
+
+ System.arraycopy(greypattern, 0, rasterdata, i * 32, 32);
+
+ }
+
+ return rasterdata;
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * An Image Segment is represented by a set of self-defining fields, fields
+ * that describe their own contents. It starts with a Begin Segment, and
+ * ends with an End Segment.
+ *
+ * Between the Begin Segment and End Segment is the image information to
+ * be processed, called the Image Content.
+ *
+ * Only one Image Content can exist within a single IOCA Image Segment.
+ */
+public class ImageSegment extends AbstractAFPObject {
+
+ /**
+ * Default name for the object environment group
+ */
+ private static final String DEFAULT_NAME = "IS01";
+
+ /**
+ * The name of the image segment
+ */
+ private String _name;
+
+ /**
+ * The name of the image segment as EBCIDIC bytes
+ */
+ private byte[] _nameBytes;
+
+ /**
+ * The ImageContent for the image segment
+ */
+ private ImageContent _imageContent = null;
+
+ /**
+ * Default constructor for the ImageSegment.
+ */
+ public ImageSegment() {
+
+ this(DEFAULT_NAME);
+
+ }
+
+ /**
+ * Constructor for the image segment with the specified name,
+ * the name must be a fixed length of eight characters.
+ * @param name The name of the image.
+ */
+ public ImageSegment(String name) {
+
+ if (name.length() != 4) {
+ String msg = "Image segment name must be 4 characters long " + name;
+ log.error("Constructor:: " + msg);
+ throw new IllegalArgumentException(msg);
+ }
+
+ _name = name;
+
+ try {
+
+ _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
+
+ } catch (UnsupportedEncodingException usee) {
+
+ _nameBytes = name.getBytes();
+ log.warn(
+ "Constructor:: UnsupportedEncodingException translating the name "
+ + name);
+
+ }
+
+ }
+
+ /**
+ * Sets the image size parameters
+ * resolution, hsize and vsize.
+ * @param hresol The horizontal resolution of the image.
+ * @param vresol The vertical resolution of the image.
+ * @param hsize The horizontal size of the image.
+ * @param vsize The vertival size of the image.
+ */
+ public void setImageSize(int hresol, int vresol, int hsize, int vsize) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageSize(hresol, vresol, hsize, vsize);
+ }
+
+ /**
+ * Sets the image encoding.
+ * @param encoding The image encoding.
+ */
+ public void setImageEncoding(byte encoding) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageEncoding(encoding);
+ }
+
+ /**
+ * Sets the image compression.
+ * @param compression The image compression.
+ */
+ public void setImageCompression(byte compression) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageCompression(compression);
+ }
+
+ /**
+ * Sets the image IDE size.
+ * @param size The IDE size.
+ */
+ public void setImageIDESize(byte size) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageIDESize(size);
+ }
+
+ /**
+ * Sets the image IDE color model.
+ * @param size The IDE color model.
+ */
+ public void setImageIDEColorModel(byte colorModel) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageIDEColorModel(colorModel);
+ }
+
+ /**
+ * Set the data of the image.
+ * @param data the image data
+ */
+ public void setImageData(byte data[]) {
+ if (_imageContent == null) {
+ _imageContent = new ImageContent();
+ }
+ _imageContent.setImageData(data);
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Segment
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ if (_imageContent != null) {
+ _imageContent.writeDataStream(os);
+ }
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the Image Segment.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x70, // ID
+ 0x04, // Length
+ 0x00, // Name byte 1
+ 0x00, // Name byte 2
+ 0x00, // Name byte 3
+ 0x00, // Name byte 4
+ };
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[2 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the Image Segment.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x71, // ID
+ 0x00, // Length
+ };
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * Describes the measurement characteristics of the image when it is created.
+ */
+public class ImageSizeParameter extends AbstractAFPObject {
+
+ private int _hresol = 0;
+ private int _vresol = 0;
+ private int _hsize = 0;
+ private int _vsize = 0;
+
+ /**
+ * Constructor for a ImageSizeParameter for the specified
+ * resolution, hsize and vsize.
+ * @param hresol The horizontal resolution of the image.
+ * @param vresol The vertical resolution of the image.
+ * @param hsize The hsize of the image.
+ * @param vsize The vsize of the vsize.
+ */
+ public ImageSizeParameter(int hresol, int vresol, int hsize, int vsize) {
+
+ _hresol = hresol;
+ _vresol = vresol;
+ _hsize = hsize;
+ _vsize = vsize;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Image Size Parameter
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ (byte)0x94, // ID = Image Size Parameter
+ 0x09, // Length
+ 0x00, // Unit base - 10 Inches
+ 0x00, // HRESOL
+ 0x00, //
+ 0x00, // VRESOL
+ 0x00, //
+ 0x00, // HSIZE
+ 0x00, //
+ 0x00, // VSIZE
+ 0x00, //
+ };
+
+ byte[] x = BinaryUtils.convert(_hresol, 2);
+ data[3] = x[0];
+ data[4] = x[1];
+
+ byte[] y = BinaryUtils.convert(_vresol, 2);
+ data[5] = y[0];
+ data[6] = y[1];
+
+ byte[] w = BinaryUtils.convert(_hsize, 2);
+ data[7] = w[0];
+ data[8] = w[1];
+
+ byte[] h = BinaryUtils.convert(_vsize, 2);
+ data[9] = h[0];
+ data[10] = h[1];
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * An Include Object structured field references an object on a page or overlay.
+ * It optionally contains parameters that identify the object and that specify
+ * presentation parameters such as object position, size, orientation, mapping,
+ * and default color.
+ * <p>
+ * Where the presentation parameters conflict with parameters specified in the
+ * object's environment group (OEG), the parameters in the Include Object
+ * structured field override. If the referenced object is a page segment, the
+ * IOB parameters override the corresponding environment group parameters on all
+ * data objects in the page segment.
+ * </p>
+ */
+public class IncludeObject extends AbstractNamedAFPObject {
+
+ /**
+ * The object type
+ */
+ private byte _objectType = (byte) 0x92;
+
+ /**
+ * The orientation on the include object
+ */
+ private int _orientation = 0;
+
+ /**
+ * Constructor for the include object with the specified name, the name must
+ * be a fixed length of eight characters and is the name of the referenced
+ * object.
+ *
+ * @param name
+ * the name of the image
+ */
+ public IncludeObject(String name) {
+
+ super(name);
+ _objectType = (byte) 0xFB;
+
+ }
+
+ /**
+ * Sets the orienation to use for the Include Object.
+ *
+ * @param orientation
+ * The orientation (0,90, 180, 270)
+ */
+ public void setOrientation(int orientation) {
+
+ if (orientation == 0 || orientation == 90 || orientation == 180
+ || orientation == 270) {
+ _orientation = orientation;
+ } else {
+ throw new IllegalArgumentException(
+ "The orientation must be one of the values 0, 90, 180, 270");
+ }
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Include Object
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[37];
+
+ data[0] = 0x5A;
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(36, 2); //Ignore first byte
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a IOB
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAF;
+ data[5] = (byte) 0xC3;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+ data[9 + i] = _nameBytes[i];
+ }
+
+ data[17] = 0x00;
+ data[18] = _objectType;
+
+ // XoaOset
+ data[20] = (byte) 0xFF;
+ data[21] = (byte) 0xFF;
+ data[22] = (byte) 0xFF;
+
+ // YoaOset
+ data[23] = (byte) 0xFF;
+ data[24] = (byte) 0xFF;
+ data[25] = (byte) 0xFF;
+
+ switch (_orientation) {
+ case 90:
+ data[26] = 0x2D;
+ data[27] = 0x00;
+ data[28] = 0x5A;
+ data[29] = 0x00;
+ break;
+ case 180:
+ data[26] = 0x5A;
+ data[27] = 0x00;
+ data[28] = (byte) 0x87;
+ data[29] = 0x00;
+ break;
+ case 270:
+ data[26] = (byte) 0x87;
+ data[27] = 0x00;
+ data[28] = 0x00;
+ data[29] = 0x00;
+ break;
+ default:
+ data[26] = 0x00;
+ data[27] = 0x00;
+ data[28] = 0x2D;
+ data[29] = 0x00;
+ break;
+ }
+
+ // XocaOset
+ data[30] = (byte) 0xFF;
+ data[31] = (byte) 0xFF;
+ data[32] = (byte) 0xFF;
+
+ // YocaOset
+ data[33] = (byte) 0xFF;
+ data[34] = (byte) 0xFF;
+ data[35] = (byte) 0xFF;
+
+ data[36] = 0x01;
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ *
+ * The Include Page Overlay structured field references an overlay resource
+ * definition that is to be positioned on the page. A page overlay can be
+ * referenced at any time during the page state, but not during an object state.
+ * The overlay contains its own active environment group definition.
+ *
+ * Note: There is no need for the triplets, so I have ignored them.
+ *
+ * A real example of where this will be used is for static overlays, such as an
+ * address on the page.
+ *
+ */
+public class IncludePageOverlay extends AbstractNamedAFPObject {
+
+ /**
+ * The x coordinate
+ */
+ private int _xCoor = 0;
+
+ /**
+ * The y coordinate
+ */
+ private int _yCoor = 0;
+
+ /**
+ * The orientation
+ */
+ private int _orientation = 0;
+
+ /**
+ * Constructor for the Include Page Overlay
+ * @param overlayName Name of the page segment
+ * @param x The x position
+ * @param y The y position
+ * @param orientation The orientation
+ */
+ public IncludePageOverlay(String overlayName, int x, int y, int orientation) {
+
+ super(overlayName);
+
+ _xCoor = x;
+ _yCoor = y;
+ setOrientation(orientation);
+ }
+
+ /**
+ * Sets the orienation to use for the overlay.
+ *
+ * @param orientation
+ * The orientation (0,90, 180, 270)
+ */
+ public void setOrientation(int orientation) {
+
+ if (orientation == 0 || orientation == 90 || orientation == 180
+ || orientation == 270) {
+ _orientation = orientation;
+ } else {
+ throw new IllegalArgumentException(
+ "The orientation must be one of the values 0, 90, 180, 270");
+ }
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Include Page Overlay
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[25]; //(9 +16)
+
+ data[0] = 0x5A;
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(24, 2); //Ignore first byte
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a IPO
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAF;
+ data[5] = (byte) 0xD8;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ byte[] r2 = BinaryUtils.convert(_xCoor, 3);
+ data[17] = r2[0]; // x coordinate
+ data[18] = r2[1];
+ data[19] = r2[2];
+
+ byte[] r3 = BinaryUtils.convert(_yCoor, 3);
+ data[20] = r3[0]; // y coordinate
+ data[21] = r3[1];
+ data[22] = r3[2];
+
+ switch (_orientation) {
+ case 90:
+ data[23] = 0x2D;
+ data[24] = 0x00;
+ break;
+ case 180:
+ data[23] = 0x5A;
+ data[24] = 0x00;
+ break;
+ case 270:
+ data[23] = (byte) 0x87;
+ data[24] = 0x00;
+ break;
+ default:
+ data[23] = 0x00;
+ data[24] = 0x00;
+ break;
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Include Page Segment structured field references a page segment resource
+ * object that is to be presented on the page or overlay presentation space. The IPS
+ * specifies a reference point on the including page or overlay coordinate system that
+ * may be used to position objects contained in the page segment. A page segment
+ * can be referenced at any time during page or overlay state, but not during an
+ * object state. The page segment inherits the active environment group definition of
+ * the including page or overlay.
+ *
+ * Note : No use for Triplets.
+ *
+ * A 'real' example for where this will be used is for
+ * the dynamic placing of overlay objects, such as signatures
+ * that may have to be placed at different positions on a document.
+ *
+ */
+public class IncludePageSegment extends AbstractNamedAFPObject{
+
+ /**
+ * The x position where we need to put this object on the page
+ */
+ private byte [] _xCoor;
+
+ /**
+ * The y position where we need to put this object on the page
+ */
+ private byte [] _yCoor;
+
+ /**
+ * Constructor for the Include Page Segment
+ * @param name Name of the page segment
+ * @param xVal The x position
+ * @param yVal The y position
+ */
+ public IncludePageSegment(String name, int xVal, int yVal){
+
+ super(name);
+ _xCoor = BinaryUtils.convert(xVal, 3);
+ _yCoor = BinaryUtils.convert(yVal, 3);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Include Page Segment
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[23]; //(9 +14)
+
+ data[0] = 0x5A;
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(22, 2); //Ignore first byte
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a IPS
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAF;
+ data[5] = (byte) 0x5F;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ data[17] = _xCoor[0]; // x coordinate
+ data[18] = _xCoor[1];
+ data[19] = _xCoor[2];
+
+ data[20] = _yCoor[0]; // y coordinate
+ data[21] = _yCoor[1];
+ data[22] = _yCoor[2];
+
+ os.write(data);
+
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Invoke Medium Map structured field identifies the Medium Map that is to
+ * become active for the document. An Invoke Medium Map structured field affects
+ * the document's current environment. The Medium Map's effect on current environment
+ * parameter values lasts until a new Medium Map is invoked.
+ */
+public class InvokeMediumMap extends AbstractNamedAFPObject {
+
+ /**
+ * Constructor for the Invoke Medium Map
+ * @param mediumMapName Name of the medium map
+ */
+ public InvokeMediumMap(String mediumMapName) {
+
+ super(mediumMapName);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Invoke Medium Map
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A;
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(16, 2); //Ignore first byte
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a IPO
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAB;
+ data[5] = (byte) 0xCC;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import org.apache.fop.render.afp.exceptions.FontRuntimeException;
+import org.apache.fop.render.afp.fonts.AFPFont;
+import org.apache.fop.render.afp.fonts.CharacterSet;
+import org.apache.fop.render.afp.fonts.OutlineFont;
+import org.apache.fop.render.afp.fonts.RasterFont;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Map Coded Font structured field maps a unique coded font resource local
+ * ID, which may be embedded one or more times within an object's data and
+ * descriptor, to the identifier of a coded font resource object. Additionally,
+ * the Map Coded Font structured field specifies a set of resource attributes
+ * for the coded font.
+ *
+ * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
+ */
+public class MapCodedFont extends AbstractAFPObject {
+
+ /**
+ * The collection of map coded fonts (maximum of 254)
+ */
+ private ArrayList _fontlist = null;
+
+ /**
+ * Constructor for the MapCodedFont
+ */
+ public MapCodedFont() {
+
+ _fontlist = new ArrayList();
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Map Coded Font
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ baos.write(0x5A);
+ baos.write(new byte[] { 0x00, 0x00 });
+
+ // Field identifier for a MapCodedFont
+ baos.write(new byte[] { (byte) 0xD3, (byte) 0xAB, (byte) 0x8A });
+
+ // Reserved
+ baos.write(new byte[] { 0x00, 0x00, 0x00 });
+
+ for (int i = 0; i < _fontlist.size(); i++) {
+
+ FontDefinition fd = (FontDefinition) _fontlist.get(i);
+
+ // Start of repeating groups (occurs 1 to 254)
+ baos.write(0x00);
+
+ if (fd._scale == 0) {
+ // Raster Font
+ baos.write(0x22); // Length of 34
+ } else {
+ // Outline Font
+ baos.write(0x3A); // Length of 58
+ }
+
+ // Font Character Set Name Reference
+ baos.write(0x0C);
+ baos.write(0x02);
+ baos.write((byte) 0x86);
+ baos.write(0x00);
+ baos.write(fd._characterset);
+
+ // Font Code Page Name Reference
+ baos.write(0x0C);
+ baos.write(0x02);
+ baos.write((byte) 0x85);
+ baos.write(0x00);
+ baos.write(fd._codepage);
+
+ // Character Rotation
+ baos.write(0x04);
+ baos.write(0x26);
+ baos.write(fd._orientation);
+ baos.write(0x00);
+
+ // Resource Local Identifier
+ baos.write(0x04);
+ baos.write(0x24);
+ baos.write(0x05);
+ baos.write(fd._fontReferenceKey);
+
+ if (fd._scale != 0) {
+ // Outline Font (triplet '1F')
+ baos.write(0x14);
+ baos.write(0x1F);
+ baos.write(0x00);
+ baos.write(0x00);
+
+ baos.write(BinaryUtils.convert(fd._scale, 2)); // Height
+ baos.write(new byte[] { 0x00, 0x00 }); // Width
+
+ baos.write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00 });
+
+ baos.write(0x60);
+
+ // Outline Font (triplet '5D')
+ baos.write(0x04);
+ baos.write(0x5D);
+ baos.write(BinaryUtils.convert(fd._scale, 2));
+ }
+
+ }
+
+ byte[] data = baos.toByteArray();
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(data.length - 1, 2);
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ os.write(data);
+
+ }
+
+ /**
+ * Add a font definition on the the map coded font object.
+ *
+ * @param fontReference
+ * the font number used as the resource identifier
+ * @param font
+ * the font
+ * @param size
+ * the size of the font
+ * @param orientation
+ * the orientation of the font
+ */
+ public void addFont(byte fontReference, AFPFont font, int size, int orientation)
+ throws MaximumSizeExceededException {
+
+ FontDefinition fd = new FontDefinition();
+
+ fd._fontReferenceKey = fontReference;
+
+ switch (orientation) {
+ case 90:
+ fd._orientation = 0x2D;
+ break;
+ case 180:
+ fd._orientation = 0x5A;
+ break;
+ case 270:
+ fd._orientation = (byte) 0x87;
+ break;
+ default:
+ fd._orientation = 0x00;
+ break;
+ }
+
+ try {
+
+ if (font instanceof RasterFont) {
+
+ RasterFont raster = (RasterFont) font;
+ CharacterSet cs = raster.getCharacterSet(size);
+ if (cs == null) {
+ String msg = "Character set not found for font "
+ + font.getFontName() + " with point size " + size;
+ log.error(msg);
+ throw new FontRuntimeException(msg);
+ }
+
+ fd._characterset = cs.getNameBytes();
+
+ if (fd._characterset.length != 8) {
+ throw new IllegalArgumentException("The character set "
+ + new String(fd._characterset,
+ AFPConstants.EBCIDIC_ENCODING)
+ + " must have a fixed length of 8 characters.");
+ }
+
+ fd._codepage = cs.getCodePage().getBytes(
+ AFPConstants.EBCIDIC_ENCODING);
+
+ if (fd._codepage.length != 8) {
+ throw new IllegalArgumentException("The code page "
+ + new String(fd._codepage,
+ AFPConstants.EBCIDIC_ENCODING)
+ + " must have a fixed length of 8 characters.");
+ }
+
+ } else if (font instanceof OutlineFont) {
+
+ OutlineFont outline = (OutlineFont) font;
+ CharacterSet cs = outline.getCharacterSet();
+ fd._characterset = cs.getNameBytes();
+
+ // There are approximately 72 points to 1 inch or 20 1440ths per point.
+
+ fd._scale = ((size / 1000) * 20);
+
+ fd._codepage = cs.getCodePage().getBytes(
+ AFPConstants.EBCIDIC_ENCODING);
+
+ if (fd._codepage.length != 8) {
+ throw new IllegalArgumentException("The code page "
+ + new String(fd._codepage,
+ AFPConstants.EBCIDIC_ENCODING)
+ + " must have a fixed length of 8 characters.");
+ }
+
+ } else {
+ String msg = "Font of type " + font.getClass().getName()
+ + " not recognized.";
+ log.error(msg);
+ throw new FontRuntimeException(msg);
+ }
+
+ if (_fontlist.size() > 253) {
+
+ // Throw an exception if the size is exceeded
+ throw new MaximumSizeExceededException();
+
+ } else {
+
+ _fontlist.add(fd);
+
+ }
+
+ } catch (UnsupportedEncodingException ex) {
+
+ throw new FontRuntimeException("Failed to create font "
+ + " due to a UnsupportedEncodingException", ex);
+
+ }
+
+ }
+
+ /**
+ * Private utility class used as a container for font attributes
+ */
+ private class FontDefinition {
+
+ /**
+ * The code page of the font
+ */
+ private byte[] _codepage;
+
+ /**
+ * The character set of the font
+ */
+ private byte[] _characterset;
+
+ /**
+ * The font reference key
+ */
+ private byte _fontReferenceKey;
+
+ /**
+ * The orientation of the font
+ */
+ private byte _orientation;
+
+ /**
+ * The scale (only specified for outline fonts)
+ */
+ private int _scale = 0;
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Map Page Overlay structured field maps a Resource Local ID to the name of
+ * a Begin Overlay structured field. A Map Page Overlay structured field may
+ * contain from one to 254 repeating groups.
+ *
+ */
+public class MapPageOverlay extends AbstractAFPObject {
+
+ /**
+ * The collection of overlays (maximum of 254 stored as byte[])
+ */
+ private ArrayList _overLays = new ArrayList();
+
+ /**
+ * Constructor for the Map Page Overlay
+ */
+ public MapPageOverlay() {
+
+ }
+
+ /**
+ * Add an overlay to to the map page overlay object.
+ *
+ * @param name
+ * The name of the overlay.
+ */
+ public void addOverlay(String name) throws MaximumSizeExceededException {
+
+ if (_overLays.size() > 253) {
+ throw new MaximumSizeExceededException();
+ }
+
+ if (name.length() != 8) {
+ throw new IllegalArgumentException("The name of overlay " + name
+ + " must be 8 characters");
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("addOverlay():: adding overlay " + name);
+ }
+
+ byte[] data;
+
+ try {
+
+ data = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
+ _overLays.add(data);
+
+ } catch (UnsupportedEncodingException usee) {
+
+ log
+ .error("addOverlay():: UnsupportedEncodingException translating the name "
+ + name);
+
+ }
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Map Page Overlay
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+
+ int oLayCount = _overLays.size();
+ int recordlength = oLayCount * 18;
+
+ byte[] data = new byte[recordlength + 9];
+
+ data[0] = 0x5A;
+
+ // Set the total record length
+ byte[] rl1 = BinaryUtils.convert(recordlength + 8, 2); //Ignore the
+ // first byte in
+ // the length
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a MPO
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xAB;
+ data[5] = (byte) 0xD8;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ int pos = 8;
+
+ //For each overlay
+ byte olayref = 0x00;
+
+ for (int i = 0; i < oLayCount; i++) {
+
+ olayref = (byte) (olayref + 1);
+
+ data[++pos] = 0x00;
+ data[++pos] = 0x12; //the length of repeating group
+
+ data[++pos] = 0x0C; //Fully Qualified Name
+ data[++pos] = 0x02;
+ data[++pos] = (byte) 0x84;
+ data[++pos] = 0x00;
+
+ //now add the name
+ byte[] name = (byte[]) _overLays.get(i);
+
+ for (int j = 0; j < name.length; j++) {
+
+ data[++pos] = name[j];
+
+ }
+
+ data[++pos] = 0x04; //Resource Local Identifier (RLI)
+ data[++pos] = 0x24;
+ data[++pos] = 0x02;
+
+ //now add the unique id to the RLI
+ data[++pos] = olayref;
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+/**
+ * An exception to handle maximum sizes being exceeded.
+ *
+ */
+public class MaximumSizeExceededException extends Exception {
+
+ public MaximumSizeExceededException() {
+ super();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Object Area Descriptor structured field specifies the size and attributes
+ * of an object area presentation space.
+ *
+ */
+public class ObjectAreaDescriptor extends AbstractAFPObject {
+
+ private int _width = 0;
+ private int _height = 0;
+
+ /**
+ * Construct an object area descriptor for the specified object width
+ * and object height.
+ * @param width The page width.
+ * @param height The page height.
+ */
+ public ObjectAreaDescriptor(int width, int height) {
+
+ _width = width;
+ _height = height;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Object Area Descriptor
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A,
+ 0x00, // Length
+ 0x1C, // Length
+ (byte) 0xD3,
+ (byte) 0xA6,
+ (byte) 0x6B,
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x03, // Triplet length
+ 0x43, // tid = Descriptor Position Triplet
+ 0x01, // DesPosId = 1
+ 0x08, // Triplet length
+ 0x4B, // tid = Measurement Units Triplet
+ 0x00, // XaoBase = 10 inches
+ 0x00, // YaoBase = 10 inches
+ 0x09, // XaoUnits = 2400
+ 0x60, // XaoUnits =
+ 0x09, // YaoUnits = 2400
+ 0x60, // YaoUnits =
+ 0x09, // Triplet length
+ 0x4C, // tid = Object Area Size
+ 0x02, // Size Type
+ 0x00, // XoaSize
+ 0x00,
+ 0x00,
+ 0x00, // YoaSize
+ 0x00,
+ 0x00,
+ };
+
+ byte[] l = BinaryUtils.convert(data.length - 1, 2);
+ data[1] = l[0];
+ data[2] = l[1];
+
+ byte[] x = BinaryUtils.convert(_width, 3);
+ data[23] = x[0];
+ data[24] = x[1];
+ data[25] = x[2];
+
+ byte[] y = BinaryUtils.convert(_height, 3);
+ data[26] = y[0];
+ data[27] = y[1];
+ data[28] = y[2];
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Object Area Position structured field specifies the origin and
+ * orientation of the object area, and the origin and orientation of the
+ * object content within the object area.
+ */
+public class ObjectAreaPosition extends AbstractAFPObject {
+
+ private int _x = 0;
+ private int _y = 0;
+ private int _rot = 0;
+
+ /**
+ * Construct an object area position for the specified object y, y position.
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param rotation The coordinate system rotation (must be 0, 90, 180, 270).
+ */
+ public ObjectAreaPosition(int x, int y, int rotation) {
+
+ _x = x;
+ _y = y;
+ _rot = rotation;
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Object Area Position
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A,
+ 0x00, // Length
+ 0x20, // Length
+ (byte) 0xD3,
+ (byte) 0xAC,
+ (byte) 0x6B,
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x01, // OAPosID = 1
+ 0x17, // RGLength = 23
+ 0x00, // XoaOSet
+ 0x00,
+ 0x00,
+ 0x00, // YoaOSet
+ 0x00,
+ 0x00,
+ (byte)(_rot / 2), // XoaOrent
+ 0x00,
+ (byte)(_rot / 2 + 45), // YoaOrent
+ 0x00,
+ 0x00, // Reserved
+ 0x00, // XocaOSet
+ 0x00,
+ 0x00,
+ 0x00, // YocaOSet
+ 0x00,
+ 0x00,
+ 0x00, // XocaOrent
+ 0x00,
+ 0x2D, // YocaOrent
+ 0x00,
+ 0x01, // RefCSys
+ };
+
+ byte[] l = BinaryUtils.convert(data.length - 1, 2);
+ data[1] = l[0];
+ data[2] = l[1];
+
+ byte[] x = BinaryUtils.convert(_x, 3);
+ data[11] = x[0];
+ data[12] = x[1];
+ data[13] = x[2];
+
+ byte[] y = BinaryUtils.convert(_y, 3);
+ data[14] = y[0];
+ data[15] = y[1];
+ data[16] = y[2];
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+
+/**
+ * An Object Environment Group (OEG) may be associated with an object and is contained
+ * within the object's begin-end envelope.
+ * The object environment group defines the object's origin and orientation on the page,
+ * and can contain font and color attribute table information. The scope of an object
+ * environment group is the scope of its containing object.
+ *
+ * An application that creates a data-stream document may omit some of the parameters
+ * normally contained in the object environment group, or it may specify that one or
+ * more default values are to be used.
+ */
+public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject {
+
+ /**
+ * Default name for the object environment group
+ */
+ private static final String DEFAULT_NAME = "OEG00001";
+
+ /**
+ * The ObjectAreaDescriptor for the object environment group
+ */
+ private ObjectAreaDescriptor _objectAreaDescriptor = null;
+
+ /**
+ * The ObjectAreaPosition for the object environment group
+ */
+ private ObjectAreaPosition _objectAreaPosition = null;
+
+ /**
+ * The ImageDataDescriptor for the object environment group
+ */
+ private ImageDataDescriptor _imageDataDescriptor = null;
+
+ /**
+ * Default constructor for the ObjectEnvironmentGroup.
+ */
+ public ObjectEnvironmentGroup() {
+
+ this(DEFAULT_NAME);
+
+ }
+
+ /**
+ * Constructor for the ObjectEnvironmentGroup, this takes a
+ * name parameter which must be 8 characters long.
+ * @param name the object environment group name
+ */
+ public ObjectEnvironmentGroup(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Sets the object area parameters.
+ * @param x the x position of the object
+ * @param y the y position of the object
+ * @param width the object width
+ * @param height the object height
+ * @param rotation the object orientation
+ */
+ public void setObjectArea(int x, int y, int width, int height, int rotation) {
+
+ _objectAreaDescriptor = new ObjectAreaDescriptor(width, height);
+ _objectAreaPosition = new ObjectAreaPosition(x, y, rotation);
+
+ }
+
+ /**
+ * Set the dimensions of the image.
+ * @param xresol the x resolution of the image
+ * @param yresol the y resolution of the image
+ * @param width the image width
+ * @param height the image height
+ */
+ public void setImageData(int xresol, int yresol, int width, int height) {
+ _imageDataDescriptor = new ImageDataDescriptor(xresol, yresol, width, height);
+ }
+
+ /**
+ * Accessor method to obtain write the AFP datastream for
+ * the object environment group.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+
+ writeStart(os);
+
+ _objectAreaDescriptor.writeDataStream(os);
+
+ _objectAreaPosition.writeDataStream(os);
+
+ if (_imageDataDescriptor != null) {
+ _imageDataDescriptor.writeDataStream(os);
+ }
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the object environment group.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A, // Structured field identifier
+ 0x00, // Length byte 1
+ 0x10, // Length byte 2
+ (byte) 0xD3, // Structured field id byte 1
+ (byte) 0xA8, // Structured field id byte 2
+ (byte) 0xC7, // Structured field id byte 3
+ 0x00, // Flags
+ 0x00, // Reserved
+ 0x00, // Reserved
+ 0x00, // Name
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ 0x00, //
+ };
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the object environment group.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xC7; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+/**
+ */
+public class Overlay extends AbstractPageObject{
+
+ /**
+ * Construct a new overlay object for the specified name argument, the overlay
+ * name should be an 8 character identifier.
+ *
+ * @param name
+ * the name of the page.
+ * @param width
+ * the width of the page.
+ * @param height
+ * the height of the page.
+ * @param rotation
+ * the rotation of the page.
+ */
+ public Overlay(String name, int width, int height, int rotation) {
+
+ super(name, width, height, rotation);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the overlay.
+ *
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ _activeEnvironmentGroup.writeDataStream(os);
+
+ writeObjectList(_segments, os);
+
+ writeObjectList(_tagLogicalElements, os);
+
+ writeObjectList(_objects, os);
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the overlay.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xDF; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the overlay.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xDF; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Page Descriptor structured field specifies the size and attributes of
+ * a page or overlay presentation space.
+ *
+ */
+public class PageDescriptor extends AbstractAFPObject {
+
+ private int _width = 0;
+ private int _height = 0;
+
+ /**
+ * Construct a page descriptor for the specified page width
+ * and page height.
+ * @param width The page width.
+ * @param height The page height.
+ */
+ public PageDescriptor(int width, int height) {
+
+ _width = width;
+ _height = height;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Page Descriptor
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A,
+ 0x00,
+ 0x17,
+ (byte) 0xD3,
+ (byte) 0xA6,
+ (byte) 0xAF,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x09,
+ 0x60,
+ 0x09,
+ 0x60,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ };
+
+ byte[] x = BinaryUtils.convert(_width, 3);
+ data[15] = x[0];
+ data[16] = x[1];
+ data[17] = x[2];
+
+ byte[] y = BinaryUtils.convert(_height, 3);
+ data[18] = y[0];
+ data[19] = y[1];
+ data[20] = y[2];
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A page group is used in the data stream to define a named, logical grouping
+ * of sequential pages. Page groups are delimited by begin-end structured fields
+ * that carry the name of the page group. Page groups are defined so that the
+ * pages that comprise the group can be referenced or processed as a single
+ * entity. Page groups are often processed in stand-alone fashion; that is, they
+ * are indexed, retrieved, and presented outside the context of the containing
+ * document.
+ *
+ * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
+ */
+public class PageGroup extends AbstractNamedAFPObject {
+
+ /**
+ * The pages contained within this group
+ */
+ private List _objects = new ArrayList();
+
+ /**
+ * The tag logical elements contained within this group
+ */
+ private List _tagLogicalElements = new ArrayList();
+
+ /**
+ * The page state
+ */
+ private boolean _complete = false;
+
+ /**
+ * Constructor for the PageGroup.
+ *
+ * @param name
+ * the name of the page group
+ */
+ public PageGroup(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Adds a page object to the group.
+ *
+ * @param page
+ * the page object to add
+ */
+ public void addPage(PageObject page) {
+
+ if (!_objects.contains(page)) {
+ _objects.add(page);
+ }
+
+ }
+
+ /**
+ * @return the name of the page group
+ */
+ public String getName() {
+ return _name;
+ }
+
+ /**
+ * Creates a TagLogicalElement on the page.
+ *
+ * @param name
+ * the name of the tag
+ * @param value
+ * the value of the tag
+ */
+ public void createTagLogicalElement(String name, String value) {
+
+ TagLogicalElement tle = new TagLogicalElement(name, value);
+ _tagLogicalElements.add(tle);
+
+ }
+
+ /**
+ * Creates an InvokeMediaMap on the page.
+ *
+ * @param name
+ * the name of the media map
+ */
+ public void createInvokeMediumMap(String name) {
+
+ InvokeMediumMap imm = new InvokeMediumMap(name);
+ _objects.add(imm);
+
+ }
+
+ /**
+ * Method to mark the end of the page group.
+ */
+ public void endPageGroup() {
+
+ _complete = true;
+
+ }
+
+ /**
+ * Returns an indication if the page group is complete
+ */
+ public boolean isComplete() {
+ return _complete;
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the page group.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ writeObjectList(_tagLogicalElements, os);
+
+ writeObjectList(_objects, os);
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the page group.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xAD; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the page group.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xAD; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+import java.io.IOException;
+import java.io.OutputStream;
+
+
+
+/**
+ * Pages contain the data objects that comprise a presentation document. Each
+ * page has a set of data objects associated with it. Each page within a
+ * document is independent from any other page, and each must establish its own
+ * environment parameters.
+ *
+ * The page is the level in the document component hierarchy that is used for
+ * printing or displaying a document's content. The data objects contained in
+ * the page envelope in the data stream are presented when the page is
+ * presented. Each data object has layout information associated with it that
+ * directs the placement and orientation of the data on the page. In addition,
+ * each page contains layout information that specifies the measurement units,
+ * page width, and page depth.
+ *
+ * A page is initiated by a begin page structured field and terminated by an end
+ * page structured field. Structured fields that define objects and active
+ * environment groups or that specify attributes of the page may be encountered
+ * in page state.
+ *
+ */
+public class PageObject extends AbstractPageObject {
+
+ /**
+ * The resource group object
+ */
+ private ResourceGroup _resourceGroup = null;
+
+ /**
+ * Construct a new page object for the specified name argument, the page
+ * name should be an 8 character identifier.
+ *
+ * @param name
+ * the name of the page.
+ * @param width
+ * the width of the page.
+ * @param height
+ * the height of the page.
+ * @param rotation
+ * the rotation of the page.
+ */
+ public PageObject(String name, int width, int height, int rotation) {
+
+ super(name, width, height, rotation);
+
+ }
+
+ /**
+ * Adds an overlay to the page resources
+ * @param overlay the overlay to add
+ */
+ public void addOverlay(Overlay overlay) {
+ if (_resourceGroup == null) {
+ _resourceGroup = new ResourceGroup();
+ }
+ _resourceGroup.addOverlay(overlay);
+ }
+
+ /**
+ * Creates an IncludePageOverlay on the page.
+ *
+ * @param name
+ * the name of the overlay
+ * @param x
+ * the x position of the overlay
+ * @param y
+ * the y position of the overlay
+ * @param orientation
+ * the orientation required for the overlay
+ */
+ public void createIncludePageOverlay(String name, int x, int y, int orientation) {
+
+ IncludePageOverlay ipo = new IncludePageOverlay(name, x, y, orientation);
+ _objects.add(ipo);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the page.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ if (_resourceGroup != null) {
+ _resourceGroup.writeDataStream(os);
+ }
+
+ _activeEnvironmentGroup.writeDataStream(os);
+
+ writeObjectList(_segments, os);
+
+ writeObjectList(_tagLogicalElements, os);
+
+ writeObjectList(_objects, os);
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the page.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xAF; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the page.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xAF; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.awt.Color;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * Presentation text data contains the graphic characters and the control
+ * sequences necessary to position the characters within the object space. The
+ * data consists of: - graphic characters to be presented - control sequences
+ * that position them - modal control sequences that adjust the positions by
+ * small amounts - other functions causing text to be presented with differences
+ * in appearance.
+ *
+ * The graphic characters are expected to conform to a coded font representation
+ * so that they can be translated from the code point in the object data to the
+ * character in the coded font. The units of measure for linear displacements
+ * are derived from the PresentationTextDescriptor or from the hierarchical
+ * defaults.
+ *
+ * In addition to graphic character code points, Presentation Text data can
+ * contain embedded control sequences. These are strings of two or more bytes
+ * which signal an alternate mode of processing for the content of the current
+ * Presentation Text data.
+ *
+ */
+public class PresentationTextData extends AbstractAFPObject {
+
+ /**
+ * The maximum size of the presentation text data.
+ */
+ private static final int MAX_SIZE = 8192;
+
+ /**
+ * The afp data relating to this presentaion text data.
+ */
+ private ByteArrayOutputStream _baos = new ByteArrayOutputStream(1024);
+
+ /**
+ * The current x coordinate.
+ */
+ private int _currentXCoordinate = -1;
+
+ /**
+ * The current y cooridnate
+ */
+ private int _currentYCoordinate = -1;
+
+ /**
+ * The current font
+ */
+ private String _currentFont = "";
+
+ /**
+ * The current orientation
+ */
+ private int _currentOrientation = 0;
+
+ /**
+ * The current color
+ */
+ private Color _currentColor = new Color(0, 0, 0);
+
+ /**
+ * The current variable space increment
+ */
+ private int _currentVariableSpaceCharacterIncrement = 0;
+
+ /**
+ * The current inter character adjustment
+ */
+ private int _currentInterCharacterAdjustment = 0;
+
+ /**
+ * Default constructor for the PresentationTextData.
+ */
+ public PresentationTextData() {
+
+ this(false);
+
+ }
+
+ /**
+ * Constructor for the PresentationTextData, the boolean flag indicate
+ * whether the control sequence prefix should be set to indicate the start
+ * of a new control sequence.
+ *
+ * @param controlInd
+ * The control sequence indicator.
+ */
+ public PresentationTextData(boolean controlInd) {
+
+ _baos.write(new byte[] { 0x5A, // Structured field identifier
+ 0x00, // Record length byte 1
+ 0x00, // Record length byte 2
+ (byte) 0xD3, // PresentationTextData identifier byte 1
+ (byte) 0xEE, // PresentationTextData identifier byte 2
+ (byte) 0x9B, // PresentationTextData identifier byte 3
+ 0x00, // Flag
+ 0x00, // Reserved
+ 0x00, // Reserved
+ }, 0, 9);
+
+ if (controlInd) {
+ _baos.write(new byte[] { 0x2B, (byte) 0xD3 }, 0, 2);
+ }
+
+ }
+
+ /**
+ * The Set Coded Font Local control sequence activates a coded font and
+ * specifies the character attributes to be used. This is a modal control
+ * sequence.
+ *
+ * @param font
+ * The font local identifier.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void setCodedFont(byte font, ByteArrayOutputStream afpdata) {
+
+ // Avoid unnecessary specification of the font
+ if (String.valueOf(font).equals(_currentFont)) {
+ return;
+ } else {
+ _currentFont = String.valueOf(font);
+ }
+
+ afpdata.write(new byte[] { 0x03, (byte) 0xF1, font, }, 0, 3);
+
+ }
+
+ /**
+ * Establishes the current presentation position on the baseline at a new
+ * I-axis coordinate, which is a specified number of measurement units from
+ * the B-axis. There is no change to the current B-axis coordinate.
+ *
+ * @param coordinate
+ * The coordinate for the inline move.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void absoluteMoveInline(int coordinate,
+ ByteArrayOutputStream afpdata) {
+
+ byte[] b = BinaryUtils.convert(coordinate, 2);
+
+ afpdata.write(new byte[] { 0x04, (byte) 0xC7, b[0], b[1], }, 0, 4);
+
+ _currentXCoordinate = coordinate;
+
+ }
+
+ /**
+ * Establishes the baseline and the current presentation position at a new
+ * B-axis coordinate, which is a specified number of measurement units from
+ * the I-axis. There is no change to the current I-axis coordinate.
+ *
+ * @param coordinate
+ * The coordinate for the baseline move.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void absoluteMoveBaseline(int coordinate,
+ ByteArrayOutputStream afpdata) {
+
+ byte[] b = BinaryUtils.convert(coordinate, 2);
+
+ afpdata.write(new byte[] { 0x04, (byte) 0xD3, b[0], b[1], }, 0, 4);
+
+ _currentYCoordinate = coordinate;
+
+ }
+
+ /**
+ * The Transparent Data control sequence contains a sequence of code points
+ * that are presented without a scan for embedded control sequences.
+ *
+ * @param data
+ * The text data to add.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void addTransparentData(byte[] data, ByteArrayOutputStream afpdata) {
+
+ // Calculate the length
+ int l = data.length + 2;
+
+ if (l > 255) {
+ // Check that we are not exceeding the maximum length
+ throw new IllegalArgumentException(
+ "Transparent data is longer than 253 bytes: " + data);
+ }
+
+ afpdata.write(new byte[] { BinaryUtils.convert(l)[0], (byte) 0xDB, },
+ 0, 2);
+
+ afpdata.write(data, 0, data.length);
+
+ }
+
+ /**
+ * Draws a line of specified length and specified width in the B-direction
+ * from the current presentation position. The location of the current
+ * presentation position is unchanged.
+ *
+ * @param length
+ * The length of the rule.
+ * @param width
+ * The width of the rule.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void drawBaxisRule(int length, int width,
+ ByteArrayOutputStream afpdata) {
+
+ afpdata.write(new byte[] { 0x07, // Length
+ (byte) 0xE7, // Type
+ }, 0, 2);
+
+ // Rule length
+ byte[] data1 = BinaryUtils.shortToByteArray((short) length);
+ afpdata.write(data1, 0, data1.length);
+ // Rule width
+ byte[] data2 = BinaryUtils.shortToByteArray((short) width);
+ afpdata.write(data2, 0, data2.length);
+ // Rule width fraction
+ afpdata.write(0x00);
+
+ }
+
+ /**
+ * Draws a line of specified length and specified width in the I-direction
+ * from the current presentation position. The location of the current
+ * presentation position is unchanged.
+ *
+ * @param length
+ * The length of the rule.
+ * @param width
+ * The width of the rule.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void drawIaxisRule(int length, int width,
+ ByteArrayOutputStream afpdata) {
+
+ afpdata.write(new byte[] { 0x07, // Length
+ (byte) 0xE5, // Type
+ }, 0, 2);
+
+ // Rule length
+ byte[] data1 = BinaryUtils.shortToByteArray((short) length);
+ afpdata.write(data1, 0, data1.length);
+ // Rule width
+ byte[] data2 = BinaryUtils.shortToByteArray((short) width);
+ afpdata.write(data2, 0, data2.length);
+ // Rule width fraction
+ afpdata.write(0x00);
+
+ }
+
+ /**
+ * Create the presentation text data for the byte array of data.
+ *
+ * @param fontNumber
+ * The font resource identifier.
+ * @param x
+ * The x coordinate for the text data.
+ * @param y
+ * The y coordinate for the text data.
+ * @param orientation
+ * The orientation of the text data.
+ * @param col
+ * The text color.
+ * @param vsci
+ * The variable space character increment.
+ * @param ica
+ * The inter character adjustment.
+ * @param data
+ * The text data to be created.
+ * @throws MaximumSizeExceededException
+ */
+ public void createTextData(int fontNumber, int x, int y, int orientation,
+ Color col, int vsci, int ica, byte[] data)
+ throws MaximumSizeExceededException {
+
+ ByteArrayOutputStream afpdata = new ByteArrayOutputStream();
+
+ if (_currentOrientation != orientation) {
+ setTextOrientation(orientation, afpdata);
+ _currentOrientation = orientation;
+ _currentXCoordinate = -1;
+ _currentYCoordinate = -1;
+ }
+
+ // Avoid unnecessary specification of the Y co-ordinate
+ if (y != _currentYCoordinate) {
+ absoluteMoveBaseline(y, afpdata);
+ _currentXCoordinate = -1;
+ }
+
+ // Avoid unnecessary specification of the X co-ordinate
+ if (x != _currentXCoordinate) {
+ absoluteMoveInline(x, afpdata);
+ }
+
+ // Avoid unnecessary specification of the variable space increment
+ if (vsci != _currentVariableSpaceCharacterIncrement) {
+ setVariableSpaceCharacterIncrement(vsci, afpdata);
+ _currentVariableSpaceCharacterIncrement = vsci;
+ }
+
+ // Avoid unnecessary specification of the inter character adjustment
+ if (ica != _currentInterCharacterAdjustment) {
+ setInterCharacterAdjustment(ica, afpdata);
+ _currentInterCharacterAdjustment = ica;
+ }
+
+ // Avoid unnecessary specification of the text color
+ if (!col.equals(_currentColor)) {
+ setExtendedTextColor(col, afpdata);
+ _currentColor = col;
+ }
+
+ setCodedFont(BinaryUtils.convert(fontNumber)[0], afpdata);
+ addTransparentData(data, afpdata);
+ _currentXCoordinate = -1;
+
+ int s = afpdata.size();
+
+ if (_baos.size() + s > MAX_SIZE) {
+ _currentXCoordinate = -1;
+ _currentYCoordinate = -1;
+ throw new MaximumSizeExceededException();
+ }
+
+ byte[] outputdata = afpdata.toByteArray();
+ _baos.write(outputdata, 0, outputdata.length);
+
+ }
+
+ /**
+ * Drawing of lines using the starting and ending coordinates, thickness and
+ * colour arguments.
+ *
+ * @param x1
+ * The starting X coordinate.
+ * @param y1
+ * The starting Y coordinate.
+ * @param x2
+ * The ending X coordinate.
+ * @param y2
+ * The ending Y coordinate.
+ * @param thickness
+ * The line thickness.
+ * @param orientation
+ * The orientation of the text data.
+ * @param col
+ * The text color.
+ */
+ public void createLineData(int x1, int y1, int x2, int y2, int thickness,
+ int orientation, Color col) throws MaximumSizeExceededException {
+
+ ByteArrayOutputStream afpdata = new ByteArrayOutputStream();
+
+ if (_currentOrientation != orientation) {
+ setTextOrientation(orientation, afpdata);
+ _currentOrientation = orientation;
+ }
+
+ // Avoid unnecessary specification of the Y coordinate
+ if (y1 != _currentYCoordinate) {
+ absoluteMoveBaseline(y1, afpdata);
+ }
+
+ // Avoid unnecessary specification of the X coordinate
+ if (x1 != _currentXCoordinate) {
+ absoluteMoveInline(x1, afpdata);
+ }
+
+ if (!col.equals(_currentColor)) {
+ setExtendedTextColor(col, afpdata);
+ _currentColor = col;
+ }
+
+ if (y1 == y2) {
+ drawIaxisRule(x2 - x1, thickness, afpdata);
+ } else if (x1 == x2) {
+ drawBaxisRule(y2 - y1, thickness, afpdata);
+ } else {
+ return;
+ }
+
+ int s = afpdata.size();
+
+ if (_baos.size() + s > MAX_SIZE) {
+ _currentXCoordinate = -1;
+ _currentYCoordinate = -1;
+ throw new MaximumSizeExceededException();
+ }
+
+ byte[] outputdata = afpdata.toByteArray();
+ _baos.write(outputdata, 0, outputdata.length);
+
+ }
+
+ /**
+ * The Set Text Orientation control sequence establishes the I-direction and
+ * B-direction for the subsequent text. This is a modal control sequence.
+ *
+ * Semantics: This control sequence specifies the I-axis and B-axis
+ * orientations with respect to the Xp-axis for the current Presentation
+ * Text object. The orientations are rotational values expressed in degrees
+ * and minutes.
+ *
+ * @param orientation
+ * The text orientation (0,90, 180, 270).
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void setTextOrientation(int orientation,
+ ByteArrayOutputStream afpdata) {
+
+ afpdata.write(new byte[] { 0x06, (byte) 0xF7, }, 0, 2);
+
+ switch (orientation) {
+ case 90:
+ afpdata.write(0x2D);
+ afpdata.write(0x00);
+ afpdata.write(0x5A);
+ afpdata.write(0x00);
+ break;
+ case 180:
+ afpdata.write(0x5A);
+ afpdata.write(0x00);
+ afpdata.write(0x87);
+ afpdata.write(0x00);
+ break;
+ case 270:
+ afpdata.write(0x87);
+ afpdata.write(0x00);
+ afpdata.write(0x00);
+ afpdata.write(0x00);
+ break;
+ default:
+ afpdata.write(0x00);
+ afpdata.write(0x00);
+ afpdata.write(0x2D);
+ afpdata.write(0x00);
+ break;
+ }
+
+ }
+
+ /**
+ * The Set Extended Text Color control sequence specifies a color value and
+ * defines the color space and encoding for that value. The specified color
+ * value is applied to foreground areas of the text presentation space.
+ * This is a modal control sequence.
+ *
+ * @param col
+ * The color to be set.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void setExtendedTextColor(Color col,
+ ByteArrayOutputStream afpdata) {
+
+ afpdata.write(new byte[] {
+ 15 // Control sequence length
+ , (byte)0x81 // Control sequence function type
+ , 0x00 // Reserved; must be zero
+ , 0x01 // Color space - 0x01 = RGB
+ , 0x00 // Reserved; must be zero
+ , 0x00 // Reserved; must be zero
+ , 0x00 // Reserved; must be zero
+ , 0x00 // Reserved; must be zero
+ , 8 // Number of bits in component 1
+ , 8 // Number of bits in component 2
+ , 8 // Number of bits in component 3
+ , 0 // Number of bits in component 4
+ , (byte)(col.getRed()) // Red intensity
+ , (byte)(col.getGreen()) // Green intensity
+ , (byte)(col.getBlue()) // Blue intensity
+ }, 0, 15);
+
+ }
+
+ /**
+ * //TODO
+ * This is a modal control sequence.
+ *
+ * @param incr
+ * The increment to be set.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void setVariableSpaceCharacterIncrement(int incr,
+ ByteArrayOutputStream afpdata) {
+
+ byte[] b = BinaryUtils.convert(incr, 2);
+
+ afpdata.write(new byte[] {
+ 4 // Control sequence length
+ , (byte)0xC5 // Control sequence function type
+ , b[0]
+ , b[1]
+ }, 0, 4);
+
+ }
+
+ /**
+ * //TODO
+ * This is a modal control sequence.
+ *
+ * @param incr
+ * The increment to be set.
+ * @param afpdata
+ * The output stream to which data should be written.
+ */
+ private void setInterCharacterAdjustment(int incr,
+ ByteArrayOutputStream afpdata) {
+
+ byte[] b = BinaryUtils.convert(Math.abs(incr), 2);
+
+ afpdata.write(new byte[] {
+ 5 // Control sequence length
+ , (byte)0xC3 // Control sequence function type
+ , b[0]
+ , b[1]
+ , (byte)(incr >= 0 ? 0 : 1) // Direction
+ }, 0, 5);
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for
+ * the text data.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = _baos.toByteArray();
+ byte[] size = BinaryUtils.convert(data.length - 1, 2);
+ data[1] = size[0];
+ data[2] = size[1];
+
+ os.write(data);
+
+ }
+
+ /**
+ * A control sequence is a sequence of bytes that specifies a control
+ * function. A control sequence consists of a control sequence introducer
+ * and zero or more parameters. The control sequence can extend multiple
+ * presentation text data objects, but must eventually be terminated. This
+ * method terminates the control sequence.
+ *
+ * @throws MaximumSizeExceededException
+ */
+ public void endControlSequence() throws MaximumSizeExceededException {
+
+ byte[] data = new byte[2];
+ data[0] = 0x02;
+ data[1] = (byte) 0xF8;
+
+ if (data.length + _baos.size() > MAX_SIZE) {
+ throw new MaximumSizeExceededException();
+ }
+
+ _baos.write(data, 0, data.length);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * The Presentation Text Descriptor specifies the units of measure for the
+ * Presentation Text object space, the size of the Presentation Text object
+ * space, and the initial values for modal parameters, called initial text
+ * conditions. Initial values not provided are defaulted by the controlling
+ * environment or the receiving device.
+ *
+ * The Presentation Text Descriptor provides the following initial values:
+ * - Unit base
+ * - Xp-units per unit base
+ * - Yp-units per unit base
+ * - Xp-extent of the presentation space
+ * - Yp-extent of the presentation space
+ * - Initial text conditions.
+ *
+ * The initial text conditions are values provided by the Presentation Text
+ * Descriptor to initialize the modal parameters of the control sequences.
+ * Modal control sequences typically are characterized by the word set in
+ * the name of the control sequence. Modal parameters are identified as such
+ * in their semantic descriptions.
+ *
+ */
+public class PresentationTextDescriptor extends AbstractAFPObject {
+
+ private int _width = 0;
+ private int _height = 0;
+
+ /**
+ * Constructor a PresentationTextDescriptor for the specified
+ * width and height.
+ * @param width The width of the page.
+ * @param height The height of the page.
+ */
+ public PresentationTextDescriptor(int width, int height) {
+
+ _width = width;
+ _height = height;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the Presentation Text Descriptor
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[] {
+ 0x5A,
+ 0x00,
+ 0x16,
+ (byte) 0xD3,
+ (byte) 0xB1,
+ (byte) 0x9B,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x09,
+ 0x60,
+ 0x09,
+ 0x60,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+ };
+
+ byte[] x = BinaryUtils.convert(_width, 3);
+ data[15] = x[0];
+ data[16] = x[1];
+ data[17] = x[2];
+
+ byte[] y = BinaryUtils.convert(_height, 3);
+ data[18] = y[0];
+ data[19] = y[1];
+ data[20] = y[2];
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.awt.Color;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+/**
+ * The Presentation Text object is the data object used in document processing
+ * environments for representing text which has been prepared for presentation.
+ * Text, as used here, means an ordered string of characters, such as graphic
+ * symbols, numbers, and letters, that are suitable for the specific purpose of
+ * representing coherent information. Text which has been prepared for
+ * presentation has been reduced to a primitive form through explicit
+ * specification of the characters and their placement in the presentation
+ * space. Control sequences which designate specific control functions may be
+ * embedded within the text. These functions extend the primitive form by
+ * applying specific characteristics to the text when it is presented. The
+ * collection of the graphic characters and control codes is called Presentation
+ * Text, and the object that contains the Presentation Text is called the
+ * PresentationText object.
+ *
+ */
+public class PresentationTextObject extends AbstractNamedAFPObject {
+
+ /**
+ * Default name for the presentation text object
+ */
+ private static final String DEFAULT_NAME = "PTO00001";
+
+ private PresentationTextData currentPresentationTextData = null;
+
+ private ArrayList presentationTextData = new ArrayList();
+
+ /**
+ * Default constructor for the PresentationTextObject
+ */
+ public PresentationTextObject() {
+
+ this(DEFAULT_NAME);
+
+ }
+
+ /**
+ * Construct a new PresentationTextObject for the specified name argument,
+ * the name should be an 8 character identifier.
+ */
+ public PresentationTextObject(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Create the presentation text data for the byte array of data.
+ *
+ * @param fontNumber
+ * The font resource identifier.
+ * @param x
+ * The x coordinate for the text data.
+ * @param y
+ * The y coordinate for the text data.
+ * @param col
+ * The text color.
+ * @param vsci
+ * The variable space character increment.
+ * @param ica
+ * The inter character increment.
+ * @param data
+ * The text data to be created.
+ */
+ public void createTextData(int fontNumber, int x, int y, Color col, int vsci, int ica, byte[] data) {
+
+ // Use a default orientation of zero
+ createTextData(fontNumber, x, y, 0, col, vsci, ica, data);
+
+ }
+
+ /**
+ * Create the presentation text data for the byte array of data.
+ *
+ * @param fontNumber
+ * The font resource identifier.
+ * @param x
+ * The x coordinate for the text data.
+ * @param y
+ * The y coordinate for the text data.
+ * @param orientation
+ * The orientation of the text data.
+ * @param col
+ * The text color.
+ * @param vsci
+ * The variable space character increment.
+ * @param ica
+ * The inter character adjustment.
+ * @param data
+ * The text data to be created.
+ */
+ public void createTextData(int fontNumber, int x, int y, int orientation,
+ Color col, int vsci, int ica, byte[] data) {
+
+ if (currentPresentationTextData == null) {
+ startPresentationTextData();
+ }
+
+ try {
+
+ currentPresentationTextData.createTextData(fontNumber, x, y,
+ orientation, col, vsci, ica, data);
+
+ } catch (MaximumSizeExceededException msee) {
+
+ endPresentationTextData();
+ createTextData(fontNumber, x, y, orientation, col, vsci, ica, data);
+
+ }
+
+ }
+
+ /**
+ * Drawing of lines using the starting and ending coordinates, thickness.
+ *
+ * @param x1
+ * The first x coordinate of the line.
+ * @param y1
+ * The first y coordinate of the line.
+ * @param x2
+ * The second x coordinate of the line.
+ * @param y2
+ * The second y coordinate of the line.
+ * @param thickness
+ * The thickness of the line.
+ * @param col
+ * The text color.
+ */
+ public void createLineData(int x1, int y1, int x2, int y2, int thickness, Color col) {
+ // Default orientation
+ createLineData(x1, y1, x2, y2, thickness, 0, col);
+ }
+
+ /**
+ * Drawing of lines using the starting and ending coordinates, thickness and
+ * orientation arguments.
+ *
+ * @param x1
+ * The first x coordinate of the line.
+ * @param y1
+ * The first y coordinate of the line.
+ * @param x2
+ * The second x coordinate of the line.
+ * @param y2
+ * The second y coordinate of the line.
+ * @param thickness
+ * The thickness of the line.
+ * @param orientation
+ * The orientation of the line.
+ * @param col
+ * The text color.
+ */
+ public void createLineData(int x1, int y1, int x2, int y2, int thickness,
+ int orientation, Color col) {
+
+ if (currentPresentationTextData == null) {
+ startPresentationTextData();
+ }
+
+ try {
+
+ currentPresentationTextData.createLineData(x1, y1, x2, y2,
+ thickness, orientation, col);
+
+ } catch (MaximumSizeExceededException msee) {
+
+ endPresentationTextData();
+ createLineData(x1, y1, x2, y2, thickness, orientation, col);
+
+ }
+
+ }
+
+ /**
+ * Helper method to mark the start of the presentation text data
+ */
+ private void startPresentationTextData() {
+
+ if (presentationTextData.size() == 0) {
+ currentPresentationTextData = new PresentationTextData(true);
+ } else {
+ currentPresentationTextData = new PresentationTextData();
+ }
+
+ presentationTextData.add(currentPresentationTextData);
+
+ }
+
+ /**
+ * Helper method to mark the end of the presentation text data
+ */
+ private void endPresentationTextData() {
+
+ currentPresentationTextData = null;
+
+ }
+
+ /**
+ * Accessor method to write the AFP datastream for the PresentationTextObject.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ writeObjectList(presentationTextData, os);
+
+ writeEnd(os);
+
+ }
+
+ public String getName() {
+
+ return _name;
+
+ }
+
+ /**
+ * Helper method to write the start of the presenation text object.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0x9B; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the presenation text object.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0x9B; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * A control sequence is a sequence of bytes that specifies a control
+ * function. A control sequence consists of a control sequence introducer
+ * and zero or more parameters. The control sequence can extend multiple
+ * presentation text data objects, but must eventually be terminated. This
+ * method terminates the control sequence.
+ */
+ public void endControlSequence() {
+
+ if (currentPresentationTextData == null) {
+ startPresentationTextData();
+ }
+
+ try {
+
+ currentPresentationTextData.endControlSequence();
+
+ } catch (MaximumSizeExceededException msee) {
+
+ endPresentationTextData();
+ endControlSequence();
+
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A Resource Group contains a set of overlays.
+ */
+public final class ResourceGroup extends AbstractNamedAFPObject {
+
+ /**
+ * Default name for the resource group
+ */
+ private static final String DEFAULT_NAME = "RG000001";
+
+
+ /**
+ * The overlays contained in this resource group
+ */
+ private List _overlays = new ArrayList();
+
+ public ResourceGroup() {
+
+ this(DEFAULT_NAME);
+
+ }
+
+ /**
+ * Constructor for the ResourceGroup, this takes a
+ * name parameter which must be 8 characters long.
+ * @param name the resource group name
+ */
+ public ResourceGroup(String name) {
+
+ super(name);
+
+ }
+
+ /**
+ * Adds an overlay to the resource group
+ * @param overlay the overlay to add
+ */
+ public void addOverlay(Overlay overlay) {
+ _overlays.add(overlay);
+ }
+
+ /**
+ * Returns the list of overlays
+ * @return the list of overlays
+ */
+ public List getOverlays() {
+ return _overlays;
+ }
+
+ /**
+ * Accessor method to obtain write the AFP datastream for
+ * the resource group.
+ * @param os The stream to write to
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os)
+ throws IOException {
+
+ writeStart(os);
+
+ writeObjectList(_overlays, os);
+
+ writeEnd(os);
+
+ }
+
+ /**
+ * Helper method to write the start of the resource group.
+ * @param os The stream to write to
+ */
+ private void writeStart(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA8; // Structured field id byte 2
+ data[5] = (byte) 0xC6; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+ /**
+ * Helper method to write the end of the resource group.
+ * @param os The stream to write to
+ */
+ private void writeEnd(OutputStream os)
+ throws IOException {
+
+ byte[] data = new byte[17];
+
+ data[0] = 0x5A; // Structured field identifier
+ data[1] = 0x00; // Length byte 1
+ data[2] = 0x10; // Length byte 2
+ data[3] = (byte) 0xD3; // Structured field id byte 1
+ data[4] = (byte) 0xA9; // Structured field id byte 2
+ data[5] = (byte) 0xC6; // Structured field id byte 3
+ data[6] = 0x00; // Flags
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ for (int i = 0; i < _nameBytes.length; i++) {
+
+ data[9 + i] = _nameBytes[i];
+
+ }
+
+ os.write(data);
+
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.render.afp.tools.BinaryUtils;
+
+/**
+ * A Tag Logical Element structured field assigns an attribute name and an
+ * attribute value to a page or page group. The Tag Logical Element structured
+ * field may be embedded directly in the page or page group, or it may reference
+ * the page or page group from a document index. When a Tag Logical Element
+ * structured field references a page or is embedded in a page following the
+ * active environment group, it is associated with the page. When a Tag Logical
+ * Element structured field references a page group or is embedded in a page
+ * group following the Begin Named Page Group structured field, it is associated
+ * with the page group. When a Tag Logical Element structured field is associated
+ * with a page group, the parameters of the Tag Logical Element structured field
+ * are inherited by all pages in the page group and by all other page groups
+ * that are nested in the page group. The scope of a Tag Logical Element is
+ * determined by its position with respect to other TLEs that reference, or are
+ * embedded in, the same page or page group. The Tag Logical Element structured
+ * field does not provide any presentation specifications and therefore has no
+ * effect on the appearance of a document when it is presented.
+ * <p/>
+ */
+public class TagLogicalElement extends AbstractAFPObject {
+
+ /**
+ * Name of the key, used within the TLE
+ */
+ private String _tleName = null;
+
+ /**
+ * Value returned by the key
+ */
+ private String _tleValue = null;
+
+ /**
+ * Byte representaion of the name
+ */
+ private byte[] _tleByteName = null;
+
+ /**
+ * Byte representaion of the value
+ */
+ private byte[] _tleByteValue = null;
+
+ /**
+ * Construct a tag logical element with the name and value specified.
+ * @param name the name of the tag logical element
+ * @param value the value of the tag logical element
+ */
+ public TagLogicalElement(String name, String value) {
+
+ _tleName = name;
+ _tleValue = value;
+
+ try {
+
+ _tleByteName = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
+ _tleByteValue = value.getBytes(AFPConstants.EBCIDIC_ENCODING);
+
+ } catch (UnsupportedEncodingException usee) {
+
+ _tleByteName = name.getBytes();
+ _tleByteValue = value.getBytes();
+ log.warn(
+ "Constructor:: UnsupportedEncodingException translating the name "
+ + name);
+
+ }
+
+ }
+
+ /**
+ * Accessor method to obtain the byte array AFP datastream for the
+ * TagLogicalElement.
+ * @param os The outputsteam stream
+ * @throws java.io.IOException
+ */
+ public void writeDataStream(OutputStream os) throws IOException {
+
+ byte[] data = new byte[17 + _tleName.length() + _tleValue.length()];
+
+ data[0] = 0x5A;
+ // Set the total record length
+ byte[] rl1 =
+ BinaryUtils.convert(16 + _tleName.length() + _tleValue.length(), 2);
+ //Ignore first byte
+ data[1] = rl1[0];
+ data[2] = rl1[1];
+
+ // Structured field ID for a TLE
+ data[3] = (byte) 0xD3;
+ data[4] = (byte) 0xA0;
+ data[5] = (byte) 0x90;
+
+ data[6] = 0x00; // Reserved
+ data[7] = 0x00; // Reserved
+ data[8] = 0x00; // Reserved
+
+ //Use 2 triplets, attrubute name and value (the key for indexing)
+
+ byte[] rl2 = BinaryUtils.convert(_tleName.length() + 4, 1);
+ data[9] = rl2[0]; // length of the triplet, including this field
+ data[10] = 0x02; //Identifies it as a FQN triplet
+ data[11] = 0x0B; // GID format
+ data[12] = 0x00;
+
+ int pos = 13;
+ for (int i = 0; i < _tleByteName.length; i++) {
+ data[pos++] = _tleByteName[i];
+ }
+
+ byte[] rl3 = BinaryUtils.convert(_tleByteValue.length + 4, 1);
+ data[pos++] = rl3[0]; // length of the triplet, including this field
+ data[pos++] = 0x36; //Identifies the triplet, attribute value
+ data[pos++] = 0x00; // Reserved
+ data[pos++] = 0x00; // Reserved
+
+ for (int i = 0; i < _tleByteValue.length; i++) {
+ data[pos++] = _tleByteValue[i];
+ }
+ os.write(data);
+
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.modca;
+
+/**
+ * The TagLogicalElementBean provides a bean for holding the attributes of
+ * a tag logical element as key value pairs.
+ * <p/>
+ */
+public class TagLogicalElementBean {
+
+ /** The key attribute */
+ private String _key;
+
+ /** The value attribute */
+ private String _value;
+
+ /**
+ * Constructor for the TagLogicalElementBean.
+ * @param key the key attribute
+ * @param value the value attribute
+ */
+ public TagLogicalElementBean(String key, String value) {
+ _key = key;
+ _value = value;
+ }
+
+ /**
+ * Getter for the key attribute.
+ * @return the key
+ */
+ public String getKey() {
+ return _key;
+ }
+
+ /**
+ * Getter for the value attribute.
+ * @return the value
+ */
+ public String getValue() {
+ return _value;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.tools;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Library of utility useful conversion methods.
+ *
+ */
+public final class BinaryUtils {
+
+ /**
+ * Convert an int into the corresponding byte array by encoding each
+ * two hexadecimal digits as a char. This will return a byte array
+ * to the length specified by bufsize.
+ * @param integer The int representation.
+ * @param bufsize The required byte array size.
+ */
+ public static byte[] convert(int integer, int bufsize) {
+
+ StringBuffer buf = new StringBuffer(Integer.toHexString(integer));
+ if (buf.length() % 2 == 0) {
+ // Ignore even number of digits
+ } else {
+ // Convert to an even number of digits
+ buf.insert(0, "0");
+ }
+ int size = buf.length() / 2;
+ while (size < bufsize) {
+ buf.insert(0, "00");
+ size++;
+ };
+ return convert(buf.toString());
+
+ }
+
+ /**
+ * Convert an int into the corresponding byte array by encoding each
+ * two hexadecimal digits as a char.
+ * @param integer The int representation
+ */
+ public static byte[] convert(int integer) {
+
+ return convert(Integer.toHexString(integer));
+
+ }
+
+ /**
+ * Convert a String of hexadecimal digits into the corresponding
+ * byte array by encoding each two hexadecimal digits as a byte.
+ * @param digits The hexadecimal digits representation.
+ */
+ public static byte[] convert(String digits) {
+
+ if (digits.length() % 2 == 0) {
+ // Even number of digits, so ignore
+ } else {
+ // Convert to an even number of digits
+ digits = "0" + digits;
+ }
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ for (int i = 0; i < digits.length(); i += 2) {
+ char c1 = digits.charAt(i);
+ char c2 = digits.charAt(i + 1);
+ byte b = 0;
+ if ((c1 >= '0') && (c1 <= '9'))
+ b += ((c1 - '0') * 16);
+ else if ((c1 >= 'a') && (c1 <= 'f'))
+ b += ((c1 - 'a' + 10) * 16);
+ else if ((c1 >= 'A') && (c1 <= 'F'))
+ b += ((c1 - 'A' + 10) * 16);
+ else
+ throw new IllegalArgumentException("Bad hexadecimal digit");
+ if ((c2 >= '0') && (c2 <= '9'))
+ b += (c2 - '0');
+ else if ((c2 >= 'a') && (c2 <= 'f'))
+ b += (c2 - 'a' + 10);
+ else if ((c2 >= 'A') && (c2 <= 'F'))
+ b += (c2 - 'A' + 10);
+ else
+ throw new IllegalArgumentException("Bad hexadecimal digit");
+ baos.write(b);
+ }
+ return (baos.toByteArray());
+
+ }
+
+ /**
+ * Convert the specified short into a byte array.
+ * @param value The value to be converted.
+ * @param array The array to receive the data.
+ * @param offset The offset into the byte array for the start of the value.
+ */
+ public static void shortToByteArray(
+ short value,
+ byte[] array,
+ int offset) {
+ array[offset] = (byte) (value >>> 8);
+ array[offset + 1] = (byte) value;
+ }
+
+ /**
+ * Convert the specified short into a byte array.
+ * @param value The value to be converted.
+ * @return The byte array
+ */
+ public static byte[] shortToByteArray(short value) {
+ byte[] serverValue = new byte[2];
+ shortToByteArray(value, serverValue, 0);
+ return serverValue;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.tools;
+
+import java.io.IOException;
+import java.net.URL;
+
+import org.apache.fop.render.afp.exceptions.FontRuntimeException;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+/**
+ * An entity resolver for both DOM and SAX models of the SAX document.
+ * <p>
+ * The entity resolver only handles queries for the DTD. It will find any URI
+ * with a recognised public id and return an {@link org.xml.sax.InputSource}.
+ * <p>
+ * @author <a href="mailto:joe@exubero.com">Joe Schmetzer</a>
+ */
+public class DTDEntityResolver implements EntityResolver {
+
+ /** Public ID for the AFP fonts 1.0 DTD. */
+ public static final String AFP_DTD_1_0_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.0//EN";
+
+ /** Resource location for the AFP fonts 1.0 DTD. */
+ public static final String AFP_DTD_1_0_RESOURCE = "afp-fonts-1.0.dtd";
+
+ /** Public ID for the AFP fonts 1.1 DTD. */
+ public static final String AFP_DTD_1_1_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.1//EN";
+
+ /** Resource location for the AFP fonts 1.1 DTD. */
+ public static final String AFP_DTD_1_1_RESOURCE = "afp-fonts-1.1.dtd";
+
+ /** Public ID for the AFP fonts 1.2 DTD. */
+ public static final String AFP_DTD_1_2_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.2//EN";
+
+ /** Resource location for the AFP fonts 1.2 DTD. */
+ public static final String AFP_DTD_1_2_RESOURCE = "afp-fonts-1.2.dtd";
+
+ /**
+ * Resolve the combination of system and public identifiers.
+ * If this resolver recognises the publicId, it will handle the resolution
+ * from the classpath, otherwise it will return null and allow the default
+ * resolution to occur.
+ *
+ * @param publicId the public identifier to use
+ * @param systemId the system identifier to resolve
+ * @return An input source to the entity or null if not handled
+ * @throws IOException an error reading the stream
+ */
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws IOException {
+
+ URL resource = null;
+ if ( AFP_DTD_1_2_ID.equals(publicId) ) {
+ resource = getResource( AFP_DTD_1_2_RESOURCE );
+ } else if ( AFP_DTD_1_1_ID.equals(publicId) ) {
+ resource = getResource( AFP_DTD_1_1_RESOURCE );
+ } else if ( AFP_DTD_1_0_ID.equals(publicId) ) {
+ throw new FontRuntimeException(
+ "The AFP Installed Font Definition 1.0 DTD is not longer supported" );
+ } else if( systemId != null && systemId.indexOf("afp-fonts.dtd") >= 0 ) {
+ throw new FontRuntimeException(
+ "The AFP Installed Font Definition DTD must be specified using the public id" );
+ } else {
+ return null;
+ }
+
+ InputSource inputSource = new InputSource( resource.openStream() );
+ inputSource.setPublicId( publicId );
+ inputSource.setSystemId( systemId );
+
+ return inputSource;
+ }
+
+ /**
+ * Returns the URL of a resource on the classpath
+ * @param resourceName the path to the resource relative to the root of the
+ * classpath.
+ * @return the URL of the required resource
+ * @throws FontRuntimeException if the resource could not be found.
+ */
+ private URL getResource(String resourcePath) {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (cl == null) {
+ cl = ClassLoader.getSystemClassLoader();
+ }
+
+ URL resource = cl.getResource( resourcePath );
+ if (resource == null) {
+ throw new FontRuntimeException( "Resource " + resourcePath +
+ " could not be found on the classpath" );
+ }
+
+ return resource;
+ }
+}
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.tools;
+
+/**
+ * Library of utility methods useful in dealing with strings.
+ *
+ */
+public class StringUtils {
+
+ /**
+ * Padds the string to the left with the given character for
+ * the specified length.
+ * @param input The input string.
+ * @param padding The char used for padding.
+ * @param length The length of the new string.
+ * @return The padded string.
+ */
+ public static String lpad(String input, char padding, int length) {
+
+ if (input == null) {
+ input = new String();
+ }
+
+ if (input.length() >= length) {
+ return input;
+ } else {
+ StringBuffer result = new StringBuffer();
+ int numChars = length - input.length();
+ for (int i = 0; i < numChars; i++) {
+ result.append(padding);
+ }
+ result.append(input);
+ return result.toString();
+ }
+ }
+
+ /**
+ * Padds the string to the right with the given character for
+ * the specified length.
+ * @param input The input string.
+ * @param padding The char used for padding.
+ * @param length The length of the new string.
+ * @return The padded string.
+ */
+ public static String rpad(String input, char padding, int length) {
+
+ if (input == null) {
+ input = new String();
+ }
+
+ if (input.length() >= length) {
+ return input;
+ } else {
+ StringBuffer result = new StringBuffer(input);
+ int numChars = length - input.length();
+ for (int i = 0; i < numChars; i++) {
+ result.append(padding);
+ }
+ return result.toString();
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.tools;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A helper class to read structured fields from a MO:DCA document. Each
+ * component of a mixed object document is explicitly defined and delimited
+ * in the data. This is accomplished through the use of MO:DCA data structures,
+ * called structured fields. Structured fields are used to envelop document
+ * components and to provide commands and information to applications using
+ * the data. Structured fields may contain one or more parameters. Each
+ * parameter provides one value from a set of values defined by the architecture.
+ * <p/>
+ * MO:DCA structured fields consist of two parts: an introducer that identifies
+ * the length and type of the structured field, and data that provides the
+ * structured field's effect. The data is contained in a set of parameters,
+ * which can consist of other data structures and data elements. The maximum
+ * length of a structured field is 32767 bytes.
+ * <p/>
+ */
+public class StructuredFieldReader {
+
+ /**
+ * The input stream to read
+ */
+ private InputStream _inputStream = null;
+
+ /**
+ * The constructor for the StructuredFieldReader
+ * @param inputStream the input stream to process
+ */
+ public StructuredFieldReader(InputStream inputStream) {
+
+ _inputStream = inputStream;
+
+ }
+
+ /**
+ * Get the next structured field as identified by the identifer
+ * parameter (this must be a valid MO:DCA structured field.
+ * @param identifier the three byte identifier
+ * @throws IOException
+ */
+ public byte[] getNext(byte[] identifier) throws IOException {
+
+ int bufferPointer = 0;
+ byte[] bufferData = new byte[identifier.length + 2];
+ for (int x = 0; x < identifier.length; x++) {
+ bufferData[x] = (byte) 0;
+ }
+
+ int c;
+ while ((c = _inputStream.read()) > -1) {
+
+ bufferData[bufferPointer] = (byte) c;
+
+ // Check the last characters in the buffer
+ int index = 0;
+ boolean found = true;
+
+ for (int i = identifier.length - 1; i > -1; i--) {
+
+ int p = bufferPointer - index;
+ if (p < 0) {
+ p = bufferData.length + p;
+ }
+
+ index++;
+
+ if (identifier[i] != bufferData[p]) {
+ found = false;
+ break;
+ }
+
+ }
+
+ if (found) {
+
+ byte[] length = new byte[2];
+
+ int a = bufferPointer - identifier.length;
+ if (a < 0) {
+ a = bufferData.length + a;
+ }
+
+ int b = bufferPointer - identifier.length - 1;
+ if (b < 0) {
+ b = bufferData.length + b;
+ }
+
+ length[0] = bufferData[b];
+ length[1] = bufferData[a];
+
+ int reclength = ((length[0] & 0xFF) << 8)
+ + (length[1] & 0xFF) - identifier.length - 2;
+
+ byte[] retval = new byte[reclength];
+
+ _inputStream.read(retval, 0, reclength);
+
+ return retval;
+
+ }
+
+ bufferPointer++;
+ if (bufferPointer >= bufferData.length) {
+ bufferPointer = 0;
+ }
+
+ }
+
+ return new byte[] {
+ };
+
+ }
+
+}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import org.apache.fop.render.afp.fonts.AFPFont;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * This class encapsulates the font atributes that need to be included
- * in the AFP data stream. This class does not assist in converting the
- * font attributes to AFP code pages and character set values.
- *
- */
-public class AFPFontAttributes {
-
- /**
- * The font reference byte
- */
- private byte _fontReference;
-
- /**
- * The font key
- */
- private String _fontKey;
-
- /**
- * The font
- */
- private AFPFont _font;
-
- /**
- * The point size
- */
- private int _pointSize;
-
- /**
- * Constructor for the AFPFontAttributes
- * @param fontKey the font key
- * @param font the font
- * @param pointSize the point size
- */
- public AFPFontAttributes(
-
- String fontKey,
- AFPFont font,
- int pointSize) {
-
- _fontKey = fontKey;
- _font = font;
- _pointSize = pointSize;
-
- }
- /**
- * @return the font
- */
- public AFPFont getFont() {
- return _font;
- }
-
- /**
- * @return the FontKey attribute
- */
- public String getFontKey() {
-
- return _fontKey + _pointSize;
-
- }
-
- /**
- * @return the point size attribute
- */
- public int getPointSize() {
- return _pointSize;
- }
-
- /**
- * @return the FontReference attribute
- */
- public byte getFontReference() {
- return _fontReference;
- }
-
- /**
- * Sets the FontReference attribute
- * @param fontReference the FontReference to set
- */
- public void setFontReference(int fontReference) {
-
- String id = String.valueOf(fontReference);
- _fontReference = BinaryUtils.convert(id)[0];
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-
-import org.apache.fop.render.AbstractGraphics2DAdapter;
-import org.apache.fop.render.Graphics2DImagePainter;
-import org.apache.fop.render.RendererContext;
-
-/**
- * Graphics2DAdapter implementation for AFP.
- */
-public class AFPGraphics2DAdapter extends AbstractGraphics2DAdapter {
-
- /**
- * Main constructor
- */
- public AFPGraphics2DAdapter() {
- }
-
- /** @see org.apache.fop.render.Graphics2DAdapter */
- public void paintImage(Graphics2DImagePainter painter,
- RendererContext context,
- int x, int y, int width, int height) throws IOException {
- RendererContext.RendererContextWrapper wrappedContext
- = new RendererContext.RendererContextWrapper(context);
- AFPRenderer afp = (AFPRenderer)context.getRenderer();
- Boolean grayObj = (Boolean)context.getProperty(AFPRendererContextConstants.AFP_GRAYSCALE);
- boolean gray = (grayObj != null ? grayObj.booleanValue() : false);
-
- //Paint to a BufferedImage
- int resolution = (int)Math.round(context.getUserAgent().getTargetResolution());
- BufferedImage bi = paintToBufferedImage(painter, wrappedContext, resolution, gray, false);
-
- afp.drawBufferedImage(bi, resolution, x, y, width, height);
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import java.awt.Color;
-import java.awt.Rectangle;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.commons.io.output.ByteArrayOutputStream;
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.area.Block;
-import org.apache.fop.area.BlockViewport;
-import org.apache.fop.area.BodyRegion;
-import org.apache.fop.area.CTM;
-import org.apache.fop.area.OffDocumentItem;
-import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.RegionReference;
-import org.apache.fop.area.RegionViewport;
-import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.Leader;
-import org.apache.fop.area.inline.Image;
-import org.apache.fop.area.inline.SpaceArea;
-import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.area.inline.WordArea;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontMetrics;
-import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.FontUtil;
-import org.apache.fop.fonts.Typeface;
-import org.apache.fop.fonts.base14.Courier;
-import org.apache.fop.fonts.base14.Helvetica;
-import org.apache.fop.fonts.base14.TimesRoman;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.image.ImageFactory;
-import org.apache.fop.image.TIFFImage;
-import org.apache.fop.image.XMLImage;
-import org.apache.fop.render.AbstractPathOrientedRenderer;
-import org.apache.fop.render.Graphics2DAdapter;
-import org.apache.fop.render.RendererContext;
-import org.apache.fop.render.afp.extensions.AFPElementMapping;
-import org.apache.fop.render.afp.extensions.AFPPageSetup;
-import org.apache.fop.render.afp.fonts.AFPFontInfo;
-import org.apache.fop.render.afp.fonts.AFPFont;
-import org.apache.fop.render.afp.fonts.CharacterSet;
-import org.apache.fop.render.afp.fonts.FopCharacterSet;
-import org.apache.fop.render.afp.fonts.OutlineFont;
-import org.apache.fop.render.afp.fonts.RasterFont;
-import org.apache.fop.render.afp.modca.AFPConstants;
-import org.apache.fop.render.afp.modca.AFPDataStream;
-import org.apache.fop.render.afp.modca.ImageObject;
-import org.apache.fop.render.afp.modca.PageObject;
-import org.w3c.dom.Document;
-
-
-/**
- * This is an implementation of a FOP Renderer that renders areas to AFP.
- * <p>
- * A renderer is primarily designed to convert a given area tree into the output
- * document format. It should be able to produce pages and fill the pages with
- * the text and graphical content. Usually the output is sent to an output
- * stream. Some output formats may support extra information that is not
- * available from the area tree or depends on the destination of the document.
- * Each renderer is given an area tree to render to its output format. The area
- * tree is simply a representation of the pages and the placement of text and
- * graphical objects on those pages.
- * </p>
- * <p>
- * The renderer will be given each page as it is ready and an output stream to
- * write the data out. All pages are supplied in the order they appear in the
- * document. In order to save memory it is possble to render the pages out of
- * order. Any page that is not ready to be rendered is setup by the renderer
- * first so that it can reserve a space or reference for when the page is ready
- * to be rendered.The renderer is responsible for managing the output format and
- * associated data and flow.
- * </p>
- * <p>
- * Each renderer is totally responsible for its output format. Because font
- * metrics (and therefore layout) are obtained in two different ways depending
- * on the renderer, the renderer actually sets up the fonts being used. The font
- * metrics are used during the layout process to determine the size of
- * characters.
- * </p>
- * <p>
- * The render context is used by handlers. It contains information about the
- * current state of the renderer, such as the page, the position, and any other
- * miscellanous objects that are required to draw into the page.
- * </p>
- * <p>
- * A renderer is created by implementing the Renderer interface. However, the
- * AbstractRenderer does most of what is needed, including iterating through the
- * tree parts, so it is this that is extended. This means that this object only
- * need to implement the basic functionality such as text, images, and lines.
- * AbstractRenderer's methods can easily be overridden to handle things in a
- * different way or do some extra processing.
- * </p>
- * <p>
- * The relevent AreaTree structures that will need to be rendered are Page,
- * Viewport, Region, Span, Block, Line, Inline. A renderer implementation
- * renders each individual page, clips and aligns child areas to a viewport,
- * handle all types of inline area, text, image etc and draws various lines and
- * rectangles.
- * </p>
- *
- * Note: There are specific extensions that have been added to the
- * FO. They are specific to their location within the FO and have to be
- * processed accordingly (ie. at the start or end of the page).
- *
- */
-public class AFPRenderer extends AbstractPathOrientedRenderer {
-
- /**
- * AFP factor for a 240 resolution = 72000/240 = 300
- */
- private static final int DPI_CONVERSION_FACTOR_240 = 300;
-
- /**
- * The afp data stream object responsible for generating afp data
- */
- private AFPDataStream _afpDataStream = null;
-
- /**
- * The map of afp root extensions
- */
- private HashMap _rootExtensionMap = null;
-
- /**
- * The map of page segments
- */
- private HashMap _pageSegmentsMap = null;
-
- /**
- * The fonts on the current page
- */
- private HashMap _currentPageFonts = null;
-
- /**
- * The current color object
- */
- private Color _currentColor = null;
-
- /**
- * The page font number counter, used to determine the next font reference
- */
- private int _pageFontCounter = 0;
-
- /**
- * The current font family
- */
- private String _currentFontFamily = "";
-
- /**
- * The current font size
- */
- private int _currentFontSize = 0;
-
- /**
- * The Options to be set on the AFPRenderer
- */
- private Map _afpOptions = null;
-
- /**
- * The page width
- */
- private int _pageWidth = 0;
-
- /**
- * The page height
- */
- private int _pageHeight = 0;
-
- /**
- * The current page sequence id
- */
- private String _pageSequenceId = null;
-
- /**
- * The portrait rotation
- */
- private int _portraitRotation = 0;
-
- /**
- * The landscape rotation
- */
- private int _landscapeRotation = 270;
-
- /**
- * The line cache, avoids drawing duplicate lines in tables.
- */
- private HashSet _lineCache = null;
-
- /**
- * The current x position for line drawing
- */
- private float _x;
-
- /**
- * The current y position for line drawing
- */
- private float _y;
-
- /**
- * The map of saved incomplete pages
- */
- private Map _pages = null;
-
- /**
- * Flag to the set the output object type for images
- */
- private boolean colorImages = false;
-
- /**
- * Default value for image depth
- */
- private int bitsPerPixel = 8;
-
- /**
- * Constructor for AFPRenderer.
- */
- public AFPRenderer() {
- super();
- }
-
- /**
- * Set up the font info
- *
- * @param inFontInfo font info to set up
- */
- public void setupFontInfo(FontInfo inFontInfo) {
- this.fontInfo = inFontInfo;
- int num = 1;
- if (this.fontList != null && this.fontList.size() > 0) {
- for (Iterator it = this.fontList.iterator(); it.hasNext(); ) {
- AFPFontInfo afi = (AFPFontInfo)it.next();
- AFPFont bf = (AFPFont)afi.getAFPFont();
- for (Iterator it2 = afi.getFontTriplets().iterator(); it2.hasNext(); ) {
- FontTriplet ft = (FontTriplet)it2.next();
- this.fontInfo.addFontProperties("F" + num, ft.getName()
- , ft.getStyle(), ft.getWeight());
- this.fontInfo.addMetrics("F" + num, bf);
- num++;
- }
- }
- } else {
- log.warn("No AFP fonts configured - using default setup");
- }
- if (this.fontInfo.fontLookup("sans-serif", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZH200 ", 1, new Helvetica());
- AFPFont bf = new OutlineFont("Helvetica", cs);
- this.fontInfo.addFontProperties("F" + num, "sans-serif", "normal", 400);
- this.fontInfo.addMetrics("F" + num, bf);
- num++;
- }
- if (this.fontInfo.fontLookup("serif", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZN200 ", 1, new TimesRoman());
- AFPFont bf = new OutlineFont("Helvetica", cs);
- this.fontInfo.addFontProperties("F" + num, "serif", "normal", 400);
- this.fontInfo.addMetrics("F" + num, bf);
- num++;
- }
- if (this.fontInfo.fontLookup("monospace", "normal", 400) == null) {
- CharacterSet cs = new FopCharacterSet("T1V10500", "Cp500", "CZ4200 ", 1, new Courier());
- AFPFont bf = new OutlineFont("Helvetica", cs);
- this.fontInfo.addFontProperties("F" + num, "monospace", "normal", 400);
- this.fontInfo.addMetrics("F" + num, bf);
- num++;
- }
- if (this.fontInfo.fontLookup("any", "normal", 400) == null) {
- FontTriplet ft = this.fontInfo.fontLookup("sans-serif", "normal", 400);
- this.fontInfo.addFontProperties(this.fontInfo.getInternalFontKey(ft), "any", "normal", 400);
- }
- }
-
- /**
- */
- private AFPFontInfo buildFont(Configuration fontCfg, String _path)
- throws ConfigurationException {
-
- Configuration[] triple = fontCfg.getChildren("font-triplet");
- List tripleList = new java.util.ArrayList();
- if (triple.length == 0) {
- log.error("Mandatory font configuration element '<font-triplet...' is missing");
- return null;
- }
- for (int j = 0; j < triple.length; j++) {
- int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
- tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
- triple[j].getAttribute("style"),
- weight));
- }
-
- //build the fonts
- Configuration afpFontCfg = fontCfg.getChild("afp-font");
- if (afpFontCfg == null) {
- log.error("Mandatory font configuration element '<afp-font...' is missing");
- return null;
- }
- String path = afpFontCfg.getAttribute("path", _path);
- String type = afpFontCfg.getAttribute("type");
- if (type == null) {
- log.error("Mandatory afp-font configuration attribute 'type=' is missing");
- return null;
- }
- String codepage = afpFontCfg.getAttribute("codepage");
- if (codepage == null) {
- log.error("Mandatory afp-font configuration attribute 'code=' is missing");
- return null;
- }
- String encoding = afpFontCfg.getAttribute("encoding");
- if (encoding == null) {
- log.error("Mandatory afp-font configuration attribute 'encoding=' is missing");
- return null;
- }
-
- if ("raster".equalsIgnoreCase(type)) {
-
- String name = afpFontCfg.getAttribute("name", "Unknown");
-
- // Create a new font object
- RasterFont font = new RasterFont(name);
-
- Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font");
- if (rasters.length == 0) {
- log.error("Mandatory font configuration elements '<afp-raster-font...' are missing");
- return null;
- }
- for (int j = 0; j < rasters.length; j++) {
- Configuration rasterCfg = rasters[j];
-
- String characterset = rasterCfg.getAttribute("characterset");
- if (characterset == null) {
- log.error("Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
- return null;
- }
- int size = rasterCfg.getAttributeAsInteger("size");
- String base14 = rasterCfg.getAttribute("base14-font", null);
-
- if (base14 != null) {
- try {
- Class clazz = Class.forName("org.apache.fop.fonts.base14."
- + base14);
- try {
- Typeface tf = (Typeface)clazz.newInstance();
- font.addCharacterSet(size, new FopCharacterSet(
- codepage, encoding, characterset, size, tf));
- } catch (Exception ie) {
- String msg = "The base 14 font class " + clazz.getName()
- + " could not be instantiated";
- log.error(msg);
- }
- } catch (ClassNotFoundException cnfe) {
- String msg = "The base 14 font class for " + characterset
- + " could not be found";
- log.error(msg);
- }
- } else {
- font.addCharacterSet(size, new CharacterSet(
- codepage, encoding, characterset, path));
- }
- }
- return new AFPFontInfo(font, tripleList);
-
- } else if ("outline".equalsIgnoreCase(type)) {
-
- String characterset = afpFontCfg.getAttribute("characterset");
- if (characterset == null) {
- log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
- return null;
- }
- String name = afpFontCfg.getAttribute("name", characterset);
-
- CharacterSet characterSet = null;
-
- String base14 = afpFontCfg.getAttribute("base14-font", null);
-
- if (base14 != null) {
- try {
- Class clazz = Class.forName("org.apache.fop.fonts.base14."
- + base14);
- try {
- Typeface tf = (Typeface)clazz.newInstance();
- characterSet = new FopCharacterSet(
- codepage, encoding, characterset, 1, tf);
- } catch (Exception ie) {
- String msg = "The base 14 font class " + clazz.getName()
- + " could not be instantiated";
- log.error(msg);
- }
- } catch (ClassNotFoundException cnfe) {
- String msg = "The base 14 font class for " + characterset
- + " could not be found";
- log.error(msg);
- }
- } else {
- characterSet = new CharacterSet(codepage, encoding, characterset, path);
- }
- // Create a new font object
- OutlineFont font = new OutlineFont(name, characterSet);
- return new AFPFontInfo(font, tripleList);
- } else {
- log.error("No or incorrect type attribute");
- }
- return null;
- }
-
- /**
- * Builds a list of AFPFontInfo objects for use with the setup() method.
- * @param cfg Configuration object
- * @return List the newly created list of fonts
- * @throws ConfigurationException if something's wrong with the config data
- */
- public List buildFontListFromConfiguration(Configuration cfg)
- throws ConfigurationException {
- List fontList = new java.util.ArrayList();
- Configuration[] font = cfg.getChild("fonts").getChildren("font");
- for (int i = 0; i < font.length; i++) {
- AFPFontInfo afi = buildFont(font[i], null);
- if (afi != null) {
- if (log.isDebugEnabled()) {
- log.debug("Adding font " + afi.getAFPFont().getFontName());
- for (int j = 0; j < afi.getFontTriplets().size(); ++j) {
- FontTriplet triplet = (FontTriplet) afi.getFontTriplets().get(j);
- log.debug("Font triplet "
- + triplet.getName() + ", "
- + triplet.getStyle() + ", "
- + triplet.getWeight());
- }
- }
-
- fontList.add(afi);
- }
- }
- return fontList;
- }
-
- /**
- * Configure the AFP renderer.
- * Get the configuration to be used for fonts etc.
- * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
- */
- public void configure(Configuration cfg) throws ConfigurationException {
- //Font configuration
- this.fontList = buildFontListFromConfiguration(cfg);
- Configuration images = cfg.getChild("images");
- if (!"color".equalsIgnoreCase(images.getAttribute("mode", "b+w"))) {
- bitsPerPixel = images.getAttributeAsInteger("bits-per-pixel", 8);
- switch (bitsPerPixel) {
- case 1:
- case 4:
- case 8:
- break;
- default:
- log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
- bitsPerPixel = 8;
- break;
- }
- } else {
- colorImages = true;
- }
-
- }
-
- /**
- * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
- */
- public void setUserAgent(FOUserAgent agent) {
- super.setUserAgent(agent);
- }
-
- /**
- * @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream)
- */
- public void startRenderer(OutputStream outputStream) throws IOException {
- _currentPageFonts = new HashMap();
- _currentColor = new Color(255, 255, 255);
- _afpDataStream = new AFPDataStream();
- _afpDataStream.setPortraitRotation(_portraitRotation);
- _afpDataStream.setLandscapeRotation(_landscapeRotation);
- _afpDataStream.startDocument(outputStream);
- }
-
- /**
- * @see org.apache.fop.render.Renderer#stopRenderer(java.io.OutputStream)
- */
- public void stopRenderer() throws IOException {
- _afpDataStream.endDocument();
- }
-
- /**
- * @see org.apache.fop.render.Renderer#supportsOutOfOrder()
- */
- public boolean supportsOutOfOrder() {
- //return false;
- return true;
- }
-
- /**
- * Prepare a page for rendering. This is called if the renderer supports
- * out of order rendering. The renderer should prepare the page so that a
- * page further on in the set of pages can be rendered. The body of the
- * page should not be rendered. The page will be rendered at a later time
- * by the call to render page.
- *
- * @see org.apache.fop.render.Renderer#preparePage(PageViewport)
- */
- public void preparePage(PageViewport page) {
- // initializeRootExtensions(page);
-
- _currentFontFamily = "";
- _currentFontSize = 0;
- _pageFontCounter = 0;
- _currentPageFonts.clear();
- _lineCache = new HashSet();
-
- Rectangle2D bounds = page.getViewArea();
-
- _pageWidth = mpts2units(bounds.getWidth());
- _pageHeight = mpts2units(bounds.getHeight());
-
- // renderPageGroupExtensions(page);
-
- _afpDataStream.startPage(_pageWidth, _pageHeight, 0);
-
- renderPageObjectExtensions(page);
-
- if (_pages == null) {
- _pages = new HashMap();
- }
- _pages.put(page, _afpDataStream.savePage());
-
- }
-
- /**
- * @see org.apache.fop.render.Renderer#processOffDocumentItem(OffDocumentItem)
- */
- public void processOffDocumentItem(OffDocumentItem odi) {
- // TODO
- }
-
- /** @see org.apache.fop.render.Renderer#getGraphics2DAdapter() */
- public Graphics2DAdapter getGraphics2DAdapter() {
- return new AFPGraphics2DAdapter();
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#startVParea(CTM, Rectangle2D)
- */
- public void startVParea(CTM ctm, Rectangle2D clippingRect) {
- // dummy not used
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#endVParea()
- */
- public void endVParea() {
- // dummy not used
- }
-
- /**
- * Renders a region viewport. <p>
- *
- * The region may clip the area and it establishes a position from where
- * the region is placed.</p>
- *
- * @param port The region viewport to be rendered
- */
- public void renderRegionViewport(RegionViewport port) {
- if (port != null) {
- Rectangle2D view = port.getViewArea();
- // The CTM will transform coordinates relative to
- // this region-reference area into page coords, so
- // set origin for the region to 0,0.
- currentBPPosition = 0;
- currentIPPosition = 0;
-
- RegionReference regionReference = port.getRegionReference();
- handleRegionTraits(port);
-
- /*
- _afpDataStream.startOverlay(mpts2units(view.getX())
- , mpts2units(view.getY())
- , mpts2units(view.getWidth())
- , mpts2units(view.getHeight())
- , rotation);
- */
-
- pushViewPortPos(new ViewPortPos(view, regionReference.getCTM()));
-
- if (regionReference.getRegionClass() == FO_REGION_BODY) {
- renderBodyRegion((BodyRegion) regionReference);
- } else {
- renderRegion(regionReference);
- }
- /*
- _afpDataStream.endOverlay();
- */
- popViewPortPos();
- }
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#renderBlockViewport(BlockViewport, List)
- */
- protected void renderBlockViewport(BlockViewport bv, List children) {
- // clip and position viewport if necessary
-
- // save positions
- int saveIP = currentIPPosition;
- int saveBP = currentBPPosition;
- //String saveFontName = currentFontName;
-
- CTM ctm = bv.getCTM();
- int borderPaddingStart = bv.getBorderAndPaddingWidthStart();
- int borderPaddingBefore = bv.getBorderAndPaddingWidthBefore();
- float x, y;
- x = (float)(bv.getXOffset() + containingIPPosition) / 1000f;
- y = (float)(bv.getYOffset() + containingBPPosition) / 1000f;
- //This is the content-rect
- float width = (float)bv.getIPD() / 1000f;
- float height = (float)bv.getBPD() / 1000f;
-
-
- if (bv.getPositioning() == Block.ABSOLUTE
- || bv.getPositioning() == Block.FIXED) {
-
- currentIPPosition = bv.getXOffset();
- currentBPPosition = bv.getYOffset();
-
- //For FIXED, we need to break out of the current viewports to the
- //one established by the page. We save the state stack for restoration
- //after the block-container has been painted. See below.
- List breakOutList = null;
- if (bv.getPositioning() == Block.FIXED) {
- breakOutList = breakOutOfStateStack();
- }
-
- CTM tempctm = new CTM(containingIPPosition, containingBPPosition);
- ctm = tempctm.multiply(ctm);
-
- //Adjust for spaces (from margin or indirectly by start-indent etc.
- x += bv.getSpaceStart() / 1000f;
- currentIPPosition += bv.getSpaceStart();
-
- y += bv.getSpaceBefore() / 1000f;
- currentBPPosition += bv.getSpaceBefore();
-
- float bpwidth = (borderPaddingStart + bv.getBorderAndPaddingWidthEnd()) / 1000f;
- float bpheight = (borderPaddingBefore + bv.getBorderAndPaddingWidthAfter()) / 1000f;
-
- drawBackAndBorders(bv, x, y, width + bpwidth, height + bpheight);
-
- //Now adjust for border/padding
- currentIPPosition += borderPaddingStart;
- currentBPPosition += borderPaddingBefore;
-
- Rectangle2D clippingRect = null;
- clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
- bv.getIPD(), bv.getBPD());
-
- // startVParea(ctm, clippingRect);
- pushViewPortPos(new ViewPortPos(clippingRect, ctm));
- currentIPPosition = 0;
- currentBPPosition = 0;
- renderBlocks(bv, children);
- //endVParea();
- popViewPortPos();
-
- if (breakOutList != null) {
- restoreStateStackAfterBreakOut(breakOutList);
- }
-
- currentIPPosition = saveIP;
- currentBPPosition = saveBP;
- } else {
-
- currentBPPosition += bv.getSpaceBefore();
-
- //borders and background in the old coordinate system
- handleBlockTraits(bv);
-
- //Advance to start of content area
- currentIPPosition += bv.getStartIndent();
-
- CTM tempctm = new CTM(containingIPPosition, currentBPPosition);
- ctm = tempctm.multiply(ctm);
-
- //Now adjust for border/padding
- currentBPPosition += borderPaddingBefore;
-
- Rectangle2D clippingRect = null;
- clippingRect = new Rectangle(currentIPPosition, currentBPPosition,
- bv.getIPD(), bv.getBPD());
-
- //startVParea(ctm, clippingRect);
- pushViewPortPos(new ViewPortPos(clippingRect, ctm));
-
- currentIPPosition = 0;
- currentBPPosition = 0;
- renderBlocks(bv, children);
- //endVParea();
- popViewPortPos();
-
- currentIPPosition = saveIP;
- currentBPPosition = saveBP;
-
- currentBPPosition += (int)(bv.getAllocBPD());
- }
- //currentFontName = saveFontName;
- }
-
- /**
- * @see org.apache.fop.render.Renderer#renderPage(PageViewport)
- */
- public void renderPage(PageViewport page) {
-
- // initializeRootExtensions(page);
-
- _currentFontFamily = "";
- _currentFontSize = 0;
- _pageFontCounter = 0;
- _currentPageFonts.clear();
- _lineCache = new HashSet();
-
- Rectangle2D bounds = page.getViewArea();
-
- _pageWidth = mpts2units(bounds.getWidth());
- _pageHeight = mpts2units(bounds.getHeight());
-
- if (_pages != null && _pages.containsKey(page)) {
-
- _afpDataStream.restorePage((PageObject)_pages.remove(page));
-
- } else {
- // renderPageGroupExtensions(page);
-
- _afpDataStream.startPage(_pageWidth, _pageHeight, 0);
-
- renderPageObjectExtensions(page);
-
- }
-
- pushViewPortPos(new ViewPortPos());
-
- renderPageAreas(page.getPage());
-
- Iterator i = _currentPageFonts.values().iterator();
- while (i.hasNext()) {
- AFPFontAttributes afpFontAttributes = (AFPFontAttributes) i.next();
-
- _afpDataStream.createFont(
- afpFontAttributes.getFontReference(),
- afpFontAttributes.getFont(),
- afpFontAttributes.getPointSize());
-
- }
-
- try {
- _afpDataStream.endPage();
- } catch (IOException ioex) {
- // TODO What shall we do?
- }
-
- popViewPortPos();
-
- }
-
- /**
- * Clip using the current path.
- * @see org.apache.fop.render.AbstractRenderer#clip
- */
- public void clip() {
- // TODO
- }
-
- /**
- * Clip using a rectangular area.
- * @see org.apache.fop.render.AbstractRenderer#clipRect(float, float, float, float)
- */
- public void clipRect(float x, float y, float width, float height) {
- // TODO
- }
-
- /**
- * Moves the current point to (x, y), omitting any connecting line segment.
- * @see org.apache.fop.render.AbstractRenderer#moveTo(float, float)
- */
- public void moveTo(float x, float y) {
- // TODO
- }
-
- /**
- * Appends a straight line segment from the current point to (x, y). The
- * new current point is (x, y).
- * @see org.apache.fop.render.AbstractRenderer#lineTo(float, float)
- */
- public void lineTo(float x, float y) {
- // TODO
- }
-
- /**
- * Closes the current subpath by appending a straight line segment from
- * the current point to the starting point of the subpath.
- * @see org.apache.fop.render.AbstractRenderer#closePath
- */
- public void closePath() {
- // TODO
- }
-
- /**
- * Fill a rectangular area.
- * @see org.apache.fop.render.AbstractRenderer#fillRect(float, float, float, float)
- */
- public void fillRect(float x, float y, float width, float height) {
- /*
- _afpDataStream.createShading(
- pts2units(x),
- pts2units(y),
- pts2units(width),
- pts2units(height),
- _currentColor.getRed(),
- _currentColor.getGreen(),
- _currentColor.getBlue());
- */
- _afpDataStream.createLine(
- pts2units(x),
- pts2units(y),
- pts2units(x + width),
- pts2units(y),
- pts2units(height),
- _currentColor);
- }
-
- /**
- * Draw a border segment of an XSL-FO style border.
- * @see org.apache.fop.render.AbstractRenderer#drawBorderLine(float, float, float, float,
- * boolean, boolean, int, Color)
- */
- public void drawBorderLine(float x1, float y1, float x2, float y2,
- boolean horz, boolean startOrBefore, int style, Color col) {
- float w = x2 - x1;
- float h = y2 - y1;
- if ((w < 0) || (h < 0)) {
- log.error("Negative extent received. Border won't be painted.");
- return;
- }
- switch (style) {
- case Constants.EN_DOUBLE:
- if (horz) {
- float h3 = h / 3;
- float ym1 = y1;
- float ym2 = ym1 + h3 + h3;
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(ym1),
- pts2units(x2),
- pts2units(ym1),
- pts2units(h3),
- col
- );
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(ym2),
- pts2units(x2),
- pts2units(ym2),
- pts2units(h3),
- col
- );
- } else {
- float w3 = w / 3;
- float xm1 = x1;
- float xm2 = xm1 + w3 + w3;
- _afpDataStream.createLine(
- pts2units(xm1),
- pts2units(y1),
- pts2units(xm1),
- pts2units(y2),
- pts2units(w3),
- col
- );
- _afpDataStream.createLine(
- pts2units(xm2),
- pts2units(y1),
- pts2units(xm2),
- pts2units(y2),
- pts2units(w3),
- col
- );
- }
- break;
- case Constants.EN_DASHED:
- if (horz) {
- float w2 = 2 * h;
- while (x1 + w2 < x2) {
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(y1),
- pts2units(x1 + w2),
- pts2units(y1),
- pts2units(h),
- col
- );
- x1 += 2 * w2;
- }
- } else {
- float h2 = 2 * w;
- while (y1 + h2 < y2) {
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(y1),
- pts2units(x1),
- pts2units(y1 + h2),
- pts2units(w),
- col
- );
- y1 += 2 * h2;
- }
- }
- break;
- case Constants.EN_DOTTED:
- if (horz) {
- while (x1 + h < x2) {
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(y1),
- pts2units(x1 + h),
- pts2units(y1),
- pts2units(h),
- col
- );
- x1 += 2 * h;
- }
- } else {
- while (y1 + w < y2) {
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(y1),
- pts2units(x1),
- pts2units(y1 + w),
- pts2units(w),
- col
- );
- y1 += 2 * w;
- }
- }
- break;
- case Constants.EN_GROOVE:
- case Constants.EN_RIDGE:
- {
- float colFactor = (style == EN_GROOVE ? 0.4f : -0.4f);
- if (horz) {
- Color uppercol = lightenColor(col, -colFactor);
- Color lowercol = lightenColor(col, colFactor);
- float h3 = h / 3;
- float ym1 = y1;
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(ym1),
- pts2units(x2),
- pts2units(ym1),
- pts2units(h3),
- uppercol
- );
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(ym1 + h3),
- pts2units(x2),
- pts2units(ym1 + h3),
- pts2units(h3),
- col
- );
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(ym1 + h3 + h3),
- pts2units(x2),
- pts2units(ym1 + h3 + h3),
- pts2units(h3),
- lowercol
- );
- } else {
- Color leftcol = lightenColor(col, -colFactor);
- Color rightcol = lightenColor(col, colFactor);
- float w3 = w / 3;
- float xm1 = x1 + (w3 / 2);
- _afpDataStream.createLine(
- pts2units(xm1),
- pts2units(y1),
- pts2units(xm1),
- pts2units(y2),
- pts2units(w3),
- leftcol
- );
- _afpDataStream.createLine(
- pts2units(xm1 + w3),
- pts2units(y1),
- pts2units(xm1 + w3),
- pts2units(y2),
- pts2units(w3),
- col
- );
- _afpDataStream.createLine(
- pts2units(xm1 + w3 + w3),
- pts2units(y1),
- pts2units(xm1 + w3 + w3),
- pts2units(y2),
- pts2units(w3),
- rightcol
- );
- }
- break;
- }
- case Constants.EN_HIDDEN:
- break;
- case Constants.EN_INSET:
- case Constants.EN_OUTSET:
- default:
- _afpDataStream.createLine(
- pts2units(x1),
- pts2units(y1),
- pts2units(horz ? x2 : x1),
- pts2units(horz ? y1 : y2),
- pts2units(Math.abs(horz ? (y2 - y1) : (x2 - x1))),
- col
- );
- }
- }
-
- /**
- * @see org.apache.fop.render.PrintRenderer#createRendererContext(
- * int, int, int, int, java.util.Map)
- */
- protected RendererContext createRendererContext(int x, int y, int width, int height, Map foreignAttributes) {
- RendererContext context;
- context = super.createRendererContext(x, y, width, height, foreignAttributes);
- context.setProperty(AFPRendererContextConstants.AFP_GRAYSCALE,
- new Boolean(!this.colorImages));
- return context;
- }
-
- /**
- * Draw an image at the indicated location.
- * @see org.apache.fop.render.AbstractRenderer#drawImage(String, Rectangle2D, Map)
- */
- public void drawImage(String url, Rectangle2D pos, Map foreignAttributes) {
- String name = null;
- if (_pageSegmentsMap != null) {
- name = (String)_pageSegmentsMap.get(url);
- }
- if (name != null) {
- int x = mpts2units(pos.getX() + currentIPPosition);
- int y = mpts2units(pos.getY() + currentBPPosition);
- _afpDataStream.createIncludePageSegment(name, x, y);
- } else {
- url = ImageFactory.getURL(url);
- ImageFactory fact = userAgent.getFactory().getImageFactory();
- FopImage fopimage = fact.getImage(url, userAgent);
- if (fopimage == null) {
- return;
- }
- if (!fopimage.load(FopImage.DIMENSIONS)) {
- return;
- }
- String mime = fopimage.getMimeType();
- if ("text/xml".equals(mime) || MimeConstants.MIME_SVG.equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- Document doc = ((XMLImage) fopimage).getDocument();
- String ns = ((XMLImage) fopimage).getNameSpace();
-
- renderDocument(doc, ns, pos, foreignAttributes);
- } else if (MimeConstants.MIME_EPS.equals(mime)) {
- log.warn("EPS images are not supported by this renderer");
- /*
- } else if (MimeConstants.MIME_JPEG.equals(mime)) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- fact.releaseImage(url, userAgent);
-
- int x = mpts2units(pos.getX() + currentIPPosition);
- int y = mpts2units(pos.getY() + currentBPPosition);
- int w = mpts2units(pos.getWidth());
- int h = mpts2units(pos.getHeight());
- ImageObject io = _afpDataStream.getImageObject();
- io.setImageViewport(x, y, w, h);
- io.setImageParameters(
- (int)(fopimage.getHorizontalResolution() * 10),
- (int)(fopimage.getVerticalResolution() * 10),
- fopimage.getWidth(),
- fopimage.getHeight()
- );
- io.setImageIDESize((byte)fopimage.getBitsPerPixel());
- io.setImageEncoding((byte)0x83);
- io.setImageData(fopimage.getRessourceBytes());
- */
- } else if (MimeConstants.MIME_TIFF.equals(mime)
- && fopimage instanceof TIFFImage) {
- TIFFImage tiffImage = (TIFFImage) fopimage;
- int x = mpts2units(pos.getX() + currentIPPosition);
- int y = mpts2units(pos.getY() + currentBPPosition);
- int w = mpts2units(pos.getWidth());
- int h = mpts2units(pos.getHeight());
- ImageObject io = _afpDataStream.getImageObject(x, y, w, h);
- io.setImageParameters(
- (int)(fopimage.getHorizontalResolution() * 10),
- (int)(fopimage.getVerticalResolution() * 10),
- fopimage.getWidth(),
- fopimage.getHeight()
- );
- if (tiffImage.getStripCount() == 1) {
- int comp = tiffImage.getCompression();
- if (comp == 3) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- io.setImageEncoding((byte)0x81);
- io.setImageData(fopimage.getRessourceBytes());
- } else if (comp == 4) {
- if (!fopimage.load(FopImage.ORIGINAL_DATA)) {
- return;
- }
- io.setImageEncoding((byte)0x82);
- io.setImageData(fopimage.getRessourceBytes());
- } else {
- if (!fopimage.load(FopImage.BITMAP)) {
- return;
- }
- convertToGrayScaleImage(io, fopimage.getBitmaps());
- }
- } else {
- if (!fopimage.load(FopImage.BITMAP)) {
- return;
- }
- convertToGrayScaleImage(io, fopimage.getBitmaps());
- }
- } else {
- if (!fopimage.load(FopImage.BITMAP)) {
- return;
- }
- fact.releaseImage(url, userAgent);
-
- int x = mpts2units(pos.getX() + currentIPPosition);
- int y = mpts2units(pos.getY() + currentBPPosition);
- int w = mpts2units(pos.getWidth());
- int h = mpts2units(pos.getHeight());
- ImageObject io = _afpDataStream.getImageObject(x, y, w, h);
- io.setImageParameters(
- (int)(fopimage.getHorizontalResolution() * 10),
- (int)(fopimage.getVerticalResolution() * 10),
- fopimage.getWidth(),
- fopimage.getHeight()
- );
- if (colorImages) {
- io.setImageIDESize((byte)24);
- io.setImageData(fopimage.getBitmaps());
- } else {
- convertToGrayScaleImage(io, fopimage.getBitmaps());
- }
- }
- }
- }
-
- /**
- * Writes a BufferedImage to an OutputStream as raw sRGB bitmaps.
- * @param img the BufferedImage
- * @param out the OutputStream
- * @throws IOException In case of an I/O error.
- */
- public static void writeImage(BufferedImage img, OutputStream out) throws IOException {
- int w = img.getWidth();
- int h = img.getHeight();
- int[] tmpMap = img.getRGB(0, 0, w, h, null, 0, w);
- for (int i = 0; i < h; i++) {
- for (int j = 0; j < w; j++) {
- int p = tmpMap[i * w + j];
- int r = (p >> 16) & 0xFF;
- int g = (p >> 8) & 0xFF;
- int b = (p) & 0xFF;
- out.write((byte)(r & 0xFF));
- out.write((byte)(g & 0xFF));
- out.write((byte)(b & 0xFF));
- }
- }
- }
-
- /**
- * Draws a BufferedImage to AFP.
- * @param bi the BufferedImage
- * @param resolution the resolution of the BufferedImage
- * @param x the x coordinate (in mpt)
- * @param y the y coordinate (in mpt)
- * @param w the width of the viewport (in mpt)
- * @param h the height of the viewport (in mpt)
- */
- public void drawBufferedImage(BufferedImage bi, int resolution, int x, int y, int w, int h) {
- int afpx = mpts2units(x);
- int afpy = mpts2units(y);
- int afpw = mpts2units(w);
- int afph = mpts2units(h);
- ByteArrayOutputStream baout = new ByteArrayOutputStream();
- try {
- //Serialize image
- writeImage(bi, baout);
- byte[] buf = baout.toByteArray();
-
- //Generate image
- ImageObject io = _afpDataStream.getImageObject(afpx, afpy, afpw, afph);
- io.setImageParameters(
- resolution, resolution,
- bi.getWidth(),
- bi.getHeight()
- );
- if (colorImages) {
- io.setImageIDESize((byte)24);
- io.setImageData(buf);
- } else {
- //TODO Teach it how to handle grayscale BufferedImages directly
- //because this is pretty inefficient
- convertToGrayScaleImage(io, buf);
- }
- } catch (IOException ioe) {
- log.error("Error while serializing bitmap: " + ioe.getMessage(), ioe);
- }
- }
-
- /**
- * Establishes a new foreground or fill color.
- * @see org.apache.fop.render.AbstractRenderer#updateColor(Color, boolean)
- */
- public void updateColor(Color col, boolean fill) {
- if (fill) {
- _currentColor = col;
- }
- }
-
- /**
- * Restores the state stack after a break out.
- * @param breakOutList the state stack to restore.
- */
- public void restoreStateStackAfterBreakOut(List breakOutList) {
-
- }
-
- /**
- * Breaks out of the state stack to handle fixed block-containers.
- * @return the saved state stack to recreate later
- */
- public List breakOutOfStateStack() {
- return null;
- }
-
- /** Saves the graphics state of the rendering engine. */
- public void saveGraphicsState() {
-
- }
-
- /** Restores the last graphics state of the rendering engine. */
- public void restoreGraphicsState() {
-
- }
-
- /** Indicates the beginning of a text object. */
- public void beginTextObject() {
-
- }
-
- /** Indicates the end of a text object. */
- public void endTextObject() {
-
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#renderImage(Image, Rectangle2D)
- */
- public void renderImage(Image image, Rectangle2D pos) {
- String url = image.getURL();
- drawImage(url, pos);
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#renderText(TextArea)
- */
- public void renderText(TextArea text) {
- renderInlineAreaBackAndBorders(text);
-
- String name = getInternalFontNameForArea(text);
- _currentFontSize = ((Integer) text.getTrait(Trait.FONT_SIZE)).intValue();
- AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
-
- Color col = (Color) text.getTrait(Trait.COLOR);
-
- int vsci = mpts2units(tf.getWidth(' ', _currentFontSize) / 1000
- + text.getTextWordSpaceAdjust()
- + text.getTextLetterSpaceAdjust());
-
- // word.getOffset() = only height of text itself
- // currentBlockIPPosition: 0 for beginning of line; nonzero
- // where previous line area failed to take up entire allocated space
- int rx = currentIPPosition + text.getBorderAndPaddingWidthStart();
- int bl = currentBPPosition + text.getOffset() + text.getBaselineOffset();
-
- // Set letterSpacing
- //float ls = fs.getLetterSpacing() / this.currentFontSize;
-
- String worddata = text.getText();
-
- // Create an AFPFontAttributes object from the current font details
- AFPFontAttributes afpFontAttributes =
- new AFPFontAttributes(name, tf, _currentFontSize);
-
- if (!_currentPageFonts.containsKey(afpFontAttributes.getFontKey())) {
- // Font not found on current page, so add the new one
- _pageFontCounter++;
- afpFontAttributes.setFontReference(_pageFontCounter);
- _currentPageFonts.put(
- afpFontAttributes.getFontKey(),
- afpFontAttributes);
-
- } else {
- // Use the previously stored font attributes
- afpFontAttributes =
- (AFPFontAttributes) _currentPageFonts.get(
- afpFontAttributes.getFontKey());
- }
-
- // Try and get the encoding to use for the font
- String encoding = null;
-
- try {
- encoding = tf.getCharacterSet(_currentFontSize).getEncoding();
- } catch (Throwable ex) {
- encoding = AFPConstants.EBCIDIC_ENCODING;
- log.warn(
- "renderText():: Error getting encoding for font "
- + " - using default encoding "
- + encoding);
- }
-
- try {
- _afpDataStream.createText(
- afpFontAttributes.getFontReference(),
- mpts2units(rx),
- mpts2units(bl),
- col,
- vsci,
- mpts2units(text.getTextLetterSpaceAdjust()),
- worddata.getBytes(encoding));
- } catch (UnsupportedEncodingException usee) {
- log.error(
- "renderText:: Font "
- + afpFontAttributes.getFontKey()
- + " caused UnsupportedEncodingException");
- }
-
- super.renderText(text);
-
- renderTextDecoration(tf, _currentFontSize, text, bl, rx);
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#renderWord(WordArea)
- */
- public void renderWord(WordArea word) {
- String name = getInternalFontNameForArea(word.getParentArea());
- int size = ((Integer) word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
- AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
-
- String s = word.getWord();
-
- FontMetrics metrics = fontInfo.getMetricsFor(name);
-
- super.renderWord(word);
- }
-
- /**
- * @see org.apache.fop.render.AbstractRenderer#renderSpace(SpaceArea)
- */
- public void renderSpace(SpaceArea space) {
- String name = getInternalFontNameForArea(space.getParentArea());
- int size = ((Integer) space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue();
- AFPFont tf = (AFPFont) fontInfo.getFonts().get(name);
-
- String s = space.getSpace();
-
- FontMetrics metrics = fontInfo.getMetricsFor(name);
-
- super.renderSpace(space);
- }
-
- /**
- * Render leader area.
- * This renders a leader area which is an area with a rule.
- * @param area the leader area to render
- */
- public void renderLeader(Leader area) {
- renderInlineAreaBackAndBorders(area);
-
- int style = area.getRuleStyle();
- float startx = (currentIPPosition + area.getBorderAndPaddingWidthStart()) / 1000f;
- float starty = (currentBPPosition + area.getOffset()) / 1000f;
- float endx = (currentIPPosition + area.getBorderAndPaddingWidthStart()
- + area.getIPD()) / 1000f;
- float ruleThickness = area.getRuleThickness() / 1000f;
- Color col = (Color)area.getTrait(Trait.COLOR);
-
- switch (style) {
- case EN_SOLID:
- case EN_DASHED:
- case EN_DOUBLE:
- case EN_DOTTED:
- case EN_GROOVE:
- case EN_RIDGE:
- drawBorderLine(startx, starty, endx, starty + ruleThickness,
- true, true, style, col);
- break;
- default:
- throw new UnsupportedOperationException("rule style not supported");
- }
- super.renderLeader(area);
- }
-
- /**
- * @see org.apache.fop.render.Renderer#setProducer(String)
- */
- public void setProducer(String producer) {
- _afpDataStream.setProducer(producer);
- }
-
- /**
- * @see org.apache.fop.render.Renderer#setOptions(Map)
- */
- public void setOptions(Map options) {
-
- _afpOptions = options;
-
- }
-
- /**
- * Determines the orientation from the string representation, this method
- * guarantees to return a value of either 0, 90, 180 or 270.
- *
- * @return the orientation
- */
- private int getOrientation(String orientationString) {
-
- int orientation = 0;
- if (orientationString != null && orientationString.length() > 0) {
- try {
- orientation = Integer.parseInt(orientationString);
- } catch (NumberFormatException nfe) {
- log.error(
- "Cannot use orientation of "
- + orientation
- + " defaulting to zero.");
- orientation = 0;
- }
- } else {
- orientation = 0;
- }
- switch (orientation) {
- case 0 :
- break;
- case 90 :
- break;
- case 180 :
- break;
- case 270 :
- break;
- default :
- log.error(
- "Cannot use orientation of "
- + orientation
- + " defaulting to zero.");
- orientation = 0;
- break;
- }
-
- return orientation;
-
- }
-
- /**
- * Sets the rotation to be used for portrait pages, valid values are 0
- * (default), 90, 180, 270.
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setPortraitRotation(int rotation) {
-
- if (rotation == 0
- || rotation == 90
- || rotation == 180
- || rotation == 270) {
- _portraitRotation = rotation;
- } else {
- throw new IllegalArgumentException("The portrait rotation must be one"
- + " of the values 0, 90, 180, 270");
-
- }
-
- }
-
- /**
- * Sets the rotation to be used for landsacpe pages, valid values are 0, 90,
- * 180, 270 (default).
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setLandscapeRotation(int rotation) {
-
- if (rotation == 0
- || rotation == 90
- || rotation == 180
- || rotation == 270) {
- _landscapeRotation = rotation;
- } else {
- throw new IllegalArgumentException("The landscape rotation must be one"
- + " of the values 0, 90, 180, 270");
- }
-
- }
-
- /**
- * Get the MIME type of the renderer.
- *
- * @return The MIME type of the renderer
- */
- public String getMimeType() {
- return MimeConstants.MIME_AFP;
- }
-
- /**
- * Method to render the page extension.
- * <p>
- *
- * @param page
- * the page object
- */
- private void renderPageObjectExtensions(PageViewport page) {
-
- _pageSegmentsMap = null;
- if (page.getExtensionAttachments() != null
- && page.getExtensionAttachments().size() > 0) {
- //Extract all AFPPageSetup instances from the attachment list on the s-p-m
- Iterator i = page.getExtensionAttachments().iterator();
- while (i.hasNext()) {
- ExtensionAttachment attachment = (ExtensionAttachment)i.next();
- if (AFPPageSetup.CATEGORY.equals(attachment.getCategory())) {
- AFPPageSetup aps = (AFPPageSetup)attachment;
- String element = aps.getElementName();
- if (AFPElementMapping.INCLUDE_PAGE_OVERLAY.equals(element)) {
- String overlay = aps.getName();
- if (overlay != null) {
- _afpDataStream.createIncludePageOverlay(overlay);
- }
- } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(element)) {
- String name = aps.getName();
- String source = aps.getValue();
- if (_pageSegmentsMap == null) {
- _pageSegmentsMap = new HashMap();
- }
- _pageSegmentsMap.put(source, name);
- } else if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(element)) {
- String name = aps.getName();
- String value = aps.getValue();
- if (_pageSegmentsMap == null) {
- _pageSegmentsMap = new HashMap();
- }
- _afpDataStream.createTagLogicalElement(name, value);
- }
- }
- }
- }
-
- }
-
- /**
- * Converts FOP mpt measurement to afp measurement units
- * @param mpt the millipoints value
- */
- private int mpts2units(int mpt) {
- return mpts2units((double) mpt);
- }
-
- /**
- * Converts FOP pt measurement to afp measurement units
- * @param mpt the millipoints value
- */
- private int pts2units(float mpt) {
- return mpts2units(mpt * 1000d);
- }
-
- /**
- * Converts FOP mpt measurement to afp measurement units
- * @param mpt the millipoints value
- */
- private int mpts2units(double mpt) {
- return (int)Math.round(mpt / DPI_CONVERSION_FACTOR_240);
- }
-
- private void convertToGrayScaleImage(ImageObject io, byte raw[]) {
- int pixelsPerByte = 8 / bitsPerPixel;
- byte bw[] = new byte[raw.length / (3 * pixelsPerByte)];
- int k = 0;
- for (int i = 0, j = 0; i < raw.length; i += 3, j++) {
- if (j == pixelsPerByte) {
- j = 0;
- k++;
- }
- // see http://www.jguru.com/faq/view.jsp?EID=221919
- double greyVal = 0.212671d * ((int) raw[i] & 0xff)
- + 0.715160d * ((int) raw[i + 1] & 0xff)
- + 0.072169d * ((int) raw[i + 2] & 0xff);
- switch (bitsPerPixel) {
- case 1:
- if (greyVal > 128) {
- bw[k] |= (byte)(1 << j);
- }
- break;
- case 4:
- greyVal /= 16;
- bw[k] |= (byte)((byte)greyVal << (j * 4));
- break;
- case 8:
- bw[k] = (byte)greyVal;
- break;
- }
- }
- io.setImageIDESize((byte)bitsPerPixel);
- io.setImageData(bw);
- }
-
- private class ViewPortPos {
- int x = 0;
- int y = 0;
- int rot = 0;
-
- ViewPortPos() {
- }
-
- ViewPortPos(Rectangle2D view, CTM ctm) {
- ViewPortPos currentVP = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
- int xOrigin;
- int yOrigin;
- int width;
- int height;
- switch (currentVP.rot) {
- case 90:
- width = mpts2units(view.getHeight());
- height = mpts2units(view.getWidth());
- xOrigin = _pageWidth - width - mpts2units(view.getY()) - currentVP.y;
- yOrigin = mpts2units(view.getX()) + currentVP.x;
- break;
- case 180:
- width = mpts2units(view.getWidth());
- height = mpts2units(view.getHeight());
- xOrigin = _pageWidth - width - mpts2units(view.getX()) - currentVP.x;
- yOrigin = _pageHeight - height - mpts2units(view.getY()) - currentVP.y;
- break;
- case 270:
- width = mpts2units(view.getHeight());
- height = mpts2units(view.getWidth());
- xOrigin = mpts2units(view.getY()) + currentVP.y;
- yOrigin = _pageHeight - height - mpts2units(view.getX()) - currentVP.x;
- break;
- default:
- xOrigin = mpts2units(view.getX()) + currentVP.x;
- yOrigin = mpts2units(view.getY()) + currentVP.y;
- width = mpts2units(view.getWidth());
- height = mpts2units(view.getHeight());
- break;
- }
- this.rot = currentVP.rot;
- double ctmf[] = ctm.toArray();
- if (ctmf[0] == 0.0d && ctmf[1] == -1.0d && ctmf[2] == 1.0d && ctmf[3] == 0.d) {
- this.rot += 270;
- } else if (ctmf[0] == -1.0d && ctmf[1] == 0.0d && ctmf[2] == 0.0d && ctmf[3] == -1.0d) {
- this.rot += 180;
- } else if (ctmf[0] == 0.0d && ctmf[1] == 1.0d && ctmf[2] == -1.0d && ctmf[3] == 0.0d) {
- this.rot += 90;
- }
- this.rot %= 360;
- switch (this.rot) {
- /*
- case 0:
- this.x = mpts2units(view.getX()) + x;
- this.y = mpts2units(view.getY()) + y;
- break;
- case 90:
- this.x = mpts2units(view.getY()) + y;
- this.y = _pageWidth - mpts2units(view.getX() + view.getWidth()) - x;
- break;
- case 180:
- this.x = _pageWidth - mpts2units(view.getX() + view.getWidth()) - x;
- this.y = _pageHeight - mpts2units(view.getY() + view.getHeight()) - y;
- break;
- case 270:
- this.x = _pageHeight - mpts2units(view.getY() + view.getHeight()) - y;
- this.y = mpts2units(view.getX()) + x;
- break;
- */
- case 0:
- this.x = xOrigin;
- this.y = yOrigin;
- break;
- case 90:
- this.x = yOrigin;
- this.y = _pageWidth - width - xOrigin;
- break;
- case 180:
- this.x = _pageWidth - width - xOrigin;
- this.y = _pageHeight - height - yOrigin;
- break;
- case 270:
- this.x = _pageHeight - height - yOrigin;
- this.y = xOrigin;
- break;
- }
- }
-
- public String toString() {
- return "x:" + x + " y:" + y + " rot:" + rot;
- }
-
- }
-
- private List viewPortPositions = new ArrayList();
-
- private void pushViewPortPos(ViewPortPos vpp) {
- viewPortPositions.add(vpp);
- _afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
- }
-
- private void popViewPortPos() {
- viewPortPositions.remove(viewPortPositions.size() - 1);
- if (viewPortPositions.size() > 0) {
- ViewPortPos vpp = (ViewPortPos)viewPortPositions.get(viewPortPositions.size() - 1);
- _afpDataStream.setOffsets(vpp.x, vpp.y, vpp.rot);
- }
- }
-
-}
-
+++ /dev/null
-/*\r
- * Copyright 2006 The Apache Software Foundation.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-/* $Id$ */\r
-\r
-package org.apache.fop.render.afp;\r
-\r
-import org.apache.fop.render.RendererContextConstants;\r
-\r
-/**\r
- * Defines a number of standard constants (keys) for use by the RendererContext class.\r
- */\r
-public interface AFPRendererContextConstants extends RendererContextConstants {\r
-\r
- /**\r
- * Key for a Boolean value that enables grayscale processing instead of color \r
- * processing.\r
- */\r
- String AFP_GRAYSCALE = "afpGrayscale";\r
-\r
-}\r
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.render.AbstractRendererMaker;
-import org.apache.fop.render.Renderer;
-
-/**
- * RendererMaker for the AFP Renderer.
- */
-public class AFPRendererMaker extends AbstractRendererMaker {
-
- private static final String[] MIMES = new String[] {
- MimeConstants.MIME_AFP,
- MimeConstants.MIME_AFP_ALT};
-
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
- return new AFPRenderer();
- }
-
- /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
- public boolean needsOutputStream() {
- return true;
- }
-
- /** @see org.apache.fop.render.AbstractRendererMaker#getSupportedMimeTypes() */
- public String[] getSupportedMimeTypes() {
- return MIMES;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp;
-
-// FOP
-import org.apache.fop.render.AbstractGenericSVGHandler;
-import org.apache.fop.render.Renderer;
-
-/**
- * AFP XML handler for SVG. Uses Apache Batik for SVG processing.
- * This handler handles XML for foreign objects and delegates to AFPGraphics2DAdapter.
- * @see AFPGraphics2DAdapter
- */
-public class AFPSVGHandler extends AbstractGenericSVGHandler {
-
- /** @see org.apache.fop.render.XMLHandler#supportsRenderer(org.apache.fop.render.Renderer) */
- public boolean supportsRenderer(Renderer renderer) {
- return (renderer instanceof AFPRenderer);
- }
-
-}
-
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.exceptions;
-
-/**
- * A runtime exception for handling fatal errors in processing fonts.
- * <p/>
- */
-public class FontRuntimeException extends NestedRuntimeException {
-
- /**
- * Constructs a FontRuntimeException with the specified message.
- * @param msg the exception mesaage
- */
- public FontRuntimeException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a FontRuntimeException with the specified message
- * wrapping the underlying exception.
- * @param msg the exception mesaage
- * @param t the underlying exception
- */
- public FontRuntimeException(String msg, Throwable t) {
- super(msg, t);
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.exceptions;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Handy class for wrapping runtime Exceptions with a root cause.
- * This technique is no longer necessary in Java 1.4, which provides
- * built-in support for exception nesting. Thus exceptions in applications
- * written to use Java 1.4 need not extend this class.
- *
- */
-public abstract class NestedRuntimeException extends RuntimeException {
-
- /** Root cause of this nested exception */
- private Throwable _underlyingException;
-
- /**
- * Construct a <code>NestedRuntimeException</code> with the specified detail message.
- * @param msg The detail message.
- */
- public NestedRuntimeException(String msg) {
- super(msg);
- }
-
- /**
- * Construct a <code>NestedRuntimeException</code> with the specified
- * detail message and nested exception.
- * @param msg The detail message.
- * @param t The nested exception.
- */
- public NestedRuntimeException(String msg, Throwable t) {
- super(msg);
- _underlyingException = t;
-
- }
-
- /**
- * Gets the original triggering exception
- * @return The original exception as a throwable.
- */
- public Throwable getUnderlyingException() {
-
- return _underlyingException;
-
- }
-
- /**
- * Return the detail message, including the message from the nested
- * exception if there is one.
- * @return The detail message.
- */
- public String getMessage() {
-
- if (_underlyingException == null) {
- return super.getMessage();
- } else {
- return super.getMessage()
- + "; nested exception is "
- + _underlyingException.getClass().getName();
- }
-
- }
-
- /**
- * Print the composite message and the embedded stack trace to the specified stream.
- * @param ps the print stream
- */
- public void printStackTrace(PrintStream ps) {
- if (_underlyingException == null) {
- super.printStackTrace(ps);
- } else {
- ps.println(this);
- _underlyingException.printStackTrace(ps);
- }
- }
-
- /**
- * Print the composite message and the embedded stack trace to the specified writer.
- * @param pw the print writer
- */
- public void printStackTrace(PrintWriter pw) {
- if (_underlyingException == null) {
- super.printStackTrace(pw);
- } else {
- pw.println(this);
- _underlyingException.printStackTrace(pw);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.exceptions;
-
-/**
- * A runtime exception for handling fatal errors in rendering.
- * <p/>
- */
-public class RendererRuntimeException extends NestedRuntimeException {
-
- /**
- * Constructs a RendererRuntimeException with the specified message.
- * @param msg the exception mesaage
- */
- public RendererRuntimeException(String msg) {
- super(msg);
- }
-
- /**
- * Constructs a RendererRuntimeException with the specified message
- * wrapping the underlying exception.
- * @param msg the exception mesaage
- * @param t the underlying exception
- */
- public RendererRuntimeException(String msg, Throwable t) {
- super(msg, t);
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.properties.Property;
-import org.apache.fop.fo.properties.StringProperty;
-
-/**
- * This class extends the org.apache.fop.fo.StringProperty.Maker inner class
- * in order to provide a static property maker. The object faciliates
- * extraction of attributes from formatted objects based on the static list
- * as defined in the AFPElementMapping implementation.
- * <p/>
- */
-public class AFPAttribute extends StringProperty.Maker {
-
- /**
- * The attribute property.
- */
- private Property _property;
-
- /**
- * Constructor for the AFPAttribute.
- * @param name The attribute name
- */
- protected AFPAttribute(String name) {
- super(0);
- _property = null;
- }
-
- /**
- * Overide the make method to return the property object
- * @param propertyList the property list from which to make the property
- * @return property The property object.
- */
- public Property make(PropertyList propertyList) {
- if (_property == null) {
- _property = make(propertyList, "", propertyList.getParentFObj());
- }
- return _property;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.ValidationException;
-import org.apache.fop.fo.XMLObj;
-
-/**
- * This class extends the org.apache.fop.extensions.ExtensionObj class. The
- * object faciliates extraction of elements from formatted objects based on
- * the static list as defined in the AFPElementMapping implementation.
- * <p/>
- */
-public class AFPElement extends AbstractAFPExtensionObject {
-
- /**
- * Constructs an AFP object (called by Maker).
- *
- * @param parent the parent formatting object
- * @param name the name of the afp element
- */
- public AFPElement(FONode parent, String name) {
- super(parent, name);
- }
-
- /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
- public String getNamespaceURI() {
- return AFPElementMapping.NAMESPACE;
- }
-
- /** @see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
- public String getNormalNamespacePrefix() {
- return "afp";
- }
-
- /** @see org.apache.fop.fo.FONode#startOfNode() */
- protected void startOfNode() throws FOPException {
- super.startOfNode();
- //if (!AFPElementMapping.NAMESPACE.equals(parent.getNamespaceURI())
- // || !AFPElementMapping.PAGE.equals(parent.getLocalName())) {
- // throw new ValidationException(getName() + " must be a child of afp:page.");
- //}
- if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
- throw new ValidationException(getName() + " must be a child of fo:simple-page-master.");
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-
-import java.util.HashMap;
-
-import org.apache.fop.fo.ElementMapping;
-import org.apache.fop.fo.FONode;
-
-
-/**
- * AFPElementMapping object provides the ability to extract information
- * from the formatted object that reside in the afp namespace. This is used
- * for custom AFP extensions not supported by the FO schema. Examples include
- * adding overlays or indexing a document using the tag logical element
- * structured field.
- * <p/>
- */
-public class AFPElementMapping extends ElementMapping {
-
- public static final String PAGE = "page";
-
- public static final String PAGE_GROUP = "page-group";
-
- public static final String TAG_LOGICAL_ELEMENT = "tag-logical-element";
-
- public static final String INCLUDE_PAGE_OVERLAY = "include-page-overlay";
-
- public static final String INCLUDE_PAGE_SEGMENT = "include-page-segment";
-
- /**
- * The namespace used for AFP extensions
- */
- public static final String NAMESPACE = "http://xmlgraphics.apache.org/fop/extensions/afp";
-
- /**
- * The usual namespace prefix used for AFP extensions
- */
- public static final String NAMESPACE_PREFIX = "afp";
-
- /** Main constructor */
- public AFPElementMapping() {
- this.namespaceURI = NAMESPACE;
- }
-
- /**
- * Private static synchronized method to set up the element and atribute
- * HashMaps, this defines what elements and attributes are extracted.
- */
- protected void initialize() {
-
- if (foObjs == null) {
- foObjs = new HashMap();
- foObjs.put(PAGE, new AFPPageSetupMaker());
- // foObjs.put(PAGE_GROUP, new AFPMaker());
- foObjs.put(
- TAG_LOGICAL_ELEMENT,
- new AFPTagLogicalElementMaker());
- foObjs.put(
- INCLUDE_PAGE_SEGMENT,
- new AFPIncludePageSegmentMaker());
- foObjs.put(
- INCLUDE_PAGE_OVERLAY,
- new AFPIncludePageOverlayMaker());
- }
-
- }
-
- static class AFPPageSetupMaker extends ElementMapping.Maker {
- public FONode make(FONode parent) {
- return new AFPPageSetupElement(parent);
- }
- }
-
- static class AFPIncludePageOverlayMaker extends ElementMapping.Maker {
- public FONode make(FONode parent) {
- return new AFPElement(parent, INCLUDE_PAGE_OVERLAY);
- }
- }
-
- static class AFPIncludePageSegmentMaker extends ElementMapping.Maker {
- public FONode make(FONode parent) {
- return new AFPElement(parent, INCLUDE_PAGE_SEGMENT);
- }
- }
-
- static class AFPTagLogicalElementMaker extends ElementMapping.Maker {
- public FONode make(FONode parent) {
- return new AFPElement(parent, TAG_LOGICAL_ELEMENT);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-
-import java.io.Serializable;
-
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-
-/**
- * This is the pass-through value object for the PostScript extension.
- */
-public class AFPPageSetup implements ExtensionAttachment, Serializable {
-
- /** The category URI for this extension attachment. */
- public static final String CATEGORY = "apache:fop:extensions:afp";
-
- private String elementName;
-
- private String name;
-
- private String value;
-
- /**
- * Default constructor.
- * @param name the name of the setup code object, may be null
- */
- public AFPPageSetup(String name) {
- this.elementName = name;
- }
-
- /** @return the name */
- public String getElementName() {
- return elementName;
- }
-
- /** @return the name */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the name of the setup code object.
- * @param name The name to set.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @return the value
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Sets the value
- * @param source The value name to set.
- */
- public void setValue(String source) {
- this.value = source;
- }
-
- /** @see org.apache.fop.fo.extensions.ExtensionAttachment#getCategory() */
- public String getCategory() {
- return CATEGORY;
- }
-
- /** @see java.lang.Object#toString() */
- public String toString() {
- return "AFPPageSetup(element-name=" + getElementName() + " name=" + getName() + ")";
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.ValidationException;
-
-/**
- * Extension element for fox:ps-page-setup-code.
- */
-public class AFPPageSetupElement extends AbstractAFPExtensionObject {
-
- /**
- * Main constructor
- * @param parent parent FO node
- */
- public AFPPageSetupElement(FONode parent) {
- super(parent, "page");
- }
-
- /** @see org.apache.fop.fo.FONode#startOfNode() */
- protected void startOfNode() throws FOPException {
- super.startOfNode();
- if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) {
- throw new ValidationException(getName() + " must be a child of fo:simple-page-master.");
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.extensions;
-
-// FOP
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.PropertyList;
-import org.apache.fop.fo.ValidationException;
-import org.apache.fop.fo.extensions.ExtensionAttachment;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-
-/**
- * Base class for the AFP-specific extension elements.
- */
-public abstract class AbstractAFPExtensionObject extends FONode {
-
- private AFPPageSetup setupCode = null;
-
- private String _name = null;
-
- /**
- * @see org.apache.fop.fo.FONode#FONode(FONode)
- * @param parent the parent formatting object
- * @param name the name of the afp element
- */
- public AbstractAFPExtensionObject(FONode parent, String name) {
- super(parent);
- _name = name;
- setupCode = new AFPPageSetup(name);
- }
-
- /**
- * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
- * here, blocks XSL FO's from having non-FO parents.
- */
- protected void validateChildNode(Locator loc, String nsURI, String localName)
- throws ValidationException {
- if (FO_URI.equals(nsURI)) {
- invalidChildError(loc, nsURI, localName);
- }
- }
-
- /** @see org.apache.fop.fo.FONode */
- protected void addCharacters(char[] data, int start, int length,
- PropertyList pList, Locator locator) {
- }
-
- /** @see org.apache.fop.fo.FONode#getNamespaceURI() */
- public String getNamespaceURI() {
- return AFPElementMapping.NAMESPACE;
- }
-
- /**@see org.apache.fop.fo.FONode#getNormalNamespacePrefix() */
- public String getNormalNamespacePrefix() {
- return AFPElementMapping.NAMESPACE_PREFIX;
- }
-
- /** @see org.apache.fop.fo.FONode#processNode */
- public void processNode(String elementName, Locator locator,
- Attributes attlist, PropertyList propertyList)
- throws FOPException {
- String name = attlist.getValue("name");
- if (name != null && name.length() > 0) {
- setupCode.setName(name);
- } else {
- throw new FOPException(elementName + " must have a name attribute.");
- }
- if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(elementName)) {
- name = attlist.getValue("src");
- if (name != null && name.length() > 0) {
- setupCode.setValue(name);
- } else {
- throw new FOPException(elementName + " must have a src attribute.");
- }
- }
- if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(elementName)) {
- name = attlist.getValue("value");
- if (name != null && name.length() > 0) {
- setupCode.setValue(name);
- } else {
- throw new FOPException(elementName + " must have a value attribute.");
- }
- }
- }
-
- /** @see org.apache.fop.fo.FONode#endOfNode() */
- protected void endOfNode() throws FOPException {
- super.endOfNode();
- }
-
- /** @see org.apache.fop.fo.FONode#getExtensionAttachment() */
- public ExtensionAttachment getExtensionAttachment() {
- return this.setupCode;
- }
-
- /** @see org.apache.fop.fo.FONode#getLocalName() */
- public String getLocalName() {
- return _name;
- }
-
-}
-
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-import java.util.Map;
-import org.apache.fop.fonts.FontType;
-import org.apache.fop.fonts.Typeface;
-
-
-/**
- * All implemenations of AFP fonts should extend this base class,
- * the object implements the FontMetrics information.
- * <p/>
- */
-public abstract class AFPFont extends Typeface {
-
- /** The font name */
- protected String _name;
-
- /**
- * Constructor for the base font requires the name.
- * @param name the name of the font
- */
- public AFPFont(String name) {
-
- _name = name;
-
- }
-
- /**
- * @return the name of the font.
- */
- public String getFontName() {
- return _name;
- }
-
- /**
- * Returns the type of the font.
- * @return the font type
- */
- public FontType getFontType() {
- return FontType.OTHER;
- }
-
- /**
- * Indicates if the font has kering information.
- * @return True, if kerning is available.
- */
- public boolean hasKerningInfo() {
- return false;
- }
-
- /**
- * Returns the kerning map for the font.
- * @return the kerning map
- */
- public Map getKerningInfo() {
- return null;
- }
-
- /**
- * Returns the character set for a given size
- * @param size the font size
- * @return the character set object
- */
- public abstract CharacterSet getCharacterSet(int size);
-
- /**
- * Determines whether this font contains a particular character/glyph.
- * @param c character to check
- * @return True if the character is supported, Falso otherwise
- */
- public boolean hasChar(char c) {
- return true;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-import java.util.List;
-
-/**
- * FontInfo contains meta information on fonts
- */
-public class AFPFontInfo {
-
- private AFPFont font;
- private List fontTriplets;
-
- /**
- * Main constructor
- * @param afpFont The AFP Font
- * @param fontTriplets List of font triplets to associate with this font
- */
- public AFPFontInfo(AFPFont afpFont, List fontTriplets) {
- this.font = afpFont;
- this.fontTriplets = fontTriplets;
- }
-
- /**
- * Returns the afp font
- * @return the afp font
- */
- public AFPFont getAFPFont() {
- return font;
- }
-
- /**
- * Returns the list of font triplets associated with this font.
- * @return List of font triplets
- */
- public List getFontTriplets() {
- return fontTriplets;
- }
-
-}
-
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.exceptions.FontRuntimeException;
-import org.apache.fop.render.afp.modca.AFPConstants;
-import org.apache.fop.render.afp.tools.StructuredFieldReader;
-
-/**
- * The AFPFontReader is responsible for reading the font attributes from binary
- * code page files and the character set metric files. In IBM font structure, a
- * code page maps each character of text to the characters in a character set.
- * Each character is translated into a code point. When the character is
- * printed, each code point is matched to a character ID on the code page
- * specified. The character ID is then matched to the image (raster pattern or
- * outline pattern) of the character in the character set specified. The image
- * in the character set is the image that is printed in the document. To be a
- * valid code page for a particular character set, all character IDs in the code
- * page must be included in that character set. <p/>This class will read the
- * font information from the binary code page files and character set metric
- * files in order to determine the correct metrics to use when rendering the
- * formatted object. <p/>
- *
- * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
- */
-public final class AFPFontReader {
-
- /**
- * Static logging instance
- */
- protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
-
- /**
- * Template used to convert lists to arrays.
- */
- private static final CharacterSetOrientation[] EMPTY_CSO_ARRAY = new CharacterSetOrientation[0];
-
- /** Codepage MO:DCA structured field. */
- private static final byte[] CODEPAGE_SF = new byte[] { (byte) 0xD3,
- (byte) 0xA8, (byte) 0x87 };
-
- /** Character table MO:DCA structured field. */
- private static final byte[] CHARACTER_TABLE_SF = new byte[] { (byte) 0xD3,
- (byte) 0x8C, (byte) 0x87 };
-
- /** Font control MO:DCA structured field. */
- private static final byte[] FONT_CONTROL_SF = new byte[] { (byte) 0xD3,
- (byte) 0xA7, (byte) 0x89 };
-
- /** Font orientation MO:DCA structured field. */
- private static final byte[] FONT_ORIENTATION_SF = new byte[] { (byte) 0xD3,
- (byte) 0xAE, (byte) 0x89 };
-
- /** Font position MO:DCA structured field. */
- private static final byte[] FONT_POSITION_SF = new byte[] { (byte) 0xD3,
- (byte) 0xAC, (byte) 0x89 };
-
- /** Font index MO:DCA structured field. */
- private static final byte[] FONT_INDEX_SF = new byte[] { (byte) 0xD3,
- (byte) 0x8C, (byte) 0x89 };
-
- /**
- * The conversion factor to millipoints for 240 dpi
- */
- private static final int FOP_100_DPI_FACTOR = 1;
-
- /**
- * The conversion factor to millipoints for 240 dpi
- */
- private static final int FOP_240_DPI_FACTOR = 300000;
-
- /**
- * The conversion factor to millipoints for 300 dpi
- */
- private static final int FOP_300_DPI_FACTOR = 240000;
-
- /**
- * The encoding to use to convert from EBCIDIC to ASCII
- */
- private static final String ASCII_ENCODING = "UTF8";
-
- /**
- * The collection of code pages
- */
- private static HashMap _codePages = new HashMap();
-
- /**
- * Load the font details and metrics into the CharacterSetMetric object,
- * this will use the actual afp code page and character set files to load
- * the object with the necessary metrics.
- *
- * @param characterSet the CharacterSetMetric object to populate
- */
- public static void loadCharacterSetMetric(CharacterSet characterSet) {
-
- InputStream inputStream = null;
-
- try {
-
- /**
- * Get the code page which contains the character mapping
- * information to map the unicode character id to the graphic
- * chracter global identifier.
- */
- String cp = new String(characterSet.getCodePage());
- String path = characterSet.getPath();
-
- HashMap codepage = (HashMap) _codePages.get(cp);
-
- if (codepage == null) {
- codepage = loadCodePage(cp, characterSet.getEncoding(), path);
- _codePages.put(cp, codepage);
- }
-
- /**
- * Load the character set metric information, no need to cache this
- * information as it should be cached by the objects that wish to
- * load character set metric information.
- */
- final String characterset = characterSet.getName();
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- if (classLoader == null) {
- classLoader = AFPFontReader.class.getClassLoader();
- }
-
- URL url = classLoader.getResource(path);
- if (url == null) {
- try {
- File file = new File(path);
- url = file.toURL();
- if (url == null) {
- String msg = "CharacterSet file not found for "
- + characterset + " in classpath: " + path;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
- } catch (MalformedURLException ex) {
- String msg = "CharacterSet file not found for "
- + characterset + " in classpath: " + path;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
-
- }
-
- File directory = new File(url.getPath());
-
- final String filterpattern = characterset.trim();
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(filterpattern);
- }
- };
-
- File[] csfont = directory.listFiles(filter);
- if (csfont.length < 1) {
- String msg = "CharacterSet file search for " + characterset
- + " located " + csfont.length + " files";
- log.error(msg);
- throw new FileNotFoundException(msg);
- } else if (csfont.length > 1) {
- String msg = "CharacterSet file search for " + characterset
- + " located " + csfont.length + " files";
- log.warn(msg);
- }
-
- inputStream = inputStream = csfont[0].toURL().openStream();
- if (inputStream == null) {
- String msg = "Failed to open character set resource "
- + characterset;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
-
- StructuredFieldReader sfr = new StructuredFieldReader(inputStream);
-
- // Process D3A789 Font Control
- FontControl fnc = processFontControl(sfr);
-
- //process D3AE89 Font Orientation
- CharacterSetOrientation[] csoArray = processFontOrientation(sfr);
-
- //process D3AC89 Font Position
- processFontPosition(sfr, csoArray, fnc.getDpi());
-
- //process D38C89 Font Index (per orientation)
- for (int i = 0; i < csoArray.length; i++) {
- processFontIndex(sfr, csoArray[i], codepage, fnc.getDpi());
- characterSet.addCharacterSetOrientation(csoArray[i]);
- }
-
- } catch (Exception ex) {
- throw new FontRuntimeException(
- "Failed to load the character set metrics for code page "
- + characterSet.getCodePage(), ex);
- } finally {
- try {
- inputStream.close();
- } catch (Exception ex) {
- // Ignore
- }
- }
-
- }
-
- /**
- * Load the code page information from the appropriate file. The file name
- * to load is determined by the code page name and the file extension 'CDP'.
- *
- * @param codePage
- * the code page identifier
- * @param encoding
- * the encoding to use for the character decoding
- */
- private static HashMap loadCodePage(String codePage, String encoding,
- String path) throws IOException, FileNotFoundException {
-
- // Create the HashMap to store code page information
- HashMap codepages = new HashMap();
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- if (classLoader == null) {
- classLoader = AFPFontReader.class.getClassLoader();
- }
-
- URL url = classLoader.getResource(path);
-
- if (url == null) {
- try {
- File file = new File(path);
- url = file.toURL();
- if (url == null) {
- String msg = "CodePage file not found for " + codePage
- + " in classpath: " + path;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
- } catch (MalformedURLException ex) {
- String msg = "CodePage file not found for " + codePage
- + " in classpath: " + path;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
-
- }
-
- File directory = new File(url.getPath());
-
- final String filterpattern = codePage.trim();
- FilenameFilter filter = new FilenameFilter() {
- public boolean accept(File dir, String name) {
- return name.startsWith(filterpattern);
- }
- };
-
- File[] codepage = directory.listFiles(filter);
-
- if (codepage.length < 1) {
- String msg = "CodePage file search for " + codePage + " located "
- + codepage.length + " files";
- log.error(msg);
- throw new FileNotFoundException(msg);
- } else if (codepage.length > 1) {
- String msg = "CodePage file search for " + codePage + " located "
- + codepage.length + " files";
- log.warn(msg);
- }
-
- InputStream is = codepage[0].toURL().openStream();
-
- if (is == null) {
- String msg = "AFPFontReader:: loadCodePage(String):: code page file not found for "
- + codePage;
- log.error(msg);
- throw new FileNotFoundException(msg);
- }
-
- StructuredFieldReader sfr = new StructuredFieldReader(is);
- byte[] data = sfr.getNext(CHARACTER_TABLE_SF);
-
- int position = 0;
- byte[] gcgiBytes = new byte[8];
- byte[] charBytes = new byte[1];
-
- // Read data, ignoring bytes 0 - 2
- for (int index = 3; index < data.length; index++) {
- if (position < 8) {
- // Build the graphic character global identifier key
- gcgiBytes[position] = data[index];
- position++;
- } else if (position == 9) {
- position = 0;
- // Set the character
- charBytes[0] = data[index];
- String gcgiString = new String(gcgiBytes,
- AFPConstants.EBCIDIC_ENCODING);
- String charString = new String(charBytes, encoding);
- int value = charString.charAt(0);
- codepages.put(gcgiString, charString);
- } else {
- position++;
- }
- }
-
- try {
- is.close();
- } catch (Exception ex) {
- // Ignore
- }
-
- return codepages;
-
- }
-
- /**
- * Process the font control details using the structured field reader.
- *
- * @param sfr
- * the structured field reader
- */
- private static FontControl processFontControl(StructuredFieldReader sfr)
- throws IOException {
-
- byte[] fncData = sfr.getNext(FONT_CONTROL_SF);
-
- int position = 0;
-
- FontControl fontControl = new AFPFontReader().new FontControl();
-
- if (fncData[7] == (byte) 0x02) {
- fontControl.setRelative(true);
- }
-
- int dpi = (((fncData[9] & 0xFF) << 8) + (fncData[10] & 0xFF)) / 10;
-
- fontControl.setDpi(dpi);
-
- return fontControl;
-
- }
-
- /**
- * Process the font orientation details from using the structured field
- * reader.
- *
- * @param sfr
- * the structured field reader
- */
- private static CharacterSetOrientation[] processFontOrientation(
- StructuredFieldReader sfr) throws IOException {
-
- byte[] data = sfr.getNext(FONT_ORIENTATION_SF);
-
- int position = 0;
- byte[] fnoData = new byte[26];
-
- ArrayList orientations = new ArrayList();
-
- // Read data, ignoring bytes 0 - 2
- for (int index = 3; index < data.length; index++) {
- // Build the font orientation record
- fnoData[position] = data[index];
- position++;
-
- if (position == 26) {
-
- position = 0;
-
- int orientation = 0;
-
- switch (fnoData[2]) {
- case 0x00:
- orientation = 0;
- break;
- case 0x2D:
- orientation = 90;
- break;
- case 0x5A:
- orientation = 180;
- break;
- case (byte) 0x87:
- orientation = 270;
- break;
- default:
- System.out.println("ERROR: Oriantation");
- }
-
- CharacterSetOrientation cso = new CharacterSetOrientation(
- orientation);
- orientations.add(cso);
-
- }
- }
-
- return (CharacterSetOrientation[]) orientations
- .toArray(EMPTY_CSO_ARRAY);
- }
-
- /**
- * Populate the CharacterSetOrientation object in the suplied array with the
- * font position details using the supplied structured field reader.
- *
- * @param sfr
- * the structured field reader
- * @param csoArray
- * the array of CharacterSetOrientation objects
- */
- private static void processFontPosition(StructuredFieldReader sfr,
- CharacterSetOrientation[] csoArray, int dpi) throws IOException {
-
- byte[] data = sfr.getNext(FONT_POSITION_SF);
-
- int position = 0;
- byte[] fpData = new byte[26];
-
- int csoIndex = 0;
- int fopFactor = 0;
-
- switch (dpi) {
- case 100:
- fopFactor = FOP_100_DPI_FACTOR;
- break;
- case 240:
- fopFactor = FOP_240_DPI_FACTOR;
- break;
- case 300:
- fopFactor = FOP_300_DPI_FACTOR;
- break;
- default:
- String msg = "Unsupported font resolution of " + dpi + " dpi.";
- log.error(msg);
- throw new IOException(msg);
- }
-
- // Read data, ignoring bytes 0 - 2
- for (int index = 3; index < data.length; index++) {
- if (position < 22) {
- // Build the font orientation record
- fpData[position] = data[index];
- } else if (position == 22) {
-
- position = 0;
-
- CharacterSetOrientation cso = csoArray[csoIndex];
-
- int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 0xFF);
- int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 0xFF);
- int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 0xFF);
- int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 0xFF);
-
- dscHeight = dscHeight * -1;
-
- cso.setXHeight(xHeight * fopFactor);
- cso.setCapHeight(capHeight * fopFactor);
- cso.setAscender(ascHeight * fopFactor);
- cso.setDescender(dscHeight * fopFactor);
-
- csoIndex++;
-
- fpData[position] = data[index];
-
- }
-
- position++;
- }
-
- }
-
- /**
- * Process the font index details for the character set orientation.
- *
- * @param sfr
- * the structured field reader
- * @param cso
- * the CharacterSetOrientation object to populate
- * @param codepage
- * the map of code pages
- */
- private static void processFontIndex(StructuredFieldReader sfr,
- CharacterSetOrientation cso, HashMap codepage, int dpi)
- throws IOException {
-
- byte[] data = sfr.getNext(FONT_INDEX_SF);
-
- int fopFactor = 0;
-
- switch (dpi) {
- case 100:
- fopFactor = FOP_100_DPI_FACTOR;
- break;
- case 240:
- fopFactor = FOP_240_DPI_FACTOR;
- break;
- case 300:
- fopFactor = FOP_300_DPI_FACTOR;
- break;
- default:
- String msg = "Unsupported font resolution of " + dpi + " dpi.";
- log.error(msg);
- throw new IOException(msg);
- }
-
- int position = 0;
-
- byte[] gcgid = new byte[8];
- byte[] fiData = new byte[20];
-
- int lowest = 255;
- int highest = 0;
-
- // Read data, ignoring bytes 0 - 2
- for (int index = 3; index < data.length; index++) {
- if (position < 8) {
- gcgid[position] = (byte) data[index];
- position++;
- } else if (position < 27) {
- fiData[position - 8] = (byte) data[index];
- position++;
- } else if (position == 27) {
-
- fiData[position - 8] = (byte) data[index];
-
- position = 0;
-
- String gcgiString = new String(gcgid, AFPConstants.EBCIDIC_ENCODING);
-
- String idx = (String) codepage.get(gcgiString);
-
- if (idx != null) {
-
- int cidx = idx.charAt(0);
- int width = ((fiData[0] & 0xFF) << 8) + (fiData[1] & 0xFF);
-
- if (cidx < lowest) {
- lowest = cidx;
- }
-
- if (cidx > highest) {
- highest = cidx;
- }
-
- int a = (width * fopFactor);
-
- cso.setWidth(cidx, a);
-
- }
-
- }
- }
-
- cso.setFirstChar(lowest);
- cso.setLastChar(highest);
-
- }
-
- private class FontControl {
-
- private int _dpi;
-
- private boolean isRelative = false;
-
- public int getDpi() {
- return _dpi;
- }
-
- public void setDpi(int i) {
- _dpi = i;
- }
-
- public boolean isRelative() {
- return isRelative;
- }
-
- public void setRelative(boolean b) {
- isRelative = b;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.modca.AFPConstants;
-import org.apache.fop.render.afp.tools.StringUtils;
-
-/**
- * The IBM Font Object Content Architecture (FOCA) supports presentation
- * of character shapes by defining their characteristics, which include
- * font description information for identifying the characters, font metric
- * information for positioning the characters, and character shape information
- * for presenting the character images.
- * <p/>
- * Presenting a graphic character on a presentation surface requires
- * information on the rotation and position of character on the physical
- * or logical page.
- * <p/>
- * This class proivdes font metric information for a particular font
- * as identified by the character set name. This information is obtained
- * directly from the AFP font files which must be installed in the path
- * specified in the afp-fonts xml definition file.
- * <p/>
- */
-public class CharacterSet {
-
- /**
- * Static logging instance
- */
- protected static final Log log = LogFactory.getLog(CharacterSet.class.getName());
-
- /**
- * The code page to which the character set relates
- */
- protected String _codePage;
-
- /**
- * The encoding used for the code page
- */
- protected String _encoding;
-
- /**
- * The character set relating to the font
- */
- protected String _name;
-
- /**
- * The name of the character set as EBCIDIC bytes
- */
- private byte[] _nameBytes;
-
- /**
- * The path to the installed fonts
- */
- protected String _path;
-
- /**
- * Indicator as to whether to metrics have been loaded
- */
- private boolean _isMetricsLoaded = false;
-
- /**
- * The current orientation (currently only 0 is suppoted by FOP)
- */
- private String _currentOrientation = "0";
-
- /**
- * The collection of objects for each orientation
- */
- private HashMap _characterSetOrientations;
-
- /**
- * Constructor for the CharacterSetMetric object, the character set is used
- * to load the font information from the actual AFP font.
- * @param codePage the code page identifier
- * @param encoding the encoding of the font
- * @param name the character set name
- * @param path the path to the installed afp fonts
- */
- public CharacterSet(
- String codePage,
- String encoding,
- String name,
- String path) {
-
- if (name.length() > 8) {
- String msg = "Character set name must be a maximum of 8 characters " + name;
- log.error("Constructor:: " + msg);
- throw new IllegalArgumentException(msg);
- }
-
- if (name.length() < 8) {
- _name = StringUtils.rpad(name, ' ', 8);
- } else {
- _name = name;
- }
-
- try {
-
- _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
-
- } catch (UnsupportedEncodingException usee) {
-
- _nameBytes = name.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
-
- }
-
- _codePage = codePage;
- _encoding = encoding;
- _path = path;
- _characterSetOrientations = new HashMap(4);
-
- }
-
- /**
- * Add character set metric information for the different orientations
- * @param cso the metrics for the orientation
- */
- public void addCharacterSetOrientation(CharacterSetOrientation cso) {
-
- _characterSetOrientations.put(
- String.valueOf(cso.getOrientation()),
- cso);
-
- }
-
- /**
- * Ascender height is the distance from the character baseline to the
- * top of the character box. A negative ascender height signifies that
- * all of the graphic character is below the character baseline. For
- * a character rotation other than 0, ascender height loses its
- * meaning when the character is lying on its side or is upside down
- * with respect to normal viewing orientation. For the general case,
- * Ascender Height is the character�s most positive y-axis value.
- * For bounded character boxes, for a given character having an
- * ascender, ascender height and baseline offset are equal.
- * @return the ascender value in millipoints
- */
- public int getAscender() {
- load();
- return getCharacterSetOrientation().getAscender();
- }
-
- /**
- * Cap height is the average height of the uppercase characters in
- * a font. This value is specified by the designer of a font and is
- * usually the height of the uppercase M.
- * @return the cap height value in millipoints
- */
- public int getCapHeight() {
- load();
- return getCharacterSetOrientation().getCapHeight();
- }
-
- /**
- * Descender depth is the distance from the character baseline to
- * the bottom of a character box. A negative descender depth signifies
- * that all of the graphic character is above the character baseline.
- * @return the descender value in millipoints
- */
- public int getDescender() {
- load();
- return getCharacterSetOrientation().getDescender();
- }
-
- /**
- * The first character in the character set
- * @return the first character
- */
- public int getFirstChar() {
- load();
- return getCharacterSetOrientation().getFirstChar();
- }
-
- /**
- * The last character in the character set
- * @return the last character
- */
- public int getLastChar() {
- load();
- return getCharacterSetOrientation().getLastChar();
- }
-
- /**
- * @return the path where the font resources are installed
- */
- public String getPath() {
- return _path;
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of all characters
- * @return the widths of all characters
- */
- public int[] getWidths() {
- load();
- return getCharacterSetOrientation().getWidths();
- }
-
- /**
- * XHeight refers to the height of the lower case letters above the baseline.
- * @return the typical height of characters
- */
- public int getXHeight() {
- load();
- return getCharacterSetOrientation().getXHeight();
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character from which the width will be calculated
- * @return the width of the character
- */
- public int width(int character) {
- load();
- return getCharacterSetOrientation().width(character);
- }
-
- /**
- * Lazy creation of the character metrics, the afp font file will only
- * be processed on a method call requiring the metric information.
- */
- private void load() {
-
- if (!_isMetricsLoaded) {
-
- AFPFontReader.loadCharacterSetMetric(this);
- _isMetricsLoaded = true;
-
- }
-
- }
-
- /**
- * Returns the AFP character set identifier
- * @return String
- */
- public String getName() {
- return _name;
- }
-
- /**
- * Returns the AFP character set identifier
- * @return byte[]
- */
- public byte[] getNameBytes() {
- return _nameBytes;
- }
-
- /**
- * Returns the AFP code page identifier
- * @return String
- */
- public String getCodePage() {
- return _codePage;
- }
-
- /**
- * Returns the AFP code page encoding
- * @return String
- */
- public String getEncoding() {
- return _encoding;
- }
-
- /**
- * Helper method to return the current CharacterSetOrientation, note
- * that FOP does not yet implement the "reference-orientation"
- * attribute therefore we always use the orientation zero degrees,
- * Other orientation information is captured for use by a future
- * implementation (whenever FOP implement the mechanism). This is also
- * the case for landscape prints which use an orientation of 270 degrees,
- * in 99.9% of cases the font metrics will be the same as the 0 degrees
- * therefore the implementation currely will always use 0 degrees.
- * @return characterSetOrentation The current orientation metrics.
- */
- private CharacterSetOrientation getCharacterSetOrientation() {
-
- CharacterSetOrientation c =
- (CharacterSetOrientation) _characterSetOrientations.get(
- _currentOrientation);
- return c;
-
- }
-
- /**
- * Map a Unicode character to a code point in the font.
- * The code tables are already converted to Unicode therefore
- * we can use the identity mapping.
- * @param c character to map
- * @return the mapped character
- */
- public char mapChar(char c) {
- return c;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-
-/**
- * The IBM Font Object Content Architecture (FOCA) supports presentation
- * of character shapes by defining their characteristics, which include
- * Font-Description information for identifying the characters, Font-Metric
- * information for positioning the characters, and Character-Shape
- * information for presenting the character images.
- *
- * Presenting a graphic character on a presentation surface requires
- * that you communicate this information clearly to rotate and position
- * characters correctly on the physical or logical page.
- *
- * This class proivdes font metric information for a particular font
- * as by the orientation.
- *
- * This informtaion is obtained directly from the AFP font files which must
- * be installed in the classpath under in the location specified by the path
- * attribute in the afp-font.xml file.
- * <p/>
- */
-public class CharacterSetOrientation {
-
- /**
- * The code page to which the character set relates
- */
- private String _codePage;
-
- /**
- * The encoding used for the code page
- */
- private String _encoding;
-
- /**
- * The ascender height for the character set
- */
- private int _ascender;
-
- /**
- * The descender depth for the character set
- */
- private int _descender;
-
- /**
- * The height of capital letters
- */
- private int _capHeight;
-
- /**
- * The characters in the charcater set
- */
- private int[] _characters = new int[256];
-
- /**
- * The height of lowercase letters
- */
- private int _xHeight;
-
- /**
- * The first character
- */
- private int _firstCharacter;
-
- /**
- * The last character
- */
- private int _lastCharacter;
-
-
- /**
- * The character set orientation
- */
- private int _orientation = 0;
-
- /**
- * Constructor for the CharacterSetOrientation, the orientation is
- * expressed as the degrees rotation (i.e 0, 90, 180, 270)
- * @param orientation the character set orientation
- */
- public CharacterSetOrientation(int orientation) {
-
- _orientation = orientation;
-
- }
-
- /**
- * Ascender height is the distance from the character baseline to the
- * top of the character box. A negative ascender height signifies that
- * all of the graphic character is below the character baseline. For
- * a character rotation other than 0, ascender height loses its
- * meaning when the character is lying on its side or is upside down
- * with respect to normal viewing orientation. For the general case,
- * Ascender Height is the character�s most positive y-axis value.
- * For bounded character boxes, for a given character having an
- * ascender, ascender height and baseline offset are equal.
- * @return the ascender value in millipoints
- */
- public int getAscender() {
- return _ascender;
- }
-
- /**
- * Cap height is the average height of the uppercase characters in
- * a font. This value is specified by the designer of a font and is
- * usually the height of the uppercase M.
- * @return the cap height value in millipoints
- */
- public int getCapHeight() {
- return _capHeight;
- }
-
- /**
- * Descender depth is the distance from the character baseline to
- * the bottom of a character box. A negative descender depth signifies
- * that all of the graphic character is above the character baseline.
- * @return the descender value in millipoints
- */
- public int getDescender() {
- return _descender;
- }
-
- /**
- * The first character in the character set
- * @return the first character
- */
- public int getFirstChar() {
- return _firstCharacter;
- }
-
- /**
- * The last character in the character set
- * @return the last character
- */
- public int getLastChar() {
- return _lastCharacter;
- }
-
- /**
- * The orientation for these metrics in the character set
- * @return the orientation
- */
- public int getOrientation() {
- return _orientation;
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of all characters
- * in this character set.
- * @return the widths of all characters
- */
- public int[] getWidths() {
-
- int arr[] = new int[(getLastChar() - getFirstChar()) + 1];
- System.arraycopy(_characters, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
- return arr;
-
- }
-
- /**
- * XHeight refers to the height of the lower case letters above
- * the baseline.
- * @return heightX the typical height of characters
- */
- public int getXHeight() {
- return _xHeight;
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character to evaluate
- * @return the widths of the character
- */
- public int width(int character) {
- return _characters[character];
- }
-
- /**
- * Ascender height is the distance from the character baseline to the
- * top of the character box. A negative ascender height signifies that
- * all of the graphic character is below the character baseline. For
- * a character rotation other than 0, ascender height loses its
- * meaning when the character is lying on its side or is upside down
- * with respect to normal viewing orientation. For the general case,
- * Ascender Height is the character�s most positive y-axis value.
- * For bounded character boxes, for a given character having an
- * ascender, ascender height and baseline offset are equal.
- * @param ascender the ascender to set
- */
- public void setAscender(int ascender) {
- _ascender = ascender;
- }
-
- /**
- * Cap height is the average height of the uppercase characters in
- * a font. This value is specified by the designer of a font and is
- * usually the height of the uppercase M.
- * @param capHeight the cap height to set
- */
- public void setCapHeight(int capHeight) {
- _capHeight = capHeight;
- }
-
- /**
- * Descender depth is the distance from the character baseline to
- * the bottom of a character box. A negative descender depth signifies
- * that all of the graphic character is above the character baseline.
- * @param descender the descender value in millipoints
- */
- public void setDescender(int descender) {
- _descender = descender;
- }
-
- /**
- * The first character in the character set
- * @param firstCharacter the first character
- */
- public void setFirstChar(int firstCharacter) {
- _firstCharacter = firstCharacter;
- }
-
- /**
- * The last character in the character set
- * @param lastCharacter the last character
- */
- public void setLastChar(int lastCharacter) {
- _lastCharacter = lastCharacter;
- }
-
- /**
- * Set the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character for which the width is being set
- * @param width the widths of the character
- */
- public void setWidth(int character, int width) {
-
- if (character >= _characters.length) {
- // Increase the size of the array if necessary
- int arr[] = new int[(character - _firstCharacter) + 1];
- System.arraycopy(_characters, 0, arr, 0, _characters.length);
- _characters = arr;
- }
- _characters[character] = width;
-
- }
-
- /**
- * XHeight refers to the height of the lower case letters above
- * the baseline.
- * @param xHeight the typical height of characters
- */
- public void setXHeight(int xHeight) {
- _xHeight = xHeight;
- }
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-import org.apache.fop.fonts.Typeface;
-
-/**
- * A Character set for a normal FOP font<p/>
- */
-public class FopCharacterSet extends CharacterSet {
-
- /** The character set for this font */
- private Typeface _characterSet = null;
- private int _size = 0;
-
- /**
- * Constructor for the CharacterSetMetric object, the character set is used
- * to load the font information from the actual AFP font.
- * @param codePage the code page identifier
- * @param encoding the encoding of the font
- * @param name the character set name
- * @param size the font size
- * @param characterSet the fop character set
- */
- public FopCharacterSet(
- String codePage,
- String encoding,
- String name,
- int size,
- Typeface characterSet) {
- super(codePage, encoding, name, null);
- _characterSet = characterSet;
- _size = size * 1000;
- }
-
- /**
- * Ascender height is the distance from the character baseline to the
- * top of the character box. A negative ascender height signifies that
- * all of the graphic character is below the character baseline. For
- * a character rotation other than 0, ascender height loses its
- * meaning when the character is lying on its side or is upside down
- * with respect to normal viewing orientation. For the general case,
- * Ascender Height is the character�s most positive y-axis value.
- * For bounded character boxes, for a given character having an
- * ascender, ascender height and baseline offset are equal.
- * @return the ascender value in millipoints
- */
- public int getAscender() {
- return _characterSet.getAscender(_size);
- }
-
- /**
- * Cap height is the average height of the uppercase characters in
- * a font. This value is specified by the designer of a font and is
- * usually the height of the uppercase M.
- * @return the cap height value in millipoints
- */
- public int getCapHeight() {
- return _characterSet.getCapHeight(_size);
- }
-
- /**
- * Descender depth is the distance from the character baseline to
- * the bottom of a character box. A negative descender depth signifies
- * that all of the graphic character is above the character baseline.
- * @return the descender value in millipoints
- */
- public int getDescender() {
- return _characterSet.getDescender(_size);
- }
-
- /**
- * The first character in the character set
- * @return the first character
- */
- public int getFirstChar() {
- return 0;
- }
-
- /**
- * The last character in the character set
- * @return the last character
- */
- public int getLastChar() {
- return 0;
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of all characters
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return _characterSet.getWidths();
- }
-
- /**
- * XHeight refers to the height of the lower case letters above the baseline.
- * @return the typical height of characters
- */
- public int getXHeight() {
- return _characterSet.getXHeight(_size);
- }
-
- /**
- * Get the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character from which the width will be calculated
- * @return the width of the character
- */
- public int width(int character) {
- return _characterSet.getWidth(character, _size);
- }
-
- /**
- * Map a Unicode character to a code point in the font.
- * @param c character to map
- * @return the mapped character
- */
- public char mapChar(char c) {
- return _characterSet.mapChar(c);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-/**
- * A font defined as a set of lines and curves as opposed to a bitmap font. An
- * outline font can be scaled to any size and otherwise transformed more easily
- * than a bitmap font, and with more attractive results. <p/>
- *
- */
-public class OutlineFont extends AFPFont {
-
- /** The character set for this font */
- private CharacterSet _characterSet = null;
-
- /**
- * Constructor for an outline font.
- *
- * @param name
- * the name of the font
- * @param characterSet
- * the chracter set
- */
- public OutlineFont(String name, CharacterSet characterSet) {
- super(name);
- _characterSet = characterSet;
- }
-
- /**
- * Get the character set metrics.
- *
- * @return the character set
- */
- public CharacterSet getCharacterSet() {
-
- return _characterSet;
-
- }
-
- /**
- * Get the character set metrics.
- * @param size ignored
- * @return the character set
- */
- public CharacterSet getCharacterSet(int size) {
-
- return _characterSet;
-
- }
-
- /**
- * Get the first character in this font.
- */
- public int getFirstChar() {
-
- return _characterSet.getFirstChar();
-
- }
-
- /**
- * Get the last character in this font.
- */
- public int getLastChar() {
-
- return _characterSet.getLastChar();
-
- }
-
- /**
- * The ascender is the part of a lowercase letter that extends above the
- * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
- * used to denote the part of the letter extending above the x-height.
- *
- * @param size
- * the point size
- */
- public int getAscender(int size) {
-
- return _characterSet.getAscender() / 1000 * size;
-
- }
-
- /**
- * Obtains the height of capital letters for the specified point size.
- *
- * @param size
- * the point size
- */
- public int getCapHeight(int size) {
-
- return _characterSet.getCapHeight() / 1000 * size;
-
- }
-
- /**
- * The descender is the part of a lowercase letter that extends below the
- * base line, such as "g", "j", or "p". Also used to denote the part of the
- * letter extending below the base line.
- *
- * @param size
- * the point size
- */
- public int getDescender(int size) {
-
- return _characterSet.getDescender() / 1000 * size;
-
- }
-
- /**
- * The "x-height" (the height of the letter "x").
- *
- * @param size
- * the point size
- */
- public int getXHeight(int size) {
-
- return _characterSet.getXHeight() / 1000 * size;
-
- }
-
- /**
- * Obtain the width of the character for the specified point size.
- */
- public int getWidth(int character, int size) {
-
- return _characterSet.width(character) / 1000 * size;
-
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size
- * the point size
- * @return the widths of all characters
- */
- public int[] getWidths(int size) {
-
- int[] widths = _characterSet.getWidths();
- for (int i = 0; i < widths.length; i++) {
- widths[i] = widths[i] / 1000 * size;
- }
- return widths;
-
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
-
- return getWidths(1000);
-
- }
-
- /**
- * Map a Unicode character to a code point in the font.
- * @param c character to map
- * @return the mapped character
- */
- public char mapChar(char c) {
- return _characterSet.mapChar(c);
- }
-
- /**
- * Get the encoding of the font.
- * @return the encoding
- */
- public String getEncoding() {
- return _characterSet.getEncoding();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.fonts;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.exceptions.FontRuntimeException;
-
-/**
- * A font where each character is stored as an array of pixels (a bitmap). Such
- * fonts are not easily scalable, in contrast to vectored fonts. With this type
- * of font, the font metrics information is held in character set files (one for
- * each size and style). <p/>
- *
- */
-public class RasterFont extends AFPFont {
-
- /** Static logging instance */
- protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.fonts");
-
- private HashMap _characterSets = new HashMap();
-
- private CharacterSet _characterSet = null;
-
- /**
- * Constructor for the raster font requires the name, weight and style
- * attribute to be available as this forms the key to the font.
- *
- * @param name
- * the name of the font
- */
- public RasterFont(String name) {
- super(name);
- }
-
- public void addCharacterSet(int size, CharacterSet characterSet) {
-
- _characterSets.put(String.valueOf(size), characterSet);
-
- _characterSet = characterSet;
-
- }
-
- /**
- * Get the character set metrics for the specified point size.
- *
- * @param size the point size
- * @return the character set metrics
- */
- public CharacterSet getCharacterSet(int size) {
-
- String pointsize = String.valueOf(size / 1000);
- CharacterSet csm = (CharacterSet) _characterSets.get(pointsize);
- if (csm == null) {
- csm = (CharacterSet) _characterSets.get(size + "mpt");
- }
- if (csm == null) {
- // Get char set with nearest font size
- int distance = Integer.MAX_VALUE;
- for (Iterator it = _characterSets.entrySet().iterator(); it.hasNext(); ) {
- Map.Entry me = (Map.Entry)it.next();
- String key = (String)me.getKey();
- if (!key.endsWith("mpt")) {
- int mpt = Integer.parseInt(key) * 1000;
- if (Math.abs(size - mpt) < distance) {
- distance = Math.abs(size - mpt);
- pointsize = (String)me.getKey();
- csm = (CharacterSet)me.getValue();
- }
- }
- }
- if (csm != null) {
- _characterSets.put(size + "mpt", csm);
- String msg = "No " + (size / 1000) + "pt font " + _name
- + " found, substituted with " + pointsize + "pt font";
- log.warn(msg);
- }
- }
- if (csm == null) {
- String msg = "No font found for font " + _name
- + " with point size " + pointsize;
- log.error(msg);
- throw new FontRuntimeException(msg);
- }
- return csm;
-
- }
-
- /**
- * Get the first character in this font.
- */
- public int getFirstChar() {
-
- Iterator i = _characterSets.values().iterator();
- if (i.hasNext()) {
- CharacterSet csm = (CharacterSet) i.next();
- return csm.getFirstChar();
- } else {
- String msg = "getFirstChar() - No character set found for font:" + _name;
- log.error(msg);
- throw new FontRuntimeException(msg);
- }
-
- }
-
- /**
- * Get the last character in this font.
- */
- public int getLastChar() {
-
- Iterator i = _characterSets.values().iterator();
- if (i.hasNext()) {
- CharacterSet csm = (CharacterSet) i.next();
- return csm.getLastChar();
- } else {
- String msg = "getLastChar() - No character set found for font:" + _name;
- log.error(msg);
- throw new FontRuntimeException(msg);
- }
-
- }
-
- /**
- * The ascender is the part of a lowercase letter that extends above the
- * "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
- * used to denote the part of the letter extending above the x-height.
- *
- * @param size the point size
- */
- public int getAscender(int size) {
-
- return getCharacterSet(size).getAscender();
-
- }
-
- /**
- * Obtains the height of capital letters for the specified point size.
- *
- * @param size the point size
- */
- public int getCapHeight(int size) {
-
- return getCharacterSet(size).getCapHeight();
-
- }
-
- /**
- * The descender is the part of a lowercase letter that extends below the
- * base line, such as "g", "j", or "p". Also used to denote the part of the
- * letter extending below the base line.
- *
- * @param size the point size
- */
- public int getDescender(int size) {
-
- return getCharacterSet(size).getDescender();
-
- }
-
- /**
- * The "x-height" (the height of the letter "x").
- *
- * @param size the point size
- */
- public int getXHeight(int size) {
-
- return getCharacterSet(size).getXHeight();
-
- }
-
- /**
- * Obtain the width of the character for the specified point size.
- */
- public int getWidth(int character, int size) {
-
- return getCharacterSet(size).width(character);
-
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size
- * the point size
- * @return the widths of all characters
- */
- public int[] getWidths(int size) {
-
- return getCharacterSet(size).getWidths();
-
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
-
- return getWidths(1000);
-
- }
-
- /**
- * Map a Unicode character to a code point in the font.
- * @param c character to map
- * @return the mapped character
- */
- public char mapChar(char c) {
- return _characterSet.mapChar(c);
- }
-
- /**
- * Get the encoding of the font.
- * @return the encoding
- */
- public String getEncoding() {
- return _characterSet.getEncoding();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-/**
- * Constants used by the AFP renderer.
- *
- */
-public interface AFPConstants {
-
- /**
- * The encoding to use to convert to EBCIDIC
- */
- public String EBCIDIC_ENCODING = "Cp1146";
-
- /**
- * The encoding to use to convert to ASCII
- */
- public String ASCII_ENCODING = "Cp1252";
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.awt.Color;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.fop.render.afp.fonts.AFPFont;
-import org.apache.fop.render.afp.tools.StringUtils;
-
-/**
- * A data stream is a continuous ordered stream of data elements and objects
- * conforming to a given format. Application programs can generate data streams
- * destined for a presentation service, archive library, presentation device or
- * another application program. The strategic presentation data stream
- * architectures used is Mixed Object Document Content Architecture (MO:DCA�).
- *
- * The MO:DCA architecture defines the data stream used by applications to
- * describe documents and object envelopes for interchange with other
- * applications and application services. Documents defined in the MO:DCA format
- * may be archived in a database, then later retrieved, viewed, annotated and
- * printed in local or distributed systems environments. Presentation fidelity
- * is accommodated by including resource objects in the documents that reference
- * them.
- *
- */
-public class AFPDataStream {
-
- /**
- * Static logging instance
- */
- protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
-
- /**
- * Boolean completion indicator
- */
- private boolean _complete = false;
-
- /**
- * The application producing the AFP document
- */
- private String _producer = null;
-
- /**
- * The AFP document object
- */
- private Document _document = null;
-
- /**
- * The current page group object
- */
- private PageGroup _currentPageGroup = null;
-
- /**
- * The current page object
- */
- private PageObject _currentPageObject = null;
-
- /**
- * The current overlay object
- */
- private Overlay _currentOverlay = null;
-
- /**
- * The current page
- */
- private AbstractPageObject _currentPage = null;
-
- /**
- * The page count
- */
- private int _pageCount = 0;
-
- /**
- * The page group count
- */
- private int _pageGroupCount = 0;
-
- /**
- * The overlay count
- */
- private int _ovlCount = 0;
-
- /**
- * The portrait rotation
- */
- private int _portraitRotation = 0;
-
- /**
- * The landscape rotation
- */
- private int _landscapeRotation = 270;
-
- /**
- * The x offset
- */
- private int _xOffset = 0;
-
- /**
- * The y offset
- */
- private int _yOffset = 0;
-
- /**
- * The rotation
- */
- private int _rotation;
-
- /**
- * The outputstream for the data stream
- */
- private OutputStream _outputStream = null;
-
- /**
- * Default constructor for the AFPDataStream.
- */
- public AFPDataStream() {
- }
-
- /**
- * The document is started by invoking this method which creates an instance
- * of the AFP Document object.
- */
- public void startDocument(OutputStream outputStream) {
-
- if (_document != null) {
- String msg = "Invalid state - document already started.";
- log.warn("startDocument():: " + msg);
- throw new IllegalStateException(msg);
- }
-
- _document = new Document();
- _outputStream = outputStream;
-
- }
-
- /**
- * The document is ended by invoking this method which creates an instance
- * of the AFP Document object and registers the start with a validation map
- * which ensures that methods are not invoked out of the correct sequence.
- */
- public void endDocument()
- throws IOException {
-
- if (_complete) {
- String msg = "Invalid state - document already ended.";
- log.warn("endDocument():: " + msg);
- throw new IllegalStateException(msg);
- }
-
- if (_currentPageObject != null) {
- // End the current page if necessary
- endPage();
- }
-
- if (_currentPageGroup != null) {
- // End the current page group if necessary
- endPageGroup();
- }
-
- _document.endDocument();
- _document.writeDataStream(_outputStream);
- _outputStream.flush();
-
- _complete = true;
-
- _document = null;
-
- _outputStream = null;
- }
-
- /**
- * Start a new page. When processing has finished on the current page, the
- * {@link #endPage()}method must be invoked to mark the page ending.
- *
- * @param pageWidth
- * the width of the page
- * @param pageHeight
- * the height of the page
- * @param pageRotation
- * the rotation of the page
- */
- public void startPage(int pageWidth, int pageHeight, int pageRotation) {
-
- String pageName = "PGN"
- + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
-
- _currentPageObject = new PageObject(pageName, pageWidth, pageHeight, pageRotation);
- _currentPage = _currentPageObject;
- _currentOverlay = null;
- setOffsets(0, 0, 0);
- }
-
- /**
- * Start a new overlay. When processing has finished on the current overlay, the
- * {@link #endOverlay()}method must be invoked to mark the overlay ending.
- *
- * @param overlayX
- * the x position of the overlay on the page
- * @param overlayY
- * the y position of the overlay on the page
- * @param overlayWidth
- * the width of the overlay
- * @param overlayHeight
- * the height of the overlay
- * @param overlayRotation
- * the rotation of the overlay
- */
- public void startOverlay(int overlayX, int overlayY, int overlayWidth, int overlayHeight, int overlayRotation) {
-
- String overlayName = "OVL"
- + StringUtils.lpad(String.valueOf(_ovlCount++), '0', 5);
-
- _currentOverlay = new Overlay(overlayName, overlayWidth, overlayHeight, overlayRotation);
- _currentPageObject.addOverlay(_currentOverlay);
- _currentPageObject.createIncludePageOverlay(overlayName, overlayX, overlayY, 0);
- _currentPage = _currentOverlay;
- setOffsets(0, 0, 0);
- }
-
- /**
- * Helper method to mark the end of the current overlay.
- */
- public void endOverlay() {
-
- _currentOverlay.endPage();
- _currentOverlay = null;
- _currentPage = _currentPageObject;
-
- }
-
- /**
- * Helper method to save the current page.
- */
- public PageObject savePage() {
-
- PageObject pageObject = _currentPageObject;
- if (_currentPageGroup != null) {
- _currentPageGroup.addPage(_currentPageObject);
- } else {
- _document.addPage(_currentPageObject);
- }
- _currentPageObject = null;
- _currentPage = null;
- return pageObject;
-
- }
-
- /**
- * Helper method to restore the current page.
- */
- public void restorePage(PageObject pageObject) {
-
- _currentPageObject = pageObject;
- _currentPage = pageObject;
-
- }
-
- /**
- * Helper method to mark the end of the current page.
- */
- public void endPage()
- throws IOException {
-
- _currentPageObject.endPage();
- if (_currentPageGroup != null) {
- _currentPageGroup.addPage(_currentPageObject);
- } else {
- _document.addPage(_currentPageObject);
- _document.writeDataStream(_outputStream);
- }
-
- _currentPageObject = null;
- _currentPage = null;
-
- }
-
- /**
- * Sets the offsets to be used for element positioning
- *
- * @param xOffset
- * the offset in the x direction
- * @param yOffset
- * the offset in the y direction
- * @param rotation
- * the rotation
- */
- public void setOffsets(int xOffset, int yOffset, int rotation) {
- _xOffset = xOffset;
- _yOffset = yOffset;
- _rotation = rotation;
- }
-
- /**
- * Helper method to create a map coded font object on the current page, this
- * method delegates the construction of the map coded font object to the
- * active environment group on the current page.
- *
- * @param fontReference
- * the font number used as the resource identifier
- * @param font
- * the font
- * @param size
- * the point size of the font
- */
- public void createFont(byte fontReference, AFPFont font, int size) {
-
- _currentPage.createFont(fontReference, font, size);
-
- }
-
- /**
- * Helper method to create text on the current page, this method delegates
- * to the current presentation text object in order to construct the text.
- *
- * @param fontNumber
- * the font number used as the resource identifier
- * @param x
- * the x coordinate of the text
- * @param y
- * the y coordinate of the text
- * @param col
- * the text color
- * @param vsci
- * The variable space character increment.
- * @param ica
- * The inter character adjustment.
- * @param data
- * the text data to create
- */
- public void createText(int fontNumber, int x, int y, Color col, int vsci, int ica, byte[] data) {
-
- _currentPage.createText(fontNumber, x + _xOffset, y + _yOffset, _rotation, col, vsci, ica, data);
-
- }
-
- /**
- * Returns an ImageObject used to create an image in the datastream.
- *
- * @param x
- * the x position of the image
- * @param y
- * the y position of the image
- * @param w
- * the width of the image
- * @param h
- * the height of the image
- */
- public ImageObject getImageObject(int x, int y, int w, int h) {
-
- int xOrigin;
- int yOrigin;
- int width;
- int height;
- switch (_rotation) {
- case 90:
- xOrigin = _currentPage.getWidth() - y - _yOffset;
- yOrigin = x + _xOffset;
- width = h;
- height = w;
- break;
- case 180:
- xOrigin = _currentPage.getWidth() - x - _xOffset;
- yOrigin = _currentPage.getHeight() - y - _yOffset;
- width = w;
- height = h;
- break;
- case 270:
- xOrigin = y + _yOffset;
- yOrigin = _currentPage.getHeight() - x - _xOffset;
- width = h;
- height = w;
- break;
- default:
- xOrigin = x + _xOffset;
- yOrigin = y + _yOffset;
- width = w;
- height = h;
- break;
- }
- ImageObject io = _currentPage.getImageObject();
- io.setImageViewport(xOrigin, yOrigin, width, height, _rotation);
- return io;
-
- }
-
- /**
- * Method to create a line on the current page.
- *
- * @param x1
- * the first x coordinate of the line
- * @param y1
- * the first y coordinate of the line
- * @param x2
- * the second x coordinate of the line
- * @param y2
- * the second y coordinate of the line
- * @param thickness
- * the thickness of the line
- * @param col
- * The text color.
- */
- public void createLine(int x1, int y1, int x2, int y2, int thickness, Color col) {
-
- _currentPage.createLine(x1 + _xOffset, y1 + _yOffset, x2 + _xOffset, y2 + _yOffset, thickness, _rotation, col);
-
- }
-
- /**
- * Sets the application producing the AFP.
- *
- * @param producer
- * the application producing the AFP datastream
- */
- public void setProducer(String producer) {
- _producer = producer;
- }
-
- /**
- * This method will create shading on the page using the specified
- * coordinates (the shading contrast is controlled via the red, green, blue
- * parameters, by converting this to grey scale).
- *
- * @param x
- * the x coordinate of the shading
- * @param y
- * the y coordinate of the shading
- * @param w
- * the width of the shaded area
- * @param h
- * the height of the shaded area
- * @param red
- * the red value
- * @param green
- * the green value
- * @param blue
- * the blue value
- */
- public void createShading(int x, int y, int w, int h, int red, int green,
- int blue) {
-
- _currentPage.createShading(x + _xOffset, y + _xOffset, w, h, red, green, blue);
-
- }
-
- /**
- * Helper method which allows creation of the MPO object, via the AEG. And
- * the IPO via the Page. (See actual object for descriptions.)
- *
- * @param name
- * the name of the static overlay
- */
- public void createIncludePageOverlay(String name) {
-
- _currentPageObject.createIncludePageOverlay(name, 0, 0, _rotation);
- ActiveEnvironmentGroup aeg = _currentPageObject.getActiveEnvironmentGroup();
- aeg.createOverlay(name);
-
- }
-
- /**
- * Helper method which allows creation of the IMM object.
- *
- * @param name
- * the name of the medium map
- */
- public void createInvokeMediumMap(String name) {
-
- if (_currentPageGroup == null) {
- startPageGroup();
- }
- _currentPageGroup.createInvokeMediumMap(name);
-
- }
-
- /**
- * Creates an IncludePageSegment on the current page.
- *
- * @param name
- * the name of the include page segment
- * @param x
- * the x coordinate for the overlay
- * @param y
- * the y coordinate for the overlay
- */
- public void createIncludePageSegment(String name, int x, int y) {
-
- int xOrigin;
- int yOrigin;
- switch (_rotation) {
- case 90:
- xOrigin = _currentPage.getWidth() - y - _yOffset;
- yOrigin = x + _xOffset;
- break;
- case 180:
- xOrigin = _currentPage.getWidth() - x - _xOffset;
- yOrigin = _currentPage.getHeight() - y - _yOffset;
- break;
- case 270:
- xOrigin = y + _yOffset;
- yOrigin = _currentPage.getHeight() - x - _xOffset;
- break;
- default:
- xOrigin = x + _xOffset;
- yOrigin = y + _yOffset;
- break;
- }
- _currentPage.createIncludePageSegment(name, xOrigin, yOrigin);
-
- }
-
- /**
- * Creates a TagLogicalElement on the current page.
- *
- * @param attributes
- * the array of key value pairs.
- */
- public void createPageTagLogicalElement(TagLogicalElementBean[] attributes) {
-
- for (int i = 0; i < attributes.length; i++) {
- String name = (String) attributes[i].getKey();
- String value = (String) attributes[i].getValue();
- _currentPage.createTagLogicalElement(name, value);
- }
-
- }
-
- /**
- * Creates a TagLogicalElement on the current page group.
- *
- * @param attributes
- * the array of key value pairs.
- */
- public void createPageGroupTagLogicalElement(
- TagLogicalElementBean[] attributes) {
-
- for (int i = 0; i < attributes.length; i++) {
- String name = (String) attributes[i].getKey();
- String value = (String) attributes[i].getValue();
- _currentPageGroup.createTagLogicalElement(name, value);
- }
-
- }
-
- /**
- * Creates a TagLogicalElement on the current page or page group
- *
- * @param name
- * The tag name
- * @param value
- * The tag value
- */
- public void createTagLogicalElement(String name, String value) {
-
- if (_currentPageGroup != null) {
- _currentPageGroup.createTagLogicalElement(name, value);
- } else {
- _currentPage.createTagLogicalElement(name, value);
- }
-
- }
-
- /**
- * Start a new page group. When processing has finished on the current page
- * group the {@link #endPageGroup()}method must be invoked to mark the page
- * group ending.
- *
- * @param name
- * the name of the page group
- */
- public void startPageGroup() {
-
- String pageGroupName = "PGP"
- + StringUtils.lpad(String.valueOf(_pageCount++), '0', 5);
-
- _currentPageGroup = new PageGroup(pageGroupName);
-
- }
-
- /**
- * Helper method to mark the end of the page group.
- */
- public void endPageGroup()
- throws IOException {
-
- _currentPageGroup.endPageGroup();
- _document.addPageGroup(_currentPageGroup);
- _document.writeDataStream(_outputStream);
- _currentPageGroup = null;
-
- }
-
- /**
- * Sets the rotation to be used for portrait pages, valid values are 0
- * (default), 90, 180, 270.
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setPortraitRotation(int rotation) {
-
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
- _portraitRotation = rotation;
- } else {
- throw new IllegalArgumentException(
- "The portrait rotation must be one of the values 0, 90, 180, 270");
- }
-
- }
-
- /**
- * Sets the rotation to be used for landscape pages, valid values are 0, 90,
- * 180, 270 (default).
- *
- * @param rotation
- * The rotation in degrees.
- */
- public void setLandscapeRotation(int rotation) {
-
- if (rotation == 0 || rotation == 90 || rotation == 180
- || rotation == 270) {
- _landscapeRotation = rotation;
- } else {
- throw new IllegalArgumentException(
- "The landscape rotation must be one of the values 0, 90, 180, 270");
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * This is the base class for all data stream objects. Page objects are
- * responsible for building and generating the binary datastream in an
- * AFP format.
- *
- */
-public abstract class AbstractAFPObject {
-
- /**
- * Static logging instance
- */
- protected static final Log log = LogFactory.getLog("org.apache.fop.render.afp.modca");
-
- /**
- * DataStream objects must implement the writeDataStream()
- * method to write its data to the given OutputStream
- * @param os The outputsteam stream
- * @throws java.io.IOException
- */
- public abstract void writeDataStream(OutputStream os) throws IOException;
-
- /**
- * Help method to write a set of AFPObjects to the AFP datastream.
- * @afpObjects a list of AFPObjects
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- protected void writeObjectList(List afpObjects, OutputStream os)
- throws IOException {
-
- for (Iterator it = afpObjects.iterator(); it.hasNext(); ) {
- ((AbstractAFPObject)it.next()).writeDataStream(os);
- }
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.UnsupportedEncodingException;
-
-/**
- * This is the base class for all named data stream objects.
- * A named data stream object has an 8 byte EBCIDIC name.
- *
- */
-public abstract class AbstractNamedAFPObject extends AbstractAFPObject{
-
- /**
- * The actual name of the object
- */
- protected String _name = null;
-
- /**
- * The name of the object in EBCIDIC bytes
- */
- protected byte[] _nameBytes;
-
- /**
- * Constructor for the ActiveEnvironmentGroup, this takes a
- * name parameter which should be 8 characters long.
- * @param name the object name
- */
- public AbstractNamedAFPObject(String name) {
-
- if (name.length() < 8) {
- name = (name + " ").substring(0, 8);
- } else if (name.length() > 8) {
- log.warn("Constructor:: name truncated to 8 chars"+ name);
- name = name.substring(0, 8);
- }
-
- try {
-
- _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
-
- } catch (UnsupportedEncodingException usee) {
-
- _nameBytes = name.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
-
- }
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.awt.Color;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.fop.render.afp.fonts.AFPFont;
-import org.apache.fop.render.afp.tools.StringUtils;
-
-/**
- * Pages contain the data objects that comprise a presentation document. Each
- * page has a set of data objects associated with it. Each page within a
- * document is independent from any other page, and each must establish its own
- * environment parameters.
- *
- * The page is the level in the document component hierarchy that is used for
- * printing or displaying a document's content. The data objects contained in
- * the page envelope in the data stream are presented when the page is
- * presented. Each data object has layout information associated with it that
- * directs the placement and orientation of the data on the page. In addition,
- * each page contains layout information that specifies the measurement units,
- * page width, and page depth.
- *
- * A page is initiated by a begin page structured field and terminated by an end
- * page structured field. Structured fields that define objects and active
- * environment groups or that specify attributes of the page may be encountered
- * in page state.
- *
- */
-public abstract class AbstractPageObject extends AbstractNamedAFPObject {
-
- /**
- * The active environment group for the page
- */
- protected ActiveEnvironmentGroup _activeEnvironmentGroup = null;
-
- /**
- * The presentation text object, we only have one per page
- */
- private PresentationTextObject _presentationTextObject = null;
-
- /**
- * The list of objects within the page
- */
- protected List _objects = new ArrayList();
-
- /**
- * The list of tag logical elements
- */
- protected ArrayList _tagLogicalElements = new ArrayList();
-
- /**
- * The list of the include page segments
- */
- protected ArrayList _segments = new ArrayList();
-
- /**
- * The page width
- */
- private int _width;
-
- /**
- * The page height
- */
- private int _height;
-
- /**
- * The page rotation
- */
- private int _rotation = 0;
-
- /**
- * The page state
- */
- private boolean _complete = false;
-
- /**
- * Construct a new page object for the specified name argument, the page
- * name should be an 8 character identifier.
- *
- * @param name
- * the name of the page.
- * @param width
- * the width of the page.
- * @param height
- * the height of the page.
- * @param rotation
- * the rotation of the page.
- */
- public AbstractPageObject(String name, int width, int height, int rotation) {
-
- super(name);
-
- _name = name;
-
- _rotation = rotation;
- _width = width;
- _height = height;
-
- /**
- * Every page object must have an ActiveEnvironmentGroup
- */
- _activeEnvironmentGroup = new ActiveEnvironmentGroup(_width, _height);
-
- if (_rotation != 0) {
- switch (_rotation) {
- case 90:
- _activeEnvironmentGroup.setPosition(_width, 0, _rotation);
- break;
- case 180:
- _activeEnvironmentGroup.setPosition(_width, _height, _rotation);
- break;
- case 270:
- _activeEnvironmentGroup.setPosition(0, _height, _rotation);
- break;
- }
- }
-
- /**
- * We have a presentation text object per page
- */
- _presentationTextObject = new PresentationTextObject();
- _objects.add(_presentationTextObject);
-
- }
-
- /**
- * Helper method to create a map coded font object on the current page, this
- * method delegates the construction of the map coded font object to the
- * active environment group on the page.
- *
- * @param fontReference
- * the font number used as the resource identifier
- * @param font
- * the font
- * @param size
- * the point size of the font
- */
- public void createFont(byte fontReference, AFPFont font, int size) {
-
- _activeEnvironmentGroup.createFont(fontReference, font, size, 0);
-
- }
-
- /**
- * Helper method to create a line on the current page, this method delegates
- * to the presentation text object in order to construct the line.
- *
- * @param x1
- * the first x coordinate of the line
- * @param y1
- * the first y coordinate of the line
- * @param x2
- * the second x coordinate of the line
- * @param y2
- * the second y coordinate of the line
- * @param thickness
- * the thickness of the line
- * @param rotation
- * the rotation of the line
- * @param col
- * The text color.
- */
- public void createLine(int x1, int y1, int x2, int y2, int thickness, int rotation, Color col) {
-
- if (_presentationTextObject == null) {
- _presentationTextObject = new PresentationTextObject();
- _objects.add(_presentationTextObject);
- }
- _presentationTextObject.createLineData(x1, y1, x2, y2, thickness, rotation, col);
-
- }
-
- /**
- * Helper method to create text on the current page, this method delegates
- * to the presentation text object in order to construct the text.
- *
- * @param fontNumber
- * the font number used as the resource identifier
- * @param x
- * the x coordinate of the text data
- * @param y
- * the y coordinate of the text data
- * @param rotation
- * the rotation of the text data
- * @param col
- * the text color
- * @param vsci
- * The variable space character increment.
- * @param ica
- * The inter character adjustment.
- * @param data
- * the text data to create
- */
- public void createText(int fontNumber, int x, int y, int rotation, Color col, int vsci, int ica, byte[] data) {
-
- if (_presentationTextObject == null) {
- _presentationTextObject = new PresentationTextObject();
- _objects.add(_presentationTextObject);
- }
- _presentationTextObject.createTextData(fontNumber, x, y, rotation, col, vsci, ica, data);
-
- }
-
- /**
- * Helper method to mark the end of the page. This should end the control
- * sequence on the current presenation text object.
- */
- public void endPage() {
-
- if (_presentationTextObject != null) {
- _presentationTextObject.endControlSequence();
- }
-
- _complete = true;
-
- }
-
- /**
- * This method will create shading on the page using the specified
- * coordinates (the shading contrast is controlled via the red, green blue
- * parameters, by converting this to grey scale).
- *
- * @param x
- * the x coordinate of the shading
- * @param y
- * the y coordinate of the shading
- * @param w
- * the width of the shaded area
- * @param h
- * the height of the shaded area
- * @param red
- * the red value
- * @param green
- * the green value
- * @param blue
- * the blue value
- */
- public void createShading(int x, int y, int w, int h, int red, int green,
- int blue) {
-
- int xCoord = 0;
- int yCoord = 0;
- int width = 0;
- int height = 0;
-
- switch (_rotation) {
- case 90:
- xCoord = _width - y - h;
- yCoord = x;
- width = h;
- height = w;
- break;
- case 180:
- xCoord = _width - x - w;
- yCoord = _height - y - h;
- width = w;
- height = h;
- break;
- case 270:
- xCoord = y;
- yCoord = _height - x - w;
- width = h;
- height = w;
- break;
- default:
- xCoord = x;
- yCoord = y;
- width = w;
- height = h;
- break;
- }
-
- // Convert the color to grey scale
- float shade = (float) ((red * 0.3) + (green * 0.59) + (blue * 0.11));
-
- int greyscale = Math.round((shade / 255) * 16);
-
- String imageName = "IMG"
- + StringUtils.lpad(String.valueOf(_objects.size() + 1),
- '0', 5);
-
- IMImageObject io = new IMImageObject(imageName);
- ImageOutputControl ioc = new ImageOutputControl(0, 0);
- ImageInputDescriptor iid = new ImageInputDescriptor();
- ImageCellPosition icp = new ImageCellPosition(xCoord, yCoord);
- icp.setXFillSize(width);
- icp.setYFillSize(height);
- icp.setXSize(64);
- icp.setYSize(8);
-
- //defing this as a resource
- ImageRasterData ird = new ImageRasterData(ImageRasterPattern
- .getRasterData(greyscale));
-
- io.setImageOutputControl(ioc);
- io.setImageInputDescriptor(iid);
- io.setImageCellPosition(icp);
- io.setImageRasterData(ird);
- _objects.add(io);
-
- }
-
- /**
- * Helper method to create an image on the current page and to return
- * the object.
- */
- public ImageObject getImageObject() {
-
- if (_presentationTextObject != null) {
- _presentationTextObject.endControlSequence();
- }
- _presentationTextObject = null;
-
- String imageName = "IMG"
- + StringUtils.lpad(String.valueOf(_objects.size() + 1),
- '0', 5);
-
- ImageObject io = new ImageObject(imageName);
- _objects.add(io);
- return io;
- }
-
- /**
- * Creates a TagLogicalElement on the page.
- *
- * @param name
- * the name of the tag
- * @param value
- * the value of the tag
- */
- public void createTagLogicalElement(String name, String value) {
-
- TagLogicalElement tle = new TagLogicalElement(name, value);
- _tagLogicalElements.add(tle);
-
- }
-
- /**
- * Creates an IncludePageSegment on the current page.
- *
- * @param name
- * the name of the page segment
- * @param xCoor
- * the x cooridinate of the page segment.
- * @param yCoor
- * the y cooridinate of the page segment.
- */
- public void createIncludePageSegment(String name, int xCoor, int yCoor) {
-
- IncludePageSegment ips = new IncludePageSegment(name, xCoor, yCoor);
- _segments.add(ips);
-
- }
-
- /**
- * Returns the ActiveEnvironmentGroup associated with this page.
- *
- * @return the ActiveEnvironmentGroup object
- */
- public ActiveEnvironmentGroup getActiveEnvironmentGroup() {
- return _activeEnvironmentGroup;
- }
-
- /**
- * Returns an indication if the page is complete
- */
- public boolean isComplete() {
- return _complete;
- }
-
- /**
- * Returns the height of the page
- */
- public int getHeight() {
- return _height;
- }
-
- /**
- * Returns the width of the page
- */
- public int getWidth() {
- return _width;
- }
-
- /**
- * Returns the rotation of the page
- */
- public int getRotation() {
- return _rotation;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import org.apache.fop.render.afp.fonts.AFPFont;
-
-/**
- * An Active Environment Group (AEG) is associated with each page,
- * and is contained in the page's begin-end envelope in the data stream.
- * The active environment group contains layout and formatting information
- * that defines the measurement units and size of the page, and may contain
- * resource information.
- *
- * Any objects that are required for page presentation and that are to be
- * treated as resource objects must be mapped with a map structured field
- * in the AEG. The scope of an active environment group is the scope of its
- * containing page or overlay.
- *
- */
-public final class ActiveEnvironmentGroup extends AbstractNamedAFPObject {
-
- /**
- * Default name for the active environment group
- */
- private static final String DEFAULT_NAME = "AEG00001";
-
- /**
- * The collection of MapCodedFont objects
- */
- private ArrayList _mapCodedFonts = new ArrayList();
-
- /**
- * The Object Area Descriptor for the active environment group
- */
- private ObjectAreaDescriptor _objectAreaDescriptor = null;
-
- /**
- * The Object Area Position for the active environment group
- */
- private ObjectAreaPosition _objectAreaPosition = null;
-
- /**
- * The PresentationTextDescriptor for the active environment group
- */
- private PresentationTextDescriptor _presentationTextDataDescriptor = null;
-
- /**
- * The PageDescriptor for the active environment group
- */
- private PageDescriptor _pageDescriptor = null;
-
- /**
- * The collection of MapPageOverlay objects
- */
- private ArrayList _mapPageOverlays = new ArrayList();
-
- /**
- * Default constructor for the ActiveEnvironmentGroup.
- * @param width the page width
- * @param height the page height
- */
- public ActiveEnvironmentGroup(int width, int height) {
-
- this(DEFAULT_NAME, width, height);
-
- }
-
- /**
- * Constructor for the ActiveEnvironmentGroup, this takes a
- * name parameter which must be 8 characters long.
- * @param name the active environment group name
- * @param width the page width
- * @param height the page height
- */
- public ActiveEnvironmentGroup(String name, int width, int height) {
-
- super(name);
-
- // Create PageDescriptor
- _pageDescriptor = new PageDescriptor(width, height);
-
- // Create ObjectAreaDescriptor
- _objectAreaDescriptor = new ObjectAreaDescriptor(width, height);
-
- // Create PresentationTextDataDescriptor
- _presentationTextDataDescriptor =
- new PresentationTextDescriptor(width, height);
-
- }
-
- /**
- * Set the position of the object area
- * @param x the x offset
- * @param y the y offset
- * @param rotation the rotation
- */
- public void setPosition(int x, int y, int rotation) {
-
- // Create ObjectAreaPosition
- _objectAreaPosition = new ObjectAreaPosition(x, y, rotation);
-
- }
-
- /**
- * Accessor method to obtain the PageDescriptor object of the
- * active environment group.
- * @return the page descriptor object
- */
- public PageDescriptor getPageDescriptor() {
-
- return _pageDescriptor;
-
- }
-
- /**
- * Accessor method to obtain the PresentationTextDataDescriptor object of
- * the active environment group.
- * @return the presentation text descriptor
- */
- public PresentationTextDescriptor getPresentationTextDataDescriptor() {
-
- return _presentationTextDataDescriptor;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the active environment group.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(_mapCodedFonts, os);
-
- writeObjectList(_mapPageOverlays, os);
-
- _pageDescriptor.writeDataStream(os);
-
- if (_objectAreaDescriptor != null && _objectAreaPosition != null) {
- _objectAreaDescriptor.writeDataStream(os);
- _objectAreaPosition.writeDataStream(os);
- }
-
- _presentationTextDataDescriptor.writeDataStream(os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the active environment group.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xC9; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the active environment group.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xC9; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Method to create a map coded font object
- * @param fontReference the font number used as the resource identifier
- * @param font the font
- * @param size the point size of the font
- * @param orientation the orientation of the font (e.g. 0, 90, 180, 270)
- */
- public void createFont(
- byte fontReference,
- AFPFont font,
- int size,
- int orientation) {
-
- MapCodedFont mcf = getCurrentMapCodedFont();
-
- if (mcf == null) {
- mcf = new MapCodedFont();
- _mapCodedFonts.add(mcf);
- }
-
- try {
-
- mcf.addFont(
- fontReference,
- font,
- size,
- orientation);
-
- } catch (MaximumSizeExceededException msee) {
-
- mcf = new MapCodedFont();
- _mapCodedFonts.add(mcf);
-
- try {
-
- mcf.addFont(
- fontReference,
- font,
- size,
- orientation);
-
- } catch (MaximumSizeExceededException ex) {
-
- // Should never happen (but log just in case)
- log.error("createFont():: resulted in a MaximumSizeExceededException");
-
- }
-
- }
-
- }
-
- /**
- * Actually creates the MPO object.
- * Also creates the supporting object (an IPO)
- * @param name the name of the overlay to be used
- */
- public void createOverlay(String name) {
-
- MapPageOverlay mpo = getCurrentMapPageOverlay();
-
- if (mpo == null) {
- mpo = new MapPageOverlay();
- _mapPageOverlays.add(mpo);
- }
-
- try {
-
- mpo.addOverlay(name);
-
- } catch (MaximumSizeExceededException msee) {
- mpo = new MapPageOverlay();
- _mapPageOverlays.add(mpo);
- try {
- mpo.addOverlay(name);
- } catch (MaximumSizeExceededException ex) {
- // Should never happen (but log just in case)
- log.error("createOverlay():: resulted in a MaximumSizeExceededException");
- }
- }
- }
-
- /**
- * Getter method for the most recent MapCodedFont added to the
- * Active Environment Group (returns null if no MapCodedFonts exist)
- * @return the most recent Map Coded Font.
- */
- private MapCodedFont getCurrentMapCodedFont() {
-
- int size = _mapCodedFonts.size();
- if (size > 0) {
- return (MapCodedFont) _mapCodedFonts.get(_mapCodedFonts.size() - 1);
- } else {
- return null;
- }
-
- }
-
- /**
- * Getter method for the most recent MapPageOverlay added to the
- * Active Environment Group (returns null if no MapPageOverlay exist)
- * @return the most recent Map Coded Font
- */
- private MapPageOverlay getCurrentMapPageOverlay() {
-
- int size = _mapPageOverlays.size();
- if (size > 0) {
- return (MapPageOverlay) _mapPageOverlays.get(
- _mapPageOverlays.size() - 1);
- } else {
- return null;
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-
-/**
- * The document is the highest level of the MO:DCA data-stream document
- * component hierarchy. Documents can be made up of pages, and the pages,
- * which are at the intermediate level, can be made up of objects. Objects
- * are at the lowest level, and can be bar codes, graphics, images, and
- * presentation text.
- *
- * At each level of the hierarchy certain sets of MO:DCA data structures,
- * called structured fields, are permissible. The document, pages and objects
- * are bounded by structured fields that define their beginnings and their ends.
- * These structured fields, called begin-end pairs, provide an envelope for the
- * data-stream components. This feature enables a processor of the data stream
- * that is not fully compliant with the architecture to bypass those objects
- * that are beyond its scope, and to process the data stream to the best of its
- * abilities.
- *
- * A presentation document is one that has been formatted and is intended for
- * presentation, usually on a printer or display device. A data stream containing
- * a presentation document should produce the same document content in the
- * same format on different printers or display devices dependent, however,
- * on the capabilities of each of the printers or display devices. A presentation
- * document can reference resources that are to be included as part of the
- * document to be presented.
- *
- */
-public final class Document extends AbstractNamedAFPObject {
-
- /**
- * Ststic default name reference
- */
- private final static String DEFAULT_NAME = "DOC00001";
-
- /**
- * A list of the objects in the document
- */
- private ArrayList _objects = new ArrayList();
-
- /**
- * The document started state
- */
- private boolean _started = false;
-
- /**
- * The document completion state
- */
- private boolean _complete = false;
-
- /**
- * Default constructor for the document object.
- */
- public Document() {
- this(DEFAULT_NAME);
- }
-
- /**
- * Constructor for the document object.
- * @param name The name of the document
- */
- public Document(String name) {
-
- super(name);
-
- }
-
- /**
- * Adds a page to the document.
- * @param page - the Page object
- */
- public void addPage(PageObject page) {
- if (!_objects.contains(page)) {
- _objects.add(page);
- }
- }
-
- /**
- * Adds a PageGroup to the document.
- * @param pageGroup the PageGroup object
- */
- public void addPageGroup(PageGroup pageGroup) {
- _objects.add(pageGroup);
- }
-
- /**
- * Method to mark the end of the page group.
- */
- public void endDocument() {
-
- _complete = true;
-
- }
-
- /**
- * Returns an indication if the page group is complete
- */
- public boolean isComplete() {
- return _complete;
- }
-
- /**
- * Accessor method to write the AFP datastream for document.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- if (!_started) {
- writeStart(os);
- _started = true;
- }
-
- for (Iterator it = _objects.iterator(); it.hasNext(); ) {
- AbstractAFPObject ao = (AbstractAFPObject)it.next();
- if (ao instanceof PageObject && ((PageObject)ao).isComplete()
- || ao instanceof PageGroup && ((PageGroup)ao).isComplete()) {
- ao.writeDataStream(os);
- it.remove();
- } else {
- break;
- }
- }
-
- if (_complete) {
- writeEnd(os);
- }
-
- }
-
- /**
- * Helper method to write the start of the Document
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xA8; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the Document.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xA8; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * The End Named Page Group (ENG) structured field terminates a page group that was
- * initiated by a Begin Named Page Group structured field.
- *
- * Note :This object will be used to represent an ENG
- * structured field. It is necessary as you can't end
- * a PageGroup because you don't know where the group
- * will end (as this is controlled by the tags in the FO).
- * <p>
- *
- */
-public class EndPageGroup extends AbstractNamedAFPObject {
-
- public EndPageGroup(String groupId) {
-
- super(groupId);
-
- log.debug("A ENG is being created for group: " + groupId);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the End Page Group.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xAD; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * An IM image data object specifies the contents of a raster image and
- * its placement on a page, overlay, or page segment. An IM image can be
- * either simple or complex. A simple image is composed of one or more Image
- * Raster Data (IRD) structured fields that define the raster pattern for the
- * entire image. A complex image is divided into regions called image cells.
- * Each image cell is composed of one or more IRD structured fields that define
- * the raster pattern for the image cell, and one Image Cell Position (ICP)
- * structured field that defines the position of the image cell relative to
- * the origin of the entire image. Each ICP also specifies the size of the
- * image cell and a fill rectangle into which the cell is replicated.
- * <p/>
- */
-public class IMImageObject extends AbstractNamedAFPObject {
-
- /**
- * The image output control
- */
- private ImageOutputControl _imageOutputControl = null;
-
- /**
- * The image input descriptor
- */
- private ImageInputDescriptor _imageInputDescriptor = null;
-
- /**
- * The image cell position
- */
- private ImageCellPosition _imageCellPosition = null;
-
- /**
- * The image rastor data
- */
- private ImageRasterData _imageRastorData = null;
-
- /**
- * Constructor for the image object with the specified name,
- * the name must be a fixed length of eight characters.
- * @param name The name of the image.
- */
- public IMImageObject(String name) {
-
- super(name);
-
- }
-
- /**
- * Sets the ImageOutputControl.
- * @param imageOutputControl The imageOutputControl to set
- */
- public void setImageOutputControl(ImageOutputControl imageOutputControl) {
- _imageOutputControl = imageOutputControl;
- }
-
- /**
- * Sets the ImageCellPosition.
- * @param imageCellPosition The imageCellPosition to set
- */
- public void setImageCellPosition(ImageCellPosition imageCellPosition) {
- _imageCellPosition = imageCellPosition;
- }
-
- /**
- * Sets the ImageInputDescriptor.
- * @param imageInputDescriptor The imageInputDescriptor to set
- */
- public void setImageInputDescriptor(ImageInputDescriptor imageInputDescriptor) {
- _imageInputDescriptor = imageInputDescriptor;
- }
-
- /**
- * Sets the ImageRastorData.
- * @param imageRastorData The imageRastorData to set
- */
- public void setImageRasterData(ImageRasterData imageRastorData) {
- _imageRastorData = imageRastorData;
- }
-
- /**
- * Accessor method to write the AFP datastream for the IM Image Objetc
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (_imageOutputControl != null) {
- _imageOutputControl.writeDataStream(os);
- }
-
- if (_imageInputDescriptor != null) {
- _imageInputDescriptor.writeDataStream(os);
- }
-
- if (_imageCellPosition != null) {
- _imageCellPosition.writeDataStream(os);
- }
-
- if (_imageRastorData != null) {
- _imageRastorData.writeDataStream(os);
- }
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the IM Image Object.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0x7B; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the IM Image Object.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0x7B; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The IM Image Cell Position structured field specifies the placement,
- * size, and replication of IM image cells.
- */
-public class ImageCellPosition extends AbstractAFPObject {
-
- /**
- * Offset of image cell in X direction
- */
- private int _XcoSet = 0;
-
- /**
- * Offset of image cell in Y direction
- */
- private int _YcoSet = 0;
-
- /**
- * Size of image cell in X direction
- */
- private byte[] _XcSize = new byte[] { (byte)0xFF, (byte)0xFF };
-
- /**
- * Size of image cell in Y direction
- */
- private byte[] _YcSize = new byte[] { (byte)0xFF, (byte)0xFF };
-
- /**
- * Size of fill rectangle in X direction
- */
- private byte[] _XFillSize = new byte[] { (byte)0xFF, (byte)0xFF };
-
- /**
- * Size of fill rectangle in Y direction
- */
- private byte[] _YFillSize = new byte[] { (byte)0xFF, (byte)0xFF };
-
- /**
- * Constructor for the ImageCellPosition
- * @param x The offset of image cell in X direction
- * @param y The offset of image cell in Y direction
- */
- public ImageCellPosition(int x, int y) {
-
- _XcoSet = x;
- _YcoSet = y;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Cell Position
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[21];
-
- data[0] = 0x5A;
-
- data[1] = 0x00;
- data[2] = 0x14;
-
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAC;
- data[5] = (byte) 0x7B;
- data[6] = 0x00;
- data[7] = 0x00;
- data[8] = 0x00;
-
- /**
- * Specifies the offset along the Xp direction, in image points,
- * of this image cell from the IM image object area origin.
- */
- byte[] x1 = BinaryUtils.convert(_XcoSet, 2);
- data[9] = x1[0];
- data[10] = x1[1];
-
- /**
- * Specifies the offset along the Yp direction, in image points,
- * of this image cell from the IM image object area origin.
- */
- byte[] x2 = BinaryUtils.convert(_YcoSet, 2);
- data[11] = x2[0];
- data[12] = x2[1];
-
- data[13] = _XcSize[0];
- data[14] = _XcSize[1];
-
- data[15] = _YcSize[0];
- data[16] = _YcSize[1];
-
- data[17] = _XFillSize[0];
- data[18] = _XFillSize[1];
-
- data[19] = _YFillSize[0];
- data[20] = _YFillSize[1];
-
- os.write(data);
-
- }
-
- /**
- * Specifies the extent in the X direction, in image points,
- * of this image cell. A value of X'FFFF' indicates that the
- * default extent specified in bytes 28 and 29 of the Image
- * Input Descriptor (IID) is to be used.
- * @param xcSize The size to set.
- */
- public void setXSize(int xcSize) {
-
- byte[] x = BinaryUtils.convert(xcSize, 2);
- _XcSize[0] = x[0];
- _XcSize[1] = x[1];
-
- }
-
- /**
- * Specifies the extent of the fill rectangle in the X direction,
- * in image points. This value can be smaller than, equal to, or
- * larger than the image cell extent in the X direction (XCSize).
- * A value of X'FFFF' indicates that the image cell X-extent should
- * be used as the fill rectangle X-extent. The fill rectangle is
- * filled in the X direction by repeating the image cell in the
- * X direction. The image cell can be truncated to fit the rectangle.
- * @param xFillSize The size to set.
- */
- public void setXFillSize(int xFillSize) {
-
- byte[] x = BinaryUtils.convert(xFillSize, 2);
- _XFillSize[0] = x[0];
- _XFillSize[1] = x[1];
-
- }
-
- /**
- * Specifies the extent in the Y direction, in image points,
- * of this image cell. A value of X'FFFF' indicates that the
- * default extent specified in bytes 30 and 31 of the Image
- * Input Descriptor (IID) is to be used.
- * @param ycSize The size to set.
- */
- public void setYSize(int ycSize) {
-
- byte[] x = BinaryUtils.convert(ycSize, 2);
- _YcSize[0] = x[0];
- _YcSize[1] = x[1];
-
- }
-
- /**
- * Specifies the extent of the fill rectangle in the Y direction,
- * in image points. This value can be smaller than, equal to, or
- * larger than the image cell extent in the Y direction (YCSize).
- * A value of X'FFFF' indicates that the image cell Y-extent should
- * be used as the fill rectangle Y-extent. The fill rectangle is
- * filled in the Y direction by repeating the image cell in the
- * Y direction. The image cell can be truncated to fit the rectangle.
- * @param yFillSize The size to set.
- */
- public void setYFillSize(int yFillSize) {
-
- byte[] x = BinaryUtils.convert(yFillSize, 2);
- _YFillSize[0] = x[0];
- _YFillSize[1] = x[1];
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- */
-public class ImageContent extends AbstractAFPObject {
-
- /**
- * The image size parameter
- */
- private ImageSizeParameter _imageSizeParameter = null;
-
- /**
- * The image encoding
- */
- private byte _encoding = 0x03;
-
- /**
- * The image ide size
- */
- private byte _size = 1;
-
- /**
- * The image compression
- */
- private byte _compression = (byte)0xC0;
-
- /**
- * The image color model
- */
- private byte _colorModel = 0x01;
-
- /**
- * The image data
- */
- private byte _data[] = null;
-
- /**
- * Constructor for the image content
- */
- public ImageContent() {
-
- }
-
- /**
- * Sets the image size parameters
- * resolution, hsize and vsize.
- * @param hresol The horizontal resolution of the image.
- * @param vresol The vertical resolution of the image.
- * @param hsize The horizontal size of the image.
- * @param vsize The vertival size of the image.
- */
- public void setImageSize(int hresol, int vresol, int hsize, int vsize) {
- _imageSizeParameter = new ImageSizeParameter(hresol, vresol, hsize, vsize);
- }
-
- /**
- * Sets the image encoding.
- * @param encoding The image encoding.
- */
- public void setImageEncoding(byte encoding) {
- _encoding = encoding;
- }
-
- /**
- * Sets the image compression.
- * @param compression The image compression.
- */
- public void setImageCompression(byte compression) {
- _compression = compression;
- }
-
- /**
- * Sets the image IDE size.
- * @param size The IDE size.
- */
- public void setImageIDESize(byte size) {
- _size = size;
- }
-
- /**
- * Sets the image IDE color model.
- * @param size The IDE color model.
- */
- public void setImageIDEColorModel(byte colorModel) {
- _colorModel = colorModel;
- }
-
- /**
- * Set the data of the image.
- */
- public void setImageData(byte data[]) {
- _data = data;
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Content
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (_imageSizeParameter != null) {
- _imageSizeParameter.writeDataStream(os);
- }
-
- os.write(getImageEncodingParameter());
-
- os.write(getImageIDESizeParameter());
-
- os.write(getIDEStructureParameter());
-
- os.write(getExternalAlgorithmParameter());
-
- if (_data != null) {
- int off = 0;
- while (off < _data.length) {
- int len = Math.min(30000, _data.length - off);
- os.write(getImageDataStart(len));
- os.write(_data, off, len);
- off += len;
- }
- }
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the Image Content.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- (byte)0x91, // ID
- 0x01, // Length
- (byte)0xff, // Object Type = IOCA Image Object
- };
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the Image Content.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- (byte)0x93, // ID
- 0x00, // Length
- };
-
- os.write(data);
-
- }
-
- /**
- * Helper method to return the start of the image segment.
- * @return byte[] The data stream.
- */
- private byte[] getImageDataStart(int len) {
-
- byte[] data = new byte[] {
- (byte)0xFE, // ID
- (byte)0x92, // ID
- 0x00, // Length
- 0x00, // Length
- };
-
- byte[] l = BinaryUtils.convert(len, 2);
- data[2] = l[0];
- data[3] = l[1];
-
-
- return data;
-
- }
-
- /**
- * Helper method to return the image encoding parameter.
- * @return byte[] The data stream.
- */
- private byte[] getImageEncodingParameter() {
-
- byte[] data = new byte[] {
- (byte)0x95, // ID
- 0x02, // Length
- _encoding,
- 0x01, // RECID
- };
-
- return data;
-
- }
-
- /**
- * Helper method to return the external algorithm parameter.
- * @return byte[] The data stream.
- */
- private byte[] getExternalAlgorithmParameter() {
-
- if (_encoding == (byte)0x83 && _compression != 0) {
- byte[] data = new byte[] {
- (byte)0x95, // ID
- 0x00, // Length
- 0x10, // ALGTYPE = Compression Algorithm
- 0x00, // Reserved
- (byte)0x83, // COMPRID = JPEG
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- _compression, // MARKER
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- };
- data[1] = (byte)(data.length - 2);
- return data;
- }
- return new byte[0];
- }
-
- /**
- * Helper method to return the image encoding parameter.
- * @return byte[] The data stream.
- */
- private byte[] getImageIDESizeParameter() {
-
- byte[] data = new byte[] {
- (byte)0x96, // ID
- 0x01, // Length
- _size,
- };
-
- return data;
-
- }
-
- /**
- * Helper method to return the external algorithm parameter.
- * @return byte[] The data stream.
- */
- private byte[] getIDEStructureParameter() {
-
- if (_colorModel != 0 && _size == 24) {
- byte bits = (byte)(_size / 3);
- byte[] data = new byte[] {
- (byte)0x9B, // ID
- 0x00, // Length
- 0x00, // FLAGS
- 0x00, // Reserved
- _colorModel, // COLOR MODEL
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- bits,
- bits,
- bits,
- };
- data[1] = (byte)(data.length - 2);
- return data;
- }
- return new byte[0];
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- */
-public class ImageDataDescriptor extends AbstractAFPObject {
-
- private int _xresol = 0;
- private int _yresol = 0;
- private int _width = 0;
- private int _height = 0;
-
- /**
- * Constructor for a ImageDataDescriptor for the specified
- * resolution, width and height.
- * @param xresol The horizontal resolution of the image.
- * @param yresol The vertical resolution of the image.
- * @param width The width of the image.
- * @param height The height of the height.
- */
- public ImageDataDescriptor(int xresol, int yresol, int width, int height) {
-
- _xresol = xresol;
- _yresol = yresol;
- _width = width;
- _height = height;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Data Descriptor
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A,
- 0x00,
- 0x20,
- (byte) 0xD3,
- (byte) 0xA6,
- (byte) 0xFB,
- 0x00, // Flags
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Unit base - 10 Inches
- 0x00, // XRESOL
- 0x00, //
- 0x00, // YRESOL
- 0x00, //
- 0x00, // XSIZE
- 0x00, //
- 0x00, // YSIZE
- 0x00, //
- (byte)0xF7, // ID = Set IOCA Function Set
- 0x02, // Length
- 0x01, // Category = Function set identifier
- 0x0B, // FCNSET = IOCA FS 11
- };
-
- byte[] l = BinaryUtils.convert(data.length - 1, 2);
- data[1] = l[0];
- data[2] = l[1];
-
- byte[] x = BinaryUtils.convert(_xresol, 2);
- data[10] = x[0];
- data[11] = x[1];
-
- byte[] y = BinaryUtils.convert(_yresol, 2);
- data[12] = y[0];
- data[13] = y[1];
-
- byte[] w = BinaryUtils.convert(_width, 2);
- data[14] = w[0];
- data[15] = w[1];
-
- byte[] h = BinaryUtils.convert(_height, 2);
- data[16] = h[0];
- data[17] = h[1];
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The IM Image Input Descriptor structured field contains the
- * descriptor data for an IM image data object. This data specifies
- * the resolution, size, and color of the IM image.
- */
-public class ImageInputDescriptor extends AbstractAFPObject {
-
- /**
- * The resolution of the raster image (default 240)
- */
- private int _resolution = 240;
-
-
- /**
- * Accessor method to write the AFP datastream for the Image Input Descriptor
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[45];
-
- data[0] = 0x5A;
- data[1] = 0x00;
- data[2] = 0x2C;
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xA6;
- data[5] = (byte) 0x7B;
- data[6] = 0x00;
- data[7] = 0x00;
- data[8] = 0x00;
-
- // Constant data.
- data[9] = 0x00;
- data[10] = 0x00;
- data[11] = 0x09;
- data[12] = 0x60;
- data[13] = 0x09;
- data[14] = 0x60;
- data[15] = 0x00;
- data[16] = 0x00;
- data[17] = 0x00;
- data[18] = 0x00;
- data[19] = 0x00;
- data[20] = 0x00;
-
- // X Base (Fixed x00)
- data[21] = 0x00;
- // Y Base (Fixed x00)
- data[22] = 0x00;
-
- byte[] imagepoints = BinaryUtils.convert(_resolution * 10, 2);
-
- /**
- * Specifies the number of image points per unit base for the X axis
- * of the image. This value is ten times the resolution of the image
- * in the X direction.
- */
- data[23] = imagepoints[0];
- data[24] = imagepoints[1];
-
- /**
- * Specifies the number of image points per unit base for the Y axis
- * of the image. This value is ten times the resolution of the image
- * in the Y direction.
- */
- data[25] = imagepoints[0];
- data[26] = imagepoints[1];
-
- /**
- * Specifies the extent in the X direction, in image points, of an
- * non-celled (simple) image.
- */
- data[27] = 0x00;
- data[28] = 0x01;
-
- /**
- * Specifies the extent in the Y direction, in image points, of an
- * non-celled (simple) image.
- */
- data[29] = 0x00;
- data[30] = 0x01;
-
- // Constant Data
- data[31] = 0x00;
- data[32] = 0x00;
- data[33] = 0x00;
- data[34] = 0x00;
- data[35] = 0x2D;
- data[36] = 0x00;
-
- // Default size of image cell in X direction
- data[37] = 0x00;
- data[38] = 0x01;
-
- // Default size of image cell in Y direction
- data[39] = 0x00;
- data[40] = 0x01;
-
- // Constant Data
- data[41] = 0x00;
- data[42] = 0x01;
-
- // Image Color
- data[43] = (byte)0xFF;
- data[44] = (byte)0xFF;
-
- os.write(data);
-
- }
-
- /**
- * Sets the resolution information for the raster image
- * the default value is a resolution of 240 dpi.
- * @param resolution The resolution value
- */
- public void setResolution(int resolution) {
- _resolution = resolution;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * An IOCA Image Data Object
- */
-public class ImageObject extends AbstractNamedAFPObject {
-
- /**
- * The object environment group
- */
- private ObjectEnvironmentGroup _objectEnvironmentGroup = null;
-
- /**
- * The image segment
- */
- private ImageSegment _imageSegment = null;
-
- /**
- * Constructor for the image object with the specified name,
- * the name must be a fixed length of eight characters.
- * @param name The name of the image.
- */
- public ImageObject(String name) {
-
- super(name);
-
- }
-
- /**
- * Sets the image display area position and size.
- *
- * @param x
- * the x position of the image
- * @param y
- * the y position of the image
- * @param w
- * the width of the image
- * @param h
- * the height of the image
- * @param r
- * the rotation of the image
- */
- public void setImageViewport(int x, int y, int w, int h, int r) {
- if (_objectEnvironmentGroup == null) {
- _objectEnvironmentGroup = new ObjectEnvironmentGroup();
- }
- _objectEnvironmentGroup.setObjectArea(x, y, w, h, r);
- }
-
- /**
- * Set the dimensions of the image.
- * @param xresol the x resolution of the image
- * @param yresol the y resolution of the image
- * @param width the image width
- * @param height the image height
- */
- public void setImageParameters(int xresol, int yresol, int width, int height) {
- if (_objectEnvironmentGroup == null) {
- _objectEnvironmentGroup = new ObjectEnvironmentGroup();
- }
- _objectEnvironmentGroup.setImageData(xresol, yresol, width, height);
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageSize(xresol, yresol, width, height);
- }
-
- /**
- * Sets the image encoding.
- * @param encoding The image encoding.
- */
- public void setImageEncoding(byte encoding) {
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageEncoding(encoding);
- }
-
- /**
- * Sets the image compression.
- * @param compression The image compression.
- */
- public void setImageCompression(byte compression) {
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageCompression(compression);
- }
-
- /**
- * Sets the image IDE size.
- * @param size The IDE size.
- */
- public void setImageIDESize(byte size) {
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageIDESize(size);
- }
-
- /**
- * Sets the image IDE color model.
- * @param size The IDE color model.
- */
- public void setImageIDEColorModel(byte colorModel) {
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageIDEColorModel(colorModel);
- }
-
- /**
- * Set the data of the image.
- * @param data The image data
- */
- public void setImageData(byte data[]) {
- if (_imageSegment == null) {
- _imageSegment = new ImageSegment();
- }
- _imageSegment.setImageData(data);
- }
-
- /**
- * Sets the ObjectEnvironmentGroup.
- * @param objectEnvironmentGroup The objectEnvironmentGroup to set
- */
- public void setObjectEnvironmentGroup(ObjectEnvironmentGroup objectEnvironmentGroup) {
- _objectEnvironmentGroup = objectEnvironmentGroup;
- }
-
- /**
- * Helper method to return the start of the image object.
- * @return byte[] The data stream.
- */
- private byte[] getIPDStart(int len) {
-
- byte[] data = new byte[] {
-
- 0x5A, // Structured field identifier
- 0x00, // Length byte 1
- 0x10, // Length byte 2
- (byte) 0xD3, // Structured field id byte 1
- (byte) 0xEE, // Structured field id byte 2
- (byte) 0xFB, // Structured field id byte 3
- 0x00, // Flags
- 0x00, // Reserved
- 0x00, // Reserved
- };
-
- byte[] l = BinaryUtils.convert(len + 8, 2);
- data[1] = l[0];
- data[2] = l[1];
-
- return data;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Object
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (_objectEnvironmentGroup != null) {
- _objectEnvironmentGroup.writeDataStream(os);
- }
-
- if (_imageSegment != null) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- _imageSegment.writeDataStream(baos);
- byte b[] = baos.toByteArray();
- int off = 0;
- while (off < b.length) {
- int len = Math.min(30000, b.length - off);
- os.write(getIPDStart(len));
- os.write(b, off, len);
- off += len;
- }
- }
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the Image Object.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xFB; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the Image Object.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xFB; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The IM Image Output Control structured field specifies the position and
- * orientation of the IM image object area and the mapping of the image points
- * to presentation device pels.
- *
- */
-public class ImageOutputControl extends AbstractAFPObject {
-
- /**
- * The orientation of the image
- */
- private int _orientation = 0;
-
- /**
- * Specifies the offset, along the X-axis, of the IM image object area
- * origin to the origin of the including page
- */
- private int _Xcoordinate = 0;
-
- /**
- * Specifies the offset, along the Y-axis, of the IM image object area
- * origin to the origin of the including page
- */
- private int _Ycoordinate = 0;
-
- /**
- * Map an image point to a single presentation device pel
- */
- private boolean _singlepoint = true;
-
- /**
- * Constructor for the ImageOutputControl The x parameter specifies the
- * offset, along the X-axis, of the IM image object area origin to the
- * origin of the including page and the y parameter specifies the offset
- * along the Y-axis. The offset is specified in image points and is resolved
- * using the units of measure specified for the image in the IID structured
- * field.
- *
- * @param x
- * The X-axis offset.
- * @param y
- * The Y-axis offset.
- */
- public ImageOutputControl(int x, int y) {
-
- _Xcoordinate = x;
- _Ycoordinate = y;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Output Control
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[33];
-
- data[0] = 0x5A;
- data[1] = 0x00;
- data[2] = 0x20;
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xA7;
- data[5] = (byte) 0x7B;
- data[6] = 0x00;
- data[7] = 0x00;
- data[8] = 0x00;
-
- // XoaOset
- byte[] x1 = BinaryUtils.convert(_Xcoordinate, 3);
- data[9] = x1[0];
- data[10] = x1[1];
- data[11] = x1[2];
-
- // YoaOset
- byte[] x2 = BinaryUtils.convert(_Ycoordinate, 3);
- data[12] = x2[0];
- data[13] = x2[1];
- data[14] = x2[2];
-
- switch (_orientation) {
- case 0:
- // 0 and 90 degrees respectively
- data[15] = 0x00;
- data[16] = 0x00;
- data[17] = 0x2D;
- data[18] = 0x00;
- break;
- case 90:
- // 90 and 180 degrees respectively
- data[15] = 0x2D;
- data[16] = 0x00;
- data[17] = 0x5A;
- data[18] = 0x00;
- break;
- case 180:
- // 180 and 270 degrees respectively
- data[15] = 0x5A;
- data[16] = 0x00;
- data[17] = (byte) 0x87;
- data[18] = 0x00;
- break;
- case 270:
- // 270 and 0 degrees respectively
- data[15] = (byte) 0x87;
- data[16] = 0x00;
- data[17] = 0x00;
- data[18] = 0x00;
- break;
- default:
- // 0 and 90 degrees respectively
- data[15] = 0x00;
- data[16] = 0x00;
- data[17] = 0x2D;
- data[18] = 0x00;
- break;
-
- }
-
- // Constant Data
- data[19] = 0x00;
- data[20] = 0x00;
- data[21] = 0x00;
- data[22] = 0x00;
- data[23] = 0x00;
- data[24] = 0x00;
- data[25] = 0x00;
- data[26] = 0x00;
-
- if (_singlepoint) {
- data[27] = 0x03;
- data[28] = (byte) 0xE8;
- data[29] = 0x03;
- data[30] = (byte) 0xE8;
- } else {
- data[27] = 0x07;
- data[28] = (byte) 0xD0;
- data[29] = 0x07;
- data[30] = (byte) 0xD0;
- }
-
- // Constant Data
- data[31] = (byte) 0xFF;
- data[32] = (byte) 0xFF;
-
- os.write(data);
-
- }
-
- /**
- * Sets the orientation which specifies the amount of clockwise rotation of
- * the IM image object area.
- *
- * @param orientation
- * The orientation to set.
- */
- public void setOrientation(int orientation) {
-
- if (orientation == 0 || orientation == 90 || orientation == 180
- || orientation == 270) {
- _orientation = orientation;
- } else {
- throw new IllegalArgumentException(
- "The orientation must be one of the values 0, 90, 180, 270");
- }
-
- }
-
- /**
- * Sets the singlepoint, if true map an image point to a single presentation
- * device pel in the IM image object area. If false map an image point to
- * two presentation device pels in the IM image object area (double-dot)
- *
- * @param singlepoint
- * Use the singlepoint basis when true.
- */
- public void setSinglepoint(boolean singlepoint) {
- _singlepoint = singlepoint;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * Contains the image points that define the IM image raster pattern.
- *
- * A raster pattern is the array of presentation device pels that forms
- * the image. The image data is uncompressed. Bits are grouped into
- * bytes and are ordered from left to right within each byte. Each bit
- * in the image data represents an image point and is mapped to
- * presentation device pels as specified in the IOC structured field.
- * A bit with value B'1' indicates a significant image point; a bit
- * with value B'0' indicates an insignificant image point.
- * Image points are recorded from left to right in rows that represents
- * scan lines (X direction), and rows representing scan lines are
- * recorded from top to bottom (Y direction). When the image is
- * presented, all image points in a row are presented before any
- * image points in the next sequential row are presented, and all rows
- * have the same number of image points. If the total number of image
- * points is not a multiple of 8, the last byte of the image data is
- * padded to a byte boundary. The padding bits do not represent image
- * points and are ignored by presentation devices.
- */
-public class ImageRasterData extends AbstractAFPObject {
-
- /**
- * The image raster data
- */
- private byte[] _rasterdata;
-
- /**
- * Constructor for the image raster data object
- * @param rasterdata The raster image data
- */
- public ImageRasterData(byte[] rasterdata) {
-
- _rasterdata = rasterdata;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Raster Data
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[9];
-
- data[0] = 0x5A;
-
- // The size of the structured field
- byte[] x = BinaryUtils.convert(_rasterdata.length + 8, 2);
- data[1] = x[0];
- data[2] = x[1];
-
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xEE;
- data[5] = (byte) 0x7B;
- data[6] = 0x00;
- data[7] = 0x00;
- data[8] = 0x00;
-
- os.write(data);
- os.write(_rasterdata);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-/**
- * Raster data is a grid of cells covering an area of interest.
- * Each pixel, the smallest unit of information in the grid, displays
- * a unique attribute. This static class generates raster data for different
- * shades of grey (betweeen 0 and 16) the lower the number being the
- * darker the shade. The image data dimensions are 64 x 8.
- */
-public class ImageRasterPattern {
-
- /**
- * The Raster Pattern for Greyscale 16
- */
- private static final byte[] GREYSCALE16 = new byte[] {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- };
-
- /**
- * The Raster Pattern for Greyscale 15
- */
- private static final byte[] GREYSCALE15 = new byte[] {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- };
-
- /**
- * The Raster Pattern for Greyscale 14
- */
- private static final byte[] GREYSCALE14 = new byte[] {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 13
- */
- private static final byte[] GREYSCALE13 = new byte[] {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
- /**
- * The Raster Pattern for Greyscale 12
- */
- private static final byte[] GREYSCALE12 = new byte[] {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
- /**
- * The Raster Pattern for Greyscale 11
- */
- private static final byte[] GREYSCALE11 = new byte[] {
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
- /**
- * The Raster Pattern for Greyscale 10
- */
- private static final byte[] GREYSCALE10 = new byte[] {
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- 0x44,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
- /**
- * The Raster Pattern for Greyscale 9
- */
- private static final byte[] GREYSCALE09 = new byte[] {
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- 0x11,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
- /**
- * The Raster Pattern for Greyscale 8
- */
- private static final byte[] GREYSCALE08 = new byte[] {
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 7
- */
- private static final byte[] GREYSCALE07 = new byte[] {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 6
- */
- private static final byte[] GREYSCALE06 = new byte[] {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- };
-
- /**
- * The Raster Pattern for Greyscale 5
- */
- private static final byte[] GREYSCALE05 = new byte[] {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xEE,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 4
- */
- private static final byte[] GREYSCALE04 = new byte[] {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xAA,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- };
-
- /**
- * The Raster Pattern for Greyscale 3
- */
- private static final byte[] GREYSCALE03 = new byte[] {
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- 0x55,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xBB,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- };
-
- /**
- * The Raster Pattern for Greyscale 2
- */
- private static final byte[] GREYSCALE02 = new byte[] {
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xDD,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 1
- */
- private static final byte[] GREYSCALE01 = new byte[] {
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- 0x77,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- };
-
-
- /**
- * The Raster Pattern for Greyscale 00
- */
- private static final byte[] GREYSCALE00 = new byte[] {
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- (byte)0xFF,
- };
-
- /**
- * Static method to return the raster image data for the
- * grey scale specified. The scale should be between 0 (darkest)
- * and 16 (lightest).
- * @param greyscale The grey scale value (0 - 16)
- */
- public static byte[] getRasterData(int greyscale) {
-
- int repeat = 16;
-
- byte[] greypattern = new byte[32];
- byte[] rasterdata = new byte[32 * repeat];
-
- switch (greyscale) {
- case 0:
- System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32);
- break;
- case 1:
- System.arraycopy(GREYSCALE01, 0, greypattern, 0, 32);
- break;
- case 2:
- System.arraycopy(GREYSCALE02, 0, greypattern, 0, 32);
- break;
- case 3:
- System.arraycopy(GREYSCALE03, 0, greypattern, 0, 32);
- break;
- case 4:
- System.arraycopy(GREYSCALE04, 0, greypattern, 0, 32);
- break;
- case 5:
- System.arraycopy(GREYSCALE05, 0, greypattern, 0, 32);
- break;
- case 6:
- System.arraycopy(GREYSCALE06, 0, greypattern, 0, 32);
- break;
- case 7:
- System.arraycopy(GREYSCALE07, 0, greypattern, 0, 32);
- break;
- case 8:
- System.arraycopy(GREYSCALE08, 0, greypattern, 0, 32);
- break;
- case 9:
- System.arraycopy(GREYSCALE09, 0, greypattern, 0, 32);
- break;
- case 10:
- System.arraycopy(GREYSCALE10, 0, greypattern, 0, 32);
- break;
- case 11:
- System.arraycopy(GREYSCALE11, 0, greypattern, 0, 32);
- break;
- case 12:
- System.arraycopy(GREYSCALE12, 0, greypattern, 0, 32);
- break;
- case 13:
- System.arraycopy(GREYSCALE13, 0, greypattern, 0, 32);
- break;
- case 14:
- System.arraycopy(GREYSCALE14, 0, greypattern, 0, 32);
- break;
- case 15:
- System.arraycopy(GREYSCALE15, 0, greypattern, 0, 32);
- break;
- case 16:
- System.arraycopy(GREYSCALE16, 0, greypattern, 0, 32);
- break;
- default :
- System.arraycopy(GREYSCALE00, 0, greypattern, 0, 32);
- break;
- }
-
- for (int i = 0; i < repeat; i++) {
-
- System.arraycopy(greypattern, 0, rasterdata, i * 32, 32);
-
- }
-
- return rasterdata;
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * An Image Segment is represented by a set of self-defining fields, fields
- * that describe their own contents. It starts with a Begin Segment, and
- * ends with an End Segment.
- *
- * Between the Begin Segment and End Segment is the image information to
- * be processed, called the Image Content.
- *
- * Only one Image Content can exist within a single IOCA Image Segment.
- */
-public class ImageSegment extends AbstractAFPObject {
-
- /**
- * Default name for the object environment group
- */
- private static final String DEFAULT_NAME = "IS01";
-
- /**
- * The name of the image segment
- */
- private String _name;
-
- /**
- * The name of the image segment as EBCIDIC bytes
- */
- private byte[] _nameBytes;
-
- /**
- * The ImageContent for the image segment
- */
- private ImageContent _imageContent = null;
-
- /**
- * Default constructor for the ImageSegment.
- */
- public ImageSegment() {
-
- this(DEFAULT_NAME);
-
- }
-
- /**
- * Constructor for the image segment with the specified name,
- * the name must be a fixed length of eight characters.
- * @param name The name of the image.
- */
- public ImageSegment(String name) {
-
- if (name.length() != 4) {
- String msg = "Image segment name must be 4 characters long " + name;
- log.error("Constructor:: " + msg);
- throw new IllegalArgumentException(msg);
- }
-
- _name = name;
-
- try {
-
- _nameBytes = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
-
- } catch (UnsupportedEncodingException usee) {
-
- _nameBytes = name.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
-
- }
-
- }
-
- /**
- * Sets the image size parameters
- * resolution, hsize and vsize.
- * @param hresol The horizontal resolution of the image.
- * @param vresol The vertical resolution of the image.
- * @param hsize The horizontal size of the image.
- * @param vsize The vertival size of the image.
- */
- public void setImageSize(int hresol, int vresol, int hsize, int vsize) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageSize(hresol, vresol, hsize, vsize);
- }
-
- /**
- * Sets the image encoding.
- * @param encoding The image encoding.
- */
- public void setImageEncoding(byte encoding) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageEncoding(encoding);
- }
-
- /**
- * Sets the image compression.
- * @param compression The image compression.
- */
- public void setImageCompression(byte compression) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageCompression(compression);
- }
-
- /**
- * Sets the image IDE size.
- * @param size The IDE size.
- */
- public void setImageIDESize(byte size) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageIDESize(size);
- }
-
- /**
- * Sets the image IDE color model.
- * @param size The IDE color model.
- */
- public void setImageIDEColorModel(byte colorModel) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageIDEColorModel(colorModel);
- }
-
- /**
- * Set the data of the image.
- * @param data the image data
- */
- public void setImageData(byte data[]) {
- if (_imageContent == null) {
- _imageContent = new ImageContent();
- }
- _imageContent.setImageData(data);
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Segment
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (_imageContent != null) {
- _imageContent.writeDataStream(os);
- }
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the Image Segment.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x70, // ID
- 0x04, // Length
- 0x00, // Name byte 1
- 0x00, // Name byte 2
- 0x00, // Name byte 3
- 0x00, // Name byte 4
- };
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[2 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the Image Segment.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x71, // ID
- 0x00, // Length
- };
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * Describes the measurement characteristics of the image when it is created.
- */
-public class ImageSizeParameter extends AbstractAFPObject {
-
- private int _hresol = 0;
- private int _vresol = 0;
- private int _hsize = 0;
- private int _vsize = 0;
-
- /**
- * Constructor for a ImageSizeParameter for the specified
- * resolution, hsize and vsize.
- * @param hresol The horizontal resolution of the image.
- * @param vresol The vertical resolution of the image.
- * @param hsize The hsize of the image.
- * @param vsize The vsize of the vsize.
- */
- public ImageSizeParameter(int hresol, int vresol, int hsize, int vsize) {
-
- _hresol = hresol;
- _vresol = vresol;
- _hsize = hsize;
- _vsize = vsize;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Image Size Parameter
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- (byte)0x94, // ID = Image Size Parameter
- 0x09, // Length
- 0x00, // Unit base - 10 Inches
- 0x00, // HRESOL
- 0x00, //
- 0x00, // VRESOL
- 0x00, //
- 0x00, // HSIZE
- 0x00, //
- 0x00, // VSIZE
- 0x00, //
- };
-
- byte[] x = BinaryUtils.convert(_hresol, 2);
- data[3] = x[0];
- data[4] = x[1];
-
- byte[] y = BinaryUtils.convert(_vresol, 2);
- data[5] = y[0];
- data[6] = y[1];
-
- byte[] w = BinaryUtils.convert(_hsize, 2);
- data[7] = w[0];
- data[8] = w[1];
-
- byte[] h = BinaryUtils.convert(_vsize, 2);
- data[9] = h[0];
- data[10] = h[1];
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * An Include Object structured field references an object on a page or overlay.
- * It optionally contains parameters that identify the object and that specify
- * presentation parameters such as object position, size, orientation, mapping,
- * and default color.
- * <p>
- * Where the presentation parameters conflict with parameters specified in the
- * object's environment group (OEG), the parameters in the Include Object
- * structured field override. If the referenced object is a page segment, the
- * IOB parameters override the corresponding environment group parameters on all
- * data objects in the page segment.
- * </p>
- */
-public class IncludeObject extends AbstractNamedAFPObject {
-
- /**
- * The object type
- */
- private byte _objectType = (byte) 0x92;
-
- /**
- * The orientation on the include object
- */
- private int _orientation = 0;
-
- /**
- * Constructor for the include object with the specified name, the name must
- * be a fixed length of eight characters and is the name of the referenced
- * object.
- *
- * @param name
- * the name of the image
- */
- public IncludeObject(String name) {
-
- super(name);
- _objectType = (byte) 0xFB;
-
- }
-
- /**
- * Sets the orienation to use for the Include Object.
- *
- * @param orientation
- * The orientation (0,90, 180, 270)
- */
- public void setOrientation(int orientation) {
-
- if (orientation == 0 || orientation == 90 || orientation == 180
- || orientation == 270) {
- _orientation = orientation;
- } else {
- throw new IllegalArgumentException(
- "The orientation must be one of the values 0, 90, 180, 270");
- }
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Include Object
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[37];
-
- data[0] = 0x5A;
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(36, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a IOB
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAF;
- data[5] = (byte) 0xC3;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
- data[9 + i] = _nameBytes[i];
- }
-
- data[17] = 0x00;
- data[18] = _objectType;
-
- // XoaOset
- data[20] = (byte) 0xFF;
- data[21] = (byte) 0xFF;
- data[22] = (byte) 0xFF;
-
- // YoaOset
- data[23] = (byte) 0xFF;
- data[24] = (byte) 0xFF;
- data[25] = (byte) 0xFF;
-
- switch (_orientation) {
- case 90:
- data[26] = 0x2D;
- data[27] = 0x00;
- data[28] = 0x5A;
- data[29] = 0x00;
- break;
- case 180:
- data[26] = 0x5A;
- data[27] = 0x00;
- data[28] = (byte) 0x87;
- data[29] = 0x00;
- break;
- case 270:
- data[26] = (byte) 0x87;
- data[27] = 0x00;
- data[28] = 0x00;
- data[29] = 0x00;
- break;
- default:
- data[26] = 0x00;
- data[27] = 0x00;
- data[28] = 0x2D;
- data[29] = 0x00;
- break;
- }
-
- // XocaOset
- data[30] = (byte) 0xFF;
- data[31] = (byte) 0xFF;
- data[32] = (byte) 0xFF;
-
- // YocaOset
- data[33] = (byte) 0xFF;
- data[34] = (byte) 0xFF;
- data[35] = (byte) 0xFF;
-
- data[36] = 0x01;
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- *
- * The Include Page Overlay structured field references an overlay resource
- * definition that is to be positioned on the page. A page overlay can be
- * referenced at any time during the page state, but not during an object state.
- * The overlay contains its own active environment group definition.
- *
- * Note: There is no need for the triplets, so I have ignored them.
- *
- * A real example of where this will be used is for static overlays, such as an
- * address on the page.
- *
- */
-public class IncludePageOverlay extends AbstractNamedAFPObject {
-
- /**
- * The x coordinate
- */
- private int _xCoor = 0;
-
- /**
- * The y coordinate
- */
- private int _yCoor = 0;
-
- /**
- * The orientation
- */
- private int _orientation = 0;
-
- /**
- * Constructor for the Include Page Overlay
- * @param overlayName Name of the page segment
- * @param x The x position
- * @param y The y position
- * @param orientation The orientation
- */
- public IncludePageOverlay(String overlayName, int x, int y, int orientation) {
-
- super(overlayName);
-
- _xCoor = x;
- _yCoor = y;
- setOrientation(orientation);
- }
-
- /**
- * Sets the orienation to use for the overlay.
- *
- * @param orientation
- * The orientation (0,90, 180, 270)
- */
- public void setOrientation(int orientation) {
-
- if (orientation == 0 || orientation == 90 || orientation == 180
- || orientation == 270) {
- _orientation = orientation;
- } else {
- throw new IllegalArgumentException(
- "The orientation must be one of the values 0, 90, 180, 270");
- }
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Include Page Overlay
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[25]; //(9 +16)
-
- data[0] = 0x5A;
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(24, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a IPO
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAF;
- data[5] = (byte) 0xD8;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- byte[] r2 = BinaryUtils.convert(_xCoor, 3);
- data[17] = r2[0]; // x coordinate
- data[18] = r2[1];
- data[19] = r2[2];
-
- byte[] r3 = BinaryUtils.convert(_yCoor, 3);
- data[20] = r3[0]; // y coordinate
- data[21] = r3[1];
- data[22] = r3[2];
-
- switch (_orientation) {
- case 90:
- data[23] = 0x2D;
- data[24] = 0x00;
- break;
- case 180:
- data[23] = 0x5A;
- data[24] = 0x00;
- break;
- case 270:
- data[23] = (byte) 0x87;
- data[24] = 0x00;
- break;
- default:
- data[23] = 0x00;
- data[24] = 0x00;
- break;
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Include Page Segment structured field references a page segment resource
- * object that is to be presented on the page or overlay presentation space. The IPS
- * specifies a reference point on the including page or overlay coordinate system that
- * may be used to position objects contained in the page segment. A page segment
- * can be referenced at any time during page or overlay state, but not during an
- * object state. The page segment inherits the active environment group definition of
- * the including page or overlay.
- *
- * Note : No use for Triplets.
- *
- * A 'real' example for where this will be used is for
- * the dynamic placing of overlay objects, such as signatures
- * that may have to be placed at different positions on a document.
- *
- */
-public class IncludePageSegment extends AbstractNamedAFPObject{
-
- /**
- * The x position where we need to put this object on the page
- */
- private byte [] _xCoor;
-
- /**
- * The y position where we need to put this object on the page
- */
- private byte [] _yCoor;
-
- /**
- * Constructor for the Include Page Segment
- * @param name Name of the page segment
- * @param xVal The x position
- * @param yVal The y position
- */
- public IncludePageSegment(String name, int xVal, int yVal){
-
- super(name);
- _xCoor = BinaryUtils.convert(xVal, 3);
- _yCoor = BinaryUtils.convert(yVal, 3);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Include Page Segment
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[23]; //(9 +14)
-
- data[0] = 0x5A;
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(22, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a IPS
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAF;
- data[5] = (byte) 0x5F;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- data[17] = _xCoor[0]; // x coordinate
- data[18] = _xCoor[1];
- data[19] = _xCoor[2];
-
- data[20] = _yCoor[0]; // y coordinate
- data[21] = _yCoor[1];
- data[22] = _yCoor[2];
-
- os.write(data);
-
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Invoke Medium Map structured field identifies the Medium Map that is to
- * become active for the document. An Invoke Medium Map structured field affects
- * the document's current environment. The Medium Map's effect on current environment
- * parameter values lasts until a new Medium Map is invoked.
- */
-public class InvokeMediumMap extends AbstractNamedAFPObject {
-
- /**
- * Constructor for the Invoke Medium Map
- * @param mediumMapName Name of the medium map
- */
- public InvokeMediumMap(String mediumMapName) {
-
- super(mediumMapName);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Invoke Medium Map
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A;
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(16, 2); //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a IPO
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAB;
- data[5] = (byte) 0xCC;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-import org.apache.fop.render.afp.exceptions.FontRuntimeException;
-import org.apache.fop.render.afp.fonts.AFPFont;
-import org.apache.fop.render.afp.fonts.CharacterSet;
-import org.apache.fop.render.afp.fonts.OutlineFont;
-import org.apache.fop.render.afp.fonts.RasterFont;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Map Coded Font structured field maps a unique coded font resource local
- * ID, which may be embedded one or more times within an object's data and
- * descriptor, to the identifier of a coded font resource object. Additionally,
- * the Map Coded Font structured field specifies a set of resource attributes
- * for the coded font.
- *
- * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
- */
-public class MapCodedFont extends AbstractAFPObject {
-
- /**
- * The collection of map coded fonts (maximum of 254)
- */
- private ArrayList _fontlist = null;
-
- /**
- * Constructor for the MapCodedFont
- */
- public MapCodedFont() {
-
- _fontlist = new ArrayList();
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Map Coded Font
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- baos.write(0x5A);
- baos.write(new byte[] { 0x00, 0x00 });
-
- // Field identifier for a MapCodedFont
- baos.write(new byte[] { (byte) 0xD3, (byte) 0xAB, (byte) 0x8A });
-
- // Reserved
- baos.write(new byte[] { 0x00, 0x00, 0x00 });
-
- for (int i = 0; i < _fontlist.size(); i++) {
-
- FontDefinition fd = (FontDefinition) _fontlist.get(i);
-
- // Start of repeating groups (occurs 1 to 254)
- baos.write(0x00);
-
- if (fd._scale == 0) {
- // Raster Font
- baos.write(0x22); // Length of 34
- } else {
- // Outline Font
- baos.write(0x3A); // Length of 58
- }
-
- // Font Character Set Name Reference
- baos.write(0x0C);
- baos.write(0x02);
- baos.write((byte) 0x86);
- baos.write(0x00);
- baos.write(fd._characterset);
-
- // Font Code Page Name Reference
- baos.write(0x0C);
- baos.write(0x02);
- baos.write((byte) 0x85);
- baos.write(0x00);
- baos.write(fd._codepage);
-
- // Character Rotation
- baos.write(0x04);
- baos.write(0x26);
- baos.write(fd._orientation);
- baos.write(0x00);
-
- // Resource Local Identifier
- baos.write(0x04);
- baos.write(0x24);
- baos.write(0x05);
- baos.write(fd._fontReferenceKey);
-
- if (fd._scale != 0) {
- // Outline Font (triplet '1F')
- baos.write(0x14);
- baos.write(0x1F);
- baos.write(0x00);
- baos.write(0x00);
-
- baos.write(BinaryUtils.convert(fd._scale, 2)); // Height
- baos.write(new byte[] { 0x00, 0x00 }); // Width
-
- baos.write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00 });
-
- baos.write(0x60);
-
- // Outline Font (triplet '5D')
- baos.write(0x04);
- baos.write(0x5D);
- baos.write(BinaryUtils.convert(fd._scale, 2));
- }
-
- }
-
- byte[] data = baos.toByteArray();
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(data.length - 1, 2);
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- os.write(data);
-
- }
-
- /**
- * Add a font definition on the the map coded font object.
- *
- * @param fontReference
- * the font number used as the resource identifier
- * @param font
- * the font
- * @param size
- * the size of the font
- * @param orientation
- * the orientation of the font
- */
- public void addFont(byte fontReference, AFPFont font, int size, int orientation)
- throws MaximumSizeExceededException {
-
- FontDefinition fd = new FontDefinition();
-
- fd._fontReferenceKey = fontReference;
-
- switch (orientation) {
- case 90:
- fd._orientation = 0x2D;
- break;
- case 180:
- fd._orientation = 0x5A;
- break;
- case 270:
- fd._orientation = (byte) 0x87;
- break;
- default:
- fd._orientation = 0x00;
- break;
- }
-
- try {
-
- if (font instanceof RasterFont) {
-
- RasterFont raster = (RasterFont) font;
- CharacterSet cs = raster.getCharacterSet(size);
- if (cs == null) {
- String msg = "Character set not found for font "
- + font.getFontName() + " with point size " + size;
- log.error(msg);
- throw new FontRuntimeException(msg);
- }
-
- fd._characterset = cs.getNameBytes();
-
- if (fd._characterset.length != 8) {
- throw new IllegalArgumentException("The character set "
- + new String(fd._characterset,
- AFPConstants.EBCIDIC_ENCODING)
- + " must have a fixed length of 8 characters.");
- }
-
- fd._codepage = cs.getCodePage().getBytes(
- AFPConstants.EBCIDIC_ENCODING);
-
- if (fd._codepage.length != 8) {
- throw new IllegalArgumentException("The code page "
- + new String(fd._codepage,
- AFPConstants.EBCIDIC_ENCODING)
- + " must have a fixed length of 8 characters.");
- }
-
- } else if (font instanceof OutlineFont) {
-
- OutlineFont outline = (OutlineFont) font;
- CharacterSet cs = outline.getCharacterSet();
- fd._characterset = cs.getNameBytes();
-
- // There are approximately 72 points to 1 inch or 20 1440ths per point.
-
- fd._scale = ((size / 1000) * 20);
-
- fd._codepage = cs.getCodePage().getBytes(
- AFPConstants.EBCIDIC_ENCODING);
-
- if (fd._codepage.length != 8) {
- throw new IllegalArgumentException("The code page "
- + new String(fd._codepage,
- AFPConstants.EBCIDIC_ENCODING)
- + " must have a fixed length of 8 characters.");
- }
-
- } else {
- String msg = "Font of type " + font.getClass().getName()
- + " not recognized.";
- log.error(msg);
- throw new FontRuntimeException(msg);
- }
-
- if (_fontlist.size() > 253) {
-
- // Throw an exception if the size is exceeded
- throw new MaximumSizeExceededException();
-
- } else {
-
- _fontlist.add(fd);
-
- }
-
- } catch (UnsupportedEncodingException ex) {
-
- throw new FontRuntimeException("Failed to create font "
- + " due to a UnsupportedEncodingException", ex);
-
- }
-
- }
-
- /**
- * Private utility class used as a container for font attributes
- */
- private class FontDefinition {
-
- /**
- * The code page of the font
- */
- private byte[] _codepage;
-
- /**
- * The character set of the font
- */
- private byte[] _characterset;
-
- /**
- * The font reference key
- */
- private byte _fontReferenceKey;
-
- /**
- * The orientation of the font
- */
- private byte _orientation;
-
- /**
- * The scale (only specified for outline fonts)
- */
- private int _scale = 0;
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Map Page Overlay structured field maps a Resource Local ID to the name of
- * a Begin Overlay structured field. A Map Page Overlay structured field may
- * contain from one to 254 repeating groups.
- *
- */
-public class MapPageOverlay extends AbstractAFPObject {
-
- /**
- * The collection of overlays (maximum of 254 stored as byte[])
- */
- private ArrayList _overLays = new ArrayList();
-
- /**
- * Constructor for the Map Page Overlay
- */
- public MapPageOverlay() {
-
- }
-
- /**
- * Add an overlay to to the map page overlay object.
- *
- * @param name
- * The name of the overlay.
- */
- public void addOverlay(String name) throws MaximumSizeExceededException {
-
- if (_overLays.size() > 253) {
- throw new MaximumSizeExceededException();
- }
-
- if (name.length() != 8) {
- throw new IllegalArgumentException("The name of overlay " + name
- + " must be 8 characters");
- }
-
- if (log.isDebugEnabled()) {
- log.debug("addOverlay():: adding overlay " + name);
- }
-
- byte[] data;
-
- try {
-
- data = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
- _overLays.add(data);
-
- } catch (UnsupportedEncodingException usee) {
-
- log
- .error("addOverlay():: UnsupportedEncodingException translating the name "
- + name);
-
- }
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Map Page Overlay
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
-
- int oLayCount = _overLays.size();
- int recordlength = oLayCount * 18;
-
- byte[] data = new byte[recordlength + 9];
-
- data[0] = 0x5A;
-
- // Set the total record length
- byte[] rl1 = BinaryUtils.convert(recordlength + 8, 2); //Ignore the
- // first byte in
- // the length
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a MPO
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xAB;
- data[5] = (byte) 0xD8;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- int pos = 8;
-
- //For each overlay
- byte olayref = 0x00;
-
- for (int i = 0; i < oLayCount; i++) {
-
- olayref = (byte) (olayref + 1);
-
- data[++pos] = 0x00;
- data[++pos] = 0x12; //the length of repeating group
-
- data[++pos] = 0x0C; //Fully Qualified Name
- data[++pos] = 0x02;
- data[++pos] = (byte) 0x84;
- data[++pos] = 0x00;
-
- //now add the name
- byte[] name = (byte[]) _overLays.get(i);
-
- for (int j = 0; j < name.length; j++) {
-
- data[++pos] = name[j];
-
- }
-
- data[++pos] = 0x04; //Resource Local Identifier (RLI)
- data[++pos] = 0x24;
- data[++pos] = 0x02;
-
- //now add the unique id to the RLI
- data[++pos] = olayref;
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-/**
- * An exception to handle maximum sizes being exceeded.
- *
- */
-public class MaximumSizeExceededException extends Exception {
-
- public MaximumSizeExceededException() {
- super();
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Object Area Descriptor structured field specifies the size and attributes
- * of an object area presentation space.
- *
- */
-public class ObjectAreaDescriptor extends AbstractAFPObject {
-
- private int _width = 0;
- private int _height = 0;
-
- /**
- * Construct an object area descriptor for the specified object width
- * and object height.
- * @param width The page width.
- * @param height The page height.
- */
- public ObjectAreaDescriptor(int width, int height) {
-
- _width = width;
- _height = height;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Object Area Descriptor
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A,
- 0x00, // Length
- 0x1C, // Length
- (byte) 0xD3,
- (byte) 0xA6,
- (byte) 0x6B,
- 0x00, // Flags
- 0x00, // Reserved
- 0x00, // Reserved
- 0x03, // Triplet length
- 0x43, // tid = Descriptor Position Triplet
- 0x01, // DesPosId = 1
- 0x08, // Triplet length
- 0x4B, // tid = Measurement Units Triplet
- 0x00, // XaoBase = 10 inches
- 0x00, // YaoBase = 10 inches
- 0x09, // XaoUnits = 2400
- 0x60, // XaoUnits =
- 0x09, // YaoUnits = 2400
- 0x60, // YaoUnits =
- 0x09, // Triplet length
- 0x4C, // tid = Object Area Size
- 0x02, // Size Type
- 0x00, // XoaSize
- 0x00,
- 0x00,
- 0x00, // YoaSize
- 0x00,
- 0x00,
- };
-
- byte[] l = BinaryUtils.convert(data.length - 1, 2);
- data[1] = l[0];
- data[2] = l[1];
-
- byte[] x = BinaryUtils.convert(_width, 3);
- data[23] = x[0];
- data[24] = x[1];
- data[25] = x[2];
-
- byte[] y = BinaryUtils.convert(_height, 3);
- data[26] = y[0];
- data[27] = y[1];
- data[28] = y[2];
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Object Area Position structured field specifies the origin and
- * orientation of the object area, and the origin and orientation of the
- * object content within the object area.
- */
-public class ObjectAreaPosition extends AbstractAFPObject {
-
- private int _x = 0;
- private int _y = 0;
- private int _rot = 0;
-
- /**
- * Construct an object area position for the specified object y, y position.
- * @param x The x coordinate.
- * @param y The y coordinate.
- * @param rotation The coordinate system rotation (must be 0, 90, 180, 270).
- */
- public ObjectAreaPosition(int x, int y, int rotation) {
-
- _x = x;
- _y = y;
- _rot = rotation;
- }
-
- /**
- * Accessor method to write the AFP datastream for the Object Area Position
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A,
- 0x00, // Length
- 0x20, // Length
- (byte) 0xD3,
- (byte) 0xAC,
- (byte) 0x6B,
- 0x00, // Flags
- 0x00, // Reserved
- 0x00, // Reserved
- 0x01, // OAPosID = 1
- 0x17, // RGLength = 23
- 0x00, // XoaOSet
- 0x00,
- 0x00,
- 0x00, // YoaOSet
- 0x00,
- 0x00,
- (byte)(_rot / 2), // XoaOrent
- 0x00,
- (byte)(_rot / 2 + 45), // YoaOrent
- 0x00,
- 0x00, // Reserved
- 0x00, // XocaOSet
- 0x00,
- 0x00,
- 0x00, // YocaOSet
- 0x00,
- 0x00,
- 0x00, // XocaOrent
- 0x00,
- 0x2D, // YocaOrent
- 0x00,
- 0x01, // RefCSys
- };
-
- byte[] l = BinaryUtils.convert(data.length - 1, 2);
- data[1] = l[0];
- data[2] = l[1];
-
- byte[] x = BinaryUtils.convert(_x, 3);
- data[11] = x[0];
- data[12] = x[1];
- data[13] = x[2];
-
- byte[] y = BinaryUtils.convert(_y, 3);
- data[14] = y[0];
- data[15] = y[1];
- data[16] = y[2];
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-
-/**
- * An Object Environment Group (OEG) may be associated with an object and is contained
- * within the object's begin-end envelope.
- * The object environment group defines the object's origin and orientation on the page,
- * and can contain font and color attribute table information. The scope of an object
- * environment group is the scope of its containing object.
- *
- * An application that creates a data-stream document may omit some of the parameters
- * normally contained in the object environment group, or it may specify that one or
- * more default values are to be used.
- */
-public final class ObjectEnvironmentGroup extends AbstractNamedAFPObject {
-
- /**
- * Default name for the object environment group
- */
- private static final String DEFAULT_NAME = "OEG00001";
-
- /**
- * The ObjectAreaDescriptor for the object environment group
- */
- private ObjectAreaDescriptor _objectAreaDescriptor = null;
-
- /**
- * The ObjectAreaPosition for the object environment group
- */
- private ObjectAreaPosition _objectAreaPosition = null;
-
- /**
- * The ImageDataDescriptor for the object environment group
- */
- private ImageDataDescriptor _imageDataDescriptor = null;
-
- /**
- * Default constructor for the ObjectEnvironmentGroup.
- */
- public ObjectEnvironmentGroup() {
-
- this(DEFAULT_NAME);
-
- }
-
- /**
- * Constructor for the ObjectEnvironmentGroup, this takes a
- * name parameter which must be 8 characters long.
- * @param name the object environment group name
- */
- public ObjectEnvironmentGroup(String name) {
-
- super(name);
-
- }
-
- /**
- * Sets the object area parameters.
- * @param x the x position of the object
- * @param y the y position of the object
- * @param width the object width
- * @param height the object height
- * @param rotation the object orientation
- */
- public void setObjectArea(int x, int y, int width, int height, int rotation) {
-
- _objectAreaDescriptor = new ObjectAreaDescriptor(width, height);
- _objectAreaPosition = new ObjectAreaPosition(x, y, rotation);
-
- }
-
- /**
- * Set the dimensions of the image.
- * @param xresol the x resolution of the image
- * @param yresol the y resolution of the image
- * @param width the image width
- * @param height the image height
- */
- public void setImageData(int xresol, int yresol, int width, int height) {
- _imageDataDescriptor = new ImageDataDescriptor(xresol, yresol, width, height);
- }
-
- /**
- * Accessor method to obtain write the AFP datastream for
- * the object environment group.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
-
- writeStart(os);
-
- _objectAreaDescriptor.writeDataStream(os);
-
- _objectAreaPosition.writeDataStream(os);
-
- if (_imageDataDescriptor != null) {
- _imageDataDescriptor.writeDataStream(os);
- }
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the object environment group.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A, // Structured field identifier
- 0x00, // Length byte 1
- 0x10, // Length byte 2
- (byte) 0xD3, // Structured field id byte 1
- (byte) 0xA8, // Structured field id byte 2
- (byte) 0xC7, // Structured field id byte 3
- 0x00, // Flags
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Name
- 0x00, //
- 0x00, //
- 0x00, //
- 0x00, //
- 0x00, //
- 0x00, //
- 0x00, //
- };
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the object environment group.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xC7; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-
-/**
- */
-public class Overlay extends AbstractPageObject{
-
- /**
- * Construct a new overlay object for the specified name argument, the overlay
- * name should be an 8 character identifier.
- *
- * @param name
- * the name of the page.
- * @param width
- * the width of the page.
- * @param height
- * the height of the page.
- * @param rotation
- * the rotation of the page.
- */
- public Overlay(String name, int width, int height, int rotation) {
-
- super(name, width, height, rotation);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the overlay.
- *
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- _activeEnvironmentGroup.writeDataStream(os);
-
- writeObjectList(_segments, os);
-
- writeObjectList(_tagLogicalElements, os);
-
- writeObjectList(_objects, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the overlay.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xDF; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the overlay.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xDF; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Page Descriptor structured field specifies the size and attributes of
- * a page or overlay presentation space.
- *
- */
-public class PageDescriptor extends AbstractAFPObject {
-
- private int _width = 0;
- private int _height = 0;
-
- /**
- * Construct a page descriptor for the specified page width
- * and page height.
- * @param width The page width.
- * @param height The page height.
- */
- public PageDescriptor(int width, int height) {
-
- _width = width;
- _height = height;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Page Descriptor
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A,
- 0x00,
- 0x17,
- (byte) 0xD3,
- (byte) 0xA6,
- (byte) 0xAF,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x09,
- 0x60,
- 0x09,
- 0x60,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- };
-
- byte[] x = BinaryUtils.convert(_width, 3);
- data[15] = x[0];
- data[16] = x[1];
- data[17] = x[2];
-
- byte[] y = BinaryUtils.convert(_height, 3);
- data[18] = y[0];
- data[19] = y[1];
- data[20] = y[2];
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A page group is used in the data stream to define a named, logical grouping
- * of sequential pages. Page groups are delimited by begin-end structured fields
- * that carry the name of the page group. Page groups are defined so that the
- * pages that comprise the group can be referenced or processed as a single
- * entity. Page groups are often processed in stand-alone fashion; that is, they
- * are indexed, retrieved, and presented outside the context of the containing
- * document.
- *
- * @author <a href="mailto:pete@townsend.uk.com">Pete Townsend </a>
- */
-public class PageGroup extends AbstractNamedAFPObject {
-
- /**
- * The pages contained within this group
- */
- private List _objects = new ArrayList();
-
- /**
- * The tag logical elements contained within this group
- */
- private List _tagLogicalElements = new ArrayList();
-
- /**
- * The page state
- */
- private boolean _complete = false;
-
- /**
- * Constructor for the PageGroup.
- *
- * @param name
- * the name of the page group
- */
- public PageGroup(String name) {
-
- super(name);
-
- }
-
- /**
- * Adds a page object to the group.
- *
- * @param page
- * the page object to add
- */
- public void addPage(PageObject page) {
-
- if (!_objects.contains(page)) {
- _objects.add(page);
- }
-
- }
-
- /**
- * @return the name of the page group
- */
- public String getName() {
- return _name;
- }
-
- /**
- * Creates a TagLogicalElement on the page.
- *
- * @param name
- * the name of the tag
- * @param value
- * the value of the tag
- */
- public void createTagLogicalElement(String name, String value) {
-
- TagLogicalElement tle = new TagLogicalElement(name, value);
- _tagLogicalElements.add(tle);
-
- }
-
- /**
- * Creates an InvokeMediaMap on the page.
- *
- * @param name
- * the name of the media map
- */
- public void createInvokeMediumMap(String name) {
-
- InvokeMediumMap imm = new InvokeMediumMap(name);
- _objects.add(imm);
-
- }
-
- /**
- * Method to mark the end of the page group.
- */
- public void endPageGroup() {
-
- _complete = true;
-
- }
-
- /**
- * Returns an indication if the page group is complete
- */
- public boolean isComplete() {
- return _complete;
- }
-
- /**
- * Accessor method to write the AFP datastream for the page group.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(_tagLogicalElements, os);
-
- writeObjectList(_objects, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the page group.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xAD; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the page group.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xAD; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-import java.io.IOException;
-import java.io.OutputStream;
-
-
-
-/**
- * Pages contain the data objects that comprise a presentation document. Each
- * page has a set of data objects associated with it. Each page within a
- * document is independent from any other page, and each must establish its own
- * environment parameters.
- *
- * The page is the level in the document component hierarchy that is used for
- * printing or displaying a document's content. The data objects contained in
- * the page envelope in the data stream are presented when the page is
- * presented. Each data object has layout information associated with it that
- * directs the placement and orientation of the data on the page. In addition,
- * each page contains layout information that specifies the measurement units,
- * page width, and page depth.
- *
- * A page is initiated by a begin page structured field and terminated by an end
- * page structured field. Structured fields that define objects and active
- * environment groups or that specify attributes of the page may be encountered
- * in page state.
- *
- */
-public class PageObject extends AbstractPageObject {
-
- /**
- * The resource group object
- */
- private ResourceGroup _resourceGroup = null;
-
- /**
- * Construct a new page object for the specified name argument, the page
- * name should be an 8 character identifier.
- *
- * @param name
- * the name of the page.
- * @param width
- * the width of the page.
- * @param height
- * the height of the page.
- * @param rotation
- * the rotation of the page.
- */
- public PageObject(String name, int width, int height, int rotation) {
-
- super(name, width, height, rotation);
-
- }
-
- /**
- * Adds an overlay to the page resources
- * @param overlay the overlay to add
- */
- public void addOverlay(Overlay overlay) {
- if (_resourceGroup == null) {
- _resourceGroup = new ResourceGroup();
- }
- _resourceGroup.addOverlay(overlay);
- }
-
- /**
- * Creates an IncludePageOverlay on the page.
- *
- * @param name
- * the name of the overlay
- * @param x
- * the x position of the overlay
- * @param y
- * the y position of the overlay
- * @param orientation
- * the orientation required for the overlay
- */
- public void createIncludePageOverlay(String name, int x, int y, int orientation) {
-
- IncludePageOverlay ipo = new IncludePageOverlay(name, x, y, orientation);
- _objects.add(ipo);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the page.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- if (_resourceGroup != null) {
- _resourceGroup.writeDataStream(os);
- }
-
- _activeEnvironmentGroup.writeDataStream(os);
-
- writeObjectList(_segments, os);
-
- writeObjectList(_tagLogicalElements, os);
-
- writeObjectList(_objects, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the page.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xAF; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the page.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xAF; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.awt.Color;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * Presentation text data contains the graphic characters and the control
- * sequences necessary to position the characters within the object space. The
- * data consists of: - graphic characters to be presented - control sequences
- * that position them - modal control sequences that adjust the positions by
- * small amounts - other functions causing text to be presented with differences
- * in appearance.
- *
- * The graphic characters are expected to conform to a coded font representation
- * so that they can be translated from the code point in the object data to the
- * character in the coded font. The units of measure for linear displacements
- * are derived from the PresentationTextDescriptor or from the hierarchical
- * defaults.
- *
- * In addition to graphic character code points, Presentation Text data can
- * contain embedded control sequences. These are strings of two or more bytes
- * which signal an alternate mode of processing for the content of the current
- * Presentation Text data.
- *
- */
-public class PresentationTextData extends AbstractAFPObject {
-
- /**
- * The maximum size of the presentation text data.
- */
- private static final int MAX_SIZE = 8192;
-
- /**
- * The afp data relating to this presentaion text data.
- */
- private ByteArrayOutputStream _baos = new ByteArrayOutputStream(1024);
-
- /**
- * The current x coordinate.
- */
- private int _currentXCoordinate = -1;
-
- /**
- * The current y cooridnate
- */
- private int _currentYCoordinate = -1;
-
- /**
- * The current font
- */
- private String _currentFont = "";
-
- /**
- * The current orientation
- */
- private int _currentOrientation = 0;
-
- /**
- * The current color
- */
- private Color _currentColor = new Color(0, 0, 0);
-
- /**
- * The current variable space increment
- */
- private int _currentVariableSpaceCharacterIncrement = 0;
-
- /**
- * The current inter character adjustment
- */
- private int _currentInterCharacterAdjustment = 0;
-
- /**
- * Default constructor for the PresentationTextData.
- */
- public PresentationTextData() {
-
- this(false);
-
- }
-
- /**
- * Constructor for the PresentationTextData, the boolean flag indicate
- * whether the control sequence prefix should be set to indicate the start
- * of a new control sequence.
- *
- * @param controlInd
- * The control sequence indicator.
- */
- public PresentationTextData(boolean controlInd) {
-
- _baos.write(new byte[] { 0x5A, // Structured field identifier
- 0x00, // Record length byte 1
- 0x00, // Record length byte 2
- (byte) 0xD3, // PresentationTextData identifier byte 1
- (byte) 0xEE, // PresentationTextData identifier byte 2
- (byte) 0x9B, // PresentationTextData identifier byte 3
- 0x00, // Flag
- 0x00, // Reserved
- 0x00, // Reserved
- }, 0, 9);
-
- if (controlInd) {
- _baos.write(new byte[] { 0x2B, (byte) 0xD3 }, 0, 2);
- }
-
- }
-
- /**
- * The Set Coded Font Local control sequence activates a coded font and
- * specifies the character attributes to be used. This is a modal control
- * sequence.
- *
- * @param font
- * The font local identifier.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void setCodedFont(byte font, ByteArrayOutputStream afpdata) {
-
- // Avoid unnecessary specification of the font
- if (String.valueOf(font).equals(_currentFont)) {
- return;
- } else {
- _currentFont = String.valueOf(font);
- }
-
- afpdata.write(new byte[] { 0x03, (byte) 0xF1, font, }, 0, 3);
-
- }
-
- /**
- * Establishes the current presentation position on the baseline at a new
- * I-axis coordinate, which is a specified number of measurement units from
- * the B-axis. There is no change to the current B-axis coordinate.
- *
- * @param coordinate
- * The coordinate for the inline move.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void absoluteMoveInline(int coordinate,
- ByteArrayOutputStream afpdata) {
-
- byte[] b = BinaryUtils.convert(coordinate, 2);
-
- afpdata.write(new byte[] { 0x04, (byte) 0xC7, b[0], b[1], }, 0, 4);
-
- _currentXCoordinate = coordinate;
-
- }
-
- /**
- * Establishes the baseline and the current presentation position at a new
- * B-axis coordinate, which is a specified number of measurement units from
- * the I-axis. There is no change to the current I-axis coordinate.
- *
- * @param coordinate
- * The coordinate for the baseline move.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void absoluteMoveBaseline(int coordinate,
- ByteArrayOutputStream afpdata) {
-
- byte[] b = BinaryUtils.convert(coordinate, 2);
-
- afpdata.write(new byte[] { 0x04, (byte) 0xD3, b[0], b[1], }, 0, 4);
-
- _currentYCoordinate = coordinate;
-
- }
-
- /**
- * The Transparent Data control sequence contains a sequence of code points
- * that are presented without a scan for embedded control sequences.
- *
- * @param data
- * The text data to add.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void addTransparentData(byte[] data, ByteArrayOutputStream afpdata) {
-
- // Calculate the length
- int l = data.length + 2;
-
- if (l > 255) {
- // Check that we are not exceeding the maximum length
- throw new IllegalArgumentException(
- "Transparent data is longer than 253 bytes: " + data);
- }
-
- afpdata.write(new byte[] { BinaryUtils.convert(l)[0], (byte) 0xDB, },
- 0, 2);
-
- afpdata.write(data, 0, data.length);
-
- }
-
- /**
- * Draws a line of specified length and specified width in the B-direction
- * from the current presentation position. The location of the current
- * presentation position is unchanged.
- *
- * @param length
- * The length of the rule.
- * @param width
- * The width of the rule.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void drawBaxisRule(int length, int width,
- ByteArrayOutputStream afpdata) {
-
- afpdata.write(new byte[] { 0x07, // Length
- (byte) 0xE7, // Type
- }, 0, 2);
-
- // Rule length
- byte[] data1 = BinaryUtils.shortToByteArray((short) length);
- afpdata.write(data1, 0, data1.length);
- // Rule width
- byte[] data2 = BinaryUtils.shortToByteArray((short) width);
- afpdata.write(data2, 0, data2.length);
- // Rule width fraction
- afpdata.write(0x00);
-
- }
-
- /**
- * Draws a line of specified length and specified width in the I-direction
- * from the current presentation position. The location of the current
- * presentation position is unchanged.
- *
- * @param length
- * The length of the rule.
- * @param width
- * The width of the rule.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void drawIaxisRule(int length, int width,
- ByteArrayOutputStream afpdata) {
-
- afpdata.write(new byte[] { 0x07, // Length
- (byte) 0xE5, // Type
- }, 0, 2);
-
- // Rule length
- byte[] data1 = BinaryUtils.shortToByteArray((short) length);
- afpdata.write(data1, 0, data1.length);
- // Rule width
- byte[] data2 = BinaryUtils.shortToByteArray((short) width);
- afpdata.write(data2, 0, data2.length);
- // Rule width fraction
- afpdata.write(0x00);
-
- }
-
- /**
- * Create the presentation text data for the byte array of data.
- *
- * @param fontNumber
- * The font resource identifier.
- * @param x
- * The x coordinate for the text data.
- * @param y
- * The y coordinate for the text data.
- * @param orientation
- * The orientation of the text data.
- * @param col
- * The text color.
- * @param vsci
- * The variable space character increment.
- * @param ica
- * The inter character adjustment.
- * @param data
- * The text data to be created.
- * @throws MaximumSizeExceededException
- */
- public void createTextData(int fontNumber, int x, int y, int orientation,
- Color col, int vsci, int ica, byte[] data)
- throws MaximumSizeExceededException {
-
- ByteArrayOutputStream afpdata = new ByteArrayOutputStream();
-
- if (_currentOrientation != orientation) {
- setTextOrientation(orientation, afpdata);
- _currentOrientation = orientation;
- _currentXCoordinate = -1;
- _currentYCoordinate = -1;
- }
-
- // Avoid unnecessary specification of the Y co-ordinate
- if (y != _currentYCoordinate) {
- absoluteMoveBaseline(y, afpdata);
- _currentXCoordinate = -1;
- }
-
- // Avoid unnecessary specification of the X co-ordinate
- if (x != _currentXCoordinate) {
- absoluteMoveInline(x, afpdata);
- }
-
- // Avoid unnecessary specification of the variable space increment
- if (vsci != _currentVariableSpaceCharacterIncrement) {
- setVariableSpaceCharacterIncrement(vsci, afpdata);
- _currentVariableSpaceCharacterIncrement = vsci;
- }
-
- // Avoid unnecessary specification of the inter character adjustment
- if (ica != _currentInterCharacterAdjustment) {
- setInterCharacterAdjustment(ica, afpdata);
- _currentInterCharacterAdjustment = ica;
- }
-
- // Avoid unnecessary specification of the text color
- if (!col.equals(_currentColor)) {
- setExtendedTextColor(col, afpdata);
- _currentColor = col;
- }
-
- setCodedFont(BinaryUtils.convert(fontNumber)[0], afpdata);
- addTransparentData(data, afpdata);
- _currentXCoordinate = -1;
-
- int s = afpdata.size();
-
- if (_baos.size() + s > MAX_SIZE) {
- _currentXCoordinate = -1;
- _currentYCoordinate = -1;
- throw new MaximumSizeExceededException();
- }
-
- byte[] outputdata = afpdata.toByteArray();
- _baos.write(outputdata, 0, outputdata.length);
-
- }
-
- /**
- * Drawing of lines using the starting and ending coordinates, thickness and
- * colour arguments.
- *
- * @param x1
- * The starting X coordinate.
- * @param y1
- * The starting Y coordinate.
- * @param x2
- * The ending X coordinate.
- * @param y2
- * The ending Y coordinate.
- * @param thickness
- * The line thickness.
- * @param orientation
- * The orientation of the text data.
- * @param col
- * The text color.
- */
- public void createLineData(int x1, int y1, int x2, int y2, int thickness,
- int orientation, Color col) throws MaximumSizeExceededException {
-
- ByteArrayOutputStream afpdata = new ByteArrayOutputStream();
-
- if (_currentOrientation != orientation) {
- setTextOrientation(orientation, afpdata);
- _currentOrientation = orientation;
- }
-
- // Avoid unnecessary specification of the Y coordinate
- if (y1 != _currentYCoordinate) {
- absoluteMoveBaseline(y1, afpdata);
- }
-
- // Avoid unnecessary specification of the X coordinate
- if (x1 != _currentXCoordinate) {
- absoluteMoveInline(x1, afpdata);
- }
-
- if (!col.equals(_currentColor)) {
- setExtendedTextColor(col, afpdata);
- _currentColor = col;
- }
-
- if (y1 == y2) {
- drawIaxisRule(x2 - x1, thickness, afpdata);
- } else if (x1 == x2) {
- drawBaxisRule(y2 - y1, thickness, afpdata);
- } else {
- return;
- }
-
- int s = afpdata.size();
-
- if (_baos.size() + s > MAX_SIZE) {
- _currentXCoordinate = -1;
- _currentYCoordinate = -1;
- throw new MaximumSizeExceededException();
- }
-
- byte[] outputdata = afpdata.toByteArray();
- _baos.write(outputdata, 0, outputdata.length);
-
- }
-
- /**
- * The Set Text Orientation control sequence establishes the I-direction and
- * B-direction for the subsequent text. This is a modal control sequence.
- *
- * Semantics: This control sequence specifies the I-axis and B-axis
- * orientations with respect to the Xp-axis for the current Presentation
- * Text object. The orientations are rotational values expressed in degrees
- * and minutes.
- *
- * @param orientation
- * The text orientation (0,90, 180, 270).
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void setTextOrientation(int orientation,
- ByteArrayOutputStream afpdata) {
-
- afpdata.write(new byte[] { 0x06, (byte) 0xF7, }, 0, 2);
-
- switch (orientation) {
- case 90:
- afpdata.write(0x2D);
- afpdata.write(0x00);
- afpdata.write(0x5A);
- afpdata.write(0x00);
- break;
- case 180:
- afpdata.write(0x5A);
- afpdata.write(0x00);
- afpdata.write(0x87);
- afpdata.write(0x00);
- break;
- case 270:
- afpdata.write(0x87);
- afpdata.write(0x00);
- afpdata.write(0x00);
- afpdata.write(0x00);
- break;
- default:
- afpdata.write(0x00);
- afpdata.write(0x00);
- afpdata.write(0x2D);
- afpdata.write(0x00);
- break;
- }
-
- }
-
- /**
- * The Set Extended Text Color control sequence specifies a color value and
- * defines the color space and encoding for that value. The specified color
- * value is applied to foreground areas of the text presentation space.
- * This is a modal control sequence.
- *
- * @param col
- * The color to be set.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void setExtendedTextColor(Color col,
- ByteArrayOutputStream afpdata) {
-
- afpdata.write(new byte[] {
- 15 // Control sequence length
- , (byte)0x81 // Control sequence function type
- , 0x00 // Reserved; must be zero
- , 0x01 // Color space - 0x01 = RGB
- , 0x00 // Reserved; must be zero
- , 0x00 // Reserved; must be zero
- , 0x00 // Reserved; must be zero
- , 0x00 // Reserved; must be zero
- , 8 // Number of bits in component 1
- , 8 // Number of bits in component 2
- , 8 // Number of bits in component 3
- , 0 // Number of bits in component 4
- , (byte)(col.getRed()) // Red intensity
- , (byte)(col.getGreen()) // Green intensity
- , (byte)(col.getBlue()) // Blue intensity
- }, 0, 15);
-
- }
-
- /**
- * //TODO
- * This is a modal control sequence.
- *
- * @param incr
- * The increment to be set.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void setVariableSpaceCharacterIncrement(int incr,
- ByteArrayOutputStream afpdata) {
-
- byte[] b = BinaryUtils.convert(incr, 2);
-
- afpdata.write(new byte[] {
- 4 // Control sequence length
- , (byte)0xC5 // Control sequence function type
- , b[0]
- , b[1]
- }, 0, 4);
-
- }
-
- /**
- * //TODO
- * This is a modal control sequence.
- *
- * @param incr
- * The increment to be set.
- * @param afpdata
- * The output stream to which data should be written.
- */
- private void setInterCharacterAdjustment(int incr,
- ByteArrayOutputStream afpdata) {
-
- byte[] b = BinaryUtils.convert(Math.abs(incr), 2);
-
- afpdata.write(new byte[] {
- 5 // Control sequence length
- , (byte)0xC3 // Control sequence function type
- , b[0]
- , b[1]
- , (byte)(incr >= 0 ? 0 : 1) // Direction
- }, 0, 5);
-
- }
-
- /**
- * Accessor method to write the AFP datastream for
- * the text data.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = _baos.toByteArray();
- byte[] size = BinaryUtils.convert(data.length - 1, 2);
- data[1] = size[0];
- data[2] = size[1];
-
- os.write(data);
-
- }
-
- /**
- * A control sequence is a sequence of bytes that specifies a control
- * function. A control sequence consists of a control sequence introducer
- * and zero or more parameters. The control sequence can extend multiple
- * presentation text data objects, but must eventually be terminated. This
- * method terminates the control sequence.
- *
- * @throws MaximumSizeExceededException
- */
- public void endControlSequence() throws MaximumSizeExceededException {
-
- byte[] data = new byte[2];
- data[0] = 0x02;
- data[1] = (byte) 0xF8;
-
- if (data.length + _baos.size() > MAX_SIZE) {
- throw new MaximumSizeExceededException();
- }
-
- _baos.write(data, 0, data.length);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * The Presentation Text Descriptor specifies the units of measure for the
- * Presentation Text object space, the size of the Presentation Text object
- * space, and the initial values for modal parameters, called initial text
- * conditions. Initial values not provided are defaulted by the controlling
- * environment or the receiving device.
- *
- * The Presentation Text Descriptor provides the following initial values:
- * - Unit base
- * - Xp-units per unit base
- * - Yp-units per unit base
- * - Xp-extent of the presentation space
- * - Yp-extent of the presentation space
- * - Initial text conditions.
- *
- * The initial text conditions are values provided by the Presentation Text
- * Descriptor to initialize the modal parameters of the control sequences.
- * Modal control sequences typically are characterized by the word set in
- * the name of the control sequence. Modal parameters are identified as such
- * in their semantic descriptions.
- *
- */
-public class PresentationTextDescriptor extends AbstractAFPObject {
-
- private int _width = 0;
- private int _height = 0;
-
- /**
- * Constructor a PresentationTextDescriptor for the specified
- * width and height.
- * @param width The width of the page.
- * @param height The height of the page.
- */
- public PresentationTextDescriptor(int width, int height) {
-
- _width = width;
- _height = height;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the Presentation Text Descriptor
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[] {
- 0x5A,
- 0x00,
- 0x16,
- (byte) 0xD3,
- (byte) 0xB1,
- (byte) 0x9B,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x09,
- 0x60,
- 0x09,
- 0x60,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- };
-
- byte[] x = BinaryUtils.convert(_width, 3);
- data[15] = x[0];
- data[16] = x[1];
- data[17] = x[2];
-
- byte[] y = BinaryUtils.convert(_height, 3);
- data[18] = y[0];
- data[19] = y[1];
- data[20] = y[2];
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.awt.Color;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-
-/**
- * The Presentation Text object is the data object used in document processing
- * environments for representing text which has been prepared for presentation.
- * Text, as used here, means an ordered string of characters, such as graphic
- * symbols, numbers, and letters, that are suitable for the specific purpose of
- * representing coherent information. Text which has been prepared for
- * presentation has been reduced to a primitive form through explicit
- * specification of the characters and their placement in the presentation
- * space. Control sequences which designate specific control functions may be
- * embedded within the text. These functions extend the primitive form by
- * applying specific characteristics to the text when it is presented. The
- * collection of the graphic characters and control codes is called Presentation
- * Text, and the object that contains the Presentation Text is called the
- * PresentationText object.
- *
- */
-public class PresentationTextObject extends AbstractNamedAFPObject {
-
- /**
- * Default name for the presentation text object
- */
- private static final String DEFAULT_NAME = "PTO00001";
-
- private PresentationTextData currentPresentationTextData = null;
-
- private ArrayList presentationTextData = new ArrayList();
-
- /**
- * Default constructor for the PresentationTextObject
- */
- public PresentationTextObject() {
-
- this(DEFAULT_NAME);
-
- }
-
- /**
- * Construct a new PresentationTextObject for the specified name argument,
- * the name should be an 8 character identifier.
- */
- public PresentationTextObject(String name) {
-
- super(name);
-
- }
-
- /**
- * Create the presentation text data for the byte array of data.
- *
- * @param fontNumber
- * The font resource identifier.
- * @param x
- * The x coordinate for the text data.
- * @param y
- * The y coordinate for the text data.
- * @param col
- * The text color.
- * @param vsci
- * The variable space character increment.
- * @param ica
- * The inter character increment.
- * @param data
- * The text data to be created.
- */
- public void createTextData(int fontNumber, int x, int y, Color col, int vsci, int ica, byte[] data) {
-
- // Use a default orientation of zero
- createTextData(fontNumber, x, y, 0, col, vsci, ica, data);
-
- }
-
- /**
- * Create the presentation text data for the byte array of data.
- *
- * @param fontNumber
- * The font resource identifier.
- * @param x
- * The x coordinate for the text data.
- * @param y
- * The y coordinate for the text data.
- * @param orientation
- * The orientation of the text data.
- * @param col
- * The text color.
- * @param vsci
- * The variable space character increment.
- * @param ica
- * The inter character adjustment.
- * @param data
- * The text data to be created.
- */
- public void createTextData(int fontNumber, int x, int y, int orientation,
- Color col, int vsci, int ica, byte[] data) {
-
- if (currentPresentationTextData == null) {
- startPresentationTextData();
- }
-
- try {
-
- currentPresentationTextData.createTextData(fontNumber, x, y,
- orientation, col, vsci, ica, data);
-
- } catch (MaximumSizeExceededException msee) {
-
- endPresentationTextData();
- createTextData(fontNumber, x, y, orientation, col, vsci, ica, data);
-
- }
-
- }
-
- /**
- * Drawing of lines using the starting and ending coordinates, thickness.
- *
- * @param x1
- * The first x coordinate of the line.
- * @param y1
- * The first y coordinate of the line.
- * @param x2
- * The second x coordinate of the line.
- * @param y2
- * The second y coordinate of the line.
- * @param thickness
- * The thickness of the line.
- * @param col
- * The text color.
- */
- public void createLineData(int x1, int y1, int x2, int y2, int thickness, Color col) {
- // Default orientation
- createLineData(x1, y1, x2, y2, thickness, 0, col);
- }
-
- /**
- * Drawing of lines using the starting and ending coordinates, thickness and
- * orientation arguments.
- *
- * @param x1
- * The first x coordinate of the line.
- * @param y1
- * The first y coordinate of the line.
- * @param x2
- * The second x coordinate of the line.
- * @param y2
- * The second y coordinate of the line.
- * @param thickness
- * The thickness of the line.
- * @param orientation
- * The orientation of the line.
- * @param col
- * The text color.
- */
- public void createLineData(int x1, int y1, int x2, int y2, int thickness,
- int orientation, Color col) {
-
- if (currentPresentationTextData == null) {
- startPresentationTextData();
- }
-
- try {
-
- currentPresentationTextData.createLineData(x1, y1, x2, y2,
- thickness, orientation, col);
-
- } catch (MaximumSizeExceededException msee) {
-
- endPresentationTextData();
- createLineData(x1, y1, x2, y2, thickness, orientation, col);
-
- }
-
- }
-
- /**
- * Helper method to mark the start of the presentation text data
- */
- private void startPresentationTextData() {
-
- if (presentationTextData.size() == 0) {
- currentPresentationTextData = new PresentationTextData(true);
- } else {
- currentPresentationTextData = new PresentationTextData();
- }
-
- presentationTextData.add(currentPresentationTextData);
-
- }
-
- /**
- * Helper method to mark the end of the presentation text data
- */
- private void endPresentationTextData() {
-
- currentPresentationTextData = null;
-
- }
-
- /**
- * Accessor method to write the AFP datastream for the PresentationTextObject.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(presentationTextData, os);
-
- writeEnd(os);
-
- }
-
- public String getName() {
-
- return _name;
-
- }
-
- /**
- * Helper method to write the start of the presenation text object.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0x9B; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the presenation text object.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0x9B; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * A control sequence is a sequence of bytes that specifies a control
- * function. A control sequence consists of a control sequence introducer
- * and zero or more parameters. The control sequence can extend multiple
- * presentation text data objects, but must eventually be terminated. This
- * method terminates the control sequence.
- */
- public void endControlSequence() {
-
- if (currentPresentationTextData == null) {
- startPresentationTextData();
- }
-
- try {
-
- currentPresentationTextData.endControlSequence();
-
- } catch (MaximumSizeExceededException msee) {
-
- endPresentationTextData();
- endControlSequence();
-
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A Resource Group contains a set of overlays.
- */
-public final class ResourceGroup extends AbstractNamedAFPObject {
-
- /**
- * Default name for the resource group
- */
- private static final String DEFAULT_NAME = "RG000001";
-
-
- /**
- * The overlays contained in this resource group
- */
- private List _overlays = new ArrayList();
-
- public ResourceGroup() {
-
- this(DEFAULT_NAME);
-
- }
-
- /**
- * Constructor for the ResourceGroup, this takes a
- * name parameter which must be 8 characters long.
- * @param name the resource group name
- */
- public ResourceGroup(String name) {
-
- super(name);
-
- }
-
- /**
- * Adds an overlay to the resource group
- * @param overlay the overlay to add
- */
- public void addOverlay(Overlay overlay) {
- _overlays.add(overlay);
- }
-
- /**
- * Returns the list of overlays
- * @return the list of overlays
- */
- public List getOverlays() {
- return _overlays;
- }
-
- /**
- * Accessor method to obtain write the AFP datastream for
- * the resource group.
- * @param os The stream to write to
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os)
- throws IOException {
-
- writeStart(os);
-
- writeObjectList(_overlays, os);
-
- writeEnd(os);
-
- }
-
- /**
- * Helper method to write the start of the resource group.
- * @param os The stream to write to
- */
- private void writeStart(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA8; // Structured field id byte 2
- data[5] = (byte) 0xC6; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
- /**
- * Helper method to write the end of the resource group.
- * @param os The stream to write to
- */
- private void writeEnd(OutputStream os)
- throws IOException {
-
- byte[] data = new byte[17];
-
- data[0] = 0x5A; // Structured field identifier
- data[1] = 0x00; // Length byte 1
- data[2] = 0x10; // Length byte 2
- data[3] = (byte) 0xD3; // Structured field id byte 1
- data[4] = (byte) 0xA9; // Structured field id byte 2
- data[5] = (byte) 0xC6; // Structured field id byte 3
- data[6] = 0x00; // Flags
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- for (int i = 0; i < _nameBytes.length; i++) {
-
- data[9 + i] = _nameBytes[i];
-
- }
-
- os.write(data);
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-import org.apache.fop.render.afp.tools.BinaryUtils;
-
-/**
- * A Tag Logical Element structured field assigns an attribute name and an
- * attribute value to a page or page group. The Tag Logical Element structured
- * field may be embedded directly in the page or page group, or it may reference
- * the page or page group from a document index. When a Tag Logical Element
- * structured field references a page or is embedded in a page following the
- * active environment group, it is associated with the page. When a Tag Logical
- * Element structured field references a page group or is embedded in a page
- * group following the Begin Named Page Group structured field, it is associated
- * with the page group. When a Tag Logical Element structured field is associated
- * with a page group, the parameters of the Tag Logical Element structured field
- * are inherited by all pages in the page group and by all other page groups
- * that are nested in the page group. The scope of a Tag Logical Element is
- * determined by its position with respect to other TLEs that reference, or are
- * embedded in, the same page or page group. The Tag Logical Element structured
- * field does not provide any presentation specifications and therefore has no
- * effect on the appearance of a document when it is presented.
- * <p/>
- */
-public class TagLogicalElement extends AbstractAFPObject {
-
- /**
- * Name of the key, used within the TLE
- */
- private String _tleName = null;
-
- /**
- * Value returned by the key
- */
- private String _tleValue = null;
-
- /**
- * Byte representaion of the name
- */
- private byte[] _tleByteName = null;
-
- /**
- * Byte representaion of the value
- */
- private byte[] _tleByteValue = null;
-
- /**
- * Construct a tag logical element with the name and value specified.
- * @param name the name of the tag logical element
- * @param value the value of the tag logical element
- */
- public TagLogicalElement(String name, String value) {
-
- _tleName = name;
- _tleValue = value;
-
- try {
-
- _tleByteName = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
- _tleByteValue = value.getBytes(AFPConstants.EBCIDIC_ENCODING);
-
- } catch (UnsupportedEncodingException usee) {
-
- _tleByteName = name.getBytes();
- _tleByteValue = value.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
-
- }
-
- }
-
- /**
- * Accessor method to obtain the byte array AFP datastream for the
- * TagLogicalElement.
- * @param os The outputsteam stream
- * @throws java.io.IOException
- */
- public void writeDataStream(OutputStream os) throws IOException {
-
- byte[] data = new byte[17 + _tleName.length() + _tleValue.length()];
-
- data[0] = 0x5A;
- // Set the total record length
- byte[] rl1 =
- BinaryUtils.convert(16 + _tleName.length() + _tleValue.length(), 2);
- //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a TLE
- data[3] = (byte) 0xD3;
- data[4] = (byte) 0xA0;
- data[5] = (byte) 0x90;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- //Use 2 triplets, attrubute name and value (the key for indexing)
-
- byte[] rl2 = BinaryUtils.convert(_tleName.length() + 4, 1);
- data[9] = rl2[0]; // length of the triplet, including this field
- data[10] = 0x02; //Identifies it as a FQN triplet
- data[11] = 0x0B; // GID format
- data[12] = 0x00;
-
- int pos = 13;
- for (int i = 0; i < _tleByteName.length; i++) {
- data[pos++] = _tleByteName[i];
- }
-
- byte[] rl3 = BinaryUtils.convert(_tleByteValue.length + 4, 1);
- data[pos++] = rl3[0]; // length of the triplet, including this field
- data[pos++] = 0x36; //Identifies the triplet, attribute value
- data[pos++] = 0x00; // Reserved
- data[pos++] = 0x00; // Reserved
-
- for (int i = 0; i < _tleByteValue.length; i++) {
- data[pos++] = _tleByteValue[i];
- }
- os.write(data);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.modca;
-
-/**
- * The TagLogicalElementBean provides a bean for holding the attributes of
- * a tag logical element as key value pairs.
- * <p/>
- */
-public class TagLogicalElementBean {
-
- /** The key attribute */
- private String _key;
-
- /** The value attribute */
- private String _value;
-
- /**
- * Constructor for the TagLogicalElementBean.
- * @param key the key attribute
- * @param value the value attribute
- */
- public TagLogicalElementBean(String key, String value) {
- _key = key;
- _value = value;
- }
-
- /**
- * Getter for the key attribute.
- * @return the key
- */
- public String getKey() {
- return _key;
- }
-
- /**
- * Getter for the value attribute.
- * @return the value
- */
- public String getValue() {
- return _value;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.tools;
-
-import java.io.ByteArrayOutputStream;
-
-/**
- * Library of utility useful conversion methods.
- *
- */
-public final class BinaryUtils {
-
- /**
- * Convert an int into the corresponding byte array by encoding each
- * two hexadecimal digits as a char. This will return a byte array
- * to the length specified by bufsize.
- * @param integer The int representation.
- * @param bufsize The required byte array size.
- */
- public static byte[] convert(int integer, int bufsize) {
-
- StringBuffer buf = new StringBuffer(Integer.toHexString(integer));
- if (buf.length() % 2 == 0) {
- // Ignore even number of digits
- } else {
- // Convert to an even number of digits
- buf.insert(0, "0");
- }
- int size = buf.length() / 2;
- while (size < bufsize) {
- buf.insert(0, "00");
- size++;
- };
- return convert(buf.toString());
-
- }
-
- /**
- * Convert an int into the corresponding byte array by encoding each
- * two hexadecimal digits as a char.
- * @param integer The int representation
- */
- public static byte[] convert(int integer) {
-
- return convert(Integer.toHexString(integer));
-
- }
-
- /**
- * Convert a String of hexadecimal digits into the corresponding
- * byte array by encoding each two hexadecimal digits as a byte.
- * @param digits The hexadecimal digits representation.
- */
- public static byte[] convert(String digits) {
-
- if (digits.length() % 2 == 0) {
- // Even number of digits, so ignore
- } else {
- // Convert to an even number of digits
- digits = "0" + digits;
- }
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- for (int i = 0; i < digits.length(); i += 2) {
- char c1 = digits.charAt(i);
- char c2 = digits.charAt(i + 1);
- byte b = 0;
- if ((c1 >= '0') && (c1 <= '9'))
- b += ((c1 - '0') * 16);
- else if ((c1 >= 'a') && (c1 <= 'f'))
- b += ((c1 - 'a' + 10) * 16);
- else if ((c1 >= 'A') && (c1 <= 'F'))
- b += ((c1 - 'A' + 10) * 16);
- else
- throw new IllegalArgumentException("Bad hexadecimal digit");
- if ((c2 >= '0') && (c2 <= '9'))
- b += (c2 - '0');
- else if ((c2 >= 'a') && (c2 <= 'f'))
- b += (c2 - 'a' + 10);
- else if ((c2 >= 'A') && (c2 <= 'F'))
- b += (c2 - 'A' + 10);
- else
- throw new IllegalArgumentException("Bad hexadecimal digit");
- baos.write(b);
- }
- return (baos.toByteArray());
-
- }
-
- /**
- * Convert the specified short into a byte array.
- * @param value The value to be converted.
- * @param array The array to receive the data.
- * @param offset The offset into the byte array for the start of the value.
- */
- public static void shortToByteArray(
- short value,
- byte[] array,
- int offset) {
- array[offset] = (byte) (value >>> 8);
- array[offset + 1] = (byte) value;
- }
-
- /**
- * Convert the specified short into a byte array.
- * @param value The value to be converted.
- * @return The byte array
- */
- public static byte[] shortToByteArray(short value) {
- byte[] serverValue = new byte[2];
- shortToByteArray(value, serverValue, 0);
- return serverValue;
- }
-
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.tools;
-
-import java.io.IOException;
-import java.net.URL;
-
-import org.apache.fop.render.afp.exceptions.FontRuntimeException;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-/**
- * An entity resolver for both DOM and SAX models of the SAX document.
- * <p>
- * The entity resolver only handles queries for the DTD. It will find any URI
- * with a recognised public id and return an {@link org.xml.sax.InputSource}.
- * <p>
- * @author <a href="mailto:joe@exubero.com">Joe Schmetzer</a>
- */
-public class DTDEntityResolver implements EntityResolver {
-
- /** Public ID for the AFP fonts 1.0 DTD. */
- public static final String AFP_DTD_1_0_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.0//EN";
-
- /** Resource location for the AFP fonts 1.0 DTD. */
- public static final String AFP_DTD_1_0_RESOURCE = "afp-fonts-1.0.dtd";
-
- /** Public ID for the AFP fonts 1.1 DTD. */
- public static final String AFP_DTD_1_1_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.1//EN";
-
- /** Resource location for the AFP fonts 1.1 DTD. */
- public static final String AFP_DTD_1_1_RESOURCE = "afp-fonts-1.1.dtd";
-
- /** Public ID for the AFP fonts 1.2 DTD. */
- public static final String AFP_DTD_1_2_ID = "-//APACHE/DTD AFP Installed Font Definition DTD 1.2//EN";
-
- /** Resource location for the AFP fonts 1.2 DTD. */
- public static final String AFP_DTD_1_2_RESOURCE = "afp-fonts-1.2.dtd";
-
- /**
- * Resolve the combination of system and public identifiers.
- * If this resolver recognises the publicId, it will handle the resolution
- * from the classpath, otherwise it will return null and allow the default
- * resolution to occur.
- *
- * @param publicId the public identifier to use
- * @param systemId the system identifier to resolve
- * @return An input source to the entity or null if not handled
- * @throws IOException an error reading the stream
- */
- public InputSource resolveEntity(String publicId, String systemId)
- throws IOException {
-
- URL resource = null;
- if ( AFP_DTD_1_2_ID.equals(publicId) ) {
- resource = getResource( AFP_DTD_1_2_RESOURCE );
- } else if ( AFP_DTD_1_1_ID.equals(publicId) ) {
- resource = getResource( AFP_DTD_1_1_RESOURCE );
- } else if ( AFP_DTD_1_0_ID.equals(publicId) ) {
- throw new FontRuntimeException(
- "The AFP Installed Font Definition 1.0 DTD is not longer supported" );
- } else if( systemId != null && systemId.indexOf("afp-fonts.dtd") >= 0 ) {
- throw new FontRuntimeException(
- "The AFP Installed Font Definition DTD must be specified using the public id" );
- } else {
- return null;
- }
-
- InputSource inputSource = new InputSource( resource.openStream() );
- inputSource.setPublicId( publicId );
- inputSource.setSystemId( systemId );
-
- return inputSource;
- }
-
- /**
- * Returns the URL of a resource on the classpath
- * @param resourceName the path to the resource relative to the root of the
- * classpath.
- * @return the URL of the required resource
- * @throws FontRuntimeException if the resource could not be found.
- */
- private URL getResource(String resourcePath) {
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null) {
- cl = ClassLoader.getSystemClassLoader();
- }
-
- URL resource = cl.getResource( resourcePath );
- if (resource == null) {
- throw new FontRuntimeException( "Resource " + resourcePath +
- " could not be found on the classpath" );
- }
-
- return resource;
- }
-}
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.tools;
-
-/**
- * Library of utility methods useful in dealing with strings.
- *
- */
-public class StringUtils {
-
- /**
- * Padds the string to the left with the given character for
- * the specified length.
- * @param input The input string.
- * @param padding The char used for padding.
- * @param length The length of the new string.
- * @return The padded string.
- */
- public static String lpad(String input, char padding, int length) {
-
- if (input == null) {
- input = new String();
- }
-
- if (input.length() >= length) {
- return input;
- } else {
- StringBuffer result = new StringBuffer();
- int numChars = length - input.length();
- for (int i = 0; i < numChars; i++) {
- result.append(padding);
- }
- result.append(input);
- return result.toString();
- }
- }
-
- /**
- * Padds the string to the right with the given character for
- * the specified length.
- * @param input The input string.
- * @param padding The char used for padding.
- * @param length The length of the new string.
- * @return The padded string.
- */
- public static String rpad(String input, char padding, int length) {
-
- if (input == null) {
- input = new String();
- }
-
- if (input.length() >= length) {
- return input;
- } else {
- StringBuffer result = new StringBuffer(input);
- int numChars = length - input.length();
- for (int i = 0; i < numChars; i++) {
- result.append(padding);
- }
- return result.toString();
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2006 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.afp.tools;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A helper class to read structured fields from a MO:DCA document. Each
- * component of a mixed object document is explicitly defined and delimited
- * in the data. This is accomplished through the use of MO:DCA data structures,
- * called structured fields. Structured fields are used to envelop document
- * components and to provide commands and information to applications using
- * the data. Structured fields may contain one or more parameters. Each
- * parameter provides one value from a set of values defined by the architecture.
- * <p/>
- * MO:DCA structured fields consist of two parts: an introducer that identifies
- * the length and type of the structured field, and data that provides the
- * structured field's effect. The data is contained in a set of parameters,
- * which can consist of other data structures and data elements. The maximum
- * length of a structured field is 32767 bytes.
- * <p/>
- */
-public class StructuredFieldReader {
-
- /**
- * The input stream to read
- */
- private InputStream _inputStream = null;
-
- /**
- * The constructor for the StructuredFieldReader
- * @param inputStream the input stream to process
- */
- public StructuredFieldReader(InputStream inputStream) {
-
- _inputStream = inputStream;
-
- }
-
- /**
- * Get the next structured field as identified by the identifer
- * parameter (this must be a valid MO:DCA structured field.
- * @param identifier the three byte identifier
- * @throws IOException
- */
- public byte[] getNext(byte[] identifier) throws IOException {
-
- int bufferPointer = 0;
- byte[] bufferData = new byte[identifier.length + 2];
- for (int x = 0; x < identifier.length; x++) {
- bufferData[x] = (byte) 0;
- }
-
- int c;
- while ((c = _inputStream.read()) > -1) {
-
- bufferData[bufferPointer] = (byte) c;
-
- // Check the last characters in the buffer
- int index = 0;
- boolean found = true;
-
- for (int i = identifier.length - 1; i > -1; i--) {
-
- int p = bufferPointer - index;
- if (p < 0) {
- p = bufferData.length + p;
- }
-
- index++;
-
- if (identifier[i] != bufferData[p]) {
- found = false;
- break;
- }
-
- }
-
- if (found) {
-
- byte[] length = new byte[2];
-
- int a = bufferPointer - identifier.length;
- if (a < 0) {
- a = bufferData.length + a;
- }
-
- int b = bufferPointer - identifier.length - 1;
- if (b < 0) {
- b = bufferData.length + b;
- }
-
- length[0] = bufferData[b];
- length[1] = bufferData[a];
-
- int reclength = ((length[0] & 0xFF) << 8)
- + (length[1] & 0xFF) - identifier.length - 2;
-
- byte[] retval = new byte[reclength];
-
- _inputStream.read(retval, 0, reclength);
-
- return retval;
-
- }
-
- bufferPointer++;
- if (bufferPointer >= bufferData.length) {
- bufferPointer = 0;
- }
-
- }
-
- return new byte[] {
- };
-
- }
-
-}