Browse Source

Merged changes from trunk up to revision 1351540


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1352963 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1^2
Vincent Hennebert 12 years ago
parent
commit
81e6ffaa6a
56 changed files with 1266 additions and 214 deletions
  1. 37
    0
      findbugs-exclude.xml
  2. BIN
      lib/xmlgraphics-commons-1.5svn.jar
  3. 18
    0
      src/documentation/content/xdocs/trunk/configuration.xml
  4. 8
    5
      src/documentation/content/xdocs/trunk/graphics.xml
  5. 2
    0
      src/java/META-INF/services/org.apache.fop.render.ImageHandler
  6. 2
    2
      src/java/org/apache/fop/afp/AFPGraphics2D.java
  7. 4
    2
      src/java/org/apache/fop/afp/modca/ImageObject.java
  8. 1
    1
      src/java/org/apache/fop/afp/modca/PresentationTextData.java
  9. 2
    1
      src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
  10. 3
    2
      src/java/org/apache/fop/apps/FOUserAgent.java
  11. 1
    1
      src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
  12. 1
    1
      src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java
  13. 10
    4
      src/java/org/apache/fop/fo/FOEventHandler.java
  14. 3
    2
      src/java/org/apache/fop/fo/properties/CondLengthProperty.java
  15. 10
    6
      src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
  16. 23
    11
      src/java/org/apache/fop/layoutmgr/BreakElement.java
  17. 5
    2
      src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
  18. 5
    1
      src/java/org/apache/fop/pdf/BitmapImage.java
  19. 1
    1
      src/java/org/apache/fop/pdf/PDFColor.java
  20. 4
    1
      src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
  21. 0
    6
      src/java/org/apache/fop/pdf/PDFObject.java
  22. 23
    31
      src/java/org/apache/fop/pdf/PDFResources.java
  23. 2
    1
      src/java/org/apache/fop/render/ImageHandler.java
  24. 2
    1
      src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
  25. 1
    1
      src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java
  26. 2
    2
      src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java
  27. 1
    1
      src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java
  28. 2
    1
      src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
  29. 2
    1
      src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
  30. 2
    1
      src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
  31. 2
    2
      src/java/org/apache/fop/render/intermediate/IFContext.java
  32. 4
    4
      src/java/org/apache/fop/render/intermediate/IFUtil.java
  33. 1
    1
      src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
  34. 2
    1
      src/java/org/apache/fop/render/java2d/Java2DPainter.java
  35. 2
    1
      src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
  36. 2
    1
      src/java/org/apache/fop/render/pcl/PCLPainter.java
  37. 68
    1
      src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
  38. 258
    0
      src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java
  39. 2
    71
      src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java
  40. 65
    0
      src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java
  41. 113
    0
      src/java/org/apache/fop/render/ps/ImageEncoderPNG.java
  42. 0
    6
      src/java/org/apache/fop/render/ps/NativeTextHandler.java
  43. 2
    1
      src/java/org/apache/fop/render/ps/PSDocumentHandler.java
  44. 111
    0
      src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java
  45. 19
    7
      src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java
  46. 1
    1
      src/java/org/apache/fop/svg/PDFAElementBridge.java
  47. 3
    2
      src/java/org/apache/fop/traits/MinOptMax.java
  48. 2
    2
      src/java/org/apache/fop/traits/TraitEnum.java
  49. 1
    1
      src/java/org/apache/fop/util/ColorExt.java
  50. 39
    21
      src/sandbox/org/apache/fop/render/mif/MIFHandler.java
  51. 2
    1
      src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
  52. 2
    1
      src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
  53. 21
    0
      status.xml
  54. 92
    0
      test/java/org/apache/fop/render/RawPNGTestUtil.java
  55. 142
    0
      test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java
  56. 133
    0
      test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java

+ 37
- 0
findbugs-exclude.xml View File

@@ -5171,4 +5171,41 @@
<Method name="getNonEmptyLevels"/>
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.AbstractImageAdapter"/>
<Method name="populateXObjectDictionaryForIndexColorModel"/>
<Bug pattern="OS_OPEN_STREAM"/>
</Match>
<Match>
<Class name="org.apache.fop.render.pdf.ImageRawPNGAdapter"/>
<Or>
<Method name="outputContents"/>
<Method name="setup"/>
</Or>
<Or>
<Bug pattern="OS_OPEN_STREAM"/>
<Bug pattern="OS_OPEN_STREAM_EXCEPTION_PATH"/>
</Or>
</Match>
<Match>
<Class name="org.apache.fop.render.ps.ImageEncoderPNG"/>
<Method name="writeTo"/>
<Bug pattern="OS_OPEN_STREAM"/>
</Match>
<Match>
<Or>
<Class name="org.apache.fop.render.pdf.PDFImageHandlerRawPNG"/>
<Class name="org.apache.fop.render.ps.PSImageHandlerRawPNG"/>
</Or>
<Method name="getSupportedImageFlavors"/>
<Bug pattern="EI_EXPOSE_REP"/>
</Match>
<Match>
<Class name="org.apache.fop.render.ps.PSImageHandlerRawPNG"/>
<Or>
<Method name="handleImage"/>
<Method name="generateForm"/>
</Or>
<Bug pattern="BC_UNCONFIRMED_CAST"/>
</Match>
</FindBugsFilter>

BIN
lib/xmlgraphics-commons-1.5svn.jar View File


+ 18
- 0
src/documentation/content/xdocs/trunk/configuration.xml View File

@@ -281,6 +281,24 @@
treated as zero penalty in most cases. For more details on the image loading framework,
please consult the documentation there.
</p>
<p>
The ImageLoaderPNG and ImageLoaderRawPNG have a hard-coded penalty of 1000 and as such the
ImageLoaderImageIO image loader will be selected by default when loading PNGs unless
the latter is disabled by awarding a INFINITE penalty to it, or one of the former two is
promoted by awarding a strong negative penalty (say, -10000) to it.
</p>
<source><![CDATA[<fop version="1.0">
[..]
<image-loading>
<penalty value="-10000"
class="org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawPNG"/>
<penalty value="INFINITE"
class="org.apache.xmlgraphics.image.loader.impl.ImageLoaderPNG"/>
<penalty value="INFINITE"
class="org.apache.xmlgraphics.image.loader.impl.imageio.ImageLoaderImageIO"/>
</image-loading>
<renderers....
</fop>]]></source>
</section>
<section id="renderers">
<title>Renderer configuration</title>

+ 8
- 5
src/documentation/content/xdocs/trunk/graphics.xml View File

@@ -108,7 +108,7 @@
<tr>
<td><a href="#png">PNG</a> (Portable Network Graphic)</td>
<td>bitmap</td>
<td/>
<td>(X)</td>
<td/>
<td>X</td>
</tr>
@@ -217,8 +217,8 @@
</tr>
<tr>
<td><a href="#png">PNG</a> (Portable Network Graphic)</td>
<td>X</td>
<td>X</td>
<td>X [2]</td>
<td>X [2]</td>
<td>X</td>
<td>X</td>
<td>X</td>
@@ -383,8 +383,11 @@
<section id="png">
<title>PNG</title>
<p>
PNG images are supported through an Image&amp;nbsp;I/O codec. Transparency is supported but
not guaranteed to work with every output format.
FOP native support of PNG only includes the variants with 8 bits per channel and without
interlacing. Native support requires using the ImageLoaderRawPNG image loader.
Support through a Image I/O codec can use either the internal XGC PNG codec or the JRE PNG
codec. The associated image loaders are, respectively, ImageLoaderPNG and ImageLoaderImageIO.
Transparency is supported but not guaranteed to work with every output format.
</p>
</section>
<section id="svg">

+ 2
- 0
src/java/META-INF/services/org.apache.fop.render.ImageHandler View File

@@ -1,6 +1,7 @@
org.apache.fop.render.pdf.PDFImageHandlerGraphics2D
org.apache.fop.render.pdf.PDFImageHandlerRenderedImage
org.apache.fop.render.pdf.PDFImageHandlerRawJPEG
org.apache.fop.render.pdf.PDFImageHandlerRawPNG
org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax
org.apache.fop.render.pdf.PDFImageHandlerSVG
org.apache.fop.render.java2d.Java2DImageHandlerRenderedImage
@@ -11,6 +12,7 @@ org.apache.fop.render.ps.PSImageHandlerRenderedImage
org.apache.fop.render.ps.PSImageHandlerEPS
org.apache.fop.render.ps.PSImageHandlerRawCCITTFax
org.apache.fop.render.ps.PSImageHandlerRawJPEG
org.apache.fop.render.ps.PSImageHandlerRawPNG
org.apache.fop.render.ps.PSImageHandlerGraphics2D
org.apache.fop.render.ps.PSImageHandlerSVG
org.apache.fop.render.afp.AFPImageHandlerRenderedImage

+ 2
- 2
src/java/org/apache/fop/afp/AFPGraphics2D.java View File

@@ -67,7 +67,7 @@ import org.apache.fop.svg.NativeImageHandler;

