git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1903803 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_8
@@ -229,7 +229,7 @@ class PropertyTokenizer { | |||
++exprIndex; | |||
scanHexDigits(); | |||
int len = exprIndex - currentTokenStartIndex - 1; | |||
if (len % 3 == 0) { | |||
if (len % 3 == 0 || len == 8) { | |||
currentToken = TOK_COLORSPEC; | |||
} else { | |||
//Actually not a color at all, but an NCNAME starting with "#" |
@@ -23,6 +23,7 @@ import java.awt.Color; | |||
import java.awt.color.ColorSpace; | |||
import java.awt.color.ICC_ColorSpace; | |||
import java.awt.color.ICC_Profile; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.commons.logging.Log; | |||
@@ -45,6 +46,7 @@ public class PDFColorHandler { | |||
private Log log = LogFactory.getLog(PDFColorHandler.class); | |||
private PDFResources resources; | |||
private PDFResourceContext resourceContext; | |||
private Map<String, PDFCIELabColorSpace> cieLabColorSpaces; | |||
@@ -52,8 +54,9 @@ public class PDFColorHandler { | |||
* Create a new instance for the given {@link PDFResources} | |||
* @param resources the PDF resources | |||
*/ | |||
public PDFColorHandler(PDFResources resources) { | |||
public PDFColorHandler(PDFResources resources, PDFResourceContext resourceContext) { | |||
this.resources = resources; | |||
this.resourceContext = resourceContext; | |||
} | |||
private PDFDocument getDocument() { | |||
@@ -67,7 +70,7 @@ public class PDFColorHandler { | |||
* @param color the color | |||
* @param fill true for fill color, false for stroke color | |||
*/ | |||
public void establishColor(StringBuffer codeBuffer, Color color, boolean fill) { | |||
public void establishColor(StringBuffer codeBuffer, Color color, boolean fill, boolean alpha) { | |||
if (color instanceof ColorWithAlternatives) { | |||
ColorWithAlternatives colExt = (ColorWithAlternatives)color; | |||
//Alternate colors have priority | |||
@@ -87,7 +90,7 @@ public class PDFColorHandler { | |||
//Fallback | |||
boolean established = establishColorFromColor(codeBuffer, color, fill); | |||
if (!established) { | |||
establishDeviceRGB(codeBuffer, color, fill); | |||
establishDeviceRGB(codeBuffer, color, fill, alpha); | |||
} | |||
} | |||
@@ -188,7 +191,7 @@ public class PDFColorHandler { | |||
} | |||
} | |||
private void establishDeviceRGB(StringBuffer codeBuffer, Color color, boolean fill) { | |||
private void establishDeviceRGB(StringBuffer codeBuffer, Color color, boolean fill, boolean alpha) { | |||
float[] comps; | |||
if (color.getColorSpace().isCS_sRGB()) { | |||
comps = color.getColorComponents(null); | |||
@@ -199,6 +202,9 @@ public class PDFColorHandler { | |||
ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); | |||
comps = color.getColorComponents(sRGB, null); | |||
} | |||
if (alpha) { | |||
writeAlpha(color, codeBuffer); | |||
} | |||
if (ColorUtil.isGray(color)) { | |||
comps = new float[] {comps[0]}; //assuming that all components are the same | |||
writeColor(codeBuffer, comps, 1, (fill ? "g" : "G")); | |||
@@ -207,7 +213,20 @@ public class PDFColorHandler { | |||
} | |||
} | |||
private void writeAlpha(Color color, StringBuffer codeBuffer) { | |||
int alpha = color.getAlpha(); | |||
if (alpha != 255 && alpha != 0 && resourceContext != null) { | |||
Map<String, Float> vals = new HashMap<>(); | |||
vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, alpha / 255f); | |||
vals.put(PDFGState.GSTATE_ALPHA_STROKE, 1.0f); | |||
PDFGState gState = getDocument().getFactory().makeGState(vals, PDFGState.DEFAULT); | |||
resourceContext.addGState(gState); | |||
codeBuffer.append("/").append(gState.getName()).append(" gs\n"); | |||
} | |||
} | |||
private void establishDeviceCMYK(StringBuffer codeBuffer, Color color, boolean fill) { | |||
writeAlpha(color, codeBuffer); | |||
writeColor(codeBuffer, color, 4, (fill ? "k" : "K")); | |||
} | |||
@@ -751,7 +751,7 @@ public class PDFDocument { | |||
poss = new PDFGState(); | |||
poss.addValues(current); | |||
poss.addValues(avail); | |||
if (poss.equals(wanted)) { | |||
if (poss.contentEquals(wanted)) { | |||
return avail; | |||
} | |||
} |
@@ -96,7 +96,7 @@ public class PDFContentGenerator { | |||
}; | |||
this.currentState = new PDFPaintingState(); | |||
this.colorHandler = new PDFColorHandler(document.getResources()); | |||
this.colorHandler = new PDFColorHandler(document.getResources(), resourceContext); | |||
this.context = context; | |||
} | |||
@@ -455,7 +455,7 @@ public class PDFContentGenerator { | |||
*/ | |||
protected void setColor(Color col, boolean fill, StringBuffer pdf) { | |||
if (pdf != null) { | |||
colorHandler.establishColor(pdf, col, fill); | |||
colorHandler.establishColor(pdf, col, fill, true); | |||
} else { | |||
setColor(col, fill, getStream()); | |||
} |
@@ -83,7 +83,7 @@ public class PSImageHandlerRenderedImage implements PSImageHandler { | |||
ImageEncodingHelper helper = new ImageEncodingHelper(ri); | |||
ColorModel cm = helper.getEncodedColorModel(); | |||
PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen, ri); | |||
PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen, ri, null); | |||
} | |||
/** {@inheritDoc} */ |
@@ -102,7 +102,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { | |||
this.pdfDoc = new PDFDocument("Apache FOP Version " + Version.getVersion() | |||
+ ": PDFDocumentGraphics2D"); | |||
this.pdfContext = new PDFContext(); | |||
this.colorHandler = new PDFColorHandler(this.pdfDoc.getResources()); | |||
this.colorHandler = new PDFColorHandler(this.pdfDoc.getResources(), resourceContext); | |||
} | |||
/** | |||
@@ -237,7 +237,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { | |||
public void setBackgroundColor(Color col) { | |||
StringBuffer sb = new StringBuffer(); | |||
sb.append("q\n"); | |||
this.colorHandler.establishColor(sb, col, true); | |||
this.colorHandler.establishColor(sb, col, true, true); | |||
sb.append("0 0 ").append(width).append(" ").append(height).append(" re\n"); | |||
@@ -217,7 +217,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand | |||
TransparencyIgnoredEventListener listener) { | |||
this(textAsShapes); | |||
pdfDoc = doc; | |||
this.colorHandler = new PDFColorHandler(doc.getResources()); | |||
this.colorHandler = new PDFColorHandler(doc.getResources(), page); | |||
resourceContext = page; | |||
currentFontName = font; | |||
currentFontSize = size; | |||
@@ -790,7 +790,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand | |||
} | |||
if (doWrite) { | |||
StringBuffer sb = new StringBuffer(); | |||
colorHandler.establishColor(sb, col, fill); | |||
colorHandler.establishColor(sb, col, fill, false); | |||
currentStream.write(sb.toString()); | |||
} | |||
} |
@@ -471,4 +471,36 @@ public class PDFPainterTestCase { | |||
pdfPainter.drawImageUsingImageHandler(info, new Rectangle()); | |||
Assert.assertEquals(event[0].getEventKey(), "imageWritingError"); | |||
} | |||
@Test | |||
public void testAlphaColor() throws Exception { | |||
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI()); | |||
foUserAgent = fopFactory.newFOUserAgent(); | |||
PDFDocumentHandler pdfDocumentHandler = new PDFDocumentHandler(new IFContext(foUserAgent)); | |||
pdfDocumentHandler.setResult(new StreamResult(new ByteArrayOutputStream())); | |||
pdfDocumentHandler.startDocument(); | |||
pdfDocumentHandler.startPage(0, "", "", new Dimension()); | |||
PDFPainter pdfPainter = new PDFPainter(pdfDocumentHandler, null); | |||
pdfPainter.fillRect(new Rectangle(10, 10), new Color(0, 0, 0, 128)); | |||
PDFFilterList filters = pdfPainter.generator.getStream().getFilterList(); | |||
filters.setDisableAllFilters(true); | |||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); | |||
pdfPainter.generator.getStream().output(bos); | |||
Assert.assertEquals("<< /Length 1 0 R >>\n" | |||
+ "stream\n" | |||
+ "q\n" | |||
+ "1 0 0 -1 0 0 cm\n" | |||
+ "/GS1 gs\n" | |||
+ "0 g\n" | |||
+ "0 0 0.01 0.01 re f\n" | |||
+ "\n" | |||
+ "endstream", bos.toString()); | |||
bos.reset(); | |||
pdfDocumentHandler.getCurrentPage().getGStates().iterator().next().output(bos); | |||
Assert.assertEquals(bos.toString(), "<<\n" | |||
+ "/Type /ExtGState\n" | |||
+ "/ca 0.5019608\n" | |||
+ "/CA 1.0\n" | |||
+ ">>"); | |||
} | |||
} |