Last active
November 25, 2025 01:29
-
-
Save samdphillips/c60dec4b3b58b6d708728024188d669c to your computer and use it in GitHub Desktop.
Fran Sans (https://emilysneddon.com/fran-sans-essay) in Rhombus pict form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #lang rhombus/static/and_meta | |
| import: | |
| draw | |
| pict open | |
| space.enforest path: | |
| space_path p/path | |
| macro_definer macro | |
| meta_namespace path_meta: | |
| parse_syntax_class Parsed | |
| parsed_packer pack | |
| parsed_unpacker unpack | |
| expr.macro '«path '$(e :: path_meta.Parsed)'»': | |
| def '[$cmd, ...]' = path_meta.unpack(e) | |
| def p = Syntax.make_temp_id() | |
| def body = '$p . $cmd; ...' | |
| 'block: | |
| def $p = draw.Path() | |
| $body | |
| $p :~ draw.Path' | |
| path.macro '$a #%juxtapose $b': | |
| def '[$left, ...]' = path_meta.unpack(a) | |
| def '[$right, ...]' = path_meta.unpack(b) | |
| path_meta.pack('[$left, ..., $right, ...]') | |
| path.macro 'M $a $b': | |
| path_meta.pack('[move_to([$a, $b])]') | |
| path.macro 'L $a $b': | |
| path_meta.pack('[line_to([$a, $b])]') | |
| path.macro 'C $a $b $c $d $e $f': | |
| path_meta.pack('[curve_to([$a, $b], [$c, $d], [$e, $f])]') | |
| path.macro 'Z': | |
| path_meta.pack('[close()]') | |
| def uc1: | |
| path 'M 0 0 L 50 0 C 50 0 0 0 0 50 Z' | |
| def uc2: | |
| path 'M 50 0 C 50 0 0 0 0 50 L 50 50 Z' | |
| def solid: | |
| path 'M 0 0 L 0 50 L 50 50 L 50 0 Z' | |
| def x0: | |
| path 'M 0 50 L 0 0 L 25 25 Z' | |
| def x1: | |
| path 'M 0 0 L 50 0 L 25 25 Z' | |
| def x2: | |
| path 'M 50 0 L 50 50 L 25 25 Z' | |
| def x3: | |
| path 'M 50 50 L 0 50 L 25 25 Z' | |
| def z0: | |
| path 'M 0 0 L 50 0 L 0 50 Z' | |
| def z1: | |
| path 'M 0 50 L 50 50 L 50 0 Z' | |
| def vl00: | |
| path 'M 0 0 L 25 50 L 0 50 Z' | |
| def vl01: | |
| path 'M 0 0 L 50 0 L 50 50 L 25 50 Z' | |
| def vl10: | |
| path 'M 0 0 C 0 50 50 50 50 50 L 0 50 Z' | |
| def vl11: | |
| path 'M 0 0 C 0 50 50 50 50 50 L 25 0 Z' | |
| def vl12: | |
| path 'M 25 0 L 50 0 L 50 50 Z' | |
| // blue (more BART like) | |
| // def bcolor = draw.Color(27, 143, 179) | |
| // yellow (closert to Muni display) | |
| def bcolor = draw.Color(228, 232, 16) | |
| // glow from panel | |
| def bg_color :~ draw.Color = draw.Color(78, 6, 1) | |
| //def pcolor = bcolor | |
| def pcolor = Color(0, 0, 0, 0.1) | |
| def brush = draw.Brush(~color: bcolor) | |
| def pen = draw.Pen(~color: pcolor) | |
| fun segment(path) :~ Pict: | |
| fun do_draw(dc :~ draw.DC, dx :~ Real, dy :~ Real): | |
| dc.save_and_restore: | |
| dc.brush := brush | |
| dc.pen := pen | |
| dc.path(~dx: dx, ~dy: dy, path) | |
| dc(do_draw, ~width: 50, ~height: 50) | |
| def s00_0 = segment(uc1) | |
| def s00_1 = segment(uc2) | |
| def s10_0 = segment(solid) | |
| def s20_0 = s00_1.hflip() | |
| def s20_1 = s00_0.hflip() | |
| def s01_0 = s10_0 | |
| def s11_0 = segment(x0) | |
| def s11_1 = segment(x1) | |
| def s11_2 = segment(x2) | |
| def s11_3 = segment(x3) | |
| def s21_0 = segment(z0) | |
| def s21_1 = segment(z1) | |
| def s02_0 = segment(x0) | |
| def s02_1 = segment(x1) | |
| def s02_2 = segment(x2) | |
| def s02_3 = segment(x3) | |
| def s03_0 = segment(vl00) | |
| def s03_1 = segment(vl01) | |
| def s13_0 = segment(x0) | |
| def s13_1 = segment(x1) | |
| def s13_2 = segment(x2) | |
| def s13_3 = segment(x3) | |
| def s23_0 = s03_1.hflip() | |
| def s23_1 = s03_0.hflip() | |
| def s04_0 = segment(vl10) | |
| def s04_1 = segment(vl11) | |
| def s04_2 = segment(vl12) | |
| def s14_0 = s10_0 | |
| def s24_0 = s04_2.hflip() | |
| def s24_1 = s04_1.hflip() | |
| def s24_2 = s04_0.hflip() | |
| operator (p ? v) :~ Pict: | |
| ~weaker_than bits.(?) | |
| if v | p | blank(50) | |
| defn.macro 'cell $(name :: Identifier): [$(v :: Identifier), ...]': | |
| let [n, ...] = [(each 0..Syntax.unwrap_sequence('$v; ...').length()), ...] | |
| 'fun $name(x :~ Nat) :~ Pict: | |
| overlay($v ? x bits.(?) $n, ...)' | |
| defn.macro 'row $(name :: Identifier): | |
| $(c0 :: Identifier) $(c1 :: Identifier) $(c2 :: Identifier)': | |
| let [n, ...] = [8, 4, 0] | |
| let [c, ...] = [c0, c1, c2] | |
| 'fun $name(x :~ Nat): | |
| beside($c(x bits.(>>) $n bits.and 0xf), ...)' | |
| cell s00: [s00_0, s00_1] | |
| cell s10: [s10_0] | |
| cell s20: [s20_0, s20_1] | |
| row s0: s00 s10 s20 | |
| cell s01: [s01_0] | |
| cell s11: [s11_0, s11_1, s11_2, s11_3] | |
| cell s21: [s21_0, s21_1] | |
| row s1: s01 s11 s21 | |
| cell s02: [s02_0, s02_1, s02_2, s02_3] | |
| cell s12: [s02_0, s02_1, s02_2, s02_3] | |
| cell s22: [s02_0, s02_1, s02_2, s02_3] | |
| row s2: s02 s12 s22 | |
| cell s03: [s03_0, s03_1] | |
| cell s13: [s13_0, s13_1, s13_2, s13_3] | |
| cell s23: [s23_0, s23_1] | |
| row s3: s03 s13 s23 | |
| cell s04: [s04_0, s04_1, s04_2] | |
| cell s14: [s14_0] | |
| cell s24: [s24_0, s24_1, s24_2] | |
| row s4: s04 s14 s24 | |
| fun display(a, b, c, d, e) :~ Pict: | |
| def [p, ...] = [s0, s1, s2, s3, s4] | |
| def [n, ...] = [a, b, c, d, e] | |
| stack(p(n), ...) | |
| fun display_line(s :: String) :~ Pict: | |
| def glyphs: | |
| for List (c: s): | |
| def g: | |
| match letters.get(c, #false) | |
| | #false: blank(~width: 3 * 50, ~height: 5 * 50) | |
| | vs: display(&vs) | |
| rectangle(~around: g, ~fill: bg_color) | |
| beside(~sep: 15, &glyphs) | |
| def letters: | |
| { | |
| Char"A": [0x2f1, 0xf0f, 0xfff, 0xf0f, 0xf0f], | |
| Char"B": [0x3f1, 0xf0f, 0xffb, 0xf0f, 0xff3], | |
| Char"C": [0x2f1, 0xf00, 0xf00, 0xf00, 0x6f3], | |
| Char"D": [0x311, 0x103, 0xf0f, 0x303, 0x713], | |
| Char"E": [0x313, 0x100, 0xff0, 0x300, 0x717], | |
| Char"F": [0x313, 0x100, 0xff0, 0x300, 0x700], | |
| Char"G": [0x211, 0x100, 0xf4f, 0x303, 0x613], | |
| Char"H": [0x303, 0x103, 0xfff, 0x303, 0x707], | |
| Char"I": [0x010, 0x0f0, 0x0f0, 0x0f0, 0x010], | |
| Char"J": [0x003, 0x003, 0x00f, 0x303, 0x613], | |
| Char"K": [0x303, 0x1c1, 0xff9, 0x303, 0x707], | |
| Char"L": [0x300, 0x100, 0xf00, 0x300, 0x717], | |
| Char"M": [0x303, 0x1d3, 0xf2f, 0x303, 0x707], | |
| Char"N": [0x303, 0x193, 0xfff, 0x363, 0x707], | |
| Char"O": [0x211, 0x103, 0xf0f, 0x303, 0x613], | |
| Char"P": [0x211, 0x103, 0xff3, 0x300, 0x700], | |
| Char"Q": [0x211, 0x103, 0xf0f, 0x36f, 0x610], | |
| Char"R": [0x311, 0x103, 0xffb, 0x303, 0x707], | |
| Char"S": [0x211, 0x100, 0x6f9, 0x003, 0x613], | |
| Char"T": [0x313, 0x0f0, 0x0f0, 0x0f0, 0x010], | |
| Char"U": [0x303, 0x103, 0xf0f, 0x303, 0x613], | |
| Char"V": [0x303, 0x103, 0xf0f, 0x2f1, 0x411], | |
| Char"W": [0x303, 0x103, 0xf8f, 0x373, 0x603], | |
| Char"X": [0x303, 0x103, 0xefb, 0x303, 0x707], | |
| Char"Y": [0x303, 0x103, 0x6f3, 0x0f0, 0x010], | |
| Char"Z": [0x313, 0x0c1, 0xc30, 0x300, 0x717], | |
| } | |
| fun frame(p) :~ Pict: | |
| rectangle(~around: p, ~fill: "black") | |
| frame(stack(~sep:15, | |
| display_line(" JUDAH "), | |
| display_line("OCEAN BEACH"))).scale(1/3) | |
| frame(display_line("EMBARCADERO")).scale(1/2) | |
| frame(stack(~sep:15, | |
| display_line(" OCEAN VIEW "), | |
| display_line("SAN JOSE AVE"))).scale(1/3) | |
| frame(stack(~sep:15, | |
| display_line("ABCDEFGHIJ"), | |
| display_line("KLMNOPQRST"), | |
| display_line(" UVWXYZ "))).scale(1/2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment