11// @ts -expect-error ts being silly
2- import { PDFFont } from '@react-pdf/pdfkit' ;
2+ import PDFDocument from '@react-pdf/pdfkit' ;
33import * as fontkit from 'fontkit' ;
44import { Font } from './types' ;
55
@@ -18,6 +18,18 @@ export const STANDARD_FONTS = [
1818 'Times-BoldItalic' ,
1919] ;
2020
21+ // Create a shared lightweight document for accessing standard font instances.
22+ // Standard fonts are created once and cached, so this is negligible overhead.
23+ let _sharedDoc : any = null ;
24+
25+ const openStandardFont = ( src : string ) => {
26+ if ( ! _sharedDoc ) {
27+ _sharedDoc = new PDFDocument ( { autoFirstPage : false } ) ;
28+ }
29+ _sharedDoc . font ( src ) ;
30+ return _sharedDoc . _font ;
31+ } ;
32+
2133class StandardFont implements Font {
2234 name : string ;
2335 src : any ;
@@ -57,11 +69,21 @@ class StandardFont implements Font {
5769 this . numGlyphs = 0 ;
5870 this . characterSet = [ ] ;
5971
60- this . src = PDFFont . open ( null , src ) ;
72+ this . src = openStandardFont ( src ) ;
6173 }
6274
6375 encode ( str : string ) {
64- return this . src . encode ( str ) ;
76+ const [ encoded , positions ] = this . src . encode ( str ) ;
77+
78+ // Soft hyphens (U+00AD) should have zero width for line breaking purposes.
79+ // Upstream pdfkit maps them to 'hyphen' in AFM data, so we override here.
80+ for ( let i = 0 ; i < str . length ; i ++ ) {
81+ if ( str . charCodeAt ( i ) === 0x00ad ) {
82+ positions [ i ] . advanceWidth = 0 ;
83+ }
84+ }
85+
86+ return [ encoded , positions ] ;
6587 }
6688
6789 layout ( str : string ) {
0 commit comments