<?xml version="1.0"?>
-<!--
- 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$ -->
<!--
\r
:runFop\r
rem ECHO "%JAVACMD%"\r
-"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
+"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" %FOP_OPTS% org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
\r
:runFop\r
rem echo "%JAVACMD%" %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
-"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
+"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" %FOP_OPTS% org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
\r
ENDLOCAL\r
<p>
By convention, FO extensions in FOP use the "fox" namespace prefix.
To use any of the FO extensions, add a namespace entry for
- <code>http://xml.apache.org/fop/extensions</code> to the root element:
+ <code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element:
</p>
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source>
<p>
By convention, FO extensions in FOP use the "fox" namespace prefix.
To use any of the FO extensions, add a namespace entry for
- <code>http://xml.apache.org/fop/extensions</code> to the root element:
+ <code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element:
</p>
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source>
<p>
By convention, FO extensions in FOP use the "fox" namespace prefix.
To use any of the FO extensions, add a namespace entry for
- <code>http://xml.apache.org/fop/extensions</code> to the root element:
+ <code>http://xmlgraphics.apache.org/fop/extensions</code> to the root element:
</p>
<source><![CDATA[<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions">]]></source>
if (attributeValue != null) {
- if (attributeName.startsWith("xmlns:")) {
- //Ignore namespace declarations
+ if (attributeName.startsWith("xmlns:")
+ || "xmlns".equals(attributeName)) {
+ //Ignore namespace declarations if the XML parser/XSLT processor
+ //reports them as 'regular' attributes
return;
}
}
/**
- * @param propID ID of property
+ * @param propId ID of property
* @return new Property object
* @throws PropertyException if there's a problem while processing the property
*/
return new CommonAbsolutePosition(this);
}
-
/**
* Constructs a CommonFont object.
*
nestedBlockStack.pop();
}
charIter = null;
+ firstWhiteSpaceInSeq = null;
}
}
}
* @param isFirstPage True if page is first page
* @param isLastPage True if page is last page
* @param isBlankPage True if page is blank
- * @param isOnlyPage True if page is the only page
* @return True if the conditions for this reference are met
*/
protected boolean isValid(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
boolean isBlankPage) {
- // page-position
- if (isOnlyPage) {
- if (pagePosition != EN_ONLY) {
- return false;
- }
- } else if (isFirstPage) {
- if (pagePosition == EN_REST) {
- return false;
- } else if (pagePosition == EN_LAST) {
- return false;
- }
- } else if (isLastPage) {
- if (pagePosition == EN_REST) {
- return false;
- } else if (pagePosition == EN_FIRST) {
- return false;
- }
- } else {
- if (pagePosition == EN_FIRST) {
- return false;
- } else if (pagePosition == EN_LAST) {
- return false;
- }
- }
- // odd-or-even
- if (isOddPage) {
- if (oddOrEven == EN_EVEN) {
- return false;
- }
- } else {
- if (oddOrEven == EN_ODD) {
- return false;
- }
- }
+ return (
+ // page-position
+ (pagePosition == EN_ANY
+ || (pagePosition == EN_FIRST && isFirstPage)
+ || (pagePosition == EN_LAST && isLastPage)
+ || (pagePosition == EN_ONLY && (isFirstPage && isLastPage))
+ || (pagePosition == EN_REST && !(isFirstPage || isLastPage))
+ )
+ // odd-or-even
+ && (oddOrEven == EN_ANY
+ || (oddOrEven == EN_ODD && isOddPage)
+ || (oddOrEven == EN_EVEN && !isOddPage)
+ )
+ // blank-or-not-blank
+ && (blankOrNotBlank == EN_ANY
+ || (blankOrNotBlank == EN_BLANK && isBlankPage)
+ || (blankOrNotBlank == EN_NOT_BLANK && !isBlankPage)
+ ));
+
- // blank-or-not-blank
- if (isBlankPage) {
- if (blankOrNotBlank == EN_NOT_BLANK) {
- return false;
- }
- } else {
- if (blankOrNotBlank == EN_BLANK) {
- return false;
- }
- }
- return true;
}
/**
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
- if (localName.equals("title")) {
+ if ("title".equals(localName)) {
if (titleFO != null) {
tooManyNodesError(loc, "fo:title");
- } else if (flowMap.size() > 0) {
+ } else if (!flowMap.isEmpty()) {
nodesOutOfOrderError(loc, "fo:title", "fo:static-content");
} else if (mainFlow != null) {
nodesOutOfOrderError(loc, "fo:title", "fo:flow");
}
- } else if (localName.equals("static-content")) {
+ } else if ("static-content".equals(localName)) {
if (mainFlow != null) {
nodesOutOfOrderError(loc, "fo:static-content", "fo:flow");
}
- } else if (localName.equals("flow")) {
+ } else if ("flow".equals(localName)) {
if (mainFlow != null) {
tooManyNodesError(loc, "fo:flow");
}
public void addChildNode(FONode child) throws FOPException {
int childId = child.getNameId();
- if (childId == FO_TITLE) {
- this.titleFO = (Title) child;
- } else if (childId == FO_FLOW) {
- this.mainFlow = (Flow) child;
+ switch (childId) {
+ case FO_TITLE:
+ this.titleFO = (Title)child;
+ break;
+ case FO_FLOW:
+ this.mainFlow = (Flow)child;
addFlow(mainFlow);
- } else if (childId == FO_STATIC_CONTENT) {
- addFlow((StaticContent) child);
- String flowName = ((StaticContent) child).getFlowName();
- flowMap.put(flowName, child);
+ break;
+ case FO_STATIC_CONTENT:
+ addFlow((StaticContent)child);
+ flowMap.put(((StaticContent)child).getFlowName(), child);
+ break;
+ default:
+ assert false;
}
}
* page sequence
* @param isLastPage indicator whether this page is the last page of the
* page sequence
- * @param isOnlyPage indicator whether this page is the only page of the
- * page sequence
* @param isBlank indicator whether the page will be blank
* @return the SimplePageMaster to use for this page
* @throws PageProductionException if there's a problem determining the page master
*/
public SimplePageMaster getNextSimplePageMaster(int page,
- boolean isFirstPage,
- boolean isLastPage,
- boolean isOnlyPage,
- boolean isBlank) throws PageProductionException {
+ boolean isFirstPage,
+ boolean isLastPage,
+ boolean isBlank) throws PageProductionException {
if (pageSequenceMaster == null) {
return simplePageMaster;
+ " isOdd=" + isOddPage
+ " isFirst=" + isFirstPage
+ " isLast=" + isLastPage
- + " isOnly=" + isOnlyPage
+ " isBlank=" + isBlank + ")");
}
return pageSequenceMaster.getNextSimplePageMaster(isOddPage,
- isFirstPage, isLastPage, isOnlyPage, isBlank);
+ isFirstPage, isLastPage, isBlank);
}
/**
* @return true if there is a previous item, false if the current one was the first one.
*/
public boolean goToPreviousSimplePageMaster() {
- if (pageSequenceMaster == null) {
- return true;
- } else {
- return pageSequenceMaster.goToPreviousSimplePageMaster();
- }
+ return pageSequenceMaster == null || pageSequenceMaster.goToPreviousSimplePageMaster();
}
/** @return true if the page-sequence has a page-master with page-position="last" */
public boolean hasPagePositionLast() {
- if (pageSequenceMaster == null) {
- return false;
- } else {
- return pageSequenceMaster.hasPagePositionLast();
- }
+ return pageSequenceMaster != null && pageSequenceMaster.hasPagePositionLast();
}
/** @return true if the page-sequence has a page-master with page-position="only" */
public boolean hasPagePositionOnly() {
- if (pageSequenceMaster == null) {
- return false;
- } else {
- return pageSequenceMaster.hasPagePositionOnly();
- }
+ return pageSequenceMaster != null && pageSequenceMaster.hasPagePositionOnly();
}
/**
* @param isOddPage True if the next page number is odd
* @param isFirstPage True if the next page is the first
* @param isLastPage True if the next page is the last
- * @param isOnlyPage True if the next page is the only page
* @param isBlankPage True if the next page is blank
* @return the requested page master
* @throws PageProductionException if there's a problem determining the next page master
public SimplePageMaster getNextSimplePageMaster(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
boolean isBlankPage)
throws PageProductionException {
if (currentSubSequence == null) {
}
}
String pageMasterName = currentSubSequence
- .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage);
+ .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage);
boolean canRecover = true;
while (pageMasterName == null) {
SubSequenceSpecifier nextSubSequence = getNextSubSequence();
currentSubSequence = nextSubSequence;
}
pageMasterName = currentSubSequence
- .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage);
+ .getNextPageMasterName(isOddPage, isFirstPage, isLastPage, isBlankPage);
}
SimplePageMaster pageMaster = this.layoutMasterSet
.getSimplePageMaster(pageMasterName);
public String getNextPageMasterName(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
boolean isBlankPage) {
if (getMaximumRepeats() != INFINITE) {
if (numberConsumed < getMaximumRepeats()) {
for (int i = 0; i < conditionalPageMasterRefs.size(); i++) {
ConditionalPageMasterReference cpmr
= (ConditionalPageMasterReference)conditionalPageMasterRefs.get(i);
- if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isOnlyPage, isBlankPage)) {
+ if (cpmr.isValid(isOddPage, isFirstPage, isLastPage, isBlankPage)) {
return cpmr.getMasterReference();
}
}
public String getNextPageMasterName(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
boolean isEmptyPage) {
if (getMaximumRepeats() != INFINITE) {
if (numberConsumed < getMaximumRepeats()) {
public String getNextPageMasterName(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
- boolean isEmptyPage) {
+ boolean isBlankPage) {
if (this.state == FIRST) {
this.state = DONE;
return masterReference;
this.state = FIRST;
}
-
-
/** {@inheritDoc} */
public boolean goToPrevious() {
if (state == FIRST) {
* @param isOddPage True if the next page number is odd
* @param isFirstPage True if the next page is the first
* @param isLastPage True if the next page is the last
- * @param isOnlyPage True if the next page is the only page
* @param isBlankPage True if the next page is blank
* @return the page master name
* @throws PageProductionException if there's a problem determining the next page master
String getNextPageMasterName(boolean isOddPage,
boolean isFirstPage,
boolean isLastPage,
- boolean isOnlyPage,
boolean isBlankPage)
throws PageProductionException;
import javax.xml.parsers.DocumentBuilderFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
import org.apache.commons.logging.LogFactory;
+
import org.apache.fop.Version;
import org.apache.fop.fonts.type1.PFMFile;
import org.apache.fop.util.CommandLineLogger;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
/**
* A tool which reads PFM files from Adobe Type 1 fonts and creates
el = doc.createElement("descender");
root.appendChild(el);
- value = new Integer(-pfm.getLowerCaseDescent());
+ value = new Integer(pfm.getLowerCaseDescent());
el.appendChild(doc.createTextNode(value.toString()));
Element bbox = doc.createElement("bbox");
/**
* Read the "OS/2" table
*/
- private final void readOS2(FontFileReader in) throws IOException {
+ private void readOS2(FontFileReader in) throws IOException {
// Check if font is embeddable
- if (dirTabs.get("OS/2") != null) {
- seekTab(in, "OS/2", 2 * 2);
+ TTFDirTabEntry os2Entry = (TTFDirTabEntry)dirTabs.get("OS/2");
+ if (os2Entry != null) {
+ seekTab(in, "OS/2", 0);
+ int version = in.readTTFUShort();
+ if (log.isDebugEnabled()) {
+ log.debug("OS/2 table: version=" + version
+ + ", offset=" + os2Entry.getOffset() + ", len=" + os2Entry.getLength());
+ }
+ in.skip(2); //xAvgCharWidth
this.usWeightClass = in.readTTFUShort();
// usWidthClass
in.skip(3 * 2);
int v;
os2Ascender = in.readTTFShort(); //sTypoAscender
- log.debug("sTypoAscender: " + os2Ascender
- + " " + convertTTFUnit2PDFUnit(os2Ascender));
os2Descender = in.readTTFShort(); //sTypoDescender
- log.debug("sTypoDescender: " + os2Descender
- + " " + convertTTFUnit2PDFUnit(os2Descender));
v = in.readTTFShort(); //sTypoLineGap
- log.debug("sTypoLineGap: " + v);
v = in.readTTFUShort(); //usWinAscent
- log.debug("usWinAscent: " + v + " " + convertTTFUnit2PDFUnit(v));
v = in.readTTFUShort(); //usWinDescent
- log.debug("usWinDescent: " + v + " " + convertTTFUnit2PDFUnit(v));
- in.skip(2 * 4);
- this.os2xHeight = in.readTTFShort(); //sxHeight
- log.debug("sxHeight: " + this.os2xHeight);
- this.os2CapHeight = in.readTTFShort(); //sCapHeight
- log.debug("sCapHeight: " + this.os2CapHeight);
+ if (log.isDebugEnabled()) {
+ log.debug("sTypoAscender: " + os2Ascender
+ + " " + convertTTFUnit2PDFUnit(os2Ascender));
+ log.debug("sTypoDescender: " + os2Descender
+ + " " + convertTTFUnit2PDFUnit(os2Descender));
+ log.debug("sTypoLineGap: " + v);
+ log.debug("usWinAscent: " + v + " " + convertTTFUnit2PDFUnit(v));
+ log.debug("usWinDescent: " + v + " " + convertTTFUnit2PDFUnit(v));
+ }
+
+ //version 1 OS/2 table might end here
+ if (os2Entry.getLength() >= 78 + (2 * 4) + (2 * 2)) {
+ in.skip(2 * 4);
+ this.os2xHeight = in.readTTFShort(); //sxHeight
+ this.os2CapHeight = in.readTTFShort(); //sCapHeight
+ if (log.isDebugEnabled()) {
+ log.debug("sxHeight: " + this.os2xHeight);
+ log.debug("sCapHeight: " + this.os2CapHeight);
+ }
+ }
} else {
isEmbeddable = true;
package org.apache.fop.fonts.type1;
+import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataInputStream;
*/
public class PFMInputStream extends java.io.FilterInputStream {
- private DataInputStream datain;
+ private final DataInputStream datain;
/**
* Constructs a PFMInputStream based on an InputStream representing the
public String readString() throws IOException {
InputStreamReader reader = new InputStreamReader(in, "ISO-8859-1");
StringBuffer buf = new StringBuffer();
+
int ch = reader.read();
- while (ch != 0) {
+ while (ch > 0) {
buf.append((char)ch);
ch = reader.read();
}
+ if (ch == -1) {
+ throw new EOFException("Unexpected end of stream reached");
+ }
return buf.toString();
}
import org.apache.batik.gvt.GraphicsNode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
+import org.apache.fop.svg.SimpleSVGUserAgent;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
+import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageConverter;
import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.apache.xmlgraphics.util.UnitConv;
-import org.apache.fop.svg.SimpleSVGUserAgent;
-
/**
* This ImageConverter converts SVG images to Java2D.
* <p>
/** {@inheritDoc} */
public ImageFlavor getSourceFlavor() {
- return ImageFlavor.XML_DOM;
+ return XMLNamespaceEnabledImageFlavor.SVG_DOM;
}
/** {@inheritDoc} */
package org.apache.fop.image.loader.batik;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoaderFactory;
import org.apache.xmlgraphics.image.loader.spi.ImageLoader;
import org.apache.xmlgraphics.util.MimeConstants;
public class ImageLoaderFactorySVG extends AbstractImageLoaderFactory {
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
- ImageFlavor.XML_DOM};
+ XMLNamespaceEnabledImageFlavor.SVG_DOM};
private static final String[] MIMES = new String[] {
MimeConstants.MIME_SVG};
import java.util.Map;
import org.apache.batik.dom.svg.SVGDOMImplementation;
-
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
+import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageLoader;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.util.MimeConstants;
* @param targetFlavor the target flavor
*/
public ImageLoaderSVG(ImageFlavor targetFlavor) {
- if (!(ImageFlavor.XML_DOM.equals(targetFlavor))) {
+ if (!(XMLNamespaceEnabledImageFlavor.SVG_DOM.equals(targetFlavor))) {
throw new IllegalArgumentException("Unsupported target ImageFlavor: " + targetFlavor);
}
this.targetFlavor = targetFlavor;
indexOfCachedLastPage = (isLastPage ? intIndex : -1);
}
if (replace) {
- disardCacheStartingWith(intIndex);
+ discardCacheStartingWith(intIndex);
page = cacheNextPage(index, isBlank, isLastPage);
}
return page;
}
- private void disardCacheStartingWith(int index) {
+ private void discardCacheStartingWith(int index) {
while (index < cachedPages.size()) {
this.cachedPages.remove(cachedPages.size() - 1);
if (!pageSeq.goToPreviousSimplePageMaster()) {
private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage) {
String pageNumberString = pageSeq.makeFormattedPageNumber(index);
+ boolean isFirstPage = (startPageOfPageSequence == index);
SimplePageMaster spm = pageSeq.getNextSimplePageMaster(
- index, (startPageOfPageSequence == index), isLastPage, false, isBlank);
+ index, isFirstPage, isLastPage, isBlank);
Region body = spm.getRegion(FO_REGION_BODY);
if (!pageSeq.getMainFlow().getFlowName().equals(body.getRegionName())) {
*/
public AlphaRasterImage(String k, Raster alpha) {
this.key = k;
+ //Enable the commented line below if 16-bit alpha channels are desired.
+ //Otherwise, we compress the alpha channel to 8 bit which should be sufficient.
+ //this.bitsPerComponent = alpha.getSampleModel().getSampleSize(0);
this.bitsPerComponent = 8;
this.colorSpace = new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY);
if (alpha == null) {
alpha.getDataElements(0, y, w, 1, line);
out.write(line);
}
+ } else if (dataType == DataBuffer.TYPE_USHORT) {
+ short[] sline = new short[nbands * w];
+ byte[] line = new byte[nbands * w];
+ for (int y = 0; y < h; y++) {
+ alpha.getDataElements(0, y, w, 1, sline);
+ for (int i = 0; i < w; i++) {
+ //this compresses a 16-bit alpha channel to 8 bits!
+ //we probably don't ever need a 16-bit channel
+ line[i] = (byte)(sline[i] >> 8);
+ }
+ out.write(line);
+ }
} else if (dataType == DataBuffer.TYPE_INT) {
//Is there an better way to get a 8bit raster from a TYPE_INT raster?
int shift = 24;
* @param type which filter list to modify
*/
public void addDefaultFilters(Map filters, String type) {
+ if (METADATA_FILTER.equals(type)) {
+ //XMP metadata should not be embedded in clear-text
+ addFilter(new NullFilter());
+ return;
+ }
List filterset = null;
if (filters != null) {
filterset = (List)filters.get(type);
}
}
if (filterset == null || filterset.size() == 0) {
- if (METADATA_FILTER.equals(type)) {
- //XMP metadata should not be embedded in clear-text
- addFilter(new NullFilter());
- } else if (JPEG_FILTER.equals(type)) {
+ if (JPEG_FILTER.equals(type)) {
//JPEG is already well compressed
addFilter(new NullFilter());
} else if (TIFF_FILTER.equals(type)) {
PageSequenceMaster master
= pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference);
this.pagemaster = master.getNextSimplePageMaster(
- false, false, false, false, false);
+ false, false, false, false);
}
}
* the FOP project.
*/
-import java.io.Writer;
import java.io.IOException;
+import java.io.Writer;
import java.util.Iterator;
/** A cell in an RTF table, container for paragraphs, lists, etc.
// Reach the column index in table context corresponding to the current column cell
// id is the index of the current cell (it begins at 1)
// getColumnIndex() is the index of the current column in table context (it begins at 0)
- // => so we must widthdraw 1 when comparing these two variables.
+ // => so we must withdraw 1 when comparing these two variables.
while ((this.id - 1) != tableColumnsInfo.getColumnIndex()) {
tableColumnsInfo.selectNextColumn();
}
- // We widthdraw one cell because the first cell is already created
+ // We withdraw one cell because the first cell is already created
// (it's the current cell) !
int i = nbMergedCells - 1;
while (i > 0) {
final int xPos = offset + iCurrentWidth;
//these lines added by Chris Scott, Westinghouse
- //some attributes need to be writting before opening block
+ //some attributes need to be written before opening block
if (setCenter) {
- writeControlWord("qc");
+ writeControlWord("trqc");
} else if (setRight) {
- writeControlWord("qr");
+ writeControlWord("trqr");
} else {
- writeControlWord("ql");
+ writeControlWord("trql");
}
writeAttributes (attrib, ITableAttributes.CELL_VERT_ALIGN);
writeControlWord("cellx" + xPos);
- //TODO Why is this here, right after an alignment command is written (see above)?
- writeControlWord("ql");
-
return xPos;
}
<changes>
<release version="FOP Trunk" date="TBD">
+ <action context="Layout" dev="AD" type="fix" fixes-bug="40798">
+ Bugzilla 40798: A conditional-page-master-reference with page-position="last" qualifies
+ for a first page, if it is also the last. Additionally: also added support for
+ page-position="only".
+ </action>
+ <action context="Code" dev="AD" type="fix" fixes-bug="45842" due-to="Carsten Siedentop">
+ Make fop.bat and fop.cmd use the %FOP_OPTS% environment variable.
+ </action>
+ <action context="Renderers" dev="JM" type="add" fixes-bug="45795">
+ PDF Output: Added support for handling 16-bit alpha channel. They are currently
+ converted to 8 bits.
+ </action>
+ <action context="Renderers" dev="JM" type="fix">
+ PDF Output: Made sure the XMP Metadata stream is never compressed.
+ </action>
+ <action context="Fonts" dev="JM" type="fix" fixes-bug="45734" due-to="J. Frantzius">
+ Fix for PFMReader after bug #43089 changed the behavior of PFMFile. Fixes baseline
+ problems when Type 1 fonts are used in conjunction with XML font metric files.
+ </action>
+ <action context="Renderers" dev="JM" type="fix" fixes-bug="45616" due-to="Pavel Kysilka">
+ Fix for table handling in RTF output, so the output works with OpenOffice and AbiWord, too.
+ </action>
<action context="Code" dev="AD" type="fix" fixes-bug="45667">
Quick-fix to avoid a possible NullPointerException when using
empty inlines and hyphenation.
import junit.framework.TestSuite;
import org.apache.fop.fonts.TrueTypeAnsiTestCase;
+import org.apache.fop.image.loader.batik.ImageLoaderTestCase;
+import org.apache.fop.image.loader.batik.ImagePreloaderTestCase;
import org.apache.fop.render.pdf.PDFAConformanceTestCase;
import org.apache.fop.render.pdf.PDFCMapTestCase;
import org.apache.fop.render.pdf.PDFEncodingTestCase;
suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class));
suite.addTest(new TestSuite(TrueTypeAnsiTestCase.class));
suite.addTest(RichTextFormatTestSuite.suite());
+ suite.addTest(new TestSuite(ImageLoaderTestCase.class));
+ suite.addTest(new TestSuite(ImagePreloaderTestCase.class));
//$JUnit-END$
return suite;
}
package org.apache.fop.image.loader.batik;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
import java.io.File;
import junit.framework.TestCase;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
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.ImageManager;
+import org.apache.xmlgraphics.image.loader.XMLNamespaceEnabledImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.image.writer.ImageWriterUtil;
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.FopFactory;
-
/**
* Tests for bundled ImageLoader implementations.
*/
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
assertNotNull("ImageInfo must not be null", info);
- Image img = manager.getImage(info, ImageFlavor.XML_DOM,
+ Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM,
userAgent.getImageSessionContext());
assertNotNull("Image must not be null", img);
- assertEquals(ImageFlavor.XML_DOM, img.getFlavor());
+ assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor());
ImageXMLDOM imgDom = (ImageXMLDOM)img;
assertNotNull(imgDom.getDocument());
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace());
ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
assertNotNull("ImageInfo must not be null", info);
- Image img = manager.getImage(info, ImageFlavor.XML_DOM,
+ Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM,
userAgent.getImageSessionContext());
assertNotNull("Image must not be null", img);
- assertEquals(ImageFlavor.XML_DOM, img.getFlavor());
+ assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor());
ImageXMLDOM imgDom = (ImageXMLDOM)img;
assertNotNull(imgDom.getDocument());
assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace());
assertEquals(612000, info.getSize().getHeightMpt());
}
+ public void testSVGWithReferences() throws Exception {
+ String uri = "test/resources/fop/svg/images.svg";
+ FopFactory ff = FopFactory.newInstance();
+ FOUserAgent userAgent = ff.newFOUserAgent();
+
+ ImageManager manager = ff.getImageManager();
+ ImageInfo info = manager.preloadImage(uri, userAgent.getImageSessionContext());
+ assertNotNull("ImageInfo must not be null", info);
+
+ Image img = manager.getImage(info, XMLNamespaceEnabledImageFlavor.SVG_DOM,
+ userAgent.getImageSessionContext());
+ assertNotNull("Image must not be null", img);
+ assertEquals(XMLNamespaceEnabledImageFlavor.SVG_DOM, img.getFlavor());
+ ImageXMLDOM imgDom = (ImageXMLDOM)img;
+ assertNotNull(imgDom.getDocument());
+ assertEquals("http://www.w3.org/2000/svg", imgDom.getRootNamespace());
+ info = imgDom.getInfo(); //Switch to the ImageInfo returned by the image
+ assertEquals(400000, info.getSize().getWidthMpt());
+ assertEquals(400000, info.getSize().getHeightMpt());
+ assertEquals(400, info.getSize().getWidthPx());
+ assertEquals(400, info.getSize().getHeightPx());
+
+ img = manager.getImage(info, ImageFlavor.RENDERED_IMAGE,
+ userAgent.getImageSessionContext());
+ assertNotNull("Image must not be null", img);
+ assertEquals(ImageFlavor.RENDERED_IMAGE, img.getFlavor());
+ ImageRendered imgRed = (ImageRendered)img;
+ RenderedImage renImg = imgRed.getRenderedImage();
+ assertNotNull(renImg);
+ if (DEBUG_TARGET_DIR != null) {
+ ImageWriterUtil.saveAsPNG(renImg,
+ (int)userAgent.getTargetResolution(),
+ new File(DEBUG_TARGET_DIR, "images.svg.png"));
+ }
+ assertEquals(400, renImg.getWidth());
+ assertEquals(400, renImg.getHeight());
+ info = imgRed.getInfo(); //Switch to the ImageInfo returned by the image
+ assertEquals(400000, info.getSize().getWidthMpt());
+ assertEquals(400000, info.getSize().getHeightMpt());
+ Raster raster = renImg.getData();
+ // This pixel is white
+ int[] pixel1 = raster.getPixel(1, 1, (int[] )null);
+ // This pixel is from the embedded JPG and is not white
+ int[] pixel80 = raster.getPixel(80, 80, (int[]) null);
+ assertEquals(pixel1.length, pixel80.length);
+ boolean same = true;
+ for (int i = 0; i < pixel1.length; i++) {
+ same &= (pixel1[i] == pixel80[i]);
+ }
+ assertFalse("Embedding JPG into SVG failed", same);
+ }
+
+
+
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks for the use of a 'last' conditional-page-master-reference
+ for a first/only page (see: https://issues.apache.org/bugzilla/show_bug.cgi?id=40798)
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ font-family="Times" font-size="20pt">
+
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="only-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="only-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="first-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="first-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="last-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="last-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="rest-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="rest-region" extent="10mm"/>
+ </fo:simple-page-master>
+
+ <fo:page-sequence-master master-name="whatever">
+ <fo:repeatable-page-master-alternatives maximum-repeats="1">
+ <fo:conditional-page-master-reference master-reference="only-page-layout"
+ page-position="last"/>
+ <fo:conditional-page-master-reference master-reference="first-page-layout"
+ page-position="first"/>
+ </fo:repeatable-page-master-alternatives>
+ <fo:repeatable-page-master-alternatives maximum-repeats="no-limit">
+ <fo:conditional-page-master-reference master-reference="last-page-layout"
+ page-position="last"/>
+ <fo:conditional-page-master-reference master-reference="rest-page-layout"
+ page-position="rest"/>
+ </fo:repeatable-page-master-alternatives>
+ </fo:page-sequence-master>
+
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="whatever">
+ <fo:static-content flow-name="first-region">
+ <fo:block id="header.first.1" text-align="center">first</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="only-region">
+ <fo:block id="header.only.1" text-align="center">only</fo:block>
+ </fo:static-content>
+ <fo:flow flow-name="frame-body">
+ <fo:block>This is the only page</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="whatever">
+ <fo:static-content flow-name="only-region">
+ <fo:block id="header.only.2" text-align="center">only</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="first-region">
+ <fo:block id="header.first.2" text-align="center">first</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="last-region">
+ <fo:block id="header.last.2" text-align="center">last</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="rest-region">
+ <fo:block id="header.rest.2" text-align="center">rest</fo:block>
+ </fo:static-content>
+ <fo:flow flow-name="frame-body">
+ <fo:block>This is the first page</fo:block>
+ <fo:block break-before="page">This is a middle page</fo:block>
+ <fo:block break-before="page">This is a middle page</fo:block>
+ <fo:block break-before="page">This is the last page</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="header.only.1" xpath="(/areaTree/pageSequence[1]//regionBefore)[1]/block[1]/@prod-id" />
+ <eval expected="header.first.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[1]/block[1]/@prod-id" />
+ <eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[2]/block[1]/@prod-id" />
+ <eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[3]/block[1]/@prod-id" />
+ <eval expected="header.last.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[4]/block[1]/@prod-id" />
+ </checks>
+</testcase>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks for the use of an 'only' conditional-page-master-reference (XSL 1.1)
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ font-family="Times" font-size="20pt">
+
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="only-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="only-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="first-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="first-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="last-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="last-region" extent="10mm"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="rest-page-layout"
+ page-height="297mm" page-width="210mm"
+ margin-top="15mm" margin-bottom="15mm"
+ margin-left="15mm" margin-right="15mm">
+ <fo:region-body region-name="frame-body" margin-top="10mm"/>
+ <fo:region-before region-name="rest-region" extent="10mm"/>
+ </fo:simple-page-master>
+
+ <fo:page-sequence-master master-name="whatever">
+ <fo:repeatable-page-master-alternatives maximum-repeats="no-limit">
+ <fo:conditional-page-master-reference master-reference="only-page-layout"
+ page-position="only"/>
+ <fo:conditional-page-master-reference master-reference="first-page-layout"
+ page-position="first"/>
+ <fo:conditional-page-master-reference master-reference="last-page-layout"
+ page-position="last"/>
+ <fo:conditional-page-master-reference master-reference="rest-page-layout"
+ page-position="rest"/>
+ </fo:repeatable-page-master-alternatives>
+ </fo:page-sequence-master>
+
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="whatever">
+ <fo:static-content flow-name="first-region">
+ <fo:block id="header.first.1" text-align="center">first</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="only-region">
+ <fo:block id="header.only.1" text-align="center">only</fo:block>
+ </fo:static-content>
+ <fo:flow flow-name="frame-body">
+ <fo:block>This is the only page</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="whatever">
+ <fo:static-content flow-name="only-region">
+ <fo:block id="header.only.2" text-align="center">only</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="first-region">
+ <fo:block id="header.first.2" text-align="center">first</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="last-region">
+ <fo:block id="header.last.2" text-align="center">last</fo:block>
+ </fo:static-content>
+ <fo:static-content flow-name="rest-region">
+ <fo:block id="header.rest.2" text-align="center">rest</fo:block>
+ </fo:static-content>
+ <fo:flow flow-name="frame-body">
+ <fo:block>This is the first page</fo:block>
+ <fo:block break-before="page">This is a middle page</fo:block>
+ <fo:block break-before="page">This is a middle page</fo:block>
+ <fo:block break-before="page">This is the last page</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="header.only.1" xpath="(/areaTree/pageSequence[1]//regionBefore)[1]/block[1]/@prod-id" />
+ <eval expected="header.first.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[1]/block[1]/@prod-id" />
+ <eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[2]/block[1]/@prod-id" />
+ <eval expected="header.rest.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[3]/block[1]/@prod-id" />
+ <eval expected="header.last.2" xpath="(/areaTree/pageSequence[2]//regionBefore)[4]/block[1]/@prod-id" />
+ </checks>
+</testcase>