Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java Wed Sep 19 15:00:15 2012 @@ -19,13 +19,9 @@ package org.apache.fop.render.bitmap; -import java.awt.image.BufferedImage; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.xmlgraphics.image.writer.ImageWriterParams; - import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.render.Renderer; @@ -33,9 +29,7 @@ import org.apache.fop.render.RendererCon import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser; import org.apache.fop.render.intermediate.IFDocumentHandler; -import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T4; -import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T6; -import static org.apache.fop.render.bitmap.TIFFCompressionValues.NONE; +import static org.apache.fop.render.bitmap.TIFFCompressionValue.NONE; /** * TIFF Renderer configurator @@ -62,43 +56,40 @@ public class TIFFRendererConfigurator ex final TIFFRendererConfig config = (TIFFRendererConfig) getRendererConfig(renderer); if (config != null) { TIFFRenderer tiffRenderer = (TIFFRenderer) renderer; - //set compression - tiffRenderer.setBufferedImageType(getCompressionType(config, tiffRenderer.getWriterParams())); + setCompressionMethod(config.getCompressionType(), tiffRenderer.getRenderingSettings()); } super.configure(renderer); } - private int getCompressionType(TIFFRendererConfig config, ImageWriterParams writerParms) - throws FOPException { - //Some compression formats need a special image format: - TIFFCompressionValues compression = config.getCompressionType(); + private void setCompressionMethod(TIFFCompressionValue compression, + BitmapRenderingSettings settings) throws FOPException { if (compression != null) { if (compression != NONE) { - writerParms.setCompressionMethod(compression.getName()); + settings.setCompressionMethod(compression.getName()); } if (LOG.isInfoEnabled()) { LOG.info("TIFF compression set to " + compression.getName()); } + if (compression.hasCCITTCompression()) { + settings.setBufferedImageType(compression.getImageType()); + } } - return getBufferedImageTypeFor(compression); } - private int getBufferedImageTypeFor(TIFFCompressionValues compressionType) { - if (compressionType == CCITT_T6 || compressionType == CCITT_T4) { - return BufferedImage.TYPE_BYTE_BINARY; - } else { - return BufferedImage.TYPE_INT_ARGB; - } + private boolean isSingleStrip(TIFFRendererConfig config) { + Boolean singleRowPerStrip = config.isSingleStrip(); + return singleRowPerStrip == null ? false : singleRowPerStrip; } - /** {@inheritDoc} */ + @Override public void configure(IFDocumentHandler documentHandler) throws FOPException { - final TIFFRendererConfig tiffConfig = (TIFFRendererConfig) getRendererConfig(documentHandler); - if (tiffConfig != null) { + final TIFFRendererConfig config = (TIFFRendererConfig) getRendererConfig(documentHandler); + if (config != null) { TIFFDocumentHandler tiffHandler = (TIFFDocumentHandler) documentHandler; BitmapRenderingSettings settings = tiffHandler.getSettings(); configure(documentHandler, settings, new TIFFRendererConfigParser()); - settings.setBufferedImageType(getCompressionType(tiffConfig, settings.getWriterParams())); + setCompressionMethod(config.getCompressionType(), settings); + settings.getWriterParams().setSingleStrip(isSingleStrip(config)); } }
Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFEventProducer.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFEventProducer.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFEventProducer.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFEventProducer.java Wed Sep 19 15:00:15 2012 @@ -59,12 +59,11 @@ public interface PDFEventProducer extend * Custom structure type is not standard as per the PDF reference. * * @param source the event source - * @param fo the local name of the formatting object having the custom type * @param type custom structure type * @param fallback default structure type used as a fallback * @event.severity WARN */ - void nonStandardStructureType(Object source, String fo, String type, String fallback); + void nonStandardStructureType(Object source, String type, String fallback); /** * The encryption length must be a multiple of 8 between 40 and 128. Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java Wed Sep 19 15:00:15 2012 @@ -132,7 +132,7 @@ class PDFLogicalStructureHandler { ? structureTreeElement.getParentStructElem() : structureTreeElement; pageParentTreeArray.add(parent); - String type = parent.getStructureType().toString(); + String type = parent.getStructureType().getName().toString(); int mcid = pageParentTreeArray.length() - 1; return new MarkedContentInfo(type, mcid, structureTreeElement); } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java Wed Sep 19 15:00:15 2012 @@ -21,25 +21,272 @@ package org.apache.fop.render.pdf; import java.util.LinkedList; import java.util.Locale; +import java.util.Map; import org.xml.sax.Attributes; +import org.xml.sax.helpers.AttributesImpl; import org.apache.fop.accessibility.StructureTreeElement; import org.apache.fop.accessibility.StructureTreeEventHandler; import org.apache.fop.events.EventBroadcaster; import org.apache.fop.fo.extensions.ExtensionElementMapping; +import org.apache.fop.fo.pagination.Flow; import org.apache.fop.pdf.PDFFactory; -import org.apache.fop.pdf.PDFName; -import org.apache.fop.pdf.PDFObject; import org.apache.fop.pdf.PDFParentTree; import org.apache.fop.pdf.PDFStructElem; import org.apache.fop.pdf.PDFStructTreeRoot; +import org.apache.fop.pdf.StandardStructureAttributes.Table.Scope; +import org.apache.fop.pdf.StandardStructureTypes; +import org.apache.fop.pdf.StandardStructureTypes.Grouping; +import org.apache.fop.pdf.StandardStructureTypes.Table; +import org.apache.fop.pdf.StructureHierarchyMember; +import org.apache.fop.pdf.StructureType; +import org.apache.fop.util.XMLUtil; class PDFStructureTreeBuilder implements StructureTreeEventHandler { - private PDFFactory pdfFactory; + private static final String ROLE = "role"; + + private static final Map<String, StructureElementBuilder> BUILDERS + = new java.util.HashMap<String, StructureElementBuilder>(); + + private static final StructureElementBuilder DEFAULT_BUILDER + = new DefaultStructureElementBuilder(Grouping.NON_STRUCT); + + static { + // Declarations and Pagination and Layout Formatting Objects + StructureElementBuilder regionBuilder = new RegionBuilder(); + addBuilder("root", StandardStructureTypes.Grouping.DOCUMENT); + addBuilder("page-sequence", new PageSequenceBuilder()); + addBuilder("static-content", regionBuilder); + addBuilder("flow", regionBuilder); + // Block-level Formatting Objects + addBuilder("block", StandardStructureTypes.Paragraphlike.P); + addBuilder("block-container", StandardStructureTypes.Grouping.DIV); + // Inline-level Formatting Objects + addBuilder("character", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("external-graphic", new ImageBuilder()); + addBuilder("instream-foreign-object", new ImageBuilder()); + addBuilder("inline", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("inline-container", StandardStructureTypes.Grouping.DIV); + addBuilder("page-number", StandardStructureTypes.InlineLevelStructure.QUOTE); + addBuilder("page-number-citation", StandardStructureTypes.InlineLevelStructure.QUOTE); + addBuilder("page-number-citation-last", StandardStructureTypes.InlineLevelStructure.QUOTE); + // Formatting Objects for Tables + addBuilder("table-and-caption", StandardStructureTypes.Grouping.DIV); + addBuilder("table", new TableBuilder()); + addBuilder("table-caption", StandardStructureTypes.Grouping.CAPTION); + addBuilder("table-header", StandardStructureTypes.Table.THEAD); + addBuilder("table-footer", new TableFooterBuilder()); + addBuilder("table-body", StandardStructureTypes.Table.TBODY); + addBuilder("table-row", StandardStructureTypes.Table.TR); + addBuilder("table-cell", new TableCellBuilder()); + // Formatting Objects for Lists + addBuilder("list-block", StandardStructureTypes.List.L); + addBuilder("list-item", StandardStructureTypes.List.LI); + addBuilder("list-item-body", StandardStructureTypes.List.LBODY); + addBuilder("list-item-label", StandardStructureTypes.List.LBL); + // Dynamic Effects: Link and Multi Formatting Objects + addBuilder("basic-link", StandardStructureTypes.InlineLevelStructure.LINK); + // Out-of-Line Formatting Objects + addBuilder("float", StandardStructureTypes.Grouping.DIV); + addBuilder("footnote", StandardStructureTypes.InlineLevelStructure.NOTE); + addBuilder("footnote-body", StandardStructureTypes.Grouping.SECT); + addBuilder("wrapper", StandardStructureTypes.InlineLevelStructure.SPAN); + addBuilder("marker", StandardStructureTypes.Grouping.PRIVATE); + + addBuilder("#PCDATA", new PlaceholderBuilder()); + } + + private static void addBuilder(String fo, StructureType structureType) { + addBuilder(fo, new DefaultStructureElementBuilder(structureType)); + } + + private static void addBuilder(String fo, StructureElementBuilder mapper) { + BUILDERS.put(fo, mapper); + } + + private interface StructureElementBuilder { + + PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, PDFFactory pdfFactory, + EventBroadcaster eventBroadcaster); + + } + + private static class DefaultStructureElementBuilder implements StructureElementBuilder { + + private final StructureType defaultStructureType; + + DefaultStructureElementBuilder(StructureType structureType) { + this.defaultStructureType = structureType; + } + + public final PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, + PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + String role = attributes.getValue(ROLE); + StructureType structureType; + if (role == null) { + structureType = defaultStructureType; + } else { + structureType = StandardStructureTypes.get(role); + if (structureType == null) { + structureType = defaultStructureType; + PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(role, role, + structureType.toString()); + } + } + PDFStructElem structElem = createStructureElement(parent, structureType); + setAttributes(structElem, attributes); + addKidToParent(structElem, parent, attributes); + registerStructureElement(structElem, pdfFactory); + return structElem; + } + + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new PDFStructElem(parent, structureType); + } + + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + } + + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + parent.addKid(kid); + } + + protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory) { + pdfFactory.getDocument().registerStructureElement(structureElement); + } + + } + + private static class PageSequenceBuilder extends DefaultStructureElementBuilder { + + PageSequenceBuilder() { + super(StandardStructureTypes.Grouping.PART); + } - private PDFLogicalStructureHandler logicalStructureHandler; + @Override + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new PageSequenceStructElem(parent, structureType); + } + + } + + private static class RegionBuilder extends DefaultStructureElementBuilder { + + RegionBuilder() { + super(StandardStructureTypes.Grouping.SECT); + } + + @Override + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + String flowName = attributes.getValue(Flow.FLOW_NAME); + ((PageSequenceStructElem) parent).addContent(flowName, kid); + } + + } + + private static class ImageBuilder extends DefaultStructureElementBuilder { + + ImageBuilder() { + super(StandardStructureTypes.Illustration.FIGURE); + } + + @Override + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); + if (altTextNode == null) { + altTextNode = "No alternate text specified"; + } + structElem.put("Alt", altTextNode); + } + + } + + private static class TableBuilder extends DefaultStructureElementBuilder { + + TableBuilder() { + super(StandardStructureTypes.Table.TABLE); + } + + @Override + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + return new TableStructElem(parent, structureType); + } + } + + private static class TableFooterBuilder extends DefaultStructureElementBuilder { + + public TableFooterBuilder() { + super(StandardStructureTypes.Table.TFOOT); + } + + @Override + protected void addKidToParent(PDFStructElem kid, StructureHierarchyMember parent, + Attributes attributes) { + ((TableStructElem) parent).addTableFooter(kid); + } + } + + private static class TableCellBuilder extends DefaultStructureElementBuilder { + + TableCellBuilder() { + super(StandardStructureTypes.Table.TD); + } + + @Override + protected PDFStructElem createStructureElement(StructureHierarchyMember parent, + StructureType structureType) { + PDFStructElem grandParent = ((PDFStructElem) parent).getParentStructElem(); + //TODO What to do with cells from table-footer? Currently they are mapped on TD. + if (grandParent.getStructureType() == StandardStructureTypes.Table.THEAD) { + structureType = StandardStructureTypes.Table.TH; + } else { + structureType = StandardStructureTypes.Table.TD; + } + return super.createStructureElement(parent, structureType); + } + + @Override + protected void registerStructureElement(PDFStructElem structureElement, PDFFactory pdfFactory) { + if (structureElement.getStructureType() == Table.TH) { + pdfFactory.getDocument().registerStructureElement(structureElement, Scope.COLUMN); + } else { + pdfFactory.getDocument().registerStructureElement(structureElement); + } + } + + @Override + protected void setAttributes(PDFStructElem structElem, Attributes attributes) { + String columnSpan = attributes.getValue("number-columns-spanned"); + if (columnSpan != null) { + structElem.setTableAttributeColSpan(Integer.parseInt(columnSpan)); + } + String rowSpan = attributes.getValue("number-rows-spanned"); + if (rowSpan != null) { + structElem.setTableAttributeRowSpan(Integer.parseInt(rowSpan)); + } + } + + } + + private static class PlaceholderBuilder implements StructureElementBuilder { + + public PDFStructElem build(StructureHierarchyMember parent, Attributes attributes, + PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + PDFStructElem elem = new PDFStructElem.Placeholder(parent); + parent.addKid(elem); + return elem; + } + + } + + private PDFFactory pdfFactory; private EventBroadcaster eventBroadcaster; @@ -51,97 +298,65 @@ class PDFStructureTreeBuilder implements this.pdfFactory = pdfFactory; } + void setEventBroadcaster(EventBroadcaster eventBroadcaster) { + this.eventBroadcaster = eventBroadcaster; + } + void setLogicalStructureHandler(PDFLogicalStructureHandler logicalStructureHandler) { - this.logicalStructureHandler = logicalStructureHandler; - createRootStructureElement(); + createRootStructureElement(logicalStructureHandler); } - private void createRootStructureElement() { + private void createRootStructureElement(PDFLogicalStructureHandler logicalStructureHandler) { assert rootStructureElement == null; PDFParentTree parentTree = logicalStructureHandler.getParentTree(); PDFStructTreeRoot structTreeRoot = pdfFactory.getDocument().makeStructTreeRoot(parentTree); - rootStructureElement = createStructureElement("root", structTreeRoot, null); - structTreeRoot.addKid(rootStructureElement); + rootStructureElement = createStructureElement("root", structTreeRoot, + new AttributesImpl(), pdfFactory, eventBroadcaster); } - void setEventBroadcaster(EventBroadcaster eventBroadcaster) { - this.eventBroadcaster = eventBroadcaster; - } + private static PDFStructElem createStructureElement(String name, StructureHierarchyMember parent, + Attributes attributes, PDFFactory pdfFactory, EventBroadcaster eventBroadcaster) { + StructureElementBuilder builder = BUILDERS.get(name); + if (builder == null) { + // TODO is a fallback really necessary? + builder = DEFAULT_BUILDER; + } + return builder.build(parent, attributes, pdfFactory, eventBroadcaster); + } public void startPageSequence(Locale language, String role) { ancestors = new LinkedList<PDFStructElem>(); - PDFStructElem structElem = createStructureElement("page-sequence", rootStructureElement, role); + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute("", ROLE, ROLE, XMLUtil.CDATA, role); + PDFStructElem structElem = createStructureElement("page-sequence", + rootStructureElement, attributes, pdfFactory, eventBroadcaster); if (language != null) { structElem.setLanguage(language); } - rootStructureElement.addKid(structElem); ancestors.add(structElem); } - private PDFStructElem createStructureElement(String name, PDFObject parent, String role) { - PDFName structureType = FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster); - return pdfFactory.getDocument().makeStructureElement(structureType, parent); - } - public void endPageSequence() { } public StructureTreeElement startNode(String name, Attributes attributes) { PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem = createStructureElement(name, parent, role); - setSpanAttributes(structElem, attributes); - parent.addKid(structElem); + PDFStructElem structElem = createStructureElement(name, parent, attributes, + pdfFactory, eventBroadcaster); ancestors.addFirst(structElem); return structElem; } - private void setSpanAttributes(PDFStructElem structElem, Attributes attributes) { - String columnSpan = attributes.getValue("number-columns-spanned"); - if (columnSpan != null) { - structElem.setTableAttributeColSpan(Integer.parseInt(columnSpan)); - } - String rowSpan = attributes.getValue("number-rows-spanned"); - if (rowSpan != null) { - structElem.setTableAttributeRowSpan(Integer.parseInt(rowSpan)); - } - } - public void endNode(String name) { - removeFirstAncestor(); - } - - private void removeFirstAncestor() { ancestors.removeFirst(); } public StructureTreeElement startImageNode(String name, Attributes attributes) { - PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem = createStructureElement(name, parent, role); - parent.addKid(structElem); - String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text"); - if (altTextNode != null) { - structElem.put("Alt", altTextNode); - } else { - structElem.put("Alt", "No alternate text specified"); - } - ancestors.addFirst(structElem); - return structElem; + return startNode(name, attributes); } public StructureTreeElement startReferencedNode(String name, Attributes attributes) { - PDFStructElem parent = ancestors.getFirst(); - String role = attributes.getValue("role"); - PDFStructElem structElem; - if ("#PCDATA".equals(name)) { - structElem = new PDFStructElem.Placeholder(parent, name); - } else { - structElem = createStructureElement(name, parent, role); - } - parent.addKid(structElem); - ancestors.addFirst(structElem); - return structElem; + return startNode(name, attributes); } } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/ps/PSFontUtils.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/ps/PSFontUtils.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/ps/PSFontUtils.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/src/java/org/apache/fop/render/ps/PSFontUtils.java Wed Sep 19 15:00:15 2012 @@ -38,7 +38,7 @@ import org.apache.xmlgraphics.ps.dsc.Res import org.apache.fop.fonts.Base14Font; import org.apache.fop.fonts.CIDFontType; -import org.apache.fop.fonts.CIDSubset; +import org.apache.fop.fonts.CIDSet; import org.apache.fop.fonts.CMapSegment; import org.apache.fop.fonts.CustomFont; import org.apache.fop.fonts.EmbeddingMode; @@ -457,15 +457,17 @@ public class PSFontUtils extends org.apa // TODO /FontInfo gen.write("/CIDCount "); - CIDSubset cidSubset = font.getCIDSubset(); - int subsetSize = cidSubset.getSubsetSize(); - gen.write(subsetSize); + CIDSet cidSet = font.getCIDSet(); + int numberOfGlyphs = cidSet.getNumberOfGlyphs(); + gen.write(numberOfGlyphs); gen.writeln(" def"); gen.writeln("/GDBytes 2 def"); // TODO always 2? gen.writeln("/CIDMap [<"); int colCount = 0; int lineCount = 1; - for (int cid = 0; cid < subsetSize; cid++) { + int nextBitSet = 0; + int previousBitSet = 0; + for (int cid = 0; cid < numberOfGlyphs; cid++) { if (colCount++ == 20) { gen.newLine(); colCount = 1; @@ -478,7 +480,23 @@ public class PSFontUtils extends org.apa if (font.getEmbeddingMode() != EmbeddingMode.FULL) { gid = HexEncoder.encode(cid, 4); } else { - gid = HexEncoder.encode(cidSubset.getGlyphIndexForSubsetIndex(cid), 4); + previousBitSet = nextBitSet; + nextBitSet = cidSet.getGlyphIndices().nextSetBit(nextBitSet); + while (previousBitSet++ < nextBitSet) { + // if there are gaps in the indices we pad them with zeros + gen.write("0000"); + cid++; + if (colCount++ == 20) { + gen.newLine(); + colCount = 1; + if (lineCount++ == 800) { + gen.writeln("> <"); + lineCount = 1; + } + } + } + gid = HexEncoder.encode(nextBitSet, 4); + nextBitSet++; } gen.write(gid); } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/status.xml URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/status.xml?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/status.xml (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/status.xml Wed Sep 19 15:00:15 2012 @@ -62,6 +62,62 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> <release version="FOP Trunk" date="TBD"> + <action context="Fonts" dev="MH" type="add" fixes-bug="53868" importance="low" due-to="Luis Bernardo"> + Full font embedding in PDF + </action> + <action context="Renderers" dev="PH" type="add" fixes-bug="53865" importance="low"> + Added configuration for RowPerStrip configuration in the Tiff renderer. + RowsPerStrip can be configured to 1 or to the total # of rows. + See docs for fop.xconf configuration details. + </action> + <action context="Layout" dev="VH" type="fix" fixes-bug="53598" due-to="Robert Meyer"> + Always set the breakClass field to a legal value in BreakElement, so as to avoid + IllegalArgumentExceptions in other parts of the code. + </action> + <action context="Layout" dev="VH" type="fix" fixes-bug="45715" due-to="Luis Bernardo"> + Restored support for break-before on fo:table. + </action> + <action context="Layout" dev="VH" type="fix" fixes-bug="53827"> + When an fo:block has a non-zero value for its text-indent property and is broken over two + pages of different widths, then the first line on the second page is missing one word and + appears indented. + </action> + <action context="Renderers" dev="MH" type="fix" fixes-bug="53790"> + Prevented the TIFF configurator from overriding the Bitmap configurator unless CCITT + compression is enabled. + </action> + <action context="Renderers" dev="MH" type="fix" fixes-bug="53786"> + Removed the Attribute Qualifier on TLEs as they aren't used. + </action> + <action context="Renderers" dev="MH" type="fix" fixes-bug="48954" due-to="PH"> + Support for character encoding of TLEs in AFP output + </action> + <action context="Renderers" dev="VH" type="fix" fixes-bug="53778"> + When PDF accessibility is enabled, the contents for the different regions must appear in the + proper order in the structure tree. + </action> + <action context="Renderers" dev="MH" type="fix" fixes-bug="53766" due-to="Robert Meyer"> + Remove StandardEncoding as the encoding type from fonts used in the PDF renderer + </action> + <action context="Fonts" dev="MH" type="fix" fixes-bug="53685"> + Cached AFP charactersets have more unique keys preventing the two characters with + but different binaries conflicting. + </action> + <action context="Fonts" dev="MH" type="fix" fixes-bug="53657" due-to="Robert Meyer"> + AFP fonts default to the nominal character increment to font metrics when glyph info + is missing from the characterset. + </action> + <action context="Layout" dev="VH" type="fix" fixes-bug="53688"> + Wrong page number reported when a column overflows the region-body in a multi-column + document. + </action> + <action context="Renderers" dev="VH" type="add" fixes-bug="53639"> + When PDF accessibility is enabled, the Scope attribute must be present in the structure tree + for table header elements. + </action> + <action context="Fonts" dev="MH" type="add" fixes-bug="53600" due-to="Robert Meyer"> + Added an event if a glyph and its metric information does not exist in the character set + </action> <action context="Renderers" dev="VH" type="add" fixes-bug="53596"> When PDF accessibility is enabled, the structure tree must contain information about the number of columns or rows spanned by a table cell. Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java Wed Sep 19 15:00:15 2012 @@ -19,8 +19,6 @@ package org.apache.fop.accessibility.fo; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -34,7 +32,6 @@ import javax.xml.transform.TransformerFa import javax.xml.transform.dom.DOMResult; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.custommonkey.xmlunit.Diff; @@ -57,9 +54,17 @@ import org.apache.fop.fotreetest.DummyFO public class FO2StructureTreeConverterTestCase { - private interface FOLoader { + private static class FOLoader { - InputStream getFoInputStream(); + private final String resourceName; + + FOLoader(String resourceName) { + this.resourceName = resourceName; + } + + public InputStream getFoInputStream() { + return getResource(resourceName); + } } private static final String STRUCTURE_TREE_SEQUENCE_NAME = "structure-tree-sequence"; @@ -68,62 +73,30 @@ public class FO2StructureTreeConverterTe @Test public void testCompleteDocument() throws Exception { - foLoader = new FOLoader() { - public InputStream getFoInputStream() { - return getResource("/org/apache/fop/fo/complete_document.fo"); - } - }; - testConverter(); + testConverter("/org/apache/fop/fo/complete_document.fo"); } @Test public void testTableFooters() throws Exception { - foLoader = new FOLoader() { - public InputStream getFoInputStream() { - return getResource("table-footers.fo"); - } - }; - testConverter(); - } - - @Test - public void testCompleteContentWrappedInTableFooter() throws Exception { - Source xslt = new StreamSource(getResource("wrapCompleteDocumentInTableFooter.xsl")); - Transformer transformer = createTransformer(xslt); - InputStream originalFO = getResource("/org/apache/fop/fo/complete_document.fo"); - ByteArrayOutputStream transformedFoOutput = new ByteArrayOutputStream(); - transformer.transform(new StreamSource(originalFO), new StreamResult(transformedFoOutput)); - final byte[] transformedFoOutputBytes = transformedFoOutput.toByteArray(); - foLoader = new FOLoader() { - public InputStream getFoInputStream() { - return new ByteArrayInputStream(transformedFoOutputBytes); - } - }; - testConverter(); + testConverter("table-footers.fo"); } @Test public void testArtifact() throws Exception { - foLoader = new FOLoader() { - - public InputStream getFoInputStream() { - return getResource("artifact.fo"); - } - }; - testConverter(); + testConverter("artifact.fo"); } - private Transformer createTransformer(Source xslt) throws TransformerFactoryConfigurationError, - TransformerConfigurationException { - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - return transformerFactory.newTransformer(xslt); + @Test + public void testSideRegions() throws Exception { + testConverter("/org/apache/fop/fo/pagination/side-regions.fo"); } private static InputStream getResource(String name) { return FO2StructureTreeConverterTestCase.class.getResourceAsStream(name); } - private void testConverter() throws Exception { + private void testConverter(String foResourceName) throws Exception { + foLoader = new FOLoader(foResourceName); DOMResult expectedStructureTree = loadExpectedStructureTree(); DOMResult actualStructureTree = buildActualStructureTree(); final Diff diff = createDiff(expectedStructureTree, actualStructureTree); Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl Wed Sep 19 15:00:15 2012 @@ -50,6 +50,25 @@ <xsl:call-template name="copy"/> </xsl:template> + <xsl:template match="fo:static-content/@flow-name|fo:flow/@flow-name"> + <xsl:choose> + <xsl:when test=". = 'xsl-region-body' or + . = 'xsl-region-before' or + . = 'xsl-region-after' or + . = 'xsl-region-start' or + . = 'xsl-region-end' or + . = 'xsl-before-float-separator' or + . = 'xsl-footnote-separator'"> + <xsl:copy/> + </xsl:when> + <xsl:otherwise> + <xsl:attribute name="{local-name()}"> + <xsl:value-of select="concat('xsl-', local-name(//*[@region-name = current()]))"/> + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <!-- Block-level Formatting Objects --> <xsl:template match="fo:block|fo:block-container"> <xsl:call-template name="copy"/> @@ -73,15 +92,7 @@ <xsl:call-template name="copy"/> </xsl:template> - <xsl:template match="fo:table"> - <xsl:copy> - <xsl:apply-templates select="@*"/> - <xsl:apply-templates select="*[name() != 'fo:table-footer']"/> - <xsl:apply-templates select="fo:table-footer"/> - </xsl:copy> - </xsl:template> - - <xsl:template match="fo:table-header|fo:table-footer|fo:table-body|fo:table-row|fo:table-cell"> + <xsl:template match="fo:table|fo:table-header|fo:table-footer|fo:table-body|fo:table-row|fo:table-cell"> <xsl:call-template name="copy"/> </xsl:template> Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/apps/TIFFRendererConfBuilder.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/apps/TIFFRendererConfBuilder.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/apps/TIFFRendererConfBuilder.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/apps/TIFFRendererConfBuilder.java Wed Sep 19 15:00:15 2012 @@ -20,7 +20,7 @@ package org.apache.fop.apps; import static org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererOption.COMPRESSION; - +import static org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererOption.SINGLE_STRIP; public class TIFFRendererConfBuilder extends BitmapRendererConfBuilder { public TIFFRendererConfBuilder() { @@ -31,4 +31,9 @@ public class TIFFRendererConfBuilder ext createTextElement(COMPRESSION, mode); return this; } + + public TIFFRendererConfBuilder setSingleStrip(boolean single) { + createTextElement(SINGLE_STRIP, String.valueOf(single)); + return this; + } } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventChecker.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventChecker.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventChecker.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventChecker.java Wed Sep 19 15:00:15 2012 @@ -19,6 +19,9 @@ package org.apache.fop.events; +import java.util.Map; + +import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; /** @@ -28,10 +31,13 @@ class EventChecker implements EventListe private final String expectedEventID; + private final Map<String, Object> expectedParams; + private boolean eventReceived; - EventChecker(String expectedEventID) { + EventChecker(String expectedEventID, Map<String, Object> expectedParams) { this.expectedEventID = expectedEventID; + this.expectedParams = expectedParams; } public void processEvent(Event event) { @@ -39,6 +45,9 @@ class EventChecker implements EventListe String id = event.getEventID(); if (id.equals(expectedEventID)) { eventReceived = true; + for (Map.Entry<String, Object> param : expectedParams.entrySet()) { + assertEquals(event.getParam(param.getKey()), param.getValue()); + } } } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventProcessingTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventProcessingTestCase.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventProcessingTestCase.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/events/EventProcessingTestCase.java Wed Sep 19 15:00:15 2012 @@ -22,6 +22,9 @@ package org.apache.fop.events; import java.io.File; import java.io.InputStream; import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -62,9 +65,10 @@ public class EventProcessingTestCase { CONFIG_BASE_DIR = base.resolve("test/config/"); } - public void doTest(InputStream inStream, URI fopConf, String expectedEventID, String mimeType) - throws Exception { - EventChecker eventChecker = new EventChecker(expectedEventID); + + public void doTest(InputStream inStream, URI fopConf, String expectedEventID, String mimeType, + Map<String, Object> expectedParams) throws Exception { + EventChecker eventChecker = new EventChecker(expectedEventID, expectedParams); FopFactory fopFactory; if (fopConf != null) { fopFactory = FopFactory.newInstance(new File(fopConf)); @@ -81,6 +85,19 @@ public class EventProcessingTestCase { Result res = new SAXResult(fop.getDefaultHandler()); transformer.transform(src, res); eventChecker.end(); + + } + + public void doTest(InputStream inStream, URI fopConf, String expectedEventID, String mimeType) + throws Exception { + Map<String, Object> noParams = Collections.emptyMap(); + doTest(inStream, fopConf, expectedEventID, mimeType, noParams); + } + + public void doTest(String filename, String expectedEventID, Map<String, Object> expectedParams) + throws Exception { + doTest(BASE_DIR.resolve(filename).toURL().openStream(), null, expectedEventID, + MimeConstants.MIME_PDF, expectedParams); } public void doTest(String filename, String expectedEventID) throws Exception { @@ -133,4 +150,12 @@ public class EventProcessingTestCase { public void testViewportBPDOverflow() throws Exception { doTest("viewport-overflow.fo", BlockLevelEventProducer.class.getName() + ".viewportBPDOverflow"); } + + @Test + public void testPageOverflow() throws Exception { + Map<String, Object> params = new HashMap<String, Object>(); + params.put("page", "1"); + doTest("region-body_overflow.fo", BlockLevelEventProducer.class.getName() + ".regionOverflow", + params); + } } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java Wed Sep 19 15:00:15 2012 @@ -24,14 +24,16 @@ import java.net.URI; import org.junit.Test; +import static org.junit.Assert.assertEquals; + import org.apache.fop.apps.io.InternalResourceResolver; import org.apache.fop.apps.io.ResourceResolver; import org.apache.fop.apps.io.ResourceResolverFactory; +import org.apache.fop.fonts.CIDSet; import org.apache.fop.fonts.CIDSubset; +import org.apache.fop.fonts.EmbeddingMode; import org.apache.fop.fonts.MultiByteFont; -import static org.junit.Assert.assertEquals; - /** * Test case for {@link PDFFactory}. */ @@ -45,7 +47,7 @@ public class PDFFactoryTestCase { public void testSubsetFontNamePrefix() { class MockedFont extends MultiByteFont { public MockedFont(InternalResourceResolver resolver) { - super(resolver); + super(resolver, EmbeddingMode.AUTO); } @Override @@ -54,8 +56,8 @@ public class PDFFactoryTestCase { } @Override - public CIDSubset getCIDSubset() { - return new CIDSubset(); + public CIDSet getCIDSet() { + return new CIDSubset(this); } } PDFDocument doc = new PDFDocument("Test"); Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java Wed Sep 19 15:00:15 2012 @@ -26,9 +26,11 @@ import org.apache.fop.apps.TIFFRendererC import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class TIFFRendererConfigParserTestCase - extends AbstractBitmapRendererConfigParserTester { +extends AbstractBitmapRendererConfigParserTester { public TIFFRendererConfigParserTestCase() { super(new TIFFRendererConfigParser()); @@ -47,9 +49,17 @@ public class TIFFRendererConfigParserTes @Test public void testCompression() throws Exception { - for (TIFFCompressionValues value : TIFFCompressionValues.values()) { + for (TIFFCompressionValue value : TIFFCompressionValue.values()) { parseConfig(createRenderer().setCompressionMode(value.getName())); assertEquals(value, getConfig().getCompressionType()); } } + + @Test + public void testSingleStrip() throws Exception { + parseConfig(createRenderer().setSingleStrip(true)); + assertTrue(getConfig().isSingleStrip()); + parseConfig(createRenderer().setSingleStrip(false)); + assertFalse(getConfig().isSingleStrip()); + } } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java Wed Sep 19 15:00:15 2012 @@ -23,14 +23,17 @@ import java.awt.image.BufferedImage; import org.junit.Test; + import org.apache.fop.apps.FopConfBuilder; import org.apache.fop.apps.MimeConstants; import org.apache.fop.apps.TIFFRendererConfBuilder; import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser; -import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T4; -import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T6; +import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T4; +import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T6; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class TIFFRendererConfiguratorTestCase extends AbstractBitmapRendererConfiguratorTest { @@ -51,7 +54,7 @@ public class TIFFRendererConfiguratorTes @Test @Override public void testColorModes() throws Exception { - for (TIFFCompressionValues value : TIFFCompressionValues.values()) { + for (TIFFCompressionValue value : TIFFCompressionValue.values()) { parseConfig(createBuilder().setCompressionMode(value.getName())); if (value == CCITT_T6 || value == CCITT_T4) { assertEquals(BufferedImage.TYPE_BYTE_BINARY, settings.getBufferedImageType()); @@ -60,4 +63,13 @@ public class TIFFRendererConfiguratorTes } } } + + @Test + public void testSingleStrip() throws Exception { + parseConfig(createBuilder().setSingleStrip(true)); + assertTrue(settings.getWriterParams().isSingleStrip()); + parseConfig(createBuilder().setSingleStrip(false)); + assertFalse(settings.getWriterParams().isSingleStrip()); + } + } Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/1.5/test.pdf URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/1.5/test.pdf?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/fop.xconf URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/fop.xconf?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== --- xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/fop.xconf (original) +++ xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/fop.xconf Wed Sep 19 15:00:15 2012 @@ -6,6 +6,7 @@ <font-base>../../resources/fonts/ttf/</font-base> <renderers> <renderer mime="application/pdf"> + <version>1.4</version> <filterList> <value>null</value> </filterList> Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/pdf/role.pdf URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/pdf/role.pdf?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== Binary files - no diff available. Modified: xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/pdf/role_non-standard.pdf URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_XGC_URI_Resolution/test/pdf/accessibility/pdf/role_non-standard.pdf?rev=1387628&r1=1387627&r2=1387628&view=diff ============================================================================== Binary files - no diff available. --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
