/*-- $Id$ -- ============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "FOP" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact apache@apache.org. 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by James Tauber . For more information on the Apache Software Foundation, please see . */ //Author : Seshadri G package org.apache.fop.mif; // images are the one place that FOP classes outside this package get // referenced and I'd rather not do it import org.apache.fop.image.FopImage; import org.apache.fop.messaging.MessageHandler; import org.apache.fop.layout.LinkSet; import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.datatypes.IDReferences; import org.apache.fop.layout.Page; import org.apache.fop.layout.FontMetric; import org.apache.fop.layout.FontDescriptor; // Java import java.io.*; import java.io.PrintWriter; import java.util.*; import java.awt.Rectangle; /** * class representing a MIF document. * * The document is built up by calling various methods and then finally * output to given filehandle using output method. * */ public class MIFDocument { /** the version of MIF supported */ protected static final String mifVersion = "5.5"; protected BookComponent bookComponent; private Flow curFlow; // this is a ref to the current flow which could be a textflow or // a table private ID curIDCounter=new ID(); class ID { private int idCounter=1; public int getnewID() { return idCounter++; } } class FontFormat { public FontFormat() { } } class ParagraphFormat extends FontFormat { public ParagraphFormat() {} int startIndent; int endIndent; } class Document { protected int height; protected int width; public Document() {} public void output(OutputStream stream) throws IOException { String mif="\n\n>"; byte buf[]=mif.getBytes(); stream.write(buf); } } class PolyLine { public PolyLine() {} } class ImportObject { private String url; private int x,y,w,h; public ImportObject(String url,int x,int y,int w,int h) { this.url=url; this.x=x; this.y=y; this.w=w; this.h=h; } public void output(OutputStream stream) throws IOException { String path=this.url; //Strip 'file:' path= path.substring(5); String result=""; int i; do { // replace all matching '/' i=path.indexOf("/"); if (i != -1) { result=path.substring(0,i); result += ""; result += path.substring(i + 1); path=result; } } while (i!= -1); String mif="\n"; mif += "\n\t" + path + "'" + " >"; mif +="\n\t"; mif += "\n> #End ImportObj"; stream.write(mif.getBytes()); } } class Frame { private int ID; private int x,y,w,h; Vector content=new Vector(); public Frame(int x, int y, int w, int h) { this.ID=curIDCounter.getnewID(); this.x=x; this.y=y; this.w=w; this.h=h; } public void addContent(ImportObject obj) { content.addElement(obj); } public void output(OutputStream stream) throws IOException { String mif="\n"; mif += "\n\t\n\t\n\t\n\t\n\t\n\t \n >"; mif +="\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t"; mif += "\n\t"; stream.write(mif.getBytes()); Enumeration e=content.elements(); while (e.hasMoreElements()) { ((ImportObject) e.nextElement()).output(stream); } mif ="\n> #End Frame"; stream.write(mif.getBytes()); } public int getID() { return this.ID; } } class TextRect { private int rx,ry,w,h; private int numCols; private int curCol=0; //Current column being processed private int colGap=0; private int textRectID; public TextRect(int numCols) { this.numCols=numCols; this.curCol=0; this.textRectID=curIDCounter.getnewID(); } public int getTextRectID() { return textRectID; } public void setTextRectProp(int left,int top,int width,int height) { if (curCol==0) { //Use the left and top margins rx=left; ry=top; w=width; // current column width , not the entire span h=height; curCol++; } else if (curCol==1) { // Figure out the column gap and the span of the textrect colGap=left-rx-width; // Next the entire width w=numCols*width + (numCols-1)*colGap; curCol++; } } public void output(OutputStream stream) throws IOException { String mif="\n" + "\n\t" ; if (numCols>1) { mif += "\n"; mif += "\n"; } mif += "\n> #End TextRect" ; byte buf[]=mif.getBytes(); stream.write(buf); } } class Page { private String pageType; private String pageTag; private String pageBackground; private Vector textRects; public Page(String pageType, String pageTag, String pageBackground) { this.pageType=pageType; this.pageTag=pageTag; this.pageBackground=pageBackground; this.textRects=new Vector(); } public Page() { this.pageType="BodyPage"; this.pageBackground="Default"; this.textRects=new Vector(); } public void addTextRect(int numCols) { TextRect textRect=new TextRect(numCols); this.textRects.addElement(textRect); } public TextRect curTextRect() { return (TextRect) textRects.lastElement(); } public void output(OutputStream stream) throws IOException { String mif="\n" + "\n\t"; byte buf[]=mif.getBytes(); stream.write(buf); Enumeration e=textRects.elements(); while (e.hasMoreElements()) { ((TextRect) e.nextElement()).output(stream); } mif="\n> #End Page\n"; stream.write(mif.getBytes()); } } abstract class Flow { public Flow() {} public abstract Para curPara(); public abstract void startPara(); } class TextFlow extends Flow { Vector paras; private int ID; // This ID is used within ParaLine, however it is // logical to keep it unique to a textflow public TextFlow() { //The current textrect into which the textflow goes //is the last created. this.ID=((bookComponent.curPage()).curTextRect()).getTextRectID(); this.paras=new Vector(); } public int getTextRectID() { return ID; } public Para curPara() { return (Para) paras.lastElement(); } public void startPara() { this.paras.addElement(new Para(ID)); } public void output(OutputStream stream) throws IOException { String mif="\n"; mif += "\n"; mif += "\n>"; } stream.write(mif.getBytes()); Enumeration e=paraLines.elements(); while (e.hasMoreElements()) { ((ParaLine) e.nextElement()).output(stream); } mif="\n> #End ParaLine"; stream.write(mif.getBytes()); } } class ParaLine { Vector content; int textRectID; String tableID; String aFrameID; public ParaLine(int textRectID) { this.textRectID=textRectID; this.content=new Vector(); } public ParaLine () { this.textRectID=0; // There is no ID used, in tables this.content=new Vector(); } public void addContent(Object obj) { this.content.addElement(obj); } public void output(OutputStream stream) throws IOException { String mif="\n"; stream.write(mif.getBytes()); Enumeration e = this.content.elements(); while (e.hasMoreElements()) { Object elem=(Object) e.nextElement(); if (elem instanceof String) { // Output newlines as char hard return if (elem == "\n") { mif ="\n"; } else { mif="\n\t"; } stream.write(mif.getBytes()); } else if (elem instanceof Frame) { mif="\n\t"; stream.write(mif.getBytes()); } else if (elem instanceof Tbl) { mif="\n\t"; stream.write(mif.getBytes()); } } mif="\n> #End ParaLine"; stream.write(mif.getBytes()); } } class PgfCatalog { Vector pgfs; // Paragraph formats public PgfCatalog() {} public void output(OutputStream stream) throws IOException { String mif="\n" + "\n>" + "\n>"; stream.write(mif.getBytes()); } } class Color { public Color() {} } class ColorCatalog { public ColorCatalog() {} } class Ruling { int penWidth; int pen; int lines; public Ruling() { // Default ruling penWidth=1; pen=0; lines=1; } public void output(OutputStream stream) throws IOException { String mif = "\n"; mif +="\n"; mif +="\n"; mif +="\n"; mif +="\n>"; stream.write(mif.getBytes()); } } class RulingCatalog { // Contains multiple rulings Vector ruling = new Vector(); public RulingCatalog() { // Add the defualt ruling to the catalog ruling.addElement(new Ruling()); } public void output(OutputStream stream) throws IOException { String mif="\n"; stream.write(mif.getBytes()); } } class Row { class Cell { private int rowSpan,colSpan; private Vector paras; // Paras public Cell(int rowSpan,int colSpan) { this.rowSpan=rowSpan; this.colSpan=colSpan; paras=new Vector(); } public void startPara() { this.paras.addElement(new Para()); } public void output(OutputStream stream) throws IOException { String mif="\n\t\t"; // note tbl format to be added in a later release mif += "\n" + "\n"; stream.write(mif.getBytes()); if (! tblHead.isEmpty()) { Enumeration e=tblHead.elements(); while (e.hasMoreElements()) { ((Row) e.nextElement()).output(stream); } } if (! tblFoot.isEmpty()) { Enumeration e=tblFoot.elements(); while (e.hasMoreElements()) { ((Row) e.nextElement()).output(stream); } } if (! tblBody.isEmpty()) { mif="\n\t" ; stream.write(mif.getBytes()); pgfCatalog.output(stream); rulingCatalog.output(stream); document.output(stream); if (! aFrames.isEmpty()) { mif="\n