GNU Unifont 15.1.04
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.
 
void output4 (int thisword)
 Output a 4-byte integer in little-endian order.
 
void output2 (int thisword)
 Output a 2-byte integer in little-endian order.
 
void gethex (char *instring, int plane_array[0x10000][16], int plane)
 Read a Unifont .hex-format input file from stdin.
 
void genlongbmp (int plane_array[0x10000][16], int dpi, int tinynum, int plane)
 Generate the BMP output file in long format.
 
void genwidebmp (int plane_array[0x10000][16], int dpi, int tinynum, int plane)
 Generate the BMP output file in wide format.
 

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 73 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 303 of file unifontpic.c.

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

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

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

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

204{
205
206 putchar ( thisword & 0xFF);
207 putchar ((thisword >> 8) & 0xFF);
208
209 return;
210}
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 185 of file unifontpic.c.

186{
187
188 putchar ( thisword & 0xFF);
189 putchar ((thisword >> 8) & 0xFF);
190 putchar ((thisword >> 16) & 0xFF);
191 putchar ((thisword >> 24) & 0xFF);
192
193 return;
194}
Here is the caller graph for this function: