Restored support for AFP Extensions (TLE, NOP, Overlays and Page Segments) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@725308 13f79535-47bb-0310-9956-ffa450edef68pull/37/head
@@ -79,6 +79,9 @@ public class DataStream { | |||
/** The current page */ | |||
private AbstractPageObject currentPage = null; | |||
/** Sequence number for TLE's.*/ | |||
private int tleSequence = 0; | |||
/** The MO:DCA interchange set in use (default to MO:DCA-P IS/2 set) */ | |||
private InterchangeSet interchangeSet | |||
= InterchangeSet.valueOf(InterchangeSet.MODCA_PRESENTATION_INTERCHANGE_SET_2); | |||
@@ -474,7 +477,7 @@ public class DataStream { | |||
for (int i = 0; i < attributes.length; i++) { | |||
String name = attributes[i].getKey(); | |||
String value = attributes[i].getValue(); | |||
currentPage.createTagLogicalElement(name, value); | |||
currentPage.createTagLogicalElement(name, value, tleSequence++); | |||
} | |||
} | |||
@@ -504,7 +507,7 @@ public class DataStream { | |||
if (currentPageGroup != null) { | |||
currentPageGroup.createTagLogicalElement(name, value); | |||
} else { | |||
currentPage.createTagLogicalElement(name, value); | |||
currentPage.createTagLogicalElement(name, value, tleSequence++); | |||
} | |||
} | |||
@@ -546,7 +549,7 @@ public class DataStream { | |||
*/ | |||
public void startPageGroup() throws IOException { | |||
endPageGroup(); | |||
this.currentPageGroup = factory.createPageGroup(); | |||
this.currentPageGroup = factory.createPageGroup(tleSequence); | |||
} | |||
/** | |||
@@ -557,6 +560,7 @@ public class DataStream { | |||
public void endPageGroup() throws IOException { | |||
if (currentPageGroup != null) { | |||
currentPageGroup.endPageGroup(); | |||
tleSequence = currentPageGroup.getTleSequence(); | |||
document.addPageGroup(currentPageGroup); | |||
document.writeToStream(outputStream); | |||
currentPageGroup = null; |
@@ -219,13 +219,13 @@ public class Factory { | |||
/** | |||
* Creates a new MO:DCA {@link PageGroup} | |||
* | |||
* @param tleSequence current start tle sequence number within stream | |||
* @return a new {@link PageGroup} | |||
*/ | |||
public PageGroup createPageGroup() { | |||
public PageGroup createPageGroup(int tleSequence) { | |||
String name = PAGE_GROUP_NAME_PREFIX | |||
+ StringUtils.lpad(String.valueOf(++pageGroupCount), '0', 5); | |||
return new PageGroup(this, name); | |||
return new PageGroup(this, name, tleSequence); | |||
} | |||
/** | |||
@@ -381,10 +381,11 @@ public class Factory { | |||
* | |||
* @param name name of the element | |||
* @param value value of the element | |||
* @param tleSequence current start tle sequence number within stream* | |||
* @return a new {@link TagLogicalElement} | |||
*/ | |||
public TagLogicalElement createTagLogicalElement(String name, String value) { | |||
TagLogicalElement tle = new TagLogicalElement(name, value); | |||
public TagLogicalElement createTagLogicalElement(String name, String value, int tleSequence) { | |||
TagLogicalElement tle = new TagLogicalElement(name, value, tleSequence); | |||
return tle; | |||
} | |||
@@ -181,7 +181,7 @@ public abstract class AbstractAFPObject implements Streamable { | |||
public interface Type { | |||
/** Attribute */ | |||
byte ATTRIBUTE = (byte)0x0A; | |||
byte ATTRIBUTE = (byte)0xA0; | |||
/** Copy Count */ | |||
byte COPY_COUNT = (byte)0xA2; |
@@ -222,9 +222,11 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen | |||
* the name of the tag | |||
* @param value | |||
* the value of the tag | |||
* @param tleID | |||
* unique ID within AFP stream | |||
*/ | |||
public void createTagLogicalElement(String name, String value) { | |||
TagLogicalElement tle = new TagLogicalElement(name, value); | |||
public void createTagLogicalElement(String name, String value, int tleID) { | |||
TagLogicalElement tle = new TagLogicalElement(name, value, tleID); | |||
if (tagLogicalElements == null) { | |||
tagLogicalElements = new java.util.ArrayList/*<TagLogicalElement>*/(); | |||
} |
@@ -163,6 +163,11 @@ implements Streamable { | |||
* @return true if this object can be written | |||
*/ | |||
protected boolean canWrite(AbstractAFPObject obj) { | |||
return obj instanceof AbstractPageObject && ((Completable)obj).isComplete(); | |||
if (obj instanceof AbstractPageObject) { | |||
return ((Completable)obj).isComplete(); | |||
} | |||
else { | |||
return this.isComplete(); | |||
} | |||
} | |||
} |
@@ -39,14 +39,21 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { | |||
/** The tag logical elements contained within this group */ | |||
private List tagLogicalElements = null; | |||
/** | |||
* Sequence number for TLE's. | |||
*/ | |||
private int tleSequence = 0; | |||
/** | |||
* Constructor for the PageGroup. | |||
* | |||
* @param factory the resource manager | |||
* @param name the name of the page group | |||
* @param tleSequence current start tle sequence number within stream | |||
*/ | |||
public PageGroup(Factory factory, String name) { | |||
public PageGroup(Factory factory, String name, int tleSequence) { | |||
super(factory, name); | |||
this.tleSequence = tleSequence; | |||
} | |||
private List getTagLogicalElements() { | |||
@@ -65,9 +72,10 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { | |||
* the value of the tag | |||
*/ | |||
public void createTagLogicalElement(String name, String value) { | |||
TagLogicalElement tle = factory.createTagLogicalElement(name, value); | |||
TagLogicalElement tle = factory.createTagLogicalElement(name, value, tleSequence); | |||
if (!getTagLogicalElements().contains(tle)) { | |||
getTagLogicalElements().add(tle); | |||
tleSequence++; | |||
} | |||
} | |||
@@ -102,4 +110,8 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { | |||
public String toString() { | |||
return this.getName(); | |||
} | |||
public int getTleSequence() { | |||
return tleSequence; | |||
} | |||
} |
@@ -57,26 +57,47 @@ public class TagLogicalElement extends AbstractAFPObject { | |||
*/ | |||
private String value = null; | |||
/** | |||
* Sequence of TLE within document | |||
*/ | |||
private int tleID; | |||
/** | |||
* 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 | |||
* @param tleID unique identifier for TLE within AFP stream | |||
*/ | |||
public TagLogicalElement(String name, String value) { | |||
public TagLogicalElement(String name, String value, int tleID) { | |||
this.name = name; | |||
this.value = value; | |||
this.tleID = tleID; | |||
} | |||
/** {@inheritDoc} */ | |||
public void writeToStream(OutputStream os) throws IOException { | |||
byte[] data = new byte[17 + name.length() + value.length()]; | |||
// convert name and value to ebcdic | |||
byte[] tleByteName = null; | |||
byte[] tleByteValue = null; | |||
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); | |||
} | |||
byte[] data = new byte[27 + tleByteName.length + tleByteValue.length]; | |||
data[0] = 0x5A; | |||
// Set the total record length | |||
byte[] rl1 | |||
= BinaryUtils.convert(16 + name.length() + value.length(), 2); | |||
= BinaryUtils.convert(26 + tleByteName.length + tleByteValue.length, 2); | |||
//Ignore first byte | |||
data[1] = rl1[0]; | |||
data[2] = rl1[1]; | |||
@@ -90,27 +111,15 @@ public class TagLogicalElement extends AbstractAFPObject { | |||
data[7] = 0x00; // Reserved | |||
data[8] = 0x00; // Reserved | |||
//Use 2 triplets, attrubute name and value (the key for indexing) | |||
//Use 2 triplets, attribute name and value (the key for indexing) | |||
byte[] rl2 = BinaryUtils.convert(name.length() + 4, 1); | |||
byte[] rl2 = BinaryUtils.convert(tleByteName.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; | |||
byte[] tleByteName = null; | |||
byte[] tleByteValue = null; | |||
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); | |||
} | |||
// write out TLE name | |||
int pos = 13; | |||
for (int i = 0; i < tleByteName.length; i++) { | |||
data[pos++] = tleByteName[i]; | |||
@@ -125,6 +134,18 @@ public class TagLogicalElement extends AbstractAFPObject { | |||
for (int i = 0; i < tleByteValue.length; i++) { | |||
data[pos++] = tleByteValue[i]; | |||
} | |||
// attribute qualifier | |||
data[pos++] = 0x10; | |||
data[pos++] = (byte)0x80; | |||
byte[] id = BinaryUtils.convert(tleID, 4); | |||
for (int i = 0; i < id.length; i++) { | |||
data[pos++] = id[i]; | |||
} | |||
byte[] level = BinaryUtils.convert(1, 4); | |||
for (int i = 0; i < level.length; i++) { | |||
data[pos++] = level[i]; | |||
} | |||
os.write(data); | |||
} | |||
} |
@@ -53,6 +53,6 @@ public class AFPElement extends AbstractAFPExtensionObject { | |||
/** {@inheritDoc} */ | |||
protected ExtensionAttachment instantiateExtensionAttachment() { | |||
return new AFPPageSetup(getName()); | |||
return new AFPPageSetup(getLocalName()); | |||
} | |||
} |
@@ -20,7 +20,7 @@ | |||
package org.apache.fop.render.afp.extensions; | |||
/** | |||
* This is the pass-through value object for the PostScript extension. | |||
* This is the pass-through value object for the AFP extension. | |||
*/ | |||
public class AFPPageSetup extends AFPExtensionAttachment { | |||
@@ -53,6 +53,9 @@ | |||
<changes> | |||
<release version="FOP Trunk" date="TBD"> | |||
<action context="Renderers" dev="CB" type="fix" fixes-bug="46369"> | |||
Fixed bug that caused AFP Renderer Extensions to be ignored. | |||
</action> | |||
<action context="Code" dev="AD" type="fix" fixes-bug="46319"> | |||
Fixed a memory-leak in Marker.MarkerAttribute, where an instance was used both as key and value in | |||
a WeakHashMap, effectively neutralizing the benefit of using WeakReferences. Solved by extending |