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 /*      $OpenBSD: rasops8.c,v 1.12 2023/01/18 11:08:49 nicm Exp $       */
    2 /*      $NetBSD: rasops8.c,v 1.8 2000/04/12 14:22:29 pk 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 
   37 #include <dev/wscons/wsdisplayvar.h>
   38 #include <dev/wscons/wsconsio.h>
   39 #include <dev/rasops/rasops.h>
   40 
   41 int     rasops8_putchar(void *, int, int, u_int, uint32_t attr);
   42 #ifndef RASOPS_SMALL
   43 int     rasops8_putchar8(void *, int, int, u_int, uint32_t attr);
   44 int     rasops8_putchar12(void *, int, int, u_int, uint32_t attr);
   45 int     rasops8_putchar16(void *, int, int, u_int, uint32_t attr);
   46 void    rasops8_makestamp(struct rasops_info *ri, uint32_t);
   47 
   48 /*
   49  * 4x1 stamp for optimized character blitting
   50  */
   51 static int32_t  stamp[16];
   52 static uint32_t stamp_attr;
   53 static int      stamp_mutex;    /* XXX see note in README */
   54 #endif
   55 
   56 /*
   57  * XXX this confuses the hell out of gcc2 (not egcs) which always insists
   58  * that the shift count is negative.
   59  *
   60  * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
   61  * destination = STAMP_READ(offset)
   62  */
   63 #define STAMP_SHIFT(fb,n)       ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
   64 #define STAMP_MASK              (0xf << 2)
   65 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   66 
   67 /*
   68  * Initialize a 'rasops_info' descriptor for this depth.
   69  */
   70 void
   71 rasops8_init(struct rasops_info *ri)
   72 {
   73 
   74         switch (ri->ri_font->fontwidth) {
   75 #ifndef RASOPS_SMALL
   76         case 8:
   77                 ri->ri_ops.putchar = rasops8_putchar8;
   78                 break;
   79         case 12:
   80                 ri->ri_ops.putchar = rasops8_putchar12;
   81                 break;
   82         case 16:
   83                 ri->ri_ops.putchar = rasops8_putchar16;
   84                 break;
   85 #endif /* !RASOPS_SMALL */
   86         default:
   87                 ri->ri_ops.putchar = rasops8_putchar;
   88                 break;
   89         }
   90 }
   91 
   92 /*
   93  * Put a single character.
   94  */
   95 int
   96 rasops8_putchar(void *cookie, int row, int col, u_int uc, uint32_t attr)
   97 {
   98         int width, height, cnt, fs, fb;
   99         u_char *dp, *rp, *fr, clr[2];
  100         struct rasops_info *ri;
  101 
  102         ri = (struct rasops_info *)cookie;
  103 
  104 #ifdef RASOPS_CLIPPING
  105         /* Catches 'row < 0' case too */
  106         if ((unsigned)row >= (unsigned)ri->ri_rows)
  107                 return 0;
  108 
  109         if ((unsigned)col >= (unsigned)ri->ri_cols)
  110                 return 0;
  111 #endif
  112         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  113 
  114         height = ri->ri_font->fontheight;
  115         width = ri->ri_font->fontwidth;
  116         clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
  117         clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
  118 
  119         if (uc == ' ') {
  120                 u_char c = clr[0];
  121 
  122                 while (height--) {
  123                         dp = rp;
  124                         rp += ri->ri_stride;
  125 
  126                         for (cnt = width; cnt; cnt--)
  127                                 *dp++ = c;
  128                 }
  129         } else {
  130                 uc -= ri->ri_font->firstchar;
  131                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  132                 fs = ri->ri_font->stride;
  133 
  134                 while (height--) {
  135                         dp = rp;
  136                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
  137                         fr += fs;
  138                         rp += ri->ri_stride;
  139 
  140                         for (cnt = width; cnt; cnt--) {
  141                                 *dp++ = clr[(fb >> 31) & 1];
  142                                 fb <<= 1;
  143                         }
  144                 }
  145         }
  146 
  147         /* Do underline */
  148         if ((attr & WSATTR_UNDERLINE) != 0) {
  149                 u_char c = clr[1];
  150 
  151                 rp -= (ri->ri_stride << 1);
  152 
  153                 while (width--)
  154                         *rp++ = c;
  155         }
  156 
  157         return 0;
  158 }
  159 
  160 #ifndef RASOPS_SMALL
  161 /*
  162  * Recompute the 4x1 blitting stamp.
  163  */
  164 void
  165 rasops8_makestamp(struct rasops_info *ri, uint32_t attr)
  166 {
  167         int32_t fg, bg;
  168         int i;
  169 
  170         fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
  171         bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
  172         stamp_attr = attr;
  173 
  174         for (i = 0; i < 16; i++) {
  175 #if BYTE_ORDER == LITTLE_ENDIAN
  176                 stamp[i] = (i & 8 ? fg : bg);
  177                 stamp[i] |= ((i & 4 ? fg : bg) << 8);
  178                 stamp[i] |= ((i & 2 ? fg : bg) << 16);
  179                 stamp[i] |= ((i & 1 ? fg : bg) << 24);
  180 #else
  181                 stamp[i] = (i & 1 ? fg : bg);
  182                 stamp[i] |= ((i & 2 ? fg : bg) << 8);
  183                 stamp[i] |= ((i & 4 ? fg : bg) << 16);
  184                 stamp[i] |= ((i & 8 ? fg : bg) << 24);
  185 #endif
  186 #if NRASOPS_BSWAP > 0
  187                 if (ri->ri_flg & RI_BSWAP)
  188                         stamp[i] = swap32(stamp[i]);
  189 #endif
  190         }
  191 }
  192 
  193 /*
  194  * Put a single character. This is for 8-pixel wide fonts.
  195  */
  196 int
  197 rasops8_putchar8(void *cookie, int row, int col, u_int uc, uint32_t attr)
  198 {
  199         struct rasops_info *ri;
  200         int height, fs;
  201         int32_t *rp;
  202         u_char *fr;
  203 
  204         /* Can't risk remaking the stamp if it's already in use */
  205         if (stamp_mutex++) {
  206                 stamp_mutex--;
  207                 return rasops8_putchar(cookie, row, col, uc, attr);
  208         }
  209 
  210         ri = (struct rasops_info *)cookie;
  211 
  212 #ifdef RASOPS_CLIPPING
  213         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  214                 stamp_mutex--;
  215                 return 0;
  216         }
  217 
  218         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  219                 stamp_mutex--;
  220                 return 0;
  221         }
  222 #endif
  223 
  224         /* Recompute stamp? */
  225         if (attr != stamp_attr)
  226                 rasops8_makestamp(ri, attr);
  227 
  228         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  229         height = ri->ri_font->fontheight;
  230 
  231         if (uc == ' ') {
  232                 while (height--) {
  233                         rp[0] = rp[1] = stamp[0];
  234                         DELTA(rp, ri->ri_stride, int32_t *);
  235                 }
  236         } else {
  237                 uc -= ri->ri_font->firstchar;
  238                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  239                 fs = ri->ri_font->stride;
  240 
  241                 while (height--) {
  242                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  243                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  244 
  245                         fr += fs;
  246                         DELTA(rp, ri->ri_stride, int32_t *);
  247                 }
  248         }
  249 
  250         /* Do underline */
  251         if ((attr & WSATTR_UNDERLINE) != 0) {
  252                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  253                 rp[0] = rp[1] = stamp[15];
  254         }
  255 
  256         stamp_mutex--;
  257 
  258         return 0;
  259 }
  260 
  261 /*
  262  * Put a single character. This is for 12-pixel wide fonts.
  263  */
  264 int
  265 rasops8_putchar12(void *cookie, int row, int col, u_int uc, uint32_t attr)
  266 {
  267         struct rasops_info *ri;
  268         int height, fs;
  269         int32_t *rp;
  270         u_char *fr;
  271 
  272         /* Can't risk remaking the stamp if it's already in use */
  273         if (stamp_mutex++) {
  274                 stamp_mutex--;
  275                 return rasops8_putchar(cookie, row, col, uc, attr);
  276         }
  277 
  278         ri = (struct rasops_info *)cookie;
  279 
  280 #ifdef RASOPS_CLIPPING
  281         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  282                 stamp_mutex--;
  283                 return 0;
  284         }
  285 
  286         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  287                 stamp_mutex--;
  288                 return 0;
  289         }
  290 #endif
  291 
  292         /* Recompute stamp? */
  293         if (attr != stamp_attr)
  294                 rasops8_makestamp(ri, attr);
  295 
  296         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  297         height = ri->ri_font->fontheight;
  298 
  299         if (uc == ' ') {
  300                 while (height--) {
  301                         int32_t c = stamp[0];
  302 
  303                         rp[0] = rp[1] = rp[2] = c;
  304                         DELTA(rp, ri->ri_stride, int32_t *);
  305                 }
  306         } else {
  307                 uc -= ri->ri_font->firstchar;
  308                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  309                 fs = ri->ri_font->stride;
  310 
  311                 while (height--) {
  312                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  313                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  314                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  315 
  316                         fr += fs;
  317                         DELTA(rp, ri->ri_stride, int32_t *);
  318                 }
  319         }
  320 
  321         /* Do underline */
  322         if ((attr & WSATTR_UNDERLINE) != 0) {
  323                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  324                 rp[0] = rp[1] = rp[2] = stamp[15];
  325         }
  326 
  327         stamp_mutex--;
  328 
  329         return 0;
  330 }
  331 
  332 /*
  333  * Put a single character. This is for 16-pixel wide fonts.
  334  */
  335 int
  336 rasops8_putchar16(void *cookie, int row, int col, u_int uc, uint32_t attr)
  337 {
  338         struct rasops_info *ri;
  339         int height, fs;
  340         int32_t *rp;
  341         u_char *fr;
  342 
  343         /* Can't risk remaking the stamp if it's already in use */
  344         if (stamp_mutex++) {
  345                 stamp_mutex--;
  346                 return rasops8_putchar(cookie, row, col, uc, attr);
  347         }
  348 
  349         ri = (struct rasops_info *)cookie;
  350 
  351 #ifdef RASOPS_CLIPPING
  352         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  353                 stamp_mutex--;
  354                 return 0;
  355         }
  356 
  357         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  358                 stamp_mutex--;
  359                 return 0;
  360         }
  361 #endif
  362 
  363         /* Recompute stamp? */
  364         if (attr != stamp_attr)
  365                 rasops8_makestamp(ri, attr);
  366 
  367         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  368         height = ri->ri_font->fontheight;
  369 
  370         if (uc == ' ') {
  371                 while (height--)
  372                         rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
  373         } else {
  374                 uc -= ri->ri_font->firstchar;
  375                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  376                 fs = ri->ri_font->stride;
  377 
  378                 while (height--) {
  379                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  380                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  381                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  382                         rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
  383 
  384                         fr += fs;
  385                         DELTA(rp, ri->ri_stride, int32_t *);
  386                 }
  387         }
  388 
  389         /* Do underline */
  390         if ((attr & WSATTR_UNDERLINE) != 0) {
  391                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  392                 rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
  393         }
  394 
  395         stamp_mutex--;
  396 
  397         return 0;
  398 }
  399 #endif /* !RASOPS_SMALL */

Cache object: c6455ff06616f5f471b2d3a37f530a3b


[ 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.