import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* 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;
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;
}
+ /**
+ * 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;
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
continue;
}
- in.writeTTFUShort(offset + 2, newIdx.intValue());
+ in.writeTTFUShort((int)(offset + 2), newIdx.intValue());
offset += 4;
* 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++;
}
}
}
// 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 {