Subject: | Patch for CAM::PDF::getStringWidth to handle Type0 fonts |
I needed to compute graphics state parameters (including text state) for PDF files with Type0 fonts. Here's a patch that works for me:
--- PDF.pm.bak Thu Aug 15 05:08:26 2013
+++ PDF.pm Fri Aug 24 15:11:36 2018
@@ -2263,6 +2263,55 @@
}
my $width = 0;
+
+ if ( $self-> getValue( $fontmetrics-> { Subtype }) eq 'Type0' ) {
+ my $cidf_node = ( $self-> getValue(
+ $fontmetrics-> { DescendantFonts }))-> [ 0 ];
+
+ unless ( exists $cidf_node-> { dw }) { # seen?
+ my $cidf = $self-> getValue( $cidf_node );
+
+ $cidf_node-> { dw } = exists $cidf-> { DW }
+ ? $self-> getValue( $cidf-> { DW })
+ : 1000;
+ $cidf_node-> { w } = {};
+
+ if ( exists $cidf-> { W }) {
+ my @w = @{ $self-> getValue( $cidf-> { W })};
+ my $i = 0;
+ my $c;
+ LOOP: {
+ $c = $self-> getValue( $w[ $i++ ]);
+ if ( $w[ $i ]{ type } eq 'number' ) {
+ $cidf_node-> { w }{ $_ } = $self-> getValue( $w[ $i ])
+ for $c .. $w[ $i++ ]{ value };
+ $i++
+ }
+ else {
+ $cidf_node-> { w }{ $c++ } = $_
+ for map { $self-> getValue( $_ )}
+ @{ $self-> getValue( $w[ $i++ ])}
+ }
+ redo LOOP if $i < $#w
+ }
+ }
+ }
+
+# Assume double-byte, Identity-H encoding;
+# also assume CIDToGIDMap is Identity.
+# $string is sequence of character codes as
+# argument to e.g. Tj operator -- NOT "utf-8" or
+# anything human readable.
+# All of the above fits my purposes perfectly.
+
+ for my $char ( unpack 'n*', $string ) {
+ $width += exists $cidf_node-> { w }{ $char }
+ ? $cidf_node-> { w }{ $char }
+ : $cidf_node-> { dw };
+ }
+ return $width / 1000;
+ }
+
if ($fontmetrics)
{
if ($fontmetrics->{Widths})