root/dev/rasops/rasops15.c

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

DEFINITIONS

This source file includes following definitions.
  1. rasops15_init
  2. rasops15_putchar
  3. rasops15_makestamp
  4. rasops15_putchar8
  5. rasops15_putchar12
  6. rasops15_putchar16

    1 /*      $OpenBSD: rasops15.c,v 1.5 2006/01/08 17:18:05 miod Exp $       */
    2 /*      $NetBSD: rasops15.c,v 1.7 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    rasops15_putchar(void *, int, int, u_int, long attr);
   49 #ifndef RASOPS_SMALL
   50 void    rasops15_putchar8(void *, int, int, u_int, long attr);
   51 void    rasops15_putchar12(void *, int, int, u_int, long attr);
   52 void    rasops15_putchar16(void *, int, int, u_int, long attr);
   53 void    rasops15_makestamp(struct rasops_info *, long);
   54 
   55 /*
   56  * (2x2)x1 stamp for optimized character blitting
   57  */
   58 static int32_t  stamp[32];
   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 int32_t[0] = STAMP_READ(offset)
   69  * destination int32_t[1] = STAMP_READ(offset + 4)
   70  */
   71 #define STAMP_SHIFT(fb,n)       ((n*4-3) >= 0 ? (fb)>>(n*4-3):(fb)<<-(n*4-3))
   72 #define STAMP_MASK              (15 << 3)
   73 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   74 
   75 /*
   76  * Initialize rasops_info struct for this colordepth.
   77  */
   78 void
   79 rasops15_init(ri)
   80         struct rasops_info *ri;
   81 {
   82 
   83         switch (ri->ri_font->fontwidth) {
   84 #ifndef RASOPS_SMALL
   85         case 8:
   86                 ri->ri_ops.putchar = rasops15_putchar8;
   87                 break;
   88 
   89         case 12:
   90                 ri->ri_ops.putchar = rasops15_putchar12;
   91                 break;
   92 
   93         case 16:
   94                 ri->ri_ops.putchar = rasops15_putchar16;
   95                 break;
   96 #endif  /* !RASOPS_SMALL */
   97         default:
   98                 ri->ri_ops.putchar = rasops15_putchar;
   99                 break;
  100         }
  101 
  102         if (ri->ri_rnum == 0) {
  103                 ri->ri_rnum = 5;
  104                 ri->ri_rpos = 0;
  105                 ri->ri_gnum = 5 + (ri->ri_depth == 16);
  106                 ri->ri_gpos = 5;
  107                 ri->ri_bnum = 5;
  108                 ri->ri_bpos = 10 + (ri->ri_depth == 16);
  109         }
  110 }
  111 
  112 /*
  113  * Paint a single character.
  114  */
  115 void
  116 rasops15_putchar(cookie, row, col, uc, attr)
  117         void *cookie;
  118         int row, col;
  119         u_int uc;
  120         long attr;
  121 {
  122         int fb, width, height, cnt, clr[2];
  123         struct rasops_info *ri;
  124         u_char *dp, *rp, *fr;
  125 
  126         ri = (struct rasops_info *)cookie;
  127 
  128 #ifdef RASOPS_CLIPPING
  129         /* Catches 'row < 0' case too */
  130         if ((unsigned)row >= (unsigned)ri->ri_rows)
  131                 return;
  132 
  133         if ((unsigned)col >= (unsigned)ri->ri_cols)
  134                 return;
  135 #endif
  136 
  137         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  138         height = ri->ri_font->fontheight;
  139         width = ri->ri_font->fontwidth;
  140 
  141         clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
  142         clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
  143 
  144         if (uc == ' ') {
  145                 int16_t c = (int16_t)clr[0];
  146                 while (height--) {
  147                         dp = rp;
  148                         rp += ri->ri_stride;
  149 
  150                         for (cnt = width; cnt; cnt--) {
  151                                 *(int16_t *)dp = c;
  152                                 dp += 2;
  153                         }
  154                 }
  155         } else {
  156                 uc -= ri->ri_font->firstchar;
  157                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  158 
  159                 while (height--) {
  160                         dp = rp;
  161                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
  162                         fr += ri->ri_font->stride;
  163                         rp += ri->ri_stride;
  164 
  165                         for (cnt = width; cnt; cnt--) {
  166                                 *(int16_t *)dp = (int16_t)clr[(fb >> 31) & 1];
  167                                 fb <<= 1;
  168                                 dp += 2;
  169                         }
  170                 }
  171         }
  172 
  173         /* Do underline */
  174         if ((attr & 1) != 0) {
  175                 int16_t c = (int16_t)clr[1];
  176                 rp -= ri->ri_stride << 1;
  177 
  178                 while (width--) {
  179                         *(int16_t *)rp = c;
  180                         rp += 2;
  181                 }
  182         }
  183 }
  184 
  185 #ifndef RASOPS_SMALL
  186 /*
  187  * Recompute the (2x2)x1 blitting stamp.
  188  */
  189 void
  190 rasops15_makestamp(ri, attr)
  191         struct rasops_info *ri;
  192         long attr;
  193 {
  194         int32_t fg, bg;
  195         int i;
  196 
  197         fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffff;
  198         bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffff;
  199         stamp_attr = attr;
  200 
  201         for (i = 0; i < 32; i += 2) {
  202 #if BYTE_ORDER == LITTLE_ENDIAN
  203                 stamp[i] = (i & 16 ? fg : bg);
  204                 stamp[i] |= ((i & 8 ? fg : bg) << 16);
  205                 stamp[i + 1] = (i & 4 ? fg : bg);
  206                 stamp[i + 1] |= ((i & 2 ? fg : bg) << 16);
  207 #else
  208                 stamp[i + 1] = (i & 2 ? fg : bg);
  209                 stamp[i + 1] |= ((i & 4 ? fg : bg) << 16);
  210                 stamp[i] = (i & 8 ? fg : bg);
  211                 stamp[i] |= ((i & 16 ? fg : bg) << 16);
  212 #endif
  213         }
  214 }
  215 
  216 /*
  217  * Paint a single character. This is for 8-pixel wide fonts.
  218  */
  219 void
  220 rasops15_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, so, 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                 rasops15_putchar(cookie, row, col, uc, attr);
  235                 return;
  236         }
  237 
  238         ri = (struct rasops_info *)cookie;
  239 
  240 #ifdef RASOPS_CLIPPING
  241         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  242                 stamp_mutex--;
  243                 return;
  244         }
  245 
  246         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  247                 stamp_mutex--;
  248                 return;
  249         }
  250 #endif
  251 
  252         /* Recompute stamp? */
  253         if (attr != stamp_attr)
  254                 rasops15_makestamp(ri, attr);
  255 
  256         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  257         height = ri->ri_font->fontheight;
  258 
  259         if (uc == (u_int)-1) {
  260                 int32_t c = stamp[0];
  261                 while (height--) {
  262                         rp[0] = rp[1] = rp[2] = rp[3] = c;
  263                         DELTA(rp, ri->ri_stride, int32_t *);
  264                 }
  265         } else {
  266                 uc -= ri->ri_font->firstchar;
  267                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  268                 fs = ri->ri_font->stride;
  269 
  270                 while (height--) {
  271                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  272                         rp[0] = STAMP_READ(so);
  273                         rp[1] = STAMP_READ(so + 4);
  274 
  275                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  276                         rp[2] = STAMP_READ(so);
  277                         rp[3] = STAMP_READ(so + 4);
  278 
  279                         fr += fs;
  280                         DELTA(rp, ri->ri_stride, int32_t *);
  281                 }
  282         }
  283 
  284         /* Do underline */
  285         if ((attr & 1) != 0) {
  286                 int32_t c = STAMP_READ(28);
  287 
  288                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  289                 rp[0] = rp[1] = rp[2] = rp[3] = c;
  290         }
  291 
  292         stamp_mutex--;
  293 }
  294 
  295 /*
  296  * Paint a single character. This is for 12-pixel wide fonts.
  297  */
  298 void
  299 rasops15_putchar12(cookie, row, col, uc, attr)
  300         void *cookie;
  301         int row, col;
  302         u_int uc;
  303         long attr;
  304 {
  305         struct rasops_info *ri;
  306         int height, so, fs;
  307         int32_t *rp;
  308         u_char *fr;
  309 
  310         /* Can't risk remaking the stamp if it's already in use */
  311         if (stamp_mutex++) {
  312                 stamp_mutex--;
  313                 rasops15_putchar(cookie, row, col, uc, attr);
  314                 return;
  315         }
  316 
  317         ri = (struct rasops_info *)cookie;
  318 
  319 #ifdef RASOPS_CLIPPING
  320         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  321                 stamp_mutex--;
  322                 return;
  323         }
  324 
  325         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  326                 stamp_mutex--;
  327                 return;
  328         }
  329 #endif
  330 
  331         /* Recompute stamp? */
  332         if (attr != stamp_attr)
  333                 rasops15_makestamp(ri, attr);
  334 
  335         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  336         height = ri->ri_font->fontheight;
  337 
  338         if (uc == (u_int)-1) {
  339                 int32_t c = stamp[0];
  340                 while (height--) {
  341                         rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  342                         DELTA(rp, ri->ri_stride, int32_t *);
  343                 }
  344         } else {
  345                 uc -= ri->ri_font->firstchar;
  346                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  347                 fs = ri->ri_font->stride;
  348 
  349                 while (height--) {
  350                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  351                         rp[0] = STAMP_READ(so);
  352                         rp[1] = STAMP_READ(so + 4);
  353 
  354                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  355                         rp[2] = STAMP_READ(so);
  356                         rp[3] = STAMP_READ(so + 4);
  357 
  358                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  359                         rp[4] = STAMP_READ(so);
  360                         rp[5] = STAMP_READ(so + 4);
  361 
  362                         fr += fs;
  363                         DELTA(rp, ri->ri_stride, int32_t *);
  364                 }
  365         }
  366 
  367         /* Do underline */
  368         if (attr & 1) {
  369                 int32_t c = STAMP_READ(28);
  370 
  371                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  372                 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  373         }
  374 
  375         stamp_mutex--;
  376 }
  377 
  378 /*
  379  * Paint a single character. This is for 16-pixel wide fonts.
  380  */
  381 void
  382 rasops15_putchar16(cookie, row, col, uc, attr)
  383         void *cookie;
  384         int row, col;
  385         u_int uc;
  386         long attr;
  387 {
  388         struct rasops_info *ri;
  389         int height, so, fs;
  390         int32_t *rp;
  391         u_char *fr;
  392 
  393         /* Can't risk remaking the stamp if it's already in use */
  394         if (stamp_mutex++) {
  395                 stamp_mutex--;
  396                 rasops15_putchar(cookie, row, col, uc, attr);
  397                 return;
  398         }
  399 
  400         ri = (struct rasops_info *)cookie;
  401 
  402 #ifdef RASOPS_CLIPPING
  403         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  404                 stamp_mutex--;
  405                 return;
  406         }
  407 
  408         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  409                 stamp_mutex--;
  410                 return;
  411         }
  412 #endif
  413 
  414         /* Recompute stamp? */
  415         if (attr != stamp_attr)
  416                 rasops15_makestamp(ri, attr);
  417 
  418         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  419         height = ri->ri_font->fontheight;
  420 
  421         if (uc == (u_int)-1) {
  422                 int32_t c = stamp[0];
  423                 while (height--) {
  424                         rp[0] = rp[1] = rp[2] = rp[3] =
  425                         rp[4] = rp[5] = rp[6] = rp[7] = c;
  426                         DELTA(rp, ri->ri_stride, int32_t *);
  427                 }
  428         } else {
  429                 uc -= ri->ri_font->firstchar;
  430                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  431                 fs = ri->ri_font->stride;
  432 
  433                 while (height--) {
  434                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  435                         rp[0] = STAMP_READ(so);
  436                         rp[1] = STAMP_READ(so + 4);
  437 
  438                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  439                         rp[2] = STAMP_READ(so);
  440                         rp[3] = STAMP_READ(so + 4);
  441 
  442                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  443                         rp[4] = STAMP_READ(so);
  444                         rp[5] = STAMP_READ(so + 4);
  445 
  446                         so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
  447                         rp[6] = STAMP_READ(so);
  448                         rp[7] = STAMP_READ(so + 4);
  449 
  450                         DELTA(rp, ri->ri_stride, int32_t *);
  451                         fr += fs;
  452                 }
  453         }
  454 
  455         /* Do underline */
  456         if (attr & 1) {
  457                 int32_t c = STAMP_READ(28);
  458 
  459                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  460                 rp[0] = rp[1] = rp[2] = rp[3] =
  461                 rp[4] = rp[5] = rp[6] = rp[7] = c;
  462         }
  463 
  464         stamp_mutex--;
  465 }
  466 #endif  /* !RASOPS_SMALL */

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