root/dev/rasops/rasops8.c

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

DEFINITIONS

This source file includes following definitions.
  1. rasops8_init
  2. rasops8_putchar
  3. rasops8_makestamp
  4. rasops8_putchar8
  5. rasops8_putchar12
  6. rasops8_putchar16

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

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