📄 raster_op.c
字号:
dstlin = dstlin1; while ( srclin != srclin2 ) { srclong = srclin; srcbit = sx & 31; dstlong = dstlin; dstbyte = dx & 3; i = w; /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */ ROP_SRCDSTCOLOR( /*op*/ op, /*pre*/ while ( i > 0 ) { dl = *dstlong;, /*s*/ *srclong & raster_bitmask[srcbit], /*d*/ dl, /*c*/ color, /*pst*/ *dstlong = ( *dstlong & ~bytemask[dstbyte] ) | ( dl & bytemask[dstbyte] ); if ( srcbit == 31 ) { srcbit = 0; ++srclong; } else ++srcbit; if ( dstbyte == 3 ) { dstbyte = 0; ++dstlong; } else ++dstbyte; --i; } ) srclin += src->linelongs; dstlin += dst->linelongs; } } } else { /* Eight to eight blit. */ u_long* srclin1; u_long* dstlin1; int srcleftignore, srcrightignore, srclongs; int dstleftignore, dstrightignore, dstlongs; if ( dst->depth != 8 ) return -1; /* depth mismatch */ srclin1 = RAS_ADDR( src, sx, sy ); dstlin1 = RAS_ADDR( dst, dx, dy );#ifdef BCOPY_FASTER /* Special-case full-width to full-width copies. */ if ( op == RAS_SRC && src->width == w && dst->width == w && src->linelongs == dst->linelongs && src->linelongs == w >> 2 ) { bcopy( (char*) srclin1, (char*) dstlin1, h * src->linelongs * sizeof(u_long) ); return 0; }#endif /*BCOPY_FASTER*/ srcleftignore = ( sx & 3 ) * 8; srclongs = ( srcleftignore + w * 8 + 31 ) >> 5; srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31; dstleftignore = ( dx & 3 ) * 8; dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; return raster_blit( src, srclin1, srcleftignore, srcrightignore, srclongs, dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ); } return 0; }/* Semi-public routine to do a no-src bitblit without clipping. Returns 0** on success, -1 on failure.*/intraster_op_nosrc_noclip( dst, dx, dy, w, h, rop ) struct raster* dst; int dx, dy, w, h, rop; { int op; op = RAS_GETOP( rop ); if ( dst->depth == 1 ) { /* One-bit no-src blit. */ u_long* dstlin1; u_long* dstlin2; u_long* dstlin; int dstleftignore, dstrightignore, dstlongs; u_long dl, lm, nlm, rm, nrm; register u_long* dstlong2; register u_long* dstlong; dstlin1 = RAS_ADDR( dst, dx, dy );#ifdef BCOPY_FASTER /* Special-case full-width clears. */ if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 ) { bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_long) ); return 0; }#endif /*BCOPY_FASTER*/ dstleftignore = ( dx & 31 ); dstlongs = ( dstleftignore + w + 31 ) >> 5; dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31; dstlin2 = dstlin1 + h * dst->linelongs; dstlin = dstlin1; if ( dstlongs == 1 ) { /* It fits into a single longword. */ lm = leftmask[dstleftignore] | rightmask[dstrightignore]; nlm = ~lm; while ( dstlin != dstlin2 ) { ROP_DST( /*op*/ op, /*pre*/ dl = *dstlin;, /*d*/ dl, /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) dstlin += dst->linelongs; } } else { lm = leftmask[dstleftignore]; rm = rightmask[dstrightignore]; nrm = ~rm; nlm = ~lm; while ( dstlin != dstlin2 ) { dstlong = dstlin; dstlong2 = dstlong + dstlongs; if ( dstrightignore != 0 ) --dstlong2; /* Leading edge. */ if ( dstleftignore != 0 ) { ROP_DST( /*op*/ op, /*pre*/ dl = *dstlong;, /*d*/ dl, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) ++dstlong; } /* Main rop. */ ROP_DST( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) {, /*d*/ *dstlong, /*pst*/ ++dstlong; } ) /* Trailing edge. */ if ( dstrightignore != 0 ) { ROP_DST( /*op*/ op, /*pre*/ dl = *dstlong;, /*d*/ dl, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) } dstlin += dst->linelongs; } } } else { /* Eight-bit no-src blit. */ register u_long color; u_long* dstlin1; u_long* dstlin2; u_long* dstlin; int dstleftignore, dstrightignore, dstlongs; u_long dl, lm, nlm, rm, nrm; register u_long* dstlong2; register u_long* dstlong; dstlin1 = RAS_ADDR( dst, dx, dy );#ifdef BCOPY_FASTER /* Special-case full-width clears. */ if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 ) { bzero( (char*) dstlin1, h * dst->linelongs * sizeof(u_long) ); return 0; }#endif /*BCOPY_FASTER*/ color = RAS_GETCOLOR( rop ); if ( color == 0 ) color = 255; /* Make 32 bits of color so we can do the ROP without shifting. */ color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 ); dstleftignore = ( dx & 3 ) * 8; dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5; dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31; dstlin2 = dstlin1 + h * dst->linelongs; dstlin = dstlin1; if ( dstlongs == 1 ) { /* It fits into a single longword. */ lm = leftmask[dstleftignore] | rightmask[dstrightignore]; nlm = ~lm; while ( dstlin != dstlin2 ) { ROP_DSTCOLOR( /*op*/ op, /*pre*/ dl = *dstlin;, /*d*/ dl, /*c*/ color, /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) dstlin += dst->linelongs; } } else { lm = leftmask[dstleftignore]; rm = rightmask[dstrightignore]; nrm = ~rm; nlm = ~lm; while ( dstlin != dstlin2 ) { dstlong = dstlin; dstlong2 = dstlong + dstlongs; if ( dstrightignore != 0 ) --dstlong2; /* Leading edge. */ if ( dstleftignore != 0 ) { ROP_DSTCOLOR( /*op*/ op, /*pre*/ dl = *dstlong;, /*d*/ dl, /*c*/ color, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) ++dstlong; } /* Main rop. */ ROP_DSTCOLOR( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) {, /*d*/ *dstlong, /*c*/ color, /*pst*/ ++dstlong; } ) /* Trailing edge. */ if ( dstrightignore != 0 ) { ROP_DSTCOLOR( /*op*/ op, /*pre*/ dl = *dstlong;, /*d*/ dl, /*c*/ color, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) } dstlin += dst->linelongs; } } } return 0; }/* This is a general bitblit routine, handling overlapping source and** destination. It's used for both the 1-to-1 and 8-to-8 cases.*/static intraster_blit( src, srclin1, srcleftignore, srcrightignore, srclongs, dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op ) struct raster* src; u_long* srclin1; int srcleftignore, srcrightignore, srclongs; struct raster* dst; u_long* dstlin1; int dstleftignore, dstrightignore, dstlongs; int h, op; { u_long* srclin2; u_long* dstlin2; int srclininc, dstlininc; u_long* srclin; u_long* dstlin; register int prevleftshift, currrightshift; int longinc; register u_long* srclong; register u_long* dstlong; register u_long* dstlong2; register u_long dl, lm, nlm, rm, nrm; prevleftshift = ( srcleftignore - dstleftignore ) & 31; srclin2 = srclin1 + h * src->linelongs; dstlin2 = dstlin1 + h * dst->linelongs; srclininc = src->linelongs; dstlininc = dst->linelongs; longinc = 1; /* Check for overlaps. */ if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) || ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) ) { /* Horizontal overlap. Should we reverse? */ if ( srclin1 < dstlin1 ) { longinc = -1; srclin1 += srclongs - 1; srclin2 += srclongs - 1; dstlin1 += dstlongs - 1; } } else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) || ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) ) { /* Vertical overlap. Should we reverse? */ if ( srclin1 < dstlin1 ) { srclin2 = srclin1 - srclininc; srclin1 += ( h - 1 ) * srclininc; dstlin1 += ( h - 1 ) * dstlininc; srclininc = -srclininc; dstlininc = -dstlininc; } } srclin = srclin1; dstlin = dstlin1; if ( prevleftshift == 0 ) { /* The bits line up, no shifting necessary. */ if ( dstlongs == 1 ) { /* It all fits into a single longword. */ lm = leftmask[dstleftignore] | rightmask[dstrightignore]; nlm = ~lm; while ( srclin != srclin2 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlin;, /*s*/ *srclin, /*d*/ dl, /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) srclin += srclininc; dstlin += dstlininc; } } else { /* Multiple longwords. */ lm = leftmask[dstleftignore]; rm = rightmask[dstrightignore]; nrm = ~rm; nlm = ~lm; if ( longinc == 1 ) { /* Left to right. */ while ( srclin != srclin2 ) { srclong = srclin; dstlong = dstlin; dstlong2 = dstlong + dstlongs; if ( dstrightignore != 0 ) --dstlong2; /* Leading edge. */ if ( dstleftignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ *srclong, /*d*/ dl, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) ++srclong; ++dstlong; } /* Main rop. */ ROP_SRCDST( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) {, /*s*/ *srclong, /*d*/ *dstlong, /*pst*/ ++srclong; ++dstlong; } ) /* Trailing edge. */ if ( dstrightignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ *srclong, /*d*/ dl, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) } srclin += srclininc; dstlin += dstlininc; } } else { /* Right to left. */ while ( srclin != srclin2 ) { srclong = srclin; dstlong = dstlin; dstlong2 = dstlong - dstlongs; if ( dstleftignore != 0 ) ++dstlong2; /* Leading edge. */ if ( dstrightignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ *srclong, /*d*/ dl, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) --srclong; --dstlong; } /* Main rop. */ ROP_SRCDST( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) {, /*s*/ *srclong, /*d*/ *dstlong, /*pst*/ --srclong; --dstlong; } ) /* Trailing edge. */ if ( dstleftignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ *srclong, /*d*/ dl, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) } srclin += srclininc; dstlin += dstlininc; } } } } else { /* General case, with shifting and everything. */ register u_long sl, prevsl; currrightshift = 32 - prevleftshift; if ( srclongs == 1 && dstlongs == 1 ) { /* It fits into a single longword, with a shift. */ lm = leftmask[dstleftignore] | rightmask[dstrightignore]; nlm = ~lm; if ( srcleftignore > dstleftignore ) { while ( srclin != srclin2 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlin;, /*s*/ *srclin << prevleftshift, /*d*/ dl, /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) srclin += srclininc; dstlin += dstlininc; } } else { while ( srclin != srclin2 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlin;, /*s*/ *srclin >> currrightshift, /*d*/ dl, /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); ) srclin += srclininc; dstlin += dstlininc; } } } else { /* Multiple longwords. */ lm = leftmask[dstleftignore]; rm = rightmask[dstrightignore]; nrm = ~rm; nlm = ~lm; if ( longinc == 1 ) { /* Left to right. */ while ( srclin != srclin2 ) { srclong = srclin; dstlong = dstlin; dstlong2 = dstlong + dstlongs; if ( srcleftignore > dstleftignore ) prevsl = *srclong++ << prevleftshift; else prevsl = 0; if ( dstrightignore != 0 ) --dstlong2; /* Leading edge. */ if ( dstleftignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ sl = *srclong; dl = *dstlong;, /*s*/ prevsl | ( sl >> currrightshift ), /*d*/ dl, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) prevsl = sl << prevleftshift; ++srclong; ++dstlong; } /* Main rop. */ ROP_SRCDST( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) { sl = *srclong;, /*s*/ prevsl | ( sl >> currrightshift ), /*d*/ *dstlong, /*pst*/ prevsl = sl << prevleftshift; ++srclong; ++dstlong; } ) /* Trailing edge. */ if ( dstrightignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ prevsl | ( *srclong >> currrightshift ), /*d*/ dl, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) } srclin += srclininc; dstlin += dstlininc; } } else { /* Right to left. */ while ( srclin != srclin2 ) { srclong = srclin; dstlong = dstlin; dstlong2 = dstlong - dstlongs; if ( srcrightignore > dstrightignore ) prevsl = *srclong-- >> currrightshift; else prevsl = 0; if ( dstleftignore != 0 ) ++dstlong2; /* Leading edge. */ if ( dstrightignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ sl = *srclong; dl = *dstlong;, /*s*/ prevsl | ( sl << prevleftshift ), /*d*/ dl, /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); ) prevsl = sl >> currrightshift; --srclong; --dstlong; } /* Main rop. */ ROP_SRCDST( /*op*/ op, /*pre*/ while ( dstlong != dstlong2 ) { sl = *srclong;, /*s*/ prevsl | ( sl << prevleftshift ), /*d*/ *dstlong, /*pst*/ prevsl = sl >> currrightshift; --srclong; --dstlong; } ) /* Trailing edge. */ if ( dstleftignore != 0 ) { ROP_SRCDST( /*op*/ op, /*pre*/ dl = *dstlong;, /*s*/ prevsl | ( *srclong << prevleftshift ), /*d*/ dl, /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); ) } srclin += srclininc; dstlin += dstlininc; } } } } return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -