Skip to content

Commit b15756b

Browse files
authored
Merge pull request #82 from dummy-index/feature/addspecglyph
Add .notdef glyph, etc. / dedicated glyph for U+0075
2 parents 56cb411 + 1f320f2 commit b15756b

13 files changed

Lines changed: 1592 additions & 984 deletions

xkcd-script/font/xkcd-script.otf

18.6 KB
Binary file not shown.

xkcd-script/font/xkcd-script.sfd

Lines changed: 1517 additions & 981 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

xkcd-script/font/xkcd-script.ttf

3.13 KB
Binary file not shown.

xkcd-script/font/xkcd-script.woff

5.36 KB
Binary file not shown.
12.4 KB
Loading
9.56 KB
Loading

xkcd-script/generator/pt4_additional_sources.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ def extract_symbol(arr, y0, y1, x0, x1, name, exclude=None):
154154

155155
# Each entry is (output_name, source_filename_stem).
156156
EXTRAS = [
157+
('notdef', '1913_i_2x__notdef'), # .notdef fallback glyph source
158+
('square', '2251_alignment_chart_2x__square'), # □ U+25A1 source
157159
('eszett', 'eszett'), # ß U+00DF / ẞ U+1E9E source
158160
('lambda', '1145_sky_color_2x__lambda'), # λ U+03BB source
159161
('tau', '2520_symbols_2x__tau'), # τ U+03C4 source

xkcd-script/generator/pt5_svg_to_font.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ def charname(char):
317317
c = font.createMappedChar(32)
318318
c.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
# ---------------------------------------------------------------------------

xkcd-script/generator/pt6_derived_chars.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,33 @@ def _accented(cp, base_name, mark_name, gap=20, x_adj=0):
212212
# Glyph aliases and re-uses
213213
# ---------------------------------------------------------------------------
214214

215+
# U+20DE COMBINING ENCLOSING SQUARE — zero-width mark sized and positioned to
216+
# enclose '?' with a small margin. GPOS would be needed for full generality.
217+
_sq = font[0x25A1]
218+
_sq_bb = _sq.boundingBox()
219+
_sq_cx = (_sq_bb[0] + _sq_bb[2]) / 2
220+
_sq_h = _sq_bb[3] - _sq_bb[1] # sq_bb[1] == 0 after baseline snap
221+
_q_bb = font[ord('?')].boundingBox()
222+
_q_adv = font[ord('?')].width
223+
_margin = 20
224+
_scale_y = (_q_bb[3] - _q_bb[1] + 2 * _margin) / _sq_h
225+
_x_offset = -_q_adv / 2 - _sq_cx
226+
_y_offset = _q_bb[1] - _margin
227+
c = font.createMappedChar(0x20DE)
228+
c.addReference(_sq.glyphname, psMat.compose(
229+
psMat.scale(1, _scale_y),
230+
psMat.translate(_x_offset, _y_offset),
231+
))
232+
c.width = 0
233+
215234
# Vertical pipe: re-use the I glyph (same stroke, same weight).
235+
c = font.createChar(-1, 'I.sansserif')
236+
c.addReference('I')
237+
c.width = font['I'].width
216238
pipe = font.createMappedChar(ord('|'))
217239
pipe.clear()
218-
pipe.addReference('I')
219-
pipe.width = font['I'].width
240+
pipe.addReference('I.sansserif', psMat.compose(psMat.scale(1, 1.3), psMat.translate(0, -0.2 * font.ascent)))
241+
pipe.width = font['I.sansserif'].width
220242

221243

222244

-25 Bytes
Loading

0 commit comments

Comments
 (0)