/* * $Id$ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. */ // Author : 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.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