Skip to content

Commit a7a29cd

Browse files
sangwoojinMaximPlusov
authored andcommitted
Do not scale TJ array adjustments by the Type 3 FontMatrix
A number in a TJ array is expressed in thousandths of a unit of text space (ISO 32000-1, 9.4.3). It is a text space quantity, not a glyph space one, so it must not be transformed by the font's FontMatrix. Since the FontMatrix scaling introduced in #733 is applied to the whole text-showing argument, the TJ adjustments are scaled by FontMatrix[0] as well. For every non-Type 3 font that factor is exactly 1/1000, so the result is unchanged. For a Type 3 font whose FontMatrix is not the conventional [0.001 0 0 0.001 0 0] the adjustments are off by the ratio between the two: with an identity FontMatrix they are 1000 times too large, which makes each glyph advance backwards and reverses the extracted reading order. Glyph widths keep using the FontMatrix, which is correct - those are glyph space values.
1 parent b1b438e commit a7a29cd

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

  • wcag-validation/src/main/java/org/verapdf/gf/model/factory/chunks

wcag-validation/src/main/java/org/verapdf/gf/model/factory/chunks/ChunkParser.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ public class ChunkParser {
6666
public static final String REPLACEMENT_CHARACTER_STRING = "\uFFFD";
6767
public static final Map<String, String> fontNameToFontFamilyMap = new HashMap<>();
6868

69+
/**
70+
* A number in a TJ array is expressed in thousandths of a unit of text space
71+
* (ISO 32000-1, 9.4.3). Unlike a glyph width, it is not a glyph space value,
72+
* so it is never scaled by the FontMatrix of a Type 3 font.
73+
*/
74+
private static final double TEXT_SPACE_UNIT = 1.0 / 1000.0;
75+
6976
private final Deque<GraphicsState> graphicsStateStack = new ArrayDeque<>();
7077
private final Stack<Long> markedContentStack = new Stack<>();
7178
private final Stack<Boolean> visibleContentStack = new Stack<Boolean>();
@@ -842,7 +849,7 @@ private TextPieces parseTextShowArgument(boolean isVertical, COSBase argument, d
842849
parseString(isVertical, (COSString) obj.getDirectBase(), textPieces, scalingFactor);
843850
} else if (obj.getType().isNumber()) {
844851
TextState textState = graphicsState.getTextState();
845-
textPieces.shiftCurrent(-obj.getReal() * scalingFactor * textState.getTextFontSize() *
852+
textPieces.shiftCurrent(-obj.getReal() * TEXT_SPACE_UNIT * textState.getTextFontSize() *
846853
(isVertical ? 1 : textState.getHorizontalScaling()));
847854
}
848855
}

0 commit comments

Comments
 (0)