Browse Source

Merged changes from Trunk up to revision 1040962


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1040969 13f79535-47bb-0310-9956-ffa450edef68
pull/26/head
Vincent Hennebert 13 years ago
parent
commit
06b6c0ef40
46 changed files with 562 additions and 556 deletions
  1. 8
    6
      src/java/org/apache/fop/fonts/AbstractCodePointMapping.java
  2. 9
    11
      src/java/org/apache/fop/fonts/CIDSubset.java
  3. 13
    11
      src/java/org/apache/fop/fonts/CustomFont.java
  4. 4
    4
      src/java/org/apache/fop/fonts/CustomFontCollection.java
  5. 3
    3
      src/java/org/apache/fop/fonts/EmbedFontInfo.java
  6. 6
    5
      src/java/org/apache/fop/fonts/Font.java
  7. 6
    8
      src/java/org/apache/fop/fonts/FontAdder.java
  8. 15
    16
      src/java/org/apache/fop/fonts/FontCache.java
  9. 6
    7
      src/java/org/apache/fop/fonts/FontDetector.java
  10. 52
    55
      src/java/org/apache/fop/fonts/FontInfo.java
  11. 18
    21
      src/java/org/apache/fop/fonts/FontInfoConfigurator.java
  12. 4
    9
      src/java/org/apache/fop/fonts/FontManager.java
  13. 5
    7
      src/java/org/apache/fop/fonts/FontManagerConfigurator.java
  14. 2
    2
      src/java/org/apache/fop/fonts/FontMetrics.java
  15. 12
    10
      src/java/org/apache/fop/fonts/FontReader.java
  16. 6
    7
      src/java/org/apache/fop/fonts/FontSetup.java
  17. 3
    3
      src/java/org/apache/fop/fonts/FontTriplet.java
  18. 2
    2
      src/java/org/apache/fop/fonts/LazyFont.java
  19. 1
    1
      src/java/org/apache/fop/fonts/MultiByteFont.java
  20. 2
    2
      src/java/org/apache/fop/fonts/MutableFont.java
  21. 10
    10
      src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java
  22. 15
    18
      src/java/org/apache/fop/fonts/SingleByteFont.java
  23. 3
    2
      src/java/org/apache/fop/fonts/Typeface.java
  24. 41
    0
      src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java
  25. 11
    9
      src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
  26. 3
    4
      src/java/org/apache/fop/fonts/autodetect/FontFinder.java
  27. 34
    42
      src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
  28. 3
    3
      src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java
  29. 3
    3
      src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java
  30. 18
    20
      src/java/org/apache/fop/fonts/truetype/TTFFile.java
  31. 9
    9
      src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
  32. 1
    1
      src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
  33. 86
    154
      src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
  34. 54
    24
      src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
  35. 4
    5
      src/java/org/apache/fop/pdf/PDFResources.java
  36. 5
    4
      src/java/org/apache/fop/render/PrintRenderer.java
  37. 6
    5
      src/java/org/apache/fop/render/PrintRendererConfigurator.java
  38. 22
    10
      src/java/org/apache/fop/render/afp/AFPPainter.java
  39. 1
    1
      src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
  40. 1
    1
      src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
  41. 4
    5
      src/java/org/apache/fop/render/ps/FontResourceCache.java
  42. 13
    18
      src/java/org/apache/fop/render/ps/PSFontUtils.java
  43. 4
    3
      src/java/org/apache/fop/tools/fontlist/FontSpec.java
  44. 3
    0
      status.xml
  45. 0
    6
      test/layoutengine/disabled-testcases.xml
  46. 31
    9
      test/layoutengine/hyphenation-testcases/block_hyphenation_linefeed_preserve.xml

+ 8
- 6
src/java/org/apache/fop/fonts/AbstractCodePointMapping.java View File

@@ -20,24 +20,25 @@
package org.apache.fop.fonts;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.util.CharUtilities;
import org.apache.xmlgraphics.fonts.Glyphs;

