GNU Unifont: src/unifontpic.c File Reference

GNU Unifont 17.0.04 Pan-Unicode font with complete Unicode Plane 0 coverage and partial coverage of higher planes

Macros | Functions
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

Copyright
  Copyright (C) 2013, 2017 Paul Hardy

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 78 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_array | The array of glyph bitmaps for a plane.
  [in] | dpi | Dots per inch, for encoding in the BMP output file header.
  [in] | tinynum | Whether to generate tiny numbers in wide grid (unused).
  [in] | plane | The Unicode plane, 0..17.

Definition at line 308 of file unifontpic.c.

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

Definition at line 595 of file unifontpic.c.

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

Definition at line 229 of file unifontpic.c.

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

## ◆ main()

int main | ( | int | argc,
|  | char ** | argv
| ) |  |

The main function.

Parameters

  [in] | argc | The count of command line arguments.
  [in] | argv | Pointer to array of command line arguments.

Returns
  This program exits with status EXIT_SUCCESS.

Definition at line 98 of file unifontpic.c.

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

Definition at line 208 of file unifontpic.c.

209{
210
211 putchar ( thisword & 0xFF);
212 putchar ((thisword >> 8) & 0xFF);
213
214 return;
215}
Here is the caller graph for this function:

## ◆ output4()

void output4 | ( | int | thisword | ) |

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

Parameters

  [in] | thisword | The 4-byte integer to output as binary data.

Definition at line 190 of file unifontpic.c.

191{
192
193 putchar ( thisword & 0xFF);
194 putchar ((thisword >> 8) & 0xFF);
195 putchar ((thisword >> 16) & 0xFF);
196 putchar ((thisword >> 24) & 0xFF);
197
198 return;
199}
Here is the caller graph for this function: