root/dev/rasops/rasops2.c

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

DEFINITIONS

This source file includes following definitions.
  1. rasops2_init
  2. rasops2_mergebits
  3. rasops2_putchar
  4. rasops2_makestamp
  5. rasops2_putchar8
  6. rasops2_putchar12
  7. rasops2_putchar16

    1 /*      $OpenBSD: rasops2.c,v 1.7 2006/08/03 18:42:06 miod Exp $        */
    2 /*      $NetBSD: rasops2.c,v 1.5 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 #include <machine/endian.h>
   44 
   45 #include <dev/wscons/wsdisplayvar.h>
   46 #include <dev/wscons/wsconsio.h>
   47 #include <dev/rasops/rasops.h>
   48 #include <dev/rasops/rasops_masks.h>
   49 
   50 void    rasops2_copycols(void *, int, int, int, int);
   51 void    rasops2_erasecols(void *, int, int, int, long);
   52 void    rasops2_do_cursor(struct rasops_info *);
   53 void    rasops2_putchar(void *, int, int col, u_int, long);
   54 u_int   rasops2_mergebits(u_char *, int, int);
   55 #ifndef RASOPS_SMALL
   56 void    rasops2_putchar8(void *, int, int col, u_int, long);
   57 void    rasops2_putchar12(void *, int, int col, u_int, long);
   58 void    rasops2_putchar16(void *, int, int col, u_int, long);
   59 void    rasops2_makestamp(struct rasops_info *, long);
   60 
   61 /*
   62  * 4x1 stamp for optimized character blitting
   63  */
   64 static int8_t   stamp[16];
   65 static long     stamp_attr;
   66 static int      stamp_mutex;    /* XXX see note in README */
   67 #endif
   68 
   69 /*
   70  * Initialize rasops_info struct for this colordepth.
   71  */
   72 void
   73 rasops2_init(ri)
   74         struct rasops_info *ri;
   75 {
   76         rasops_masks_init();
   77 
   78         switch (ri->ri_font->fontwidth) {
   79 #ifndef RASOPS_SMALL
   80         case 8:
   81                 ri->ri_ops.putchar = rasops2_putchar8;
   82                 break;
   83         case 12:
   84                 ri->ri_ops.putchar = rasops2_putchar12;
   85                 break;
   86         case 16:
   87                 ri->ri_ops.putchar = rasops2_putchar16;
   88                 break;
   89 #endif  /* !RASOPS_SMALL */
   90         default:
   91                 ri->ri_ops.putchar = rasops2_putchar;
   92                 break;
   93         }
   94 
   95         if ((ri->ri_font->fontwidth & 3) != 0) {
   96                 ri->ri_ops.erasecols = rasops2_erasecols;
   97                 ri->ri_ops.copycols = rasops2_copycols;
   98                 ri->ri_do_cursor = rasops2_do_cursor;
   99         }
  100 }
  101 
  102 /*
  103  * Compute a 2bpp expansion of a font element against the given colors.
  104  * Used by rasops2_putchar() below.
  105  */
  106 u_int
  107 rasops2_mergebits(u_char *fr, int fg, int bg)
  108 {
  109         u_int fb, bits;
  110         int mask, shift;
  111 
  112         fg &= 3;
  113         bg &= 3;
  114 
  115         bits = fr[1] | (fr[0] << 8);
  116         fb = 0;
  117         for (mask = 0x8000, shift = 32 - 2; mask != 0; mask >>= 1, shift -= 2)
  118                 fb |= (bits & mask ? fg : bg) << shift;
  119 
  120         return (fb);
  121 }
  122 
  123 /*
  124  * Paint a single character. This is the generic version, this is ugly.
  125  */
  126 void
  127 rasops2_putchar(cookie, row, col, uc, attr)
  128         void *cookie;
  129         int row, col;
  130         u_int uc;
  131         long attr;
  132 {
  133         int height, width, fs, rs, bg, fg, lmask, rmask;
  134         u_int fb;
  135         struct rasops_info *ri;
  136         int32_t *rp;
  137         u_char *fr;
  138 
  139         ri = (struct rasops_info *)cookie;
  140 
  141 #ifdef RASOPS_CLIPPING
  142         /* Catches 'row < 0' case too */
  143         if ((unsigned)row >= (unsigned)ri->ri_rows)
  144                 return;
  145 
  146         if ((unsigned)col >= (unsigned)ri->ri_cols)
  147                 return;
  148 #endif
  149 
  150         width = ri->ri_font->fontwidth << 1;
  151         height = ri->ri_font->fontheight;
  152         col *= width;
  153         rp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale + ((col >> 3) & ~3));
  154         col = col & 31;
  155         rs = ri->ri_stride;
  156 
  157         bg = ri->ri_devcmap[(attr >> 16) & 0xf];
  158         fg = ri->ri_devcmap[(attr >> 24) & 0xf];
  159 
  160         /* If fg and bg match this becomes a space character */
  161         if (fg == bg || uc == ' ') {
  162                 uc = (u_int)-1;
  163                 fr = 0;         /* shutup gcc */
  164                 fs = 0;         /* shutup gcc */
  165         } else {
  166                 uc -= ri->ri_font->firstchar;
  167                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  168                 fs = ri->ri_font->stride;
  169         }
  170 
  171         /* Single word, one mask */
  172         if ((col + width) <= 32) {
  173                 rmask = rasops_pmask[col][width];
  174                 lmask = ~rmask;
  175 
  176                 if (uc == (u_int)-1) {
  177                         bg &= rmask;
  178 
  179                         while (height--) {
  180                                 *rp = (*rp & lmask) | bg;
  181                                 DELTA(rp, rs, int32_t *);
  182                         }
  183                 } else {
  184                         while (height--) {
  185                                 fb = rasops2_mergebits(fr, fg, bg);
  186                                 *rp = (*rp & lmask) |
  187                                     (MBE(fb >> col) & rmask);
  188 
  189                                 fr += fs;
  190                                 DELTA(rp, rs, int32_t *);
  191                         }
  192                 }
  193 
  194                 /* Do underline */
  195                 if (attr & 1) {
  196                         DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  197                         *rp = (*rp & lmask) | (fg & rmask);
  198                 }
  199         } else {
  200                 lmask = ~rasops_lmask[col];
  201                 rmask = ~rasops_rmask[(col + width) & 31];
  202 
  203                 if (uc == (u_int)-1) {
  204                         width = bg & ~rmask;
  205                         bg = bg & ~lmask;
  206 
  207                         while (height--) {
  208                                 rp[0] = (rp[0] & lmask) | bg;
  209                                 rp[1] = (rp[1] & rmask) | width;
  210                                 DELTA(rp, rs, int32_t *);
  211                         }
  212                 } else {
  213                         width = 32 - col;
  214 
  215                         while (height--) {
  216                                 fb = rasops2_mergebits(fr, fg, bg);
  217 
  218                                 rp[0] = (rp[0] & lmask) |
  219                                     MBE(fb >> col);
  220                                 rp[1] = (rp[1] & rmask) |
  221                                     (MBE(fb << width) & ~rmask);
  222 
  223                                 fr += fs;
  224                                 DELTA(rp, rs, int32_t *);
  225                         }
  226                 }
  227 
  228                 /* Do underline */
  229                 if (attr & 1) {
  230                         DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  231                         rp[0] = (rp[0] & lmask) | (fg & ~lmask);
  232                         rp[1] = (rp[1] & rmask) | (fg & ~rmask);
  233                 }
  234         }
  235 }
  236 
  237 #ifndef RASOPS_SMALL
  238 /*
  239  * Recompute the blitting stamp.
  240  */
  241 void
  242 rasops2_makestamp(ri, attr)
  243         struct rasops_info *ri;
  244         long attr;
  245 {
  246         int i, fg, bg;
  247 
  248         fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 3;
  249         bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 3;
  250         stamp_attr = attr;
  251 
  252         for (i = 0; i < 16; i++) {
  253                 stamp[i] = (i & 1 ? fg : bg);
  254                 stamp[i] |= (i & 2 ? fg : bg) << 2;
  255                 stamp[i] |= (i & 4 ? fg : bg) << 4;
  256                 stamp[i] |= (i & 8 ? fg : bg) << 6;
  257         }
  258 }
  259 
  260 /*
  261  * Put a single character. This is for 8-pixel wide fonts.
  262  */
  263 void
  264 rasops2_putchar8(cookie, row, col, uc, attr)
  265         void *cookie;
  266         int row, col;
  267         u_int uc;
  268         long attr;
  269 {
  270         struct rasops_info *ri;
  271         int height, fs, rs;
  272         u_char *fr, *rp;
  273 
  274         /* Can't risk remaking the stamp if it's already in use */
  275         if (stamp_mutex++) {
  276                 stamp_mutex--;
  277                 rasops2_putchar(cookie, row, col, uc, attr);
  278                 return;
  279         }
  280 
  281         ri = (struct rasops_info *)cookie;
  282 
  283 #ifdef RASOPS_CLIPPING
  284         /* Catches 'row < 0' case too */
  285         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  286                 stamp_mutex--;
  287                 return;
  288         }
  289 
  290         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  291                 stamp_mutex--;
  292                 return;
  293         }
  294 #endif
  295 
  296         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  297         height = ri->ri_font->fontheight;
  298         rs = ri->ri_stride;
  299 
  300         /* Recompute stamp? */
  301         if (attr != stamp_attr)
  302                 rasops2_makestamp(ri, attr);
  303 
  304         if (uc == ' ') {
  305                 int8_t c = stamp[0];
  306                 while (height--) {
  307                         *(int16_t *)rp = c;
  308                         rp += rs;
  309                 }
  310         } else {
  311                 uc -= ri->ri_font->firstchar;
  312                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  313                 fs = ri->ri_font->stride;
  314 
  315                 while (height--) {
  316                         rp[0] = stamp[(*fr >> 4) & 0xf];
  317                         rp[1] = stamp[*fr & 0xf];
  318                         fr += fs;
  319                         rp += rs;
  320                 }
  321         }
  322 
  323         /* Do underline */
  324         if ((attr & 1) != 0)
  325                 *(int16_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
  326 
  327         stamp_mutex--;
  328 }
  329 
  330 /*
  331  * Put a single character. This is for 12-pixel wide fonts.
  332  */
  333 void
  334 rasops2_putchar12(cookie, row, col, uc, attr)
  335         void *cookie;
  336         int row, col;
  337         u_int uc;
  338         long attr;
  339 {
  340         struct rasops_info *ri;
  341         int height, fs, rs;
  342         u_char *fr, *rp;
  343 
  344         /* Can't risk remaking the stamp if it's already in use */
  345         if (stamp_mutex++) {
  346                 stamp_mutex--;
  347                 rasops2_putchar(cookie, row, col, uc, attr);
  348                 return;
  349         }
  350 
  351         ri = (struct rasops_info *)cookie;
  352 
  353 #ifdef RASOPS_CLIPPING
  354         /* Catches 'row < 0' case too */
  355         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  356                 stamp_mutex--;
  357                 return;
  358         }
  359 
  360         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  361                 stamp_mutex--;
  362                 return;
  363         }
  364 #endif
  365 
  366         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  367         height = ri->ri_font->fontheight;
  368         rs = ri->ri_stride;
  369 
  370         /* Recompute stamp? */
  371         if (attr != stamp_attr)
  372                 rasops2_makestamp(ri, attr);
  373 
  374         if (uc == ' ') {
  375                 int8_t c = stamp[0];
  376                 while (height--) {
  377                         rp[0] = rp[1] = rp[2] = c;
  378                         rp += rs;
  379                 }
  380         } else {
  381                 uc -= ri->ri_font->firstchar;
  382                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  383                 fs = ri->ri_font->stride;
  384 
  385                 while (height--) {
  386                         rp[0] = stamp[(fr[0] >> 4) & 0xf];
  387                         rp[1] = stamp[fr[0] & 0xf];
  388                         rp[2] = stamp[(fr[1] >> 4) & 0xf];
  389                         fr += fs;
  390                         rp += rs;
  391                 }
  392         }
  393 
  394         /* Do underline */
  395         if ((attr & 1) != 0) {
  396                 rp -= ri->ri_stride << 1;
  397                 rp[0] = rp[1] = rp[2] = stamp[15];
  398         }
  399 
  400         stamp_mutex--;
  401 }
  402 
  403 /*
  404  * Put a single character. This is for 16-pixel wide fonts.
  405  */
  406 void
  407 rasops2_putchar16(cookie, row, col, uc, attr)
  408         void *cookie;
  409         int row, col;
  410         u_int uc;
  411         long attr;
  412 {
  413         struct rasops_info *ri;
  414         int height, fs, rs;
  415         u_char *fr, *rp;
  416 
  417         /* Can't risk remaking the stamp if it's already in use */
  418         if (stamp_mutex++) {
  419                 stamp_mutex--;
  420                 rasops2_putchar(cookie, row, col, uc, attr);
  421                 return;
  422         }
  423 
  424         ri = (struct rasops_info *)cookie;
  425 
  426 #ifdef RASOPS_CLIPPING
  427         /* Catches 'row < 0' case too */
  428         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  429                 stamp_mutex--;
  430                 return;
  431         }
  432 
  433         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  434                 stamp_mutex--;
  435                 return;
  436         }
  437 #endif
  438 
  439         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  440         height = ri->ri_font->fontheight;
  441         rs = ri->ri_stride;
  442 
  443         /* Recompute stamp? */
  444         if (attr != stamp_attr)
  445                 rasops2_makestamp(ri, attr);
  446 
  447         if (uc == ' ') {
  448                 int8_t c = stamp[0];
  449                 while (height--) {
  450                         *(int32_t *)rp = c;
  451                         rp += rs;
  452                 }
  453         } else {
  454                 uc -= ri->ri_font->firstchar;
  455                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  456                 fs = ri->ri_font->stride;
  457 
  458                 while (height--) {
  459                         rp[0] = stamp[(fr[0] >> 4) & 0xf];
  460                         rp[1] = stamp[fr[0] & 0xf];
  461                         rp[2] = stamp[(fr[1] >> 4) & 0xf];
  462                         rp[3] = stamp[fr[1] & 0xf];
  463                         fr += fs;
  464                         rp += rs;
  465                 }
  466         }
  467 
  468         /* Do underline */
  469         if ((attr & 1) != 0)
  470                 *(int32_t *)(rp - (ri->ri_stride << 1)) = stamp[15];
  471 
  472         stamp_mutex--;
  473 }
  474 #endif  /* !RASOPS_SMALL */
  475 
  476 /*
  477  * Grab routines common to depths where (bpp < 8)
  478  */
  479 #define NAME(ident)     rasops2_##ident
  480 #define PIXEL_SHIFT     1
  481 
  482 #include <dev/rasops/rasops_bitops.h>

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