From d5789ad8b3779af357956861e28117ae2a0294c6 Mon Sep 17 00:00:00 2001 From: Jurjen Ladenius Date: Sun, 2 Aug 2026 18:12:26 +0200 Subject: [PATCH] Art: labelled palette reference cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit make_palettes.py now also emits kissaten-full-card.png and kissaten-portrait-card.png — each swatch shown with its palette index and hex code, so a colour can be identified while hand-editing without counting along an anonymous strip. Text is drawn with a hand-rolled 3x5 bitmap font covering digits, A-F and '#'; there is no font library available here. Drops palette_ref.png, superseded by kissaten-full.png. Co-Authored-By: Claude Opus 5 --- .../art/kissaten-full-card.png | Bin 0 -> 1880 bytes .../art/kissaten-portrait-card.png | Bin 0 -> 1358 bytes projects/kissaten_yugure/art/palette_ref.png | Bin 650 -> 0 bytes .../kissaten_yugure/tools/make_palettes.py | 46 +++++++++++++++++- 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 projects/kissaten_yugure/art/kissaten-full-card.png create mode 100644 projects/kissaten_yugure/art/kissaten-portrait-card.png delete mode 100644 projects/kissaten_yugure/art/palette_ref.png diff --git a/projects/kissaten_yugure/art/kissaten-full-card.png b/projects/kissaten_yugure/art/kissaten-full-card.png new file mode 100644 index 0000000000000000000000000000000000000000..0c07550c5a0b4924dcc2a8fe1379eee76f68787d GIT binary patch literal 1880 zcmaJ?X;4#F6b?&d31G1z2!*f+wgCd8Eg-U#eN#-4ijrW&D$Ia{$53Q5AfYT4Hw1#R z*a_nTS`!N+34<(wT0jbMgOm_W0$6Y`Ad92{A-y-jPG{(J&X2sgFYkQk`_6aHJx2%+ z($_WBMWImoA;JC;;CBjzQah!s4xU14kAI6oX<=B<-Ym*oed?_(8c^(YwP(1Ts8*DSRH#kxWd z&a6zNpwIJo%OBW$i`+#X8qX2ObzfjrO0KI_#m9(gm>E1WNjBz)X^HhH@RBzD{nh8O z;2h8Knm6J++e6Y(MxH$k@y7DygkT4=$8k6g_ta+D~uwO-&|NM8r! zOY1rz+H8TDqJVho$yEm(P>8$v@OSluSAPm}_R}?uN%wSsPKF(D^n2$7-eQ*K(z9 z0`v^d53SOmLK1j%xT#RrE{uj@))-6|Ie0~W?ycpA2IZ-`ccEZI_hce_YRWN9X6HbD z>)44tLmnBb7lZUqmp0;e%%)jA1kDnj;vDfSm>)O6oy9Ph%yB=v9ocdSWR(#Q6b*Hy zx$BV-?n^_aCiC=0drYSM)3Nxg4kK%Bb4nk?b+3}VM{nuL1O*f6Obkqbp5atxu>FBI z@`$@5O{gUY$=d3`8q7@hx7QiI^3p`|vc3^4r$rJfP6*l{o2Lb9@sY~;GqvQK-pei# z_(nA#Thv)IvQxKtx>XCY4rp__s5&hyQYjkAuV9(sJ7K#bXcwrAbM$ui<5AKm3pO!f zKfn+`VldXd_)Lh9dy<#OI<-l8)mrI=#JZ)bt=r{onxItG;QnUS?4iZ>0Ys$Q>G%4s z6zW1vs}NpugE{WSjC~`ydlSN~cplrnxPFPnr^;~+( z<}WGjB&Pe+{DSu$EDpKY)(jWK-f0438%3HW4a=3M?0X5Rcj!<=44RV`e3nsDU9uW) zD3=G5K?Ci|-{^YD*~%Ux~~7WcxyY6(!~(^J@W^<_yJBM9(G?rWjT<8w7?~p0HP;x} z&-TA@h9g-EIWEyQa2%Ice?&B=TFFP2AB=j}dh+O#aL=WC2>0#`YbGs9$5KF(7`}Rk zSi~ASR-|lH%%>C<@JmYInYp4^4Jf&+y2-H2wtv*kd=o5CMDS6M%I0oZTr0AQkC=|4 zhdZWy=XpKJ9hPvvgCXBl9?juX&Y3DSij%P;l~C<#g}N4Uw$NVFoh#IjKu|u6Pz{-#OjAn=GRmcVK#$fmn0~Dq{3EZA~t2VHWxUT zA1+N&jG?fmxbs+CxvaznQgRgvV)KP*DG2hcXpoE&eymMZcJ22K)65C_ZaPOE`@)P literal 0 HcmV?d00001 diff --git a/projects/kissaten_yugure/art/kissaten-portrait-card.png b/projects/kissaten_yugure/art/kissaten-portrait-card.png new file mode 100644 index 0000000000000000000000000000000000000000..d4b768d4648d1a875cb479871429444db78c23c6 GIT binary patch literal 1358 zcmeAS@N?(olHy`uVBq!ia0vp^FM#+T2NRIo?{aS?0|Tq5r;B4q#jUq@FHW3oAmVUw zt@8c6wxl~f-G#={J)dWDHb3L^wBej@T~lGkvgcunPI5}!KM(G2kLNo)@B%`vm`tx7 z{hUP!Eb9)OZT|i9&%f<&{+oQ_{=fU#zmIjlBVTjJ6dXL;7R@Hu9{n$R>jt;=`UMAB z%lUR(=Mi1^f9C;K@jJT@=FSxIn6`3Y7Kl?``8!-Y2l++fQ)#Tg#U5z5BZS@Tv0$0~mo3@^#|+1FYf64?z}# z;*b*v8@12!e*b*$k~q8D1FkzZJBsfKZT+@r&W}21aN75YG?s3;Kka!k$m6f{3c@9| zW`M(U9gq2^P4i4c3?hYM3Z9lk*r$A4==9T4LaPB7pLU-_cRa|_0b2pG1Oy9~?tEBR z7Y~m;QFZUWihoSvF$L?JqU&TdUpsw@6F&q=IkQbeH1dywTwQv9;i0a{s)?*Xb^E`T zMCisWKMYDg)`zAZxGIb3mz}wA3nbONx8k# z{@+@C@Kvd?1CT3zXXpJnXFo43e>+)eE*~?{4Yg0SfvHjyOX|N5w-T7LQ0pzQe+u17wZl3GV|7VZ`5_n!$ zY?ibsrBW6Wp6{i#JRZD?!?5vp<$h@5$l399_VkokkA3&+ezU#=1>xrh(-vMiWLxfi zvrK`}AxXYviA^ixx5g zQ^?E_?ggiOMA`=@OGpW` cwWgji(e}#%-KiD_f#oEFr>mdKI;Vst00U2nMF0Q* literal 0 HcmV?d00001 diff --git a/projects/kissaten_yugure/art/palette_ref.png b/projects/kissaten_yugure/art/palette_ref.png deleted file mode 100644 index 937b0b61ce4926ae625645a251573fdb3b5ce22b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8395_JKs1*KtJAX<-+h;nuN76V9`)6& o+WO|b-ZGHcqhLgbz=8e08Cw#I0yPhJ7=r@B)78&qol`;+0E>n*Z~y=R diff --git a/projects/kissaten_yugure/tools/make_palettes.py b/projects/kissaten_yugure/tools/make_palettes.py index 08680c2..e6537e4 100644 --- a/projects/kissaten_yugure/tools/make_palettes.py +++ b/projects/kissaten_yugure/tools/make_palettes.py @@ -67,6 +67,49 @@ def swatches(path, cols, sw=32, h=64): write_png(path, [[c for c in cols for _ in range(sw)]] * h) +# 3x5 glyphs, enough for indices and hex codes. No font library here. +GLYPHS = { + "0": "111101101101111", "1": "010110010010111", "2": "111001111100111", + "3": "111001111001111", "4": "101101111001001", "5": "111100111001111", + "6": "111100111101111", "7": "111001001001001", "8": "111101111101111", + "9": "111101111001111", "A": "111101111101101", "B": "110101110101110", + "C": "111100100100111", "D": "110101101101110", "E": "111100111100111", + "F": "111100111100100", "#": "101111101111101", " ": "000000000000000", + "-": "000000111000000", +} + + +def _text(px, x, y, s, col, scale=2): + for ch in s.upper(): + g = GLYPHS.get(ch, GLYPHS[" "]) + for gy in range(5): + for gx in range(3): + if g[gy*3 + gx] == "1": + for sy in range(scale): + for sx in range(scale): + yy, xx = y + gy*scale + sy, x + gx*scale + sx + if 0 <= yy < len(px) and 0 <= xx < len(px[0]): + px[yy][xx] = col + x += 4 * scale + + +def card(path, cols, names, idx, scale=2): + """Labelled reference: swatch, palette index, hex code, role name.""" + rowh, sww, pad = 7*scale + 8, 22*scale, 6 + W = sww + pad*2 + 4*scale*22 + H = rowh*len(cols) + pad*2 + bg, fg = (26, 26, 26), (255, 255, 219) + px = [[bg]*W for _ in range(H)] + for i, (c, n, ix) in enumerate(zip(cols, names, idx)): + y = pad + i*rowh + for yy in range(y, y + 7*scale): + for xx in range(pad, pad + sww): + px[yy][xx] = c + label = f"{ix:02d} #{c[0]:02X}{c[1]:02X}{c[2]:02X}" + _text(px, pad + sww + pad, y + scale, label, fg, scale) + write_png(path, px) + + def emit(stem, idx, title): cols = [PALETTE[i] for i in idx] names = [NAMES[i] for i in idx] @@ -76,7 +119,8 @@ def emit(stem, idx, title): aco(p("aco"), cols, names) act(p("act"), cols) swatches(p("png"), cols) - print(f"{stem}: {len(cols)} colours -> .gpl .ase .aco .act .png") + card(os.path.normpath(os.path.join(OUT, f"{stem}-card.png")), cols, names, idx) + print(f"{stem}: {len(cols)} colours -> .gpl .ase .aco .act .png + -card.png") if __name__ == "__main__":