Blame onefile/pixelfont.c

0ff1e5
0ff1e5
#include <stdio.h></stdio.h>
0ff1e5
#include <helianthus.h></helianthus.h>
0ff1e5
0ff1e5
0ff1e5
#define CW 4
0ff1e5
#define CH 5
0ff1e5
0ff1e5
#define MAXW 1024
0ff1e5
#define MAXH 1024
0ff1e5
#define BORDER 1
0ff1e5
0ff1e5
#define ROWS   8
0ff1e5
#define COLS  12
0ff1e5
0ff1e5
#define WIDTH  (COLS*(CW + BORDER) + BORDER)
0ff1e5
#define HEIGHT (ROWS*(CH + BORDER) + BORDER)
0ff1e5
#define CS ((MAXW/WIDTH) < (MAXH/HEIGHT) ? (MAXW/WIDTH) : (MAXH/HEIGHT))
0ff1e5
0ff1e5
#define IW 512
0ff1e5
#define IH 512
0ff1e5
#define IB 16
0ff1e5
0ff1e5
#define BCOLOR COLOR_BLACK
0ff1e5
#define FCOLOR COLOR_WHITE
0ff1e5
#define SCOLOR COLOR_YELLOW
0ff1e5
0ff1e5
#define QUOTES2(x) #x
0ff1e5
#define QUOTES(x) QUOTES2(x)
0ff1e5
0ff1e5
#define PREFIX  "data/output/pixelfont" QUOTES(CW) QUOTES(CH)
0ff1e5
#define MAPFILE PREFIX ".map"
0ff1e5
#define IMGFILE PREFIX ".png"
0ff1e5
#define CFILE   PREFIX ".c"
0ff1e5
0ff1e5
0ff1e5
int map[HEIGHT][WIDTH];
0ff1e5
unsigned int img[IH][IW];
0ff1e5
Animation imgAnim;
0ff1e5
int k = 1;
0ff1e5
0ff1e5
const char demoText[] =
0ff1e5
  "THE QUICK BROWN FOX JUMPS OVER A LAZY DOG.\n"
0ff1e5
  "the quick brown fox jumps over a lazy dog.\n"
0ff1e5
  "\n"
0ff1e5
  "`~!@#$%^&*()-_+=\\|[]{};:'\",.<>/?\n"
0ff1e5
  "\n"
0ff1e5
  "\"Free software\" means software that respects users' freedom and community.\n"
0ff1e5
  "Roughly, it means that the users have the freedom to run, copy, distribute,\n"
0ff1e5
  "study, change and improve the software. Thus, \"free software\" is a matter\n"
0ff1e5
  "of liberty, not price. To understand the concept, you should think of \"free\"\n"
0ff1e5
  "as in \"free speech\", not as in \"free beer\". We sometimes call it \"libre\n"
0ff1e5
  "software,\" borrowing the French or Spanish word for \"free\" as in freedom,\n"
0ff1e5
  "to show we do not mean the software is gratis.\n"
0ff1e5
  "\n"
0ff1e5
  "12+(34-56)*67/890\n"
0ff1e5
  "\n"
0ff1e5
  "2^3=8\n"
0ff1e5
  "3/100=3%\n"
0ff1e5
  "\n"
0ff1e5
  "e-mail of Richard Stallman: rms@gnu.org\n"
0ff1e5
  "\n"
0ff1e5
  "`reverse apostrophe`, ~tilda, array[12], {scope}\n"
0ff1e5
  "price is $100\n"
0ff1e5
  "\n"
0ff1e5
  "#include <stdio.h>\n"</stdio.h>
0ff1e5
  "int x = IB, y = IB;\n"
0ff1e5
  "for(const char *c = demoText; *c; ++c) {\n"
0ff1e5
  "  if (*c == '\\n') { x = IB, y += CH+BORDER; continue; }\n"
0ff1e5
  "  if (*c >= 32 && *c < 128) {\n"
0ff1e5
  "    int mx = ((int)*c - 32)%COLS*(CW + BORDER) + BORDER;\n"
0ff1e5
  "    int my = ((int)*c - 32)/COLS*(CH + BORDER) + BORDER;\n"
0ff1e5
  "    for(int yy = 0; yy < CH; ++yy)\n"
0ff1e5
  "    for(int xx = 0; xx < CW; ++xx)\n"
0ff1e5
  "      if (map[my + yy][mx + xx])\n"
