@@ -317,6 +317,11 @@ def charname(char):
317317c = font .createMappedChar (32 )
318318c .width = 256
319319
320+ c = font .createChar (0x0000 , '.null' ) # U+0000: null, zero-width; required by OpenType
321+ c .width = 256
322+ c = font .createChar (0x000D , 'nonmarkingreturn' ) # U+000D: carriage return, zero-width; required by OpenType
323+ c .width = 256
324+
320325
321326# ---------------------------------------------------------------------------
322327# Glyphs imported from xkcd comic images
@@ -391,6 +396,23 @@ def _import_comic_glyph(font, name, svg_path, target_top, weight_delta=0):
391396 return g
392397
393398
399+ # .notdef is shown for any codepoint the font doesn't cover; OpenType requires it.
400+ # Hand-drawn source: xkcd #1913 (I), a sketchy question-mark-in-a-box.
401+ _notdef_svg = os .path .join (_COMIC_CHARS_DIR , 'notdef.svg' )
402+ _notdef_src = _import_comic_glyph (font , 'notdef' , _notdef_svg , target_top = font .ascent , weight_delta = 20 )
403+ _bb = _notdef_src .boundingBox ()
404+ _notdef_src .transform (psMat .translate (0 , - _bb [1 ]))
405+ _bb = _notdef_src .boundingBox ()
406+ if _bb [3 ] > 0 :
407+ _notdef_src .transform (psMat .scale (font .ascent / _bb [3 ]))
408+ _notdef_src .width = int (round (_notdef_src .boundingBox ()[2 ] + 20 ))
409+ c = font .createChar (- 1 , '.notdef' )
410+ c .clear ()
411+ for _cont in _notdef_src .foreground :
412+ c .foreground += _cont
413+ c .width = _notdef_src .width
414+
415+
394416# Greek letters vectorised by pt4 from xkcd comic images.
395417# Each entry: (svg_name, unicode_cp, ref_char_for_height, baseline_snap)
396418# baseline_snap=True → translate so bb[1]=0 (letters that sit on the baseline).
@@ -592,6 +614,23 @@ def _import_comic_glyph(font, name, svg_path, target_top, weight_delta=0):
592614 _ch .width = _g .width
593615
594616
617+ # □ U+25A1 WHITE SQUARE — hand-drawn source from extras/square.png.
618+ _square_svg = os .path .join (_COMIC_CHARS_DIR , 'square.svg' )
619+ _target_top_sq = font ['H' ].boundingBox ()[3 ]
620+ _square_src = _import_comic_glyph (font , 'square' , _square_svg , target_top = _target_top_sq , weight_delta = 45 )
621+ _bb = _square_src .boundingBox ()
622+ _square_src .transform (psMat .translate (0 , - _bb [1 ]))
623+ _bb = _square_src .boundingBox ()
624+ if _bb [3 ] > 0 :
625+ _square_src .transform (psMat .scale (_target_top_sq / _bb [3 ]))
626+ _square_src .width = int (round (_square_src .boundingBox ()[2 ] + 20 ))
627+ _ch = font .createMappedChar (0x25A1 )
628+ _ch .clear ()
629+ for _cont in _square_src .foreground :
630+ _ch .foreground += _cont
631+ _ch .width = _square_src .width
632+
633+
595634# ---------------------------------------------------------------------------
596635# Save
597636# ---------------------------------------------------------------------------
0 commit comments