From b9acbd27f1942c56a5c5a8b1f61d30adaab37687 Mon Sep 17 00:00:00 2001 From: Patrick Corless Date: Tue, 20 Apr 2021 23:29:54 -0600 Subject: [PATCH] GH-182 potential fix to derive ascent/descent from bbox if not set from font descriptor. --- .../icepdf/core/pobjects/fonts/FontFile.java | 6 +-- .../core/pobjects/fonts/zfont/SimpleFont.java | 2 +- .../fonts/zfont/fontFiles/ZFontTrueType.java | 2 + .../fonts/zfont/fontFiles/ZFontType0.java | 2 + .../fonts/zfont/fontFiles/ZFontType1.java | 1 + .../fonts/zfont/fontFiles/ZFontType1C.java | 2 + .../fonts/zfont/fontFiles/ZFontType2.java | 2 + .../fonts/zfont/fontFiles/ZFontType3.java | 23 +--------- .../fonts/zfont/fontFiles/ZSimpleFont.java | 43 +++++++++++++------ .../core/pobjects/graphics/TextSprite.java | 4 +- 10 files changed, 46 insertions(+), 41 deletions(-) diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/FontFile.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/FontFile.java index df9880485..c988d71b8 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/FontFile.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/FontFile.java @@ -40,8 +40,6 @@ enum ByteEncoding { long LAYOUT_NONE = 0; - // todo do some refacotring of method name 'e' awlays seemed strange to me. - Point2D getAdvance(char ech); FontFile deriveFont(AffineTransform at); @@ -54,12 +52,12 @@ FontFile deriveFont(float[] widths, int firstCh, float missingWidth, FontFile deriveFont(Map widths, int firstCh, float missingWidth, float ascent, float descent, Rectangle2D bbox, char[] diff); + FontFile deriveFont(float pointSize); + boolean canDisplay(char ech); void setIsCid(); - FontFile deriveFont(float pointsize); - CMap getToUnicode(); String toUnicode(String displayText); diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/SimpleFont.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/SimpleFont.java index fba0a5de5..1de40753e 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/SimpleFont.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/SimpleFont.java @@ -140,7 +140,7 @@ protected void parseWidth() { font = font.deriveFont(newWidth, firstchar, missingWidth, ascent, descent, bbox, null); } // currently not using afm, instead using font's width table, seems more reliable - else if (afm != null && !isFontSubstitution) { + else if (afm != null) { font = font.deriveFont(afm.getWidths(), firstchar, missingWidth, ascent, descent, bbox, null); } } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java index d4a75be67..d2f42aad4 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java @@ -187,6 +187,7 @@ public FontFile deriveFont(float[] widths, int firstCh, float missingWidth, floa font.widths = widths; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -198,6 +199,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType0.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType0.java index 7a37663b6..c34ac21e9 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType0.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType0.java @@ -169,6 +169,7 @@ public FontFile deriveFont(float[] widths, int firstCh, float missingWidth, floa font.widths = widths; font.cMap = diff != null ? diff : font.cMap; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -181,6 +182,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1.java index 8ba55e63c..ba0f4cc2b 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1.java @@ -126,6 +126,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java index df7de6a19..292bf5992 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java @@ -98,6 +98,7 @@ public FontFile deriveFont(float[] widths, int firstCh, float missingWidth, floa font.widths = widths; font.cMap = diff != null ? diff : font.cMap; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -110,6 +111,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType2.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType2.java index 1fae578b9..013bb6085 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType2.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType2.java @@ -153,6 +153,7 @@ public FontFile deriveFont(float[] widths, int firstCh, float missingWidth, floa font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -164,6 +165,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.descent = descent; font.cMap = diff; font.bbox = bbox; + font.maxCharBounds = null; return font; } diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType3.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType3.java index 1184391cf..f6fed769f 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType3.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType3.java @@ -110,6 +110,7 @@ public FontFile deriveFont(float[] widths, int firstCh, float missingWidth, floa font.ascent = ascent; font.descent = descent; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -123,6 +124,7 @@ public FontFile deriveFont(Map widths, int firstCh, float missin font.ascent = ascent; font.descent = descent; font.bbox = bbox; + font.maxCharBounds = null; return font; } @@ -221,27 +223,6 @@ public Rectangle2D getMaxCharBounds() { return af.createTransformedShape(bBox.toJava2dCoordinates()).getBounds2D(); } - public Rectangle2D getCharBounds(char displayChar) { - Rectangle2D r = getMaxCharBounds(); - - String charName = encoding.getName(displayChar); - float width = 0f; - if (widths != null && displayChar - firstCh >= 0 && displayChar - firstCh < widths.length) { - width = widths[displayChar - firstCh]; - - } - - if (width == 0.0f) { - width = charWidths.get(charName).x; - } - - PRectangle charRect = charBBoxes.get(charName); - r.setRect(0.0, r.getY(), - width * size, - charRect.getHeight() * size); - return r; - } - /** *

Sets the horizontal displacement of this Type3 font for the specified * name. Like BBox this value must be set from inside the content parser as diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java index 7cf700e16..85859c64d 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java @@ -40,6 +40,7 @@ public abstract class ZSimpleFont implements FontFile { protected float ascent; protected float descent; protected Rectangle2D bbox = new Rectangle2D.Double(0.0, 0.0, 1.0, 1.0); + protected Rectangle2D maxCharBounds; // cid specific, todo new subclass if we get a few more? protected float defaultWidth; @@ -186,7 +187,10 @@ public Shape getOutline(String estr, float x, float y) { @Override public Rectangle2D getMaxCharBounds() { - return calculateBbox(bbox); + AffineTransform af = new AffineTransform(); + af.scale(size, -size); + af.concatenate(fontMatrix); + return af.createTransformedShape(bbox).getBounds2D(); } @Override @@ -225,12 +229,34 @@ public float getSize() { @Override public double getAscent() { - return ascent; + if (ascent != 0) { + return ascent * size; + } else { + if (maxCharBounds == null) { + maxCharBounds = getMaxCharBounds(); + } + return -maxCharBounds.getY(); + } + + } + + public double getHeight() { + if (maxCharBounds == null) { + maxCharBounds = getMaxCharBounds(); + } + return maxCharBounds.getHeight(); } + @Override public double getDescent() { - return descent; + if (descent != 0) { + return descent * size; + } else { + double height = getHeight(); + double ascent = getAscent(); + return height - ascent; + } } @Override @@ -309,6 +335,7 @@ protected void setPointSize(float pointSize) { fontTransform.concatenate(gsTransform); fontTransform.scale(pointSize, -pointSize); size = pointSize; + maxCharBounds = null; } protected char getCharDiff(char character) { @@ -319,16 +346,6 @@ protected char getCharDiff(char character) { } } - protected Rectangle2D calculateBbox(Rectangle2D bbox) { - if (bbox != null) { - AffineTransform af = new AffineTransform(); -// af.scale(size, size); - af.concatenate(fontMatrix); - return af.createTransformedShape(bbox).getBounds2D(); - } - return this.bbox; - } - protected AffineTransform convertFontMatrix(FontBoxFont fontBoxFont) { try { java.util.List matrix = fontBoxFont.getFontMatrix(); diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/graphics/TextSprite.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/graphics/TextSprite.java index 0242607b4..0425eeb54 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/graphics/TextSprite.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/graphics/TextSprite.java @@ -106,8 +106,8 @@ public GlyphText addText(String cid, String unicode, float x, float y, float wid // we can change the bounds of glyphBounds as this is what needs to be normalized // to page space // IMPORTANT: where working in Java Coordinates with any of the Font bounds - float descent = (float) font.getDescent() * font.getSize(); - float ascent = (float) font.getAscent() * font.getSize(); + float descent = (float) font.getDescent(); + float ascent = (float) font.getAscent(); float w = width; float h = ascent - descent; // width/height are kept unscaled for coords, w/h are scaled to get correct bounds w/h