Home | History | Annotate | Line # | Download | only in rasops
rasops_bitops.h revision 1.21
      1 /* 	$NetBSD: rasops_bitops.h,v 1.21 2019/08/02 04:31: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 #ifdef RASOPS_CLIPPING
     49 	if ((unsigned)row >= (unsigned)ri->ri_rows)
     50 		return;
     51 
     52 	if (col < 0) {
     53 		num += col;
     54 		col = 0;
     55 	}
     56 
     57 	if (col + num > ri->ri_cols)
     58 		num = ri->ri_cols - col;
     59 
     60 	if (num <= 0)
     61 		return;
     62 #endif
     63 
     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 
    190 			DELTA(rp, ri->ri_stride, uint32_t *);
    191 		}
    192 	}
    193 }
    194 
    195 /*
    196  * Copy columns. Ick!
    197  */
    198 static void
    199 NAME(copycols)(void *cookie, int row, int src, int dst, int num)
    200 {
    201 	struct rasops_info *ri = (struct rasops_info *)cookie;
    202 	int height, lnum, rnum, sb, db, cnt, full;
    203 	uint32_t tmp, lmask, rmask;
    204 	uint32_t *sp, *dp, *srp, *drp, *dhp, *hp;
    205 
    206 	dhp = hp = NULL;	/* XXX GCC */
    207 
    208 #ifdef RASOPS_CLIPPING
    209 	if (dst == src)
    210 		return;
    211 
    212 	/* Catches < 0 case too */
    213 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    214 		return;
    215 
    216 	if (src < 0) {
    217 		num += src;
    218 		src = 0;
    219 	}
    220 
    221 	if (src + num > ri->ri_cols)
    222 		num = ri->ri_cols - src;
    223 
    224 	if (dst < 0) {
    225 		num += dst;
    226 		dst = 0;
    227 	}
    228 
    229 	if (dst + num > ri->ri_cols)
    230 		num = ri->ri_cols - dst;
    231 
    232 	if (num <= 0)
    233 		return;
    234 #endif
    235 
    236 	cnt = ri->ri_font->fontwidth << PIXEL_SHIFT;
    237 	src *= cnt;
    238 	dst *= cnt;
    239 	num *= cnt;
    240 	row *= ri->ri_yscale;
    241 	height = ri->ri_font->fontheight;
    242 	db = dst & 31;
    243 
    244 	if (db + num <= 32) {
    245 		/* Destination is contained within a single word */
    246 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    247 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    248 		if (ri->ri_hwbits)
    249 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    250 			    ((dst >> 3) & ~3));
    251 		sb = src & 31;
    252 
    253 		while (height--) {
    254 			GETBITS(srp, sb, num, tmp);
    255 			PUTBITS(tmp, db, num, drp);
    256 			if (ri->ri_hwbits) {
    257 				PUTBITS(tmp, db, num, dhp);
    258 				DELTA(dhp, ri->ri_stride, uint32_t *);
    259 			}
    260 			DELTA(srp, ri->ri_stride, uint32_t *);
    261 			DELTA(drp, ri->ri_stride, uint32_t *);
    262 		}
    263 
    264 		return;
    265 	}
    266 
    267 	lmask = rasops_rmask[db];
    268 	rmask = rasops_lmask[(dst + num) & 31];
    269 	lnum = (32 - db) & 31;
    270 	rnum = (dst + num) & 31;
    271 
    272 	if (lmask)
    273 		full = (num - lnum) >> 5;
    274 	else
    275 		full = num >> 5;
    276 
    277 	if (src < dst && src + num > dst) {
    278 		/* Copy right-to-left */
    279 		bool sbover;
    280 		int sboff;
    281 
    282 		srp = (uint32_t *)(ri->ri_bits + row +
    283 		    (((src + num) >> 3) & ~3));
    284 		drp = (uint32_t *)(ri->ri_bits + row +
    285 		    (((dst + num) >> 3) & ~3));
    286 		if (ri->ri_hwbits)
    287 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    288 			    (((dst + num) >> 3) & ~3));
    289 
    290 		sb = src & 31;
    291 		sbover = (sb + lnum) >= 32;
    292 		sboff = (src + num) & 31;
    293 		if ((sboff -= rnum) < 0) {
    294 			srp--;
    295 			sboff += 32;
    296 		}
    297 
    298 		while (height--) {
    299 			sp = srp;
    300 			dp = drp;
    301 			DELTA(srp, ri->ri_stride, uint32_t *);
    302 			DELTA(drp, ri->ri_stride, uint32_t *);
    303 
    304 			if (rnum) {
    305 				GETBITS(sp, sboff, rnum, tmp);
    306 				PUTBITS(tmp, 0, rnum, dp);
    307 			}
    308 
    309 			/* Now aligned to 32-bits wrt dp */
    310 			for (cnt = full; cnt; cnt--) {
    311 				--dp;
    312 				--sp;
    313 				GETBITS(sp, sboff, 32, tmp);
    314 				*dp = tmp;
    315 			}
    316 
    317 			if (lmask) {
    318 				if (sbover)
    319 					--sp;
    320 				--dp;
    321 				GETBITS(sp, sb, lnum, tmp);
    322 				PUTBITS(tmp, db, lnum, dp);
    323  			}
    324 
    325 			if (ri->ri_hwbits) {
    326 				hp = dhp;
    327 				hp -= full + (lmask != 0);
    328 				memcpy(hp, dp, ((rmask != 0) + cnt +
    329 				    (lmask != 0)) << 2);
    330 				DELTA(dhp, ri->ri_stride, uint32_t *);
    331 			}
    332  		}
    333 	} else {
    334 		/* Copy left-to-right */
    335 		srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
    336 		drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
    337 		if (ri->ri_hwbits)
    338 			dhp = (uint32_t *)(ri->ri_hwbits + row +
    339 			    ((dst >> 3) & ~3));
    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 				sb += lnum;
    352 				if (sb > 31) {
    353 					sp++;
    354 					sb -= 32;
    355 				}
    356 			}
    357 
    358 			/* Now aligned to 32-bits wrt dp */
    359 			for (cnt = full; cnt; cnt--, sp++) {
    360 				GETBITS(sp, sb, 32, tmp);
    361 				*dp++ = tmp;
    362 			}
    363 
    364 			if (rmask) {
    365 				GETBITS(sp, sb, rnum, tmp);
    366 				PUTBITS(tmp, 0, rnum, dp);
    367  			}
    368 
    369 			if (ri->ri_hwbits) {
    370 				memcpy(dhp, drp, ((lmask != 0) + full +
    371 				    (rmask != 0)) << 2);
    372 				DELTA(dhp, ri->ri_stride, uint32_t *);
    373 			}
    374 
    375 			DELTA(srp, ri->ri_stride, uint32_t *);
    376 			DELTA(drp, ri->ri_stride, uint32_t *);
    377  		}
    378  	}
    379 }
    380 
    381 #endif /* _RASOPS_BITOPS_H_ */
    382