0ff1e5
  "        img[y + yy][x + xx] = FCOLOR;\n"
0ff1e5
  "  }\n"
0ff1e5
  "  x += CW+BORDER;\n"
0ff1e5
  "}\n";
0ff1e5
0ff1e5
0ff1e5
void buildDemoImage() {
0ff1e5
  for(int y = 0; y < IH; ++y)
0ff1e5
  for(int x = 0; x < IW; ++x)
0ff1e5
    imageSetPixel(IW, IH, img, x, y, BCOLOR);
0ff1e5
0ff1e5
  int x = IB, y = IB;
0ff1e5
  for(const char *c = demoText; *c; ++c) {
0ff1e5
    if (*c == '\n') { x = IB, y += CH+BORDER; continue; }
0ff1e5
    if (*c >= 32 && *c < 128) {
0ff1e5
      int mx = ((int)*c - 32)%COLS*(CW + BORDER) + BORDER;
0ff1e5
      int my = ((int)*c - 32)/COLS*(CH + BORDER) + BORDER;
0ff1e5
      for(int yy = 0; yy < CH; ++yy)
0ff1e5
      for(int xx = 0; xx < CW; ++xx)
0ff1e5
        if (map[my + yy][mx + xx])
0ff1e5
          imageSetPixel(IW, IH, img, x + xx, y + yy, FCOLOR);
0ff1e5
    }
0ff1e5
    x += CW+BORDER;
0ff1e5
  }
0ff1e5
0ff1e5
  if (imgAnim) animationDestroy(imgAnim);
0ff1e5
  imgAnim = createAnimationFromImageEx(IW, IH, img, FALSE, FALSE, FALSE, FALSE);
0ff1e5
}
0ff1e5
0ff1e5
0ff1e5
void save() {
0ff1e5
  FILE *f = fopen(MAPFILE, "w");
0ff1e5
  if (!f)
0ff1e5
    { printf("cannot write to file: %s\n", MAPFILE); return; }
0ff1e5
  for(int y = 0; y < HEIGHT; ++y) {
0ff1e5
    for(int x = 0; x < WIDTH; ++x)
0ff1e5
      fputc(map[y][x] ? '#' : ' ', f);
0ff1e5
    fputc('\n', f);
0ff1e5
  }
0ff1e5
  fclose(f);
0ff1e5
0ff1e5
  imageSave(IMGFILE, IW, IH, img);
0ff1e5
0ff1e5
  f = fopen(CFILE, "w");
0ff1e5
  if (!f)
0ff1e5
    { printf("cannot write to file: %s\n", CFILE); return; }
0ff1e5
0ff1e5
  int bits = CW*CH;
0ff1e5
  char format[] = " 0x%00llx,";
0ff1e5
  format[5] = '0' + (bits-1)/4 + 1;
0ff1e5
  unsigned long long bit = 1ull << (bits-1);
0ff1e5
  const char *itype = bits <=  8 ? "char"
0ff1e5
                    : bits <= 16 ? "short"
0ff1e5
                    : bits <= 32 ? "int"
0ff1e5
                    : "long long";
0ff1e5
3d3812
  fprintf(f, "unsigned %s font%dx%d_data[] = {\n", itype, CW, CH);
0ff1e5
  for(int r = 0; r < COLS; ++r) {
0ff1e5
    fprintf(f, " ");
0ff1e5
    for(int c = 0; c < ROWS; ++c) {
0ff1e5
      int i = r*ROWS + c;
0ff1e5
      int x = i%COLS*(CW+BORDER) + BORDER;
0ff1e5
      int y = i/COLS*(CH+BORDER) + BORDER;
0ff1e5
      unsigned long long d = 0;
0ff1e5
      for(int yy = 0; yy < CH; ++yy)
0ff1e5
      for(int xx = 0; xx < CW; ++xx)
0ff1e5
        d = (d >> 1) | (map[y + yy][x + xx] ? bit : 0);
0ff1e5
      fprintf(f, format, d);
0ff1e5
    }
0ff1e5
    fprintf(f, "\n");
0ff1e5
  }
0ff1e5
  fprintf(f, "};\n");
0ff1e5
  fclose(f);
0ff1e5
}
0ff1e5
0ff1e5
0ff1e5
void load() {
0ff1e5
  for(int y = 0; y < HEIGHT; ++y)
0ff1e5
  for(int x = 0; x < WIDTH; ++x)
0ff1e5
    map[y][x] = 0;
0ff1e5
0ff1e5
  FILE *f = fopen(MAPFILE, "r");
0ff1e5
  if (!f)
0ff1e5
    { printf("cannot read from file: %s\n", MAPFILE); return; }
0ff1e5
  int x = 0, y = 0;
0ff1e5
  while(!feof(f)) {
0ff1e5
    int c = fgetc(f);
0ff1e5
    if (c == '\n') { x = 0; ++y; continue; }
0ff1e5
    if (c == '#' && x < WIDTH && y < HEIGHT)
0ff1e5
      map[y][x] = 1;
0ff1e5
    ++x;
0ff1e5
  }
0ff1e5
}
0ff1e5
0ff1e5
0ff1e5
void init() {
0ff1e5
  background(BCOLOR);
0ff1e5
  load();
0ff1e5
  buildDemoImage();
0ff1e5
}
0ff1e5
0ff1e5
0ff1e5
void draw() {
0ff1e5
  saveState();
0ff1e5
0ff1e5
  int imx = (int)(mouseX()/CS);
0ff1e5
  int imy = (int)(mouseY()/CS);
0ff1e5
0ff1e5
  double o = CS/2.0;
0ff1e5
  stroke(colorWithAlpha(FCOLOR, 0.25));
0ff1e5
  strokeWidth(1);
0ff1e5
  for(int r = 0; r <= ROWS; ++r)
0ff1e5
    line(o, o + r*(CH+BORDER)*CS, CS*WIDTH - o, o + r*(CH+BORDER)*CS);
0ff1e5
  for(int c = 0; c <= COLS; ++c)
0ff1e5
    line(o + c*(CW+BORDER)*CS, o, o + c*(CW+BORDER)*CS, CS*HEIGHT - o);
0ff1e5
0ff1e5
  noFill();
0ff1e5
  textAlign(HALIGN_CENTER, VALIGN_CENTER);
0ff1e5
  textSize(CH*CS*0.5);
0ff1e5
  for(int i = 0; i < 96; ++i) {
0ff1e5
    double x = ((i%COLS + 0.5)*(CW+BORDER) + BORDER)*CS;
0ff1e5
    double y = ((i/COLS + 0.5)*(CH+BORDER) + BORDER)*CS;
0ff1e5
    char t[2] = { i+32, 0 };
0ff1e5
    text(x, y, t);
0ff1e5
  }
0ff1e5
0ff1e5
  fill(COLOR_WHITE);
0ff1e5
  rectTextured(imgAnim, WIDTH*CS + o, o, IW*k, IH*k);
0ff1e5
0ff1e5
  noStroke();
0ff1e5
  fill(FCOLOR);
0ff1e5
  for(int y = 0; y < HEIGHT; ++y)
0ff1e5
  for(int x = 0; x < WIDTH; ++x)
0ff1e5
    if (map[y][x]) rect(x*CS, y*CS, CS, CS);
0ff1e5
0ff1e5
  if ( imx >= BORDER && imx < WIDTH
0ff1e5
    && imy >= BORDER && imy < HEIGHT
0ff1e5
    && (imx-BORDER)%(CW+BORDER) < CW
0ff1e5
    && (imy-BORDER)%(CH+BORDER) < CH )
0ff1e5
  {
0ff1e5
    fill(colorWithAlpha(SCOLOR, 0.25));
0ff1e5
    rect(imx*CS, imy*CS, CS, CS);
0ff1e5
    if (mouseDown("left"))  { map[imy][imx] = 1; buildDemoImage(); }
0ff1e5
    if (mouseDown("right")) { map[imy][imx] = 0; buildDemoImage(); }
0ff1e5
  }
0ff1e5
0ff1e5
  if (keyWentDown("s")) {
0ff1e5
    printf("saving\n");
0ff1e5
    save();
0ff1e5
  }
0ff1e5
0ff1e5
  if (keyWentDown("any +")) {
0ff1e5
    k = k == 1 ? 2 : 1;
0ff1e5
  }
0ff1e5
0ff1e5
  restoreState();
0ff1e5
}
0ff1e5
0ff1e5
0ff1e5
int main() {
0ff1e5
  windowSetResizable(TRUE);
0ff1e5
  windowSetVariableFrameRate();
0ff1e5
  windowSetInit(&init);
0ff1e5
  windowSetDraw(&draw);
0ff1e5
  windowRun();
0ff1e5
  return 0;
0ff1e5
}