Browse Source

Fixed a bug in TTF subsetting where a composite glyph could get remapped more than once resulting in garbled character.

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1151195 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-1_1rc1old
Jeremias Maerki 12 years ago
parent
commit
61bbd77c1e
2 changed files with 53 additions and 38 deletions
  1. 49
    38
      src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
  2. 4
    0
      status.xml

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

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


/**
@@ -469,9 +470,9 @@ public class TTFSubSetFile extends TTFFile {
* Returns a List containing the glyph itself plus all glyphs
* that this composite glyph uses
*/
private List getIncludedGlyphs(FontFileReader in, int glyphOffset,
private List<Integer> getIncludedGlyphs(FontFileReader in, int glyphOffset,
Integer glyphIdx) throws IOException {
List ret = new java.util.ArrayList();
List<Integer> ret = new java.util.ArrayList<Integer>();
ret.add(glyphIdx);
int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset() + 10;
Integer compositeIdx = null;
@@ -479,7 +480,7 @@ public class TTFSubSetFile extends TTFFile {
boolean moreComposites = true;
while (moreComposites) {
flags = in.readTTFUShort(offset);
compositeIdx = new Integer(in.readTTFUShort(offset + 2));
compositeIdx = Integer.valueOf(in.readTTFUShort(offset + 2));
ret.add(compositeIdx);

offset += 4;
@@ -509,15 +510,28 @@ public class TTFSubSetFile extends TTFFile {
}


/**
* We need to remember which composites were already remapped because the value to be
* remapped is being read from the TTF file and being replaced right there. Doing this
* twice would create a bad map the second time.
*/
private Set<Long> remappedComposites = null;

/**
* Rewrite all compositepointers in glyphindex glyphIdx
*
*/
private void remapComposite(FontFileReader in, Map glyphs,
int glyphOffset,
private void remapComposite(FontFileReader in, Map<Integer, Integer> glyphs,
long glyphOffset,
Integer glyphIdx) throws IOException {
int offset = glyphOffset + (int)mtxTab[glyphIdx.intValue()].getOffset()
+ 10;
if (remappedComposites == null) {
remappedComposites = new java.util.HashSet<Long>();
}
TTFMtxEntry mtxEntry = mtxTab[glyphIdx.intValue()];
long offset = glyphOffset + mtxEntry.getOffset() + 10;
if (remappedComposites.contains(offset)) {
return;
}
remappedComposites.add(offset);

Integer compositeIdx = null;
int flags = 0;
@@ -525,8 +539,8 @@ public class TTFSubSetFile extends TTFFile {

while (moreComposites) {
flags = in.readTTFUShort(offset);
compositeIdx = new Integer(in.readTTFUShort(offset + 2));
Integer newIdx = (Integer)glyphs.get(compositeIdx);
compositeIdx = Integer.valueOf(in.readTTFUShort(offset + 2));
Integer newIdx = glyphs.get(compositeIdx);
if (newIdx == null) {
// This errormessage would look much better
// if the fontname was printed to
@@ -538,7 +552,7 @@ public class TTFSubSetFile extends TTFFile {
continue;
}

in.writeTTFUShort(offset + 2, newIdx.intValue());
in.writeTTFUShort((int)(offset + 2), newIdx.intValue());

offset += 4;

@@ -572,40 +586,41 @@ public class TTFSubSetFile extends TTFFile {
* mapping
*/
private void scanGlyphs(FontFileReader in,
Map glyphs) throws IOException {
TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf");
Map newComposites = null;
Map allComposites = new java.util.HashMap();
Map<Integer, Integer> glyphs) throws IOException {
TTFDirTabEntry glyfTable = (TTFDirTabEntry)dirTabs.get("glyf");
Map<Integer, Integer> newComposites = null;
Set<Integer> allComposites = new java.util.HashSet<Integer>();

int newIndex = glyphs.size();

if (entry != null) {
if (glyfTable != null) {
while (newComposites == null || newComposites.size() > 0) {
// Inefficient to iterate through all glyphs
newComposites = new java.util.HashMap();
newComposites = new java.util.HashMap<Integer, Integer>();

Iterator e = glyphs.keySet().iterator();
while (e.hasNext()) {
Integer origIndex = (Integer)e.next();

if (in.readTTFShort(entry.getOffset()
+ mtxTab[origIndex.intValue()].getOffset()) < 0) {
for (int origIndex : glyphs.keySet()) {
short numberOfContours = in.readTTFShort(glyfTable.getOffset()
+ mtxTab[origIndex].getOffset());
if (numberOfContours < 0) {
// origIndex is a composite glyph
allComposites.put(origIndex, glyphs.get(origIndex));
List composites
= getIncludedGlyphs(in, (int)entry.getOffset(),
allComposites.add(origIndex);
List<Integer> composites
= getIncludedGlyphs(in, (int)glyfTable.getOffset(),
origIndex);

if (log.isTraceEnabled()) {
log.trace("Glyph " + origIndex
+ " is a composite glyph using the following glyphs: "
+ composites);
}

// Iterate through all composites pointed to
// by this composite and check if they exists
// in the glyphs map, add them if not.
Iterator cps = composites.iterator();
while (cps.hasNext()) {
Integer cIdx = (Integer)cps.next();
for (int cIdx : composites) {
if (glyphs.get(cIdx) == null
&& newComposites.get(cIdx) == null) {
newComposites.put(cIdx,
new Integer(newIndex));
newComposites.put(cIdx, newIndex);
newIndex++;
}
}
@@ -613,18 +628,14 @@ public class TTFSubSetFile extends TTFFile {
}

// Add composites to glyphs
Iterator m = newComposites.keySet().iterator();
while (m.hasNext()) {
Integer im = (Integer)m.next();
for (int im : newComposites.keySet()) {
glyphs.put(im, newComposites.get(im));
}
}

// Iterate through all composites to remap their composite index
Iterator ce = allComposites.keySet().iterator();
while (ce.hasNext()) {
remapComposite(in, glyphs, (int)entry.getOffset(),
(Integer)ce.next());
for (int glyphIdx : allComposites) {
remapComposite(in, glyphs, glyfTable.getOffset(), glyphIdx);
}

} else {

+ 4
- 0
status.xml View File

@@ -60,6 +60,10 @@
documents. Example: the fix of marks layering will be such a case when it's done.
-->
<release version="FOP Trunk" date="TBD">
<action context="Fonts" dev="JM" type="fix">
Fixed a bug in TTF subsetting where a composite glyph could get
remapped more than once resulting in garbled character.
</action>
<action context="Fonts" dev="JM" type="fix" fixes-bug="50605">
Fixed a number of bugs concerning Type 1 and other single-byte fonts
(glyph width mismatches and overlapping characters).

Loading…
Cancel
Save