nx_mailpiece.nx source
↩ module page · 356 lines · 18419 B
1// nx_mailpiece.nx -- PHYSICAL MAIL COMPOSITION (rung 2 of Nishi Mail to SOTA). Composes a print-ready
2// postcard as an RGB raster and writes it as PNG (preview + the exact bitmap the sovereign print path
3// nx_img_print -> PWG/URF -> IPP feeds to a real printer). NISHI-POSTCARD: 6x4in @300dpi = 1800x1200.
4// FRONT = greeting design (accent bleed + cream panel + centered title). BACK = USPS layout: message on
5// the left, a vertical divider, the recipient address block in the address zone on the right, a stamp
6// (indicia) box top-right, and the lower-right IMb barcode clear zone kept blank by construction.
7// Sovereign: pure integer raster ops + the sovereign 8x8 font; no 3rd party. Last-mile (print vs carrier)
8// is the next rung. Commands: postcard <front.png> <back.png> <greeting> <message> <recipient> <line1> <city> <region> <postal> ; argless = selftest.
9// expect_exit: 0 license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_font8x8.nx"
12import "nx_png_write.nx"
13const K_MAGIC_1800: i64 = 1800
14const K_MAGIC_1200: i64 = 1200
15const K_MAGIC_1080: i64 = 1080
16const K_MAGIC_1040: i64 = 1040
17const K_MAGIC_1560: i64 = 1560
18const K_MAGIC_1720: i64 = 1720
19const K_MAGIC_1587: i64 = 1587
20const K_MAGIC_2550: i64 = 2550
21const K_MAGIC_3300: i64 = 3300
22const K_MAGIC_1099: i64 = 1099
23const K_MAGIC_1102: i64 = 1102
24const K_MAGIC_2199: i64 = 2199
25const K_MAGIC_2202: i64 = 2202
26const K_MAGIC_1250: i64 = 1250
27const K_MAGIC_1380: i64 = 1380
28const K_MAGIC_1950: i64 = 1950
29const K_MAGIC_2500: i64 = 2500
30const K_MAGIC_2590: i64 = 2590
31const K_MAGIC_3140: i64 = 3140
32const K_MAGIC_2850: i64 = 2850
33const K_MAGIC_1238: i64 = 1238
34const K_MAGIC_2620: i64 = 2620
35const K_MAGIC_2760: i64 = 2760
36const K_MAGIC_2640: i64 = 2640
37const K_MAGIC_1612: i64 = 1612
38const K_MAGIC_1088: i64 = 1088
39const K_MAGIC_3150: i64 = 3150
40const K_MAGIC_2175: i64 = 2175
41const K_MAGIC_1575: i64 = 1575
42const K_MAGIC_2050: i64 = 2050
43const K_MAGIC_1300: i64 = 1300
44const K_MAGIC_1890: i64 = 1890
45
46func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
47func p(s: *u8) -> i64 { sys_write(1, s, slen(s)); return 0 }
48func pn(v: i64) -> i64 {
49 var m: i64 = v; if m < 0 { p("-" as *u8); m = 0 - m }
50 let t: *u8 = sys_mmap(24); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
51 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
52 let o: *u8 = sys_mmap(24); var i: i64 = 0; while i < k { o[i] = t[k-1-i]; i = i + 1 } sys_write(1, o, k); return 0
53}
54func seq(a: *u8, b: *u8) -> i64 {
55 var i: i64 = 0
56 while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 }
57 if b[i] != (0 as u8) { return 0 }
58 return 1
59}
60
61// ---- raster primitives (canvas = W*H*3 RGB, origin top-left) ----
62func set_px(rgb: *u8, W: i64, H: i64, x: i64, y: i64, r: i64, g: i64, b: i64) -> i64 {
63 if x < 0 { return 0 }
64 if y < 0 { return 0 }
65 if x >= W { return 0 }
66 if y >= H { return 0 }
67 let o: i64 = (y * W + x) * 3
68 rgb[o] = r as u8; rgb[o+1] = g as u8; rgb[o+2] = b as u8
69 return 0
70}
71func fill_rect(rgb: *u8, W: i64, H: i64, x0: i64, y0: i64, x1: i64, y1: i64, r: i64, g: i64, b: i64) -> i64 {
72 var y: i64 = y0
73 while y <= y1 { var x: i64 = x0; while x <= x1 { set_px(rgb, W, H, x, y, r, g, b); x = x + 1 } y = y + 1 }
74 return 0
75}
76func rect_outline(rgb: *u8, W: i64, H: i64, x0: i64, y0: i64, x1: i64, y1: i64, th: i64, r: i64, g: i64, b: i64) -> i64 {
77 fill_rect(rgb, W, H, x0, y0, x1, y0 + th, r, g, b)
78 fill_rect(rgb, W, H, x0, y1 - th, x1, y1, r, g, b)
79 fill_rect(rgb, W, H, x0, y0, x0 + th, y1, r, g, b)
80 fill_rect(rgb, W, H, x1 - th, y0, x1, y1, r, g, b)
81 return 0
82}
83// draw one 8x8 glyph scaled by sc; bit 0 (LSB) = leftmost column (per nx_font8x8)
84func draw_glyph(rgb: *u8, W: i64, H: i64, tbl: *u8, ch: i64, x: i64, y: i64, sc: i64, r: i64, g: i64, b: i64) -> i64 {
85 if ch < 32 { return 0 }
86 if ch > 126 { return 0 }
87 let base: i64 = (ch - 32) * 8
88 var row: i64 = 0
89 while row < 8 {
90 let bits: i64 = tbl[base + row] as i64
91 var col: i64 = 0
92 while col < 8 {
93 if ((bits >> col) & 1) == 1 {
94 var dy: i64 = 0
95 while dy < sc { var dx: i64 = 0; while dx < sc { set_px(rgb, W, H, x + col*sc + dx, y + row*sc + dy, r, g, b); dx = dx + 1 } dy = dy + 1 }
96 }
97 col = col + 1
98 }
99 row = row + 1
100 }
101 return 0
102}
103// draw a NUL-terminated string; per-char advance = 8*sc + sp; returns end x
104func draw_text(rgb: *u8, W: i64, H: i64, tbl: *u8, s: *u8, x: i64, y: i64, sc: i64, sp: i64, r: i64, g: i64, b: i64) -> i64 {
105 var i: i64 = 0
106 var cx: i64 = x
107 while s[i] != (0 as u8) { draw_glyph(rgb, W, H, tbl, s[i] as i64, cx, y, sc, r, g, b); cx = cx + 8*sc + sp; i = i + 1 }
108 return cx
109}
110// word-wrap a string inside [x, x+maxw]; returns final y
111func draw_wrap(rgb: *u8, W: i64, H: i64, tbl: *u8, s: *u8, x: i64, y: i64, sc: i64, maxw: i64, r: i64, g: i64, b: i64) -> i64 {
112 let cw: i64 = 8*sc + sc
113 let lh: i64 = 8*sc + sc*3
114 var cx: i64 = x
115 var cy: i64 = y
116 var i: i64 = 0
117 while s[i] != (0 as u8) {
118 var j: i64 = i
119 while s[j] != (0 as u8) { if s[j] == (32 as u8) { break } j = j + 1 }
120 let wl: i64 = j - i
121 if cx + wl*cw > x + maxw { cx = x; cy = cy + lh }
122 var k: i64 = i
123 while k < j { draw_glyph(rgb, W, H, tbl, s[k] as i64, cx, cy, sc, r, g, b); cx = cx + cw; k = k + 1 }
124 i = j
125 while s[i] == (32 as u8) { cx = cx + cw; i = i + 1 }
126 if cx > x + maxw { cx = x; cy = cy + lh }
127 }
128 return cy
129}
130func cpy(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i }
131func text_w(s: *u8, sc: i64, sp: i64) -> i64 { return slen(s) * (8*sc + sp) }
132func fsize(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 } let n: i64 = sys_lseek(fd, 0, 2); sys_close(fd); return n }
133
134// ---- compose a postcard (front + back) ----
135func compose(fp: *u8, bp: *u8, greeting: *u8, message: *u8, recipient: *u8, line1: *u8, city: *u8, region: *u8, postal: *u8) -> i64 {
136 let W: i64 = K_MAGIC_1800
137 let H: i64 = K_MAGIC_1200
138 let tbl: *u8 = font8x8_table()
139
140 // ===== FRONT =====
141 let front: *u8 = sys_mmap(W * H * 3)
142 fill_rect(front, W, H, 0, 0, W-1, H-1, 34, 110, 140) // teal full bleed
143 fill_rect(front, W, H, 70, 70, W-71, H-71, 250, 247, 240) // cream panel (safe area)
144 rect_outline(front, W, H, 96, 96, W-97, H-97, 5, 190, 60, 70) // warm accent inset border
145 let gsc: i64 = 9
146 let gx: i64 = (W - text_w(greeting, gsc, gsc)) / 2
147 draw_text(front, W, H, tbl, greeting, gx, 470, gsc, gsc, 34, 36, 46)
148 let sub: *u8 = "a note from afar"
149 let ssc: i64 = 4
150 draw_text(front, W, H, tbl, sub, (W - text_w(sub, ssc, ssc)) / 2, 690, ssc, ssc, 190, 60, 70)
151 nx_png_write_rgb(fp, front, W, H)
152
153 // ===== BACK (address side) =====
154 let back: *u8 = sys_mmap(W * H * 3)
155 fill_rect(back, W, H, 0, 0, W-1, H-1, 250, 247, 240) // cream
156 fill_rect(back, W, H, 898, 120, 902, K_MAGIC_1080, 60, 62, 72) // vertical divider
157 // LEFT: the message, wrapped
158 draw_wrap(back, W, H, tbl, message, 90, 180, 4, 740, 34, 36, 46)
159 draw_text(back, W, H, tbl, "Nishi Mail - on your own hardware", 90, K_MAGIC_1040, 2, 2, 130, 130, 142)
160 // RIGHT: stamp (indicia) box top-right
161 rect_outline(back, W, H, K_MAGIC_1560, 90, K_MAGIC_1720, 250, 4, 150, 150, 162)
162 draw_text(back, W, H, tbl, "STAMP", K_MAGIC_1587, 155, 2, 2, 150, 150, 162)
163 // recipient address block in the address zone
164 let asc: i64 = 4
165 draw_text(back, W, H, tbl, recipient, 1000, 520, asc, asc, 34, 36, 46)
166 draw_text(back, W, H, tbl, line1, 1000, 590, asc, asc, 34, 36, 46)
167 let cl: *u8 = sys_mmap(256)
168 var o: i64 = 0
169 o = cpy(cl, o, city); cl[o] = 44 as u8; o = o + 1; cl[o] = 32 as u8; o = o + 1
170 o = cpy(cl, o, region); cl[o] = 32 as u8; o = o + 1; o = cpy(cl, o, postal); cl[o] = 0 as u8
171 draw_text(back, W, H, tbl, cl, 1000, 660, asc, asc, 34, 36, 46)
172 // lower-right IMb barcode clear zone (x 940..1720, y 1000..1120) left blank by construction
173 nx_png_write_rgb(bp, back, W, H)
174
175 p("NISHI-POSTCARD front=" as *u8); p(fp); p(" back=" as *u8); p(bp)
176 p(" size=1800x1200 recipient=" as *u8); p(recipient); p("\n" as *u8)
177 return 0
178}
179
180// ===== NISHI-ENVELOPE: letter (8.5x11 @300dpi, tri-fold, window-positioned address) + the No.10 face =====
181// args bundle a: [0]=out.png [1]=sender [2]=recipient [3]=line1 [4]=city [5]=region [6]=postal [7]=body
182func compose_letter(a: *i64) -> i64 {
183 let W: i64 = K_MAGIC_2550
184 let H: i64 = K_MAGIC_3300
185 let tbl: *u8 = font8x8_table()
186 let pg: *u8 = sys_mmap(W * H * 3)
187 fill_rect(pg, W, H, 0, 0, W-1, H-1, 255, 255, 255)
188 // sender block top-left (return address zone)
189 draw_text(pg, W, H, tbl, a[1] as *u8, 300, 240, 3, 3, 34, 36, 46)
190 draw_text(pg, W, H, tbl, "via Nishi Mail", 300, 320, 2, 2, 130, 130, 142)
191 // recipient block in the No.10 WINDOW ZONE (shows through when tri-folded: ~1in left, ~2.2in from top)
192 let cl: *u8 = sys_mmap(256)
193 var o: i64 = 0
194 o = cpy(cl, o, a[4] as *u8); cl[o] = 44 as u8; o = o + 1; cl[o] = 32 as u8; o = o + 1
195 o = cpy(cl, o, a[5] as *u8); cl[o] = 32 as u8; o = o + 1; o = cpy(cl, o, a[6] as *u8); cl[o] = 0 as u8
196 draw_text(pg, W, H, tbl, a[2] as *u8, 300, 660, 4, 4, 34, 36, 46)
197 draw_text(pg, W, H, tbl, a[3] as *u8, 300, 730, 4, 4, 34, 36, 46)
198 draw_text(pg, W, H, tbl, cl, 300, 800, 4, 4, 34, 36, 46)
199 // tri-fold tick marks at 1/3 and 2/3 (y=1100, y=2200)
200 fill_rect(pg, W, H, 0, K_MAGIC_1099, 48, K_MAGIC_1102, 190, 190, 198)
201 fill_rect(pg, W, H, W-49, K_MAGIC_1099, W-1, K_MAGIC_1102, 190, 190, 198)
202 fill_rect(pg, W, H, 0, K_MAGIC_2199, 48, K_MAGIC_2202, 190, 190, 198)
203 fill_rect(pg, W, H, W-49, K_MAGIC_2199, W-1, K_MAGIC_2202, 190, 190, 198)
204 // salutation + wrapped body + closing
205 let sal: *u8 = sys_mmap(320)
206 var so: i64 = 0
207 so = cpy(sal, so, "Dear " as *u8); so = cpy(sal, so, a[2] as *u8); sal[so] = 44 as u8; sal[so+1] = 0 as u8
208 draw_text(pg, W, H, tbl, sal, 300, K_MAGIC_1250, 4, 4, 34, 36, 46)
209 draw_wrap(pg, W, H, tbl, a[7] as *u8, 300, K_MAGIC_1380, 4, K_MAGIC_1950, 34, 36, 46)
210 draw_text(pg, W, H, tbl, "Warm regards," as *u8, 300, K_MAGIC_2500, 4, 4, 34, 36, 46)
211 draw_text(pg, W, H, tbl, a[1] as *u8, 300, K_MAGIC_2590, 4, 4, 34, 36, 46)
212 draw_text(pg, W, H, tbl, "Composed by Nishi Mail on your own hardware", 300, K_MAGIC_3140, 2, 2, 150, 150, 162)
213 nx_png_write_rgb(a[0] as *u8, pg, W, H)
214 p("NISHI-ENVELOPE letter=" as *u8); p(a[0] as *u8); p(" size=2550x3300 window-zone-addressed tri-fold\n" as *u8)
215 return 0
216}
217// the No.10 envelope face: 9.5 x 4.125 in @300dpi = 2850x1238; window 4.5x1.125in at 0.875in left / 0.5in bottom
218// a: [0]=out.png [1]=sender [2]=sender-cityline [3]=recipient [4]=line1 [5]=cityline
219func compose_envelope(a: *i64) -> i64 {
220 let W: i64 = K_MAGIC_2850
221 let H: i64 = K_MAGIC_1238
222 let tbl: *u8 = font8x8_table()
223 let pg: *u8 = sys_mmap(W * H * 3)
224 fill_rect(pg, W, H, 0, 0, W-1, H-1, 255, 255, 255)
225 // return address top-left
226 draw_text(pg, W, H, tbl, a[1] as *u8, 150, 120, 3, 3, 34, 36, 46)
227 draw_text(pg, W, H, tbl, a[2] as *u8, 150, 190, 3, 3, 34, 36, 46)
228 // stamp box top-right
229 rect_outline(pg, W, H, K_MAGIC_2620, 90, K_MAGIC_2760, 240, 4, 150, 150, 162)
230 draw_text(pg, W, H, tbl, "STAMP" as *u8, K_MAGIC_2640, 150, 2, 2, 150, 150, 162)
231 // the window: x 0.875in=262, w 4.5in=1350; 1.125in=337 tall, 0.5in=150 from bottom
232 rect_outline(pg, W, H, 262, 751, K_MAGIC_1612, K_MAGIC_1088, 3, 210, 210, 216)
233 draw_text(pg, W, H, tbl, a[3] as *u8, 330, 800, 4, 4, 34, 36, 46)
234 draw_text(pg, W, H, tbl, a[4] as *u8, 330, 870, 4, 4, 34, 36, 46)
235 draw_text(pg, W, H, tbl, a[5] as *u8, 330, 940, 4, 4, 34, 36, 46)
236 nx_png_write_rgb(a[0] as *u8, pg, W, H)
237 p("NISHI-ENVELOPE face=" as *u8); p(a[0] as *u8); p(" size=2850x1238 (No.10, window at spec)\n" as *u8)
238 return 0
239}
240// ===== NISHI-FOLDCARD: A7 folded card (5.25 x 7.25 in panels) = two duplex sheets 3150x2175 =====
241// a: [0]=outside.png [1]=inside.png [2]=greeting [3]=message [4]=recipient [5]=sender
242func compose_card(a: *i64) -> i64 {
243 let W: i64 = K_MAGIC_3150
244 let H: i64 = K_MAGIC_2175
245 let PW: i64 = K_MAGIC_1575
246 let tbl: *u8 = font8x8_table()
247 // OUTSIDE sheet: left = back cover, right = front cover
248 let os: *u8 = sys_mmap(W * H * 3)
249 fill_rect(os, W, H, 0, 0, W-1, H-1, 250, 247, 240)
250 fill_rect(os, W, H, PW, 0, W-1, H-1, 34, 110, 140)
251 fill_rect(os, W, H, PW+70, 70, W-71, H-71, 250, 247, 240)
252 rect_outline(os, W, H, PW+96, 96, W-97, H-97, 5, 190, 60, 70)
253 let gsc: i64 = 7
254 let gx: i64 = PW + (PW - text_w(a[2] as *u8, gsc, gsc)) / 2
255 draw_text(os, W, H, tbl, a[2] as *u8, gx, 900, gsc, gsc, 34, 36, 46)
256 let sub: *u8 = "with love, via Nishi Mail"
257 draw_text(os, W, H, tbl, sub, PW + (PW - text_w(sub, 3, 3)) / 2, K_MAGIC_1250, 3, 3, 190, 60, 70)
258 let bk: *u8 = "Nishi Mail - on your own hardware"
259 draw_text(os, W, H, tbl, bk, (PW - text_w(bk, 2, 2)) / 2, K_MAGIC_2050, 2, 2, 150, 150, 162)
260 fill_rect(os, W, H, PW-1, 0, PW+1, 40, 190, 190, 198)
261 fill_rect(os, W, H, PW-1, H-41, PW+1, H-1, 190, 190, 198)
262 nx_png_write_rgb(a[0] as *u8, os, W, H)
263 // INSIDE sheet: left blank, right = message
264 let ins: *u8 = sys_mmap(W * H * 3)
265 fill_rect(ins, W, H, 0, 0, W-1, H-1, 250, 247, 240)
266 let sal: *u8 = sys_mmap(320)
267 var so: i64 = 0
268 so = cpy(sal, so, "Dear " as *u8); so = cpy(sal, so, a[4] as *u8); sal[so] = 44 as u8; sal[so+1] = 0 as u8
269 draw_text(ins, W, H, tbl, sal, PW + 130, 300, 4, 4, 34, 36, 46)
270 draw_wrap(ins, W, H, tbl, a[3] as *u8, PW + 130, 430, 4, K_MAGIC_1300, 34, 36, 46)
271 draw_text(ins, W, H, tbl, "With love," as *u8, PW + 130, K_MAGIC_1800, 4, 4, 34, 36, 46)
272 draw_text(ins, W, H, tbl, a[5] as *u8, PW + 130, K_MAGIC_1890, 4, 4, 34, 36, 46)
273 nx_png_write_rgb(a[1] as *u8, ins, W, H)
274 p("NISHI-FOLDCARD outside=" as *u8); p(a[0] as *u8); p(" inside=" as *u8); p(a[1] as *u8); p(" size=3150x2175 (A7 duplex, fold-ticked)\n" as *u8)
275 return 0
276}
277
278func cmd_selftest() -> i64 {
279 p("=== NX-MAILPIECE SELFTEST (NISHI-POSTCARD compose -> PNG) ===\n" as *u8)
280 let fp: *u8 = "knowledge/fetched/nishi_postcard_front.png\x00" as *u8
281 let bp: *u8 = "knowledge/fetched/nishi_postcard_back.png\x00" as *u8
282 let msg: *u8 = "Thinking of you on your special day. Wish we could be there to celebrate. Sending love and a little sunshine from far away, on paper you can hold." as *u8
283 compose(fp, bp, "HAPPY BIRTHDAY" as *u8, msg, "Grandma Rose" as *u8, "742 Evergreen Terrace" as *u8, "Springfield" as *u8, "IL" as *u8, "62704" as *u8)
284 let fs: i64 = fsize(fp)
285 let bs: i64 = fsize(bp)
286 var ok: i64 = 1
287 if fs < 100 { ok = 0 }
288 if bs < 100 { ok = 0 }
289
290 // R3: letter (window-zone address + tri-fold) + No.10 envelope face + A7 folded card
291 let la: *i64 = sys_mmap(8 * 10) as *i64
292 la[0] = "knowledge/fetched/nishi_letter.png" as *u8 as i64
293 la[1] = "Jason West" as *u8 as i64
294 la[2] = "Grandma Rose" as *u8 as i64
295 la[3] = "742 Evergreen Terrace" as *u8 as i64
296 la[4] = "Springfield" as *u8 as i64
297 la[5] = "IL" as *u8 as i64
298 la[6] = "62704" as *u8 as i64
299 la[7] = "Just a note to say we are thinking of you. The garden is in full bloom and the kids ask about you every day. We will visit soon and bring photographs of everything you have missed." as *u8 as i64
300 compose_letter(la)
301 let ea: *i64 = sys_mmap(8 * 8) as *i64
302 ea[0] = "knowledge/fetched/nishi_envelope.png" as *u8 as i64
303 ea[1] = "Jason West" as *u8 as i64
304 ea[2] = "Springfield, IL 62704" as *u8 as i64
305 ea[3] = "Grandma Rose" as *u8 as i64
306 ea[4] = "742 Evergreen Terrace" as *u8 as i64
307 ea[5] = "Springfield, IL 62704" as *u8 as i64
308 compose_envelope(ea)
309 let ca: *i64 = sys_mmap(8 * 8) as *i64
310 ca[0] = "knowledge/fetched/nishi_card_outside.png" as *u8 as i64
311 ca[1] = "knowledge/fetched/nishi_card_inside.png" as *u8 as i64
312 ca[2] = "HAPPY BIRTHDAY" as *u8 as i64
313 ca[3] = "Eighty years young and still the heart of this family. We cannot wait to celebrate with you." as *u8 as i64
314 ca[4] = "Grandma Rose" as *u8 as i64
315 ca[5] = "Jason and the kids" as *u8 as i64
316 compose_card(ca)
317 let ls: i64 = fsize(la[0] as *u8)
318 let es: i64 = fsize(ea[0] as *u8)
319 let cos: i64 = fsize(ca[0] as *u8)
320 let cis: i64 = fsize(ca[1] as *u8)
321 if ls < 100 { ok = 0 }
322 if es < 100 { ok = 0 }
323 if cos < 100 { ok = 0 }
324 if cis < 100 { ok = 0 }
325
326 p("NISHI-MAILPIECE-SELFTEST postcard=" as *u8); pn(fs); p("/" as *u8); pn(bs)
327 p(" letter=" as *u8); pn(ls); p(" envelope=" as *u8); pn(es)
328 p(" card=" as *u8); pn(cos); p("/" as *u8); pn(cis)
329 if ok == 1 { p(" verdict=GREEN\n" as *u8); return 0 }
330 p(" verdict=RED\n" as *u8)
331 return 1
332}
333
334func main(argc: i64, argv: *i64) -> i64 {
335 if argc < 2 { return cmd_selftest() }
336 let cmd: *u8 = argv[1] as *u8
337 if seq(cmd, "selftest" as *u8) == 1 { return cmd_selftest() }
338 if seq(cmd, "postcard" as *u8) == 1 {
339 if argc < 11 { p("usage: postcard <front.png> <back.png> <greeting> <message> <recipient> <line1> <city> <region> <postal>\n" as *u8); return 1 }
340 return compose(argv[2] as *u8, argv[3] as *u8, argv[4] as *u8, argv[5] as *u8, argv[6] as *u8, argv[7] as *u8, argv[8] as *u8, argv[9] as *u8, argv[10] as *u8)
341 }
342 if seq(cmd, "letter" as *u8) == 1 {
343 if argc < 10 { p("usage: letter <out.png> <sender> <recipient> <line1> <city> <region> <postal> <body>\n" as *u8); return 1 }
344 return compose_letter(((argv as i64) + 16) as *i64)
345 }
346 if seq(cmd, "envelope" as *u8) == 1 {
347 if argc < 8 { p("usage: envelope <out.png> <sender> <sendercity> <recipient> <line1> <cityline>\n" as *u8); return 1 }
348 return compose_envelope(((argv as i64) + 16) as *i64)
349 }
350 if seq(cmd, "card" as *u8) == 1 {
351 if argc < 8 { p("usage: card <outside.png> <inside.png> <greeting> <message> <recipient> <sender>\n" as *u8); return 1 }
352 return compose_card(((argv as i64) + 16) as *i64)
353 }
354 p("NX-MAILPIECE usage: postcard | letter | envelope | card | selftest\n" as *u8)
355 return 1
356}