Module Name: src Committed By: rin Date: Wed Aug 7 12:36:36 UTC 2019
Modified Files: src/sys/dev/rasops: rasops2.c rasops4.c rasops_bitops.h Added Files: src/sys/dev/rasops: rasops1-4_putchar.h Log Message: Separate general putchar for 1-4bpp from rasops_bitops: - Support anti-aliasing for 2bpp, which works perfectly! - Support scaling underline dimensions with font height. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/sys/dev/rasops/rasops1-4_putchar.h cvs rdiff -u -r1.30 -r1.31 src/sys/dev/rasops/rasops2.c cvs rdiff -u -r1.25 -r1.26 src/sys/dev/rasops/rasops4.c cvs rdiff -u -r1.23 -r1.24 src/sys/dev/rasops/rasops_bitops.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/rasops/rasops2.c diff -u src/sys/dev/rasops/rasops2.c:1.30 src/sys/dev/rasops/rasops2.c:1.31 --- src/sys/dev/rasops/rasops2.c:1.30 Wed Aug 7 11:47:33 2019 +++ src/sys/dev/rasops/rasops2.c Wed Aug 7 12:36:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops2.c,v 1.30 2019/08/07 11:47:33 rin Exp $ */ +/* $NetBSD: rasops2.c,v 1.31 2019/08/07 12:36:36 rin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops2.c,v 1.30 2019/08/07 11:47:33 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops2.c,v 1.31 2019/08/07 12:36:36 rin Exp $"); #include "opt_rasops.h" @@ -51,6 +51,7 @@ static void rasops2_copycols(void *, int static void rasops2_erasecols(void *, int, int, int, long); static void rasops2_do_cursor(struct rasops_info *); static void rasops2_putchar(void *, int, int col, u_int, long); +static void rasops2_putchar_aa(void *, int, int col, u_int, long); #ifndef RASOPS_SMALL static void rasops2_putchar8(void *, int, int col, u_int, long); static void rasops2_putchar12(void *, int, int col, u_int, long); @@ -86,6 +87,11 @@ rasops2_init(struct rasops_info *ri) ri->ri_do_cursor = rasops2_do_cursor; } + if (FONT_IS_ALPHA(ri->ri_font)) { + ri->ri_ops.putchar = rasops2_putchar_aa; + return; + } + switch (ri->ri_font->fontwidth) { #ifndef RASOPS_SMALL case 8: @@ -163,4 +169,11 @@ rasops2_makestamp(struct rasops_info *ri /* * Grab routines common to depths where (bpp < 8) */ +#undef RASOPS_AA +#include "rasops1-4_putchar.h" + +#define RASOPS_AA +#include "rasops1-4_putchar.h" +#undef RASOPS_AA + #include <dev/rasops/rasops_bitops.h> Index: src/sys/dev/rasops/rasops4.c diff -u src/sys/dev/rasops/rasops4.c:1.25 src/sys/dev/rasops/rasops4.c:1.26 --- src/sys/dev/rasops/rasops4.c:1.25 Wed Aug 7 11:47:33 2019 +++ src/sys/dev/rasops/rasops4.c Wed Aug 7 12:36:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops4.c,v 1.25 2019/08/07 11:47:33 rin Exp $ */ +/* $NetBSD: rasops4.c,v 1.26 2019/08/07 12:36:36 rin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rasops4.c,v 1.25 2019/08/07 11:47:33 rin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rasops4.c,v 1.26 2019/08/07 12:36:36 rin Exp $"); #include "opt_rasops.h" @@ -163,4 +163,7 @@ rasops4_makestamp(struct rasops_info *ri /* * Grab routines common to depths where (bpp < 8) */ +#undef RASOPS_AA +#include "rasops1-4_putchar.h" + #include <dev/rasops/rasops_bitops.h> Index: src/sys/dev/rasops/rasops_bitops.h diff -u src/sys/dev/rasops/rasops_bitops.h:1.23 src/sys/dev/rasops/rasops_bitops.h:1.24 --- src/sys/dev/rasops/rasops_bitops.h:1.23 Fri Aug 2 04:39:09 2019 +++ src/sys/dev/rasops/rasops_bitops.h Wed Aug 7 12:36:36 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rasops_bitops.h,v 1.23 2019/08/02 04:39:09 rin Exp $ */ +/* $NetBSD: rasops_bitops.h,v 1.24 2019/08/07 12:36:36 rin Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -32,10 +32,6 @@ #ifndef _RASOPS_BITOPS_H_ #define _RASOPS_BITOPS_H_ 1 -#define NAME(name) NAME1(RASOPS_DEPTH, name) -#define NAME1(depth, name) NAME2(depth, name) -#define NAME2(depth, name) rasops ## depth ## _ ## name - #if RASOPS_DEPTH == 1 #define PIXEL_SHIFT 0 #elif RASOPS_DEPTH == 2 @@ -46,218 +42,9 @@ #error "Depth not supported" #endif -#define PIXEL_BITS RASOPS_DEPTH -#define COLOR_MASK __BITS(32 - PIXEL_BITS, 31) - -#if RASOPS_DEPTH != 1 -/* - * Paint a single character. This function is also applicable to - * monochrome, but that in rasops1.c is much simpler and faster. - */ -static void -NAME(putchar)(void *cookie, int row, int col, u_int uc, long attr) -{ - struct rasops_info *ri = (struct rasops_info *)cookie; - struct wsdisplay_font *font = PICK_FONT(ri, uc); - int full, cnt, bit; - uint32_t fs, rs, fb, bg, fg, lmask, rmask, lbg, rbg, clr[2]; - uint32_t height, width; - uint32_t *rp, *bp, *hp, tmp; - uint8_t *fr; - bool space; - - hp = NULL; /* XXX GCC */ - -#ifdef RASOPS_CLIPPING - /* Catches 'row < 0' case too */ - if ((unsigned)row >= (unsigned)ri->ri_rows) - return; - - if ((unsigned)col >= (unsigned)ri->ri_cols) - return; -#endif - - width = font->fontwidth << PIXEL_SHIFT; - col *= width; - height = font->fontheight; - rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + - ((col >> 3) & ~3)); - if (ri->ri_hwbits) - hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + - ((col >> 3) & ~3)); - col &= 31; - rs = ri->ri_stride; - - bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; - fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; - - /* If fg and bg match this becomes a space character */ - if (uc == ' ' || __predict_false(fg == bg)) { - space = true; - fr = NULL; /* XXX GCC */ - fs = 0; /* XXX GCC */ - } else { - space = false; - fr = FONT_GLYPH(uc, font, ri); - fs = font->stride; - } - - if (col + width <= 32) { - /* Single word, only one mask */ - - rmask = rasops_pmask[col][width & 31]; - lmask = ~rmask; - - if (space) { - bg &= rmask; - while (height--) { - tmp = (*rp & lmask) | bg; - *rp = tmp; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - *hp = tmp; - DELTA(hp, rs, uint32_t *); - } - } - } else { - clr[0] = bg & COLOR_MASK; - clr[1] = fg & COLOR_MASK; - while (height--) { - fb = be32uatoh(fr); - fr += fs; - tmp = 0; - for (bit = col; bit < col + width; - bit += PIXEL_BITS) { - tmp |= clr[(fb >> 31) & 1] >> bit; - fb <<= 1; - } - tmp = (*rp & lmask) | MBE(tmp); - *rp = tmp; - DELTA(rp, rs, uint32_t *); - if (ri->ri_hwbits) { - *hp = tmp; - DELTA(hp, rs, uint32_t *); - } - } - } - - /* Do underline */ - if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), uint32_t *); - tmp = (*rp & lmask) | (fg & rmask); - *rp = tmp; - if (ri->ri_hwbits) { - DELTA(hp, -(ri->ri_stride << 1), uint32_t *); - *hp = tmp; - } - } - - return; - } - - /* Word boundary, two masks needed */ - - lmask = ~rasops_lmask[col]; - rmask = ~rasops_rmask[(col + width) & 31]; - - if (lmask != -1) - width -= 32 - col; - full = width / 32; - width -= full * 32; - - if (space) { - lbg = bg & ~lmask; - rbg = bg & ~rmask; - - while (height--) { - bp = rp; - - if (lmask != -1) { - *bp = (*bp & lmask) | lbg; - bp++; - } - - for (cnt = full; cnt; cnt--) - *bp++ = bg; - - if (rmask != -1) - *bp = (*bp & rmask) | rbg; - - if (ri->ri_hwbits) { - memcpy(hp, rp, ((lmask != -1) + full + - (rmask != -1)) << 2); - DELTA(hp, rs, uint32_t *); - } - DELTA(rp, rs, uint32_t *); - } - } else { - clr[0] = bg & COLOR_MASK; - clr[1] = fg & COLOR_MASK; - - while (height--) { - bp = rp; - - fb = be32uatoh(fr); - fr += fs; - - if (lmask != -1) { - tmp = 0; - for (bit = col; bit < 32; bit += PIXEL_BITS) { - tmp |= clr[(fb >> 31) & 1] >> bit; - fb <<= 1; - } - *bp = (*bp & lmask) | MBE(tmp); - bp++; - } - - for (cnt = full; cnt; cnt--) { - tmp = 0; - for (bit = 0; bit < 32; bit += PIXEL_BITS) { - tmp |= clr[(fb >> 31) & 1] >> bit; - fb <<= 1; - } - *bp++ = MBE(tmp); - } - - if (rmask != -1) { - tmp = 0; - for (bit = 0; bit < width; bit += PIXEL_BITS) { - tmp |= clr[(fb >> 31) & 1] >> bit; - fb <<= 1; - } - *bp = (*bp & rmask) | MBE(tmp); - } - - if (ri->ri_hwbits) { - memcpy(hp, rp, ((lmask != -1) + full + - (rmask != -1)) << 2); - DELTA(hp, rs, uint32_t *); - } - - DELTA(rp, rs, uint32_t *); - } - } - - /* Do underline */ - if ((attr & WSATTR_UNDERLINE) != 0) { - DELTA(rp, -(ri->ri_stride << 1), uint32_t *); - bp = rp; - if (lmask != -1) { - *bp = (*bp & lmask) | (fg & ~lmask); - bp++; - } - for (cnt = full; cnt; cnt--) - *bp++ = fg; - if (rmask != -1) - *bp = (*bp & rmask) | (fg & ~rmask); - if (ri->ri_hwbits) { - DELTA(hp, -(ri->ri_stride << 1), uint32_t *); - memcpy(hp, rp, ((lmask != -1) + full + - (rmask != -1)) << 2); - } - } -} -#endif /* RASOPS_DEPTH != 1 */ +#define NAME(name) NAME1(RASOPS_DEPTH, name) +#define NAME1(depth, name) NAME2(depth, name) +#define NAME2(depth, name) rasops ## depth ## _ ## name /* * Erase columns. @@ -607,7 +394,9 @@ NAME(copycols)(void *cookie, int row, in } #undef PIXEL_SHIFT -#undef PIXEL_BITS -#undef COLOR_MASK + +#undef NAME +#undef NAME1 +#undef NAME2 #endif /* _RASOPS_BITOPS_H_ */ Added files: Index: src/sys/dev/rasops/rasops1-4_putchar.h diff -u /dev/null src/sys/dev/rasops/rasops1-4_putchar.h:1.1 --- /dev/null Wed Aug 7 12:36:36 2019 +++ src/sys/dev/rasops/rasops1-4_putchar.h Wed Aug 7 12:36:36 2019 @@ -0,0 +1,308 @@ +/* $NetBSD: rasops1-4_putchar.h,v 1.1 2019/08/07 12:36:36 rin Exp $ */ + +/* NetBSD: rasops_bitops.h,v 1.23 2019/08/02 04:39:09 rin Exp */ +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Andrew Doran. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define PIXEL_BITS RASOPS_DEPTH + +#if RASOPS_DEPTH == 1 +#define PIXEL_SHIFT 0 +#elif RASOPS_DEPTH == 2 +#define PIXEL_SHIFT 1 +#elif RASOPS_DEPTH == 4 +#define PIXEL_SHIFT 2 +#else +#error "Depth not supported" +#endif + +#ifndef RASOPS_AA +#define COLOR_MASK __BITS(32 - PIXEL_BITS, 31) +#else +# if RASOPS_DEPTH == 2 +#define COLOR_MASK 0x3 +# else +#error "Anti-aliasing not supported" +# endif +#endif + +#ifndef RASOPS_AA +#define PIXEL_OR(tmp) \ + do { \ + (tmp) |= clr[(fb >> 31) & 1] >> bit; \ + fb <<= 1; \ + } while (0 /* CONSTCOND */) +#else +#define PIXEL_OR(tmp) \ + do { \ + uint8_t c, av = *fr++; \ + if (av == 0xff) \ + c = clr[1]; \ + else if (av == 0) \ + c = clr[0]; \ + else \ + c = (av * clr[1] + (0xff - av) * clr[0]) >> 8; \ + (tmp) |= c << (32 - PIXEL_BITS - bit); \ + } while (0 /* CONSTCOND */) +#endif + +#define NAME(depth) NAME1(depth) +#ifndef RASOPS_AA +#define NAME1(depth) rasops ## depth ## _ ## putchar +#else +#define NAME1(depth) rasops ## depth ## _ ## putchar_aa +#endif + +/* + * Paint a single character. This function is also applicable to + * monochrome, but that in rasops1.c is much simpler and faster. + */ +static void +NAME(RASOPS_DEPTH)(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = (struct rasops_info *)cookie; + struct wsdisplay_font *font = PICK_FONT(ri, uc); + int full, cnt, bit; + uint32_t rs, bg, fg, lmask, rmask, lbg, rbg, clr[2]; + uint32_t height, width; + uint32_t *rp, *bp, *hp, tmp; + uint8_t *fr; + bool space; + + hp = NULL; /* XXX GCC */ + +#ifdef RASOPS_CLIPPING + /* Catches 'row < 0' case too */ + if ((unsigned)row >= (unsigned)ri->ri_rows) + return; + + if ((unsigned)col >= (unsigned)ri->ri_cols) + return; +#endif + + width = font->fontwidth << PIXEL_SHIFT; + col *= width; + height = font->fontheight; + rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale + + ((col >> 3) & ~3)); + if (ri->ri_hwbits) + hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale + + ((col >> 3) & ~3)); + col &= 31; + rs = ri->ri_stride; + + bg = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf]; + fg = ri->ri_devcmap[((uint32_t)attr >> 24) & 0xf]; + + /* If fg and bg match this becomes a space character */ + if (uc == ' ' || __predict_false(fg == bg)) { + space = true; + fr = NULL; /* XXX GCC */ + } else { + space = false; + fr = FONT_GLYPH(uc, font, ri); + } + + if (col + width <= 32) { + /* Single word, only one mask */ + + rmask = rasops_pmask[col][width & 31]; + lmask = ~rmask; + + if (space) { + bg &= rmask; + while (height--) { + tmp = (*rp & lmask) | bg; + *rp = tmp; + DELTA(rp, rs, uint32_t *); + if (ri->ri_hwbits) { + *hp = tmp; + DELTA(hp, rs, uint32_t *); + } + } + } else { + clr[0] = bg & COLOR_MASK; + clr[1] = fg & COLOR_MASK; + while (height--) { +#ifndef RASOPS_AA + uint32_t fb = be32uatoh(fr); + fr += ri->ri_font->stride; +#endif + + tmp = 0; + for (bit = col; bit < col + width; + bit += PIXEL_BITS) + PIXEL_OR(tmp); + tmp = (*rp & lmask) | MBE(tmp); + *rp = tmp; + + if (ri->ri_hwbits) { + *hp = tmp; + DELTA(hp, rs, uint32_t *); + } + + DELTA(rp, rs, uint32_t *); + } + } + + /* Do underline */ + if ((attr & WSATTR_UNDERLINE) != 0) { + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, + uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + tmp = (*rp & lmask) | (fg & rmask); + *rp = tmp; + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + *hp = tmp; + } + } + } + + return; + } + + /* Word boundary, two masks needed */ + + lmask = ~rasops_lmask[col]; + rmask = ~rasops_rmask[(col + width) & 31]; + + if (lmask != -1) + width -= 32 - col; + full = width / 32; + width -= full * 32; + + if (space) { + lbg = bg & ~lmask; + rbg = bg & ~rmask; + + while (height--) { + bp = rp; + + if (lmask != -1) { + *bp = (*bp & lmask) | lbg; + bp++; + } + + for (cnt = full; cnt; cnt--) + *bp++ = bg; + + if (rmask != -1) + *bp = (*bp & rmask) | rbg; + + if (ri->ri_hwbits) { + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + DELTA(hp, rs, uint32_t *); + } + + DELTA(rp, rs, uint32_t *); + } + } else { + clr[0] = bg & COLOR_MASK; + clr[1] = fg & COLOR_MASK; + + while (height--) { + bp = rp; + +#ifndef RASOPS_AA + uint32_t fb = be32uatoh(fr); + fr += ri->ri_font->stride; +#endif + + if (lmask != -1) { + tmp = 0; + for (bit = col; bit < 32; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp = (*bp & lmask) | MBE(tmp); + bp++; + } + + for (cnt = full; cnt; cnt--) { + tmp = 0; + for (bit = 0; bit < 32; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp++ = MBE(tmp); + } + + if (rmask != -1) { + tmp = 0; + for (bit = 0; bit < width; bit += PIXEL_BITS) + PIXEL_OR(tmp); + *bp = (*bp & rmask) | MBE(tmp); + } + + if (ri->ri_hwbits) { + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + DELTA(hp, rs, uint32_t *); + } + + DELTA(rp, rs, uint32_t *); + } + } + + /* Do underline */ + if ((attr & WSATTR_UNDERLINE) != 0) { + DELTA(rp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + if (ri->ri_hwbits) + DELTA(hp, - ri->ri_stride * ri->ri_ul.off, uint32_t *); + + for (height = ri->ri_ul.height; height; height--) { + DELTA(rp, - ri->ri_stride, uint32_t *); + bp = rp; + if (lmask != -1) { + *bp = (*bp & lmask) | (fg & ~lmask); + bp++; + } + for (cnt = full; cnt; cnt--) + *bp++ = fg; + if (rmask != -1) + *bp = (*bp & rmask) | (fg & ~rmask); + if (ri->ri_hwbits) { + DELTA(hp, - ri->ri_stride, uint32_t *); + memcpy(hp, rp, ((lmask != -1) + full + + (rmask != -1)) << 2); + } + } + } +} + +#undef PIXEL_BITS +#undef PIXEL_SHIFT +#undef COLOR_MASK + +#undef PIXEL_OR + +#undef NAME +#undef NAME1