git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@707079 13f79535-47bb-0310-9956-ffa450edef68tags/fop-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: $ */ | |||||
package org.apache.fop.fonts; | |||||
import java.io.File; | |||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | |||||
import java.util.List; | |||||
import org.apache.commons.io.FileUtils; | |||||
/** | |||||
* Font info stored in the cache | |||||
*/ | |||||
public class CachedFontInfo extends EmbedFontInfo { | |||||
/** Serialization Version UID */ | |||||
private static final long serialVersionUID = 240028291961081894L; | |||||
/** file modify date (if available) */ | |||||
private long lastModified = -1; | |||||
/** | |||||
* Returns a file given a list of urls | |||||
* @param urls array of possible font urls | |||||
* @return file font file | |||||
*/ | |||||
public static File getFileFromUrls(String[] urls) { | |||||
for (int i = 0; i < urls.length; i++) { | |||||
try { | |||||
URL url = new URL(urls[i]); | |||||
url.getFile(); | |||||
File fontFile = FileUtils.toFile(url); | |||||
if (fontFile.exists() && fontFile.canRead()) { | |||||
return fontFile; | |||||
} | |||||
} catch (IllegalArgumentException e) { | |||||
// do nothing | |||||
} catch (MalformedURLException e) { | |||||
// do nothing | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Default constructor | |||||
* @param metricsFile metrics file | |||||
* @param kerning kerning | |||||
* @param fontTriplets font triplets | |||||
* @param embedFile embed file | |||||
* @param lastModified timestamp that this font was last modified | |||||
*/ | |||||
public CachedFontInfo(String metricsFile, boolean kerning, List fontTriplets, | |||||
String embedFile, long lastModified) { | |||||
super(metricsFile, kerning, fontTriplets, embedFile); | |||||
this.lastModified = lastModified; | |||||
} | |||||
/** | |||||
* Constructor | |||||
* @param fontInfo an existing embed font info | |||||
*/ | |||||
public CachedFontInfo(EmbedFontInfo fontInfo) { | |||||
super(fontInfo.metricsFile, fontInfo.kerning, fontInfo.fontTriplets, fontInfo.embedFile); | |||||
// try and determine modified date | |||||
File fontFile = getFileFromUrls(new String[] {embedFile, metricsFile}); | |||||
if (fontFile != null ) { | |||||
this.lastModified = fontFile.lastModified(); | |||||
} | |||||
} | |||||
/** | |||||
* Gets the modified timestamp for font file (not always available) | |||||
* @return modified timestamp | |||||
*/ | |||||
public long lastModified() { | |||||
return this.lastModified; | |||||
} | |||||
/** | |||||
* Gets the modified timestamp for font file | |||||
* (used for the purposes of font info caching) | |||||
* @param lastModified modified font file timestamp | |||||
*/ | |||||
public void setLastModified(long lastModified) { | |||||
this.lastModified = lastModified; | |||||
} | |||||
/** | |||||
* @return string representation of this object | |||||
* {@inheritDoc} | |||||
*/ | |||||
public String toString() { | |||||
return super.toString() + ", lastModified=" + lastModified; | |||||
} | |||||
} |
Url is actually a Uri | |||||
--This line, and those below, will be ignored-- | |||||
M FontLoader.java |
Url is really a Uri | |||||
--This line, and those below, will be ignored-- | |||||
M FontLoader.java |
/* | |||||
* 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: PFMFile.java 595297 2007-11-15 13:28:58Z jeremias $ */ | |||||
package org.apache.fop.fonts.type1; | |||||
// Java | |||||
import java.io.ByteArrayInputStream; | |||||
import java.io.IOException; | |||||
import java.io.InputStream; | |||||
import java.util.Map; | |||||
import org.apache.commons.io.IOUtils; | |||||
import org.apache.commons.logging.Log; | |||||
import org.apache.commons.logging.LogFactory; | |||||
import org.apache.fop.fonts.Glyphs; | |||||
/** | |||||
* This class represents a PFM file (or parts of it) as a Java object. | |||||
*/ | |||||
public class PFMFile { | |||||
// Header stuff | |||||
private String windowsName; | |||||
private String postscriptName; | |||||
private short dfItalic; | |||||
private int dfWeight; | |||||
private short dfCharSet; | |||||
private short dfPitchAndFamily; | |||||
private int dfAvgWidth; | |||||
private int dfMaxWidth; | |||||
private int dfMinWidth; | |||||
private short dfFirstChar; | |||||
private short dfLastChar; | |||||
// Extension stuff | |||||
// --- | |||||
// Extend Text Metrics | |||||
private int etmCapHeight; | |||||
private int etmXHeight; | |||||
private int etmLowerCaseAscent; | |||||
private int etmLowerCaseDescent; | |||||
// Extent table | |||||
private int[] extentTable; | |||||
private Map kerningTab = new java.util.HashMap(); | |||||
/** | |||||
* logging instance | |||||
*/ | |||||
protected Log log = LogFactory.getLog(PFMFile.class); | |||||
/** | |||||
* Parses a PFM file | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
* @throws IOException In case of an I/O problem | |||||
*/ | |||||
public void load(InputStream inStream) throws IOException { | |||||
byte[] pfmBytes = IOUtils.toByteArray(inStream); | |||||
InputStream bufin = inStream; | |||||
bufin = new ByteArrayInputStream(pfmBytes); | |||||
PFMInputStream in = new PFMInputStream(bufin); | |||||
bufin.mark(512); | |||||
short sh1 = in.readByte(); | |||||
short sh2 = in.readByte(); | |||||
if (sh1 == 128 && sh2 == 1) { | |||||
//Found the first section header of a PFB file! | |||||
throw new IOException("Cannot parse PFM file. You probably specified the PFB file" | |||||
+ " of a Type 1 font as parameter instead of the PFM."); | |||||
} | |||||
bufin.reset(); | |||||
byte[] b = new byte[16]; | |||||
bufin.read(b); | |||||
if (new String(b, "US-ASCII").equalsIgnoreCase("StartFontMetrics")) { | |||||
//Found the header of a AFM file! | |||||
throw new IOException("Cannot parse PFM file. You probably specified the AFM file" | |||||
+ " of a Type 1 font as parameter instead of the PFM."); | |||||
} | |||||
bufin.reset(); | |||||
final int version = in.readShort(); | |||||
if (version != 256) { | |||||
log.warn("PFM version expected to be '256' but got '" + version + "'." | |||||
+ " Please make sure you specify the PFM as parameter" | |||||
+ " and not the PFB or the AFM."); | |||||
} | |||||
//final long filesize = in.readInt(); | |||||
bufin.reset(); | |||||
loadHeader(in); | |||||
loadExtension(in); | |||||
} | |||||
/** | |||||
* Parses the header of the PFM file. | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
* @throws IOException In case of an I/O problem | |||||
*/ | |||||
private void loadHeader(PFMInputStream inStream) throws IOException { | |||||
inStream.skip(80); | |||||
dfItalic = inStream.readByte(); | |||||
inStream.skip(2); | |||||
dfWeight = inStream.readShort(); | |||||
dfCharSet = inStream.readByte(); | |||||
inStream.skip(4); | |||||
dfPitchAndFamily = inStream.readByte(); | |||||
dfAvgWidth = inStream.readShort(); | |||||
dfMaxWidth = inStream.readShort(); | |||||
dfFirstChar = inStream.readByte(); | |||||
dfLastChar = inStream.readByte(); | |||||
inStream.skip(8); | |||||
long faceOffset = inStream.readInt(); | |||||
inStream.reset(); | |||||
inStream.skip(faceOffset); | |||||
windowsName = inStream.readString(); | |||||
inStream.reset(); | |||||
inStream.skip(117); | |||||
} | |||||
/** | |||||
* Parses the extension part of the PFM file. | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
*/ | |||||
private void loadExtension(PFMInputStream inStream) throws IOException { | |||||
final int size = inStream.readShort(); | |||||
if (size != 30) { | |||||
log.warn("Size of extension block was expected to be " | |||||
+ "30 bytes, but was " + size + " bytes."); | |||||
} | |||||
final long extMetricsOffset = inStream.readInt(); | |||||
final long extentTableOffset = inStream.readInt(); | |||||
inStream.skip(4); //Skip dfOriginTable | |||||
final long kernPairOffset = inStream.readInt(); | |||||
inStream.skip(4); //Skip dfTrackKernTable | |||||
long driverInfoOffset = inStream.readInt(); | |||||
if (kernPairOffset > 0) { | |||||
inStream.reset(); | |||||
inStream.skip(kernPairOffset); | |||||
loadKernPairs(inStream); | |||||
} | |||||
inStream.reset(); | |||||
inStream.skip(driverInfoOffset); | |||||
postscriptName = inStream.readString(); | |||||
if (extMetricsOffset != 0) { | |||||
inStream.reset(); | |||||
inStream.skip(extMetricsOffset); | |||||
loadExtMetrics(inStream); | |||||
} | |||||
if (extentTableOffset != 0) { | |||||
inStream.reset(); | |||||
inStream.skip(extentTableOffset); | |||||
loadExtentTable(inStream); | |||||
} | |||||
} | |||||
/** | |||||
* Parses the kernPairs part of the pfm file | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
*/ | |||||
private void loadKernPairs(PFMInputStream inStream) throws IOException { | |||||
int i = inStream.readShort(); | |||||
if (log.isTraceEnabled()) { | |||||
log.trace(i + " kerning pairs"); | |||||
} | |||||
while (i > 0) { | |||||
int g1 = (int)inStream.readByte(); | |||||
i--; | |||||
int g2 = (int)inStream.readByte(); | |||||
int adj = inStream.readShort(); | |||||
if (adj > 0x8000) { | |||||
adj = -(0x10000 - adj); | |||||
} | |||||
if (log.isTraceEnabled()) { | |||||
log.trace("Char no: (" + g1 + ", " + g2 + ") kern: " + adj); | |||||
final String glyph1 = Glyphs.TEX8R_GLYPH_NAMES[g1]; | |||||
final String glyph2 = Glyphs.TEX8R_GLYPH_NAMES[g2]; | |||||
log.trace("glyphs: " + glyph1 + ", " + glyph2); | |||||
} | |||||
Map adjTab = (Map)kerningTab.get(new Integer(g1)); | |||||
if (adjTab == null) { | |||||
adjTab = new java.util.HashMap(); | |||||
} | |||||
adjTab.put(new Integer(g2), new Integer(adj)); | |||||
kerningTab.put(new Integer(g1), adjTab); | |||||
} | |||||
} | |||||
/** | |||||
* Parses the extended metrics part of the PFM file. | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
*/ | |||||
private void loadExtMetrics(PFMInputStream inStream) throws IOException { | |||||
final int size = inStream.readShort(); | |||||
if (size != 52) { | |||||
log.warn("Size of extension block was expected to be " | |||||
+ "52 bytes, but was " + size + " bytes."); | |||||
} | |||||
inStream.skip(12); //Skip etmPointSize, etmOrientation, etmMasterHeight, | |||||
//etmMinScale, etmMaxScale, emtMasterUnits | |||||
etmCapHeight = inStream.readShort(); | |||||
etmXHeight = inStream.readShort(); | |||||
etmLowerCaseAscent = inStream.readShort(); | |||||
etmLowerCaseDescent = -(inStream.readShort()); | |||||
//Ignore the rest of the values | |||||
} | |||||
/** | |||||
* Parses the extent table of the PFM file. | |||||
* | |||||
* @param inStream The stream from which to read the PFM file. | |||||
*/ | |||||
private void loadExtentTable(PFMInputStream inStream) throws IOException { | |||||
extentTable = new int[dfLastChar - dfFirstChar + 1]; | |||||
dfMinWidth = dfMaxWidth; | |||||
for (short i = dfFirstChar; i <= dfLastChar; i++) { | |||||
extentTable[i - dfFirstChar] = inStream.readShort(); | |||||
if (extentTable[i - dfFirstChar] < dfMinWidth) { | |||||
dfMinWidth = extentTable[i - dfFirstChar]; | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Returns the Windows name of the font. | |||||
* | |||||
* @return The Windows name. | |||||
*/ | |||||
public String getWindowsName() { | |||||
return windowsName; | |||||
} | |||||
/** | |||||
* Return the kerning table. The kerning table is a Map with | |||||
* strings with glyphnames as keys, containing Maps as value. | |||||
* The value map contains a glyph name string key and an Integer value | |||||
* | |||||
* @return A Map containing the kerning table | |||||
*/ | |||||
public Map getKerning() { | |||||
return kerningTab; | |||||
} | |||||
/** | |||||
* Returns the Postscript name of the font. | |||||
* | |||||
* @return The Postscript name. | |||||
*/ | |||||
public String getPostscriptName() { | |||||
return postscriptName; | |||||
} | |||||
/** | |||||
* Returns the charset used for the font. | |||||
* | |||||
* @return The charset (0=WinAnsi). | |||||
*/ | |||||
public short getCharSet() { | |||||
return dfCharSet; | |||||
} | |||||
/** | |||||
* Returns the charset of the font as a string. | |||||
* | |||||
* @return The name of the charset. | |||||
*/ | |||||
public String getCharSetName() { | |||||
//TODO Had to remove the detection for Expert(Subset) encoding. The PFM is not suitable | |||||
//for detecting these character sets. We have to parse the AFM for that. | |||||
switch (dfCharSet) { | |||||
case 0: | |||||
return "WinAnsi"; // AKA ISOAdobe | |||||
case 1: | |||||
return "Expert"; | |||||
case 2: | |||||
if ("Symbol".equals(getPostscriptName())) { | |||||
return "Symbol"; | |||||
} else { | |||||
return "ExpertSubset"; | |||||
} | |||||
case 128: | |||||
return "Shift-JIS (Japanese)"; | |||||
default: | |||||
log.warn("Unknown charset detected (" + dfCharSet | |||||
+ ", 0x" + Integer.toHexString(dfCharSet) | |||||
+ "). Trying fallback to WinAnsi."); | |||||
} | |||||
return "WinAnsi"; | |||||
} | |||||
/** | |||||
* Returns the number of the character that defines | |||||
* the first entry in the widths list. | |||||
* | |||||
* @return The number of the first character. | |||||
*/ | |||||
public short getFirstChar() { | |||||
return dfFirstChar; | |||||
} | |||||
/** | |||||
* Returns the number of the character that defines | |||||
* the last entry in the widths list. | |||||
* | |||||
* @return The number of the last character. | |||||
*/ | |||||
public short getLastChar() { | |||||
return dfLastChar; | |||||
} | |||||
/** | |||||
* Returns the CapHeight parameter for the font (height of uppercase H). | |||||
* | |||||
* @return The CapHeight parameter. | |||||
*/ | |||||
public int getCapHeight() { | |||||
return etmCapHeight; | |||||
} | |||||
/** | |||||
* Returns the XHeight parameter for the font (height of lowercase x). | |||||
* | |||||
* @return The CapHeight parameter. | |||||
*/ | |||||
public int getXHeight() { | |||||
return etmXHeight; | |||||
} | |||||
/** | |||||
* Returns the LowerCaseAscent parameter for the font (height of lowercase d). | |||||
* | |||||
* @return The LowerCaseAscent parameter. | |||||
*/ | |||||
public int getLowerCaseAscent() { | |||||
return etmLowerCaseAscent; | |||||
} | |||||
/** | |||||
* Returns the LowerCaseDescent parameter for the font (height of lowercase p). | |||||
* | |||||
* @return The LowerCaseDescent parameter. | |||||
*/ | |||||
public int getLowerCaseDescent() { | |||||
return etmLowerCaseDescent; | |||||
} | |||||
/** | |||||
* Tells whether the font has proportional character spacing. | |||||
* | |||||
* @return ex. true for Times, false for Courier. | |||||
*/ | |||||
public boolean getIsProportional() { | |||||
return ((dfPitchAndFamily & 1) == 1); | |||||
} | |||||
/** | |||||
* Returns the bounding box for the font. | |||||
* Note: this value is just an approximation, | |||||
* it does not really exist in the PFM file. | |||||
* | |||||
* @return The calculated Font BBox. | |||||
*/ | |||||
public int[] getFontBBox() { | |||||
int[] bbox = new int[4]; | |||||
// Just guessing.... | |||||
if (!getIsProportional() && (dfAvgWidth == dfMaxWidth)) { | |||||
bbox[0] = -20; | |||||
} else { | |||||
bbox[0] = -100; | |||||
} | |||||
bbox[1] = getLowerCaseDescent() - 5; | |||||
bbox[2] = dfMaxWidth + 10; | |||||
bbox[3] = getLowerCaseAscent() + 5; | |||||
return bbox; | |||||
} | |||||
/** | |||||
* Indicates whether the font is non-symbolic (Font uses the Adobe standard Latin character | |||||
* set or a subset of it). | |||||
* @return true if the font is non-symbolic | |||||
*/ | |||||
public boolean isNonSymbolic() { | |||||
return (dfCharSet != 2); //!= Symbol fonts | |||||
} | |||||
/** | |||||
* Returns the characteristics flags for the font as | |||||
* needed for a PDF font descriptor (See PDF specs). | |||||
* | |||||
* @return The characteristics flags. | |||||
*/ | |||||
public int getFlags() { | |||||
int flags = 0; | |||||
if (!getIsProportional()) { | |||||
flags |= 1; //bit 1: FixedPitch | |||||
} | |||||
if (isNonSymbolic()) { | |||||
flags |= 32; //bit 6: Nonsymbolic | |||||
} else { | |||||
flags |= 4; //bit 3: Symbolic | |||||
} | |||||
//int serif = dfPitchAndFamily & 0xFFFE; | |||||
if ((dfPitchAndFamily & 16) != 0) { | |||||
flags |= 2; //bit 2: Serif | |||||
} | |||||
if ((dfPitchAndFamily & 64) != 0) { | |||||
flags |= 8; //bit 4: Script | |||||
} | |||||
if (dfItalic != 0) { | |||||
flags |= 64; //bit 7: Italic | |||||
} | |||||
return flags; | |||||
} | |||||
/** | |||||
* Returns the width of the dominant vertical stems of the font. | |||||
* Note: this value is just an approximation, | |||||
* it does not really exist in the PFM file. | |||||
* | |||||
* @return The vertical stem width. | |||||
*/ | |||||
public int getStemV() { | |||||
// Just guessing.... | |||||
if (dfItalic != 0) { | |||||
return (int)Math.round(dfMinWidth * 0.25); | |||||
} else { | |||||
return (int)Math.round(dfMinWidth * 0.6); | |||||
} | |||||
} | |||||
/** | |||||
* Returns the italic angle of the font. | |||||
* Note: this value is just an approximation, | |||||
* it does not really exist in the PFM file. | |||||
* | |||||
* @return The italic angle. | |||||
*/ | |||||
public int getItalicAngle() { | |||||
if (dfItalic != 0) { | |||||
return -16; // Just guessing.... | |||||
} else { | |||||
return 0; | |||||
} | |||||
} | |||||
/** | |||||
* Returns the width of a character | |||||
* | |||||
* @param which The number of the character for which the width is requested. | |||||
* @return The width of a character. | |||||
*/ | |||||
public int getCharWidth(short which) { | |||||
return extentTable[which - dfFirstChar]; | |||||
} | |||||
} |
/* | |||||
* 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: TIFFImage.java 557337 2007-07-18 17:37:14Z adelmelle $ */ | |||||
package org.apache.fop.image; | |||||
import java.awt.color.ColorSpace; | |||||
import java.io.IOException; | |||||
import org.apache.xmlgraphics.image.codec.util.SeekableStream; | |||||
import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory; | |||||
import org.apache.xmlgraphics.image.codec.tiff.TIFFField; | |||||
import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder; | |||||
import org.apache.xmlgraphics.image.rendered.CachableRed; | |||||
import org.apache.commons.io.IOUtils; | |||||
/** | |||||
* TIFF implementation using the Batik codecs. | |||||
*/ | |||||
public class TIFFImage extends XmlGraphicsCommonsImage { | |||||
private int compression = 0; | |||||
private int stripCount = 0; | |||||
private long stripOffset = 0; | |||||
private long stripLength = 0; | |||||
private int fillOrder = 1; | |||||
/** | |||||
* Constructs a new BatikImage instance. | |||||
* @param imgReader basic metadata for the image | |||||
*/ | |||||
public TIFFImage(FopImage.ImageInfo imgReader) { | |||||
super(imgReader); | |||||
} | |||||
/** | |||||
* The compression type set in the TIFF directory | |||||
* @return the TIFF compression type | |||||
*/ | |||||
public int getCompression() { | |||||
return compression; | |||||
} | |||||
/** | |||||
* The number of strips in the image | |||||
* @return the number of strips in the image | |||||
*/ | |||||
public int getStripCount() { | |||||
return stripCount; | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
* org.apache.xmlgraphics.image.codec.util.SeekableStream) | |||||
*/ | |||||
protected CachableRed decodeImage(SeekableStream stream) throws IOException { | |||||
org.apache.xmlgraphics.image.codec.tiff.TIFFImage img | |||||
= new org.apache.xmlgraphics.image.codec.tiff.TIFFImage | |||||
(stream, null, 0); | |||||
TIFFDirectory dir = (TIFFDirectory)img.getProperty("tiff_directory"); | |||||
TIFFField fld = dir.getField(TIFFImageDecoder.TIFF_X_RESOLUTION); | |||||
if (fld != null) { | |||||
log.debug("x resolution = " + fld.getAsDouble(0)); | |||||
this.dpiHorizontal = fld.getAsDouble(0); | |||||
} else { | |||||
log.warn("Cannot determine x resolution."); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_Y_RESOLUTION); | |||||
if (fld != null) { | |||||
log.debug("y resolution = " + fld.getAsDouble(0)); | |||||
this.dpiVertical = fld.getAsDouble(0); | |||||
} else { | |||||
log.warn("Cannot determine y resolution."); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT); | |||||
if (fld != null) { | |||||
int resUnit = fld.getAsInt(0); | |||||
if (resUnit == 3) { | |||||
//cm | |||||
this.dpiHorizontal *= 2.54f; | |||||
this.dpiVertical *= 2.54f; | |||||
} else if (resUnit != 2) { | |||||
//ignored | |||||
log.warn("Cannot determine bitmap resolution." | |||||
+ " Unimplemented resolution unit: " + resUnit); | |||||
} | |||||
} else { | |||||
log.warn("Cannot determine bitmap resolution unit."); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION); | |||||
if (fld != null) { | |||||
compression = fld.getAsInt(0); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE); | |||||
if (fld != null) { | |||||
bitsPerPixel = fld.getAsInt(0); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP); | |||||
if (fld == null) { | |||||
stripCount = 1; | |||||
} else { | |||||
stripCount = (int)(dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH) | |||||
/ fld.getAsLong(0)); | |||||
} | |||||
fld = dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER); | |||||
if (fld != null) { | |||||
fillOrder = fld.getAsInt(0); | |||||
} | |||||
stripOffset = dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS).getAsLong(0); | |||||
stripLength = dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS).getAsLong(0); | |||||
if (this.bitsPerPixel == 1) { | |||||
this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY); | |||||
} | |||||
return img; | |||||
} | |||||
/** | |||||
* Load the original TIFF data. | |||||
* This loads only strip 1 of the original TIFF data. | |||||
* | |||||
* @return true if loaded false for any error | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected boolean loadOriginalData() { | |||||
if (loadDimensions()) { | |||||
byte[] readBuf = new byte[(int)stripLength]; | |||||
int bytesRead; | |||||
try { | |||||
this.seekableInput.reset(); | |||||
this.seekableInput.skip(stripOffset); | |||||
bytesRead = seekableInput.read(readBuf); | |||||
if (bytesRead != stripLength) { | |||||
log.error("Error while loading image: length mismatch on read"); | |||||
return false; | |||||
} | |||||
// need to invert bytes if fill order = 2 | |||||
if (fillOrder == 2) { | |||||
for (int i = 0; i < (int)stripLength; i++) { | |||||
readBuf[i] = flipTable[readBuf[i] & 0xff]; | |||||
} | |||||
} | |||||
this.raw = readBuf; | |||||
return true; | |||||
} catch (IOException ioe) { | |||||
log.error("Error while loading image strip 1 (TIFF): ", ioe); | |||||
return false; | |||||
} finally { | |||||
IOUtils.closeQuietly(seekableInput); | |||||
IOUtils.closeQuietly(inputStream); | |||||
this.seekableInput = null; | |||||
this.inputStream = null; | |||||
this.cr = null; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
// Table to be used when fillOrder = 2, for flipping bytes. | |||||
// Copied from XML Graphics Commons' TIFFFaxDecoder class | |||||
private static byte[] flipTable = { | |||||
0, -128, 64, -64, 32, -96, 96, -32, | |||||
16, -112, 80, -48, 48, -80, 112, -16, | |||||
8, -120, 72, -56, 40, -88, 104, -24, | |||||
24, -104, 88, -40, 56, -72, 120, -8, | |||||
4, -124, 68, -60, 36, -92, 100, -28, | |||||
20, -108, 84, -44, 52, -76, 116, -12, | |||||
12, -116, 76, -52, 44, -84, 108, -20, | |||||
28, -100, 92, -36, 60, -68, 124, -4, | |||||
2, -126, 66, -62, 34, -94, 98, -30, | |||||
18, -110, 82, -46, 50, -78, 114, -14, | |||||
10, -118, 74, -54, 42, -86, 106, -22, | |||||
26, -102, 90, -38, 58, -70, 122, -6, | |||||
6, -122, 70, -58, 38, -90, 102, -26, | |||||
22, -106, 86, -42, 54, -74, 118, -10, | |||||
14, -114, 78, -50, 46, -82, 110, -18, | |||||
30, -98, 94, -34, 62, -66, 126, -2, | |||||
1, -127, 65, -63, 33, -95, 97, -31, | |||||
17, -111, 81, -47, 49, -79, 113, -15, | |||||
9, -119, 73, -55, 41, -87, 105, -23, | |||||
25, -103, 89, -39, 57, -71, 121, -7, | |||||
5, -123, 69, -59, 37, -91, 101, -27, | |||||
21, -107, 85, -43, 53, -75, 117, -11, | |||||
13, -115, 77, -51, 45, -83, 109, -19, | |||||
29, -99, 93, -35, 61, -67, 125, -3, | |||||
3, -125, 67, -61, 35, -93, 99, -29, | |||||
19, -109, 83, -45, 51, -77, 115, -13, | |||||
11, -117, 75, -53, 43, -85, 107, -21, | |||||
27, -101, 91, -37, 59, -69, 123, -5, | |||||
7, -121, 71, -57, 39, -89, 103, -25, | |||||
23, -105, 87, -41, 55, -73, 119, -9, | |||||
15, -113, 79, -49, 47, -81, 111, -17, | |||||
31, -97, 95, -33, 63, -65, 127, -1, | |||||
}; | |||||
// end | |||||
} |
/* | |||||
* 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.afp.extensions; | |||||
import org.xml.sax.helpers.AttributesImpl; | |||||
import org.xml.sax.ContentHandler; | |||||
import org.xml.sax.SAXException; | |||||
//import org.xml.sax.helpers.AttributesImpl; | |||||
/** | |||||
* An AFP resource group configuration definition for a document | |||||
*/ | |||||
public class AFPResourceInfo extends AFPExtensionAttachment { | |||||
private static final long serialVersionUID = -7333967815112216396L; | |||||
/** AFP resource groups are stored in an external resource file */ | |||||
private static final int LEVEL_INLINE = 0; | |||||
/** AFP resource groups are stored at page level */ | |||||
private static final int LEVEL_PAGE = 1; | |||||
/** AFP resource groups are stored at page group level */ | |||||
private static final int LEVEL_PAGE_GROUP = 2; | |||||
/** AFP resource groups are stored within the document at document level */ | |||||
private static final int LEVEL_DOCUMENT = 3; | |||||
/** AFP resource groups are stored outside the document at print file level */ | |||||
private static final int LEVEL_PRINT_FILE = 4; | |||||
/** AFP resource groups are stored in an external resource file */ | |||||
private static final int LEVEL_EXTERNAL = 5; | |||||
private static final String LEVEL_NAME_INLINE = "inline"; | |||||
private static final String LEVEL_NAME_PAGE = "page"; | |||||
private static final String LEVEL_NAME_PAGE_GROUP = "page-group"; | |||||
private static final String LEVEL_NAME_DOCUMENT = "document"; | |||||
private static final String LEVEL_NAME_PRINT_FILE = "print-file"; | |||||
private static final String LEVEL_NAME_EXTERNAL = "external"; | |||||
/** | |||||
* level token/name mapping | |||||
*/ | |||||
private static final String[] LEVEL_NAME_MAP = { | |||||
LEVEL_NAME_INLINE, LEVEL_NAME_PAGE, LEVEL_NAME_PAGE_GROUP, | |||||
LEVEL_NAME_DOCUMENT, LEVEL_NAME_PRINT_FILE, LEVEL_NAME_EXTERNAL | |||||
}; | |||||
/** | |||||
* the <afp:resource-info/> element name | |||||
*/ | |||||
public static final String ELEMENT = "resource-info"; | |||||
/** | |||||
* the level at which resource groups are placed | |||||
*/ | |||||
private int level = -1; | |||||
/** | |||||
* the destination filename for resource groups with level = "external" | |||||
*/ | |||||
private String dest; | |||||
/** | |||||
* Default constructor. | |||||
*/ | |||||
public AFPResourceInfo() { | |||||
super(ELEMENT); | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
public String toString() { | |||||
return "AFPResourceInfo(" | |||||
+ "name=" + name + ", " | |||||
+ (level > -1 ? "level=" + LEVEL_NAME_MAP[level] : "") | |||||
+ (dest != null ? ", dest=" + getDestination() : "" ) + ")"; | |||||
} | |||||
/** | |||||
* Sets the destination filename of where resources | |||||
* are to be stored for this document | |||||
* @param destination the location of the external resource group file | |||||
*/ | |||||
public void setExternalDestination(String destination) { | |||||
this.dest = destination; | |||||
} | |||||
/** | |||||
* Returns the destination filename of where external resources | |||||
* are to be stored for this document. | |||||
* @return the destination AFP external resource filename | |||||
*/ | |||||
public String getDestination() { | |||||
return this.dest; | |||||
} | |||||
/** | |||||
* Sets the level at which resource groups are stored | |||||
* @param level the resource group level | |||||
*/ | |||||
public void setLevel(int level) { | |||||
this.level = level; | |||||
} | |||||
/** | |||||
* Sets the level at which resource groups are stored | |||||
* @param name the level name | |||||
*/ | |||||
public void setLevel(String name) { | |||||
if (name != null) { | |||||
for (int i = 0; i < LEVEL_NAME_MAP.length; i++) { | |||||
if (name.toLowerCase().equals(LEVEL_NAME_MAP[i])) { | |||||
this.level = i; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Returns the level at which resource groups are stored | |||||
* @return the level at which resource groups are stored | |||||
*/ | |||||
public int getLevel() { | |||||
return this.level; | |||||
} | |||||
private static final String ATT_LEVEL = "level"; | |||||
private static final String ATT_DEST = "dest"; | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
public void toSAX(ContentHandler handler) throws SAXException { | |||||
AttributesImpl atts = new AttributesImpl(); | |||||
// name | |||||
if (hasName()) { | |||||
atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", super.getName()); | |||||
} | |||||
// level | |||||
if (level > 0) { | |||||
atts.addAttribute(null, ATT_LEVEL, ATT_LEVEL, "CDATA", LEVEL_NAME_MAP[level]); | |||||
// dest | |||||
if (level == LEVEL_EXTERNAL && dest != null && dest.length() > 0) { | |||||
atts.addAttribute(null, ATT_DEST, ATT_DEST, "CDATA", dest); | |||||
} | |||||
} | |||||
handler.startElement(CATEGORY, elementName, elementName, atts); | |||||
handler.endElement(CATEGORY, elementName, elementName); | |||||
} | |||||
/** | |||||
* @return true if this resource group is to be stored externally | |||||
*/ | |||||
public boolean isExternalLevel() { | |||||
return level == LEVEL_EXTERNAL; | |||||
} | |||||
} |
/* | |||||
* 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.afp.extensions; | |||||
import org.apache.fop.apps.FOPException; | |||||
//import org.apache.fop.fo.Constants; | |||||
import org.apache.fop.fo.Constants; | |||||
import org.apache.fop.fo.FONode; | |||||
//import org.apache.fop.fo.ValidationException; | |||||
import org.apache.fop.fo.extensions.ExtensionAttachment; | |||||
import org.apache.fop.fo.PropertyList; | |||||
import org.xml.sax.Attributes; | |||||
import org.xml.sax.Locator; | |||||
/** | |||||
* Extension element for afp:resource-group | |||||
*/ | |||||
public class AFPResourceInfoElement extends AbstractAFPExtensionObject { | |||||
/** | |||||
* Main constructor | |||||
* @param parent parent FO node | |||||
*/ | |||||
public AFPResourceInfoElement(FONode parent) { | |||||
super(parent, AFPResourceInfo.ELEMENT); | |||||
} | |||||
/** | |||||
* @throws FOPException if there's a problem during processing | |||||
* @see org.apache.fop.fo.FONode#startOfNode() | |||||
*/ | |||||
protected void startOfNode() throws FOPException { | |||||
if (parent.getNameId() != Constants.FO_INSTREAM_FOREIGN_OBJECT | |||||
&& parent.getNameId() != Constants.FO_EXTERNAL_GRAPHIC) { | |||||
invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), | |||||
"rule.childOfInstreamForeignObjectorExternalGraphic"); | |||||
} | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
public void processNode(String elementName, Locator locator, | |||||
Attributes attlist, PropertyList propertyList) | |||||
throws FOPException { | |||||
getExtensionAttachment(); | |||||
String attr = attlist.getValue("name"); | |||||
if (attr != null && attr.length() > 0) { | |||||
extensionAttachment.setName(attr); | |||||
} else { | |||||
throw new FOPException(elementName + " must have a name attribute."); | |||||
} | |||||
String lvl = attlist.getValue("level"); | |||||
AFPResourceInfo resourceInfo = (AFPResourceInfo)getExtensionAttachment(); | |||||
if (lvl != null && lvl.length() > 0) { | |||||
resourceInfo.setLevel(lvl); | |||||
if (resourceInfo.isExternalLevel()) { | |||||
String dest = attlist.getValue("dest"); | |||||
if (dest != null && dest.length() > 0) { | |||||
resourceInfo.setExternalDestination(dest); | |||||
} else { | |||||
throw new FOPException("must have a dest attribute."); | |||||
} | |||||
} | |||||
} else { | |||||
throw new FOPException("must have a level attribute."); | |||||
} | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected ExtensionAttachment instantiateExtensionAttachment() { | |||||
return new AFPResourceInfo(); | |||||
} | |||||
} |
/* | |||||
* 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.afp.modca; | |||||
import java.io.IOException; | |||||
import java.io.OutputStream; | |||||
import java.util.List; | |||||
/** | |||||
* The document index defined by the MOD:CA architecture provides functions | |||||
* for indexing the document based on document structure and on | |||||
* application-defined document tags. | |||||
*/ | |||||
public class DocumentIndex extends AbstractStructuredAFPObject { | |||||
/** | |||||
* document index element | |||||
*/ | |||||
private IndexElement indexElement; | |||||
private List linkLogicalElements; | |||||
private List tagLogicalElements; | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected void writeStart(OutputStream os) throws IOException { | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected void writeContent(OutputStream os) throws IOException { | |||||
indexElement.writeToStream(os); | |||||
writeObjects(linkLogicalElements, os); | |||||
writeObjects(tagLogicalElements, os); | |||||
} | |||||
/** | |||||
* {@inheritDoc} | |||||
*/ | |||||
protected void writeEnd(OutputStream os) throws IOException { | |||||
} | |||||
private class IndexElement extends AbstractAFPObject { | |||||
public void writeToStream(OutputStream os) throws IOException { | |||||
} | |||||
} | |||||
} |
Moved goca package to level above modca. | |||||
--This line, and those below, will be ignored-- | |||||
A goca | |||||
A goca/GraphicsChainedSegment.java | |||||
A goca/GraphicsSetPatternSymbol.java | |||||
A goca/GraphicsFillet.java | |||||
A goca/GraphicsSetCurrentPosition.java | |||||
D goca/AbstractPreparedAFPObject.java | |||||
A goca/GraphicsSetCharacterSet.java | |||||
A goca/GraphicsImageBegin.java | |||||
A goca/GraphicsLine.java | |||||
A goca/GraphicsBox.java | |||||
A goca/GraphicsFullArc.java | |||||
A goca/GraphicsSetProcessColor.java | |||||
A goca/AbstractGraphicsCoord.java | |||||
A goca/GraphicsSetLineWidth.java | |||||
A goca/GraphicsSetLineType.java | |||||
A goca/GraphicsSetArcParameters.java | |||||
A goca/AbstractGraphicsContainer.java | |||||
A goca/GraphicsString.java | |||||
A goca/GraphicsArea.java | |||||
A goca/GraphicsImageEnd.java | |||||
A goca/GraphicsData.java | |||||
A goca/GraphicsImageData.java |
Moved goca package to level above modca. | |||||
--This line, and those below, will be ignored-- | |||||
A goca | |||||
A goca/GraphicsChainedSegment.java | |||||
A goca/GraphicsSetPatternSymbol.java | |||||
A goca/GraphicsFillet.java | |||||
A goca/GraphicsSetCurrentPosition.java | |||||
D goca/AbstractPreparedAFPObject.java | |||||
A goca/GraphicsSetCharacterSet.java | |||||
A goca/GraphicsImageBegin.java | |||||
A goca/GraphicsLine.java | |||||
A goca/GraphicsBox.java | |||||
A goca/GraphicsFullArc.java | |||||
A goca/GraphicsSetProcessColor.java | |||||
A goca/AbstractGraphicsCoord.java | |||||
A goca/GraphicsSetLineWidth.java | |||||
A goca/GraphicsSetLineType.java | |||||
A goca/GraphicsSetArcParameters.java | |||||
A goca/AbstractGraphicsContainer.java | |||||
A goca/GraphicsString.java | |||||
A goca/GraphicsArea.java | |||||
A goca/GraphicsImageEnd.java | |||||
A goca/GraphicsData.java | |||||
A goca/GraphicsImageData.java |
Moved goca package to level above modca. | |||||
--This line, and those below, will be ignored-- | |||||
A goca | |||||
A goca/GraphicsChainedSegment.java | |||||
A goca/GraphicsSetPatternSymbol.java | |||||
A goca/GraphicsFillet.java | |||||
A goca/GraphicsSetCurrentPosition.java | |||||
D goca/AbstractPreparedAFPObject.java | |||||
A goca/GraphicsSetCharacterSet.java | |||||
A goca/GraphicsImageBegin.java | |||||
A goca/GraphicsLine.java | |||||
A goca/GraphicsBox.java | |||||
A goca/GraphicsFullArc.java | |||||
A goca/GraphicsSetProcessColor.java | |||||
A goca/AbstractGraphicsCoord.java | |||||
A goca/GraphicsSetLineWidth.java | |||||
A goca/GraphicsSetLineType.java | |||||
A goca/GraphicsSetArcParameters.java | |||||
A goca/AbstractGraphicsContainer.java | |||||
A goca/GraphicsString.java | |||||
A goca/GraphicsArea.java | |||||
A goca/GraphicsImageEnd.java | |||||
A goca/GraphicsData.java | |||||
A goca/GraphicsImageData.java |
Index: PDFGraphics2D.java | |||||
=================================================================== | |||||
--- PDFGraphics2D.java (Revision 570024) | |||||
+++ PDFGraphics2D.java (Arbeitskopie) | |||||
@@ -719,13 +719,15 @@ | |||||
} | |||||
c = getColor(); | |||||
- if (graphicsState.setColor(c)) { | |||||
+ graphicsState.setColor(c); | |||||
+ // if (graphicsState.setColor(c)) { | |||||
applyColor(c, false); | |||||
- } | |||||
+ // } | |||||
c = getBackground(); | |||||
- if (graphicsState.setBackColor(c)) { | |||||
+ graphicsState.setBackColor(c); | |||||
+ // if (graphicsState.setBackColor(c)) { | |||||
applyColor(c, true); | |||||
- } | |||||
+ // } | |||||
Paint paint = getPaint(); | |||||
if (graphicsState.setPaint(paint)) { | |||||
@@ -1718,13 +1720,15 @@ | |||||
} | |||||
c = getColor(); | |||||
- if (graphicsState.setColor(c)) { | |||||
+ graphicsState.setColor(c); | |||||
+ // if (graphicsState.setColor(c)) { | |||||
applyColor(c, true); | |||||
- } | |||||
+ // } | |||||
c = getBackground(); | |||||
- if (graphicsState.setBackColor(c)) { | |||||
+ graphicsState.setBackColor(c); | |||||
+ // if (graphicsState.setBackColor(c)) { | |||||
applyColor(c, false); | |||||
- } | |||||
+ // } | |||||
Paint paint = getPaint(); | |||||
if (graphicsState.setPaint(paint)) { |