root/dev/rasops/rasops24.c

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

DEFINITIONS

This source file includes following definitions.
  1. rasops24_init
  2. rasops24_putchar
  3. rasops24_makestamp
  4. rasops24_putchar8
  5. rasops24_putchar12
  6. rasops24_putchar16
  7. rasops24_eraserows
  8. rasops24_erasecols

    1 /*      $OpenBSD: rasops24.c,v 1.5 2002/07/27 22:17:49 miod Exp $       */
    2 /*      $NetBSD: rasops24.c,v 1.12 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 <machine/endian.h>
   45 
   46 #include <dev/wscons/wsdisplayvar.h>
   47 #include <dev/wscons/wsconsio.h>
   48 #include <dev/rasops/rasops.h>
   49 
   50 void    rasops24_erasecols(void *, int, int, int, long);
   51 void    rasops24_eraserows(void *, int, int, long);
   52 void    rasops24_putchar(void *, int, int, u_int, long attr);
   53 #ifndef RASOPS_SMALL
   54 void    rasops24_putchar8(void *, int, int, u_int, long attr);
   55 void    rasops24_putchar12(void *, int, int, u_int, long attr);
   56 void    rasops24_putchar16(void *, int, int, u_int, long attr);
   57 void    rasops24_makestamp(struct rasops_info *, long);
   58 
   59 /*
   60  * 4x1 stamp for optimized character blitting
   61  */
   62 static int32_t  stamp[64];
   63 static long     stamp_attr;
   64 static int      stamp_mutex;    /* XXX see note in readme */
   65 #endif
   66 
   67 /*
   68  * XXX this confuses the hell out of gcc2 (not egcs) which always insists
   69  * that the shift count is negative.
   70  *
   71  * offset = STAMP_SHIFT(fontbits, nibble #) & STAMP_MASK
   72  * destination int32_t[0] = STAMP_READ(offset)
   73  * destination int32_t[1] = STAMP_READ(offset + 4)
   74  * destination int32_t[2] = STAMP_READ(offset + 8)
   75  */
   76 #define STAMP_SHIFT(fb,n)       ((n*4-4) >= 0 ? (fb)>>(n*4-4):(fb)<<-(n*4-4))
   77 #define STAMP_MASK              (0xf << 4)
   78 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   79 
   80 /*
   81  * Initialize rasops_info struct for this colordepth.
   82  */
   83 void
   84 rasops24_init(ri)
   85         struct rasops_info *ri;
   86 {
   87 
   88         switch (ri->ri_font->fontwidth) {
   89 #ifndef RASOPS_SMALL
   90         case 8:
   91                 ri->ri_ops.putchar = rasops24_putchar8;
   92                 break;
   93         case 12:
   94                 ri->ri_ops.putchar = rasops24_putchar12;
   95                 break;
   96         case 16:
   97                 ri->ri_ops.putchar = rasops24_putchar16;
   98                 break;
   99 #endif
  100         default:
  101                 ri->ri_ops.putchar = rasops24_putchar;
  102                 break;
  103         }
  104 
  105         if (ri->ri_rnum == 0) {
  106                 ri->ri_rnum = 8;
  107                 ri->ri_rpos = 0;
  108                 ri->ri_gnum = 8;
  109                 ri->ri_gpos = 8;
  110                 ri->ri_bnum = 8;
  111                 ri->ri_bpos = 16;
  112         }
  113 
  114         ri->ri_ops.erasecols = rasops24_erasecols;
  115         ri->ri_ops.eraserows = rasops24_eraserows;
  116 }
  117 
  118 /*
  119  * Put a single character. This is the generic version.
  120  * XXX this bites - we should use masks.
  121  */
  122 void
  123 rasops24_putchar(cookie, row, col, uc, attr)
  124         void *cookie;
  125         int row, col;
  126         u_int uc;
  127         long attr;
  128 {
  129         int fb, width, height, cnt, clr[2];
  130         struct rasops_info *ri;
  131         u_char *dp, *rp, *fr;
  132 
  133         ri = (struct rasops_info *)cookie;
  134 
  135 #ifdef RASOPS_CLIPPING
  136         /* Catches 'row < 0' case too */
  137         if ((unsigned)row >= (unsigned)ri->ri_rows)
  138                 return;
  139 
  140         if ((unsigned)col >= (unsigned)ri->ri_cols)
  141                 return;
  142 #endif
  143 
  144         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  145         height = ri->ri_font->fontheight;
  146         width = ri->ri_font->fontwidth;
  147 
  148         clr[1] = ri->ri_devcmap[((u_int)attr >> 24) & 0xf];
  149         clr[0] = ri->ri_devcmap[((u_int)attr >> 16) & 0xf];
  150 
  151         if (uc == ' ') {
  152                 u_char c = clr[0];
  153                 while (height--) {
  154                         dp = rp;
  155                         rp += ri->ri_stride;
  156 
  157                         for (cnt = width; cnt; cnt--) {
  158                                 *dp++ = c >> 16;
  159                                 *dp++ = c >> 8;
  160                                 *dp++ = c;
  161                         }
  162                 }
  163         } else {
  164                 uc -= ri->ri_font->firstchar;
  165                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  166 
  167                 while (height--) {
  168                         dp = rp;
  169                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) |
  170                             (fr[0] << 24);
  171                         fr += ri->ri_font->stride;
  172                         rp += ri->ri_stride;
  173 
  174                         for (cnt = width; cnt; cnt--, fb <<= 1) {
  175                                 if ((fb >> 31) & 1) {
  176                                         *dp++ = clr[1] >> 16;
  177                                         *dp++ = clr[1] >> 8;
  178                                         *dp++ = clr[1];
  179                                 } else {
  180                                         *dp++ = clr[0] >> 16;
  181                                         *dp++ = clr[0] >> 8;
  182                                         *dp++ = clr[0];
  183                                 }
  184                         }
  185                 }
  186         }
  187 
  188         /* Do underline */
  189         if ((attr & 1) != 0) {
  190                 u_char c = clr[1];
  191 
  192                 rp -= ri->ri_stride << 1;
  193 
  194                 while (width--) {
  195                         *rp++ = c >> 16;
  196                         *rp++ = c >> 8;
  197                         *rp++ = c;
  198                 }
  199         }
  200 }
  201 
  202 #ifndef RASOPS_SMALL
  203 /*
  204  * Recompute the blitting stamp.
  205  */
  206 void
  207 rasops24_makestamp(ri, attr)
  208         struct rasops_info *ri;
  209         long attr;
  210 {
  211         u_int fg, bg, c1, c2, c3, c4;
  212         int i;
  213 
  214         fg = ri->ri_devcmap[((u_int)attr >> 24) & 0xf] & 0xffffff;
  215         bg = ri->ri_devcmap[((u_int)attr >> 16) & 0xf] & 0xffffff;
  216         stamp_attr = attr;
  217 
  218         for (i = 0; i < 64; i += 4) {
  219 #if BYTE_ORDER == LITTLE_ENDIAN
  220                 c1 = (i & 32 ? fg : bg);
  221                 c2 = (i & 16 ? fg : bg);
  222                 c3 = (i & 8 ? fg : bg);
  223                 c4 = (i & 4 ? fg : bg);
  224 #else
  225                 c1 = (i & 8 ? fg : bg);
  226                 c2 = (i & 4 ? fg : bg);
  227                 c3 = (i & 16 ? fg : bg);
  228                 c4 = (i & 32 ? fg : bg);
  229 #endif
  230                 stamp[i+0] = (c1 <<  8) | (c2 >> 16);
  231                 stamp[i+1] = (c2 << 16) | (c3 >>  8);
  232                 stamp[i+2] = (c3 << 24) | c4;
  233 
  234 #if BYTE_ORDER == LITTLE_ENDIAN
  235                 if ((ri->ri_flg & RI_BSWAP) == 0) {
  236 #else
  237                 if ((ri->ri_flg & RI_BSWAP) != 0) {
  238 #endif
  239                         stamp[i+0] = swap32(stamp[i+0]);
  240                         stamp[i+1] = swap32(stamp[i+1]);
  241                         stamp[i+2] = swap32(stamp[i+2]);
  242                 }
  243         }
  244 }
  245 
  246 /*
  247  * Put a single character. This is for 8-pixel wide fonts.
  248  */
  249 void
  250 rasops24_putchar8(cookie, row, col, uc, attr)
  251         void *cookie;
  252         int row, col;
  253         u_int uc;
  254         long attr;
  255 {
  256         struct rasops_info *ri;
  257         int height, so, fs;
  258         int32_t *rp;
  259         u_char *fr;
  260 
  261         /* Can't risk remaking the stamp if it's already in use */
  262         if (stamp_mutex++) {
  263                 stamp_mutex--;
  264                 rasops24_putchar(cookie, row, col, uc, attr);
  265                 return;
  266         }
  267 
  268         ri = (struct rasops_info *)cookie;
  269 
  270 #ifdef RASOPS_CLIPPING
  271         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  272                 stamp_mutex--;
  273                 return;
  274         }
  275 
  276         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  277                 stamp_mutex--;
  278                 return;
  279         }
  280 #endif
  281 
  282         /* Recompute stamp? */
  283         if (attr != stamp_attr)
  284                 rasops24_makestamp(ri, attr);
  285 
  286         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  287         height = ri->ri_font->fontheight;
  288 
  289         if (uc == (u_int)-1) {
  290                 int32_t c = stamp[0];
  291                 while (height--) {
  292                         rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  293                         DELTA(rp, ri->ri_stride, int32_t *);
  294                 }
  295         } else {
  296                 uc -= ri->ri_font->firstchar;
  297                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  298                 fs = ri->ri_font->stride;
  299 
  300                 while (height--) {
  301                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  302                         rp[0] = STAMP_READ(so);
  303                         rp[1] = STAMP_READ(so + 4);
  304                         rp[2] = STAMP_READ(so + 8);
  305 
  306                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  307                         rp[3] = STAMP_READ(so);
  308                         rp[4] = STAMP_READ(so + 4);
  309                         rp[5] = STAMP_READ(so + 8);
  310 
  311                         fr += fs;
  312                         DELTA(rp, ri->ri_stride, int32_t *);
  313                 }
  314         }
  315 
  316         /* Do underline */
  317         if ((attr & 1) != 0) {
  318                 int32_t c = STAMP_READ(52);
  319 
  320                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  321                 rp[0] = rp[1] = rp[2] = rp[3] = rp[4] = rp[5] = c;
  322         }
  323 
  324         stamp_mutex--;
  325 }
  326 
  327 /*
  328  * Put a single character. This is for 12-pixel wide fonts.
  329  */
  330 void
  331 rasops24_putchar12(cookie, row, col, uc, attr)
  332         void *cookie;
  333         int row, col;
  334         u_int uc;
  335         long attr;
  336 {
  337         struct rasops_info *ri;
  338         int height, so, fs;
  339         int32_t *rp;
  340         u_char *fr;
  341 
  342         /* Can't risk remaking the stamp if it's already in use */
  343         if (stamp_mutex++) {
  344                 stamp_mutex--;
  345                 rasops24_putchar(cookie, row, col, uc, attr);
  346                 return;
  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;
  355         }
  356 
  357         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  358                 stamp_mutex--;
  359                 return;
  360         }
  361 #endif
  362 
  363         /* Recompute stamp? */
  364         if (attr != stamp_attr)
  365                 rasops24_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 == (u_int)-1) {
  371                 int32_t c = stamp[0];
  372                 while (height--) {
  373                         rp[0] = rp[1] = rp[2] = rp[3] =
  374                         rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
  375                         DELTA(rp, ri->ri_stride, int32_t *);
  376                 }
  377         } else {
  378                 uc -= ri->ri_font->firstchar;
  379                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  380                 fs = ri->ri_font->stride;
  381 
  382                 while (height--) {
  383                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  384                         rp[0] = STAMP_READ(so);
  385                         rp[1] = STAMP_READ(so + 4);
  386                         rp[2] = STAMP_READ(so + 8);
  387 
  388                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  389                         rp[3] = STAMP_READ(so);
  390                         rp[4] = STAMP_READ(so + 4);
  391                         rp[5] = STAMP_READ(so + 8);
  392 
  393                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  394                         rp[6] = STAMP_READ(so);
  395                         rp[7] = STAMP_READ(so + 4);
  396                         rp[8] = STAMP_READ(so + 8);
  397 
  398                         fr += fs;
  399                         DELTA(rp, ri->ri_stride, int32_t *);
  400                 }
  401         }
  402 
  403         /* Do underline */
  404         if ((attr & 1) != 0) {
  405                 int32_t c = STAMP_READ(52);
  406 
  407                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  408                 rp[0] = rp[1] = rp[2] = rp[3] =
  409                 rp[4] = rp[5] = rp[6] = rp[7] = rp[8] = c;
  410         }
  411 
  412         stamp_mutex--;
  413 }
  414 
  415 /*
  416  * Put a single character. This is for 16-pixel wide fonts.
  417  */
  418 void
  419 rasops24_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, so, fs;
  427         int32_t *rp;
  428         u_char *fr;
  429 
  430         /* Can't risk remaking the stamp if it's already in use */
  431         if (stamp_mutex++) {
  432                 stamp_mutex--;
  433                 rasops24_putchar(cookie, row, col, uc, attr);
  434                 return;
  435         }
  436 
  437         ri = (struct rasops_info *)cookie;
  438 
  439 #ifdef RASOPS_CLIPPING
  440         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  441                 stamp_mutex--;
  442                 return;
  443         }
  444 
  445         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  446                 stamp_mutex--;
  447                 return;
  448         }
  449 #endif
  450 
  451         /* Recompute stamp? */
  452         if (attr != stamp_attr)
  453                 rasops24_makestamp(ri, attr);
  454 
  455         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  456         height = ri->ri_font->fontheight;
  457 
  458         if (uc == (u_int)-1) {
  459                 int32_t c = stamp[0];
  460                 while (height--) {
  461                         rp[0] = rp[1] = rp[2] = rp[3] =
  462                         rp[4] = rp[5] = rp[6] = rp[7] =
  463                         rp[8] = rp[9] = rp[10] = rp[11] = c;
  464                         DELTA(rp, ri->ri_stride, int32_t *);
  465                 }
  466         } else {
  467                 uc -= ri->ri_font->firstchar;
  468                 fr = (u_char *)ri->ri_font->data + uc*ri->ri_fontscale;
  469                 fs = ri->ri_font->stride;
  470 
  471                 while (height--) {
  472                         so = STAMP_SHIFT(fr[0], 1) & STAMP_MASK;
  473                         rp[0] = STAMP_READ(so);
  474                         rp[1] = STAMP_READ(so + 4);
  475                         rp[2] = STAMP_READ(so + 8);
  476 
  477                         so = STAMP_SHIFT(fr[0], 0) & STAMP_MASK;
  478                         rp[3] = STAMP_READ(so);
  479                         rp[4] = STAMP_READ(so + 4);
  480                         rp[5] = STAMP_READ(so + 8);
  481 
  482                         so = STAMP_SHIFT(fr[1], 1) & STAMP_MASK;
  483                         rp[6] = STAMP_READ(so);
  484                         rp[7] = STAMP_READ(so + 4);
  485                         rp[8] = STAMP_READ(so + 8);
  486 
  487                         so = STAMP_SHIFT(fr[1], 0) & STAMP_MASK;
  488                         rp[9] = STAMP_READ(so);
  489                         rp[10] = STAMP_READ(so + 4);
  490                         rp[11] = STAMP_READ(so + 8);
  491 
  492                         DELTA(rp, ri->ri_stride, int32_t *);
  493                         fr += fs;
  494                 }
  495         }
  496 
  497         /* Do underline */
  498         if ((attr & 1) != 0) {
  499                 int32_t c = STAMP_READ(52);
  500 
  501                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  502                 rp[0] = rp[1] = rp[2] = rp[3] =
  503                 rp[4] = rp[5] = rp[6] = rp[7] =
  504                 rp[8] = rp[9] = rp[10] = rp[11] = c;
  505         }
  506 
  507         stamp_mutex--;
  508 }
  509 #endif  /* !RASOPS_SMALL */
  510 
  511 /*
  512  * Erase rows. This is nice and easy due to alignment.
  513  */
  514 void
  515 rasops24_eraserows(cookie, row, num, attr)
  516         void *cookie;
  517         int row, num;
  518         long attr;
  519 {
  520         int n9, n3, n1, cnt, stride, delta;
  521         u_int32_t *dp, clr, stamp[3];
  522         struct rasops_info *ri;
  523 
  524         /*
  525          * If the color is gray, we can cheat and use the generic routines
  526          * (which are faster, hopefully) since the r,g,b values are the same.
  527          */
  528         if ((attr & 4) != 0) {
  529                 rasops_eraserows(cookie, row, num, attr);
  530                 return;
  531         }
  532 
  533         ri = (struct rasops_info *)cookie;
  534 
  535 #ifdef RASOPS_CLIPPING
  536         if (row < 0) {
  537                 num += row;
  538                 row = 0;
  539         }
  540 
  541         if ((row + num) > ri->ri_rows)
  542                 num = ri->ri_rows - row;
  543 
  544         if (num <= 0)
  545                 return;
  546 #endif
  547 
  548         clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
  549         stamp[0] = (clr <<  8) | (clr >> 16);
  550         stamp[1] = (clr << 16) | (clr >>  8);
  551         stamp[2] = (clr << 24) | clr;
  552 
  553 #if BYTE_ORDER == LITTLE_ENDIAN
  554         if ((ri->ri_flg & RI_BSWAP) == 0) {
  555 #else
  556         if ((ri->ri_flg & RI_BSWAP) != 0) {
  557 #endif
  558                 stamp[0] = swap32(stamp[0]);
  559                 stamp[1] = swap32(stamp[1]);
  560                 stamp[2] = swap32(stamp[2]);
  561         }
  562 
  563         /*
  564          * XXX the wsdisplay_emulops interface seems a little deficient in
  565          * that there is no way to clear the *entire* screen. We provide a
  566          * workaround here: if the entire console area is being cleared, and
  567          * the RI_FULLCLEAR flag is set, clear the entire display.
  568          */
  569         if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR) != 0) {
  570                 stride = ri->ri_stride;
  571                 num = ri->ri_height;
  572                 dp = (int32_t *)ri->ri_origbits;
  573                 delta = 0;
  574         } else {
  575                 stride = ri->ri_emustride;
  576                 num *= ri->ri_font->fontheight;
  577                 dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
  578                 delta = ri->ri_delta;
  579         }
  580 
  581         n9 = stride / 36;
  582         cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
  583         n3 = (stride - cnt) / 12;
  584         cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
  585         n1 = (stride - cnt) >> 2;
  586 
  587         while (num--) {
  588                 for (cnt = n9; cnt; cnt--) {
  589                         dp[0] = stamp[0];
  590                         dp[1] = stamp[1];
  591                         dp[2] = stamp[2];
  592                         dp[3] = stamp[0];
  593                         dp[4] = stamp[1];
  594                         dp[5] = stamp[2];
  595                         dp[6] = stamp[0];
  596                         dp[7] = stamp[1];
  597                         dp[8] = stamp[2];
  598                         dp += 9;
  599                 }
  600 
  601                 for (cnt = n3; cnt; cnt--) {
  602                         dp[0] = stamp[0];
  603                         dp[1] = stamp[1];
  604                         dp[2] = stamp[2];
  605                         dp += 3;
  606                 }
  607 
  608                 for (cnt = 0; cnt < n1; cnt++)
  609                         *dp++ = stamp[cnt];
  610 
  611                 DELTA(dp, delta, int32_t *);
  612         }
  613 }
  614 
  615 /*
  616  * Erase columns.
  617  */
  618 void
  619 rasops24_erasecols(cookie, row, col, num, attr)
  620         void *cookie;
  621         int row, col, num;
  622         long attr;
  623 {
  624         int n12, n4, height, cnt, slop, clr, stamp[3];
  625         struct rasops_info *ri;
  626         int32_t *dp, *rp;
  627         u_char *dbp;
  628 
  629         /*
  630          * If the color is gray, we can cheat and use the generic routines
  631          * (which are faster, hopefully) since the r,g,b values are the same.
  632          */
  633         if ((attr & 4) != 0) {
  634                 rasops_erasecols(cookie, row, col, num, attr);
  635                 return;
  636         }
  637 
  638         ri = (struct rasops_info *)cookie;
  639 
  640 #ifdef RASOPS_CLIPPING
  641         /* Catches 'row < 0' case too */
  642         if ((unsigned)row >= (unsigned)ri->ri_rows)
  643                 return;
  644 
  645         if (col < 0) {
  646                 num += col;
  647                 col = 0;
  648         }
  649 
  650         if ((col + num) > ri->ri_cols)
  651                 num = ri->ri_cols - col;
  652 
  653         if (num <= 0)
  654                 return;
  655 #endif
  656 
  657         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  658         num *= ri->ri_font->fontwidth;
  659         height = ri->ri_font->fontheight;
  660 
  661         clr = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xffffff;
  662         stamp[0] = (clr <<  8) | (clr >> 16);
  663         stamp[1] = (clr << 16) | (clr >>  8);
  664         stamp[2] = (clr << 24) | clr;
  665 
  666 #if BYTE_ORDER == LITTLE_ENDIAN
  667         if ((ri->ri_flg & RI_BSWAP) == 0) {
  668 #else
  669         if ((ri->ri_flg & RI_BSWAP) != 0) {
  670 #endif
  671                 stamp[0] = swap32(stamp[0]);
  672                 stamp[1] = swap32(stamp[1]);
  673                 stamp[2] = swap32(stamp[2]);
  674         }
  675 
  676         /*
  677          * The current byte offset mod 4 tells us the number of 24-bit pels
  678          * we need to write for alignment to 32-bits. Once we're aligned on
  679          * a 32-bit boundary, we're also aligned on a 4 pixel boundary, so
  680          * the stamp does not need to be rotated. The following shows the
  681          * layout of 4 pels in a 3 word region and illustrates this:
  682          *
  683          *      aaab bbcc cddd
  684          */
  685         slop = (long)rp & 3;    num -= slop;
  686         n12 = num / 12;         num -= (n12 << 3) + (n12 << 2);
  687         n4 = num >> 2;          num &= 3;
  688 
  689         while (height--) {
  690                 dbp = (u_char *)rp;
  691                 DELTA(rp, ri->ri_stride, int32_t *);
  692 
  693                 /* Align to 4 bytes */
  694                 /* XXX handle with masks, bring under control of RI_BSWAP */
  695                 for (cnt = slop; cnt; cnt--) {
  696                         *dbp++ = (clr >> 16);
  697                         *dbp++ = (clr >> 8);
  698                         *dbp++ = clr;
  699                 }
  700 
  701                 dp = (int32_t *)dbp;
  702 
  703                 /* 12 pels per loop */
  704                 for (cnt = n12; cnt; cnt--) {
  705                         dp[0] = stamp[0];
  706                         dp[1] = stamp[1];
  707                         dp[2] = stamp[2];
  708                         dp[3] = stamp[0];
  709                         dp[4] = stamp[1];
  710                         dp[5] = stamp[2];
  711                         dp[6] = stamp[0];
  712                         dp[7] = stamp[1];
  713                         dp[8] = stamp[2];
  714                         dp += 9;
  715                 }
  716 
  717                 /* 4 pels per loop */
  718                 for (cnt = n4; cnt; cnt--) {
  719                         dp[0] = stamp[0];
  720                         dp[1] = stamp[1];
  721                         dp[2] = stamp[2];
  722                         dp += 3;
  723                 }
  724 
  725                 /* Trailing slop */
  726                 /* XXX handle with masks, bring under control of RI_BSWAP */
  727                 dbp = (u_char *)dp;
  728                 for (cnt = num; cnt; cnt--) {
  729                         *dbp++ = (clr >> 16);
  730                         *dbp++ = (clr >> 8);
  731                         *dbp++ = clr;
  732                 }
  733         }
  734 }

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