LCOV - code coverage report
Current view: top level - dev/wsfont - wsfont.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 190 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: wsfont.c,v 1.52 2017/09/08 05:36:53 deraadt Exp $ */
       2             : /*      $NetBSD: wsfont.c,v 1.17 2001/02/07 13:59:24 ad Exp $   */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 1999 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Andrew Doran.
      10             :  *
      11             :  * Redistribution and use in source and binary forms, with or without
      12             :  * modification, are permitted provided that the following conditions
      13             :  * are met:
      14             :  * 1. Redistributions of source code must retain the above copyright
      15             :  *    notice, this list of conditions and the following disclaimer.
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in the
      18             :  *    documentation and/or other materials provided with the distribution.
      19             :  *
      20             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      21             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      22             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      23             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      24             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      25             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      26             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      27             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      28             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      29             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      30             :  * POSSIBILITY OF SUCH DAMAGE.
      31             :  */
      32             : 
      33             : #include <sys/param.h>
      34             : #include <sys/systm.h>
      35             : #include <sys/time.h>
      36             : #include <sys/malloc.h>
      37             : #include <sys/queue.h>
      38             : 
      39             : #include <dev/wscons/wsconsio.h>
      40             : #include <dev/wsfont/wsfont.h>
      41             : 
      42             : #include "wsfont_glue.h"      /* NRASOPS_ROTATION */
      43             : 
      44             : #undef HAVE_FONT
      45             : 
      46             : #ifdef FONT_BOLD8x16
      47             : #define HAVE_FONT 1
      48             : #include <dev/wsfont/bold8x16.h>
      49             : #endif
      50             : 
      51             : #ifdef FONT_GALLANT12x22
      52             : #define HAVE_FONT 1
      53             : #endif
      54             : 
      55             : #ifdef FONT_BOLD8x16_ISO1
      56             : #define HAVE_FONT 1
      57             : #endif
      58             : 
      59             : /*
      60             :  * Make sure we always have at least one font.
      61             :  * Unless otherwise configured, all platforms provide both a 8x16 font and a
      62             :  * larger 12x22 font.
      63             :  * Some platforms will however only provide the 8x16 font if option
      64             :  * SMALL_KERNEL.
      65             :  */
      66             : #ifndef HAVE_FONT
      67             : #define HAVE_FONT 1
      68             : 
      69             : #define FONT_BOLD8x16_ISO1
      70             : #if defined(__alpha__) || defined(__luna88k__) || defined(__macppc__) || \
      71             :     defined(__sgi__) || defined(__sparc64__) || \
      72             :     !defined(SMALL_KERNEL)
      73             : #define FONT_GALLANT12x22
      74             : #endif
      75             : 
      76             : #endif  /* HAVE_FONT */
      77             : 
      78             : #ifdef FONT_BOLD8x16_ISO1
      79             : #include <dev/wsfont/bold8x16-iso1.h>
      80             : #endif
      81             : 
      82             : #ifdef FONT_GALLANT12x22
      83             : #include <dev/wsfont/gallant12x22.h>
      84             : #endif
      85             : 
      86             : struct font {
      87             :         TAILQ_ENTRY(font) chain;
      88             :         struct  wsdisplay_font *font;
      89             :         u_short lockcount;
      90             :         u_short cookie;
      91             :         u_short flg;
      92             : };
      93             : TAILQ_HEAD(, font) fontlist;
      94             : 
      95             : /* Our list of built-in fonts */
      96             : static struct font builtin_fonts[] = {
      97             : #define BUILTIN_FONT(f, c) \
      98             :         { .font = &(f), .cookie = (c), .lockcount = 0, \
      99             :           .flg = WSFONT_STATIC | WSFONT_BUILTIN }
     100             : #ifdef FONT_BOLD8x16
     101             :         BUILTIN_FONT(bold8x16, 1),
     102             : #endif
     103             : #ifdef FONT_BOLD8x16_ISO1
     104             :         BUILTIN_FONT(bold8x16_iso1, 2),
     105             : #endif
     106             : #ifdef FONT_GALLANT12x22
     107             :         BUILTIN_FONT(gallant12x22, 3),
     108             : #endif
     109             : #undef BUILTIN_FONT
     110             : };
     111             : 
     112             : #if !defined(SMALL_KERNEL) || defined(__alpha__)
     113             : #define INCLUDE_FONT_BIT_ENDIANNESS_SWAP_CODE
     114             : #endif
     115             : 
     116             : #ifdef INCLUDE_FONT_BIT_ENDIANNESS_SWAP_CODE
     117             : 
     118             : /* Reverse the bit order in a byte */
     119             : static const u_char reverse[256] = {
     120             :         0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
     121             :         0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
     122             :         0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
     123             :         0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
     124             :         0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
     125             :         0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
     126             :         0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
     127             :         0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
     128             :         0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
     129             :         0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
     130             :         0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
     131             :         0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
     132             :         0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
     133             :         0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
     134             :         0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
     135             :         0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
     136             :         0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
     137             :         0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
     138             :         0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
     139             :         0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
     140             :         0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
     141             :         0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
     142             :         0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
     143             :         0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
     144             :         0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
     145             :         0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
     146             :         0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
     147             :         0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
     148             :         0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
     149             :         0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
     150             :         0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
     151             :         0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
     152             : };
     153             : 
     154             : #endif
     155             : 
     156             : static struct font *wsfont_find0(int);
     157             : 
     158             : #ifdef INCLUDE_FONT_BIT_ENDIANNESS_SWAP_CODE
     159             : 
     160             : /*
     161             :  * Reverse the bit order of a font
     162             :  */
     163             : static void     wsfont_revbit(struct wsdisplay_font *);
     164             : static void
     165           0 : wsfont_revbit(struct wsdisplay_font *font)
     166             : {
     167             :         u_char *p, *m;
     168             : 
     169           0 :         p = (u_char *)font->data;
     170           0 :         m = p + font->stride * font->numchars * font->fontheight;
     171             : 
     172           0 :         for (; p < m; p++)
     173           0 :                 *p = reverse[*p];
     174           0 : }
     175             : 
     176             : #endif
     177             : 
     178             : #if !defined(SMALL_KERNEL)
     179             : 
     180             : /*
     181             :  * Reverse the byte order of a font
     182             :  */
     183             : static void     wsfont_revbyte(struct wsdisplay_font *);
     184             : static void
     185           0 : wsfont_revbyte(struct wsdisplay_font *font)
     186             : {
     187             :         int x, l, r, nr;
     188             :         u_char *rp;
     189             : 
     190           0 :         if (font->stride == 1)
     191           0 :                 return;
     192             : 
     193           0 :         rp = (u_char *)font->data;
     194           0 :         nr = font->numchars * font->fontheight;
     195             : 
     196           0 :         while (nr--) {
     197             :                 l = 0;
     198           0 :                 r = font->stride - 1;
     199             : 
     200           0 :                 while (l < r) {
     201           0 :                         x = rp[l];
     202           0 :                         rp[l] = rp[r];
     203           0 :                         rp[r] = x;
     204           0 :                         l++, r--;
     205             :                 }
     206             : 
     207           0 :                 rp += font->stride;
     208             :         }
     209           0 : }
     210             : 
     211             : #endif
     212             : 
     213             : /*
     214             :  * Enumerate the list of fonts
     215             :  */
     216             : void
     217           0 : wsfont_enum(int (*cb)(void *, struct wsdisplay_font *), void *cbarg)
     218             : {
     219             :         struct font *ent;
     220             :         int s;
     221             : 
     222           0 :         s = splhigh();
     223             : 
     224           0 :         TAILQ_FOREACH(ent, &fontlist, chain)
     225           0 :                 if (cb(cbarg, ent->font) != 0)
     226             :                         break;
     227             : 
     228           0 :         splx(s);
     229           0 : }
     230             : 
     231             : #if NRASOPS_ROTATION > 0
     232             : 
     233             : void wsfont_rotate_cw(struct wsdisplay_font *, char *, int);
     234             : void wsfont_rotate_ccw(struct wsdisplay_font *, char *, int);
     235             : struct wsdisplay_font *wsfont_rotate_internal(struct wsdisplay_font *, int);
     236             : 
     237             : void
     238           0 : wsfont_rotate_cw(struct wsdisplay_font *font, char *newbits, int newstride)
     239             : {
     240             :         int b, n, r;
     241             : 
     242             :         /* Rotate the font a bit at a time. */
     243           0 :         for (n = 0; n < font->numchars; n++) {
     244           0 :                 char *ch = font->data + (n * font->stride * font->fontheight);
     245             : 
     246           0 :                 for (r = 0; r < font->fontheight; r++) {
     247           0 :                         for (b = 0; b < font->fontwidth; b++) {
     248             :                                 unsigned char *rb;
     249             : 
     250           0 :                                 rb = ch + (font->stride * r) + (b / 8);
     251           0 :                                 if (*rb & (0x80 >> (b % 8))) {
     252             :                                         unsigned char *rrb;
     253             : 
     254           0 :                                         rrb = newbits + newstride - 1 - (r / 8)
     255           0 :                                             + (n * newstride * font->fontwidth)
     256           0 :                                             + (newstride * b);
     257           0 :                                         *rrb |= (1 << (r % 8));
     258           0 :                                 }
     259             :                         }
     260             :                 }
     261             :         }
     262           0 : }
     263             : 
     264             : void
     265           0 : wsfont_rotate_ccw(struct wsdisplay_font *font, char *newbits, int newstride)
     266             : {
     267             :         int b, n, r;
     268             : 
     269             :         /* Rotate the font a bit at a time. */
     270           0 :         for (n = 0; n < font->numchars; n++) {
     271           0 :                 char *ch = font->data + (n * font->stride * font->fontheight);
     272             : 
     273           0 :                 for (r = 0; r < font->fontheight; r++) {
     274           0 :                         for (b = 0; b < font->fontwidth; b++) {
     275           0 :                                 int bb = font->fontwidth - 1 - b;
     276             :                                 unsigned char *rb;
     277             : 
     278           0 :                                 rb = ch + (font->stride * r) + (b / 8);
     279           0 :                                 if (*rb & (0x80 >> (b % 8))) {
     280             :                                         unsigned char *rrb;
     281             : 
     282           0 :                                         rrb = newbits + (r / 8)
     283           0 :                                             + (n * newstride * font->fontwidth)
     284           0 :                                             + (newstride * bb);
     285           0 :                                         *rrb |= (1 << (7 - (r % 8)));
     286           0 :                                 }
     287             :                         }
     288             :                 }
     289             :         }
     290           0 : }
     291             : 
     292             : struct wsdisplay_font *
     293           0 : wsfont_rotate_internal(struct wsdisplay_font *font, int ccw)
     294             : {
     295             :         int newstride;
     296             :         struct wsdisplay_font *newfont;
     297             :         char *newbits;
     298             : 
     299             :         /* Duplicate the existing font... */
     300           0 :         newfont = malloc(sizeof *font, M_DEVBUF, M_WAITOK);
     301             : 
     302           0 :         bcopy(font, newfont, sizeof *font);
     303           0 :         newfont->cookie = NULL;
     304             : 
     305             :         /* Allocate a buffer big enough for the rotated font. */
     306           0 :         newstride = (font->fontheight + 7) / 8;
     307           0 :         newbits = mallocarray(font->numchars, newstride * font->fontwidth,
     308             :             M_DEVBUF, M_WAITOK | M_ZERO);
     309             : 
     310           0 :         if (ccw)
     311           0 :                 wsfont_rotate_ccw(font, newbits, newstride);
     312             :         else
     313           0 :                 wsfont_rotate_cw(font, newbits, newstride);
     314             : 
     315           0 :         newfont->data = newbits;
     316             : 
     317             :         /* Update font sizes. */
     318           0 :         newfont->stride = newstride;
     319           0 :         newfont->fontwidth = font->fontheight;
     320           0 :         newfont->fontheight = font->fontwidth;
     321             : 
     322           0 :         if (wsfont_add(newfont, 0) != 0) {
     323             :                 /*
     324             :                  * If we seem to have rotated this font already, drop the
     325             :                  * new one...
     326             :                  */
     327           0 :                 free(newbits, M_DEVBUF,
     328           0 :                     font->numchars * newstride * font->fontwidth);
     329           0 :                 free(newfont, M_DEVBUF, sizeof *font);
     330             :                 newfont = NULL;
     331           0 :         }
     332             : 
     333           0 :         return (newfont);
     334             : }
     335             : 
     336             : int
     337           0 : wsfont_rotate(int cookie, int ccw)
     338             : {
     339             :         int s, ncookie;
     340             :         struct wsdisplay_font *font;
     341             :         struct font *origfont;
     342             : 
     343           0 :         s = splhigh();
     344           0 :         origfont = wsfont_find0(cookie);
     345           0 :         splx(s);
     346             : 
     347           0 :         font = wsfont_rotate_internal(origfont->font, ccw);
     348           0 :         if (font == NULL)
     349           0 :                 return (-1);
     350             : 
     351           0 :         ncookie = wsfont_find(font->name, font->fontwidth, font->fontheight,
     352           0 :             font->stride);
     353             : 
     354           0 :         return (ncookie);
     355           0 : }
     356             : 
     357             : #endif  /* NRASOPS_ROTATION */
     358             : 
     359             : /*
     360             :  * Initialize list with WSFONT_BUILTIN fonts
     361             :  */
     362             : void
     363           0 : wsfont_init(void)
     364             : {
     365             :         static int again;
     366             :         unsigned int i;
     367             : 
     368           0 :         if (again != 0)
     369           0 :                 return;
     370           0 :         again = 1;
     371             : 
     372           0 :         TAILQ_INIT(&fontlist);
     373             : 
     374           0 :         for (i = 0; i < nitems(builtin_fonts); i++) {
     375           0 :                 TAILQ_INSERT_TAIL(&fontlist, &builtin_fonts[i], chain);
     376             :         }
     377           0 : }
     378             : 
     379             : /*
     380             :  * Find a font by cookie. Called at splhigh.
     381             :  */
     382             : static struct font *
     383           0 : wsfont_find0(int cookie)
     384             : {
     385             :         struct font *ent;
     386             : 
     387           0 :         TAILQ_FOREACH(ent, &fontlist, chain)
     388           0 :                 if (ent->cookie == cookie)
     389           0 :                         return (ent);
     390             : 
     391           0 :         return (NULL);
     392           0 : }
     393             : 
     394             : /*
     395             :  * Find a font.
     396             :  */
     397             : int
     398           0 : wsfont_find(const char *name, int width, int height, int stride)
     399             : {
     400             :         struct font *ent;
     401             :         int s;
     402             : 
     403           0 :         s = splhigh();
     404             : 
     405           0 :         TAILQ_FOREACH(ent, &fontlist, chain) {
     406           0 :                 if (height != 0 && ent->font->fontheight != height)
     407             :                         continue;
     408             : 
     409           0 :                 if (width != 0 && ent->font->fontwidth != width)
     410             :                         continue;
     411             : 
     412           0 :                 if (stride != 0 && ent->font->stride != stride)
     413             :                         continue;
     414             : 
     415           0 :                 if (name != NULL && strcmp(ent->font->name, name) != 0)
     416             :                         continue;
     417             : 
     418           0 :                 splx(s);
     419           0 :                 return (ent->cookie);
     420             :         }
     421             : 
     422           0 :         splx(s);
     423           0 :         return (-1);
     424           0 : }
     425             : 
     426             : /*
     427             :  * Add a font to the list.
     428             :  */
     429             : int
     430           0 : wsfont_add(struct wsdisplay_font *font, int copy)
     431             : {
     432             :         static int cookiegen = 666;
     433             :         struct font *ent;
     434             :         int s, fontc = 0;
     435             : 
     436           0 :         s = splhigh();
     437             : 
     438             :         /* Don't allow exact duplicates */
     439           0 :         if (wsfont_find(font->name, font->fontwidth, font->fontheight,
     440           0 :             font->stride) >= 0) {
     441           0 :                 splx(s);
     442           0 :                 return (-1);
     443             :         }
     444             : 
     445           0 :         TAILQ_FOREACH(ent, &fontlist, chain)
     446           0 :                 fontc++;
     447             : 
     448           0 :         if (fontc >= WSDISPLAY_MAXFONTCOUNT) {
     449           0 :                 splx(s);
     450           0 :                 return (-1);
     451             :         }
     452             : 
     453           0 :         ent = (struct font *)malloc(sizeof *ent, M_DEVBUF, M_WAITOK);
     454             : 
     455           0 :         ent->lockcount = 0;
     456           0 :         ent->flg = 0;
     457           0 :         ent->cookie = cookiegen++;
     458             : 
     459             :         /*
     460             :          * If we are coming from a WSDISPLAYIO_LDFONT ioctl, we need to
     461             :          * make a copy of the wsdisplay_font struct, but not of font->bits.
     462             :          */
     463           0 :         if (copy) {
     464           0 :                 ent->font = (struct wsdisplay_font *)malloc(sizeof *ent->font,
     465             :                     M_DEVBUF, M_WAITOK);
     466           0 :                 memcpy(ent->font, font, sizeof(*ent->font));
     467           0 :                 ent->flg = 0;
     468           0 :         } else {
     469           0 :                 ent->font = font;
     470           0 :                 ent->flg = WSFONT_STATIC;
     471             :         }
     472             : 
     473             :         /* Now link into the list and return */
     474           0 :         TAILQ_INSERT_TAIL(&fontlist, ent, chain);
     475           0 :         splx(s);
     476           0 :         return (0);
     477           0 : }
     478             : 
     479             : /*
     480             :  * Remove a font.
     481             :  */
     482             : #ifdef notyet
     483             : int
     484             : wsfont_remove(int cookie)
     485             : {
     486             :         struct font *ent;
     487             :         int s;
     488             : 
     489             :         s = splhigh();
     490             : 
     491             :         if ((ent = wsfont_find0(cookie)) == NULL) {
     492             :                 splx(s);
     493             :                 return (-1);
     494             :         }
     495             : 
     496             :         if ((ent->flg & WSFONT_BUILTIN) != 0 || ent->lockcount != 0) {
     497             :                 splx(s);
     498             :                 return (-1);
     499             :         }
     500             : 
     501             :         /* Don't free statically allocated font data */
     502             :         if ((ent->flg & WSFONT_STATIC) != 0) {
     503             :                 free(ent->font->data, M_DEVBUF, 0);
     504             :                 free(ent->font, M_DEVBUF, 0);
     505             :         }
     506             : 
     507             :         /* Remove from list, free entry */
     508             :         TAILQ_REMOVE(&list, ent, chain);
     509             :         free(ent, M_DEVBUF, 0);
     510             :         splx(s);
     511             :         return (0);
     512             : }
     513             : #endif
     514             : 
     515             : /*
     516             :  * Lock a given font and return new lockcount. This fails if the cookie
     517             :  * is invalid, or if the font is already locked and the bit/byte order
     518             :  * requested by the caller differs.
     519             :  */
     520             : int
     521           0 : wsfont_lock(int cookie, struct wsdisplay_font **ptr, int bitorder,
     522             :     int byteorder)
     523             : {
     524             :         struct font *ent;
     525             :         int s, lc;
     526             : 
     527           0 :         s = splhigh();
     528             : 
     529           0 :         if ((ent = wsfont_find0(cookie)) != NULL) {
     530           0 :                 if (bitorder && bitorder != ent->font->bitorder) {
     531             : #ifdef INCLUDE_FONT_BIT_ENDIANNESS_SWAP_CODE
     532           0 :                         if (ent->lockcount) {
     533           0 :                                 splx(s);
     534           0 :                                 return (-1);
     535             :                         }
     536           0 :                         wsfont_revbit(ent->font);
     537           0 :                         ent->font->bitorder = bitorder;
     538             : #else
     539             :                         splx(s);
     540             :                         return (-1);
     541             : #endif
     542           0 :                 }
     543             : 
     544           0 :                 if (byteorder && byteorder != ent->font->byteorder) {
     545             : #if !defined(SMALL_KERNEL)
     546           0 :                         if (ent->lockcount) {
     547           0 :                                 splx(s);
     548           0 :                                 return (-1);
     549             :                         }
     550           0 :                         wsfont_revbyte(ent->font);
     551           0 :                         ent->font->byteorder = byteorder;
     552             : #else
     553             :                         splx(s);
     554             :                         return (-1);
     555             : #endif
     556           0 :                 }
     557             : 
     558           0 :                 lc = ++ent->lockcount;
     559           0 :                 *ptr = ent->font;
     560           0 :         } else
     561             :                 lc = -1;
     562             : 
     563           0 :         splx(s);
     564           0 :         return (lc);
     565           0 : }
     566             : 
     567             : /*
     568             :  * Unlock a given font and return new lockcount.
     569             :  */
     570             : int
     571           0 : wsfont_unlock(int cookie)
     572             : {
     573             :         struct font *ent;
     574             :         int s, lc;
     575             : 
     576           0 :         s = splhigh();
     577             : 
     578           0 :         if ((ent = wsfont_find0(cookie)) != NULL) {
     579           0 :                 if (ent->lockcount == 0)
     580           0 :                         panic("wsfont_unlock: font not locked");
     581           0 :                 lc = --ent->lockcount;
     582           0 :         } else
     583             :                 lc = -1;
     584             : 
     585           0 :         splx(s);
     586           0 :         return (lc);
     587             : }
     588             : 
     589             : #if !defined(SMALL_KERNEL)
     590             : 
     591             : /*
     592             :  * Unicode to font encoding mappings
     593             :  */
     594             : 
     595             : /*
     596             :  * To save memory, font encoding tables use a two level lookup.
     597             :  * First the high byte of the Unicode is used to lookup the level 2
     598             :  * table, then the low byte indexes that table.  Level 2 tables that are
     599             :  * not needed are omitted (NULL), and both level 1 and level 2 tables
     600             :  * have base and size attributes to keep their size down.
     601             :  */
     602             : 
     603             : struct wsfont_level1_glyphmap {
     604             :         struct wsfont_level2_glyphmap **level2;
     605             :         int base;       /* High byte for first level2 entry     */
     606             :         int size;       /* Number of level2 entries             */
     607             : };
     608             : 
     609             : struct wsfont_level2_glyphmap {
     610             :         int base;       /* Low byte for first character         */
     611             :         int size;       /* Number of characters                 */
     612             :         void *chars;    /* Pointer to character number entries  */
     613             :         int width;      /* Size of each entry in bytes (1,2,4)  */
     614             : };
     615             : 
     616             : /*
     617             :  * IBM 437 maps
     618             :  */
     619             : 
     620             : static u_int8_t
     621             : ibm437_chars_0[] = {
     622             :          0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
     623             :         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
     624             :         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
     625             :         48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
     626             :         64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
     627             :         80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
     628             :         96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
     629             :         112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
     630             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     631             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     632             :         255,173,155,156, 0, 157, 0,  0,  0,  0, 166,174,170, 0,  0,  0,
     633             :          0, 241,253, 0,  0,  0,  0, 249, 0,  0, 167,175,172,171, 0, 168,
     634             :          0,  0,  0,  0, 142,143,146,128, 0, 144, 0,  0,  0,  0,  0,  0,
     635             :          0, 165, 0,  0,  0,  0, 153, 0,  0,  0,  0,  0, 154, 0,  0,  0,
     636             :         133,160,131, 0, 132,134,145,135,138,130,136,137,141,161,140,139,
     637             :          0, 164,149,162,147, 0, 148,246, 0, 151,163,150,129, 0,  0, 152
     638             : },
     639             : ibm437_chars_1[] = {
     640             :         159
     641             : },
     642             : ibm437_chars_3[] = {
     643             :         226, 0,  0,  0,  0, 233, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     644             :         228, 0,  0, 232, 0,  0, 234, 0,  0,  0,  0,  0,  0,  0, 224,225,
     645             :          0, 235,238, 0,  0,  0,  0,  0,  0, 230, 0,  0,  0, 227, 0,  0,
     646             :         229,231
     647             : },
     648             : ibm437_chars_32[] = {
     649             :         252, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     650             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     651             :          0,  0,  0,  0,  0,  0,  0,  0, 158
     652             : },
     653             : ibm437_chars_34[] = {
     654             :         237, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     655             :          0,  0,  0, 248,250,251, 0,  0,  0, 236, 0,  0,  0,  0,  0,  0,
     656             :          0,  0,  0,  0, 239, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     657             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     658             :          0,  0,  0, 247, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     659             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  0,  0,243,
     660             :         242
     661             : },
     662             : ibm437_chars_35[] = {
     663             :         169, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     664             :         244,245
     665             : },
     666             : ibm437_chars_37[] = {
     667             :         196,205,179,186, 0,  0,  0,  0,  0,  0,  0,  0, 218,213,214,201,
     668             :         191,184,183,187,192,212,211,200,217,190,189,188,195,198, 0,  0,
     669             :         199, 0,  0, 204,180,181, 0,  0, 182, 0,  0, 185,194, 0,  0, 209,
     670             :         210, 0,  0, 203,193, 0,  0, 207,208, 0,  0, 202,197, 0,  0, 216,
     671             :          0,  0, 215, 0,  0,  0,  0,  0,  0,  0,  0, 206, 0,  0,  0,  0,
     672             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     673             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     674             :          0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     675             :         223, 0,  0,  0, 220, 0,  0,  0, 219, 0,  0,  0, 221, 0,  0,  0,
     676             :         222,176,177,178, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
     677             :         254
     678             : };
     679             : 
     680             : static struct wsfont_level2_glyphmap
     681             : ibm437_level2_0 = { 0, 256, ibm437_chars_0, 1 },
     682             : ibm437_level2_1 = { 146, 1, ibm437_chars_1, 1 },
     683             : ibm437_level2_3 = { 147, 50, ibm437_chars_3, 1 },
     684             : ibm437_level2_32 = { 127, 41, ibm437_chars_32, 1 },
     685             : ibm437_level2_34 = { 5, 97, ibm437_chars_34, 1 },
     686             : ibm437_level2_35 = { 16, 18, ibm437_chars_35, 1 },
     687             : ibm437_level2_37 = { 0, 161, ibm437_chars_37, 1 };
     688             : 
     689             : static struct wsfont_level2_glyphmap *ibm437_level1[] = {
     690             :         &ibm437_level2_0, &ibm437_level2_1, NULL, &ibm437_level2_3,
     691             :         NULL, NULL, NULL, NULL,
     692             :         NULL, NULL, NULL, NULL,
     693             :         NULL, NULL, NULL, NULL,
     694             :         NULL, NULL, NULL, NULL,
     695             :         NULL, NULL, NULL, NULL,
     696             :         NULL, NULL, NULL, NULL,
     697             :         NULL, NULL, NULL, NULL,
     698             :         &ibm437_level2_32, NULL, &ibm437_level2_34, &ibm437_level2_35,
     699             :         NULL, &ibm437_level2_37
     700             : };
     701             : 
     702             : static struct wsfont_level1_glyphmap encodings[] = {
     703             :         /* WSDISPLAY_FONTENC_ISO */
     704             :         { NULL, 0, 0 },
     705             :         /* WSDISPLAY_FONTENC_IBM */
     706             :         { ibm437_level1, 0, nitems(ibm437_level1) }
     707             : };
     708             : 
     709             : #endif  /* !SMALL_KERNEL */
     710             : 
     711             : /*
     712             :  * Remap Unicode character to glyph
     713             :  */
     714             : int
     715           0 : wsfont_map_unichar(struct wsdisplay_font *font, int c)
     716             : {
     717           0 :         if (font->encoding == WSDISPLAY_FONTENC_ISO)
     718           0 :                 return (c);
     719             : 
     720             : #if !defined(SMALL_KERNEL)
     721           0 :         if (font->encoding >= 0 && font->encoding < nitems(encodings)) {
     722           0 :                 int hi = (c >> 8), lo = c & 255;
     723             :                 struct wsfont_level1_glyphmap *map1 =
     724           0 :                     &encodings[font->encoding];
     725             :                 struct wsfont_level2_glyphmap *map2;
     726             : 
     727           0 :                 hi -= map1->base;
     728             : 
     729           0 :                 if (hi >= 0 && hi < map1->size &&
     730           0 :                     (map2 = map1->level2[hi]) != NULL) {
     731           0 :                         lo -= map2->base;
     732             : 
     733           0 :                         if (lo >= 0 && lo < map2->size) {
     734           0 :                                 switch (map2->width) {
     735             :                                 case 1:
     736           0 :                                         c = (((u_int8_t *)map2->chars)[lo]);
     737           0 :                                         break;
     738             :                                 case 2:
     739           0 :                                         c = (((u_int16_t *)map2->chars)[lo]);
     740           0 :                                         break;
     741             :                                 case 4:
     742           0 :                                         c = (((u_int32_t *)map2->chars)[lo]);
     743           0 :                                         break;
     744             :                                 }
     745             : 
     746           0 :                                 if (c != 0 || lo == 0)
     747           0 :                                         return (c);
     748             :                         }
     749             :                 }
     750           0 :         }
     751             : #endif  /* !SMALL_KERNEL */
     752             : 
     753           0 :         return (-1);
     754           0 : }

Generated by: LCOV version 1.13