@@ -2236,6 +2236,20 @@ def encode_string(self, s, fonttype):
2236
2236
return s .encode ('cp1252' , 'replace' )
2237
2237
return s .encode ('utf-16be' , 'replace' )
2238
2238
2239
+ @staticmethod
2240
+ def _font_supports_char (fonttype , char ):
2241
+ """
2242
+ Returns True if the font is able to provided the char in a PDF
2243
+
2244
+ For a Type 3 font, this method returns True only for single-byte
2245
+ chars. For Type 42 fonts this method always returns True.
2246
+ """
2247
+ if fonttype == 3 :
2248
+ return ord (char ) <= 255
2249
+ if fonttype == 42 :
2250
+ return True
2251
+ raise NotImplementedError ()
2252
+
2239
2253
def draw_text (self , gc , x , y , s , prop , angle , ismath = False , mtext = None ):
2240
2254
# docstring inherited
2241
2255
@@ -2270,26 +2284,27 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
2270
2284
}
2271
2285
self .file ._annotations [- 1 ][1 ].append (link_annotation )
2272
2286
2273
- # If fonttype != 3 emit the whole string at once without manual
2274
- # kerning.
2275
- if fonttype != 3 :
2287
+ # If fonttype is neither 3 nor 42, emit the whole string at once
2288
+ # without manual kerning.
2289
+ if fonttype not in [ 3 , 42 ] :
2276
2290
self .file .output (Op .begin_text ,
2277
2291
self .file .fontName (prop ), fontsize , Op .selectfont )
2278
2292
self ._setup_textpos (x , y , angle )
2279
2293
self .file .output (self .encode_string (s , fonttype ),
2280
2294
Op .show , Op .end_text )
2281
2295
2282
- # There is no way to access multibyte characters of Type 3 fonts, as
2283
- # they cannot have a CIDMap. Therefore, in this case we break the
2284
- # string into chunks, where each chunk contains either a string of
2285
- # consecutive 1-byte characters or a single multibyte character.
2286
- # A sequence of 1-byte characters is broken into multiple chunks to
2287
- # adjust the kerning between adjacent chunks. Each chunk is emitted
2288
- # with a separate command: 1-byte characters use the regular text show
2289
- # command (TJ) with appropriate kerning between chunks, whereas
2290
- # multibyte characters use the XObject command (Do). (If using Type
2291
- # 42 fonts, all of this complication is avoided, but of course,
2292
- # subsetting those fonts is complex/hard to implement.)
2296
+ # A sequence of characters is broken into multiple chunks. The chunking
2297
+ # serves two purposes:
2298
+ # - For Type 3 fonts, there is no way to access multibyte characters,
2299
+ # as they cannot have a CIDMap. Therefore, in this case we break
2300
+ # the string into chunks, where each chunk contains either a string
2301
+ # of consecutive 1-byte characters or a single multibyte character.
2302
+ # - A sequence of 1-byte characters is split into chunks to allow for
2303
+ # kerning adjustments between consecutive chunks.
2304
+ #
2305
+ # Each chunk is emitted with a separate command: 1-byte characters use
2306
+ # the regular text show command (TJ) with appropriate kerning between
2307
+ # chunks, whereas multibyte characters use the XObject command (Do).
2293
2308
else :
2294
2309
# List of (start_x, [prev_kern, char, char, ...]), w/o zero kerns.
2295
2310
singlebyte_chunks = []
@@ -2298,7 +2313,7 @@ def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
2298
2313
prev_was_multibyte = True
2299
2314
for item in _text_helpers .layout (
2300
2315
s , font , kern_mode = KERNING_UNFITTED ):
2301
- if ord ( item .char ) <= 255 :
2316
+ if self . _font_supports_char ( fonttype , item .char ):
2302
2317
if prev_was_multibyte :
2303
2318
singlebyte_chunks .append ((item .x , []))
2304
2319
if item .prev_kern :
0 commit comments