git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@397562 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_93
@@ -1,2 +1,3 @@ | |||
org.apache.fop.render.afp.AFPRendererMaker | |||
org.apache.fop.render.pcl.PCLRendererMaker | |||
org.apache.fop.render.svg.SVGRendererMaker |
@@ -0,0 +1,110 @@ | |||
/* | |||
* 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]; | |||
} | |||
} |
@@ -0,0 +1,169 @@ | |||
/* | |||
* 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 org.apache.fop.datatypes.ColorType; | |||
/** | |||
* AFP only supports very basic colours and this object provides a simple | |||
* bean for the colour attributes. | |||
* | |||
*/ | |||
public class AFPFontColor { | |||
/** | |||
* Red value. | |||
*/ | |||
private int _red = 0; | |||
/** | |||
* Green value. | |||
*/ | |||
private int _green = 0; | |||
/** | |||
* Blue value. | |||
*/ | |||
private int _blue = 0; | |||
/** | |||
* Constructor for the AFPColor Object | |||
* @param red The red color intensity (0-255) | |||
* @param green The green color intensity (0-255) | |||
* @param blue The blue color intensity (0-255) | |||
*/ | |||
public AFPFontColor(int red, int green, int blue) { | |||
_red = red; | |||
_green = green; | |||
_blue = blue; | |||
} | |||
/** | |||
* Constructor for the AFPColor Object | |||
* @param col the org.apache.fop.datatypes.ColorType object | |||
*/ | |||
public AFPFontColor(ColorType col) { | |||
_red = (int)(col.getRed() * 255); | |||
_green = (int)(col.getGreen() * 255); | |||
_blue = (int)(col.getBlue() * 255); | |||
} | |||
/** | |||
* Constructor for the AFPColor Object | |||
* @param col The java.awt.Color object | |||
*/ | |||
public AFPFontColor(Color col) { | |||
_red = col.getRed(); | |||
_green = col.getGreen(); | |||
_blue = col.getBlue(); | |||
} | |||
/** | |||
* Returns the blue attribute | |||
* @return int | |||
*/ | |||
public int getBlue() { | |||
return _blue; | |||
} | |||
/** | |||
* Returns the green attribute | |||
* @return int | |||
*/ | |||
public int getGreen() { | |||
return _green; | |||
} | |||
/** | |||
* Returns the red attribute | |||
* @return int | |||
*/ | |||
public int getRed() { | |||
return _red; | |||
} | |||
/** | |||
* Sets the blue attribute | |||
* @param blue The blue value to set | |||
*/ | |||
public void setBlue(int blue) { | |||
_blue = blue; | |||
} | |||
/** | |||
* Sets the green attribute | |||
* @param green The green value to set | |||
*/ | |||
public void setGreen(int green) { | |||
_green = green; | |||
} | |||
/** | |||
* Sets the red attribute | |||
* @param red The red value to set | |||
*/ | |||
public void setRed(int red) { | |||
_red = red; | |||
} | |||
/** | |||
* Sets this color object to the same values | |||
* as the given object. | |||
* @param col the source color | |||
*/ | |||
public void setTo(AFPFontColor col) { | |||
_red = col.getRed(); | |||
_green = col.getGreen(); | |||
_blue = col.getBlue(); | |||
} | |||
/** | |||
* Checks whether this object is equal to the parameter passed | |||
* as an argument. If the parameter is an instance of AFPColor | |||
* then the value are compared, otherwise the generalized equals | |||
* method is invoked on the parent class. | |||
* | |||
* @param obj the object to compare | |||
* @return boolean true if the object is equal | |||
*/ | |||
public boolean equals(Object obj) { | |||
if (obj instanceof AFPFontColor) { | |||
AFPFontColor c = (AFPFontColor) obj; | |||
if (c.getRed() == _red | |||
&& c.getGreen() == _green | |||
&& c.getBlue() == _blue) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} else { | |||
return super.equals(obj); | |||
} | |||
} | |||
} |
@@ -0,0 +1,51 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,108 @@ | |||
/* | |||
* 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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* 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 | |||
* @return property The property object. | |||
*/ | |||
public Property make(PropertyList propertyList) { | |||
if (_property == null) { | |||
_property = make(propertyList, "", propertyList.getParentFObj()); | |||
} | |||
return _property; | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
/* | |||
* 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://org.apache.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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,90 @@ | |||
/* | |||
* 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 value 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() + ")"; | |||
} | |||
} |
@@ -0,0 +1,47 @@ | |||
/* | |||
* 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."); | |||
} | |||
} | |||
} |
@@ -0,0 +1,120 @@ | |||
/* | |||
* 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; | |||
} | |||
} | |||
@@ -0,0 +1,91 @@ | |||
/* | |||
* 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 | |||
*/ | |||
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; | |||
} | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* 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; | |||
} | |||
} | |||
@@ -0,0 +1,608 @@ | |||
/* | |||
* 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; | |||
} | |||
} | |||
} |
@@ -0,0 +1,322 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,275 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,138 @@ | |||
/* | |||
* 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 Typeface 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); | |||
} | |||
} |
@@ -0,0 +1,193 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -0,0 +1,243 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
/* | |||
* 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"; | |||
} |
@@ -0,0 +1,650 @@ | |||
/* | |||
* 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.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.render.afp.AFPFontColor; | |||
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, AFPFontColor 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, AFPFontColor 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"); | |||
} | |||
} | |||
} |
@@ -0,0 +1,65 @@ | |||
/* | |||
* 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); | |||
} | |||
} | |||
} |
@@ -0,0 +1,409 @@ | |||
/* | |||
* 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; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import org.apache.fop.render.afp.AFPFontColor; | |||
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, AFPFontColor 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, AFPFontColor 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() { | |||
_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; | |||
} | |||
} |
@@ -0,0 +1,345 @@ | |||
/* | |||
* 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; | |||
} | |||
} | |||
} |
@@ -0,0 +1,213 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,74 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,190 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,193 @@ | |||
/* | |||
* 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]; | |||
} | |||
} |
@@ -0,0 +1,294 @@ | |||
/* | |||
* 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]; | |||
} | |||
} |
@@ -0,0 +1,108 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,146 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,271 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,207 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,91 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,762 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,225 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,94 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,171 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,156 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,114 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,298 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,157 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
/* | |||
* 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(); | |||
} | |||
} |
@@ -0,0 +1,106 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,111 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,194 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,130 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,97 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,207 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,185 @@ | |||
/* | |||
* 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 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); | |||
} | |||
} |
@@ -0,0 +1,598 @@ | |||
/* | |||
* 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 org.apache.fop.render.afp.AFPFontColor; | |||
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 AFPFontColor _currentColor = new AFPFontColor(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, | |||
AFPFontColor 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.setTo(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, AFPFontColor 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.setTo(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(AFPFontColor 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); | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,330 @@ | |||
/* | |||
* 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.AFPFontColor; | |||
/** | |||
* 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, AFPFontColor 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, | |||
AFPFontColor 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, AFPFontColor 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, AFPFontColor 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(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,151 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,148 @@ | |||
/* | |||
* 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); | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,131 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,112 @@ | |||
/* | |||
* 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; | |||
} | |||
} |
@@ -0,0 +1,80 @@ | |||
/* | |||
* 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(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,134 @@ | |||
/* | |||
* 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 | |||
*/ | |||
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[] { | |||
}; | |||
} | |||
} |