GNU Unifont  15.0.05
Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes
unifontpic.c File Reference

unifontpic - See the "Big Picture": the entire Unifont in one BMP bitmap More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unifontpic.h"
Include dependency graph for unifontpic.c:

Go to the source code of this file.

Macros

#define HDR_LEN   33
 

Functions

int main (int argc, char **argv)
 The main function. More...
 
void output4 (int thisword)
 Output a 4-byte integer in little-endian order. More...
 
void output2 (int thisword)
 Output a 2-byte integer in little-endian order. More...
 
void gethex (char *instring, int plane_array[0x10000][16], int plane)
 Read a Unifont .hex-format input file from stdin. More...
 
void genlongbmp (int plane_array[0x10000][16], int dpi, int tinynum, int plane)
 Generate the BMP output file in long format. More...
 
void genwidebmp (int plane_array[0x10000][16], int dpi, int tinynum, int plane)
 Generate the BMP output file in wide format. More...
 

Detailed Description

unifontpic - See the "Big Picture": the entire Unifont in one BMP bitmap

Author
Paul Hardy, 2013

Definition in file unifontpic.c.

Macro Definition Documentation

◆ HDR_LEN

#define HDR_LEN   33

Define length of header string for top of chart.

Definition at line 67 of file unifontpic.c.

Function Documentation

◆ genlongbmp()

void genlongbmp ( int  plane_array[0x10000][16],
int  dpi,
int  tinynum,
int  plane 
)

Generate the BMP output file in long format.

This function generates the BMP output file from a bitmap parameter. This is a long bitmap, 16 glyphs wide by 4,096 glyphs tall.

Parameters
[in]plane_arrayThe array of glyph bitmaps for a plane.
[in]dpiDots per inch, for encoding in the BMP output file header.
[in]tinynumWhether to generate tiny numbers in wide grid (unused).
[in]planeThe Unicode plane, 0..17.

Definition at line 294 of file unifontpic.c.

