From 274cec4a6dc9e3dd9c39c6c22b9959c600965749 Mon Sep 17 00:00:00 2001 From: Kakhnovich Raman Date: Thu, 20 Aug 2026 12:20:19 +0300 Subject: [PATCH 1/2] Add methods to get Ascent/Descent from CharProc for Type3 fonts --- .../verapdf/pd/font/type3/PDType3Font.java | 26 +++++++++++++++++++ .../pd/font/type3/Type3CharProcParser.java | 18 +++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java b/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java index d4f80ac5..1d625433 100644 --- a/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java +++ b/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java @@ -157,4 +157,30 @@ public float getWidthFromProgram(int code) { public boolean glyphIsPresent(int code) { return containsCharString(code); } + + public float getAscentFromProgram(int code) { + COSObject charProc = getCharProc(code); + if (charProc.getType() == COSObjType.COS_STREAM) { + try (Type3CharProcParser parser = new Type3CharProcParser(charProc.getData(COSStream.FilterFlags.DECODE))) { + parser.parse(); + return (float) parser.getAscent(); + } catch (IOException e) { + LOGGER.log(Level.FINE, "Can't get ascent from type 3 char proc"); + } + } + return 0; + } + + public float getDescentFromProgram(int code) { + COSObject charProc = getCharProc(code); + if (charProc.getType() == COSObjType.COS_STREAM) { + try (Type3CharProcParser parser = new Type3CharProcParser(charProc.getData(COSStream.FilterFlags.DECODE))) { + parser.parse(); + return (float) parser.getDescent(); + } catch (IOException e) { + LOGGER.log(Level.FINE, "Can't get descent from type 3 char proc"); + } + } + return 0; + } } diff --git a/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java b/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java index 8efa183f..b5ce0cba 100644 --- a/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java +++ b/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java @@ -34,6 +34,8 @@ public class Type3CharProcParser extends NotSeekableBaseParser { private double width = -1; + private double ascent = 0; + private double descent = 0; private static final String D0 = "d0"; private static final String D1 = "d1"; @@ -64,12 +66,20 @@ public void parse() throws IOException { } // else ll_x nextToken(); // ll_y + if (getToken().type == Token.Type.TT_INTEGER || getToken().type == Token.Type.TT_REAL) { + this.descent = getToken().real; + } nextToken(); // ur_x nextToken(); // ur_y + if (getToken().type == Token.Type.TT_INTEGER || getToken().type == Token.Type.TT_REAL) { + this.ascent = getToken().real; + } nextToken(); // d1 if (getToken().type != Token.Type.TT_KEYWORD || !getToken().getValue().equals(D1)) { // stream is corrupted this.width = -1; + this.ascent = 0; + this.descent = 0; throw new IOException("Can't parse type 3 char proc"); } } @@ -81,4 +91,12 @@ public void parse() throws IOException { public double getWidth() { return width; } + + public double getAscent() { + return ascent; + } + + public double getDescent() { + return descent; + } } From b8b4b268e22219847ad172e31f09fb123030c5ba Mon Sep 17 00:00:00 2001 From: Kakhnovich Raman Date: Thu, 20 Aug 2026 13:57:44 +0300 Subject: [PATCH 2/2] Update default value to null --- .../java/org/verapdf/pd/font/type3/PDType3Font.java | 12 ++++++------ .../verapdf/pd/font/type3/Type3CharProcParser.java | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java b/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java index 1d625433..6d48b4f6 100644 --- a/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java +++ b/src/main/java/org/verapdf/pd/font/type3/PDType3Font.java @@ -158,29 +158,29 @@ public boolean glyphIsPresent(int code) { return containsCharString(code); } - public float getAscentFromProgram(int code) { + public Double getAscentFromProgram(int code) { COSObject charProc = getCharProc(code); if (charProc.getType() == COSObjType.COS_STREAM) { try (Type3CharProcParser parser = new Type3CharProcParser(charProc.getData(COSStream.FilterFlags.DECODE))) { parser.parse(); - return (float) parser.getAscent(); + return parser.getAscent(); } catch (IOException e) { LOGGER.log(Level.FINE, "Can't get ascent from type 3 char proc"); } } - return 0; + return null; } - public float getDescentFromProgram(int code) { + public Double getDescentFromProgram(int code) { COSObject charProc = getCharProc(code); if (charProc.getType() == COSObjType.COS_STREAM) { try (Type3CharProcParser parser = new Type3CharProcParser(charProc.getData(COSStream.FilterFlags.DECODE))) { parser.parse(); - return (float) parser.getDescent(); + return parser.getDescent(); } catch (IOException e) { LOGGER.log(Level.FINE, "Can't get descent from type 3 char proc"); } } - return 0; + return null; } } diff --git a/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java b/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java index b5ce0cba..8e711b57 100644 --- a/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java +++ b/src/main/java/org/verapdf/pd/font/type3/Type3CharProcParser.java @@ -34,8 +34,8 @@ public class Type3CharProcParser extends NotSeekableBaseParser { private double width = -1; - private double ascent = 0; - private double descent = 0; + private Double ascent; + private Double descent; private static final String D0 = "d0"; private static final String D1 = "d1"; @@ -78,8 +78,8 @@ public void parse() throws IOException { if (getToken().type != Token.Type.TT_KEYWORD || !getToken().getValue().equals(D1)) { // stream is corrupted this.width = -1; - this.ascent = 0; - this.descent = 0; + this.ascent = null; + this.descent = null; throw new IOException("Can't parse type 3 char proc"); } }