GNU Unifont: src/unifontpic.c File Reference

GNU Unifont 15.0.02 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 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_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 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}
hexdigit
unsigned hexdigit[16][4]
32 bit representation of 16x8 0..F bitmap
Definition: unibmp2hex.c:107
output4
void output4(int thisword)
Output a 4-byte integer in little-endian order.
Definition: unifontpic.c:176
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
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
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 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] | 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 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] | 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 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}
MAXSTRING
#define MAXSTRING
Definition: unifont1per.c:57
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
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
ascii_hex
const char * ascii_hex[128]
Array of Unifont ASCII glyphs for chart row & column headings.
Definition: unifontpic.h:40
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 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] | thisword | The 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: