The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/rasops/rasops8.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: rasops8.c,v 1.18 2005/02/04 02:10:47 perry Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.18 2005/02/04 02:10:47 perry Exp $");
   41 
   42 #include "opt_rasops.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/time.h>
   47 #include <sys/bswap.h>
   48 
   49 #include <dev/wscons/wsdisplayvar.h>
   50 #include <dev/wscons/wsconsio.h>
   51 #include <dev/rasops/rasops.h>
   52 
   53 static void     rasops8_putchar(void *, int, int, u_int, long attr);
   54 #ifndef RASOPS_SMALL
   55 static void     rasops8_putchar8(void *, int, int, u_int, long attr);
   56 static void     rasops8_putchar12(void *, int, int, u_int, long attr);
   57 static void     rasops8_putchar16(void *, int, int, u_int, long attr);
   58 static void     rasops8_makestamp(struct rasops_info *ri, long);
   59 
   60 /*
   61  * 4x1 stamp for optimized character blitting
   62  */
   63 static int32_t  stamp[16];
   64 static long     stamp_attr;
   65 static int      stamp_mutex;    /* XXX see note in README */
   66 #endif
   67 
   68 /*
   69  * XXX this confuses the hell out of gcc2 (not egcs) which always insists
   70  * that the shift count is negative.
   71  *
   72  * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
   73  * destination = STAMP_READ(offset)
   74  */
   75 #define STAMP_SHIFT(fb,n)       ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
   76 #define STAMP_MASK              (0xf << 2)
   77 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   78 
   79 /*
   80  * Initialize a 'rasops_info' descriptor for this depth.
   81  */
   82 void
   83 rasops8_init(ri)
   84         struct rasops_info *ri;
   85 {
   86 
   87         switch (ri->ri_font->fontwidth) {
   88 #ifndef RASOPS_SMALL
   89         case 8:
   90                 ri->ri_ops.putchar = rasops8_putchar8;
   91                 break;
   92         case 12:
   93                 ri->ri_ops.putchar = rasops8_putchar12;
   94                 break;
   95         case 16:
   96                 ri->ri_ops.putchar = rasops8_putchar16;
   97                 break;
   98 #endif /* !RASOPS_SMALL */
   99         default:
  100                 ri->ri_ops.putchar = rasops8_putchar;
  101                 break;
  102         }
  103 }
  104 
  105 /*
  106  * Put a single character.
  107  */
  108 static void
  109 rasops8_putchar(cookie, row, col, uc, attr)
  110         void *cookie;
  111         int row, col;
  112         u_int uc;
  113         long attr;
  114 {
  115         int width, height, cnt, fs, fb;
  116         u_char *dp, *rp, *fr, clr[2];
  117         struct rasops_info *ri;
  118 
  119         ri = (struct rasops_info *)cookie;
  120 
  121         if (!CHAR_IN_FONT(uc, ri->ri_font))
  122                 return;
  123 
  124 #ifdef RASOPS_CLIPPING
  125         /* Catches 'row < 0' case too */
  126         if ((unsigned)row >= (unsigned)ri->ri_rows)
  127                 return;
  128 
  129         if ((unsigned)col >= (unsigned)ri->ri_cols)
  130                 return;
  131 #endif
  132         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  133 
  134         height = ri->ri_font->fontheight;
  135         width = ri->ri_font->fontwidth;
  136         clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
  137         clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
  138 
  139         if (uc == ' ') {
  140                 u_char c = clr[0];
  141 
  142                 while (height--) {
  143                         dp = rp;
  144                         rp += ri->ri_stride;
  145 
  146                         for (cnt = width; cnt; cnt--)
  147                                 *dp++ = c;
  148                 }
  149         } else {
  150                 uc -= ri->ri_font->firstchar;
  151                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  152                 fs = ri->ri_font->stride;
  153 
  154                 while (height--) {
  155                         dp = rp;
  156                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
  157                         fr += fs;
  158                         rp += ri->ri_stride;
  159 
  160                         for (cnt = width; cnt; cnt--) {
  161                                 *dp++ = clr[(fb >> 31) & 1];
  162                                 fb <<= 1;
  163                         }
  164                 }
  165         }
  166 
  167         /* Do underline */
  168         if ((attr & 1) != 0) {
  169                 u_char c = clr[1];
  170 
  171                 rp -= (ri->ri_stride << 1);
  172 
  173                 while (width--)
  174                         *rp++ = c;
  175         }
  176 }
  177 
  178 #ifndef RASOPS_SMALL
  179 /*
  180  * Recompute the 4x1 blitting stamp.
  181  */
  182 static void
  183 rasops8_makestamp(ri, attr)
  184         struct rasops_info *ri;
  185         long attr;
  186 {
  187         int32_t fg, bg;
  188         int i;
  189 
  190         fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
  191         bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
  192         stamp_attr = attr;
  193 
  194         for (i = 0; i < 16; i++) {
  195 #if BYTE_ORDER == BIG_ENDIAN
  196 #define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP
  197 #else
  198 #define NEED_LITTLE_ENDIAN_STAMP 0
  199 #endif
  200                 if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) {
  201                         /* little endian */
  202                         stamp[i] = (i & 8 ? fg : bg);
  203                         stamp[i] |= ((i & 4 ? fg : bg) << 8);
  204                         stamp[i] |= ((i & 2 ? fg : bg) << 16);
  205                         stamp[i] |= ((i & 1 ? fg : bg) << 24);
  206                 } else {
  207                         /* big endian */
  208                         stamp[i] = (i & 1 ? fg : bg);
  209                         stamp[i] |= ((i & 2 ? fg : bg) << 8);
  210                         stamp[i] |= ((i & 4 ? fg : bg) << 16);
  211                         stamp[i] |= ((i & 8 ? fg : bg) << 24);
  212                 }
  213         }
  214 }
  215 
  216 /*
  217  * Put a single character. This is for 8-pixel wide fonts.
  218  */
  219 static void
  220 rasops8_putchar8(cookie, row, col, uc, attr)
  221         void *cookie;
  222         int row, col;
  223         u_int uc;
  224         long attr;
  225 {
  226         struct rasops_info *ri;
  227         int height, fs;
  228         int32_t *rp;
  229         u_char *fr;
  230 
  231         /* Can't risk remaking the stamp if it's already in use */
  232         if (stamp_mutex++) {
  233                 stamp_mutex--;
  234                 rasops8_putchar(cookie, row, col, uc, attr);
  235                 return;
  236         }
  237 
  238         ri = (struct rasops_info *)cookie;
  239 
  240         if (!CHAR_IN_FONT(uc, ri->ri_font))
  241                 return;
  242 
  243 #ifdef RASOPS_CLIPPING
  244         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  245                 stamp_mutex--;
  246                 return;
  247         }
  248 
  249         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  250                 stamp_mutex--;
  251                 return;
  252         }
  253 #endif
  254 
  255         /* Recompute stamp? */
  256         if (attr != stamp_attr)
  257                 rasops8_makestamp(ri, attr);
  258 
  259         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  260         height = ri->ri_font->fontheight;
  261 
  262         if (uc == ' ') {
  263                 while (height--) {
  264                         rp[0] = rp[1] = stamp[0];
  265                         DELTA(rp, ri->ri_stride, int32_t *);
  266                 }
  267         } else {
  268                 uc -= ri->ri_font->firstchar;
  269                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  270                 fs = ri->ri_font->stride;
  271 
  272                 while (height--) {
  273                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  274                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  275 
  276                         fr += fs;
  277                         DELTA(rp, ri->ri_stride, int32_t *);
  278                 }
  279         }
  280 
  281         /* Do underline */
  282         if ((attr & 1) != 0) {
  283                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  284                 rp[0] = rp[1] = stamp[15];
  285         }
  286 
  287         stamp_mutex--;
  288 }
  289 
  290 /*
  291  * Put a single character. This is for 12-pixel wide fonts.
  292  */
  293 static void
  294 rasops8_putchar12(cookie, row, col, uc, attr)
  295         void *cookie;
  296         int row, col;
  297         u_int uc;
  298         long attr;
  299 {
  300         struct rasops_info *ri;
  301         int height, fs;
  302         int32_t *rp;
  303         u_char *fr;
  304 
  305         /* Can't risk remaking the stamp if it's already in use */
  306         if (stamp_mutex++) {
  307                 stamp_mutex--;
  308                 rasops8_putchar(cookie, row, col, uc, attr);
  309                 return;
  310         }
  311 
  312         ri = (struct rasops_info *)cookie;
  313 
  314         if (!CHAR_IN_FONT(uc, ri->ri_font))
  315             return;
  316 
  317 #ifdef RASOPS_CLIPPING
  318         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  319                 stamp_mutex--;
  320                 return;
  321         }
  322 
  323         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  324                 stamp_mutex--;
  325                 return;
  326         }
  327 #endif
  328 
  329         /* Recompute stamp? */
  330         if (attr != stamp_attr)
  331                 rasops8_makestamp(ri, attr);
  332 
  333         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  334         height = ri->ri_font->fontheight;
  335 
  336         if (uc == ' ') {
  337                 while (height--) {
  338                         int32_t c = stamp[0];
  339 
  340                         rp[0] = rp[1] = rp[2] = c;
  341                         DELTA(rp, ri->ri_stride, int32_t *);
  342                 }
  343         } else {
  344                 uc -= ri->ri_font->firstchar;
  345                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  346                 fs = ri->ri_font->stride;
  347 
  348                 while (height--) {
  349                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  350                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  351                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  352 
  353                         fr += fs;
  354                         DELTA(rp, ri->ri_stride, int32_t *);
  355                 }
  356         }
  357 
  358         /* Do underline */
  359         if ((attr & 1) != 0) {
  360                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  361                 rp[0] = rp[1] = rp[2] = stamp[15];
  362         }
  363 
  364         stamp_mutex--;
  365 }
  366 
  367 /*
  368  * Put a single character. This is for 16-pixel wide fonts.
  369  */
  370 static void
  371 rasops8_putchar16(cookie, row, col, uc, attr)
  372         void *cookie;
  373         int row, col;
  374         u_int uc;
  375         long attr;
  376 {
  377         struct rasops_info *ri;
  378         int height, fs;
  379         int32_t *rp;
  380         u_char *fr;
  381 
  382         /* Can't risk remaking the stamp if it's already in use */
  383         if (stamp_mutex++) {
  384                 stamp_mutex--;
  385                 rasops8_putchar(cookie, row, col, uc, attr);
  386                 return;
  387         }
  388 
  389         ri = (struct rasops_info *)cookie;
  390 
  391         if (!CHAR_IN_FONT(uc, ri->ri_font))
  392                 return;
  393 
  394 #ifdef RASOPS_CLIPPING
  395         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  396                 stamp_mutex--;
  397                 return;
  398         }
  399 
  400         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  401                 stamp_mutex--;
  402                 return;
  403         }
  404 #endif
  405 
  406         /* Recompute stamp? */
  407         if (attr != stamp_attr)
  408                 rasops8_makestamp(ri, attr);
  409 
  410         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  411         height = ri->ri_font->fontheight;
  412 
  413         if (uc == ' ') {
  414                 while (height--)
  415                         rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
  416         } else {
  417                 uc -= ri->ri_font->firstchar;
  418                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  419                 fs = ri->ri_font->stride;
  420 
  421                 while (height--) {
  422                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  423                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  424                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  425                         rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
  426 
  427                         fr += fs;
  428                         DELTA(rp, ri->ri_stride, int32_t *);
  429                 }
  430         }
  431 
  432         /* Do underline */
  433         if ((attr & 1) != 0) {
  434                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  435                 rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
  436         }
  437 
  438         stamp_mutex--;
  439 }
  440 #endif /* !RASOPS_SMALL */

Cache object: 8b494801946a062bce26fcfe8a779186


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.