root/dev/wsfont/wsfont.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wsfont_revbit
  2. wsfont_revbyte
  3. wsfont_enum
  4. wsfont_rotate_internal
  5. wsfont_rotate
  6. wsfont_init
  7. wsfont_find0
  8. wsfont_find
  9. wsfont_add
  10. wsfont_remove
  11. wsfont_lock
  12. wsfont_getflg
  13. wsfont_unlock
  14. wsfont_map_unichar

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

/* [<][>][^][v][top][bottom][index][help] */