Home | History | Annotate | Line # | Download | only in rasops
rasops_bitops.h revision 1.19
      1 /* 	$NetBSD: rasops_bitops.h,v 1.19 2019/08/01 03:43:54 rin 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  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef _RASOPS_BITOPS_H_
     33 #define _RASOPS_BITOPS_H_ 1
     34 
     35 /*
     36  * Erase columns.
     37  */
     38 static void
     39 NAME(erasecols)(void *cookie, int row, int col, int num, long attr)
     40 {
     41 	struct rasops_info *ri = (struct rasops_info *)cookie;
     42 	uint32_t lclr, rclr, clr;
     43 	uint32_t *dp, *rp, *hp, tmp, lmask, rmask;
     44 	int height, cnt;
     45 
     46 	hp = NULL;	/* XXX GCC */
     47 
     48 
     49 #ifdef RASOPS_CLIPPING
     50 	if ((unsigned)row >= (unsigned)ri->ri_rows)
     51 		return;
     52 
     53 	if (col < 0) {
     54 		num += col;
     55 		col = 0;
     56 	}
     57 
     58 	if (col + num > ri->ri_cols)
     59 		num = ri->ri_cols - col;
     60 
     61 	if (num <= 0)
     62 		return;
     63 #endif
     64 	col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
     65 	num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
     66 	height = ri->ri_font->fontheight;
     67 	clr = ri->ri_devcmap[((uint32_t)attr >> 16) & 0xf];
     68 	rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
     69 	if (ri->ri_hwbits)
     70 		hp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
     71 		    ((col >> 3) & ~3));
     72 	col &= 31;
     73 
     74 	if (col + num <= 32) {
     75 		lmask = ~rasops_pmask[col][num & 31];
     76 		lclr = clr & ~lmask;
     77 
     78 		while (height--) {
     79 			dp = rp;
     80 			DELTA(rp, ri->ri_stride, uint32_t *);
     81 
     82 			tmp = (*dp & lmask) | lclr;
     83 			*dp = tmp;
     84 			if (ri->ri_hwbits) {
     85 				*hp = tmp;
     86 				DELTA(hp, ri->ri_stride, uint32_t *);
     87 			}
     88 		}
     89 	} else {
     90 		lmask = rasops_rmask[col];
     91 		rmask = rasops_lmask[(col + num) & 31];
     92 
     93 		if (lmask)
     94 			num = (num - (32 - col)) >> 5;
     95 		else
     96 			num = num >> 5;
     97 
     98 		lclr = clr & ~lmask;
     99 		rclr = clr & ~rmask;
    100 
    101 		while (height--) {
    102 			dp = rp;
    103 
    104 			if (lmask) {
    105 				*dp = (*dp & lmask) | lclr;
    106 				dp++;
    107 			}
    108 
    109 			for (cnt = num; cnt > 0; cnt--)
    110 				*dp++ = clr;
    111 
    112 			if (rmask)
    113 				*dp = (*dp & rmask) | rclr;
    114 
    115 			if (ri->ri_hwbits) {
    116 				memcpy(hp, rp, ((lmask != 0) + num +
    117 				    (rmask != 0)) << 2);
    118 				DELTA(hp, ri->ri_stride, uint32_t *);
    119 			}
    120 			DELTA(rp, ri->ri_stride, uint32_t *);
    121 		}
    122 	}
    123 }
    124 
    125 /*
    126  * Actually paint the cursor.
    127  */
    128 static void
    129 NAME(do_cursor)(struct rasops_info *ri)
    130 {
    131 	int height, row, col, num, cnt;
    132 	uint32_t *dp, *rp, *hp, tmp, lmask, rmask;
    133 
    134 	hp = NULL;	/* XXX GCC */
    135 
    136 	row = ri->ri_crow;
    137 	col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
    138 	height = ri->ri_font->fontheight;
    139 	num = ri->ri_font->fontwidth << PIXEL_SHIFT;
    140 	rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale +
    141 	    ((col >> 3) & ~3));
    142 	if (ri->ri_hwbits)
    143 		hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale +
    144 		    ((col >> 3) & ~3));
    145 	col &= 31;
    146 
    147 	if (col + num <= 32) {
    148 		lmask = rasops_pmask[col][num & 31];
    149 
    150 		while (height--) {
    151 			tmp = *rp ^ lmask;
    152 			*rp = tmp;
    153 			if (ri->ri_hwbits) {
    154 				*hp = tmp;
    155 				DELTA(hp, ri->ri_stride, uint32_t *);
    156 			}
    157 			DELTA(rp, ri->ri_stride, uint32_t *);
    158 		}
    159 	} else {
    160 		lmask = ~rasops_rmask[col];
    161 		rmask = ~rasops_lmask[(col + num) & 31];
    162 
    163 		if (lmask != -1)
    164 			num = (num - (32 - col)) >> 5;
    165 		else
    166 			num = num >> 5;
    167 
    168 		while (height--) {
    169 			dp = rp;
    170 
    171 			if (lmask != -1) {
    172 				*dp = *dp ^ lmask;
    173 				dp++;
    174 			}
    175 
    176 			for (cnt = num; cnt; cnt--) {
    177 				*dp = ~*dp;
    178 				dp++;
    179 			}
    180 
    181 			if (rmask != -1)
    182 				*dp = *dp ^ rmask;
    183 
    184 			if (ri->ri_hwbits) {
    185 				memcpy(hp, rp, ((lmask != -1) + num +
    186 				    (rmask != -1)) << 2);
    187 				DELTA(hp, ri->ri_stride, uint32_t *);
    188 			}
    189 			DELTA(rp, ri->ri_stride, uint32_t *);
    190 		}
    191 	}
    192 }
    193 
    194 /*
    195  * Copy columns. Ick!
    196  */
    197 static void
    198 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
    199 {
    200 	struct rasops_info *ri = (struct rasops_info *)cookie;
    201 	int height, lnum, rnum, sb, db, cnt, full;
    202 	uint32_t tmp, lmask, rmask;
    203 	uint32_t *sp, *dp, *srp, *drp, *dhp, *hp;
    204 
    205 	dhp = hp = NULL;	/* XXX GCC */
    206 
    207 #ifdef RASOPS_CLIPPING
    208 	if (dst == src)
    209 		return;
    210 
    211 	/* Catches < 0 case too */
    212 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    213 		return;
    214 
    215 	if (src < 0) {
    216 		num += src;
    217 		src = 0;
    218 	}
    219 
    220 	if (src + num > ri->ri_cols)
    221 		num = ri->ri_cols - src;
    222 
    223 	if (dst < 0) {
    224 		num += dst;
    225 		dst = 0;
    226 	}
    227 
    228 	if (dst + num > ri->ri_cols)
    229 		num = ri->ri_cols - dst;
    230 
    231 	if (num <= 0)
    232 		return;
    233 #endif
    234 
    235 	cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
    236 	src *= cnt;
    237 	dst *= cnt;
    238 	num *= cnt;
    239 	row *= ri->ri_yscale;
    240 	height = ri->ri_font->fontheight;
    241 	db = dst & 31;
    242 
    243 	if (db + num <= 32) {
    244 		/* Destination is contained within a single word */
    245 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    246 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    247 		if (ri->ri_hwbits)
    248 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    249 			    ((dst >> 3) & ~3));
    250 		sb = src & 31;
    251 
    252 		while (height--) {
    253 			GETBITS(srp, sb, num, tmp);
    254 			PUTBITS(tmp, db, num, drp);
    255 			if (ri->ri_hwbits) {
    256 				PUTBITS(tmp, db, num, dhp);
    257 				DELTA(dhp, ri->ri_stride, uint32_t *);
    258 			}
    259 			DELTA(srp, ri->ri_stride, uint32_t *);
    260 			DELTA(drp, ri->ri_stride, uint32_t *);
    261 		}
    262 
    263 		return;
    264 	}
    265 
    266 	lmask = rasops_rmask[db];
    267 	rmask = rasops_lmask[(dst + num) & 31];
    268 	lnum = (32 - db) & 31;
    269 	rnum = (dst + num) & 31;
    270 
    271 	if (lmask)
    272 		full = (num - (32 - (dst & 31))) >> 5;
    273 	else
    274 		full = num >> 5;
    275 
    276 	if (src < dst && src + num > dst) {
    277 		/* Copy right-to-left */
    278 		bool sbover;
    279 		int sboff;
    280 
    281 		srp = (uint32_t *)(ri->ri_bits + row +
    282 		    (((src + num) >> 3) & ~3));
    283 		drp = (uint32_t *)(ri->ri_bits + row +
    284 		    (((dst + num) >> 3) & ~3));
    285 		if (ri->ri_hwbits)
    286 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    287 			    (((dst + num) >> 3) & ~3));
    288 
    289 		sb = src & 31;
    290 		sbover = (sb + lnum) >= 32;
    291 		sboff = (src + num) & 31;
    292 		if ((sboff -= rnum) < 0) {
    293 			srp--;
    294 			sboff += 32;
    295 		}
    296 
    297 		while (height--) {
    298 			sp = srp;
    299 			dp = drp;
    300 			DELTA(srp, ri->ri_stride, uint32_t *);
    301 			DELTA(drp, ri->ri_stride, uint32_t *);
    302 
    303 			if (rnum) {
    304 				GETBITS(sp, sboff, rnum, tmp);
    305 				PUTBITS(tmp, 0, rnum, dp);
    306 			}
    307 
    308 			/* Now aligned to 32-bits wrt dp */
    309 			for (cnt = full; cnt; cnt--) {
    310 				--dp;
    311 				--sp;
    312 				GETBITS(sp, sboff, 32, tmp);
    313 				*dp = tmp;
    314 			}
    315 
    316 			if (lmask) {
    317 				if (sbover)
    318 					--sp;
    319 				--dp;
    320 				GETBITS(sp, sb, lnum, tmp);
    321 				PUTBITS(tmp, db, lnum, dp);
    322  			}
    323 
    324 			if (ri->ri_hwbits) {
    325 				hp = dhp;
    326 				hp -= full + (lmask != 0);
    327 				memcpy(hp, dp, ((rmask != 0) + cnt +
    328 				    (lmask != 0)) << 2);
    329 				DELTA(dhp, ri->ri_stride, uint32_t *);
    330 			}
    331  		}
    332 	} else {
    333 		/* Copy left-to-right */
    334 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    335 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    336 		if (ri->ri_hwbits)
    337 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    338 			    ((dst >> 3) & ~3));
    339 		db = dst & 31;
    340 
    341 		while (height--) {
    342 			sb = src & 31;
    343 			sp = srp;
    344 			dp = drp;
    345 
    346 			if (lmask) {
    347 				GETBITS(sp, sb, lnum, tmp);
    348 				PUTBITS(tmp, db, lnum, dp);
    349 				dp++;
    350 
    351 				if (sb += lnum > 31) {
    352 					sp++;
    353 					sb -= 32;
    354 				}
    355 			}
    356 
    357 			/* Now aligned to 32-bits wrt dp */
    358 			for (cnt = full; cnt; cnt--, sp++) {
    359 				GETBITS(sp, sb, 32, tmp);
    360 				*dp++ = tmp;
    361 			}
    362 
    363 			if (rmask) {
    364 				GETBITS(sp, sb, rnum, tmp);
    365 				PUTBITS(tmp, 0, rnum, dp);
    366  			}
    367 
    368 			if (ri->ri_hwbits) {
    369 				memcpy(dhp, drp, ((lmask != 0) + full +
    370 				    (rmask != 0)) << 2);
    371 				DELTA(dhp, ri->ri_stride, uint32_t *);
    372 			}
    373 
    374 			DELTA(srp, ri->ri_stride, uint32_t *);
    375 			DELTA(drp, ri->ri_stride, uint32_t *);
    376  		}
    377  	}
    378 }
    379 
    380 #endif /* _RASOPS_BITOPS_H_ */
    381