/**
* Abstract base class for code point mapping classes (1-byte character encodings).
*/
public class AbstractCodePointMapping implements SingleByteEncoding {

private String name;
private final String name;
private char[] latin1Map;
private char[] characters;
private char[] codepoints;
private char[] unicodeMap; //code point to Unicode char
private String[] charNameMap; //all character names in the encoding
private Map fallbackMap; //Here we accumulate all mappings we have found through substitution
//Here we accumulate all mappings we have found through substitution
private Map<Character, Character> fallbackMap;

/**
* Main constructor.
@@ -144,7 +145,7 @@ public class AbstractCodePointMapping implements SingleByteEncoding {
//Fallback: using cache
synchronized (this) {
if (fallbackMap != null) {
Character fallback = (Character)fallbackMap.get(new Character(c));
Character fallback = fallbackMap.get(new Character(c));
if (fallback != null) {
return fallback.charValue();
}
@@ -172,7 +173,7 @@ public class AbstractCodePointMapping implements SingleByteEncoding {
private void putFallbackCharacter(char c, char mapTo) {
synchronized (this) {
if (this.fallbackMap == null) {
this.fallbackMap = new java.util.HashMap();
this.fallbackMap = new HashMap<Character, Character>();
}
this.fallbackMap.put(new Character(c), new Character(mapTo));
}
@@ -239,6 +240,7 @@ public class AbstractCodePointMapping implements SingleByteEncoding {
}

/** {@inheritDoc} */
@Override
public String toString() {
return getName();
}

+ 9
- 11
src/java/org/apache/fop/fonts/CIDSubset.java View File

@@ -21,7 +21,7 @@ package org.apache.fop.fonts;

import java.util.BitSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
import java.util.Map;

import org.apache.fop.util.CharUtilities;
@@ -42,18 +42,18 @@ public class CIDSubset {
/**
* usedGlyphs contains orginal, new glyph index (glyph index -> char selector)
*/
private Map/*<Integer, Integer>*/ usedGlyphs = new java.util.HashMap();
private Map<Integer, Integer> usedGlyphs = new HashMap<Integer, Integer>();

/**
* usedGlyphsIndex contains new glyph, original index (char selector -> glyph index)
*/
private Map/*<Integer, Integer>*/ usedGlyphsIndex = new java.util.HashMap();
private Map<Integer, Integer> usedGlyphsIndex = new HashMap<Integer, Integer>();
private int usedGlyphsCount = 0;

/**
* usedCharsIndex contains new glyph, original char (char selector -> Unicode)
*/
private Map/*<Integer, Character>*/ usedCharsIndex = new java.util.HashMap();
private Map<Integer, Character> usedCharsIndex = new HashMap<Integer, Character>();

/**
* Default constructor.
@@ -84,7 +84,7 @@ public class CIDSubset {
* @return the original index (or -1 if no glyph index is available for the subset index)
*/
public int getGlyphIndexForSubsetIndex(int subsetIndex) {
Integer glyphIndex = (Integer)usedGlyphsIndex.get(new Integer(subsetIndex));
Integer glyphIndex = usedGlyphsIndex.get(new Integer(subsetIndex));
if (glyphIndex != null) {
return glyphIndex.intValue();
} else {
@@ -99,7 +99,7 @@ public class CIDSubset {
* @return the Unicode value or "NOT A CHARACTER" (0xFFFF)
*/
public char getUnicodeForSubsetIndex(int subsetIndex) {
Character mapValue = (Character)usedCharsIndex.get(new Integer(subsetIndex));
Character mapValue = usedCharsIndex.get(new Integer(subsetIndex));
if (mapValue != null) {
return mapValue.charValue();
} else {
@@ -118,7 +118,7 @@ public class CIDSubset {
public int mapSubsetChar(int glyphIndex, char unicode) {
// Reencode to a new subset font or get the reencoded value
// IOW, accumulate the accessed characters and build a character map for them
Integer subsetCharSelector = (Integer)usedGlyphs.get(new Integer(glyphIndex));
Integer subsetCharSelector = usedGlyphs.get(new Integer(glyphIndex));
if (subsetCharSelector == null) {
int selector = usedGlyphsCount;
usedGlyphs.put(new Integer(glyphIndex),
@@ -139,7 +139,7 @@ public class CIDSubset {
* character selector (i.e. the subset index in this case).
* @return Map Map&lt;Integer, Integer&gt; of the font subset
*/
public Map/*<Integer, Integer>*/ getSubsetGlyphs() {
public Map<Integer, Integer> getSubsetGlyphs() {
return Collections.unmodifiableMap(this.usedGlyphs);
}

@@ -169,9 +169,7 @@ public class CIDSubset {
*/
public BitSet getGlyphIndexBitSet() {
BitSet bitset = new BitSet();
Iterator iter = usedGlyphsIndex.keySet().iterator();
while (iter.hasNext()) {
Integer cid = (Integer)iter.next();
for (Integer cid : usedGlyphs.keySet()) {
bitset.set(cid.intValue());
}
return bitset;

+ 13
- 11
src/java/org/apache/fop/fonts/CustomFont.java View File

@@ -21,6 +21,8 @@ package org.apache.fop.fonts;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@@ -35,7 +37,7 @@ public abstract class CustomFont extends Typeface

private String fontName = null;
private String fullName = null;
private Set familyNames = null; //Set<String>
private Set<String> familyNames = null;
private String fontSubName = null;
private String embedFileName = null;
private String embedResourceName = null;
@@ -55,7 +57,7 @@ public abstract class CustomFont extends Typeface
private int firstChar = 0;
private int lastChar = 255;

private Map kerning;
private Map<Integer, Map<Integer, Integer>> kerning;

private boolean useKerning = true;

@@ -81,7 +83,7 @@ public abstract class CustomFont extends Typeface
* Returns the font family names.
* @return the font family names (a Set of Strings)
*/
public Set getFamilyNames() {
public Set<String> getFamilyNames() {
return Collections.unmodifiableSet(this.familyNames);
}

@@ -278,11 +280,11 @@ public abstract class CustomFont extends Typeface
/**
* {@inheritDoc}
*/
public final Map getKerningInfo() {
public final Map<Integer, Map<Integer, Integer>> getKerningInfo() {
if (hasKerningInfo()) {
return kerning;
} else {
return java.util.Collections.EMPTY_MAP;
return Collections.emptyMap();
}
}

@@ -299,8 +301,8 @@ public abstract class CustomFont extends Typeface
}

/** {@inheritDoc} */
public void setFamilyNames(Set names) {
this.familyNames = new java.util.HashSet(names);
public void setFamilyNames(Set<String> names) {
this.familyNames = new HashSet<String>(names);
}

/**
@@ -437,9 +439,9 @@ public abstract class CustomFont extends Typeface
}

/** {@inheritDoc} */
public void putKerningEntry(Integer key, Map value) {
public void putKerningEntry(Integer key, Map<Integer, Integer> value) {
if (kerning == null) {
kerning = new java.util.HashMap();
kerning = new HashMap<Integer, Map<Integer, Integer>>();
}
this.kerning.put(key, value);
}
@@ -449,9 +451,9 @@ public abstract class CustomFont extends Typeface
* @param kerningMap the kerning map (Map<Integer, Map<Integer, Integer>, the integers are
* character codes)
*/
public void replaceKerningMap(Map kerningMap) {
public void replaceKerningMap(Map<Integer, Map<Integer, Integer>> kerningMap) {
if (kerningMap == null) {
this.kerning = Collections.EMPTY_MAP;
this.kerning = Collections.emptyMap();
} else {
this.kerning = kerningMap;
}

+ 4
- 4
src/java/org/apache/fop/fonts/CustomFontCollection.java View File

@@ -27,7 +27,7 @@ import java.util.List;
public class CustomFontCollection implements FontCollection {

private FontResolver fontResolver;
private List/*<EmbedFontInfo>*/ embedFontInfoList;
private final List<EmbedFontInfo> embedFontInfoList;

/**
* Main constructor.
@@ -35,7 +35,7 @@ public class CustomFontCollection implements FontCollection {
* @param customFonts the list of custom fonts
*/
public CustomFontCollection(FontResolver fontResolver,
List/*<EmbedFontInfo>*/ customFonts) {
List<EmbedFontInfo> customFonts) {
this.fontResolver = fontResolver;
if (this.fontResolver == null) {
//Ensure that we have minimal font resolution capabilities
@@ -54,7 +54,7 @@ public class CustomFontCollection implements FontCollection {
//FontReader reader = null;

for (int i = 0; i < embedFontInfoList.size(); i++) {
EmbedFontInfo embedFontInfo = (EmbedFontInfo)embedFontInfoList.get(i);
EmbedFontInfo embedFontInfo = embedFontInfoList.get(i);

//String metricsFile = configFontInfo.getMetricsFile();
internalName = "F" + num;
@@ -69,7 +69,7 @@ public class CustomFontCollection implements FontCollection {
LazyFont font = new LazyFont(embedFontInfo, this.fontResolver);
fontInfo.addMetrics(internalName, font);

List triplets = embedFontInfo.getFontTriplets();
List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) {
FontTriplet triplet = (FontTriplet) triplets.get(tripletIndex);
fontInfo.addFontProperties(internalName, triplet);

+ 3
- 3
src/java/org/apache/fop/fonts/EmbedFontInfo.java View File

@@ -46,7 +46,7 @@ public class EmbedFontInfo implements Serializable {
protected String subFontName = null;

/** the list of associated font triplets */
private List/*<FontTriplet>*/ fontTriplets = null;
private List<FontTriplet> fontTriplets = null;

private transient boolean embedded = true;

@@ -59,7 +59,7 @@ public class EmbedFontInfo implements Serializable {
* @param subFontName the sub-fontname used for TrueType Collections (null otherwise)
*/
public EmbedFontInfo(String metricsFile, boolean kerning,
List/*<FontTriplet>*/ fontTriplets, String embedFile, String subFontName) {
List<FontTriplet> fontTriplets, String embedFile, String subFontName) {
this.metricsFile = metricsFile;
this.embedFile = embedFile;
this.kerning = kerning;
@@ -120,7 +120,7 @@ public class EmbedFontInfo implements Serializable {
* Returns the list of font triplets associated with this font.
* @return List of font triplets
*/
public List/*<FontTriplet>*/ getFontTriplets() {
public List<FontTriplet> getFontTriplets() {
return fontTriplets;
}


+ 6
- 5
src/java/org/apache/fop/fonts/Font.java View File

@@ -19,11 +19,11 @@

package org.apache.fop.fonts;

import java.util.Collections;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.CodePointMapping;

/**
* This class holds font state information and provides access to the font
@@ -160,11 +160,11 @@ public class Font {
* Returns the font's kerning table
* @return the kerning table
*/
public Map getKerning() {
public Map<Integer, Map<Integer, Integer>> getKerning() {
if (metric.hasKerningInfo()) {
return metric.getKerningInfo();
} else {
return java.util.Collections.EMPTY_MAP;
return Collections.emptyMap();
}
}

@@ -178,9 +178,9 @@ public class Font {
* @return the distance to adjust for kerning, 0 if there's no kerning
*/
public int getKernValue(char ch1, char ch2) {
Map kernPair = (Map)getKerning().get(new Integer(ch1));
Map<Integer, Integer> kernPair = getKerning().get(new Integer(ch1));
if (kernPair != null) {
Integer width = (Integer)kernPair.get(new Integer(ch2));
Integer width = kernPair.get(new Integer(ch2));
if (width != null) {
return width.intValue() * getFontSize() / 1000;
}
@@ -239,6 +239,7 @@ public class Font {
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');

+ 6
- 8
src/java/org/apache/fop/fonts/FontAdder.java View File

@@ -20,7 +20,6 @@
package org.apache.fop.fonts;

import java.net.URL;
import java.util.Iterator;
import java.util.List;

import org.apache.fop.fonts.autodetect.FontInfoFinder;
@@ -29,9 +28,9 @@ import org.apache.fop.fonts.autodetect.FontInfoFinder;
* Adds a list of fonts to a given font info list
*/
public class FontAdder {
private FontEventListener listener;
private FontResolver resolver;
private FontManager manager;
private final FontEventListener listener;
private final FontResolver resolver;
private final FontManager manager;

/**
* Main constructor
@@ -50,14 +49,13 @@ public class FontAdder {
* @param fontURLList font file list
* @param fontInfoList a configured font info list
*/
public void add(List/*<URL>*/ fontURLList, List/*<EmbedFontInfo>*/ fontInfoList) {
public void add(List<URL> fontURLList, List<EmbedFontInfo> fontInfoList) {
FontCache cache = manager.getFontCache();
FontInfoFinder finder = new FontInfoFinder();
finder.setEventListener(listener);

for (Iterator iter = fontURLList.iterator(); iter.hasNext();) {
URL fontUrl = (URL)iter.next();
EmbedFontInfo[] embedFontInfos = finder.find(fontUrl, resolver, cache);
for (URL fontURL : fontURLList) {
EmbedFontInfo[] embedFontInfos = finder.find(fontURL, resolver, cache);
if (embedFontInfos == null) {
continue;
}

+ 15
- 16
src/java/org/apache/fop/fonts/FontCache.java View File

@@ -31,6 +31,7 @@ import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
@@ -71,13 +72,13 @@ public final class FontCache implements Serializable {
* master mapping of font url -> font info. This needs to be a list, since a
* TTC file may contain more than 1 font.
*/
private Map/* <String, CachedFontFile> */fontfileMap = null;
private Map<String, CachedFontFile> fontfileMap = null;

/**
* mapping of font url -> file modified date (for all fonts that have failed
* to load)
*/
private Map failedFontMap/* <String, Long>*/ = null;
private Map<String, Long> failedFontMap = null;

/**
* Default constructor
@@ -304,9 +305,9 @@ public final class FontCache implements Serializable {
return null;
}

private Map/* <String, CachedFontFile> */getFontFileMap() {
private Map<String, CachedFontFile> getFontFileMap() {
if (fontfileMap == null) {
fontfileMap = new java.util.HashMap/* <String, CachedFontFile> */();
fontfileMap = new HashMap<String, CachedFontFile>();
}
return fontfileMap;
}
@@ -322,8 +323,7 @@ public final class FontCache implements Serializable {
synchronized (changeLock) {
CachedFontFile cachedFontFile;
if (containsFont(cacheKey)) {
cachedFontFile = (CachedFontFile) getFontFileMap()
.get(cacheKey);
cachedFontFile = getFontFileMap().get(cacheKey);
if (!cachedFontFile.containsFont(fontInfo)) {
cachedFontFile.put(fontInfo);
}
@@ -352,8 +352,7 @@ public final class FontCache implements Serializable {
* @return CachedFontFile object
*/
public CachedFontFile getFontFile(String embedUrl) {
return containsFont(embedUrl) ? (CachedFontFile) getFontFileMap().get(
embedUrl) : null;
return containsFont(embedUrl) ? getFontFileMap().get(embedUrl) : null;
}

/**
@@ -408,8 +407,8 @@ public final class FontCache implements Serializable {
public boolean isFailedFont(String embedUrl, long lastModified) {
synchronized (changeLock) {
if (getFailedFontMap().containsKey(embedUrl)) {
long failedLastModified = ((Long) getFailedFontMap().get(
embedUrl)).longValue();
long failedLastModified = getFailedFontMap().get(
embedUrl).longValue();
if (lastModified != failedLastModified) {
// this font has been changed so lets remove it
// from failed font map for now
@@ -440,9 +439,9 @@ public final class FontCache implements Serializable {
}
}

private Map/* <String, Long> */getFailedFontMap() {
private Map<String, Long> getFailedFontMap() {
if (failedFontMap == null) {
failedFontMap = new java.util.HashMap/* <String, Long> */();
failedFontMap = new HashMap<String, Long>();
}
return failedFontMap;
}
@@ -491,15 +490,15 @@ public final class FontCache implements Serializable {
/** file modify date (if available) */
private long lastModified = -1;

private Map/* <String, EmbedFontInfo> */filefontsMap = null;
private Map<String, EmbedFontInfo> filefontsMap = null;

public CachedFontFile(long lastModified) {
setLastModified(lastModified);
}

private Map/* <String, EmbedFontInfo> */getFileFontsMap() {
private Map<String, EmbedFontInfo> getFileFontsMap() {
if (filefontsMap == null) {
filefontsMap = new java.util.HashMap/* <String, EmbedFontInfo> */();
filefontsMap = new HashMap<String, EmbedFontInfo>();
}
return filefontsMap;
}
@@ -514,7 +513,7 @@ public final class FontCache implements Serializable {
}

public EmbedFontInfo[] getEmbedFontInfos() {
return (EmbedFontInfo[]) getFileFontsMap().values().toArray(
return getFileFontsMap().values().toArray(
new EmbedFontInfo[getFileFontsMap().size()]);
}


+ 6
- 7
src/java/org/apache/fop/fonts/FontDetector.java View File

@@ -42,9 +42,9 @@ public class FontDetector {
"application/x-font", "application/x-font-truetype"
};

private FontManager fontManager;
private FontAdder fontAdder;
private boolean strict;
private final FontManager fontManager;
private final FontAdder fontAdder;
private final boolean strict;

/**
* Main constructor
@@ -63,7 +63,7 @@ public class FontDetector {
* @param fontInfoList a list of fontinfo to populate
* @throws FOPException thrown if a problem occurred during detection
*/
public void detect(List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
public void detect(List<EmbedFontInfo> fontInfoList) throws FOPException {
// search in font base if it is defined and
// is a directory but don't recurse
FontFileFinder fontFileFinder = new FontFileFinder();
@@ -72,8 +72,7 @@ public class FontDetector {
try {
File fontBase = FileUtils.toFile(new URL(fontBaseURL));
if (fontBase != null) {
List/*<URL>*/ fontURLList = fontFileFinder.find(
fontBase.getAbsolutePath());
List<URL> fontURLList = fontFileFinder.find(fontBase.getAbsolutePath());
fontAdder.add(fontURLList, fontInfoList);

//Can only use the font base URL if it's a file URL
@@ -84,7 +83,7 @@ public class FontDetector {
}

// native o/s font directory finding
List/*<URL>*/ systemFontList;
List<URL> systemFontList;
try {
systemFontList = fontFileFinder.find();
fontAdder.add(systemFontList, fontInfoList);

+ 52
- 55
src/java/org/apache/fop/fonts/FontInfo.java View File

@@ -19,12 +19,15 @@

package org.apache.fop.fonts;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -44,26 +47,26 @@ public class FontInfo {
protected static final Log log = LogFactory.getLog(FontInfo.class);

/** Map containing fonts that have been used */
private Map/*<String,FontMetrics>*/ usedFonts = null; //(String = font key)
private Map<String, Typeface> usedFonts = null; //(String = font key)

/** look up a font-triplet to find a font-name */
private Map/*<FontTriplet,String>*/ triplets = null; //(String = font key)
private Map<FontTriplet, String> triplets = null; //(String = font key)

/** look up a font-triplet to find its priority
* (only used inside addFontProperties()) */
private Map/*<FontTriplet,Integer>*/ tripletPriorities = null; //Map<FontTriplet,Integer>
private Map<FontTriplet, Integer> tripletPriorities = null; //Map<FontTriplet,Integer>

/** look up a font-name to get a font (that implements FontMetrics at least) */
private Map/*<String,FontMetrics>*/ fonts = null; //(String = font key)
private Map<String, Typeface> fonts = null; //(String = font key)

/**
* a collection of missing fonts; used to make sure the user gets
* a warning for a missing font only once (not every time the font is used)
*/
private Set/*<FontTriplet>*/ loggedFontKeys = null;
private Set<FontTriplet> loggedFontKeys = null;

/** Cache for Font instances. */
private Map/*<FontTriplet, Map>*/ fontInstanceCache = null;
private Map<FontTriplet, Map<Integer, Font>> fontInstanceCache = null;

/** Event listener for font events */
private FontEventListener eventListener = null;
@@ -72,10 +75,10 @@ public class FontInfo {
* Main constructor
*/
public FontInfo() {
this.triplets = new java.util.HashMap/*<FontTriplet, String>*/();
this.tripletPriorities = new java.util.HashMap/*<FontTriplet, Integer>*/();
this.fonts = new java.util.HashMap/*<String, FontMetrics>*/();
this.usedFonts = new java.util.HashMap/*<String,FontMetrics>*/();
this.triplets = new HashMap<FontTriplet, String>();
this.tripletPriorities = new HashMap<FontTriplet, Integer>();
this.fonts = new HashMap<String, Typeface>();
this.usedFonts = new HashMap<String, Typeface>();
}

/**
@@ -135,10 +138,10 @@ public class FontInfo {
if (log.isDebugEnabled()) {
log.debug("Registering: " + triplet + " under " + internalFontKey);
}
String oldName = (String)triplets.get(triplet);
String oldName = triplets.get(triplet);
int newPriority = triplet.getPriority();
if (oldName != null) {
int oldPriority = ((Integer)tripletPriorities.get(triplet)).intValue();
int oldPriority = tripletPriorities.get(triplet).intValue();
if (oldPriority < newPriority) {
logDuplicateFont(triplet, false, oldName, oldPriority,
internalFontKey, newPriority);
@@ -168,9 +171,9 @@ public class FontInfo {
if (log.isDebugEnabled()) {
log.debug(triplet
+ (replacing ? ": Replacing " : ": Not replacing ")
+ ((FontMetrics)fonts.get(triplets.get(triplet))).getFullName()
+ fonts.get(triplets.get(triplet)).getFullName()
+ " (priority=" + oldPriority + ") by "
+ ((FontMetrics)fonts.get(newKey)).getFullName()
+ fonts.get(newKey).getFullName()
+ " (priority=" + newPriority + ")");
}
}
@@ -186,7 +189,7 @@ public class FontInfo {
if (metrics instanceof Typeface) {
((Typeface)metrics).setEventListener(this.eventListener);
}
this.fonts.put(internalFontKey, metrics);
this.fonts.put(internalFontKey, (Typeface)metrics);
}

/**
@@ -292,9 +295,9 @@ public class FontInfo {
usedFonts.put(internalName, fonts.get(internalName));
}

private Map/*<FontTriplet,Map<Integer,Font>>*/ getFontInstanceCache() {
private Map<FontTriplet, Map<Integer, Font>> getFontInstanceCache() {
if (fontInstanceCache == null) {
fontInstanceCache = new java.util.HashMap/*<FontTriplet, Map<Integer,Font>>*/();
fontInstanceCache = new HashMap<FontTriplet, Map<Integer, Font>>();
}
return fontInstanceCache;
}
@@ -307,14 +310,14 @@ public class FontInfo {
* @return the requested Font instance
*/
public Font getFontInstance(FontTriplet triplet, int fontSize) {
Map/*<Integer,Font>*/ sizes
= (Map/*<Integer,Font>*/)getFontInstanceCache().get(triplet);
Map<Integer, Font> sizes
= getFontInstanceCache().get(triplet);
if (sizes == null) {
sizes = new java.util.HashMap/*<Integer,Font>*/();
sizes = new HashMap<Integer, Font>();
getFontInstanceCache().put(triplet, sizes);
}
Integer size = new Integer(fontSize);
Font font = (Font)sizes.get(size);
Font font = sizes.get(size);
if (font == null) {
String fontKey = getInternalFontKey(triplet);
useFont(fontKey);
@@ -325,11 +328,9 @@ public class FontInfo {
return font;
}

private List/*<FontTriplet>*/ getTripletsForName(String fontName) {
List/*<FontTriplet>*/ matchedTriplets = new java.util.ArrayList/*<FontTriplet>*/();
Iterator it = triplets.keySet().iterator();
while (it.hasNext()) {
FontTriplet triplet = (FontTriplet)it.next();
private List<FontTriplet> getTripletsForName(String fontName) {
List<FontTriplet> matchedTriplets = new ArrayList<FontTriplet>();
for (FontTriplet triplet : triplets.keySet()) {
String tripletName = triplet.getName();
if (tripletName.toLowerCase().equals(fontName.toLowerCase())) {
matchedTriplets.add(triplet);
@@ -351,11 +352,9 @@ public class FontInfo {
int awtFontWeight = awtFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;

FontTriplet matchedTriplet = null;
List/*<FontTriplet>*/ triplets = getTripletsForName(awtFontName);
List<FontTriplet> triplets = getTripletsForName(awtFontName);
if (!triplets.isEmpty()) {
Iterator it = triplets.iterator();
while (it.hasNext()) {
FontTriplet triplet = (FontTriplet)it.next();
for (FontTriplet triplet : triplets) {
boolean styleMatched = triplet.getStyle().equals(awtFontStyle);
boolean weightMatched = triplet.getWeight() == awtFontWeight;
if (styleMatched && weightMatched) {
@@ -393,9 +392,9 @@ public class FontInfo {
return fontLookup(family, style, weight, true);
}

private List/*<FontTriplet>*/ fontLookup(String[] families, String style,
private List<FontTriplet> fontLookup(String[] families, String style,
int weight, boolean substitutable) {
List/*<FontTriplet>*/ matchingTriplets = new java.util.ArrayList/*<FontTriplet>*/();
List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>();
FontTriplet triplet = null;
for (int i = 0; i < families.length; i++) {
triplet = fontLookup(families[i], style, weight, substitutable);
@@ -426,7 +425,7 @@ public class FontInfo {
}

// try matching without substitutions
List/*<FontTriplet>*/ matchedTriplets = fontLookup(families, style, weight, false);
List<FontTriplet> matchedTriplets = fontLookup(families, style, weight, false);

// if there are no matching font triplets found try with substitutions
if (matchedTriplets.size() == 0) {
@@ -454,9 +453,9 @@ public class FontInfo {
return fontTriplets;
}

private Set/*<FontTriplet>*/ getLoggedFontKeys() {
private Set<FontTriplet> getLoggedFontKeys() {
if (loggedFontKeys == null) {
loggedFontKeys = new java.util.HashSet/*<FontTriplet>*/();
loggedFontKeys = new HashSet<FontTriplet>();
}
return loggedFontKeys;
}
@@ -544,7 +543,7 @@ public class FontInfo {
* @return the associated internal key or null, if not found
*/
public String getInternalFontKey(FontTriplet triplet) {
return (String)triplets.get(triplet);
return triplets.get(triplet);
}

/**
@@ -563,15 +562,15 @@ public class FontInfo {
* Gets a Map of all registered fonts.
* @return a read-only Map with font key/FontMetrics pairs
*/
public Map/*<String,FontMetrics>*/ getFonts() {
return java.util.Collections.unmodifiableMap(this.fonts);
public Map<String, Typeface> getFonts() {
return Collections.unmodifiableMap(this.fonts);
}

/**
* Gets a Map of all registered font triplets.
* @return a Map with FontTriplet/font key pairs
*/
public Map/*<FontTriplet,String>*/ getFontTriplets() {
public Map<FontTriplet, String> getFontTriplets() {
return this.triplets;
}

@@ -581,7 +580,7 @@ public class FontInfo {
* This is for embedded font or creating a list of used fonts.
* @return a read-only Map with font key/FontMetrics pairs
*/
public Map/*<String,FontMetrics>*/ getUsedFonts() {
public Map<String, Typeface> getUsedFonts() {
return this.usedFonts;
}

@@ -591,7 +590,7 @@ public class FontInfo {
* @return font metrics
*/
public FontMetrics getMetricsFor(String fontName) {
FontMetrics metrics = (FontMetrics)fonts.get(fontName);
Typeface metrics = fonts.get(fontName);
usedFonts.put(fontName, metrics);
return metrics;
}
@@ -601,10 +600,9 @@ public class FontInfo {
* @param fontName The font name we are looking for
* @return A list of matching font triplets
*/
public List/*<FontTriplet>*/ getTripletsFor(String fontName) {
List/*<FontTriplet>*/ foundTriplets = new java.util.ArrayList();
for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) {
Map.Entry tripletEntry = (Map.Entry) iter.next();
public List<FontTriplet> getTripletsFor(String fontName) {
List<FontTriplet> foundTriplets = new ArrayList<FontTriplet> ();
for (Map.Entry<FontTriplet, String> tripletEntry : triplets.entrySet()) {
if (fontName.equals((tripletEntry.getValue()))) {
foundTriplets.add(tripletEntry.getKey());
}
@@ -620,10 +618,10 @@ public class FontInfo {
* @return The first triplet for the given font name
*/
public FontTriplet getTripletFor(String fontName) {
List/*<FontTriplet>*/ foundTriplets = getTripletsFor(fontName);
List<FontTriplet> foundTriplets = getTripletsFor(fontName);
if (foundTriplets.size() > 0) {
Collections.sort(foundTriplets);
return (FontTriplet)foundTriplets.get(0);
return foundTriplets.get(0);
}
return null;
}
@@ -672,18 +670,17 @@ public class FontInfo {
/**
* {@inheritDoc}
*/
@Override
public String toString() {
Collection entries = new java.util.TreeSet();
Iterator iter = this.triplets.keySet().iterator();
while (iter.hasNext()) {
FontTriplet triplet = (FontTriplet)iter.next();
SortedSet<String> entries = new TreeSet<String>();
for (FontTriplet triplet : this.triplets.keySet()) {
String key = getInternalFontKey(triplet);
FontMetrics metrics = getMetricsFor(key);
entries.add(triplet.toString() + " -> " + key + " -> " + metrics.getFontName() + "\n");
}
StringBuffer stringBuffer = new StringBuffer();
for (iter = entries.iterator(); iter.hasNext();) {
stringBuffer.append(iter.next());
for (String str : entries) {
stringBuffer.append(str);
}
return stringBuffer.toString();
}

+ 18
- 21
src/java/org/apache/fop/fonts/FontInfoConfigurator.java View File

@@ -33,7 +33,6 @@ import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.autodetect.FontFileFinder;
import org.apache.fop.fonts.autodetect.FontInfoFinder;
@@ -46,11 +45,11 @@ public class FontInfoConfigurator {
/** logger instance */
protected static final Log log = LogFactory.getLog(FontInfoConfigurator.class);

private Configuration cfg;
private FontManager fontManager;
private FontResolver fontResolver;
private FontEventListener listener;
private boolean strict;
private final Configuration cfg;
private final FontManager fontManager;
private final FontResolver fontResolver;
private final FontEventListener listener;
private final boolean strict;

/**
* Main constructor
@@ -74,7 +73,8 @@ public class FontInfoConfigurator {
* @param fontInfoList a font info list
* @throws FOPException if an exception occurs while processing the configuration
*/
public void configure(List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
public void configure(List<EmbedFontInfo> fontInfoList)
throws FOPException {
Configuration fontsCfg = cfg.getChild("fonts", false);
if (fontsCfg != null) {
long start = 0;
@@ -120,7 +120,7 @@ public class FontInfoConfigurator {
}

private void addDirectories(Configuration fontsCfg,
FontAdder fontAdder, List/*<URL>*/ fontInfoList) throws FOPException {
FontAdder fontAdder, List<EmbedFontInfo> fontInfoList) throws FOPException {
// directory (multiple font) configuration
Configuration[] directories = fontsCfg.getChildren("directory");
for (int i = 0; i < directories.length; i++) {
@@ -140,7 +140,7 @@ public class FontInfoConfigurator {

// add fonts found in directory
FontFileFinder fontFileFinder = new FontFileFinder(recursive ? -1 : 1);
List/*<URL>*/ fontURLList;
List<URL> fontURLList;
try {
fontURLList = fontFileFinder.find(directory);
fontAdder.add(fontURLList, fontInfoList);
@@ -158,7 +158,7 @@ public class FontInfoConfigurator {
* @throws FOPException if an exception occurs while processing the configuration
*/
protected void addFonts(Configuration fontsCfg, FontCache fontCache,
List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
List<EmbedFontInfo> fontInfoList) throws FOPException {
// font file (singular) configuration
Configuration[] font = fontsCfg.getChildren("font");
for (int i = 0; i < font.length; i++) {
@@ -186,9 +186,8 @@ public class FontInfoConfigurator {
* @return the embedded font info
* @throws FOPException if something's wrong with the config data
*/
protected EmbedFontInfo getFontInfo(
Configuration fontCfg, FontCache fontCache)
throws FOPException {
protected EmbedFontInfo getFontInfo(Configuration fontCfg, FontCache fontCache)
throws FOPException {
String metricsUrl = fontCfg.getAttribute("metrics-url", null);
String embedUrl = fontCfg.getAttribute("embed-url", null);
String subFont = fontCfg.getAttribute("sub-font", null);
@@ -229,25 +228,23 @@ public class FontInfoConfigurator {
LogUtil.handleError(log, "font without font-triplet", strict);

File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl});
URL fontUrl;
URL fontURL = null;
try {
fontUrl = fontFile.toURI().toURL();
fontURL = fontFile.toURI().toURL();
} catch (MalformedURLException e) {
// Should never happen
log.debug("Malformed Url: " + e.getMessage());
return null;
LogUtil.handleException(log, e, strict);
}
if (fontFile != null) {
FontInfoFinder finder = new FontInfoFinder();
finder.setEventListener(listener);
EmbedFontInfo[] infos = finder.find(fontUrl, fontResolver, fontCache);
EmbedFontInfo[] infos = finder.find(fontURL, fontResolver, fontCache);
return infos[0]; //When subFont is set, only one font is returned
} else {
return null;
}
}

List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/();
List<FontTriplet> tripletList = new java.util.ArrayList<FontTriplet>();
for (int j = 0; j < tripletCfg.length; j++) {
FontTriplet fontTriplet = getFontTriplet(tripletCfg[j]);
tripletList.add(fontTriplet);
@@ -270,7 +267,7 @@ public class FontInfoConfigurator {
log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "")
+ "metric file " + embedFontInfo.getMetricsFile());
for (int j = 0; j < tripletList.size(); ++j) {
FontTriplet triplet = (FontTriplet) tripletList.get(j);
FontTriplet triplet = tripletList.get(j);
log.debug(" Font triplet "
+ triplet.getName() + ", "
+ triplet.getStyle() + ", "

+ 4
- 9
src/java/org/apache/fop/fonts/FontManager.java View File

@@ -21,7 +21,6 @@ package org.apache.fop.fonts;

import java.io.File;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.List;

import javax.xml.transform.Source;
@@ -260,7 +259,7 @@ public class FontManager {
* ({@link #getReferencedFontsMatcher()}).
* @param fontInfoList a font info list
*/
public void updateReferencedFonts(List fontInfoList) {
public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList) {
Matcher matcher = getReferencedFontsMatcher();
updateReferencedFonts(fontInfoList, matcher);
}
@@ -270,16 +269,12 @@ public class FontManager {
* @param fontInfoList a font info list
* @param matcher the font triplet matcher to use
*/
public void updateReferencedFonts(List fontInfoList, Matcher matcher) {
public void updateReferencedFonts(List<EmbedFontInfo> fontInfoList, Matcher matcher) {
if (matcher == null) {
return; //No referenced fonts
}
Iterator iter = fontInfoList.iterator();
while (iter.hasNext()) {
EmbedFontInfo fontInfo = (EmbedFontInfo)iter.next();
Iterator triplets = fontInfo.getFontTriplets().iterator();
while (triplets.hasNext()) {
FontTriplet triplet = (FontTriplet)triplets.next();
for (EmbedFontInfo fontInfo : fontInfoList) {
for (FontTriplet triplet : fontInfo.getFontTriplets()) {
if (matcher.matches(triplet)) {
fontInfo.setEmbedded(false);
break;

+ 5
- 7
src/java/org/apache/fop/fonts/FontManagerConfigurator.java View File

@@ -28,7 +28,6 @@ import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.substitute.FontSubstitutions;
import org.apache.fop.fonts.substitute.FontSubstitutionsConfigurator;
@@ -42,7 +41,7 @@ public class FontManagerConfigurator {
/** logger instance */
private static Log log = LogFactory.getLog(FontManagerConfigurator.class);

private Configuration cfg;
private final Configuration cfg;

/**
* Main constructor
@@ -114,7 +113,7 @@ public class FontManagerConfigurator {
*/
public static FontTriplet.Matcher createFontsMatcher(
Configuration cfg, boolean strict) throws FOPException {
List matcherList = new java.util.ArrayList();
List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
Configuration[] matches = cfg.getChildren("match");
for (int i = 0; i < matches.length; i++) {
try {
@@ -126,14 +125,13 @@ public class FontManagerConfigurator {
}
}
FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
(FontTriplet.Matcher[])matcherList.toArray(
new FontTriplet.Matcher[matcherList.size()]));
matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
return orMatcher;
}

private static class OrFontTripletMatcher implements FontTriplet.Matcher {

private FontTriplet.Matcher[] matchers;
private final FontTriplet.Matcher[] matchers;

public OrFontTripletMatcher(FontTriplet.Matcher[] matchers) {
this.matchers = matchers;
@@ -153,7 +151,7 @@ public class FontManagerConfigurator {

private static class FontFamilyRegExFontTripletMatcher implements FontTriplet.Matcher {

private Pattern regex;
private final Pattern regex;

public FontFamilyRegExFontTripletMatcher(String regex) {
this.regex = Pattern.compile(regex);

+ 2
- 2
src/java/org/apache/fop/fonts/FontMetrics.java View File

@@ -45,7 +45,7 @@ public interface FontMetrics {
* Returns the font's family names as a Set of Strings (Example: "Helvetica").
* @return the font's family names (a Set of Strings)
*/
Set getFamilyNames();
Set<String> getFamilyNames();

/**
* Returns the font name for font embedding (may include a prefix, Example: "1E28bcArialMT").
@@ -129,6 +129,6 @@ public interface FontMetrics {
* Returns the kerning map for the font.
* @return the kerning map
*/
Map getKerningInfo();
Map<Integer, Map<Integer, Integer>> getKerningInfo();

}

+ 12
- 10
src/java/org/apache/fop/fonts/FontReader.java View File

@@ -21,6 +21,9 @@ package org.apache.fop.fonts;

//Java
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -56,12 +59,12 @@ public class FontReader extends DefaultHandler {
private SingleByteFont singleFont = null;
private StringBuffer text = new StringBuffer();

private List cidWidths = null;
private List<Integer> cidWidths = null;
private int cidWidthIndex = 0;

private Map currentKerning = null;
private Map<Integer, Integer> currentKerning = null;

private List bfranges = null;
private List<BFEntry> bfranges = null;

private void createFont(InputSource source) throws FOPException {
XMLReader parser = null;
@@ -184,13 +187,13 @@ public class FontReader extends DefaultHandler {
returnFont.setEmbedResourceName(attributes.getValue("class"));
} else if ("cid-widths".equals(localName)) {
cidWidthIndex = getInt(attributes.getValue("start-index"));
cidWidths = new java.util.ArrayList();
cidWidths = new ArrayList<Integer>();
} else if ("kerning".equals(localName)) {
currentKerning = new java.util.HashMap();
currentKerning = new HashMap<Integer, Integer>();
returnFont.putKerningEntry(new Integer(attributes.getValue("kpx1")),
currentKerning);
} else if ("bfranges".equals(localName)) {
bfranges = new java.util.ArrayList();
bfranges = new ArrayList<BFEntry>();
} else if ("bf".equals(localName)) {
BFEntry entry = new BFEntry(getInt(attributes.getValue("us")),
getInt(attributes.getValue("ue")),
@@ -235,7 +238,7 @@ public class FontReader extends DefaultHandler {
} else if ("full-name".equals(localName)) {
returnFont.setFullName(content);
} else if ("family-name".equals(localName)) {
Set s = new java.util.HashSet();
Set<String> s = new HashSet<String>();
s.add(content);
returnFont.setFamilyNames(s);
} else if ("ttc-name".equals(localName) && isCID) {
@@ -288,15 +291,14 @@ public class FontReader extends DefaultHandler {
int[] wds = new int[cidWidths.size()];
int j = 0;
for (int count = 0; count < cidWidths.size(); count++) {
Integer i = (Integer)cidWidths.get(count);
wds[j++] = i.intValue();
wds[j++] = cidWidths.get(count).intValue();
}

//multiFont.addCIDWidthEntry(cidWidthIndex, wds);
multiFont.setWidthArray(wds);

} else if ("bfranges".equals(localName)) {
multiFont.setCMap((BFEntry[])bfranges.toArray(new BFEntry[0]));
multiFont.setBFEntries(bfranges.toArray(new BFEntry[0]));
}
text.setLength(0); //Reset text buffer (see characters())
}

+ 6
- 7
src/java/org/apache/fop/fonts/FontSetup.java View File

@@ -72,7 +72,8 @@ public final class FontSetup {
* @param embedFontInfoList a list of EmbedFontInfo objects
* @param resolver the font resolver
*/
public static void setup(FontInfo fontInfo, List embedFontInfoList, FontResolver resolver) {
public static void setup(FontInfo fontInfo, List<EmbedFontInfo> embedFontInfoList,
FontResolver resolver) {
final boolean base14Kerning = false;
fontInfo.addMetrics("F1", new Helvetica(base14Kerning));
fontInfo.addMetrics("F2", new HelveticaOblique(base14Kerning));
@@ -190,7 +191,7 @@ public final class FontSetup {
* @param resolver the font resolver
*/
private static void addConfiguredFonts(FontInfo fontInfo,
List/*<EmbedFontInfo>*/ embedFontInfoList, int num, FontResolver resolver) {
List<EmbedFontInfo> embedFontInfoList, int num, FontResolver resolver) {
if (embedFontInfoList == null) {
return; //No fonts to process
}
@@ -202,18 +203,16 @@ public final class FontSetup {

String internalName = null;

for (int i = 0; i < embedFontInfoList.size(); i++) {
EmbedFontInfo embedFontInfo = (EmbedFontInfo)embedFontInfoList.get(i);

for (EmbedFontInfo embedFontInfo : embedFontInfoList) {
internalName = "F" + num;
num++;

LazyFont font = new LazyFont(embedFontInfo, resolver);
fontInfo.addMetrics(internalName, font);

List triplets = embedFontInfo.getFontTriplets();
List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) {
FontTriplet triplet = (FontTriplet) triplets.get(tripletIndex);
FontTriplet triplet = triplets.get(tripletIndex);
fontInfo.addFontProperties(internalName, triplet);
}
}

+ 3
- 3
src/java/org/apache/fop/fonts/FontTriplet.java View File

@@ -25,7 +25,7 @@ import java.io.Serializable;
/**
* FontTriplet contains information on name, style and weight of one font
*/
public class FontTriplet implements Comparable, Serializable {
public class FontTriplet implements Comparable<FontTriplet>, Serializable {

/** serial version UID */
private static final long serialVersionUID = 1168991106658033508L;
@@ -99,8 +99,8 @@ public class FontTriplet implements Comparable, Serializable {
}

/** {@inheritDoc} */
public int compareTo(Object o) {
return getKey().compareTo(((FontTriplet)o).getKey());
public int compareTo(FontTriplet o) {
return getKey().compareTo(o.getKey());
}

/** {@inheritDoc} */

+ 2
- 2
src/java/org/apache/fop/fonts/LazyFont.java View File

@@ -221,7 +221,7 @@ public class LazyFont extends Typeface implements FontDescriptor {
}

/** {@inheritDoc} */
public Set getFamilyNames() {
public Set<String> getFamilyNames() {
load(true);
return realFont.getFamilyNames();
}
@@ -293,7 +293,7 @@ public class LazyFont extends Typeface implements FontDescriptor {
/**
* {@inheritDoc}
*/
public Map getKerningInfo() {
public Map<Integer, Map<Integer, Integer>> getKerningInfo() {
load(true);
return realFont.getKerningInfo();
}

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

@@ -246,7 +246,7 @@ public class MultiByteFont extends CIDFont {
* Returns a Map of used Glyphs.
* @return Map Map of used Glyphs
*/
public Map getUsedGlyphs() {
public Map<Integer, Integer> getUsedGlyphs() {
return subset.getSubsetGlyphs();
}


+ 2
- 2
src/java/org/apache/fop/fonts/MutableFont.java View File

@@ -46,7 +46,7 @@ public interface MutableFont {
* Sets the font's family names (Example: "Helvetica").
* @param names the font's family names (a Set of Strings)
*/
void setFamilyNames(Set names);
void setFamilyNames(Set<String> names);

/**
* Sets the path to the embeddable font file.
@@ -137,6 +137,6 @@ public interface MutableFont {
* @param key Kerning key
* @param value Kerning value
*/
void putKerningEntry(Integer key, Map value);
void putKerningEntry(Integer key, Map<Integer, Integer> value);

}

+ 10
- 10
src/java/org/apache/fop/fonts/SimpleSingleByteEncoding.java View File

@@ -19,13 +19,14 @@

package org.apache.fop.fonts;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.util.CharUtilities;
import org.apache.xmlgraphics.fonts.Glyphs;

/**
* A simple implementation of the OneByteEncoding mostly used for encodings that are constructed
@@ -33,11 +34,9 @@ import org.apache.fop.util.CharUtilities;
*/
public class SimpleSingleByteEncoding implements SingleByteEncoding {

private String name;
private List mapping = new java.util.ArrayList();
//List<NamedCharacter>
private Map charMap = new java.util.HashMap();
//Map<Character(Unicode), Character(code point)>
private final String name;
private final List<NamedCharacter> mapping = new ArrayList<NamedCharacter>();
private final Map<Character, Character> charMap = new HashMap<Character, Character>();

/**
* Main constructor.
@@ -54,7 +53,7 @@ public class SimpleSingleByteEncoding implements SingleByteEncoding {

/** {@inheritDoc} */
public char mapChar(char c) {
Character nc = (Character)charMap.get(new Character(c));
Character nc = charMap.get(new Character(c));
if (nc != null) {
return nc.charValue();
}
@@ -66,7 +65,7 @@ public class SimpleSingleByteEncoding implements SingleByteEncoding {
String[] map = new String[getSize()];
Arrays.fill(map, Glyphs.NOTDEF);
for (int i = getFirstChar(); i <= getLastChar(); i++) {
NamedCharacter ch = (NamedCharacter)this.mapping.get(i - 1);
NamedCharacter ch = this.mapping.get(i - 1);
map[i] = ch.getName();
}
return map;
@@ -133,7 +132,7 @@ public class SimpleSingleByteEncoding implements SingleByteEncoding {
throw new IllegalArgumentException("codePoint must be between 0 and 255");
}
if (codePoint <= getLastChar()) {
return (NamedCharacter)this.mapping.get(codePoint - 1);
return this.mapping.get(codePoint - 1);
} else {
return null;
}
@@ -152,6 +151,7 @@ public class SimpleSingleByteEncoding implements SingleByteEncoding {
}

/** {@inheritDoc} */
@Override
public String toString() {
return getName() + " (" + getSize() + " chars)";
}

+ 15
- 18
src/java/org/apache/fop/fonts/SingleByteFont.java View File

@@ -19,10 +19,12 @@

package org.apache.fop.fonts;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -42,9 +44,8 @@ public class SingleByteFont extends CustomFont {

private int[] width = null;

private Map unencodedCharacters;
//Map<Character, UnencodedCharacter>
private List additionalEncodings;
private Map<Character, UnencodedCharacter> unencodedCharacters;
private List<SimpleSingleByteEncoding> additionalEncodings;

private PostScriptVersion ttPostScriptVersion;

@@ -88,8 +89,7 @@ public class SingleByteFont extends CustomFont {
int codePoint = i % 256;
NamedCharacter nc = encoding.getCharacterForIndex(codePoint);
UnencodedCharacter uc
= (UnencodedCharacter)this.unencodedCharacters.get(
new Character(nc.getSingleUnicodeValue()));
= this.unencodedCharacters.get(new Character(nc.getSingleUnicodeValue()));
return size * uc.getWidth();
}
return 0;
@@ -122,11 +122,10 @@ public class SingleByteFont extends CustomFont {

private char mapUnencodedChar(char ch) {
if (this.unencodedCharacters != null) {
UnencodedCharacter unencoded
= (UnencodedCharacter)this.unencodedCharacters.get(new Character(ch));
UnencodedCharacter unencoded = this.unencodedCharacters.get(new Character(ch));
if (unencoded != null) {
if (this.additionalEncodings == null) {
this.additionalEncodings = new java.util.ArrayList();
this.additionalEncodings = new ArrayList<SimpleSingleByteEncoding>();
}
SimpleSingleByteEncoding encoding = null;
char mappedStart = 0;
@@ -236,7 +235,7 @@ public class SingleByteFont extends CustomFont {
*/
public void addUnencodedCharacter(NamedCharacter ch, int width) {
if (this.unencodedCharacters == null) {
this.unencodedCharacters = new java.util.HashMap();
this.unencodedCharacters = new HashMap<Character, UnencodedCharacter>();
}
if (ch.hasSingleUnicodeValue()) {
UnencodedCharacter uc = new UnencodedCharacter(ch, width);
@@ -254,10 +253,8 @@ public class SingleByteFont extends CustomFont {
*/
public void encodeAllUnencodedCharacters() {
if (this.unencodedCharacters != null) {
Set sortedKeys = new java.util.TreeSet(this.unencodedCharacters.keySet());
Iterator iter = sortedKeys.iterator();
while (iter.hasNext()) {
Character ch = (Character)iter.next();
Set<Character> sortedKeys = new TreeSet<Character>(this.unencodedCharacters.keySet());
for (Character ch : sortedKeys) {
char mapped = mapChar(ch.charValue());
assert mapped != Typeface.NOT_FOUND;
}
@@ -293,7 +290,7 @@ public class SingleByteFont extends CustomFont {
public SimpleSingleByteEncoding getAdditionalEncoding(int index)
throws IndexOutOfBoundsException {
if (hasAdditionalEncodings()) {
return (SimpleSingleByteEncoding)this.additionalEncodings.get(index);
return this.additionalEncodings.get(index);
} else {
throw new IndexOutOfBoundsException("No additional encodings available");
}
@@ -309,7 +306,7 @@ public class SingleByteFont extends CustomFont {
int[] arr = new int[enc.getLastChar() - enc.getFirstChar() + 1];
for (int i = 0, c = arr.length; i < c; i++) {
NamedCharacter nc = enc.getCharacterForIndex(enc.getFirstChar() + i);
UnencodedCharacter uc = (UnencodedCharacter)this.unencodedCharacters.get(
UnencodedCharacter uc = this.unencodedCharacters.get(
new Character(nc.getSingleUnicodeValue()));
arr[i] = uc.getWidth();
}
@@ -318,8 +315,8 @@ public class SingleByteFont extends CustomFont {

private static final class UnencodedCharacter {

private NamedCharacter character;
private int width;
private final NamedCharacter character;
private final int width;

public UnencodedCharacter(NamedCharacter character, int width) {
this.character = character;

+ 3
- 2
src/java/org/apache/fop/fonts/Typeface.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.fonts;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
@@ -49,7 +50,7 @@ public abstract class Typeface implements FontMetrics {
/** An optional event listener that receives events such as missing glyphs etc. */
protected FontEventListener eventListener;

private Set warnedChars;
private Set<Character> warnedChars;

/**
* Get the encoding of the font.
@@ -120,7 +121,7 @@ public abstract class Typeface implements FontMetrics {
// Give up, character is not available
Character ch = new Character(c);
if (warnedChars == null) {
warnedChars = new java.util.HashSet();
warnedChars = new HashSet<Character>();
}
if (warnedChars.size() < 8 && !warnedChars.contains(ch)) {
warnedChars.add(ch);

+ 41
- 0
src/java/org/apache/fop/fonts/autodetect/FontDirFinder.java View File

@@ -0,0 +1,41 @@
/*
* 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.autodetect;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
* Implementers provide find method for searching native operating system
* for available fonts.
*/
public interface FontDirFinder {

/**
* Finds a list of font files.
*
* @return list of font files.
* @throws IOException
* In case of an I/O problem
*/
List<File> find() throws IOException;

}

+ 11
- 9
src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java View File

@@ -22,8 +22,8 @@ package org.apache.fop.fonts.autodetect;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.io.DirectoryWalker;
@@ -91,6 +91,7 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
* @return whether directory should be handled
* {@inheritDoc}
*/
@Override
protected boolean handleDirectory(File directory, int depth, Collection results) {
return true;
}
@@ -101,6 +102,7 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
* @param results collection
* {@inheritDoc}
*/
@Override
protected void handleFile(File file, int depth, Collection results) {
try {
// Looks Strange, but is actually recommended over just .URL()
@@ -116,6 +118,7 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
* @param results the collection of results objects
* {@inheritDoc}
*/
@Override
protected void handleDirectoryEnd(File directory, int depth, Collection results) {
if (log.isDebugEnabled()) {
log.debug(directory + ": found " + results.size() + " font"
@@ -130,8 +133,8 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
* @throws IOException io exception
* {@inheritDoc}
*/
public List/*<URL>*/ find() throws IOException {
final FontFinder fontDirFinder;
public List<URL> find() throws IOException {
final FontDirFinder fontDirFinder;
final String osName = System.getProperty("os.name");
if (osName.startsWith("Windows")) {
fontDirFinder = new WindowsFontDirFinder();
@@ -142,10 +145,9 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
fontDirFinder = new UnixFontDirFinder();
}
}
List/*<URL>*/ fontDirs = fontDirFinder.find();
List/*<URL>*/ results = new java.util.ArrayList/*<URL>*/();
for (Iterator iter = fontDirs.iterator(); iter.hasNext();) {
final File dir = (File)iter.next();
List<File> fontDirs = fontDirFinder.find();
List<URL> results = new java.util.ArrayList<URL>();
for (File dir : fontDirs) {
super.walk(dir, results);
}
return results;
@@ -158,8 +160,8 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
* @return list of font files
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public List find(String dir) throws IOException {
List results = new java.util.ArrayList();
public List<URL> find(String dir) throws IOException {
List<URL> results = new java.util.ArrayList<URL>();
super.walk(new File(dir), results);
return results;
}

+ 3
- 4
src/java/org/apache/fop/fonts/autodetect/FontFinder.java View File

@@ -20,6 +20,7 @@
package org.apache.fop.fonts.autodetect;

import java.io.IOException;
import java.net.URL;
import java.util.List;

/**
@@ -31,12 +32,10 @@ public interface FontFinder {
/**
* Finds a list of font files.
*
* @return list of font files. List&lt;URL&gt; in the case of the
* FontFinder, and List&lt;File&gt; in the case of the
* FonrDirFinders.
* @return list of font files.
* @throws IOException
* In case of an I/O problem
*/
List/*<URL>*/ find() throws IOException;
List<URL> find() throws IOException;

}

+ 34
- 42
src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java View File

@@ -22,7 +22,6 @@ package org.apache.fop.fonts.autodetect;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
@@ -30,7 +29,6 @@ import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.EncodingMode;
@@ -52,7 +50,7 @@ import org.apache.fop.fonts.truetype.TTFFontLoader;
public class FontInfoFinder {

/** logging instance */
private Log log = LogFactory.getLog(FontInfoFinder.class);
private final Log log = LogFactory.getLog(FontInfoFinder.class);

private FontEventListener eventListener;

@@ -72,7 +70,7 @@ public class FontInfoFinder {
* @param customFont CustomFont
* @param triplets Collection that will take the generated triplets
*/
private void generateTripletsFromFont(CustomFont customFont, Collection triplets) {
private void generateTripletsFromFont(CustomFont customFont, Collection<FontTriplet> triplets) {
if (log.isTraceEnabled()) {
log.trace("Font: " + customFont.getFullName()
+ ", family: " + customFont.getFamilyNames()
@@ -99,10 +97,9 @@ public class FontInfoFinder {
if (!fullName.equals(strippedName)) {
triplets.add(new FontTriplet(strippedName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL));
}
Set familyNames = customFont.getFamilyNames();
Iterator iter = familyNames.iterator();
while (iter.hasNext()) {
String familyName = stripQuotes((String)iter.next());
Set<String> familyNames = customFont.getFamilyNames();
for (String familyName : familyNames) {
familyName = stripQuotes(familyName);
if (!fullName.equals(familyName)) {
/* Heuristic:
* The more similar the family name to the full font name,
@@ -135,17 +132,17 @@ public class FontInfoFinder {

/**
* Attempts to determine FontInfo from a given custom font
* @param fontUrl the font URL
* @param fontURL the font URL
* @param customFont the custom font
* @param fontCache font cache (may be null)
* @return FontInfo from the given custom font
*/
private EmbedFontInfo getFontInfoFromCustomFont(
URL fontUrl, CustomFont customFont, FontCache fontCache) {
List fontTripletList = new java.util.ArrayList();
URL fontURL, CustomFont customFont, FontCache fontCache) {
List<FontTriplet> fontTripletList = new java.util.ArrayList<FontTriplet>();
generateTripletsFromFont(customFont, fontTripletList);
String embedUrl;
embedUrl = fontUrl.toExternalForm();
embedUrl = fontURL.toExternalForm();
String subFontName = null;
if (customFont instanceof MultiByteFont) {
subFontName = ((MultiByteFont)customFont).getTTCName();
@@ -162,29 +159,29 @@ public class FontInfoFinder {
/**
* Attempts to determine EmbedFontInfo from a given font file.
*
* @param fontUrl font URL. Assumed to be local.
* @param fontURL font URL. Assumed to be local.
* @param resolver font resolver used to resolve font
* @param fontCache font cache (may be null)
* @return an array of newly created embed font info. Generally, this array
* will have only one entry, unless the fontUrl is a TrueType Collection
*/
public EmbedFontInfo[] find(URL fontUrl, FontResolver resolver, FontCache fontCache) {
String embedUrl = null;
embedUrl = fontUrl.toExternalForm();
public EmbedFontInfo[] find(URL fontURL, FontResolver resolver, FontCache fontCache) {
String embedURL = null;
embedURL = fontURL.toExternalForm();

long fileLastModified = -1;
if (fontCache != null) {
fileLastModified = FontCache.getLastModified(fontUrl);
fileLastModified = FontCache.getLastModified(fontURL);
// firstly try and fetch it from cache before loading/parsing the font file
if (fontCache.containsFont(embedUrl)) {
EmbedFontInfo[] fontInfos = fontCache.getFontInfos(embedUrl, fileLastModified);
if (fontCache.containsFont(embedURL)) {
EmbedFontInfo[] fontInfos = fontCache.getFontInfos(embedURL, fileLastModified);
if (fontInfos != null) {
return fontInfos;
}
// is this a previously failed parsed font?
} else if (fontCache.isFailedFont(embedUrl, fileLastModified)) {
} else if (fontCache.isFailedFont(embedURL, fileLastModified)) {
if (log.isDebugEnabled()) {
log.debug("Skipping font file that failed to load previously: " + embedUrl);
log.debug("Skipping font file that failed to load previously: " + embedURL);
}
return null;
}
@@ -193,77 +190,72 @@ public class FontInfoFinder {

// try to determine triplet information from font file
CustomFont customFont = null;
if (fontUrl.toExternalForm().endsWith(".ttc")) {
if (fontURL.toExternalForm().endsWith(".ttc")) {
// Get a list of the TTC Font names
List ttcNames = null; //List<String>
String fontFileURI = fontUrl.toExternalForm().trim();
List<String> ttcNames = null;
String fontFileURL = fontURL.toExternalForm().trim();
InputStream in = null;
try {
in = FontLoader.openFontUri(resolver, fontFileURI);
in = FontLoader.openFontUri(resolver, fontFileURL);
TTFFile ttf = new TTFFile();
FontFileReader reader = new FontFileReader(in);
ttcNames = ttf.getTTCnames(reader);
} catch (Exception e) {
if (this.eventListener != null) {
this.eventListener.fontLoadingErrorAtAutoDetection(this, fontFileURI, e);
this.eventListener.fontLoadingErrorAtAutoDetection(this, fontFileURL, e);
}
return null;
} finally {
IOUtils.closeQuietly(in);
}

List/*<EmbedFontInfo>*/ embedFontInfoList
= new java.util.ArrayList/*<EmbedFontInfo>*/();
List<EmbedFontInfo> embedFontInfoList = new java.util.ArrayList<EmbedFontInfo>();

// For each font name ...
//for (String fontName : ttcNames) {
Iterator ttcNamesIterator = ttcNames.iterator();
while (ttcNamesIterator.hasNext()) {
String fontName = (String)ttcNamesIterator.next();

for (String fontName : ttcNames) {
if (log.isDebugEnabled()) {
log.debug("Loading " + fontName);
}
try {
TTFFontLoader ttfLoader = new TTFFontLoader(
fontFileURI, fontName, true, EncodingMode.AUTO, true, resolver);
fontFileURL, fontName, true, EncodingMode.AUTO, true, resolver);
customFont = ttfLoader.getFont();
if (this.eventListener != null) {
customFont.setEventListener(this.eventListener);
}
} catch (Exception e) {
if (fontCache != null) {
fontCache.registerFailedFont(embedUrl, fileLastModified);
fontCache.registerFailedFont(embedURL, fileLastModified);
}
if (this.eventListener != null) {
this.eventListener.fontLoadingErrorAtAutoDetection(this, embedUrl, e);
this.eventListener.fontLoadingErrorAtAutoDetection(this, embedURL, e);
}
continue;
}
EmbedFontInfo fi = getFontInfoFromCustomFont(fontUrl, customFont, fontCache);
EmbedFontInfo fi = getFontInfoFromCustomFont(fontURL, customFont, fontCache);
if (fi != null) {
embedFontInfoList.add(fi);
}
}
return (EmbedFontInfo[])embedFontInfoList.toArray(
return embedFontInfoList.toArray(
new EmbedFontInfo[embedFontInfoList.size()]);
} else {
// The normal case
try {
customFont = FontLoader.loadFont(fontUrl, null, true, EncodingMode.AUTO, resolver);
customFont = FontLoader.loadFont(fontURL, null, true, EncodingMode.AUTO, resolver);
if (this.eventListener != null) {
customFont.setEventListener(this.eventListener);
}
} catch (Exception e) {
if (fontCache != null) {
fontCache.registerFailedFont(embedUrl, fileLastModified);
fontCache.registerFailedFont(embedURL, fileLastModified);
}
if (this.eventListener != null) {
this.eventListener.fontLoadingErrorAtAutoDetection(this, embedUrl, e);
this.eventListener.fontLoadingErrorAtAutoDetection(this, embedURL, e);
}
return null;
}
EmbedFontInfo fi = getFontInfoFromCustomFont(fontUrl, customFont, fontCache);
EmbedFontInfo fi = getFontInfoFromCustomFont(fontURL, customFont, fontCache);
if (fi != null) {
return new EmbedFontInfo[] {fi};
} else {

+ 3
- 3
src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java View File

@@ -25,15 +25,15 @@ import java.util.List;
/**
* Native font finder base class
*/
public abstract class NativeFontDirFinder implements FontFinder {
public abstract class NativeFontDirFinder implements FontDirFinder {

/**
* Generic method used by Mac and Unix font finders.
* @return list of natively existing font directories
* {@inheritDoc}
*/
public List find() {
List fontDirList = new java.util.ArrayList();
public List<File> find() {
List<File> fontDirList = new java.util.ArrayList<File>();
String[] searchableDirectories = getSearchableDirectories();
if (searchableDirectories != null) {
for (int i = 0; i < searchableDirectories.length; i++) {

+ 3
- 3
src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java View File

@@ -28,7 +28,7 @@ import java.util.List;
/**
* FontFinder for native Windows platforms
*/
public class WindowsFontDirFinder implements FontFinder {
public class WindowsFontDirFinder implements FontDirFinder {

/**
* Attempts to read windir environment variable on windows
@@ -51,8 +51,8 @@ public class WindowsFontDirFinder implements FontFinder {
* {@inheritDoc}
* @return a list of detected font files
*/
public List find() {
List fontDirList = new java.util.ArrayList();
public List<File> find() {
List<File> fontDirList = new java.util.ArrayList<File>();
String windir = null;
try {
windir = System.getProperty("env.windir");

+ 18
- 20
src/java/org/apache/fop/fonts/truetype/TTFFile.java View File

@@ -28,10 +28,8 @@ import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xmlgraphics.fonts.Glyphs;

import org.apache.fop.fonts.FontUtil;
import org.apache.xmlgraphics.fonts.Glyphs;

/**
* Reads a TrueType file or a TrueType Collection.
@@ -132,17 +130,17 @@ public class TTFFile {
/** Set to true to get even more debug output than with level DEBUG */
public static final boolean TRACE_ENABLED = false;

private String encoding = "WinAnsiEncoding"; // Default encoding
private final String encoding = "WinAnsiEncoding"; // Default encoding

private short firstChar = 0;
private final short firstChar = 0;
private boolean isEmbeddable = true;
private boolean hasSerifs = true;
/**
* Table directory
*/
protected Map dirTabs;
private Map kerningTab; // for CIDs
private Map ansiKerningTab; // For winAnsiEncoding
private Map<Integer, Map<Integer, Integer>> kerningTab; // for CIDs
private Map<Integer, Map<Integer, Integer>> ansiKerningTab; // For winAnsiEncoding
private List<TTFCmapEntry> cmaps;
private List unicodeMapping;

@@ -161,12 +159,12 @@ public class TTFFile {
* Contains glyph data
*/
protected TTFMtxEntry[] mtxTab; // Contains glyph data
private int[] mtxEncoded = null;
private final int[] mtxEncoded = null;

private String postScriptName = "";
private String fullName = "";
private String notice = "";
private Set familyNames = new java.util.HashSet(); //Set<String>
private final Set familyNames = new java.util.HashSet(); //Set<String>
private String subFamilyName = "";

private long italicAngle = 0;
@@ -199,8 +197,8 @@ public class TTFFile {

// internal mapping of glyph indexes to unicode indexes
// used for quick mappings in this class
private Map glyphToUnicodeMap = new java.util.HashMap();
private Map unicodeToGlyphMap = new java.util.HashMap();
private final Map glyphToUnicodeMap = new java.util.HashMap();
private final Map unicodeToGlyphMap = new java.util.HashMap();

private TTFDirTabEntry currentDirTab;

@@ -216,8 +214,8 @@ public class TTFFile {
*/
class UnicodeMapping {

private int unicodeIndex;
private int glyphIndex;
private final int unicodeIndex;
private final int glyphIndex;

UnicodeMapping(int glyphIndex, int unicodeIndex) {
this.unicodeIndex = unicodeIndex;
@@ -884,7 +882,7 @@ public class TTFFile {
* Returns the kerning table.
* @return Map The kerning table
*/
public Map getKerning() {
public Map<Integer, Map<Integer, Integer>> getKerning() {
return kerningTab;
}

@@ -892,7 +890,7 @@ public class TTFFile {
* Returns the ANSI kerning table.
* @return Map The ANSI kerning table
*/
public Map getAnsiKerning() {
public Map<Integer, Map<Integer, Integer>> getAnsiKerning() {
return ansiKerningTab;
}

@@ -1553,7 +1551,7 @@ public class TTFFile {
log.debug("Ignoring kerning pair because Unicode index was"
+ " found for the second glyph " + i);
} else {
Map adjTab = (Map)kerningTab.get(iObj);
Map adjTab = kerningTab.get(iObj);
if (adjTab == null) {
adjTab = new java.util.HashMap();
}
@@ -1571,8 +1569,8 @@ public class TTFFile {
while (ae.hasNext()) {
Integer unicodeKey1 = (Integer)ae.next();
Integer cidKey1 = unicodeToGlyph(unicodeKey1.intValue());
Map akpx = new java.util.HashMap();
Map ckpx = (Map)kerningTab.get(unicodeKey1);
Map<Integer, Integer> akpx = new java.util.HashMap();
Map ckpx = kerningTab.get(unicodeKey1);

Iterator aee = ckpx.keySet().iterator();
while (aee.hasNext()) {
@@ -1683,8 +1681,8 @@ public class TTFFile {
* @return True if not collection or font name present, false otherwise
* @throws IOException In case of an I/O problem
*/
public final List getTTCnames(FontFileReader in) throws IOException {
List fontNames = new java.util.ArrayList();
public final List<String> getTTCnames(FontFileReader in) throws IOException {
List<String> fontNames = new java.util.ArrayList<String>();

String tag = in.readTTFString(4);


+ 9
- 9
src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java View File

@@ -24,6 +24,7 @@ import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;

@@ -46,7 +47,7 @@ public class TTFFontLoader extends FontLoader {

private MultiByteFont multiFont;
private SingleByteFont singleFont;
private String subFontName;
private final String subFontName;
private EncodingMode encodingMode;

/**
@@ -212,21 +213,20 @@ public class TTFFontLoader extends FontLoader {
private void copyKerning(TTFFile ttf, boolean isCid) {

// Get kerning
Iterator iter;
Set<Integer> kerningSet;
if (isCid) {
iter = ttf.getKerning().keySet().iterator();
kerningSet = ttf.getKerning().keySet();
} else {
iter = ttf.getAnsiKerning().keySet().iterator();
kerningSet = ttf.getAnsiKerning().keySet();
}

while (iter.hasNext()) {
Integer kpx1 = (Integer)iter.next();
for (Integer kpx1 : kerningSet) {

Map h2;
Map<Integer, Integer> h2;
if (isCid) {
h2 = (Map)ttf.getKerning().get(kpx1);
h2 = ttf.getKerning().get(kpx1);
} else {
h2 = (Map)ttf.getAnsiKerning().get(kpx1);
h2 = ttf.getAnsiKerning().get(kpx1);
}
returnFont.putKerningEntry(kpx1, h2);
}

+ 1
- 1
src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java View File

@@ -604,7 +604,7 @@ public class TTFSubSetFile extends TTFFile {
* @throws IOException in case of an I/O problem
*/
public byte[] readFont(FontFileReader in, String name,
Map glyphs) throws IOException {
Map<Integer, Integer> glyphs) throws IOException {

//Check if TrueType collection, and that the name exists in the collection
if (!checkTTC(in, name)) {

+ 86
- 154
src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java View File

@@ -27,7 +27,6 @@ import java.util.ListIterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.area.Area;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.Trait;
@@ -94,7 +93,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
*/
private static Log log = LogFactory.getLog(LineLayoutManager.class);

private Block fobj;
private final Block fobj;
private boolean isFirstInBlock;

/**
@@ -103,19 +102,19 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* inline break positions.
*/
private static class LineBreakPosition extends LeafPosition {
private int parIndex; // index of the Paragraph this Position refers to
private int startIndex; //index of the first element this Position refers to
private int availableShrink;
private int availableStretch;
private int difference;
private double dAdjust; // Percentage to adjust (stretch or shrink)
private double ipdAdjust; // Percentage to adjust (stretch or shrink)
private int startIndent;
private int lineHeight;
private int lineWidth;
private int spaceBefore;
private int spaceAfter;
private int baseline;
private final int parIndex; // index of the Paragraph this Position refers to
private final int startIndex; //index of the first element this Position refers to
private final int availableShrink;
private final int availableStretch;
private final int difference;
private final double dAdjust; // Percentage to adjust (stretch or shrink)
private final double ipdAdjust; // Percentage to adjust (stretch or shrink)
private final int startIndent;
private final int lineHeight;
private final int lineWidth;
private final int spaceBefore;
private final int spaceAfter;
private final int baseline;

LineBreakPosition( // CSOK: ParameterNumber
LayoutManager lm, int index, int startIndex, int breakIndex,
@@ -151,9 +150,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private int whiteSpaceTreament;
//private LayoutProps layoutProps;

private Length lineHeight;
private int lead;
private int follow;
private final Length lineHeight;
private final int lead;
private final int follow;
private AlignmentContext alignmentContext;

private List knuthParagraphs;
@@ -194,12 +193,12 @@ public class LineLayoutManager extends InlineStackingLayoutManager

// space at the end of the last line (in millipoints)
private MinOptMax lineFiller;
private int textAlignment;
private int textAlignmentLast;
private int textIndent;
private int lastLineEndIndent;
private final int textAlignment;
private final int textAlignmentLast;
private final int textIndent;
private final int lastLineEndIndent;
// the LM which created the paragraph
private LineLayoutManager layoutManager;
private final LineLayoutManager layoutManager;

Paragraph(LineLayoutManager llm, int alignment, int alignmentLast,
int indent, int endIndent) {
@@ -211,6 +210,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
lastLineEndIndent = endIndent;
}

@Override
public void startSequence() {
// set the minimum amount of empty space at the end of the
// last line
@@ -245,6 +245,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
}

@Override
public KnuthSequence endSequence() {
if (this.size() > ignoreAtStart) {
if (textAlignment == EN_CENTER
@@ -294,14 +295,14 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

private class LineBreakingAlgorithm extends BreakingAlgorithm {
private LineLayoutManager thisLLM;
private int pageAlignment;
private final LineLayoutManager thisLLM;
private final int pageAlignment;
private int activePossibility;
private int addedPositions;
private int textIndent;
private int lineHeight;
private int lead;
private int follow;
private final int textIndent;
private final int lineHeight;
private final int lead;
private final int follow;
private static final double MAX_DEMERITS = 10e6;

public LineBreakingAlgorithm( // CSOK: ParameterNumber
@@ -317,6 +318,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
activePossibility = -1;
}

@Override
public void updateData1(int lineCount, double demerits) {
lineLayouts.addPossibility(lineCount, demerits);
if (log.isTraceEnabled()) {
@@ -324,6 +326,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
}

@Override
public void updateData2(KnuthNode bestActiveNode,
KnuthSequence par,
int total) {
@@ -466,6 +469,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
}

@Override
protected int filterActiveNodes() {
KnuthNode bestActiveNode = null;

@@ -537,6 +541,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

/** {@inheritDoc} */
@Override
public void initialize() {
textAlignment = fobj.getTextAlign();
textAlignmentLast = fobj.getTextAlignLast();
@@ -560,6 +565,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

/** {@inheritDoc} */
@Override
public List getNextKnuthElements(LayoutContext context, int alignment) {
if (alignmentContext == null) {
FontInfo fi = fobj.getFOEventHandler().getFontInfo();
@@ -771,7 +777,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// we only need an entry in lineLayoutsList.
llPoss = new LineLayoutPossibilities();
} else {
llPoss = findOptimalBreakingPoints(alignment, (Paragraph) seq);
llPoss = findOptimalBreakingPoints(alignment, (Paragraph) seq,
!paragraphsIterator.hasNext());
}
lineLayoutsList[i] = llPoss;
}
@@ -783,16 +790,17 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

/**
* Fint the optimal linebreaks for a paragraph
* Find the optimal linebreaks for a paragraph
* @param alignment alignment of the paragraph
* @param currPar the Paragraph for which the linebreaks are found
* @param isLastPar flag indicating whether currPar is the last paragraph
* @return the line layout possibilities for the paragraph
*/
private LineLayoutPossibilities findOptimalBreakingPoints(int alignment, Paragraph currPar) {
private LineLayoutPossibilities findOptimalBreakingPoints(int alignment, Paragraph currPar,
boolean isLastPar) {
// use the member lineLayouts, which is read by LineBreakingAlgorithm.updateData1 and 2
lineLayouts = new LineLayoutPossibilities();
double maxAdjustment = 1;
int iBPcount = 0;
LineBreakingAlgorithm alg = new LineBreakingAlgorithm(alignment,
textAlignment, textAlignmentLast,
textIndent.getValue(this), currPar.lineFiller.getOpt(),
@@ -801,26 +809,26 @@ public class LineLayoutManager extends InlineStackingLayoutManager
hyphenationLadderCount.getEnum() == EN_NO_LIMIT
? 0 : hyphenationLadderCount.getValue(),
this);

if (hyphenationProperties.hyphenate.getEnum() == EN_TRUE
&& fobj.getWrapOption() != EN_NO_WRAP && !hyphenationPerformed) {
hyphenationPerformed = true;
alg.setConstantLineWidth(ipd);
boolean canWrap = (wrapOption != EN_NO_WRAP);
boolean canHyphenate = (canWrap && hyphenationProperties.hyphenate.getEnum() == EN_TRUE);

// find hyphenation points, if allowed and not yet done
if (canHyphenate && !hyphenationPerformed) {
// make sure findHyphenationPoints() is bypassed if
// the method is called twice (e.g. due to changing page-ipd)
hyphenationPerformed = isLastPar;
findHyphenationPoints(currPar);
}

// first try
int allowedBreaks;
if (wrapOption == EN_NO_WRAP) {
allowedBreaks = BreakingAlgorithm.ONLY_FORCED_BREAKS;
} else {
allowedBreaks = BreakingAlgorithm.NO_FLAGGED_PENALTIES;
}
alg.setConstantLineWidth(ipd);
iBPcount = alg.findBreakingPoints(currPar,
maxAdjustment, false, allowedBreaks);
if (iBPcount == 0 || alignment == EN_JUSTIFY) {
// first try: do not consider hyphenation points as legal breaks
int allowedBreaks = (canWrap ? BreakingAlgorithm.NO_FLAGGED_PENALTIES
: BreakingAlgorithm.ONLY_FORCED_BREAKS);
int breakingPoints = alg.findBreakingPoints(currPar, maxAdjustment, false, allowedBreaks);

if (breakingPoints == 0 || alignment == EN_JUSTIFY) {
// if the first try found a set of breaking points, save them
if (iBPcount > 0) {
if (breakingPoints > 0) {
alg.resetAlgorithm();
lineLayouts.savePossibilities(false);
} else {
@@ -829,10 +837,10 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

// now try something different
log.debug("Hyphenation possible? "
+ (hyphenationProperties.hyphenate.getEnum() == EN_TRUE));
if (hyphenationProperties.hyphenate.getEnum() == EN_TRUE
&& !(allowedBreaks == BreakingAlgorithm.ONLY_FORCED_BREAKS)) {
log.debug("Hyphenation possible? " + canHyphenate);
// Note: if allowedBreaks is guaranteed to be unchanged by alg.findBreakingPoints(),
// the below check can be simplified to 'if (canHyphenate) ...'
if (canHyphenate && allowedBreaks != BreakingAlgorithm.ONLY_FORCED_BREAKS) {
// consider every hyphenation point as a legal break
allowedBreaks = BreakingAlgorithm.ALL_BREAKS;
} else {
@@ -840,68 +848,22 @@ public class LineLayoutManager extends InlineStackingLayoutManager
maxAdjustment = 5;
}

iBPcount = alg.findBreakingPoints(currPar, maxAdjustment, false, allowedBreaks);
if (iBPcount == 0) {
breakingPoints = alg.findBreakingPoints(currPar, maxAdjustment, false, allowedBreaks);
if (breakingPoints == 0) {
// the second try failed too, try with a huge threshold
// and force the algorithm to find
// a set of breaking points
// and force the algorithm to find a set of breaking points
if (log.isDebugEnabled()) {
log.debug("No set of breaking points found with maxAdjustment = "
+ maxAdjustment
+ (hyphenationProperties.hyphenate.getEnum() == EN_TRUE
? " and hyphenation" : ""));
+ maxAdjustment + (canHyphenate ? " and hyphenation" : ""));
}
maxAdjustment = 20;
iBPcount
= alg.findBreakingPoints(currPar,
maxAdjustment, true, allowedBreaks);
alg.findBreakingPoints(currPar, maxAdjustment, true, allowedBreaks);
}

// use non-hyphenated breaks, when possible
lineLayouts.restorePossibilities();

/* extension (not in the XSL FO recommendation): if vertical alignment
is justify and the paragraph has only one layout, try using
shorter or longer lines */
//TODO This code snippet is disabled. Reenable?
/* [GA] remove dead code
if (false && alignment == EN_JUSTIFY && textAlignment == EN_JUSTIFY) {
//log.debug("LLM.getNextKnuthElements> layouts with more lines? "
//+ lineLayouts.canUseMoreLines());
//log.debug(" layouts with fewer lines? "
//+ lineLayouts.canUseLessLines());
if (!lineLayouts.canUseMoreLines()) {
alg.resetAlgorithm();
lineLayouts.savePossibilities(true);
// try with shorter lines
int savedLineWidth = ipd;
ipd = (int) (ipd * 0.95);
iBPcount = alg.findBreakingPoints(currPar,
maxAdjustment, true, allowedBreaks);
// use normal lines, when possible
lineLayouts.restorePossibilities();
ipd = savedLineWidth;
}
if (!lineLayouts.canUseLessLines()) {
alg.resetAlgorithm();
lineLayouts.savePossibilities(true);
// try with longer lines
int savedLineWidth = ipd;
ipd = (int) (ipd * 1.05);
alg.setConstantLineWidth(ipd);
iBPcount = alg.findBreakingPoints(currPar,
maxAdjustment, true, allowedBreaks);
// use normal lines, when possible
lineLayouts.restorePossibilities();
ipd = savedLineWidth;
}
//log.debug("LLM.getNextKnuthElements> now, layouts with more lines? "
//+ lineLayouts.canUseMoreLines());
//log.debug(" now, layouts with fewer lines? "
//+ lineLayouts.canUseLessLines());
}
*/
}

return lineLayouts;
}

@@ -1204,6 +1166,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

/** {@inheritDoc} */
@Override
public List getChangedKnuthElements(List oldList, int alignment) {
List returnList = new LinkedList();
for (int p = 0; p < knuthParagraphs.size(); p++) {
@@ -1278,8 +1241,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager
} else if (currLM == null) {
break;
}
//TODO Something's not right here. See block_hyphenation_linefeed_preserve.xml
//for more info: see also https://issues.apache.org/bugzilla/show_bug.cgi?id=38264

// collect word fragments, ignoring auxiliary elements;
// each word fragment was created by a different TextLM
@@ -1388,6 +1349,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* @param isNotFirst ignored
* @return always true
*/
@Override
protected boolean hasLeadingFence(boolean isNotFirst) {
return true;
}
@@ -1397,6 +1359,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* @param isNotLast ignored
* @return always true
*/
@Override
protected boolean hasTrailingFence(boolean isNotLast) {
return true;
}
@@ -1444,6 +1407,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
* @param parentIter the iterator of break positions
* @param context the context for adding areas
*/
@Override
public void addAreas(PositionIterator parentIter,
LayoutContext context) {
while (parentIter.hasNext()) {
@@ -1472,8 +1436,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager
*/
private void addInlineArea(LayoutContext context, LineBreakPosition lbp,
boolean isLastPosition) {
// the TLM which created the last KnuthElement in this line
LayoutManager lastLM = null;

KnuthSequence seq = (KnuthSequence) knuthParagraphs.get(lbp.parIndex);
int startElementIndex = lbp.startIndex;
@@ -1505,15 +1467,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
}

// Remove trailing spaces if allowed so
if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
|| whiteSpaceTreament == EN_IGNORE
|| whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) {
// ignore the last element in the line if it is a KnuthGlue object
ListIterator seqIterator = seq.listIterator(endElementIndex);
KnuthElement lastElement = (KnuthElement) seqIterator.next();
lastLM = lastElement.getLayoutManager();
if (lastElement.isGlue()) {
// ignore the last element in the line if it is a KnuthGlue object
ListIterator seqIterator = seq.listIterator(endElementIndex);
KnuthElement lastElement = (KnuthElement) seqIterator.next();
// the TLM which created the last KnuthElement in this line
LayoutManager lastLM = lastElement.getLayoutManager();
if (lastElement.isGlue()) {
// Remove trailing spaces if allowed so
if (whiteSpaceTreament == EN_IGNORE_IF_SURROUNDING_LINEFEED
|| whiteSpaceTreament == EN_IGNORE
|| whiteSpaceTreament == EN_IGNORE_IF_BEFORE_LINEFEED) {
endElementIndex--;
// this returns the same KnuthElement
seqIterator.previous();
@@ -1529,7 +1492,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
|| whiteSpaceTreament == EN_IGNORE_IF_AFTER_LINEFEED) {
// ignore KnuthGlue and KnuthPenalty objects
// at the beginning of the line
ListIterator seqIterator = seq.listIterator(startElementIndex);
seqIterator = seq.listIterator(startElementIndex);
while (seqIterator.hasNext() && !((KnuthElement) seqIterator.next()).isBox()) {
startElementIndex++;
}
@@ -1546,40 +1509,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager
lc.setTrailingSpace(new SpaceSpecifier(false));
lc.setFlags(LayoutContext.RESOLVE_LEADING_SPACE, true);

/*
* extension (not in the XSL FO recommendation): if the left and right margins
* have been optimized, recompute indents and / or adjust ratio, according
* to the paragraph horizontal alignment
*/
/* [GA] remove dead code
if (false && textAlignment == EN_JUSTIFY) {
// re-compute space adjust ratio
int updatedDifference = context.getRefIPD()
- lbp.lineWidth + lbp.difference;
double updatedRatio = 0.0;
if (updatedDifference > 0) {
updatedRatio = (float) updatedDifference / lbp.availableStretch;
} else if (updatedDifference < 0) {
updatedRatio = (float) updatedDifference / lbp.availableShrink;
}
lc.setIPDAdjust(updatedRatio);
//log.debug("LLM.addAreas> old difference = " + lbp.difference
//+ " new difference = " + updatedDifference);
//log.debug(" old ratio = " + lbp.ipdAdjust
//+ " new ratio = " + updatedRatio);
} else if (false && textAlignment == EN_CENTER) {
// re-compute indent
int updatedIndent = lbp.startIndent
+ (context.getRefIPD() - lbp.lineWidth) / 2;
lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
} else if (false && textAlignment == EN_END) {
// re-compute indent
int updatedIndent = lbp.startIndent
+ (context.getRefIPD() - lbp.lineWidth);
lineArea.addTrait(Trait.START_INDENT, new Integer(updatedIndent));
}
*/

setCurrentArea(lineArea);
setChildContext(lc);
LayoutManager childLM;
@@ -1649,6 +1578,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}

/** {@inheritDoc} */
@Override
public void addChildArea(Area childArea) {
// Make sure childArea is inline area
if (childArea instanceof InlineArea) {
@@ -1664,19 +1594,21 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// --------- Property Resolution related functions --------- //

/** {@inheritDoc} */
@Override
public boolean getGeneratesBlockArea() {
return true;
}

/** {@inheritDoc} */
@Override
public boolean getGeneratesLineArea() {
return true;
}

/** {@inheritDoc} */
@Override
public boolean isRestartable() {
return true;
}

}


+ 54
- 24
src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java View File

@@ -165,7 +165,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private int hyphIPD;

private boolean hasChanged = false;
private int returnedIndex = 0;
private int[] returnedIndices = {0, 0};
private int changeOffset = 0;
private int thisStart = 0;
private int tempStart = 0;
private List changeList = new LinkedList();
@@ -811,19 +812,19 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
//TODO: add kern to wordIPD?
}
}
int iLetterSpaces = wordLength - 1;
int letterSpaces = wordLength - 1;
// if there is a break opportunity and the next one
// is not a space, it could be used as a line end;
// add one more letter space, in case other text follows
if (breakOpportunity && !TextLayoutManager.isSpace(ch)) {
iLetterSpaces++;
letterSpaces++;
}
assert iLetterSpaces >= 0;
wordIPD = wordIPD.plus(letterSpaceIPD.mult(iLetterSpaces));
assert letterSpaces >= 0;
wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));

// create the AreaInfo object
AreaInfo areaInfo = new AreaInfo(thisStart, lastIndex, 0,
iLetterSpaces, wordIPD,
letterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunity, font);
prevAreaInfo = areaInfo;
@@ -903,11 +904,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public void hyphenate(Position pos, HyphContext hyphContext) {
AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos());
AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset);
int startIndex = areaInfo.startIndex;
int stopIndex;
boolean nothingChanged = true;
@@ -962,7 +961,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// the new AreaInfo object is not equal to the old one
changeList.add(new PendingChange(new AreaInfo(startIndex, stopIndex, 0,
letterSpaceCount, newIPD, hyphenFollows, false, false, font),
((LeafPosition) pos).getLeafPos()));
((LeafPosition) pos).getLeafPos() + changeOffset));
nothingChanged = false;
}
startIndex = stopIndex;
@@ -972,11 +971,41 @@ public class TextLayoutManager extends LeafNodeLayoutManager {

/** {@inheritDoc} */
public boolean applyChanges(final List oldList) {

// make sure the LM appears unfinished in between this call
// and the next call to getChangedKnuthElements()
setFinished(false);

if (oldList.isEmpty()) {
return false;
}

// Find the first and last positions in oldList that point to an AreaInfo
// (i.e. getLeafPos() != -1)
LeafPosition startPos = null, endPos = null;
ListIterator oldListIter;
for (oldListIter = oldList.listIterator(); oldListIter.hasNext();) {
startPos = (LeafPosition) ((KnuthElement) oldListIter.next()).getPosition();
if (startPos != null && startPos.getLeafPos() != -1) {
break;
}
}
for (oldListIter = oldList.listIterator(oldList.size()); oldListIter.hasPrevious();) {
endPos = (LeafPosition) ((KnuthElement) oldListIter.previous()).getPosition();
if (endPos != null && endPos.getLeafPos() != -1) {
break;
}
}

// set start/end index, taking into account any offset due to
// changes applied to previous paragraphs
returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset;
returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset;

int areaInfosAdded = 0;
int areaInfosRemoved = 0;

if (!changeList.isEmpty()) {
int areaInfosAdded = 0;
int areaInfosRemoved = 0;
int oldIndex = -1, changeIndex;
PendingChange currChange;
ListIterator changeListIterator = changeList.listIterator();
@@ -997,7 +1026,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
changeList.clear();
}

returnedIndex = 0;
// increase the end index for getChangedKnuthElements()
returnedIndices[1] += (areaInfosAdded - areaInfosRemoved);
// increase offset to use for subsequent paragraphs
changeOffset += (areaInfosAdded - areaInfosRemoved);

return hasChanged;
}

@@ -1009,27 +1042,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {

final LinkedList returnList = new LinkedList();

while (returnedIndex < areaInfos.size()) {
AreaInfo areaInfo = getAreaInfo(returnedIndex);
for (; returnedIndices[0] <= returnedIndices[1]; returnedIndices[0]++) {
AreaInfo areaInfo = getAreaInfo(returnedIndices[0]);
if (areaInfo.wordSpaceCount == 0) {
// areaInfo refers either to a word or a word fragment
addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndex);
addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]);
} else {
// areaInfo refers to a space
addElementsForASpace(returnList, alignment, areaInfo, returnedIndex);
addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]);
}
returnedIndex++;
}
setFinished(true);
setFinished(returnedIndices[0] == areaInfos.size() - 1);
//ElementListObserver.observe(returnList, "text-changed", null);
return returnList;
}

/**
* {@inheritDoc}
*/
/** {@inheritDoc} */
public String getWordChars(Position pos) {
int leafValue = ((LeafPosition) pos).getLeafPos();
int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset;
if (leafValue != -1) {
AreaInfo areaInfo = getAreaInfo(leafValue);
StringBuffer buffer = new StringBuffer(areaInfo.getCharLength());

+ 4
- 5
src/java/org/apache/fop/pdf/PDFResources.java View File

@@ -98,11 +98,9 @@ public class PDFResources extends PDFObject {
* @param fontInfo font info object to get font information from
*/
public void addFonts(PDFDocument doc, FontInfo fontInfo) {
Map usedFonts = fontInfo.getUsedFonts();
Iterator e = usedFonts.keySet().iterator();
while (e.hasNext()) {
String f = (String)e.next();
Typeface font = (Typeface)usedFonts.get(f);
Map<String, Typeface> usedFonts = fontInfo.getUsedFonts();
for (String f : usedFonts.keySet()) {
Typeface font = usedFonts.get(f);

//Check if the font actually had any mapping operations. If not, it is an indication
//that it has never actually been used and therefore doesn't have to be embedded.
@@ -196,6 +194,7 @@ public class PDFResources extends PDFObject {
* @return the PDF
* {@inheritDoc}
*/
@Override
public String toPDFString() {
StringBuffer p = new StringBuffer(128);
p.append(getObjectID() + "<<\n");

+ 5
- 4
src/java/org/apache/fop/render/PrintRenderer.java View File

@@ -30,6 +30,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.area.Area;
import org.apache.fop.area.Trait;
import org.apache.fop.fonts.CustomFontCollection;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
@@ -48,13 +49,13 @@ public abstract class PrintRenderer extends AbstractRenderer {
protected FontResolver fontResolver = null;

/** list of fonts */
protected List/*<EmbedFontInfo>*/ embedFontInfoList = null;
protected List<EmbedFontInfo> embedFontInfoList = null;

/**
* Adds a font list to current list of fonts
* @param fontList a font info list
*/
public void addFontList(List/*<EmbedFontInfo>*/ fontList) {
public void addFontList(List<EmbedFontInfo> fontList) {
if (embedFontInfoList == null) {
setFontList(fontList);
} else {
@@ -65,14 +66,14 @@ public abstract class PrintRenderer extends AbstractRenderer {
/**
* @param embedFontInfoList list of available fonts
*/
public void setFontList(List/*<EmbedFontInfo>*/ embedFontInfoList) {
public void setFontList(List<EmbedFontInfo> embedFontInfoList) {
this.embedFontInfoList = embedFontInfoList;
}

/**
* @return list of available embedded fonts
*/
public List/*<EmbedFontInfo>*/ getFontList() {
public List<EmbedFontInfo> getFontList() {
return this.embedFontInfoList;
}


+ 6
- 5
src/java/org/apache/fop/render/PrintRendererConfigurator.java View File

@@ -19,6 +19,7 @@

package org.apache.fop.render;

import java.util.ArrayList;
import java.util.List;

import org.apache.avalon.framework.configuration.Configuration;
@@ -76,7 +77,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator

FontEventListener listener = new FontEventAdapter(
renderer.getUserAgent().getEventBroadcaster());
List/*<EmbedFontInfo>*/ embedFontInfoList = buildFontList(cfg, fontResolver, listener);
List<EmbedFontInfo> embedFontInfoList = buildFontList(cfg, fontResolver, listener);
printRenderer.addFontList(embedFontInfoList);
}

@@ -88,7 +89,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
* @return the list of {@link EmbedFontInfo} objects
* @throws FOPException if an error occurs while processing the configuration
*/
protected List/*<EmbedFontInfo>*/ buildFontList(Configuration cfg, FontResolver fontResolver,
protected List<EmbedFontInfo> buildFontList(Configuration cfg, FontResolver fontResolver,
FontEventListener listener) throws FOPException {
FopFactory factory = userAgent.getFactory();
FontManager fontManager = factory.getFontManager();
@@ -102,7 +103,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
//Read font configuration
FontInfoConfigurator fontInfoConfigurator
= new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict);
List/*<EmbedFontInfo>*/ fontInfoList = new java.util.ArrayList/*<EmbedFontInfo>*/();
List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
fontInfoConfigurator.configure(fontInfoList);
return fontInfoList;
}
@@ -118,7 +119,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
throws FOPException {
FontManager fontManager = userAgent.getFactory().getFontManager();
List fontCollections = new java.util.ArrayList();
List<FontCollection> fontCollections = new ArrayList<FontCollection>();
fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));

Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
@@ -126,7 +127,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
FontResolver fontResolver = new DefaultFontResolver(userAgent);
FontEventListener listener = new FontEventAdapter(
userAgent.getEventBroadcaster());
List fontList = buildFontList(cfg, fontResolver, listener);
List<EmbedFontInfo> fontList = buildFontList(cfg, fontResolver, listener);
fontCollections.add(new CustomFontCollection(fontResolver, fontList));
}


+ 22
- 10
src/java/org/apache/fop/render/afp/AFPPainter.java View File

@@ -30,11 +30,6 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

import org.w3c.dom.Document;

import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;

import org.apache.fop.afp.AFPBorderPainter;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPUnitConverter;
@@ -55,6 +50,7 @@ import org.apache.fop.afp.util.ResourceAccessor;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.BorderPainter;
@@ -64,6 +60,9 @@ import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.w3c.dom.Document;

/**
* IFPainter implementation that produces AFP (MO:DCA).
@@ -76,12 +75,12 @@ public class AFPPainter extends AbstractIFPainter {
private static final int X = 0;
private static final int Y = 1;

private AFPDocumentHandler documentHandler;
private final AFPDocumentHandler documentHandler;

/** the border painter */
private AFPBorderPainterAdapter borderPainter;
private final AFPBorderPainterAdapter borderPainter;
/** the rectangle painter */
private AbstractAFPPainter rectanglePainter;
private final AbstractAFPPainter rectanglePainter;

/** unit converter */
private final AFPUnitConverter unitConv;
@@ -101,6 +100,7 @@ public class AFPPainter extends AbstractIFPainter {
}

/** {@inheritDoc} */
@Override
protected IFContext getContext() {
return this.documentHandler.getContext();
}
@@ -165,6 +165,7 @@ public class AFPPainter extends AbstractIFPainter {
}

/** {@inheritDoc} */
@Override
protected Map createDefaultImageProcessingHints(ImageSessionContext sessionContext) {
Map hints = super.createDefaultImageProcessingHints(sessionContext);

@@ -175,6 +176,7 @@ public class AFPPainter extends AbstractIFPainter {
}

/** {@inheritDoc} */
@Override
protected RenderingContext createRenderingContext() {
AFPRenderingContext psContext = new AFPRenderingContext(
getUserAgent(),
@@ -256,6 +258,7 @@ public class AFPPainter extends AbstractIFPainter {
}

/** {@inheritDoc} */
@Override
public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after,
BorderProps start, BorderProps end) throws IFException {
if (before != null || after != null || start != null || end != null) {
@@ -271,32 +274,38 @@ public class AFPPainter extends AbstractIFPainter {
//and this one. Not done for now to avoid a lot of re-implementation and code duplication.
private static class AFPBorderPainterAdapter extends BorderPainter {

private AFPBorderPainter delegate;
private final AFPBorderPainter delegate;

public AFPBorderPainterAdapter(AFPBorderPainter borderPainter) {
this.delegate = borderPainter;
}

@Override
protected void clip() throws IOException {
//not supported by AFP
}

@Override
protected void closePath() throws IOException {
//used for clipping only, so not implemented
}

@Override
protected void moveTo(int x, int y) throws IOException {
//used for clipping only, so not implemented
}

@Override
protected void lineTo(int x, int y) throws IOException {
//used for clipping only, so not implemented
}

@Override
protected void saveGraphicsState() throws IOException {
//used for clipping only, so not implemented
}

@Override
protected void restoreGraphicsState() throws IOException {
//used for clipping only, so not implemented
}
@@ -305,6 +314,7 @@ public class AFPPainter extends AbstractIFPainter {
return mpt / 1000f;
}

@Override
protected void drawBorderLine( // CSOK: ParameterNumber
int x1, int y1, int x2, int y2, boolean horz,
boolean startOrBefore, int style, Color color) throws IOException {
@@ -314,6 +324,7 @@ public class AFPPainter extends AbstractIFPainter {
delegate.paint(borderPaintInfo);
}

@Override
public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
throws IOException {
if (start.y != end.y) {
@@ -331,6 +342,7 @@ public class AFPPainter extends AbstractIFPainter {
}

/** {@inheritDoc} */
@Override
public void drawLine(Point start, Point end, int width, Color color, RuleStyle style)
throws IFException {
try {
@@ -357,7 +369,7 @@ public class AFPPainter extends AbstractIFPainter {
}

// register font as necessary
Map/*<String,FontMetrics>*/ fontMetricMap = documentHandler.getFontInfo().getFonts();
Map<String, Typeface> fontMetricMap = documentHandler.getFontInfo().getFonts();
final AFPFont afpFont = (AFPFont)fontMetricMap.get(fontKey);
final Font font = getFontInfo().getFontInstance(triplet, fontSize);
AFPPageFonts pageFonts = getPaintingState().getPageFonts();

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

@@ -95,7 +95,7 @@ public class ConfiguredFontCollection implements FontCollection {

fontInfo.addMetrics(internalName, font);

List triplets = configFontInfo.getFontTriplets();
List<FontTriplet> triplets = configFontInfo.getFontTriplets();
for (int c = 0; c < triplets.size(); c++) {
FontTriplet triplet = (FontTriplet) triplets.get(c);


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

@@ -161,7 +161,7 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
}

/** {@inheritDoc} */
public final Set getFamilyNames() {
public final Set<String> getFamilyNames() {
return typeface.getFamilyNames();
}


+ 4
- 5
src/java/org/apache/fop/render/ps/FontResourceCache.java View File

@@ -21,18 +21,17 @@ package org.apache.fop.render.ps;

import java.util.Map;

import org.apache.xmlgraphics.ps.PSResource;

import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.Typeface;
import org.apache.xmlgraphics.ps.PSResource;

/**
* A cache for font resource objects.
*/
class FontResourceCache {

private FontInfo fontInfo;
private final FontInfo fontInfo;

/** This is a map of PSResource instances of all fonts defined (key: font key) */
private Map fontResources = new java.util.HashMap();
@@ -68,8 +67,8 @@ class FontResourceCache {
postFix = key.substring(pos);
key = key.substring(0, pos);
}
Map fonts = fontInfo.getFonts();
Typeface tf = (Typeface)fonts.get(key);
Map<String, Typeface> fonts = fontInfo.getFonts();
Typeface tf = fonts.get(key);
if (tf instanceof LazyFont) {
tf = ((LazyFont)tf).getRealFont();
}

+ 13
- 18
src/java/org/apache/fop/render/ps/PSFontUtils.java View File

@@ -23,7 +23,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.Map;

import javax.xml.transform.Source;
@@ -105,7 +104,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @return a Map of PSResource instances representing all defined fonts (key: font key)
* @throws IOException in case of an I/O problem
*/
public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts,
public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map<String, Typeface> fonts,
PSEventProducer eventProducer) throws IOException {
return writeFontDict(gen, fontInfo, fonts, false, eventProducer);
}
@@ -120,14 +119,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @return a Map of PSResource instances representing all defined fonts (key: font key)
* @throws IOException in case of an I/O problem
*/
private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts,
private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map<String, Typeface> fonts,
boolean encodeAllCharacters, PSEventProducer eventProducer) throws IOException {
gen.commentln("%FOPBeginFontDict");

Map fontResources = new java.util.HashMap();
Iterator iter = fonts.keySet().iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
for (String key : fonts.keySet()) {
Typeface tf = getTypeFace(fontInfo, fonts, key);
PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName());
PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer);
@@ -164,7 +161,8 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
return fontResources;
}

private static void reencodeFonts(PSGenerator gen, Map fonts) throws IOException {
private static void reencodeFonts(PSGenerator gen, Map<String, Typeface> fonts)
throws IOException {
ResourceTracker tracker = gen.getResourceTracker();

if (!tracker.isResourceSupplied(WINANSI_ENCODING_RESOURCE)) {
@@ -174,10 +172,8 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
gen.commentln("%FOPBeginFontReencode");

//Rewrite font encodings
Iterator iter = fonts.keySet().iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
Typeface tf = (Typeface)fonts.get(key);
for (String key : fonts.keySet()) {
Typeface tf = fonts.get(key);
if (tf instanceof LazyFont) {
tf = ((LazyFont)tf).getRealFont();
if (tf == null) {
@@ -206,8 +202,9 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
gen.commentln("%FOPEndFontReencode");
}

private static Typeface getTypeFace(FontInfo fontInfo, Map fonts, String key) {
Typeface tf = (Typeface)fonts.get(key);
private static Typeface getTypeFace(FontInfo fontInfo, Map<String, Typeface> fonts,
String key) {
Typeface tf = fonts.get(key);
if (tf instanceof LazyFont) {
tf = ((LazyFont)tf).getRealFont();
}
@@ -215,7 +212,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
//This is to avoid an NPE if a malconfigured font is in the configuration but not
//used in the document. If it were used, we wouldn't get this far.
String fallbackKey = fontInfo.getInternalFontKey(Font.DEFAULT_FONT);
tf = (Typeface)fonts.get(fallbackKey);
tf = fonts.get(fallbackKey);
}
return tf;
}
@@ -562,11 +559,9 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @return a Map of PSResource instances representing all defined fonts (key: font key)
*/
public static Map determineSuppliedFonts(ResourceTracker resTracker,
FontInfo fontInfo, Map fonts) {
FontInfo fontInfo, Map<String, Typeface> fonts) {
Map fontResources = new java.util.HashMap();
Iterator iter = fonts.keySet().iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
for (String key : fonts.keySet()) {
Typeface tf = getTypeFace(fontInfo, fonts, key);
PSResource fontRes = new PSResource("font", tf.getEmbedFontName());
fontResources.put(key, fontRes);

+ 4
- 3
src/java/org/apache/fop/tools/fontlist/FontSpec.java View File

@@ -22,6 +22,7 @@ package org.apache.fop.tools.fontlist;
import java.util.Collection;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.fop.fonts.FontMetrics;
import org.apache.fop.fonts.FontTriplet;
@@ -33,8 +34,8 @@ public class FontSpec implements Comparable {

private String key;
private FontMetrics metrics;
private SortedSet familyNames = new java.util.TreeSet();
private Collection triplets = new java.util.TreeSet();
private SortedSet<String> familyNames = new TreeSet<String>();
private Collection triplets = new TreeSet();

/**
* Creates a new font spec.
@@ -50,7 +51,7 @@ public class FontSpec implements Comparable {
* Adds font family names.
* @param names the names
*/
public void addFamilyNames(Collection names) {
public void addFamilyNames(Collection<String> names) {
this.familyNames.addAll(names);
}


+ 3
- 0
status.xml View File

@@ -58,6 +58,9 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
<action context="Layout" dev="AD" type="fix" fixes-bug="38264">
Fixed behavior when combining hyphenation with preserved linefeeds or whitespace.
</action>
<action context="Code" dev="VH" type="fix" fixes-bug="49695" due-to="Joshua Marquart">
Replaced magic numbers with constants from UnitConv and GraphicsConstants.
</action>

+ 0
- 6
test/layoutengine/disabled-testcases.xml View File

@@ -38,12 +38,6 @@
<file>block_font-stretch.xml</file>
<description>Font-stretch is not implemented, yet.</description>
</testcase>
<testcase>
<name>Hyphenation with preserved linefeeds</name>
<file>block_hyphenation_linefeed_preserve.xml</file>
<description>When hyphenation is enabled and linefeeds are preserved,
the text is output multiple times.</description>
</testcase>
<testcase>
<name>linefeed-treatment</name>
<file>block_linefeed-treatment.xml</file>

+ 31
- 9
test/layoutengine/hyphenation-testcases/block_hyphenation_linefeed_preserve.xml View File

@@ -19,7 +19,11 @@
<testcase>
<info>
<p>
Check for bug: Duplicate content and linefeeds as "#".
Check for bug 38264:
<ul>
<li>duplication of content with linefeed-treatment="preserve" and hyphenate="true"</li>
<li>missing hyphens with white-space-treatment="preserve" and hyphenate="true"</li>
</ul>
</p>
</info>
<fo>
@@ -31,21 +35,39 @@
</fo:layout-master-set>
<fo:page-sequence master-reference="simple">
<fo:flow flow-name="xsl-region-body">
<fo:block line-height="10pt" background-color="orange"
white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas semper. Proin at.</fo:block>
<fo:block line-height="10pt" background-color="orange"
white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve">
<fo:block white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve">
line1
line2

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas semper. Proin at1.
</fo:block>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas semper. Proin at.
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</fo>
<checks>
<!-- Dummy check. We don't want an NPE. -->
<eval expected="2" xpath="count(//*[contains(text(), 'adipiscing')])"/>
<!-- check number of lines and word fragments -->
<eval expected="13" xpath="count(//flow[1]/block/lineArea)" />
<eval expected="17" xpath="count(//flow[1]/block/lineArea/text/word)" />
<!-- check individual word fragments -->
<eval expected="line1" xpath="(//flow[1]/block/lineArea/text/word)[1]" />
<eval expected="line2" xpath="(//flow[1]/block/lineArea/text/word)[2]" />
<eval expected="Lorem" xpath="(//flow[1]/block/lineArea/text/word)[3]" />
<eval expected="ip-" xpath="(//flow[1]/block/lineArea/text/word)[4]" />
<eval expected="sum" xpath="(//flow[1]/block/lineArea/text/word)[5]" />
<eval expected="dolor" xpath="(//flow[1]/block/lineArea/text/word)[6]" />
<eval expected="sit" xpath="(//flow[1]/block/lineArea/text/word)[7]" />
<eval expected="amet," xpath="(//flow[1]/block/lineArea/text/word)[8]" />
<eval expected="con-" xpath="(//flow[1]/block/lineArea/text/word)[9]" />
<eval expected="sectetuer" xpath="(//flow[1]/block/lineArea/text/word)[10]" />
<eval expected="adipiscing" xpath="(//flow[1]/block/lineArea/text/word)[11]" />
<eval expected="elit." xpath="(//flow[1]/block/lineArea/text/word)[12]" />
<eval expected="Maece-" xpath="(//flow[1]/block/lineArea/text/word)[13]" />
<eval expected="nas" xpath="(//flow[1]/block/lineArea/text/word)[14]" />
<eval expected="semper." xpath="(//flow[1]/block/lineArea/text/word)[15]" />
<eval expected="Proin" xpath="(//flow[1]/block/lineArea/text/word)[16]" />
<eval expected="at." xpath="(//flow[1]/block/lineArea/text/word)[17]" />
<!-- check preservation of spaces on the last line -->
<eval expected="10" xpath="count((//flow[1]/block/lineArea)[13]/text/space)" />
</checks>
</testcase>

Loading…
Cancel
Save