295 {
296 
297  char header_string[HDR_LEN]; /* centered header */
298  char raw_header[HDR_LEN]; /* left-aligned header */
299  int header[16][16]; /* header row, for chart title */
300  int hdrlen; /* length of HEADER_STRING */
301  int startcol; /* column to start printing header, for centering */
302 
303  unsigned leftcol[0x1000][16]; /* code point legend on left side of chart */
304  int d1, d2, d3, d4; /* digits for filling leftcol[][] legend */
305  int codept; /* current starting code point for legend */
306  int thisrow; /* glyph row currently being rendered */
307  unsigned toprow[16][16]; /* code point legend on top of chart */
308  int digitrow; /* row we're in (0..4) for the above hexdigit digits */
309 
310  /*
311  DataOffset = BMP Header bytes + InfoHeader bytes + ColorTable bytes.
312  */
313  int DataOffset = 14 + 40 + 8; /* fixed size for monochrome BMP */
314  int ImageSize;
315  int FileSize;
316  int Width, Height; /* bitmap image width and height in pixels */
317  int ppm; /* integer pixels per meter */
318 
319  int i, j, k;
320 
321  unsigned bytesout;
322 
323  void output4(int), output2(int);
324 
325  /*
326  Image width and height, in pixels.
327 
328  N.B.: Width must be an even multiple of 32 pixels, or 4 bytes.
329  */
330  Width = 18 * 16; /* (2 legend + 16 glyphs) * 16 pixels/glyph */
331  Height = 4099 * 16; /* (1 header + 4096 glyphs) * 16 rows/glyph */
332 
333  ImageSize = Height * (Width / 8); /* in bytes, calculated from pixels */
334 
335  FileSize = DataOffset + ImageSize;
336 
337  /* convert dots/inch to pixels/meter */
338  if (dpi == 0) dpi = 96;
339  ppm = (int)((double)dpi * 100.0 / 2.54 + 0.5);
340 
341  /*
342  Generate the BMP Header
343  */
344  putchar ('B');
345  putchar ('M');
346 
347  /*
348  Calculate file size:
349 
350  BMP Header + InfoHeader + Color Table + Raster Data
351  */
352  output4 (FileSize); /* FileSize */
353  output4 (0x0000); /* reserved */
354 
355  /* Calculate DataOffset */
356  output4 (DataOffset);
357 
358  /*
359  InfoHeader
360  */
361  output4 (40); /* Size of InfoHeader */
362  output4 (Width); /* Width of bitmap in pixels */
363  output4 (Height); /* Height of bitmap in pixels */
364  output2 (1); /* Planes (1 plane) */
365  output2 (1); /* BitCount (1 = monochrome) */
366  output4 (0); /* Compression (0 = none) */
367  output4 (ImageSize); /* ImageSize, in bytes */
368  output4 (ppm); /* XpixelsPerM (96 dpi = 3780 pixels/meter) */
369  output4 (ppm); /* YpixelsPerM (96 dpi = 3780 pixels/meter) */
370  output4 (2); /* ColorsUsed (= 2) */
371  output4 (2); /* ColorsImportant (= 2) */
372  output4 (0x00000000); /* black (reserved, B, G, R) */
373  output4 (0x00FFFFFF); /* white (reserved, B, G, R) */
374 
375  /*
376  Create header row bits.
377  */
378  snprintf (raw_header, HDR_LEN, "%s Plane %d", HEADER_STRING, plane);
379  memset ((void *)header, 0, 16 * 16 * sizeof (int)); /* fill with white */
380  memset ((void *)header_string, ' ', 32 * sizeof (char)); /* 32 spaces */
381  header_string[32] = '\0'; /* null-terminated */
382 
383  hdrlen = strlen (raw_header);
384  if (hdrlen > 32) hdrlen = 32; /* only 32 columns to print header */
385  startcol = 16 - ((hdrlen + 1) >> 1); /* to center header */
386  /* center up to 32 chars */
387  memcpy (&header_string[startcol], raw_header, hdrlen);
388 
389  /* Copy each letter's bitmap from the plane_array[][] we constructed. */
390  /* Each glyph must be single-width, to fit two glyphs in 16 pixels */
391  for (j = 0; j < 16; j++) {
392  for (i = 0; i < 16; i++) {
393  header[i][j] =
394  (ascii_bits[header_string[j+j ] & 0x7F][i] & 0xFF00) |
395  (ascii_bits[header_string[j+j+1] & 0x7F][i] >> 8);
396  }
397  }
398 
399  /*
400  Create the left column legend.
401  */
402  memset ((void *)leftcol, 0, 4096 * 16 * sizeof (unsigned));
403 
404  for (codept = 0x0000; codept < 0x10000; codept += 0x10) {
405  d1 = (codept >> 12) & 0xF; /* most significant hex digit */
406  d2 = (codept >> 8) & 0xF;
407  d3 = (codept >> 4) & 0xF;
408 
409  thisrow = codept >> 4; /* rows of 16 glyphs */
410 
411  /* fill in first and second digits */
412  for (digitrow = 0; digitrow < 5; digitrow++) {
413  leftcol[thisrow][2 + digitrow] =
414  (hexdigit[d1][digitrow] << 10) |
415  (hexdigit[d2][digitrow] << 4);
416  }
417 
418  /* fill in third digit */
419  for (digitrow = 0; digitrow < 5; digitrow++) {
420  leftcol[thisrow][9 + digitrow] = hexdigit[d3][digitrow] << 10;
421  }
422  leftcol[thisrow][9 + 4] |= 0xF << 4; /* underscore as 4th digit */
423 
424  for (i = 0; i < 15; i ++) {
425  leftcol[thisrow][i] |= 0x00000002; /* right border */
426  }
427 
428  leftcol[thisrow][15] = 0x0000FFFE; /* bottom border */
429 
430  if (d3 == 0xF) { /* 256-point boundary */
431  leftcol[thisrow][15] |= 0x00FF0000; /* longer tic mark */
432  }
433 
434  if ((thisrow % 0x40) == 0x3F) { /* 1024-point boundary */
435  leftcol[thisrow][15] |= 0xFFFF0000; /* longest tic mark */
436  }
437  }
438 
439  /*
440  Create the top row legend.
441  */
442  memset ((void *)toprow, 0, 16 * 16 * sizeof (unsigned));
443 
444  for (codept = 0x0; codept <= 0xF; codept++) {
445  d1 = (codept >> 12) & 0xF; /* most significant hex digit */
446  d2 = (codept >> 8) & 0xF;
447  d3 = (codept >> 4) & 0xF;
448  d4 = codept & 0xF; /* least significant hex digit */
449 
450  /* fill in last digit */
451  for (digitrow = 0; digitrow < 5; digitrow++) {
452  toprow[6 + digitrow][codept] = hexdigit[d4][digitrow] << 6;
453  }
454  }
455 
456  for (j = 0; j < 16; j++) {
457  /* force bottom pixel row to be white, for separation from glyphs */
458  toprow[15][j] = 0x0000;
459  }
460 
461  /* 1 pixel row with left-hand legend line */
462  for (j = 0; j < 16; j++) {
463  toprow[14][j] |= 0xFFFF;
464  }
465 
466  /* 14 rows with line on left to fill out this character row */
467  for (i = 13; i >= 0; i--) {
468  for (j = 0; j < 16; j++) {
469  toprow[i][j] |= 0x0001;
470  }
471  }
472 
473  /*
474  Now write the raster image.
475 
476  XOR each byte with 0xFF because black = 0, white = 1 in BMP.
477  */
478 
479  /* Write the glyphs, bottom-up, left-to-right, in rows of 16 (i.e., 0x10) */
480  for (i = 0xFFF0; i >= 0; i -= 0x10) {
481  thisrow = i >> 4; /* 16 glyphs per row */
482  for (j = 15; j >= 0; j--) {
483  /* left-hand legend */
484  putchar ((~leftcol[thisrow][j] >> 24) & 0xFF);
485  putchar ((~leftcol[thisrow][j] >> 16) & 0xFF);
486  putchar ((~leftcol[thisrow][j] >> 8) & 0xFF);
487  putchar ( ~leftcol[thisrow][j] & 0xFF);
488  /* Unifont glyph */
489  for (k = 0; k < 16; k++) {
490  bytesout = ~plane_array[i+k][j] & 0xFFFF;
491  putchar ((bytesout >> 8) & 0xFF);
492  putchar ( bytesout & 0xFF);
493  }
494  }
495  }
496 
497  /*
498  Write the top legend.
499  */
500  /* i == 15: bottom pixel row of header is output here */
501  /* left-hand legend: solid black line except for right-most pixel */
502  putchar (0x00);
503  putchar (0x00);
504  putchar (0x00);
505  putchar (0x01);
506  for (j = 0; j < 16; j++) {
507  putchar ((~toprow[15][j] >> 8) & 0xFF);
508  putchar ( ~toprow[15][j] & 0xFF);
509  }
510 
511  putchar (0xFF);
512  putchar (0xFF);
513  putchar (0xFF);
514  putchar (0xFC);
515  for (j = 0; j < 16; j++) {
516  putchar ((~toprow[14][j] >> 8) & 0xFF);
517  putchar ( ~toprow[14][j] & 0xFF);
518  }
519 
520  for (i = 13; i >= 0; i--) {
521  putchar (0xFF);
522  putchar (0xFF);
523  putchar (0xFF);
524  putchar (0xFD);
525  for (j = 0; j < 16; j++) {
526  putchar ((~toprow[i][j] >> 8) & 0xFF);
527  putchar ( ~toprow[i][j] & 0xFF);
528  }
529  }
530 
531  /*
532  Write the header.
533  */
534 
535  /* 7 completely white rows */
536  for (i = 7; i >= 0; i--) {
537  for (j = 0; j < 18; j++) {
538  putchar (0xFF);
539  putchar (0xFF);
540  }
541  }
542 
543  for (i = 15; i >= 0; i--) {
544  /* left-hand legend */
545  putchar (0xFF);
546  putchar (0xFF);
547  putchar (0xFF);
548  putchar (0xFF);
549  /* header glyph */
550  for (j = 0; j < 16; j++) {
551  bytesout = ~header[i][j] & 0xFFFF;
552  putchar ((bytesout >> 8) & 0xFF);
553  putchar ( bytesout & 0xFF);
554  }
555  }
556 
557  /* 8 completely white rows at very top */
558  for (i = 7; i >= 0; i--) {
559  for (j = 0; j < 18; j++) {
560  putchar (0xFF);
561  putchar (0xFF);
562  }
563  }
564 
565  return;
566 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ genwidebmp()

void genwidebmp ( int  plane_array[0x10000][16],
int  dpi,
int  tinynum,
int  plane 
)

Generate the BMP output file in wide format.

This function generates the BMP output file from a bitmap parameter. This is a wide bitmap, 256 glyphs wide by 256 glyphs tall.

Parameters
[in]plane_arrayThe array of glyph bitmaps for a plane.
[in]dpiDots per inch, for encoding in the BMP output file header.
[in]tinynumWhether to generate tiny numbers in 256x256 grid.
[in]planeThe Unicode plane, 0..17.

Definition at line 581 of file unifontpic.c.

582 {
583 
584  char header_string[257];
585  char raw_header[HDR_LEN];
586  int header[16][256]; /* header row, for chart title */
587  int hdrlen; /* length of HEADER_STRING */
588  int startcol; /* column to start printing header, for centering */
589 
590  unsigned leftcol[0x100][16]; /* code point legend on left side of chart */
591  int d1, d2, d3, d4; /* digits for filling leftcol[][] legend */
592  int codept; /* current starting code point for legend */
593  int thisrow; /* glyph row currently being rendered */
594  unsigned toprow[32][256]; /* code point legend on top of chart */
595  int digitrow; /* row we're in (0..4) for the above hexdigit digits */
596  int hexalpha1, hexalpha2; /* to convert hex digits to ASCII */
597 
598  /*
599  DataOffset = BMP Header bytes + InfoHeader bytes + ColorTable bytes.
600  */
601  int DataOffset = 14 + 40 + 8; /* fixed size for monochrome BMP */
602  int ImageSize;
603  int FileSize;
604  int Width, Height; /* bitmap image width and height in pixels */
605  int ppm; /* integer pixels per meter */
606 
607  int i, j, k;
608 
609  unsigned bytesout;
610 
611  void output4(int), output2(int);
612 
613  /*
614  Image width and height, in pixels.
615 
616  N.B.: Width must be an even multiple of 32 pixels, or 4 bytes.
617  */
618  Width = 258 * 16; /* ( 2 legend + 256 glyphs) * 16 pixels/glyph */
619  Height = 260 * 16; /* (2 header + 2 legend + 256 glyphs) * 16 rows/glyph */
620 
621  ImageSize = Height * (Width / 8); /* in bytes, calculated from pixels */
622 
623  FileSize = DataOffset + ImageSize;
624 
625  /* convert dots/inch to pixels/meter */
626  if (dpi == 0) dpi = 96;
627  ppm = (int)((double)dpi * 100.0 / 2.54 + 0.5);
628 
629  /*
630  Generate the BMP Header
631  */
632  putchar ('B');
633  putchar ('M');
634  /*
635  Calculate file size:
636 
637  BMP Header + InfoHeader + Color Table + Raster Data
638  */
639  output4 (FileSize); /* FileSize */
640  output4 (0x0000); /* reserved */
641  /* Calculate DataOffset */
642  output4 (DataOffset);
643 
644  /*
645  InfoHeader
646  */
647  output4 (40); /* Size of InfoHeader */
648  output4 (Width); /* Width of bitmap in pixels */
649  output4 (Height); /* Height of bitmap in pixels */
650  output2 (1); /* Planes (1 plane) */
651  output2 (1); /* BitCount (1 = monochrome) */
652  output4 (0); /* Compression (0 = none) */
653  output4 (ImageSize); /* ImageSize, in bytes */
654  output4 (ppm); /* XpixelsPerM (96 dpi = 3780 pixels/meter) */
655  output4 (ppm); /* YpixelsPerM (96 dpi = 3780 pixels/meter) */
656  output4 (2); /* ColorsUsed (= 2) */
657  output4 (2); /* ColorsImportant (= 2) */
658  output4 (0x00000000); /* black (reserved, B, G, R) */
659  output4 (0x00FFFFFF); /* white (reserved, B, G, R) */
660 
661  /*
662  Create header row bits.
663  */
664  snprintf (raw_header, HDR_LEN, "%s Plane %d", HEADER_STRING, plane);
665  memset ((void *)header, 0, 256 * 16 * sizeof (int)); /* fill with white */
666  memset ((void *)header_string, ' ', 256 * sizeof (char)); /* 256 spaces */
667  header_string[256] = '\0'; /* null-terminated */
668 
669  hdrlen = strlen (raw_header);
670  /* Wide bitmap can print 256 columns, but limit to 32 columns for long bitmap. */
671  if (hdrlen > 32) hdrlen = 32;
672  startcol = 127 - ((hdrlen - 1) >> 1); /* to center header */
673  /* center up to 32 chars */
674  memcpy (&header_string[startcol], raw_header, hdrlen);
675 
676  /* Copy each letter's bitmap from the plane_array[][] we constructed. */
677  for (j = 0; j < 256; j++) {
678  for (i = 0; i < 16; i++) {
679  header[i][j] = ascii_bits[header_string[j] & 0x7F][i];
680  }
681  }
682 
683  /*
684  Create the left column legend.
685  */
686  memset ((void *)leftcol, 0, 256 * 16 * sizeof (unsigned));
687 
688  for (codept = 0x0000; codept < 0x10000; codept += 0x100) {
689  d1 = (codept >> 12) & 0xF; /* most significant hex digit */
690  d2 = (codept >> 8) & 0xF;
691 
692  thisrow = codept >> 8; /* rows of 256 glyphs */
693 
694  /* fill in first and second digits */
695 
696  if (tinynum) { /* use 4x5 pixel glyphs */
697  for (digitrow = 0; digitrow < 5; digitrow++) {
698  leftcol[thisrow][6 + digitrow] =
699  (hexdigit[d1][digitrow] << 10) |
700  (hexdigit[d2][digitrow] << 4);
701  }
702  }
703  else { /* bigger numbers -- use glyphs from Unifont itself */
704  /* convert hexadecimal digits to ASCII equivalent */
705  hexalpha1 = d1 < 0xA ? '0' + d1 : 'A' + d1 - 0xA;
706  hexalpha2 = d2 < 0xA ? '0' + d2 : 'A' + d2 - 0xA;
707 
708  for (i = 0 ; i < 16; i++) {
709  leftcol[thisrow][i] =
710  (ascii_bits[hexalpha1][i] << 2) |
711  (ascii_bits[hexalpha2][i] >> 6);
712  }
713  }
714 
715  for (i = 0; i < 15; i ++) {
716  leftcol[thisrow][i] |= 0x00000002; /* right border */
717  }
718 
719  leftcol[thisrow][15] = 0x0000FFFE; /* bottom border */
720 
721  if (d2 == 0xF) { /* 4096-point boundary */
722  leftcol[thisrow][15] |= 0x00FF0000; /* longer tic mark */
723  }
724 
725  if ((thisrow % 0x40) == 0x3F) { /* 16,384-point boundary */
726  leftcol[thisrow][15] |= 0xFFFF0000; /* longest tic mark */
727  }
728  }
729 
730  /*
731  Create the top row legend.
732  */
733  memset ((void *)toprow, 0, 32 * 256 * sizeof (unsigned));
734 
735  for (codept = 0x00; codept <= 0xFF; codept++) {
736  d3 = (codept >> 4) & 0xF;
737  d4 = codept & 0xF; /* least significant hex digit */
738 
739  if (tinynum) {
740  for (digitrow = 0; digitrow < 5; digitrow++) {
741  toprow[16 + 6 + digitrow][codept] =
742  (hexdigit[d3][digitrow] << 10) |
743  (hexdigit[d4][digitrow] << 4);
744  }
745  }
746  else {
747  /* convert hexadecimal digits to ASCII equivalent */
748  hexalpha1 = d3 < 0xA ? '0' + d3 : 'A' + d3 - 0xA;
749  hexalpha2 = d4 < 0xA ? '0' + d4 : 'A' + d4 - 0xA;
750  for (i = 0 ; i < 16; i++) {
751  toprow[14 + i][codept] =
752  (ascii_bits[hexalpha1][i] ) |
753  (ascii_bits[hexalpha2][i] >> 7);
754  }
755  }
756  }
757 
758  for (j = 0; j < 256; j++) {
759  /* force bottom pixel row to be white, for separation from glyphs */
760  toprow[16 + 15][j] = 0x0000;
761  }
762 
763  /* 1 pixel row with left-hand legend line */
764  for (j = 0; j < 256; j++) {
765  toprow[16 + 14][j] |= 0xFFFF;
766  }
767 
768  /* 14 rows with line on left to fill out this character row */
769  for (i = 13; i >= 0; i--) {
770  for (j = 0; j < 256; j++) {
771  toprow[16 + i][j] |= 0x0001;
772  }
773  }
774 
775  /* Form the longer tic marks in top legend */
776  for (i = 8; i < 16; i++) {
777  for (j = 0x0F; j < 0x100; j += 0x10) {
778  toprow[i][j] |= 0x0001;
779  }
780  }
781 
782  /*
783  Now write the raster image.
784 
785  XOR each byte with 0xFF because black = 0, white = 1 in BMP.
786  */
787 
788  /* Write the glyphs, bottom-up, left-to-right, in rows of 16 (i.e., 0x10) */
789  for (i = 0xFF00; i >= 0; i -= 0x100) {
790  thisrow = i >> 8; /* 256 glyphs per row */
791  for (j = 15; j >= 0; j--) {
792  /* left-hand legend */
793  putchar ((~leftcol[thisrow][j] >> 24) & 0xFF);
794  putchar ((~leftcol[thisrow][j] >> 16) & 0xFF);
795  putchar ((~leftcol[thisrow][j] >> 8) & 0xFF);
796  putchar ( ~leftcol[thisrow][j] & 0xFF);
797  /* Unifont glyph */
798  for (k = 0x00; k < 0x100; k++) {
799  bytesout = ~plane_array[i+k][j] & 0xFFFF;
800  putchar ((bytesout >> 8) & 0xFF);
801  putchar ( bytesout & 0xFF);
802  }
803  }
804  }
805 
806  /*
807  Write the top legend.
808  */
809  /* i == 15: bottom pixel row of header is output here */
810  /* left-hand legend: solid black line except for right-most pixel */
811  putchar (0x00);
812  putchar (0x00);
813  putchar (0x00);
814  putchar (0x01);
815  for (j = 0; j < 256; j++) {
816  putchar ((~toprow[16 + 15][j] >> 8) & 0xFF);
817  putchar ( ~toprow[16 + 15][j] & 0xFF);
818  }
819 
820  putchar (0xFF);
821  putchar (0xFF);
822  putchar (0xFF);
823  putchar (0xFC);
824  for (j = 0; j < 256; j++) {
825  putchar ((~toprow[16 + 14][j] >> 8) & 0xFF);
826  putchar ( ~toprow[16 + 14][j] & 0xFF);
827  }
828 
829  for (i = 16 + 13; i >= 0; i--) {
830  if (i >= 8) { /* make vertical stroke on right */
831  putchar (0xFF);
832  putchar (0xFF);
833  putchar (0xFF);
834  putchar (0xFD);
835  }
836  else { /* all white */
837  putchar (0xFF);
838  putchar (0xFF);
839  putchar (0xFF);
840  putchar (0xFF);
841  }
842  for (j = 0; j < 256; j++) {
843  putchar ((~toprow[i][j] >> 8) & 0xFF);
844  putchar ( ~toprow[i][j] & 0xFF);
845  }
846  }
847 
848  /*
849  Write the header.
850  */
851 
852  /* 8 completely white rows */
853  for (i = 7; i >= 0; i--) {
854  for (j = 0; j < 258; j++) {
855  putchar (0xFF);
856  putchar (0xFF);
857  }
858  }
859 
860  for (i = 15; i >= 0; i--) {
861  /* left-hand legend */
862  putchar (0xFF);
863  putchar (0xFF);
864  putchar (0xFF);
865  putchar (0xFF);
866  /* header glyph */
867  for (j = 0; j < 256; j++) {
868  bytesout = ~header[i][j] & 0xFFFF;
869  putchar ((bytesout >> 8) & 0xFF);
870  putchar ( bytesout & 0xFF);
871  }
872  }
873 
874  /* 8 completely white rows at very top */
875  for (i = 7; i >= 0; i--) {
876  for (j = 0; j < 258; j++) {
877  putchar (0xFF);
878  putchar (0xFF);
879  }
880  }
881 
882  return;
883 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gethex()

void gethex ( char *  instring,
int  plane_array[0x10000][16],
int  plane 
)

Read a Unifont .hex-format input file from stdin.

Each glyph can be 2, 4, 6, or 8 ASCII hexadecimal digits wide. Glyph height is fixed at 16 pixels.

Parameters
[in]instringOne line from a Unifont .hex-format file.
[in,out]plane_arrayBitmap for this plane, one bitmap row per element.
[in]planeThe Unicode plane, 0..17.

Definition at line 215 of file unifontpic.c.

216 {
217  char *bitstring; /* pointer into instring for glyph bitmap */
218  int i; /* loop variable */
219  int codept; /* the Unicode code point of the current glyph */
220  int glyph_plane; /* Unicode plane of current glyph */
221  int ndigits; /* number of ASCII hexadecimal digits in glyph */
222  int bytespl; /* bytes per line of pixels in a glyph */
223  int temprow; /* 1 row of a quadruple-width glyph */
224  int newrow; /* 1 row of double-width output pixels */
225  unsigned bitmask; /* to mask off 2 bits of long width glyph */
226 
227  /*
228  Read each input line and place its glyph into the bit array.
229  */
230  sscanf (instring, "%X", &codept);
231  glyph_plane = codept >> 16;
232  if (glyph_plane == plane) {
233  codept &= 0xFFFF; /* array index will only have 16 bit address */
234  /* find the colon separator */
235  for (i = 0; (i < 9) && (instring[i] != ':'); i++);
236  i++; /* position past it */
237  bitstring = &instring[i];
238  ndigits = strlen (bitstring);
239  /* don't count '\n' at end of line if present */
240  if (bitstring[ndigits - 1] == '\n') ndigits--;
241  bytespl = ndigits >> 5; /* 16 rows per line, 2 digits per byte */
242 
243  if (bytespl >= 1 && bytespl <= 4) {
244  for (i = 0; i < 16; i++) { /* 16 rows per glyph */
245  /* Read correct number of hexadecimal digits given glyph width */
246  switch (bytespl) {
247  case 1: sscanf (bitstring, "%2X", &temprow);
248  bitstring += 2;
249  temprow <<= 8; /* left-justify single-width glyph */
250  break;
251  case 2: sscanf (bitstring, "%4X", &temprow);
252  bitstring += 4;
253  break;
254  /* cases 3 and 4 widths will be compressed by 50% (see below) */
255  case 3: sscanf (bitstring, "%6X", &temprow);
256  bitstring += 6;
257  temprow <<= 8; /* left-justify */
258  break;
259  case 4: sscanf (bitstring, "%8X", &temprow);
260  bitstring += 8;
261  break;
262  } /* switch on number of bytes per row */
263  /* compress glyph width by 50% if greater than double-width */
264  if (bytespl > 2) {
265  newrow = 0x0000;
266  /* mask off 2 bits at a time to convert each pair to 1 bit out */
267  for (bitmask = 0xC0000000; bitmask != 0; bitmask >>= 2) {
268  newrow <<= 1;
269  if ((temprow & bitmask) != 0) newrow |= 1;
270  }
271  temprow = newrow;
272  } /* done conditioning glyphs beyond double-width */
273  plane_array[codept][i] = temprow; /* store glyph bitmap for output */
274  } /* for each row */
275  } /* if 1 to 4 bytes per row/line */
276  } /* if this is the plane we are seeking */
277 
278  return;
279 }
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)

The main function.

Parameters
[in]argcThe count of command line arguments.
[in]argvPointer to array of command line arguments.
Returns
This program exits with status EXIT_SUCCESS.

Definition at line 87 of file unifontpic.c.

88 {
89  /* Input line buffer */
90  char instring[MAXSTRING];
91 
92  /* long and dpi are set from command-line options */
93  int wide=1; /* =1 for a 256x256 grid, =0 for a 16x4096 grid */
94  int dpi=96; /* change for 256x256 grid to fit paper if desired */
95  int tinynum=0; /* whether to use tiny labels for 256x256 grid */
96 
97  int i, j; /* loop variables */
98 
99  int plane=0; /* Unicode plane, 0..17; Plane 0 is default */
100  /* 16 pixel rows for each of 65,536 glyphs in a Unicode plane */
101  int plane_array[0x10000][16];
102 
103  void gethex();
104  void genlongbmp();
105  void genwidebmp();
106 
107  if (argc > 1) {
108  for (i = 1; i < argc; i++) {
109  if (strncmp (argv[i],"-l",2) == 0) { /* long display */
110  wide = 0;
111  }
112  else if (strncmp (argv[i],"-d",2) == 0) {
113  dpi = atoi (&argv[i][2]); /* dots/inch specified on command line */
114  }
115  else if (strncmp (argv[i],"-t",2) == 0) {
116  tinynum = 1;
117  }
118  else if (strncmp (argv[i],"-P",2) == 0) {
119  /* Get Unicode plane */
120  for (j = 2; argv[i][j] != '\0'; j++) {
121  if (argv[i][j] < '0' || argv[i][j] > '9') {
122  fprintf (stderr,
123  "ERROR: Specify Unicode plane as decimal number.\n\n");
124  exit (EXIT_FAILURE);
125  }
126  }
127  plane = atoi (&argv[i][2]); /* Unicode plane, 0..17 */
128  if (plane < 0 || plane > 17) {
129  fprintf (stderr,
130  "ERROR: Plane out of Unicode range [0,17].\n\n");
131  exit (EXIT_FAILURE);
132  }
133  }
134  }
135  }
136 
137 
138  /*
139  Initialize the ASCII bitmap array for chart titles
140  */
141  for (i = 0; i < 128; i++) {
142  gethex (ascii_hex[i], plane_array, 0); /* convert Unifont hexadecimal string to bitmap */
143  for (j = 0; j < 16; j++) ascii_bits[i][j] = plane_array[i][j];
144  }
145 
146 
147  /*
148  Read in the Unifont hex file to render from standard input
149  */
150  memset ((void *)plane_array, 0, 0x10000 * 16 * sizeof (int));
151  while (fgets (instring, MAXSTRING, stdin) != NULL) {
152  gethex (instring, plane_array, plane); /* read .hex input file and fill plane_array with glyph data */
153  } /* while not EOF */
154 
155 
156  /*
157  Write plane_array glyph data to BMP file as wide or long bitmap.
158  */
159  if (wide) {
160  genwidebmp (plane_array, dpi, tinynum, plane);
161  }
162  else {
163  genlongbmp (plane_array, dpi, tinynum, plane);
164  }
165 
166  exit (EXIT_SUCCESS);
167 }
Here is the call graph for this function:

◆ output2()

void output2 ( int  thisword)

Output a 2-byte integer in little-endian order.

Parameters
[in]thiswordThe 2-byte integer to output as binary data.

Definition at line 194 of file unifontpic.c.

195 {
196 
197  putchar ( thisword & 0xFF);
198  putchar ((thisword >> 8) & 0xFF);
199 
200  return;
201 }
Here is the caller graph for this function:

◆ output4()

void output4 ( int  thisword)

Output a 4-byte integer in little-endian order.

Parameters
[in]thiswordThe 4-byte integer to output as binary data.

Definition at line 176 of file unifontpic.c.

177 {
178 
179  putchar ( thisword & 0xFF);
180  putchar ((thisword >> 8) & 0xFF);
181  putchar ((thisword >> 16) & 0xFF);
182  putchar ((thisword >> 24) & 0xFF);
183 
184  return;
185 }
Here is the caller graph for this function:
ascii_hex
const char * ascii_hex[128]
Array of Unifont ASCII glyphs for chart row & column headings.
Definition: unifontpic.h:40
genwidebmp
void genwidebmp(int plane_array[0x10000][16], int dpi, int tinynum, int plane)
Generate the BMP output file in wide format.
Definition: unifontpic.c:581
genlongbmp
void genlongbmp(int plane_array[0x10000][16], int dpi, int tinynum, int plane)
Generate the BMP output file in long format.
Definition: unifontpic.c:294
hexdigit
unsigned hexdigit[16][4]
32 bit representation of 16x8 0..F bitmap
Definition: unibmp2hex.c:107
output2
void output2(int thisword)
Output a 2-byte integer in little-endian order.
Definition: unifontpic.c:194
HDR_LEN
#define HDR_LEN
Definition: unifontpic.c:67
output4
void output4(int thisword)
Output a 4-byte integer in little-endian order.
Definition: unifontpic.c:176
MAXSTRING
#define MAXSTRING
Definition: unifont1per.c:57
HEADER_STRING
#define HEADER_STRING
To be printed as chart title.
Definition: unifontpic.h:30
ascii_bits
int ascii_bits[128][16]
Array to hold ASCII bitmaps for chart title.
Definition: unifontpic.h:177
gethex
void gethex(char *instring, int plane_array[0x10000][16], int plane)
Read a Unifont .hex-format input file from stdin.
Definition: unifontpic.c:215