/**
* This is a concrete implementation of {@link AbstractGraphics2D} (and
* therefore of {@link Graphics2D}) which is able to generate GOCA byte
* therefore of {@link java.awt.Graphics2D}) which is able to generate GOCA byte
* codes.
*
* @see org.apache.xmlgraphics.java2d.AbstractGraphics2D
@@ -165,7 +165,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
}

/**
* Returns the AFP resource manager associated with this {@link Graphics2D} instance.
* Returns the AFP resource manager associated with this {@link java.awt.Graphics2D} instance.
* @return the resource manager
*/
public AFPResourceManager getResourceManager() {

+ 4
- 2
src/java/org/apache/fop/afp/modca/ImageObject.java View File

@@ -119,7 +119,8 @@ public class ImageObject extends AbstractDataObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
* @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
* @deprecated Use {@link org.apache.fop.afp.ioca.IDEStructureParameter#setColorModel(byte)}
* instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageSegment().setIDEColorModel(colorModel);
@@ -128,7 +129,8 @@ public class ImageObject extends AbstractDataObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
* @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
* @deprecated Use {@link org.apache.fop.afp.ioca.IDEStructureParameter#setSubtractive(boolean)}
* instead.
*/
public void setSubtractive(boolean subtractive) {
getImageSegment().setSubtractive(subtractive);

+ 1
- 1
src/java/org/apache/fop/afp/modca/PresentationTextData.java View File

@@ -46,7 +46,7 @@ import org.apache.fop.afp.util.BinaryUtils;
* which signal an alternate mode of processing for the content of the current
* Presentation Text data.
* <p>
* The content for this object can be created using {@link PtocaBuilder}.
* The content for this object can be created using {@link org.apache.fop.afp.ptoca.PtocaBuilder}.
*/
public class PresentationTextData extends AbstractAFPObject implements PtocaConstants {


+ 2
- 1
src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java View File

@@ -44,7 +44,8 @@ public class DefaultFOPResourceAccessor extends SimpleResourceAccessor {
* Constructor for resource to be accessed via the {@link FOUserAgent}. This contructor
* can take two base URIs: the category base URI is the one to use when differentiating between
* normal resources (ex. images) and font resources. So, if fonts need to be accessed, you can
* set the {@link FontManager}'s base URI instead of the one on the {@link FopFactory}.
* set the {@link org.apache.fop.fonts.FontManager}'s base URI instead of the one on the
* {@link org.apache.fop.apps.FopFactory}.
* @param userAgent the FO user agent
* @param categoryBaseURI the category base URI (may be null)
* @param baseURI the custom base URI to resolve relative URIs against (may be null)

+ 3
- 2
src/java/org/apache/fop/apps/FOUserAgent.java View File

@@ -355,7 +355,7 @@ public class FOUserAgent {
/**
* Sets font base URL.
* @param fontBaseUrl font base URL
* @deprecated Use {@link FontManager#setFontBaseURL(String)} instead.
* @deprecated Use {@link org.apache.fop.fonts.FontManager#setFontBaseURL(String)} instead.
*/
public void setFontBaseURL(String fontBaseUrl) {
try {
@@ -500,7 +500,8 @@ public class FOUserAgent {
/**
* Returns the font base URL.
* @return the font base URL
* @deprecated Use {@link FontManager#getFontBaseURL()} instead. This method is not used by FOP.
* @deprecated Use {@link org.apache.fop.fonts.FontManager#getFontBaseURL()} instead.
* This method is not used by FOP.
*/
public String getFontBaseURL() {
String fontBase = getFactory().getFontManager().getFontBaseURL();

+ 1
- 1
src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java View File

@@ -1783,9 +1783,9 @@ public class GlyphPositioningTable extends GlyphTable {
* Find device adjustment.
* @param fontSize the font size to search for
* @return an adjustment if font size matches an entry
* @asf.todo at present, assumes that 1 device unit equals one point
*/
public int findAdjustment ( int fontSize ) {
// [TODO] at present, assumes that 1 device unit equals one point
int fs = fontSize / 1000;
if ( fs < startSize ) {
return 0;

+ 1
- 1
src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java View File

@@ -360,7 +360,7 @@ public class IndicScriptProcessor extends DefaultScriptProcessor {
}

/** Abstract syllabizer. */
protected abstract static class Syllabizer {
protected abstract static class Syllabizer implements Comparable {
private String script;
private String language;
Syllabizer ( String script, String language ) {

+ 10
- 4
src/java/org/apache/fop/fo/FOEventHandler.java View File

@@ -123,11 +123,17 @@ public abstract class FOEventHandler {
public void endDocument() throws SAXException {
}

/** {@inheritDoc} */
/**
* Called upon start of root element.
* @param root element
*/
public void startRoot(Root root) {
}

/** {@inheritDoc} */
/**
* Called upon end of root element.
* @param root element
*/
public void endRoot(Root root) {
}

@@ -413,9 +419,9 @@ public abstract class FOEventHandler {

/**
* Process end of a Static.
* @param statisContent StaticContent that is ending
* @param staticContent StaticContent that is ending
*/
public void endStatic(StaticContent statisContent) {
public void endStatic(StaticContent staticContent) {
}



+ 3
- 2
src/java/org/apache/fop/fo/properties/CondLengthProperty.java View File

@@ -26,6 +26,7 @@ import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.util.CompareUtil;

/**
* Superclass for properties that have conditional lengths
@@ -192,8 +193,8 @@ public class CondLengthProperty extends Property implements CompoundDatatype {

if (obj instanceof CondLengthProperty) {
CondLengthProperty clp = (CondLengthProperty)obj;
return (this.length == clp.length
&& this.conditionality == clp.conditionality);
return (CompareUtil.equal(this.length, clp.length)
&& CompareUtil.equal(this.conditionality, clp.conditionality));
}
return false;
}

+ 10
- 6
src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java View File

@@ -41,12 +41,16 @@ public class BalancingColumnBreakingAlgorithm extends PageBreakingAlgorithm {
* @param topLevelLM the top level layout manager
* @param pageProvider the page provider
* @param layoutListener the layout listener
* @param alignment alignment of the paragraph/page. One of {@link Constants#EN_START},
* {@link Constants#EN_JUSTIFY}, {@link Constants#EN_CENTER},
* {@link Constants#EN_END}.
* For pages, {@link Constants#EN_BEFORE} and {@link Constants#EN_AFTER}
* are mapped to the corresponding inline properties,
* {@link Constants#EN_START} and {@link Constants#EN_END}.
* @param alignment alignment of the paragraph/page. One of
* {@link org.apache.fop.fo.Constants#EN_START},
* {@link org.apache.fop.fo.Constants#EN_JUSTIFY},
* {@link org.apache.fop.fo.Constants#EN_CENTER},
* {@link org.apache.fop.fo.Constants#EN_END}.
* For pages, {@link org.apache.fop.fo.Constants#EN_BEFORE} and
* {@link org.apache.fop.fo.Constants#EN_AFTER}
* are mapped to the corresponding inline properties,
* {@link org.apache.fop.fo.Constants#EN_START} and
* {@link org.apache.fop.fo.Constants#EN_END}.
* @param alignmentLast alignment of the paragraph's last line
* @param footnoteSeparatorLength length of footnote separator
* @param partOverflowRecovery {@code true} if too long elements should be moved to

+ 23
- 11
src/java/org/apache/fop/layoutmgr/BreakElement.java View File

@@ -46,8 +46,11 @@ public class BreakElement extends UnresolvedListElement {
* Create a new BreakElement for the given {@code position}, {@code penaltyValue}
* and {@code breakClass}. (Used principally to generate break-possibilities in
* ranges of content that must be kept together within the context corresponding
* to the {@code breakClass}; expected to be one of {@link Constants#EN_AUTO},
* {@link Constants#EN_LINE}, {@link Constants#EN_COLUMN} or {@link Constants#EN_PAGE})
* to the {@code breakClass}; expected to be one of
* {@link org.apache.fop.fo.Constants#EN_AUTO},
* {@link org.apache.fop.fo.Constants#EN_LINE},
* {@link org.apache.fop.fo.Constants#EN_COLUMN} or
* {@link org.apache.fop.fo.Constants#EN_PAGE})
* @param position the corresponding {@link Position}
* @param penaltyValue the penalty value
* @param breakClass the break class
@@ -64,9 +67,12 @@ public class BreakElement extends UnresolvedListElement {
* @param position the Position instance needed by the addAreas stage of the LMs.
* @param penaltyWidth the penalty width
* @param penaltyValue the penalty value for the penalty element to be constructed
* @param breakClass the break class of this penalty (one of {@link Constants#EN_AUTO},
* {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
* {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE})
* @param breakClass the break class of this penalty (one of
* {@link org.apache.fop.fo.Constants#EN_AUTO},
* {@link org.apache.fop.fo.Constants#EN_COLUMN},
* {@link org.apache.fop.fo.Constants#EN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_ODD_PAGE})
* @param context the layout context which contains the pending conditional elements
*/
public BreakElement(Position position, int penaltyWidth, int penaltyValue,
@@ -120,9 +126,12 @@ public class BreakElement extends UnresolvedListElement {
/**
* Returns the break class of this penalty.
*
* @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
* {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE},
* {@link Constants#EN_ODD_PAGE}
* @return one of
* {@link org.apache.fop.fo.Constants#EN_AUTO},
* {@link org.apache.fop.fo.Constants#EN_COLUMN},
* {@link org.apache.fop.fo.Constants#EN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}.
*/
public int getBreakClass() {
return breakClass;
@@ -131,9 +140,12 @@ public class BreakElement extends UnresolvedListElement {
/**
* Sets the break class.
*
* @param breakClass one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
* {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE},
* {@link Constants#EN_ODD_PAGE}
* @param breakClass one of
* {@link org.apache.fop.fo.Constants#EN_AUTO},
* {@link org.apache.fop.fo.Constants#EN_COLUMN},
* {@link org.apache.fop.fo.Constants#EN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}.
*/
public void setBreakClass(int breakClass) {
this.breakClass = breakClass;

+ 5
- 2
src/java/org/apache/fop/layoutmgr/KnuthPenalty.java View File

@@ -72,8 +72,11 @@ public class KnuthPenalty extends KnuthElement {
* @param penalty the penalty value of this penalty
* @param penaltyFlagged is this penalty flagged?
* @param breakClass the break class of this penalty (one of
* {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
* {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE})
* {@link org.apache.fop.fo.Constants#EN_AUTO},
* {@link org.apache.fop.fo.Constants#EN_COLUMN},
* {@link org.apache.fop.fo.Constants#EN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
* {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}).
* @param pos the Position stored in this penalty
* @param isAuxiliary is this penalty auxiliary?
*/

+ 5
- 1
src/java/org/apache/fop/pdf/BitmapImage.java View File

@@ -37,6 +37,7 @@ public class BitmapImage implements PDFImage {
private PDFColor transparent = null;
private String key;
private PDFDocument pdfDoc;
private PDFFilter pdfFilter;

/**
* Create a bitmap image.
@@ -208,9 +209,12 @@ public class BitmapImage implements PDFImage {
* {@inheritDoc}
*/
public PDFFilter getPDFFilter() {
return null;
return pdfFilter;
}

public void setPDFFilter(PDFFilter pdfFilter) {
this.pdfFilter = pdfFilter;
}
}



+ 1
- 1
src/java/org/apache/fop/pdf/PDFColor.java View File

@@ -30,7 +30,7 @@ import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
* image. And in this context, only RGB and Gray values are used.
* <p>
* Use of this class is discouraged. {@link PDFColorHandler} is now used for in-content color
* selection. For masked bitmaps, it may be wiser to switch to {@link Color} in the long run.
* selection. For masked bitmaps, it may be wiser to switch to {@link java.awt.Color} in the long run.
*/
public class PDFColor extends PDFPathPaint {
// could be 3.0 as well.

+ 4
- 1
src/java/org/apache/fop/pdf/PDFEmbeddedFile.java View File

@@ -38,7 +38,10 @@ public class PDFEmbeddedFile extends PDFStream {
put("Params", params);
}

/** {@inheritDoc} */
/**
* Determine if should encode on the fly.
* @return true if should encode on the fly
*/
protected boolean isEncodingOnTheFly() {
//Acrobat doesn't like an indirect /Length object in this case,
//but only when the embedded file is a PDF file.

+ 0
- 6
src/java/org/apache/fop/pdf/PDFObject.java View File

@@ -22,7 +22,6 @@ package org.apache.fop.pdf;
// Java
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -210,11 +209,6 @@ public abstract class PDFObject implements PDFWritable {
return pdf.length;
}

/** {@inheritDoc} */
public void outputInline(OutputStream out, Writer writer) throws IOException {
throw new UnsupportedOperationException("Don't use anymore: " + getClass().getName());
}

/** {@inheritDoc} */
public void outputInline(OutputStream out, StringBuilder textBuffer) throws IOException {
if (hasObjectNumber()) {

+ 23
- 31
src/java/org/apache/fop/pdf/PDFResources.java View File

@@ -21,9 +21,8 @@ package org.apache.fop.pdf;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

@@ -46,33 +45,33 @@ public class PDFResources extends PDFDictionary {
/**
* /Font objects keyed by their internal name
*/
protected Map fonts = new HashMap();
protected Map<String, PDFFont> fonts = new LinkedHashMap<String, PDFFont>();

/**
* Set of XObjects
*/
protected Set xObjects = new HashSet();
protected Set<PDFXObject> xObjects = new LinkedHashSet<PDFXObject>();

/**
* Set of patterns
*/
protected Set patterns = new HashSet();
protected Set<PDFPattern> patterns = new LinkedHashSet<PDFPattern>();

/**
* Set of shadings
*/
protected Set shadings = new HashSet();
protected Set<PDFShading> shadings = new LinkedHashSet<PDFShading>();

/**
* Set of ExtGStates
*/
protected Set gstates = new HashSet();
protected Set<PDFGState> gstates = new LinkedHashSet<PDFGState>();

/** Map of color spaces (key: color space name) */
protected Map colorSpaces = new HashMap();
protected Map<PDFName, PDFColorSpace> colorSpaces = new LinkedHashMap<PDFName, PDFColorSpace>();

/** Map of ICC color spaces (key: ICC profile description) */
protected Map iccColorSpaces = new HashMap();
protected Map<String, PDFICCBasedColorSpace> iccColorSpaces = new LinkedHashMap<String, PDFICCBasedColorSpace>();

/**
* create a /Resources object.
@@ -168,7 +167,7 @@ public class PDFResources extends PDFDictionary {
PDFICCBasedColorSpace icc = (PDFICCBasedColorSpace)colorSpace;
String desc = ColorProfileUtil.getICCProfileDescription(
icc.getICCStream().getICCProfile());
this.iccColorSpaces.put(desc, colorSpace);
this.iccColorSpaces.put(desc, icc);
}
}

@@ -178,7 +177,7 @@ public class PDFResources extends PDFDictionary {
* @return the requested color space or null if it wasn't found
*/
public PDFICCBasedColorSpace getICCColorSpaceByProfileName(String desc) {
PDFICCBasedColorSpace cs = (PDFICCBasedColorSpace)this.iccColorSpaces.get(desc);
PDFICCBasedColorSpace cs = this.iccColorSpaces.get(desc);
return cs;
}

@@ -188,7 +187,7 @@ public class PDFResources extends PDFDictionary {
* @return the requested color space or null if it wasn't found
*/
public PDFColorSpace getColorSpace(PDFName name) {
PDFColorSpace cs = (PDFColorSpace)this.colorSpaces.get(name);
PDFColorSpace cs = this.colorSpaces.get(name);
return cs;
}

@@ -202,28 +201,24 @@ public class PDFResources extends PDFDictionary {
if (!this.fonts.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
/* construct PDF dictionary of font object references */
Iterator fontIterator = this.fonts.keySet().iterator();
while (fontIterator.hasNext()) {
String fontName = (String)fontIterator.next();
dict.put(fontName, (PDFFont)this.fonts.get(fontName));
for (Map.Entry<String, PDFFont> entry : fonts.entrySet()) {
dict.put(entry.getKey(), entry.getValue());
}
put("Font", dict);
}

if (!this.shadings.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
for (Iterator iter = shadings.iterator(); iter.hasNext();) {
PDFShading currentShading = (PDFShading)iter.next();
dict.put(currentShading.getName(), currentShading);
for (PDFShading shading : shadings) {
dict.put(shading.getName(), shading);
}
put("Shading", dict);
}

if (!this.patterns.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
for (Iterator iter = patterns.iterator(); iter.hasNext();) {
PDFPattern currentPattern = (PDFPattern)iter.next();
dict.put(currentPattern.getName(), currentPattern);
for (PDFPattern pattern : patterns) {
dict.put(pattern.getName(), pattern);
}
put("Pattern", dict);
}
@@ -237,26 +232,23 @@ public class PDFResources extends PDFDictionary {

if (this.xObjects != null && !this.xObjects.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
for (Iterator iter = xObjects.iterator(); iter.hasNext();) {
PDFXObject xobj = (PDFXObject)iter.next();
dict.put(xobj.getName().toString(), xobj);
for (PDFXObject xObject : xObjects) {
dict.put(xObject.getName().toString(), xObject);
}
put("XObject", dict);
}

if (!this.gstates.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
for (Iterator iter = gstates.iterator(); iter.hasNext();) {
PDFGState gs = (PDFGState)iter.next();
dict.put(gs.getName(), gs);
for (PDFGState gstate : gstates) {
dict.put(gstate.getName(), gstate);
}
put("ExtGState", dict);
}

if (!this.colorSpaces.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
for (Iterator iter = colorSpaces.values().iterator(); iter.hasNext();) {
PDFColorSpace colorSpace = (PDFColorSpace)iter.next();
for (PDFColorSpace colorSpace : colorSpaces.values()) {
dict.put(colorSpace.getName(), colorSpace);
}
put("ColorSpace", dict);

+ 2
- 1
src/java/org/apache/fop/render/ImageHandler.java View File

@@ -33,7 +33,8 @@ public interface ImageHandler extends ImageHandlerBase {
* Indicates whether the image handler is compatible with the indicated target represented
* by the rendering context object and with the image to be processed. The image is also
* passed as a parameter because a handler might not support every subtype of image that is
* presented. For example: in the case of {@link ImageXMLDOM}, the image might carry an SVG
* presented. For example: in the case of
* {@link org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM}, the image might carry an SVG
* or some other XML format. One handler might only handle SVG but no other XML format.
* @param targetContext the target rendering context
* @param image the image to be processed (or null if only to check based on the rendering

+ 2
- 1
src/java/org/apache/fop/render/afp/AFPDocumentHandler.java View File

@@ -58,7 +58,8 @@ import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;

/**
* {@link IFDocumentHandler} implementation that produces AFP (MO:DCA).
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation that
* produces AFP (MO:DCA).
*/
public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
implements AFPCustomizable {

+ 1
- 1
src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java View File

@@ -27,7 +27,7 @@ import org.xml.sax.helpers.AttributesImpl;

/**
* This extension allows to include an AFP form map resource. It is implemented as an extension
* attachment ({@link ExtensionAttachment}).
* attachment ({@link org.apache.fop.fo.extensions.ExtensionAttachment}).
*/
public class AFPIncludeFormMap extends AFPExtensionAttachment {


+ 2
- 2
src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java View File

@@ -32,8 +32,8 @@ import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.extensions.ExtensionAttachment;

/**
* This class extends the {@link ExtensionObj} class. It represents the "include-form-map"
* extension in the FO tree.
* This class extends the {@link org.apache.fop.fo.extensions.ExtensionObj} class.
* It represents the "include-form-map" extension in the FO tree.
*/
public class AFPIncludeFormMapElement extends AbstractAFPExtensionObject {


+ 1
- 1
src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java View File

@@ -25,7 +25,7 @@ import org.xml.sax.helpers.AttributesImpl;

/**
* This extension allows to include an AFP Page Overlay resource. It is implemented as an extension
* attachment ({@link ExtensionAttachment}).
* attachment ({@link org.apache.fop.fo.extensions.ExtensionAttachment}).
*/
public class AFPPageOverlay extends AFPExtensionAttachment {


+ 2
- 1
src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java View File

@@ -47,7 +47,8 @@ import org.apache.fop.render.java2d.Java2DPainter;
import org.apache.fop.render.java2d.Java2DUtil;

/**
* Abstract {@link IFDocumentHandler} implementation for producing bitmap images.
* Abstract {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* for producing bitmap images.
*/
public abstract class AbstractBitmapDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {


+ 2
- 1
src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java View File

@@ -23,7 +23,8 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;

/**
* {@link IFDocumentHandler} implementation that produces PNG files.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that produces PNG files.
*/
public class PNGDocumentHandler extends AbstractBitmapDocumentHandler {


+ 2
- 1
src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java View File

@@ -23,7 +23,8 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;

/**
* {@link IFDocumentHandler} implementation that produces TIFF files.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that produces TIFF files.
*/
public class TIFFDocumentHandler extends AbstractBitmapDocumentHandler {


+ 2
- 2
src/java/org/apache/fop/render/intermediate/IFContext.java View File

@@ -145,7 +145,7 @@ public class IFContext {

/**
* Resets the current structure tree element.
* @see #setStructureTreeElement(String)
* @see #setStructureTreeElement(StructureTreeElement)
*/
public void resetStructureTreeElement() {
setStructureTreeElement(null);
@@ -154,7 +154,7 @@ public class IFContext {
/**
* Returns the current structure tree element.
* @return the structure tree element (or null if no element is active)
* @see #setStructureTreeElement(String)
* @see #setStructureTreeElement(StructureTreeElement)
*/
public StructureTreeElement getStructureTreeElement() {
return this.structureTreeElement;

+ 4
- 4
src/java/org/apache/fop/render/intermediate/IFUtil.java View File

@@ -147,8 +147,8 @@ public final class IFUtil {

/**
* Sets up the fonts on a document handler. If the document handler provides a configurator
* object the configuration from the {@link FopFactory} will be used. Otherwise,
* a default font configuration will be set up.
* object the configuration from the {@link org.apache.fop.apps.FopFactory} will be used.
* Otherwise, a default font configuration will be set up.
* @param documentHandler the document handler
* @param fontInfo the font info object (may be null)
* @throws FOPException if an error occurs while setting up the fonts
@@ -175,8 +175,8 @@ public final class IFUtil {

/**
* Sets up the fonts on a document handler. If the document handler provides a configurator
* object the configuration from the {@link FopFactory} will be used. Otherwise,
* a default font configuration will be set up.
* object the configuration from the {@link org.apache.fop.apps.FopFactory} will be used.
* Otherwise, a default font configuration will be set up.
* @param documentHandler the document handler
* @throws FOPException if an error occurs while setting up the fonts
*/

+ 1
- 1
src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java View File

@@ -36,7 +36,7 @@ import org.apache.fop.fonts.Typeface;

/**
* FontMetricsMapper that delegates most methods to an underlying
* {@link FontMetrics} instance. This class was designed to allow
* {@link org.apache.fop.fonts.FontMetrics} instance. This class was designed to allow
* the underlying {@link Font} to be loaded from a
* user-configured file not registered in the current graphics environment.
*/

+ 2
- 1
src/java/org/apache/fop/render/java2d/Java2DPainter.java View File

@@ -47,7 +47,8 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;

/**
* {@link IFPainter} implementation that paints on a Graphics2D instance.
* {@link org.apache.fop.render.intermediate.IFPainter} implementation
* that paints on a Graphics2D instance.
*/
public class Java2DPainter extends AbstractIFPainter {


+ 2
- 1
src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java View File

@@ -45,7 +45,8 @@ import org.apache.fop.render.java2d.Java2DUtil;
import org.apache.fop.render.pcl.extensions.PCLElementMapping;

/**
* {@link IFDocumentHandler} implementation that produces PCL 5.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that produces PCL 5.
*/
public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
implements PCLConstants {

+ 2
- 1
src/java/org/apache/fop/render/pcl/PCLPainter.java View File

@@ -58,7 +58,8 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;

/**
* {@link IFPainter} implementation that produces PCL 5.
* {@link org.apache.fop.render.intermediate.IFPainter} implementation
* that produces PCL 5.
*/
public class PCLPainter extends AbstractIFPainter implements PCLConstants {


+ 68
- 1
src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java View File

@@ -20,13 +20,16 @@
package org.apache.fop.render.pdf;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.IndexColorModel;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;

import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFConformanceException;
import org.apache.fop.pdf.PDFDeviceColorSpace;
@@ -50,7 +53,9 @@ public abstract class AbstractImageAdapter implements PDFImage {
/** the image */
protected Image image;

private PDFICCStream pdfICCStream = null;
private PDFICCStream pdfICCStream;

private static final int MAX_HIVAL = 255;

/**
* Creates a new PDFImage from an Image instance.
@@ -202,6 +207,68 @@ public abstract class AbstractImageAdapter implements PDFImage {
//nop
}

/**
* This is to be used by populateXObjectDictionary() when the image is palette based.
* @param dict the dictionary to fill in
* @param icm the image color model
*/
protected void populateXObjectDictionaryForIndexColorModel(PDFDictionary dict, IndexColorModel icm) {
PDFArray indexed = new PDFArray(dict);
indexed.add(new PDFName("Indexed"));
if (icm.getColorSpace().getType() != ColorSpace.TYPE_RGB) {
log.warn("Indexed color space is not using RGB as base color space."
+ " The image may not be handled correctly." + " Base color space: "
+ icm.getColorSpace() + " Image: " + image.getInfo());
}
indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
int c = icm.getMapSize();
int hival = c - 1;
if (hival > MAX_HIVAL) {
throw new UnsupportedOperationException("hival must not go beyond " + MAX_HIVAL);
}
indexed.add(Integer.valueOf(hival));
int[] palette = new int[c];
icm.getRGBs(palette);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
for (int i = 0; i < c; i++) {
// TODO Probably doesn't work for non RGB based color spaces
// See log warning above
int entry = palette[i];
baout.write((entry & 0xFF0000) >> 16);
baout.write((entry & 0xFF00) >> 8);
baout.write(entry & 0xFF);
}
indexed.add(baout.toByteArray());

dict.put("ColorSpace", indexed);
dict.put("BitsPerComponent", icm.getPixelSize());

Integer index = getIndexOfFirstTransparentColorInPalette(icm);
if (index != null) {
PDFArray mask = new PDFArray(dict);
mask.add(index);
mask.add(index);
dict.put("Mask", mask);
}
}

private static Integer getIndexOfFirstTransparentColorInPalette(IndexColorModel icm) {
byte[] alphas = new byte[icm.getMapSize()];
byte[] reds = new byte[icm.getMapSize()];
byte[] greens = new byte[icm.getMapSize()];
byte[] blues = new byte[icm.getMapSize()];
icm.getAlphas(alphas);
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
for (int i = 0; i < icm.getMapSize(); i++) {
if ((alphas[i] & 0xFF) == 0) {
return Integer.valueOf(i);
}
}
return null;
}

/**
* Converts a ColorSpace object to a PDFColorSpace object.
* @param cs ColorSpace instance

+ 258
- 0
src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java View File

@@ -0,0 +1,258 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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$ */
// Original author: Matthias Reichenbacher
package org.apache.fop.render.pdf;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
import org.apache.fop.pdf.BitmapImage;
import org.apache.fop.pdf.FlateFilter;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFFilter;
import org.apache.fop.pdf.PDFFilterException;
import org.apache.fop.pdf.PDFFilterList;
import org.apache.fop.pdf.PDFICCStream;
import org.apache.fop.pdf.PDFReference;
public class ImageRawPNGAdapter extends AbstractImageAdapter {
/** logging instance */
private static Log log = LogFactory.getLog(ImageRawPNGAdapter.class);
private PDFICCStream pdfICCStream;
private PDFFilter pdfFilter;
private String maskRef;
private PDFReference softMask;
private int numberOfInterleavedComponents;
/**
* Creates a new PDFImage from an Image instance.
* @param image the image
* @param key XObject key
*/
public ImageRawPNGAdapter(ImageRawPNG image, String key) {
super(image, key);
}
/** {@inheritDoc} */
public void setup(PDFDocument doc) {
super.setup(doc);
ColorModel cm = ((ImageRawPNG) this.image).getColorModel();
if (cm instanceof IndexColorModel) {
numberOfInterleavedComponents = 1;
} else {
// this can be 1 (gray), 2 (gray + alpha), 3 (rgb) or 4 (rgb + alpha)
// numberOfInterleavedComponents = (cm.hasAlpha() ? 1 : 0) + cm.getNumColorComponents();
numberOfInterleavedComponents = cm.getNumComponents();
}
// set up image compression for non-alpha channel
FlateFilter flate;
try {
flate = new FlateFilter();
flate.setApplied(true);
flate.setPredictor(FlateFilter.PREDICTION_PNG_OPT);
if (numberOfInterleavedComponents < 3) {
// means palette (1) or gray (1) or gray + alpha (2)
flate.setColors(1);
} else {
// means rgb (3) or rgb + alpha (4)
flate.setColors(3);
}
flate.setColumns(image.getSize().getWidthPx());
flate.setBitsPerComponent(this.getBitsPerComponent());
} catch (PDFFilterException e) {
throw new RuntimeException("FlateFilter configuration error", e);
}
this.pdfFilter = flate;
// Handle transparency channel if applicable; note that for palette images the transparency is
// not TRANSLUCENT
if (cm.hasAlpha() && cm.getTransparency() == ColorModel.TRANSLUCENT) {
doc.getProfile().verifyTransparencyAllowed(image.getInfo().getOriginalURI());
// TODO: Implement code to combine image with background color if transparency is not allowed
// here we need to inflate the PNG pixel data, which includes alpha, separate the alpha channel
// and then deflate it back again
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater());
InputStream in = ((ImageRawStream) image).createInputStream();
try {
InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
DataInputStream dataStream = new DataInputStream(infStream);
// offset is the byte offset of the alpha component
int offset = numberOfInterleavedComponents - 1; // 1 for GA, 3 for RGBA
int numColumns = image.getSize().getWidthPx();
int bytesPerRow = numberOfInterleavedComponents * numColumns;
int filter;
// read line by line; the first byte holds the filter
while ((filter = dataStream.read()) != -1) {
byte[] bytes = new byte[bytesPerRow];
dataStream.readFully(bytes, 0, bytesPerRow);
dos.write((byte) filter);
for (int j = 0; j < numColumns; j++) {
dos.write(bytes, offset, 1);
offset += numberOfInterleavedComponents;
}
offset = numberOfInterleavedComponents - 1;
}
dos.close();
} catch (IOException e) {
throw new RuntimeException("Error processing transparency channel:", e);
} finally {
IOUtils.closeQuietly(in);
}
// set up alpha channel compression
FlateFilter transFlate;
try {
transFlate = new FlateFilter();
transFlate.setApplied(true);
transFlate.setPredictor(FlateFilter.PREDICTION_PNG_OPT);
transFlate.setColors(1);
transFlate.setColumns(image.getSize().getWidthPx());
transFlate.setBitsPerComponent(this.getBitsPerComponent());
} catch (PDFFilterException e) {
throw new RuntimeException("FlateFilter configuration error", e);
}
BitmapImage alphaMask = new BitmapImage("Mask:" + this.getKey(), image.getSize().getWidthPx(),
image.getSize().getHeightPx(), baos.toByteArray(), null);
alphaMask.setPDFFilter(transFlate);
alphaMask.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
softMask = doc.addImage(null, alphaMask).makeReference();
}
}
/** {@inheritDoc} */
public PDFDeviceColorSpace getColorSpace() {
// DeviceGray, DeviceRGB, or DeviceCMYK
return toPDFColorSpace(image.getColorSpace());
}
/** {@inheritDoc} */
public int getBitsPerComponent() {
return ((ImageRawPNG) this.image).getBitDepth();
}
/** {@inheritDoc} */
public boolean isTransparent() {
return ((ImageRawPNG) this.image).isTransparent();
}
/** {@inheritDoc} */
public PDFColor getTransparentColor() {
return new PDFColor(((ImageRawPNG) this.image).getTransparentColor());
}
/** {@inheritDoc} */
public String getMask() {
return maskRef;
}
/** {@inheritDoc} */
public String getSoftMask() {
return softMask.toString();
}
/** {@inheritDoc} */
public PDFReference getSoftMaskReference() {
return softMask;
}
/** {@inheritDoc} */
public PDFFilter getPDFFilter() {
return pdfFilter;
}
/** {@inheritDoc} */
public void outputContents(OutputStream out) throws IOException {
InputStream in = ((ImageRawStream) image).createInputStream();
try {
if (numberOfInterleavedComponents == 1 || numberOfInterleavedComponents == 3) {
// means we have Gray, RGB, or Palette
IOUtils.copy(in, out);
} else {
// means we have Gray + alpha or RGB + alpha
// TODO: since we have alpha here do this when the alpha channel is extracted
int numBytes = numberOfInterleavedComponents - 1; // 1 for Gray, 3 for RGB
int numColumns = image.getSize().getWidthPx();
InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
DataInputStream dataStream = new DataInputStream(infStream);
int offset = 0;
int bytesPerRow = numberOfInterleavedComponents * numColumns;
int filter;
// here we need to inflate the PNG pixel data, which includes alpha, separate the alpha
// channel and then deflate the RGB channels back again
DeflaterOutputStream dos = new DeflaterOutputStream(out, new Deflater());
while ((filter = dataStream.read()) != -1) {
byte[] bytes = new byte[bytesPerRow];
dataStream.readFully(bytes, 0, bytesPerRow);
dos.write((byte) filter);
for (int j = 0; j < numColumns; j++) {
dos.write(bytes, offset, numBytes);
offset += numberOfInterleavedComponents;
}
offset = 0;
}
dos.close();
}
} finally {
IOUtils.closeQuietly(in);
}
}
/** {@inheritDoc} */
public PDFICCStream getICCStream() {
return pdfICCStream;
}
/** {@inheritDoc} */
public String getFilterHint() {
return PDFFilterList.PRECOMPRESSED_FILTER;
}
public void populateXObjectDictionary(PDFDictionary dict) {
ColorModel cm = ((ImageRawPNG) image).getColorModel();
if (cm instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel) cm;
super.populateXObjectDictionaryForIndexColorModel(dict, icm);
}
}
}

+ 2
- 71
src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java View File

@@ -27,8 +27,6 @@ import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@@ -36,14 +34,12 @@ import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;

import org.apache.fop.pdf.AlphaRasterImage;
import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFFilter;
import org.apache.fop.pdf.PDFFilterList;
import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFReference;

/**
@@ -162,30 +158,6 @@ public class ImageRenderedAdapter extends AbstractImageAdapter {
return (getImage().getTransparentColor() != null);
}

private static Integer getIndexOfFirstTransparentColorInPalette(RenderedImage image) {
ColorModel cm = image.getColorModel();
if (cm instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel)cm;
//Identify the transparent color in the palette
byte[] alphas = new byte[icm.getMapSize()];
byte[] reds = new byte[icm.getMapSize()];
byte[] greens = new byte[icm.getMapSize()];
byte[] blues = new byte[icm.getMapSize()];
icm.getAlphas(alphas);
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
for (int i = 0;
i < ((IndexColorModel) cm).getMapSize();
i++) {
if ((alphas[i] & 0xFF) == 0) {
return Integer.valueOf(i);
}
}
}
return null;
}

/** {@inheritDoc} */
@Override
public PDFColor getTransparentColor() {
@@ -230,54 +202,13 @@ public class ImageRenderedAdapter extends AbstractImageAdapter {
}
}

private static final int MAX_HIVAL = 255;

/** {@inheritDoc} */
@Override
public void populateXObjectDictionary(PDFDictionary dict) {
ColorModel cm = getEffectiveColorModel();
if (cm instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel)cm;
PDFArray indexed = new PDFArray(dict);
indexed.add(new PDFName("Indexed"));

if (icm.getColorSpace().getType() != ColorSpace.TYPE_RGB) {
log.warn("Indexed color space is not using RGB as base color space."
+ " The image may not be handled correctly."
+ " Base color space: " + icm.getColorSpace()
+ " Image: " + image.getInfo());
}
indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
int c = icm.getMapSize();
int hival = c - 1;
if (hival > MAX_HIVAL) {
throw new UnsupportedOperationException("hival must not go beyond " + MAX_HIVAL);
}
indexed.add(Integer.valueOf(hival));
int[] palette = new int[c];
icm.getRGBs(palette);
ByteArrayOutputStream baout = new ByteArrayOutputStream();
for (int i = 0; i < c; i++) {
//TODO Probably doesn't work for non RGB based color spaces
//See log warning above
int entry = palette[i];
baout.write((entry & 0xFF0000) >> 16);
baout.write((entry & 0xFF00) >> 8);
baout.write(entry & 0xFF);
}
indexed.add(baout.toByteArray());
IOUtils.closeQuietly(baout);

dict.put("ColorSpace", indexed);
dict.put("BitsPerComponent", icm.getPixelSize());

Integer index = getIndexOfFirstTransparentColorInPalette(getImage().getRenderedImage());
if (index != null) {
PDFArray mask = new PDFArray(dict);
mask.add(index);
mask.add(index);
dict.put("Mask", mask);
}
IndexColorModel icm = (IndexColorModel) cm;
super.populateXObjectDictionaryForIndexColorModel(dict, icm);
}
}


+ 65
- 0
src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java View File

@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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$ */

// Original author: Matthias Reichenbacher

package org.apache.fop.render.pdf;

import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;

import org.apache.fop.pdf.PDFImage;
import org.apache.fop.render.RenderingContext;

/**
* Image handler implementation which handles CCITT encoded images (CCITT fax group 3/4)
* for PDF output.
*/
public class PDFImageHandlerRawPNG extends AbstractPDFImageHandler {

private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RAW_PNG};

@Override
PDFImage createPDFImage(Image image, String xobjectKey) {
return new ImageRawPNGAdapter((ImageRawPNG) image, xobjectKey);
}

/** {@inheritDoc} */
public int getPriority() {
return 100;
}

/** {@inheritDoc} */
public Class<ImageRawPNG> getSupportedImageClass() {
return ImageRawPNG.class;
}

/** {@inheritDoc} */
public ImageFlavor[] getSupportedImageFlavors() {
return FLAVORS;
}

/** {@inheritDoc} */
public boolean isCompatible(RenderingContext targetContext, Image image) {
return (image == null || image instanceof ImageRawPNG)
&& targetContext instanceof PDFRenderingContext;
}

}

+ 113
- 0
src/java/org/apache/fop/render/ps/ImageEncoderPNG.java View File

@@ -0,0 +1,113 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.ps;

import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import org.apache.commons.io.IOUtils;

import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
import org.apache.xmlgraphics.ps.ImageEncoder;

/**
* ImageEncoder implementation for PNG images.
*/
public class ImageEncoderPNG implements ImageEncoder {
private final ImageRawPNG image;
private int numberOfInterleavedComponents;

/**
* Main constructor
* @param image the PNG image
*/
public ImageEncoderPNG(ImageRawPNG image) {
this.image = image;
ColorModel cm = ((ImageRawPNG) this.image).getColorModel();
if (cm instanceof IndexColorModel) {
numberOfInterleavedComponents = 1;
} else {
// this can be 1 (gray), 2 (gray + alpha), 3 (rgb) or 4 (rgb + alpha)
// numberOfInterleavedComponents = (cm.hasAlpha() ? 1 : 0) + cm.getNumColorComponents();
numberOfInterleavedComponents = cm.getNumComponents();
}
}

/** {@inheritDoc} */
public void writeTo(OutputStream out) throws IOException {
// TODO: refactor this code with equivalent PDF code
InputStream in = ((ImageRawStream) image).createInputStream();
try {
if (numberOfInterleavedComponents == 1 || numberOfInterleavedComponents == 3) {
// means we have Gray, RGB, or Palette
IOUtils.copy(in, out);
} else {
// means we have Gray + alpha or RGB + alpha
int numBytes = numberOfInterleavedComponents - 1; // 1 for Gray, 3 for RGB
int numColumns = image.getSize().getWidthPx();
InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
DataInputStream dataStream = new DataInputStream(infStream);
int offset = 0;
int bytesPerRow = numberOfInterleavedComponents * numColumns;
int filter;
// here we need to inflate the PNG pixel data, which includes alpha, separate the alpha
// channel and then deflate the RGB channels back again
// TODO: not using the baos below and using the original out instead (as happens in PDF)
// would be preferable but that does not work with the rest of the postscript code; this
// needs to be revisited
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(/* out */baos, new Deflater());
while ((filter = dataStream.read()) != -1) {
byte[] bytes = new byte[bytesPerRow];
dataStream.readFully(bytes, 0, bytesPerRow);
dos.write((byte) filter);
for (int j = 0; j < numColumns; j++) {
dos.write(bytes, offset, numBytes);
offset += numberOfInterleavedComponents;
}
offset = 0;
}
dos.close();
IOUtils.copy(new ByteArrayInputStream(baos.toByteArray()), out);
}
} finally {
IOUtils.closeQuietly(in);
}
}

/** {@inheritDoc} */
public String getImplicitFilter() {
String filter = "<< /Predictor 15 /Columns " + image.getSize().getWidthPx();
filter += " /Colors " + (numberOfInterleavedComponents > 2 ? 3 : 1);
filter += " /BitsPerComponent " + image.getBitDepth() + " >> /FlateDecode";
return filter;
}
}

+ 0
- 6
src/java/org/apache/fop/render/ps/NativeTextHandler.java View File

@@ -100,12 +100,6 @@ public class NativeTextHandler implements PSTextHandler {
//nop
}

/** {@inheritDoc} */
public void drawString(String text, float x, float y) throws IOException {
// TODO Remove me after removing the deprecated method in TextHandler.
throw new UnsupportedOperationException("Deprecated method!");
}

/**
* Draw a string to the PostScript document. The text is painted using
* text operations.

+ 2
- 1
src/java/org/apache/fop/render/ps/PSDocumentHandler.java View File

@@ -64,7 +64,8 @@ import org.apache.fop.render.ps.extensions.PSSetPageDevice;
import org.apache.fop.render.ps.extensions.PSSetupCode;

/**
* {@link IFDocumentHandler} implementation that produces PostScript.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that produces PostScript.
*/
public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {


+ 111
- 0
src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java View File

@@ -0,0 +1,111 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.ps;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.io.IOException;

import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
import org.apache.xmlgraphics.ps.FormGenerator;
import org.apache.xmlgraphics.ps.ImageEncoder;
import org.apache.xmlgraphics.ps.ImageFormGenerator;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSImageUtils;

import org.apache.fop.render.RenderingContext;

/**
* Image handler implementation which handles raw (not decoded) PNG images for PostScript output.
*/
public class PSImageHandlerRawPNG implements PSImageHandler {

private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RAW_PNG};

/** {@inheritDoc} */
public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException {
PSRenderingContext psContext = (PSRenderingContext) context;
PSGenerator gen = psContext.getGenerator();
ImageRawPNG png = (ImageRawPNG) image;

float x = (float) pos.getX() / 1000f;
float y = (float) pos.getY() / 1000f;
float w = (float) pos.getWidth() / 1000f;
float h = (float) pos.getHeight() / 1000f;
Rectangle2D targetRect = new Rectangle2D.Float(x, y, w, h);

ImageEncoder encoder = new ImageEncoderPNG(png);
ImageInfo info = image.getInfo();
Dimension imgDim = info.getSize().getDimensionPx();
String imgDescription = image.getClass().getName();
ColorModel cm = png.getColorModel();

PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen);
}

/** {@inheritDoc} */
public void generateForm(RenderingContext context, Image image, PSImageFormResource form)
throws IOException {
PSRenderingContext psContext = (PSRenderingContext) context;
PSGenerator gen = psContext.getGenerator();
ImageRawPNG png = (ImageRawPNG) image;
ImageInfo info = image.getInfo();
String imageDescription = info.getMimeType() + " " + info.getOriginalURI();

ImageEncoder encoder = new ImageEncoderPNG(png);
FormGenerator formGen = new ImageFormGenerator(form.getName(), imageDescription, info.getSize()
.getDimensionPt(), info.getSize().getDimensionPx(), encoder, png.getColorSpace(),
false);
formGen.generate(gen);
}

/** {@inheritDoc} */
public int getPriority() {
return 200;
}

/** {@inheritDoc} */
public Class<ImageRawPNG> getSupportedImageClass() {
return ImageRawPNG.class;
}

/** {@inheritDoc} */
public ImageFlavor[] getSupportedImageFlavors() {
return FLAVORS;
}

/** {@inheritDoc} */
public boolean isCompatible(RenderingContext targetContext, Image image) {
if (targetContext instanceof PSRenderingContext) {
PSRenderingContext psContext = (PSRenderingContext) targetContext;
// The filters required for this implementation need PS level 2 or higher
if (psContext.getGenerator().getPSLevel() >= 2) {
return (image == null || image instanceof ImageRawPNG);
}
}
return false;
}

}

+ 19
- 7
src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java View File

@@ -19,7 +19,10 @@

package org.apache.fop.render.ps;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.io.IOException;

@@ -28,6 +31,8 @@ import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.FormGenerator;
import org.apache.xmlgraphics.ps.ImageEncoder;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.ps.ImageFormGenerator;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSImageUtils;
@@ -47,17 +52,24 @@ public class PSImageHandlerRenderedImage implements PSImageHandler {
/** {@inheritDoc} */
public void handleImage(RenderingContext context, Image image, Rectangle pos)
throws IOException {
PSRenderingContext psContext = (PSRenderingContext)context;
PSRenderingContext psContext = (PSRenderingContext) context;
PSGenerator gen = psContext.getGenerator();
ImageRendered imageRend = (ImageRendered)image;
ImageRendered imageRend = (ImageRendered) image;

float x = (float)pos.getX() / 1000f;
float y = (float)pos.getY() / 1000f;
float w = (float)pos.getWidth() / 1000f;
float h = (float)pos.getHeight() / 1000f;
float x = (float) pos.getX() / 1000f;
float y = (float) pos.getY() / 1000f;
float w = (float) pos.getWidth() / 1000f;
float h = (float) pos.getHeight() / 1000f;
Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);

RenderedImage ri = imageRend.getRenderedImage();
PSImageUtils.renderBitmapImage(ri, x, y, w, h, gen);
ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(ri);
Dimension imgDim = new Dimension(ri.getWidth(), ri.getHeight());
String imgDescription = ri.getClass().getName();
ImageEncodingHelper helper = new ImageEncodingHelper(ri);
ColorModel cm = helper.getEncodedColorModel();

PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen);
}

/** {@inheritDoc} */

+ 1
- 1
src/java/org/apache/fop/svg/PDFAElementBridge.java View File

@@ -64,7 +64,7 @@ public class PDFAElementBridge extends AbstractGraphicsNodeBridge {
}

/**
* Creates a {@link CompositeGraphicsNode}.
* Creates a {@link org.apache.batik.gvt.CompositeGraphicsNode}.
* @return a new PDFANode
*/
protected GraphicsNode instantiateGraphicsNode() {

+ 3
- 2
src/java/org/apache/fop/traits/MinOptMax.java View File

@@ -22,8 +22,9 @@ package org.apache.fop.traits;
import java.io.Serializable;

/**
* This class holds the resolved (as mpoints) form of a {@link LengthRangeProperty LengthRange} or
* {@link SpaceProperty Space} type property value.
* This class holds the resolved (as mpoints) form of a
* {@link org.apache.fop.fo.properties.LengthRangeProperty} or
* {@link org.apache.fop.fo.properties.SpaceProperty} type property value.
* <p/>
* Instances of this class are immutable. All arithmetic methods like {@link #plus(MinOptMax) plus},
* {@link #minus(MinOptMax) minus} or {@link #mult(int) mult} return a different instance. So it is

+ 2
- 2
src/java/org/apache/fop/traits/TraitEnum.java View File

@@ -30,7 +30,7 @@ public abstract class TraitEnum implements Serializable {
/**
* Constructor to add a new named item.
* @param name Name of the item.
* @param enumValue the {@link Constants}.EN_* value
* @param enumValue the {@link org.apache.fop.fo.Constants}.EN_* value
*/
protected TraitEnum(String name, int enumValue) {
this.name = name;
@@ -46,7 +46,7 @@ public abstract class TraitEnum implements Serializable {
}

/**
* Returns the enumeration value (one of {@link Constants}.EN_*).
* Returns the enumeration value (one of {@link org.apache.fop.fo.Constants}.EN_*).
* @return the enumeration value
*/
public int getEnumValue() {

+ 1
- 1
src/java/org/apache/fop/util/ColorExt.java View File

@@ -28,7 +28,7 @@ import java.util.Arrays;
* <p>
* This class extends java.awt.Color class keeping track of the original color
* property values specified by the fo user in a rgb-icc call.
* @deprecated Replaced by {@link ColorWithAlternatives}
* @deprecated Replaced by {@link org.apache.xmlgraphics.java2d.color.ColorWithAlternatives}
*/
@Deprecated
public final class ColorExt extends Color {

+ 39
- 21
src/sandbox/org/apache/fop/render/mif/MIFHandler.java View File

@@ -29,8 +29,10 @@ import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.FootnoteBody;
@@ -39,6 +41,8 @@ import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
@@ -51,6 +55,7 @@ import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.render.DefaultFontResolver;

@@ -267,27 +272,27 @@ public class MIFHandler extends FOEventHandler {
}

/** {@inheritDoc} */
public void startListLabel() {
public void startListLabel(ListItemLabel listItemLabel) {
}

/** {@inheritDoc} */
public void endListLabel() {
public void endListLabel(ListItemLabel listItemLabel) {
}

/** {@inheritDoc} */
public void startListBody() {
public void startListBody(ListItemBody listItemBody) {
}

/** {@inheritDoc} */
public void endListBody() {
public void endListBody(ListItemBody listItemBody) {
}

/** {@inheritDoc} */
public void startStatic() {
public void startStatic(StaticContent staticContent) {
}

/** {@inheritDoc} */
public void endStatic() {
public void endStatic(StaticContent staticContent) {
}

/** {@inheritDoc} */
@@ -303,7 +308,7 @@ public class MIFHandler extends FOEventHandler {
}

/** {@inheritDoc} */
public void endLink() {
public void endLink(BasicLink basicLink) {
}

/** {@inheritDoc} */
@@ -315,7 +320,11 @@ public class MIFHandler extends FOEventHandler {
}

/** {@inheritDoc} */
public void foreignObject(InstreamForeignObject ifo) {
public void startInstreamForeignObject(InstreamForeignObject ifo) {
}

/** {@inheritDoc} */
public void endInstreamForeignObject(InstreamForeignObject ifo) {
}

/** {@inheritDoc} */
@@ -335,19 +344,37 @@ public class MIFHandler extends FOEventHandler {
}

/** {@inheritDoc} */
public void leader(Leader l) {
public void startLeader(Leader l) {
}

/** {@inheritDoc} */
public void endLeader(Leader l) {
}

public void character(Character c) {
appendCharacters ( new String ( new char[] {c.getCharacter()} ) );
}

/** {@inheritDoc} */
public void characters(FOText foText) {
appendCharacters ( foText.getCharSequence().toString() );
}

/** {@inheritDoc} */
public void startPageNumber(PageNumber pagenum) {
}

/** {@inheritDoc} */
public void characters(char[] data, int start, int length) {
public void endPageNumber(PageNumber pagenum) {
}

private void appendCharacters ( String str ) {
if (para != null) {
String str = new String(data, start, length);
str = str.trim();
// break into nice length chunks
if (str.length() == 0) {
return;
}

MIFElement line = new MIFElement("ParaLine");
MIFElement prop = new MIFElement("TextRectID");
prop.setValue("2");
@@ -355,17 +382,8 @@ public class MIFHandler extends FOEventHandler {
prop = new MIFElement("String");
prop.setValue("\"" + str + "\"");
line.addElement(prop);

para.addElement(line);
}
}

/** {@inheritDoc} */
public void startPageNumber(PageNumber pagenum) {
}

/** {@inheritDoc} */
public void endPageNumber(PageNumber pagenum) {
}
}


+ 2
- 1
src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java View File

@@ -54,7 +54,8 @@ import org.apache.fop.util.GenerationHelperContentHandler;
import org.apache.fop.util.XMLUtil;

/**
* {@link IFDocumentHandler} implementation that writes SVG 1.1.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that writes SVG 1.1.
*/
public class SVGDocumentHandler extends AbstractSVGDocumentHandler {


+ 2
- 1
src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java View File

@@ -32,7 +32,8 @@ import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.util.XMLUtil;

/**
* {@link IFDocumentHandler} implementation that writes SVG Print.
* {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
* that writes SVG Print.
*/
public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler {


+ 21
- 0
status.xml View File

@@ -63,6 +63,27 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
<action context="Images" dev="GA" type="update" fixes-bug="40676" due-to="Luis Bernardo">
Update site documentation about PNG image loading configuration and support.
</action>
<action context="Images" dev="GA" type="update" fixes-bug="40676" due-to="Luis Bernardo">
Fix newly introduced findbugs warnings.
</action>
<action context="Images" dev="GA" type="fix" fixes-bug="40676" due-to="Luis Bernardo, Matthias Reischenbacher">
Support use of ImageLoaderRawPNG decoder in order to prevent re-encoding of PNG images (and unnecssary output file bloat).
</action>
<action context="Code" dev="GA" type="fix" fixes-bug="53412" due-to="Alexios Giotis">
Eliminate incorrect use of object identity which produces excessive property cache collisions.
</action>
<action context="Code" dev="GA" type="fix">
Eliminate javadocs warnings.
</action>
<action context="Code" dev="GA" type="update" fixes-bug="53055">
Update xmlgraphics common jar to reflect recent fixes in XGC.
</action>
<action context="Code" dev="GA" type="update" fixes-bug="43940" due-to="Julien Aymé">
Fix handling of NaN, {+,-}Infinity, and other edge cases. Submitted by Julien Aymé.
</action>
<action context="Renderers" dev="GA" type="fix" fixes-bug="53304,53306">
Add version attribute to AT and IF intermediate formats. Also eliminate redundant use of reversed attribute in AT format.
</action>

+ 92
- 0
test/java/org/apache/fop/render/RawPNGTestUtil.java View File

@@ -0,0 +1,92 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

import org.apache.xmlgraphics.image.loader.ImageSize;

public final class RawPNGTestUtil {

private static int NUM_ROWS = 32;
private static int NUM_COLUMNS = 32;
private static int DPI = 72;

private RawPNGTestUtil() {

}

/**
* Builds a PNG IDAT section for a square of a given color and alpha; the filter is fixed.
* @param gray the gray color; set to -1 if using RGB
* @param red the red color; ignored if gray > -1
* @param green the green color; ignored if gray > -1
* @param blue the blue color; ignored if gray > -1
* @param alpha the alpha color; set to -1 if not present
* @return the PNG IDAT byte array
* @throws IOException
*/
public static byte[] buildGRGBAData(int gray, int red, int green, int blue, int alpha) throws IOException {
// build an image, 32x32, Gray or RGB, with or without alpha, and with filter
int filter = 0;
int numRows = NUM_ROWS;
int numColumns = NUM_COLUMNS;
int numComponents = (gray > -1 ? 1 : 3) + (alpha > -1 ? 1 : 0);
int numBytesPerRow = numColumns * numComponents + 1; // 1 for filter
int numBytes = numRows * numBytesPerRow;
byte[] data = new byte[numBytes];
for (int r = 0; r < numRows; r++) {
data[r * numBytesPerRow] = (byte) filter;
for (int c = 0; c < numColumns; c++) {
if (numComponents == 1) {
data[r * numBytesPerRow + numComponents * c + 1] = (byte) gray;
} else if (numComponents == 2) {
data[r * numBytesPerRow + numComponents * c + 1] = (byte) gray;
data[r * numBytesPerRow + numComponents * c + 2] = (byte) alpha;
} else if (numComponents == 3) {
data[r * numBytesPerRow + numComponents * c + 1] = (byte) red;
data[r * numBytesPerRow + numComponents * c + 2] = (byte) green;
data[r * numBytesPerRow + numComponents * c + 3] = (byte) blue;
} else if (numComponents == 4) {
data[r * numBytesPerRow + numComponents * c + 1] = (byte) red;
data[r * numBytesPerRow + numComponents * c + 2] = (byte) green;
data[r * numBytesPerRow + numComponents * c + 3] = (byte) blue;
data[r * numBytesPerRow + numComponents * c + 4] = (byte) alpha;
}
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater());
dos.write(data);
dos.close();
return baos.toByteArray();
}

/**
*
* @return a default ImageSize
*/
public static ImageSize getImageSize() {
return new ImageSize(NUM_ROWS, NUM_COLUMNS, DPI);
}
}

+ 142
- 0
test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java View File

@@ -0,0 +1,142 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.pdf;

import java.awt.image.ComponentColorModel;
import java.awt.image.IndexColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

import org.junit.Test;

import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;

import org.apache.fop.pdf.FlateFilter;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFProfile;
import org.apache.fop.render.RawPNGTestUtil;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ImageRawPNGAdapterTestCase {

@Test
public void testSetupWithIndexColorModel() {
IndexColorModel cm = mock(IndexColorModel.class);
ImageRawPNG irpng = mock(ImageRawPNG.class);
PDFDocument doc = mock(PDFDocument.class);
PDFProfile profile = mock(PDFProfile.class);
ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
ImageSize is = RawPNGTestUtil.getImageSize();

when(irpng.getColorModel()).thenReturn(cm);
// when(cm.hasAlpha()).thenReturn(false);
when(doc.getProfile()).thenReturn(profile);
when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
when(irpng.getSize()).thenReturn(is);
irpnga.setup(doc);
FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
assertEquals(1, filter.getColors());
}

@Test
public void testSetupWithComponentColorModel() throws IOException {
ComponentColorModel cm = mock(ComponentColorModel.class);
ImageRawPNG irpng = mock(ImageRawPNG.class);
PDFDocument doc = mock(PDFDocument.class);
PDFProfile profile = mock(PDFProfile.class);
ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
ImageSize is = RawPNGTestUtil.getImageSize();

when(irpng.getColorModel()).thenReturn(cm);
when(cm.getNumComponents()).thenReturn(3);
// when(cm.hasAlpha()).thenReturn(false);
when(doc.getProfile()).thenReturn(profile);
when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
when(irpng.getSize()).thenReturn(is);
irpnga.setup(doc);
FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
assertEquals(3, filter.getColors());
}

@Test
public void testOutputContentsWithRGBPNG() throws IOException {
testOutputContentsWithGRGBAPNG(-1, 128, 128, 128, -1);
}

@Test
public void testOutputContentsWithRGBAPNG() throws IOException {
testOutputContentsWithGRGBAPNG(-1, 128, 128, 128, 128);
}

@Test
public void testOutputContentsWithGPNG() throws IOException {
testOutputContentsWithGRGBAPNG(128, -1, -1, -1, -1);
}

@Test
public void testOutputContentsWithGAPNG() throws IOException {
testOutputContentsWithGRGBAPNG(128, -1, -1, -1, 128);
}

private void testOutputContentsWithGRGBAPNG(int gray, int red, int green, int blue, int alpha)
throws IOException {
int numColorComponents = gray > -1 ? 1 : 3;
int numComponents = numColorComponents + (alpha > -1 ? 1 : 0);
ComponentColorModel cm = mock(ComponentColorModel.class);
ImageRawPNG irpng = mock(ImageRawPNG.class);
PDFDocument doc = mock(PDFDocument.class);
PDFProfile profile = mock(PDFProfile.class);
ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
ImageSize is = RawPNGTestUtil.getImageSize();

when(irpng.getColorModel()).thenReturn(cm);
when(cm.getNumComponents()).thenReturn(numComponents);
// when(cm.hasAlpha()).thenReturn(false);
when(doc.getProfile()).thenReturn(profile);
when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
when(irpng.getSize()).thenReturn(is);
irpnga.setup(doc);
FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
assertEquals(numColorComponents, filter.getColors());

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] data = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, alpha);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
when(irpng.createInputStream()).thenReturn(bais);
irpnga.outputContents(baos);
if (alpha > -1) {
byte[] expected = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, -1);
assertArrayEquals(expected, baos.toByteArray());
} else {
assertArrayEquals(data, baos.toByteArray());
}
}

}

+ 133
- 0
test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java View File

@@ -0,0 +1,133 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.ps;

import java.awt.image.ComponentColorModel;
import java.awt.image.IndexColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.junit.Test;

import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;

import org.apache.fop.render.RawPNGTestUtil;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ImageEncoderPNGTestCase {

@Test
public void testWriteToWithRGBPNG() throws IOException {
testWriteToWithGRGBAPNG(-1, 128, 128, 128, -1);
}

@Test
public void testWriteToWithGPNG() throws IOException {
testWriteToWithGRGBAPNG(128, -1, -1, -1, -1);
}

@Test
public void testWriteToWithRGBAPNG() throws IOException {
testWriteToWithGRGBAPNG(-1, 128, 128, 128, 128);
}

@Test
public void testWriteToWithGAPNG() throws IOException {
testWriteToWithGRGBAPNG(128, -1, -1, -1, 128);
}

private void testWriteToWithGRGBAPNG(int gray, int red, int green, int blue, int alpha)
throws IOException {
int numComponents = (gray > -1 ? 1 : 3) + (alpha > -1 ? 1 : 0);
ImageSize is = RawPNGTestUtil.getImageSize();
ComponentColorModel cm = mock(ComponentColorModel.class);
when(cm.getNumComponents()).thenReturn(numComponents);
ImageRawPNG irpng = mock(ImageRawPNG.class);
when(irpng.getColorModel()).thenReturn(cm);
when(irpng.getSize()).thenReturn(is);
ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] data = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, alpha);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
when(irpng.createInputStream()).thenReturn(bais);
iepng.writeTo(baos);
if (alpha > -1) {
byte[] expected = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, -1);
assertArrayEquals(expected, baos.toByteArray());
} else {
assertArrayEquals(data, baos.toByteArray());
}
}

@Test
public void testWriteToWithPalettePNG() throws IOException {
ImageSize is = RawPNGTestUtil.getImageSize();
IndexColorModel cm = mock(IndexColorModel.class);
ImageRawPNG irpng = mock(ImageRawPNG.class);
when(irpng.getColorModel()).thenReturn(cm);
when(irpng.getSize()).thenReturn(is);
ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] data = RawPNGTestUtil.buildGRGBAData(128, -1, -1, -1, -1);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
when(irpng.createInputStream()).thenReturn(bais);
iepng.writeTo(baos);
assertArrayEquals(data, baos.toByteArray());
}

@Test
public void testGetImplicitFilterWithIndexColorModel() {
ImageSize is = RawPNGTestUtil.getImageSize();
IndexColorModel cm = mock(IndexColorModel.class);
ImageRawPNG irpng = mock(ImageRawPNG.class);
when(irpng.getColorModel()).thenReturn(cm);
when(irpng.getBitDepth()).thenReturn(8);
when(irpng.getSize()).thenReturn(is);
ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);

String expectedFilter = "<< /Predictor 15 /Columns 32 /Colors 1 /BitsPerComponent 8 >> /FlateDecode";
assertEquals(expectedFilter, iepng.getImplicitFilter());
}

@Test
public void testGetImplicitFilterWithComponentColorModel() {
ImageSize is = RawPNGTestUtil.getImageSize();
ComponentColorModel cm = mock(ComponentColorModel.class);
when(cm.getNumComponents()).thenReturn(3);
ImageRawPNG irpng = mock(ImageRawPNG.class);
when(irpng.getColorModel()).thenReturn(cm);
when(irpng.getBitDepth()).thenReturn(8);
when(irpng.getSize()).thenReturn(is);
ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);

String expectedFilter = "<< /Predictor 15 /Columns 32 /Colors 3 /BitsPerComponent 8 >> /FlateDecode";
assertEquals(expectedFilter, iepng.getImplicitFilter());
}

}

Loading…
Cancel
Save