Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/font/font.c
          +++ new/usr/src/uts/common/font/font.c
↓ open down ↓ 26 lines elided ↑ open up ↑
  27   27  /*
  28   28   * Copyright 2017 Toomas Soome <tsoome@me.com>
  29   29   */
  30   30  
  31   31  /*
  32   32   * Generic font related data and functions shared by early boot console
  33   33   * in dboot, kernel startup and full kernel.
  34   34   */
  35   35  #include <sys/types.h>
  36   36  #include <sys/systm.h>
       37 +#include <sys/tem_impl.h>
  37   38  #include <sys/font.h>
  38   39  #include <sys/sysmacros.h>
  39   40  
  40   41  /*
       42 + * To simplify my life, I am "temporarily" collecting the commonly used
       43 + * color bits here. The bits shared between loader, dboot, early boot, tem.
       44 + * This data would need some sort of API, but I am in no condition to figure
       45 + * something out right now.
       46 + */
       47 +
       48 +/* ANSI color to sun color translation. */
       49 +/* BEGIN CSTYLED */
       50 +/*                            Bk  Rd  Gr  Br  Bl  Mg  Cy  Wh */
       51 +const uint8_t dim_xlate[] = {  1,  5,  3,  7,  2,  6,  4,  8 };
       52 +const uint8_t brt_xlate[] = {  9, 13, 11, 15, 10, 14, 12,  0 };
       53 +
       54 +/* The pc color here is actually referring to standard 16 color VGA map. */
       55 +const uint8_t solaris_color_to_pc_color[16] = {
       56 +    15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
       57 +};
       58 +
       59 +/* 4-bit to 24-bit color translation. */
       60 +const text_cmap_t cmap4_to_24 = {
       61 +/* 0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
       62 +  Wh+  Bk   Bl   Gr   Cy   Rd   Mg   Br   Wh   Bk+  Bl+  Gr+  Cy+  Rd+  Mg+  Yw */
       63 +  .red = {
       64 + 0xff,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x40,0x00,0x00,0x00,0xff,0xff,0xff
       65 +},
       66 +  .green = {
       67 + 0xff,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x80,0x40,0x00,0xff,0xff,0x00,0x00,0xff
       68 +},
       69 +  .blue = {
       70 + 0xff,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x40,0xff,0x00,0xff,0x00,0xff,0x00
       71 +}
       72 +};
       73 +/* END CSTYLED */
       74 +
       75 +/*
  41   76   * Fonts are statically linked with this module. At some point an
  42   77   * RFE might be desireable to allow dynamic font loading.  The
  43   78   * original intention to facilitate dynamic fonts can be seen
  44   79   * by examining the data structures and set_font().  As much of
  45   80   * the original code is retained but modified to be suited for
  46   81   * traversing a list of static fonts.
  47   82   */
  48   83  
  49   84  /*
  50   85   * Must be sorted by font size in descending order
  51   86   */
  52      -struct fontlist fonts[] = {
  53      -        {  &font_data_12x22,    NULL  },
  54      -        {  &font_data_8x16,     NULL  },
  55      -        {  &font_data_7x14,     NULL  },
  56      -        {  &font_data_6x10,     NULL  },
  57      -        {  NULL, NULL  }
  58      -};
       87 +font_list_t fonts = STAILQ_HEAD_INITIALIZER(fonts);
  59   88  
  60      -void
  61      -set_font(struct font *f, short *rows, short *cols, short height, short width)
       89 +bitmap_data_t *
       90 +set_font(short *rows, short *cols, short height, short width)
  62   91  {
  63      -        bitmap_data_t   *font_selected = NULL;
       92 +        bitmap_data_t *font = NULL;
  64   93          struct fontlist *fl;
  65      -        int i;
  66   94  
  67   95          /*
       96 +         * First check for manually loaded font.
       97 +         */
       98 +        STAILQ_FOREACH(fl, &fonts, font_next) {
       99 +                if (fl->font_flags == FONT_MANUAL ||
      100 +                    fl->font_flags == FONT_BOOT) {
      101 +                        font = fl->font_data;
      102 +                        if (font->font == NULL && fl->font_load != NULL &&
      103 +                            fl->font_name != NULL) {
      104 +                                font = fl->font_load(fl->font_name);
      105 +                        }
      106 +                        if (font == NULL || font->font == NULL)
      107 +                                font = NULL;
      108 +                        break;
      109 +                }
      110 +        }
      111 +
      112 +        if (font != NULL) {
      113 +                *rows = (height - BORDER_PIXELS) / font->height;
      114 +                *cols = (width - BORDER_PIXELS) / font->width;
      115 +                return (font);
      116 +        }
      117 +
      118 +        /*
  68  119           * Find best font for these dimensions, or use default
  69  120           *
  70  121           * A 1 pixel border is the absolute minimum we could have
  71  122           * as a border around the text window (BORDER_PIXELS = 2),
  72  123           * however a slightly larger border not only looks better
  73  124           * but for the fonts currently statically built into the
  74  125           * emulator causes much better font selection for the
  75  126           * normal range of screen resolutions.
  76  127           */
  77      -        for (fl = fonts; fl->data; fl++) {
  78      -                if ((((*rows * fl->data->height) + BORDER_PIXELS) <= height) &&
  79      -                    (((*cols * fl->data->width) + BORDER_PIXELS) <= width)) {
  80      -                        font_selected = fl->data;
      128 +        STAILQ_FOREACH(fl, &fonts, font_next) {
      129 +                font = fl->font_data;
      130 +                if ((((*rows * font->height) + BORDER_PIXELS) <= height) &&
      131 +                    (((*cols * font->width) + BORDER_PIXELS) <= width)) {
      132 +                        if (font->font == NULL) {
      133 +                                if (fl->font_load != NULL &&
      134 +                                    fl->font_name != NULL) {
      135 +                                        font = fl->font_load(fl->font_name);
      136 +                                }
      137 +                                if (font == NULL)
      138 +                                        continue;
      139 +                        }
      140 +                        *rows = (height - BORDER_PIXELS) / font->height;
      141 +                        *cols = (width - BORDER_PIXELS) / font->width;
  81  142                          break;
  82  143                  }
      144 +                font = NULL;
  83  145          }
  84      -        /*
  85      -         * The minus 2 is to make sure we have at least a 1 pixel
  86      -         * border around the entire screen.
  87      -         */
  88      -        if (font_selected == NULL) {
  89      -                if (((*rows * DEFAULT_FONT_DATA.height) > height) ||
  90      -                    ((*cols * DEFAULT_FONT_DATA.width) > width)) {
  91      -                        *rows = (height - 2) / DEFAULT_FONT_DATA.height;
  92      -                        *cols = (width - 2) / DEFAULT_FONT_DATA.width;
      146 +
      147 +        if (font == NULL) {
      148 +                /*
      149 +                 * We have fonts sorted smallest last, try it before
      150 +                 * falling back to builtin.
      151 +                 */
      152 +                fl = STAILQ_LAST(&fonts, fontlist, font_next);
      153 +                if (fl != NULL && fl->font_load != NULL &&
      154 +                    fl->font_name != NULL) {
      155 +                        font = fl->font_load(fl->font_name);
  93  156                  }
  94      -                font_selected = &DEFAULT_FONT_DATA;
      157 +                if (font == NULL)
      158 +                        font = &DEFAULT_FONT_DATA;
      159 +
      160 +                *rows = (height - BORDER_PIXELS) / font->height;
      161 +                *cols = (width - BORDER_PIXELS) / font->width;
  95  162          }
  96  163  
  97      -        f->width = font_selected->width;
  98      -        f->height = font_selected->height;
      164 +        return (font);
      165 +}
  99  166  
 100      -        for (i = 0; i < ENCODED_CHARS; i++)
 101      -                f->char_ptr[i] = font_selected->encoding[i];
      167 +/* Binary search for the glyph. Return 0 if not found. */
      168 +static uint16_t
      169 +font_bisearch(const struct font_map *map, uint32_t len, uint32_t src)
      170 +{
      171 +        int min, mid, max;
 102  172  
 103      -        f->image_data = font_selected->image;
      173 +        min = 0;
      174 +        max = len - 1;
 104  175  
      176 +        /* Empty font map. */
      177 +        if (len == 0)
      178 +                return (0);
      179 +        /* Character below minimal entry. */
      180 +        if (src < map[0].font_src)
      181 +                return (0);
      182 +        /* Optimization: ASCII characters occur very often. */
      183 +        if (src <= map[0].font_src + map[0].font_len)
      184 +                return (src - map[0].font_src + map[0].font_dst);
      185 +        /* Character above maximum entry. */
      186 +        if (src > map[max].font_src + map[max].font_len)
      187 +                return (0);
      188 +
      189 +        /* Binary search. */
      190 +        while (max >= min) {
      191 +                mid = (min + max) / 2;
      192 +                if (src < map[mid].font_src)
      193 +                        max = mid - 1;
      194 +                else if (src > map[mid].font_src + map[mid].font_len)
      195 +                        min = mid + 1;
      196 +                else
      197 +                        return (src - map[mid].font_src + map[mid].font_dst);
      198 +        }
      199 +
      200 +        return (0);
 105  201  }
 106  202  
 107  203  /*
      204 + * Return glyph bitmap. If glyph is not found, we will return bitmap
      205 + * for the first (offset 0) glyph.
      206 + */
      207 +const uint8_t *
      208 +font_lookup(const struct font *vf, uint32_t c)
      209 +{
      210 +        uint32_t src;
      211 +        uint16_t dst;
      212 +        size_t stride;
      213 +
      214 +        src = TEM_CHAR(c);
      215 +
      216 +        /* Substitute bold with normal if not found. */
      217 +        if (TEM_CHAR_ATTR(c) & TEM_ATTR_BOLD) {
      218 +                dst = font_bisearch(vf->vf_map[VFNT_MAP_BOLD],
      219 +                    vf->vf_map_count[VFNT_MAP_BOLD], src);
      220 +                if (dst != 0)
      221 +                        goto found;
      222 +        }
      223 +        dst = font_bisearch(vf->vf_map[VFNT_MAP_NORMAL],
      224 +            vf->vf_map_count[VFNT_MAP_NORMAL], src);
      225 +
      226 +found:
      227 +        stride = howmany(vf->vf_width, 8) * vf->vf_height;
      228 +        return (&vf->vf_bytes[dst * stride]);
      229 +}
      230 +
      231 +/*
 108  232   * bit_to_pix4 is for 4-bit frame buffers.  It will write one output byte
 109  233   * for each 2 bits of input bitmap.  It inverts the input bits before
 110  234   * doing the output translation, for reverse video.
 111  235   *
 112  236   * Assuming foreground is 0001 and background is 0000...
 113  237   * An input data byte of 0x53 will output the bit pattern
 114  238   * 00000001 00000001 00000000 00010001.
 115  239   */
 116  240  
 117  241  void
 118  242  font_bit_to_pix4(
 119  243      struct font *f,
 120  244      uint8_t *dest,
 121      -    uint8_t c,
      245 +    uint32_t c,
 122  246      uint8_t fg_color,
 123  247      uint8_t bg_color)
 124  248  {
 125  249          int     row;
 126  250          int     byte;
 127  251          int     i;
 128      -        uint8_t *cp;
      252 +        const uint8_t *cp;
 129  253          uint8_t data;
 130  254          uint8_t nibblett;
 131  255          int     bytes_wide;
 132  256  
 133      -        cp = f->char_ptr[c];
 134      -        bytes_wide = (f->width + 7) / 8;
      257 +        cp = font_lookup(f, c);
      258 +        bytes_wide = (f->vf_width + 7) / 8;
 135  259  
 136      -        for (row = 0; row < f->height; row++) {
      260 +        for (row = 0; row < f->vf_height; row++) {
 137  261                  for (byte = 0; byte < bytes_wide; byte++) {
 138  262                          data = *cp++;
 139  263                          for (i = 0; i < 4; i++) {
 140  264                                  nibblett = (data >> ((3-i) * 2)) & 0x3;
 141  265                                  switch (nibblett) {
 142  266                                  case 0x0:
 143  267                                          *dest++ = bg_color << 4 | bg_color;
 144  268                                          break;
 145  269                                  case 0x1:
 146  270                                          *dest++ = bg_color << 4 | fg_color;
↓ open down ↓ 17 lines elided ↑ open up ↑
 164  288   *
 165  289   * Assuming foreground is 00000001 and background is 00000000...
 166  290   * An input data byte of 0x53 will output the bit pattern
 167  291   * 0000000 000000001 00000000 00000001 00000000 00000000 00000001 00000001.
 168  292   */
 169  293  
 170  294  void
 171  295  font_bit_to_pix8(
 172  296      struct font *f,
 173  297      uint8_t *dest,
 174      -    uint8_t c,
      298 +    uint32_t c,
 175  299      uint8_t fg_color,
 176  300      uint8_t bg_color)
 177  301  {
 178  302          int     row;
 179  303          int     byte;
 180  304          int     i;
 181      -        uint8_t *cp;
      305 +        const uint8_t *cp;
 182  306          uint8_t data;
 183  307          int     bytes_wide;
 184  308          uint8_t mask;
 185  309          int     bitsleft, nbits;
 186  310  
 187      -        cp = f->char_ptr[c];
 188      -        bytes_wide = (f->width + 7) / 8;
      311 +        cp = font_lookup(f, c);
      312 +        bytes_wide = (f->vf_width + 7) / 8;
 189  313  
 190      -        for (row = 0; row < f->height; row++) {
 191      -                bitsleft = f->width;
      314 +        for (row = 0; row < f->vf_height; row++) {
      315 +                bitsleft = f->vf_width;
 192  316                  for (byte = 0; byte < bytes_wide; byte++) {
 193  317                          data = *cp++;
 194  318                          mask = 0x80;
 195  319                          nbits = MIN(8, bitsleft);
 196  320                          bitsleft -= nbits;
 197  321                          for (i = 0; i < nbits; i++) {
 198  322                                  *dest++ = (data & mask ? fg_color: bg_color);
 199  323                                  mask = mask >> 1;
 200  324                          }
 201  325                  }
 202  326          }
 203  327  }
 204  328  
 205  329  /*
 206      - * bit_to_pix24 is for 24-bit frame buffers.  It will write four output bytes
      330 + * bit_to_pix16 is for 16-bit frame buffers.  It will write two output bytes
 207  331   * for each bit of input bitmap.  It inverts the input bits before
      332 + * doing the output translation, for reverse video.
      333 + *
      334 + * Assuming foreground is 11111111 11111111
      335 + * and background is 00000000 00000000
      336 + * An input data byte of 0x53 will output the bit pattern
      337 + *
      338 + * 00000000 00000000
      339 + * 11111111 11111111
      340 + * 00000000 00000000
      341 + * 11111111 11111111
      342 + * 00000000 00000000
      343 + * 00000000 00000000
      344 + * 11111111 11111111
      345 + * 11111111 11111111
      346 + *
      347 + */
      348 +
      349 +void
      350 +font_bit_to_pix16(
      351 +    struct font *f,
      352 +    uint16_t *dest,
      353 +    uint32_t c,
      354 +    uint16_t fg_color16,
      355 +    uint16_t bg_color16)
      356 +{
      357 +        int     row;
      358 +        int     byte;
      359 +        int     i;
      360 +        const uint8_t   *cp;
      361 +        uint16_t data, d;
      362 +        int     bytes_wide;
      363 +        int     bitsleft, nbits;
      364 +
      365 +        cp = font_lookup(f, c);
      366 +        bytes_wide = (f->vf_width + 7) / 8;
      367 +
      368 +        for (row = 0; row < f->vf_height; row++) {
      369 +                bitsleft = f->vf_width;
      370 +                for (byte = 0; byte < bytes_wide; byte++) {
      371 +                        data = *cp++;
      372 +                        nbits = MIN(8, bitsleft);
      373 +                        bitsleft -= nbits;
      374 +                        for (i = 0; i < nbits; i++) {
      375 +                                d = ((data << i) & 0x80 ?
      376 +                                    fg_color16 : bg_color16);
      377 +                                *dest++ = d;
      378 +                        }
      379 +                }
      380 +        }
      381 +}
      382 +
      383 +/*
      384 + * bit_to_pix24 is for 24-bit frame buffers.  It will write three output bytes
      385 + * for each bit of input bitmap.  It inverts the input bits before
      386 + * doing the output translation, for reverse video.
      387 + *
      388 + * Assuming foreground is 11111111 11111111 11111111
      389 + * and background is 00000000 00000000 00000000
      390 + * An input data byte of 0x53 will output the bit pattern
      391 + *
      392 + * 00000000 00000000 00000000
      393 + * 11111111 11111111 11111111
      394 + * 00000000 00000000 00000000
      395 + * 11111111 11111111 11111111
      396 + * 00000000 00000000 00000000
      397 + * 00000000 00000000 00000000
      398 + * 11111111 11111111 11111111
      399 + * 11111111 11111111 11111111
      400 + *
      401 + */
      402 +
      403 +void
      404 +font_bit_to_pix24(
      405 +    struct font *f,
      406 +    uint8_t *dest,
      407 +    uint32_t c,
      408 +    uint32_t fg_color32,
      409 +    uint32_t bg_color32)
      410 +{
      411 +        int     row;
      412 +        int     byte;
      413 +        int     i;
      414 +        const uint8_t   *cp;
      415 +        uint32_t data, d;
      416 +        int     bytes_wide;
      417 +        int     bitsleft, nbits;
      418 +
      419 +        cp = font_lookup(f, c);
      420 +        bytes_wide = (f->vf_width + 7) / 8;
      421 +
      422 +        for (row = 0; row < f->vf_height; row++) {
      423 +                bitsleft = f->vf_width;
      424 +                for (byte = 0; byte < bytes_wide; byte++) {
      425 +                        data = *cp++;
      426 +                        nbits = MIN(8, bitsleft);
      427 +                        bitsleft -= nbits;
      428 +                        for (i = 0; i < nbits; i++) {
      429 +                                d = ((data << i) & 0x80 ?
      430 +                                    fg_color32 : bg_color32);
      431 +                                *dest++ = d & 0xff;
      432 +                                *dest++ = (d >> 8) & 0xff;
      433 +                                *dest++ = (d >> 16) & 0xff;
      434 +                        }
      435 +                }
      436 +        }
      437 +}
      438 +
      439 +/*
      440 + * bit_to_pix32 is for 32-bit frame buffers.  It will write four output bytes
      441 + * for each bit of input bitmap.  It inverts the input bits before
 208  442   * doing the output translation, for reverse video.  Note that each
 209  443   * 24-bit RGB value is finally stored in a 32-bit unsigned int, with the
 210  444   * high-order byte set to zero.
 211  445   *
 212  446   * Assuming foreground is 00000000 11111111 11111111 11111111
 213  447   * and background is 00000000 00000000 00000000 00000000
 214  448   * An input data byte of 0x53 will output the bit pattern
 215  449   *
 216  450   * 00000000 00000000 00000000 00000000
 217  451   * 00000000 11111111 11111111 11111111
 218  452   * 00000000 00000000 00000000 00000000
 219  453   * 00000000 11111111 11111111 11111111
 220  454   * 00000000 00000000 00000000 00000000
 221  455   * 00000000 00000000 00000000 00000000
 222  456   * 00000000 11111111 11111111 11111111
 223  457   * 00000000 11111111 11111111 11111111
 224  458   *
 225  459   */
 226  460  
 227  461  void
 228      -font_bit_to_pix24(
      462 +font_bit_to_pix32(
 229  463      struct font *f,
 230  464      uint32_t *dest,
 231      -    uint8_t c,
      465 +    uint32_t c,
 232  466      uint32_t fg_color32,
 233  467      uint32_t bg_color32)
 234  468  {
 235  469          int     row;
 236  470          int     byte;
 237  471          int     i;
 238      -        uint8_t *cp;
      472 +        const uint8_t *cp, *ul;
 239  473          uint32_t data;
 240  474          int     bytes_wide;
 241  475          int     bitsleft, nbits;
 242  476  
 243      -        cp = f->char_ptr[c];
 244      -        bytes_wide = (f->width + 7) / 8;
      477 +        if (TEM_CHAR_ATTR(c) & TEM_ATTR_UNDERLINE)
      478 +                ul = font_lookup(f, 0x0332);    /* combining low line */
      479 +        else
      480 +                ul = NULL;
 245  481  
 246      -        for (row = 0; row < f->height; row++) {
 247      -                bitsleft = f->width;
      482 +        cp = font_lookup(f, c);
      483 +        bytes_wide = (f->vf_width + 7) / 8;
      484 +
      485 +        for (row = 0; row < f->vf_height; row++) {
      486 +                bitsleft = f->vf_width;
 248  487                  for (byte = 0; byte < bytes_wide; byte++) {
 249      -                        data = *cp++;
      488 +                        if (ul == NULL)
      489 +                                data = *cp++;
      490 +                        else
      491 +                                data = *cp++ | *ul++;
 250  492                          nbits = MIN(8, bitsleft);
 251  493                          bitsleft -= nbits;
 252  494                          for (i = 0; i < nbits; i++) {
 253  495                                  *dest++ = ((data << i) & 0x80 ?
 254  496                                      fg_color32 : bg_color32);
 255  497                          }
 256  498                  }
 257  499          }
 258  500  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX