1351540
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1352963 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_1rc1^2
@@ -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> |
@@ -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> |
@@ -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&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"> |
@@ -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 |
@@ -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() { |
@@ -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); |
@@ -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 { | |||
@@ -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) |
@@ -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(); |
@@ -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; |
@@ -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 ) { |
@@ -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) { | |||
} | |||
@@ -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; | |||
} |
@@ -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 |
@@ -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; |
@@ -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? | |||
*/ |
@@ -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; | |||
} | |||
} | |||
@@ -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. |
@@ -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. |
@@ -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()) { |
@@ -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); |
@@ -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 |
@@ -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 { |
@@ -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 { | |||
@@ -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 { | |||
@@ -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 { | |||
@@ -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 { | |||
@@ -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 { | |||
@@ -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 { | |||
@@ -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; |
@@ -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 | |||
*/ |
@@ -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. | |||
*/ |
@@ -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 { | |||
@@ -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 { |
@@ -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 { | |||
@@ -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 |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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. |
@@ -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 { | |||
@@ -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 +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} */ |
@@ -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() { |
@@ -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 |
@@ -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() { |
@@ -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 { |
@@ -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) { | |||
} | |||
} | |||
@@ -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 { | |||
@@ -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 { | |||
@@ -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> |
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |