The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/rasops/rasops8.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: rasops8.c,v 1.21 2006/02/18 13:57:33 jmcneill Exp $    */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: rasops8.c,v 1.21 2006/02/18 13:57:33 jmcneill Exp $");
   41 
   42 #include "opt_rasops.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/time.h>
   47 
   48 #include <dev/wscons/wsdisplayvar.h>
   49 #include <dev/wscons/wsconsio.h>
   50 #include <dev/rasops/rasops.h>
   51 
   52 static void     rasops8_putchar(void *, int, int, u_int, long attr);
   53 #ifndef RASOPS_SMALL
   54 static void     rasops8_putchar8(void *, int, int, u_int, long attr);
   55 static void     rasops8_putchar12(void *, int, int, u_int, long attr);
   56 static void     rasops8_putchar16(void *, int, int, u_int, long attr);
   57 static void     rasops8_makestamp(struct rasops_info *ri, long);
   58 
   59 /*
   60  * 4x1 stamp for optimized character blitting
   61  */
   62 static int32_t  stamp[16];
   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 = STAMP_READ(offset)
   73  */
   74 #define STAMP_SHIFT(fb,n)       ((n*4-2) >= 0 ? (fb)>>(n*4-2):(fb)<<-(n*4-2))
   75 #define STAMP_MASK              (0xf << 2)
   76 #define STAMP_READ(o)           (*(int32_t *)((caddr_t)stamp + (o)))
   77 
   78 /*
   79  * Initialize a 'rasops_info' descriptor for this depth.
   80  */
   81 void
   82 rasops8_init(ri)
   83         struct rasops_info *ri;
   84 {
   85 
   86         switch (ri->ri_font->fontwidth) {
   87 #ifndef RASOPS_SMALL
   88         case 8:
   89                 ri->ri_ops.putchar = rasops8_putchar8;
   90                 break;
   91         case 12:
   92                 ri->ri_ops.putchar = rasops8_putchar12;
   93                 break;
   94         case 16:
   95                 ri->ri_ops.putchar = rasops8_putchar16;
   96                 break;
   97 #endif /* !RASOPS_SMALL */
   98         default:
   99                 ri->ri_ops.putchar = rasops8_putchar;
  100                 break;
  101         }
  102 }
  103 
  104 /*
  105  * Put a single character.
  106  */
  107 static void
  108 rasops8_putchar(cookie, row, col, uc, attr)
  109         void *cookie;
  110         int row, col;
  111         u_int uc;
  112         long attr;
  113 {
  114         int width, height, cnt, fs, fb;
  115         u_char *dp, *rp, *hp, *hrp, *fr, clr[2];
  116         struct rasops_info *ri;
  117 
  118         ri = (struct rasops_info *)cookie;
  119         hp = hrp = NULL;
  120 
  121         if (!CHAR_IN_FONT(uc, ri->ri_font))
  122                 return;
  123 
  124 #ifdef RASOPS_CLIPPING
  125         /* Catches 'row < 0' case too */
  126         if ((unsigned)row >= (unsigned)ri->ri_rows)
  127                 return;
  128 
  129         if ((unsigned)col >= (unsigned)ri->ri_cols)
  130                 return;
  131 #endif
  132         rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
  133         if (ri->ri_hwbits)
  134                 hrp = ri->ri_hwbits + row * ri->ri_yscale + col *
  135                     ri->ri_xscale;
  136 
  137         height = ri->ri_font->fontheight;
  138         width = ri->ri_font->fontwidth;
  139         clr[0] = (u_char)ri->ri_devcmap[(attr >> 16) & 0xf];
  140         clr[1] = (u_char)ri->ri_devcmap[(attr >> 24) & 0xf];
  141 
  142         if (uc == ' ') {
  143                 u_char c = clr[0];
  144 
  145                 while (height--) {
  146                         dp = rp;
  147                         rp += ri->ri_stride;
  148                         if (ri->ri_hwbits) {
  149                                 hp = hrp;
  150                                 hrp += ri->ri_stride;
  151                         }
  152 
  153                         for (cnt = width; cnt; cnt--) {
  154                                 *dp++ = c;
  155                                 if (ri->ri_hwbits)
  156                                         *hp++ = c;
  157                         }
  158                 }
  159         } else {
  160                 uc -= ri->ri_font->firstchar;
  161                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  162                 fs = ri->ri_font->stride;
  163 
  164                 while (height--) {
  165                         dp = rp;
  166                         if (ri->ri_hwbits)
  167                                 hp = hrp;
  168                         fb = fr[3] | (fr[2] << 8) | (fr[1] << 16) | (fr[0] << 24);
  169                         fr += fs;
  170                         rp += ri->ri_stride;
  171                         if (ri->ri_hwbits)
  172                                 hrp += ri->ri_stride;
  173 
  174                         for (cnt = width; cnt; cnt--) {
  175                                 *dp++ = clr[(fb >> 31) & 1];
  176                                 if (ri->ri_hwbits)
  177                                         *hp++ = clr[(fb >> 31) & 1];
  178                                 fb <<= 1;
  179                         }
  180                 }
  181         }
  182 
  183         /* Do underline */
  184         if ((attr & 1) != 0) {
  185                 u_char c = clr[1];
  186 
  187                 rp -= (ri->ri_stride << 1);
  188                 if (ri->ri_hwbits)
  189                         hrp -= (ri->ri_stride << 1);
  190 
  191                 while (width--) {
  192                         *rp++ = c;
  193                         if (ri->ri_hwbits)
  194                                 *hrp++ = c;
  195                 }
  196         }
  197 }
  198 
  199 #ifndef RASOPS_SMALL
  200 /*
  201  * Recompute the 4x1 blitting stamp.
  202  */
  203 static void
  204 rasops8_makestamp(ri, attr)
  205         struct rasops_info *ri;
  206         long attr;
  207 {
  208         int32_t fg, bg;
  209         int i;
  210 
  211         fg = ri->ri_devcmap[(attr >> 24) & 0xf] & 0xff;
  212         bg = ri->ri_devcmap[(attr >> 16) & 0xf] & 0xff;
  213         stamp_attr = attr;
  214 
  215         for (i = 0; i < 16; i++) {
  216 #if BYTE_ORDER == BIG_ENDIAN
  217 #define NEED_LITTLE_ENDIAN_STAMP RI_BSWAP
  218 #else
  219 #define NEED_LITTLE_ENDIAN_STAMP 0
  220 #endif
  221                 if ((ri->ri_flg & RI_BSWAP) == NEED_LITTLE_ENDIAN_STAMP) {
  222                         /* little endian */
  223                         stamp[i] = (i & 8 ? fg : bg);
  224                         stamp[i] |= ((i & 4 ? fg : bg) << 8);
  225                         stamp[i] |= ((i & 2 ? fg : bg) << 16);
  226                         stamp[i] |= ((i & 1 ? fg : bg) << 24);
  227                 } else {
  228                         /* big endian */
  229                         stamp[i] = (i & 1 ? fg : bg);
  230                         stamp[i] |= ((i & 2 ? fg : bg) << 8);
  231                         stamp[i] |= ((i & 4 ? fg : bg) << 16);
  232                         stamp[i] |= ((i & 8 ? fg : bg) << 24);
  233                 }
  234         }
  235 }
  236 
  237 /*
  238  * Put a single character. This is for 8-pixel wide fonts.
  239  */
  240 static void
  241 rasops8_putchar8(cookie, row, col, uc, attr)
  242         void *cookie;
  243         int row, col;
  244         u_int uc;
  245         long attr;
  246 {
  247         struct rasops_info *ri;
  248         int height, fs;
  249         int32_t *rp, *hp;
  250         u_char *fr;
  251 
  252         /* Can't risk remaking the stamp if it's already in use */
  253         if (stamp_mutex++) {
  254                 stamp_mutex--;
  255                 rasops8_putchar(cookie, row, col, uc, attr);
  256                 return;
  257         }
  258 
  259         ri = (struct rasops_info *)cookie;
  260         hp = NULL;
  261 
  262         if (!CHAR_IN_FONT(uc, ri->ri_font))
  263                 return;
  264 
  265 #ifdef RASOPS_CLIPPING
  266         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  267                 stamp_mutex--;
  268                 return;
  269         }
  270 
  271         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  272                 stamp_mutex--;
  273                 return;
  274         }
  275 #endif
  276 
  277         /* Recompute stamp? */
  278         if (attr != stamp_attr)
  279                 rasops8_makestamp(ri, attr);
  280 
  281         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  282         if (ri->ri_hwbits)
  283                 hp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
  284                     col*ri->ri_xscale);
  285         height = ri->ri_font->fontheight;
  286 
  287         if (uc == ' ') {
  288                 while (height--) {
  289                         rp[0] = rp[1] = stamp[0];
  290                         DELTA(rp, ri->ri_stride, int32_t *);
  291                         if (ri->ri_hwbits) {
  292                                 hp[0] = hp[1] = stamp[0];
  293                                 DELTA(hp, ri->ri_stride, int32_t *);
  294                         }
  295                 }
  296         } else {
  297                 uc -= ri->ri_font->firstchar;
  298                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  299                 fs = ri->ri_font->stride;
  300 
  301                 while (height--) {
  302                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  303                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  304                         if (ri->ri_hwbits) {
  305                                 hp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) &
  306                                     STAMP_MASK);
  307                                 hp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) &
  308                                     STAMP_MASK);
  309                         }
  310 
  311                         fr += fs;
  312                         DELTA(rp, ri->ri_stride, int32_t *);
  313                         if (ri->ri_hwbits)
  314                                 DELTA(hp, ri->ri_stride, int32_t *);
  315                 }
  316         }
  317 
  318         /* Do underline */
  319         if ((attr & 1) != 0) {
  320                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  321                 rp[0] = rp[1] = stamp[15];
  322                 if (ri->ri_hwbits) {
  323                         DELTA(hp, -(ri->ri_stride << 1), int32_t *);
  324                         hp[0] = hp[1] = stamp[15];
  325                 }
  326         }
  327 
  328         stamp_mutex--;
  329 }
  330 
  331 /*
  332  * Put a single character. This is for 12-pixel wide fonts.
  333  */
  334 static void
  335 rasops8_putchar12(cookie, row, col, uc, attr)
  336         void *cookie;
  337         int row, col;
  338         u_int uc;
  339         long attr;
  340 {
  341         struct rasops_info *ri;
  342         int height, fs;
  343         int32_t *rp,  *hrp;
  344         u_char *fr;
  345 
  346         /* Can't risk remaking the stamp if it's already in use */
  347         if (stamp_mutex++) {
  348                 stamp_mutex--;
  349                 rasops8_putchar(cookie, row, col, uc, attr);
  350                 return;
  351         }
  352 
  353         ri = (struct rasops_info *)cookie;
  354         hrp = NULL;
  355 
  356         if (!CHAR_IN_FONT(uc, ri->ri_font))
  357             return;
  358 
  359 #ifdef RASOPS_CLIPPING
  360         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  361                 stamp_mutex--;
  362                 return;
  363         }
  364 
  365         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  366                 stamp_mutex--;
  367                 return;
  368         }
  369 #endif
  370 
  371         /* Recompute stamp? */
  372         if (attr != stamp_attr)
  373                 rasops8_makestamp(ri, attr);
  374 
  375         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  376         if (ri->ri_hwbits)
  377                 hrp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
  378                     col*ri->ri_xscale);
  379         height = ri->ri_font->fontheight;
  380 
  381         if (uc == ' ') {
  382                 while (height--) {
  383                         int32_t c = stamp[0];
  384 
  385                         rp[0] = rp[1] = rp[2] = c;
  386                         DELTA(rp, ri->ri_stride, int32_t *);
  387                         if (ri->ri_hwbits) {
  388                                 hrp[0] = hrp[1] = hrp[2] = c;
  389                                 DELTA(hrp, ri->ri_stride, int32_t *);
  390                         }
  391                 }
  392         } else {
  393                 uc -= ri->ri_font->firstchar;
  394                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  395                 fs = ri->ri_font->stride;
  396 
  397                 while (height--) {
  398                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  399                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  400                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  401                         if (ri->ri_hwbits) {
  402                                 hrp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  403                                 hrp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  404                                 hrp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  405                         }
  406 
  407                         fr += fs;
  408                         DELTA(rp, ri->ri_stride, int32_t *);
  409                         if (ri->ri_hwbits)
  410                                 DELTA(hrp, ri->ri_stride, int32_t *);
  411                 }
  412         }
  413 
  414         /* Do underline */
  415         if ((attr & 1) != 0) {
  416                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  417                 rp[0] = rp[1] = rp[2] = stamp[15];
  418                 if (ri->ri_hwbits) {
  419                         DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
  420                         hrp[0] = hrp[1] = hrp[2] = stamp[15];
  421                 }
  422         }
  423 
  424         stamp_mutex--;
  425 }
  426 
  427 /*
  428  * Put a single character. This is for 16-pixel wide fonts.
  429  */
  430 static void
  431 rasops8_putchar16(cookie, row, col, uc, attr)
  432         void *cookie;
  433         int row, col;
  434         u_int uc;
  435         long attr;
  436 {
  437         struct rasops_info *ri;
  438         int height, fs;
  439         int32_t *rp, *hrp;
  440         u_char *fr;
  441 
  442         /* Can't risk remaking the stamp if it's already in use */
  443         if (stamp_mutex++) {
  444                 stamp_mutex--;
  445                 rasops8_putchar(cookie, row, col, uc, attr);
  446                 return;
  447         }
  448 
  449         ri = (struct rasops_info *)cookie;
  450         hrp = NULL;
  451 
  452         if (!CHAR_IN_FONT(uc, ri->ri_font))
  453                 return;
  454 
  455 #ifdef RASOPS_CLIPPING
  456         if ((unsigned)row >= (unsigned)ri->ri_rows) {
  457                 stamp_mutex--;
  458                 return;
  459         }
  460 
  461         if ((unsigned)col >= (unsigned)ri->ri_cols) {
  462                 stamp_mutex--;
  463                 return;
  464         }
  465 #endif
  466 
  467         /* Recompute stamp? */
  468         if (attr != stamp_attr)
  469                 rasops8_makestamp(ri, attr);
  470 
  471         rp = (int32_t *)(ri->ri_bits + row*ri->ri_yscale + col*ri->ri_xscale);
  472         if (ri->ri_hwbits)
  473                 hrp = (int32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
  474                     col*ri->ri_xscale);
  475 
  476         height = ri->ri_font->fontheight;
  477 
  478         if (uc == ' ') {
  479                 while (height--) {
  480                         rp[0] = rp[1] = rp[2] = rp[3] = stamp[0];
  481                         if (ri->ri_hwbits)
  482                                 hrp[0] = hrp[1] = hrp[2] = hrp[3] = stamp[0];
  483                 }
  484         } else {
  485                 uc -= ri->ri_font->firstchar;
  486                 fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
  487                 fs = ri->ri_font->stride;
  488 
  489                 while (height--) {
  490                         rp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  491                         rp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  492                         rp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  493                         rp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
  494                         if (ri->ri_hwbits) {
  495                                 hrp[0] = STAMP_READ(STAMP_SHIFT(fr[0], 1) & STAMP_MASK);
  496                                 hrp[1] = STAMP_READ(STAMP_SHIFT(fr[0], 0) & STAMP_MASK);
  497                                 hrp[2] = STAMP_READ(STAMP_SHIFT(fr[1], 1) & STAMP_MASK);
  498                                 hrp[3] = STAMP_READ(STAMP_SHIFT(fr[1], 0) & STAMP_MASK);
  499                         }
  500 
  501                         fr += fs;
  502                         DELTA(rp, ri->ri_stride, int32_t *);
  503                         if (ri->ri_hwbits)
  504                                 DELTA(hrp, ri->ri_stride, int32_t *);
  505                 }
  506         }
  507 
  508         /* Do underline */
  509         if ((attr & 1) != 0) {
  510                 DELTA(rp, -(ri->ri_stride << 1), int32_t *);
  511                 rp[0] = rp[1] = rp[2] = rp[3] = stamp[15];
  512                 if (ri->ri_hwbits) {
  513                         DELTA(hrp, -(ri->ri_stride << 1), int32_t *);
  514                         hrp[0] = hrp[1] = hrp[2] = hrp[3] = stamp[15];
  515                 }
  516         }
  517 
  518         stamp_mutex--;
  519 }
  520 #endif /* !RASOPS_SMALL */

Cache object: 90f4c0f02a875c7501a548c146e2456d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.