root/dev/rasops/rasops4.c

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

DEFINITIONS

This source file includes following definitions.
  1. rasops4_init
  2. rasops4_putchar
  3. rasops4_putchar
  4. rasops4_makestamp
  5. rasops4_putchar8
  6. rasops4_putchar12
  7. rasops4_putchar16

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

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