ref: c5439205e34b970023b639df60cfdbb7c81cfcc6
dir: /cardgen.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
static void
usage(void)
{
fprint(2, "usage: %s [-t]\n", argv0);
exits("usage");
}
int cardwid = 200;
int cardhgt = 300;
int cardrad = 7;
int symwid = 30;
int symhgt = 30;
Point symlocs[2] = {
{ 10, 10 },
{ 200-30-10, 300-30-10 },
};
Point lbllocs[2] = {
{ 10+30+10, 20 },
{ 200-30-10-10, 300-20-10 },
};
/* 0 left, 1 right */
int lblalign[2] = {
0,
1,
};
/* nils will be skipped */
char *labels[15] = {
nil,
nil,
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"J (11)",
"Q (12)",
"K (13)",
"A (14)",
};
/* code */
Memimage *memred;
static void
drawspades(Memimage *mi)
{
/*
/\
* *
|
*/
Point c, p, q;
int d, r;
Point tip[3];
Point bot[5];
r = Dx(mi->r)/5;
c.x = Dx(mi->r)/2 - 1;
c.y = Dy(mi->r)/2 - 1;
/* points */
d = Dx(mi->r)/4.5;
p.x = c.x - d;
p.y = c.y+1;
q.x = c.x;
q.y = Dy(mi->r)/4;
memimageline(mi, p, q, Enddisc, Enddisc, r, memblack, ZP, SoverD);
p.x = c.x + d;
memimageline(mi, p, q, Enddisc, Enddisc, r, memblack, ZP, SoverD);
tip[0] = Pt(c.x+d/2, (p.y - q.y)/2);
tip[1] = Pt(c.x, (p.y - q.y)/10-1);
tip[2] = Pt(c.x-d/2, (p.y - q.y)/2);
bot[0] = Pt(c.x, c.y);
d = Dx(mi->r)/10.;
r = Dx(mi->r)/6.;
bot[1] = Pt(c.x-d, Dy(mi->r)/15.*13.);
bot[2] = Pt(c.x-r, Dy(mi->r)/15.*14.5);
bot[3] = Pt(c.x+r, Dy(mi->r)/15.*14.5);
bot[4] = Pt(c.x+d, Dy(mi->r)/15.*13.);
memfillpoly(mi, tip, nelem(tip), 0, memblack, ZP, SoverD);
memfillpoly(mi, bot, nelem(bot), 0, memblack, ZP, SoverD);
}
static void
drawclubs(Memimage *mi)
{
/*
*
* *
|
*/
Point p;
int r;
int cx;
float d;
r = Dx(mi->r) / 4.5;
d = 4.;
/* center point */
p.x = cx = Dx(mi->r) / 2 -1;
p.y = Dy(mi->r) / 5 + 1;
memimageline(mi, p, p, Enddisc, Enddisc, r, memblack, ZP, SoverD);
/* left point */
p.y = Dy(mi->r) / 2 + 1;
p.x = cx - Dx(mi->r) / d;
memimageline(mi, p, p, Enddisc, Enddisc, r, memblack, ZP, SoverD);
/* right point */
p.x = cx + Dx(mi->r) / d;
memimageline(mi, p, p, Enddisc, Enddisc, r, memblack, ZP, SoverD);
/* line */
p.x = Dx(mi->r) / 2 -1;
p.y = Dy(mi->r) / 5 + 1;
memimageline(mi, p, Pt(p.x, Dy(mi->r)/15.*14.),
Endsquare, Endsquare, Dx(mi->r)/20, memblack, ZP, SoverD);
}
static void
drawhearts(Memimage *mi)
{
/*
* *
\/
*/
Point p, q, c;
int r, d;
float f = 0.7;
c.x = Dx(mi->r)/2 - 1;
c.y = Dy(mi->r)/2;
r = Dx(mi->r)/4.5;
d = Dx(mi->r)/4.5;
p.x = c.x - d;
p.y = c.y - d;
q.x = c.x + r*f;
q.y = c.y + r*f;
memimageline(mi, p, q, Enddisc, Endsquare, r, memred, ZP, SoverD);
p.x = c.x + d;
q.x = c.x - r*f;
memimageline(mi, p, q, Enddisc, Endsquare, r, memred, ZP, SoverD);
}
static void
drawdiamonds(Memimage *mi)
{
/* circle, starting at (1.0, 0.0), counterclockwise. */
Point p[12];
Point c;
int i;
float x, y, f;
float outer, inner;
/* outer distance: diamond corners.
inner distance: inner curve. */
outer = Dx(mi->r)/2.;
inner = Dx(mi->r)/3.4;
c.x = Dx(mi->r)/2. -1;
c.y = Dy(mi->r)/2. -1;
for (i = 0; i < nelem(p); i++) {
f = ( ((float)i) / nelem(p) ) * PI*2.;
x = cos(f);
y = sin(f);
f = i%3 == 0 ? outer : inner;
p[i].x = c.x + x * f;
p[i].y = c.y + y * f;
}
memfillpoly(mi, p, nelem(p), 0, memred, ZP, SoverD);
}
static void
drawborder(Memimage *mi)
{
memimageline(mi,
Pt(mi->r.min.x, mi->r.min.y),
Pt(mi->r.max.x, mi->r.min.y),
Endsquare, Endsquare, 0, memblack, ZP, S);
memimageline(mi,
Pt(mi->r.max.x-1, mi->r.min.y),
Pt(mi->r.max.x-1, mi->r.max.y),
Endsquare, Endsquare, 0, memblack, ZP, S);
memimageline(mi,
Pt(mi->r.max.x, mi->r.max.y-1),
Pt(mi->r.min.x, mi->r.max.y-1),
Endsquare, Endsquare, 0, memblack, ZP, S);
memimageline(mi,
Pt(mi->r.min.x, mi->r.max.y),
Pt(mi->r.min.x, mi->r.min.y),
Endsquare, Endsquare, 0, memblack, ZP, S);
}
int gentemplates = 0;
static void
dogentemplates(void)
{
Memimage *mi;
int fcard;
int fsym;
int fdiamonds;
int fhearts;
int fclubs;
int fspades;
Rectangle r;
Point p;
fcard = create("tcard", OWRITE, 0664);
if (fcard < 0)
sysfatal("%r");
fsym = create("tsym", OWRITE, 0664);
if (fsym < 0)
sysfatal("%r");
fdiamonds = create("tsym0", OWRITE, 0664);
if (fdiamonds < 0)
sysfatal("%r");
fhearts = create("tsym1", OWRITE, 0664);
if (fhearts < 0)
sysfatal("%r");
fclubs = create("tsym2", OWRITE, 0664);
if (fclubs < 0)
sysfatal("%r");
fspades = create("tsym3", OWRITE, 0664);
if (fspades < 0)
sysfatal("%r");
#define FINISH(A) drawborder(mi);writememimage(A, mi);freememimage(mi);close(A);
mi = allocmemimage(Rect(-1, -1, cardwid+1, cardhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
p = Pt(cardrad*2, cardrad*2);
memimageline(mi, p, p, Enddisc, Enddisc, cardrad*2, memwhite, ZP, SoverD);
p = Pt(cardwid-cardrad*2, cardrad*2);
memimageline(mi, p, p, Enddisc, Enddisc, cardrad*2, memwhite, ZP, SoverD);
p = Pt(cardwid-cardrad*2, cardhgt-cardrad*2);
memimageline(mi, p, p, Enddisc, Enddisc, cardrad*2, memwhite, ZP, SoverD);
p = Pt(cardrad*2, cardhgt-cardrad*2);
memimageline(mi, p, p, Enddisc, Enddisc, cardrad*2, memwhite, ZP, SoverD);
r.min = Pt(cardrad*2, 0);
r.max = Pt(cardwid-cardrad*2, cardhgt);
memdraw(mi, r, memwhite, ZP, nil, ZP, S);
r.min = Pt(0, cardrad*2);
r.max = Pt(cardwid, cardhgt-cardrad*2);
memdraw(mi, r, memwhite, ZP, nil, ZP, S);
FINISH(fcard)
mi = allocmemimage(Rect(-1, -1, symwid+1, symhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
FINISH(fsym);
mi = allocmemimage(Rect(-1, -1, symwid+1, symhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
drawdiamonds(mi);
FINISH(fdiamonds);
mi = allocmemimage(Rect(-1, -1, symwid+1, symhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
drawhearts(mi);
FINISH(fhearts);
mi = allocmemimage(Rect(-1, -1, symwid+1, symhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
drawclubs(mi);
FINISH(fclubs);
mi = allocmemimage(Rect(-1, -1, symwid+1, symhgt+1), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
drawspades(mi);
FINISH(fspades);
#undef FINISH
}
static Memimage*
load(char *name)
{
Memimage *mi;
int fd;
fd = open(name, OREAD);
if (fd < 0)
sysfatal("%r");
mi = readmemimage(fd);
if (!mi)
sysfatal("creadmemimage %s: %r", name);
close(fd);
return mi;
}
Memimage *card;
Memimage *syms[4];
static void
gencard(int num, Memimage *sym, int fadd)
{
Memimage *mi;
int i, fd;
char *file;
Memsubfont *defont;
char *label;
Point text;
Point p;
Rectangle r;
label = labels[num];
if (!label)
return;
defont = getmemdefont();
text = memsubfontwidth(defont, label);
mi = allocmemimage(Rect(0, 0, cardwid, cardhgt), RGBA32);
if (!mi)
sysfatal("%r");
memfillcolor(mi, DTransparent);
memdraw(mi, mi->r, card, ZP, nil, ZP, S);
r = insetrect(sym->r, 1);
for (i = 0; i < nelem(symlocs); i++) {
memdraw(mi, rectaddpt(r, symlocs[i]), sym, ZP, nil, ZP, SatopD);
}
for (i = 0; i < nelem(lbllocs); i++) {
p = lbllocs[i];
if (lblalign[i])
p.x -= text.x;
memimagestring(mi, p, memblack, ZP, defont, label);
}
file = smprint("out/%d", num+fadd);
if (!file)
sysfatal("%r");
fd = create(file, OWRITE, 0644);
if (fd < 0)
sysfatal("%r");
writememimage(fd, mi);
freememimage(mi);
close(fd);
}
void
main(int argc, char **argv)
{
int i, j;
ARGBEGIN{
case 't':
gentemplates++;
break;
case 'h':
usage();
}ARGEND;
if (memimageinit() < 0)
sysfatal("memimageinit: %r");
memred = allocmemimage(Rect(0, 0, 1, 1), RGB24);
memfillcolor(memred, 0xFF0000FF);
memred->flags |= Frepl;
memred->clipr = memblack->clipr;
if (gentemplates) {
dogentemplates();
exits(nil);
}
card = load("card");
syms[0] = load("sym0");
syms[1] = load("sym1");
syms[2] = load("sym2");
syms[3] = load("sym3");
for (j = 0; j < 4; j++) {
for (i = 0; i < nelem(labels); i++) {
gencard(i, syms[j], j*nelem(labels));
}
}
exits(nil);
}