Files
TempleOS-Rijn/LT/Adam/Gr/GrBitMap.APZ
T
2018-09-08 21:45:20 +02:00

1465 lines
33 KiB
Plaintext

#help_index "Graphics/Bitmaps"
public void GrReset(GrBitMap *base)
{
base->color=BLACK;
base->color2=BLACK;
base->bkcolor=BLACK;
base->pen_width=1;
}
public GrBitMap *GrAlias(GrBitMap *base,TssStruct *tss)
{
GrBitMap *result=MAlloc(sizeof(GrBitMap),tss);
if (base->bitmap_signature!=BMS_SIGNATURE)
Debugger;
MemCpy(result,base,sizeof(GrBitMap));
result->win_tss=tss;
result->mem_tss=tss;
result->r=MAlloc(16<<3,tss);
GrSetIdent(result->r);
GrReset(result);
result->flags|=BMF_ALIAS;
return result;
}
public void GrDel(GrBitMap *base)
{
if (base->bitmap_signature!=BMS_SIGNATURE)
Debugger;
base->bitmap_signature=0;
Free(base->r,base->mem_tss);
if (!(base->flags & BMF_ALIAS))
Free(base->body,base->mem_tss);
Free(base,base->mem_tss);
}
#help_index "Graphics"
public void GrPlot0(GrBitMap *base,I8 x,I8 y)
{ //No clipping or transformation or pen width
U8 d,c,c2;
U1 *dst,bit,not_bit;
U8 color=base->color,bkcolor=base->bkcolor;
double dist;
if (base->flags & BMF_LOCATE_NEAREST) {
dist=DistI8(x,y,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
if (base->flags & BMF_DONT_DRAW)
return;
switch (base->type) {
case BMT_COLOR4:
d=base->plane_size;
dst=base->body+(base->left_margin+x+
(y+base->top_margin)*base->internal_width)>>3;
bit=1<<(x&7);
not_bit=~bit;
c=color.u1[0];
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
if (c & 1)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 2)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 4)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 8)
*dst|=bit;
else
*dst&=not_bit;
break;
case ROPB_COLLISION:
c2=0;
if (*dst&bit)
c2+=1;
dst+=d;
if (*dst&bit)
c2+=2;
dst+=d;
if (*dst&bit)
c2+=4;
dst+=d;
if (*dst&bit)
c2+=8;
if (c2!=bkcolor.u1[0])
base->collision_cnt++;
break;
case ROPB_XOR:
if (c & 1) *dst^=bit;
dst+=d;
if (c & 2) *dst^=bit;
dst+=d;
if (c & 4) *dst^=bit;
dst+=d;
if (c & 8) *dst^=bit;
break;
case ROPB_OR:
if (c & 1) *dst|=bit;
dst+=d;
if (c & 2) *dst|=bit;
dst+=d;
if (c & 4) *dst|=bit;
dst+=d;
if (c & 8) *dst|=bit;
break;
case ROPB_NAND:
if (c & 1) *dst&=not_bit;
dst+=d;
if (c & 2) *dst&=not_bit;
dst+=d;
if (c & 4) *dst&=not_bit;
dst+=d;
if (c & 8) *dst&=not_bit;
break;
}
break;
case BMT_MONO:
d=base->internal_width*(y+base->top_margin)+
x+base->left_margin;
c=color&0xFFFFFF;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
AssignBit(base->body,d,c);
break;
case ROPB_COLLISION:
if (c) {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=Bt(base->body,d);
else
base->collision_cnt+=!Bt(base->body,d);
} else {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=!Bt(base->body,d);
else
base->collision_cnt+=Bt(base->body,d);
}
break;
case ROPB_XOR:
if (c)
Btc(base->body,d);
break;
case ROPB_OR:
if (c)
Bts(base->body,d);
break;
case ROPB_NAND:
if (c)
Btr(base->body,d);
break;
}
break;
}
}
public I8 GrPeek0(GrBitMap *base,I8 x,I8 y)
{ //No clipping or transformation
U8 d,c;
U1 *dst,bit;
switch (base->type) {
case BMT_COLOR4:
d=base->plane_size;
dst=base->body+(base->left_margin+x+
(y+base->top_margin)*base->internal_width)>>3;
bit=1<<(x&7);
c=0;
if (*dst & bit)
c|=1;
dst+=d;
if (*dst & bit)
c|=2;
dst+=d;
if (*dst & bit)
c|=4;
dst+=d;
if (*dst & bit)
c|=8;
return c;
case BMT_MONO:
d=base->internal_width*(y+base->top_margin)+
x+base->left_margin;
return Bt(base->body,d);
}
}
#help_index "Graphics;Graphics/Bitmaps"
public BoolU4 GrBlot(GrBitMap *base,I8 x,I8 y,GrBitMap *img)
{ //Clipping but not transformation
I8 reg i,i1,i2,i3,j,k,k1,kk,kk1,w1,h1,w2,h2,plane,plane1,reg bit_mask,reg bit_shift,p,dist;
U1 reg *ptr;
U2 reg *ptr1;
I8 color,color2,reg color_byte,c,plane_size,plane_size1,plane_limit,plane_limit1;
BoolU4 draw=TRUE,color_bit;
w1= (x<0)?-x:0;
h1= (y<0)?-y:0;
w2=img->width;
h2=img->height;
if (base->flags & BMF_SCREEN_BITMAP) {
x+=base->win_tss->win_pixel_left;
y+=base->win_tss->win_pixel_top;
}
if (base->flags & BMF_LOCATE_NEAREST) { //TODO:Untested
dist=DistI8(x+img->width>>1,y+img->height>>1,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
if (base->flags & BMF_SCREEN_BITMAP) {
if (x+w1<0) w1=-x;
if (x+w2>base->win_tss->win_pixel_right)
w2=base->win_tss->win_pixel_right-x;
if (y+h1<0) h1=-y;
if (y+h2>base->win_tss->win_pixel_bottom)
h2=base->win_tss->win_pixel_bottom-y;
if (IsPixelCovered(base->win_tss,x+w1,y+h1))
draw=FALSE;
else if (IsPixelCovered(base->win_tss,x+w2,y+h2))
draw=FALSE;
x+=base->left_margin;
y+=base->top_margin;
}
if (x+w2>base->width)
w2=base->width-x;
if (y+h2>base->height)
h2=base->height-y;
if (draw && w1<w2 && h1<h2 && w2<=img->width && h2<=img->height) {
if (base->flags & BMF_DONT_DRAW)
return TRUE;
color=base->color;
p=0;
plane_size=img->plane_size<<3;
plane_size1=base->plane_size<<3;
switch (base->type) {
case BMT_COLOR4:
plane_limit=plane_size*4;
plane_limit1=plane_size1*4;
break;
case BMT_MONO:
plane_limit=plane_size;
plane_limit1=plane_size1;
break;
}
i1=(-w1)&7;
if (i1>w2) i1=w2;
i2=(w2-w1-i1)>>3;
i3=w2-w1-i2<<3-i1;
bit_shift=x&7;
bit_mask=-1-255<<bit_shift;
if (color.u1[3]==ROPB_COLLISION) {
color =base->bkcolor&0xFFFFFF;
color2=img->bkcolor &0xFFFFFF;
switch (img->type) {
case BMT_COLOR4:
k=h1*img->internal_width;
k1=(h1+y)*base->internal_width+x;
for (j=h1;j<h2;j++) {
for (i=w1;i<w2;i++) {
c=0;
for (plane1=0,p=1;plane1<plane_limit1;
plane1+=plane_size1,p<<=1)
if (Bt(base->body,k1+i+plane1))
c+=p;
if (c!=color) {
c=0;
for (plane=0,p=1;plane<plane_limit;
plane+=plane_size,p<<=1)
if (Bt(img->body,k+i+plane))
c+=p;
if (c!=color2)
base->collision_cnt++;
}
}
k+=img->internal_width;
k1+=base->internal_width;
}
break;
case BMT_MONO:
k=h1*img->internal_width;
k1=(h1+y)*base->internal_width+x;
for (j=h1;j<h2;j++) {
for (i=w1;i<w2;i++) {
c=0;
for (plane1=0,p=1;plane1<plane_limit1;
plane1+=plane_size1,p<<=1)
if (Bt(base->body,k1+i+plane1))
c+=p;
if (c!=color) {
if (Bt(img->body,k+i)!=color2)
base->collision_cnt++;
}
}
k+=img->internal_width;
k1+=base->internal_width;
}
break;
}
} else if (color.u1[3]==ROPB_TRANSPARENT && img->type==BMT_COLOR4) {
color2=img->bkcolor &0xFFFFFF;
k=h1*img->internal_width;
for (j=h1;j<h2;j++) {
for (i=w1;i<w2;i++) {
c=0;
for (plane=0,p=1;plane<plane_limit;
plane+=plane_size,p<<=1)
if (Bt(img->body,k+i+plane))
c+=p;
if (c!=color2) {
base->color=c;
GrPlot0(base,x+i-base->left_margin,y+j-base->top_margin);
}
}
k+=img->internal_width;
}
base->color=color;
} else
for (plane=0,plane1=0;plane<plane_limit;
plane+=plane_size,plane1+=plane_size1) {
if (color_bit=Bt(&color,p++))
color_byte=255;
else
color_byte=0;
kk=h1*img->internal_width+w1;
kk1=(h1+y)*base->internal_width+x+w1;
for (j=h1;j<h2;j++) {
switch (img->type) {
case BMT_COLOR4:
k=kk+plane;
k1=kk1+plane1;
ptr=img->body;
ptr1=base->body;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i1;i++)
AssignBit(ptr1,k1++,Bt(ptr,k++));
break;
case ROPB_XOR:
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Btc(ptr1,k1++);
break;
case ROPB_OR:
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Bts(ptr1,k1++);
break;
case ROPB_NAND:
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Btr(ptr1,k1++);
break;
}
ptr+=k>>3;
ptr1+=k1>>3;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i2;i++) {
*ptr1=*ptr1 & bit_mask | (*ptr++<<bit_shift);
ptr1++;
}
break;
case ROPB_XOR:
for (i=0;i<i2;i++) {
*ptr1^=*ptr++<<bit_shift;
ptr1++;
}
break;
case ROPB_OR:
for (i=0;i<i2;i++) {
*ptr1|=*ptr++<<bit_shift;
ptr1++;
}
break;
case ROPB_NAND:
for (i=0;i<i2;i++) {
*ptr1= *ptr1 & (bit_mask | ~(*ptr++<<bit_shift));
ptr1++;
}
break;
}
ptr=img->body;
ptr1=base->body;
k+=i2<<3;
k1+=i2<<3;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i3;i++)
AssignBit(ptr1,k1++,Bt(ptr,k++));
break;
case ROPB_XOR:
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Btc(ptr1,k1++);
break;
case ROPB_OR:
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Bts(ptr1,k1++);
break;
case ROPB_NAND:
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Btr(ptr1,k1++);
break;
}
break;
case BMT_MONO:
k=kk;
k1=kk1+plane1;
ptr=img->body;
ptr1=base->body;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i1;i++)
AssignBit(ptr1,k1++,color_bit && Bt(ptr,k++));
break;
case ROPB_TRANSPARENT:
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
AssignBit(ptr1,k1++,color_bit);
break;
case ROPB_XOR:
if (color_bit)
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Btc(ptr1,k1++);
break;
case ROPB_OR:
if (color_bit)
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Bts(ptr1,k1++);
break;
case ROPB_NAND:
if (color_bit)
for (i=0;i<i1;i++)
if (Bt(ptr,k++))
Btr(ptr1,k1++);
break;
}
ptr+=k>>3;
ptr1+=k1>>3;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i2;i++) {
*ptr1=*ptr1 & bit_mask | ((*ptr++ & color_byte)<<bit_shift);
ptr1++;
}
break;
case ROPB_TRANSPARENT:
for (i=0;i<i2;i++) {
bit_mask=~(*ptr<<bit_shift);
*ptr1=*ptr1 & bit_mask | ((*ptr++ & color_byte)<<bit_shift);
ptr1++;
}
break;
case ROPB_XOR:
if (color_bit)
for (i=0;i<i2;i++) {
*ptr1^=*ptr++<<bit_shift;
ptr1++;
}
break;
case ROPB_OR:
if (color_bit)
for (i=0;i<i2;i++) {
*ptr1|=*ptr++<<bit_shift;
ptr1++;
}
break;
case ROPB_NAND:
if (color_bit)
for (i=0;i<i2;i++) {
*ptr1= *ptr1 & (bit_mask | ~(*ptr++<<bit_shift));
ptr1++;
}
break;
}
ptr=img->body;
ptr1=base->body;
k+=i2<<3;
k1+=i2<<3;
switch (color.u1[3]) {
case ROPB_EQU:
for (i=0;i<i3;i++)
AssignBit(ptr1,k1++,color_bit && Bt(ptr,k++));
break;
case ROPB_TRANSPARENT:
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
AssignBit(ptr1,k1++,color_bit);
break;
case ROPB_XOR:
if (color_bit)
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Btc(ptr1,k1++);
break;
case ROPB_OR:
if (color_bit)
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Bts(ptr1,k1++);
break;
case ROPB_NAND:
if (color_bit)
for (i=0;i<i3;i++)
if (Bt(ptr,k++))
Btr(ptr1,k1++);
break;
}
break;
}
kk+=img->internal_width;
kk1+=base->internal_width;
}
}
return TRUE;
}
return FALSE;
}
#help_index "Graphics"
public BoolU4 GrText(GrBitMap *base,I8 x,I8 y,U1 *s)
{ //Clipping but not transformation
I8 len=StrLen(s),ch,reg i,i1,i2,i3,j,k1,kk1,w1,h1,w2,h2,plane1,reg bit_mask,reg bit_shift,p,dist,l,l1;
U1 reg *ptr,*font_ptr,*s1;
U2 reg *ptr1,*ptr2;
I8 color,reg color_byte,c,plane_size1,plane_limit1;
BoolU4 draw=TRUE,color_bit;
w1= (x<0)?-x:0;
h1= (y<0)?-y:0;
w2=len*FONT_WIDTH;
h2=FONT_HEIGHT;
if (base->flags & BMF_SCREEN_BITMAP) {
x+=base->win_tss->win_pixel_left;
y+=base->win_tss->win_pixel_top;
}
if (base->flags & BMF_LOCATE_NEAREST) { //TODO:Untested
dist=DistI8(x+w2>>1,y+h2>>1,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
if (base->flags & BMF_SCREEN_BITMAP) {
if (x+w1<0) w1=-x;
if (x+w2>base->win_tss->win_pixel_right)
w2=base->win_tss->win_pixel_right-x;
if (y+h1<0) h1=-y;
if (y+h2>base->win_tss->win_pixel_bottom)
h2=base->win_tss->win_pixel_bottom-y;
if (IsPixelCovered(base->win_tss,x+w1,y+h1))
draw=FALSE;
else if (IsPixelCovered(base->win_tss,x+w2,y+h2))
draw=FALSE;
x+=base->left_margin;
y+=base->top_margin;
}
if (x+w2>base->width)
w2=base->width-x;
if (y+h2>base->height)
h2=base->height-y;
if (draw && w1<w2 && h1<h2 && w2<=len*FONT_WIDTH && h2<=FONT_HEIGHT) {
if (base->flags & BMF_DONT_DRAW)
return TRUE;
color=base->color;
p=0;
plane_size1=base->plane_size<<3;
switch (base->type) {
case BMT_COLOR4:
plane_limit1=plane_size1*4;
break;
case BMT_MONO:
plane_limit1=plane_size1;
break;
}
i1=(-w1)&7;
if (i1>w2) i1=w2;
i2=(w2-w1-i1)>>3;
i3=w2-w1-i2<<3-i1;
bit_shift=x&7;
bit_mask=-1-255<<bit_shift;
s+=w1/FONT_WIDTH;
l=w1%FONT_WIDTH;
if (color.u1[3]==ROPB_COLLISION) {
color =base->bkcolor&0xFFFFFF;
ch=*s++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
for (i=w1;i<w2;i++) {
k1=(h1+y)*base->internal_width+x;
ptr=font_ptr;
for (j=h1;j<h2;j++) {
c=0;
for (plane1=0,p=1;plane1<plane_limit1;
plane1+=plane_size1,p<<=1)
if (Bt(base->body,k1+i+plane1))
c+=p;
if (c!=color) {
if (Bt(ptr,l))
base->collision_cnt++;
}
k1+=base->internal_width;
ptr++;
}
if (++l==FONT_WIDTH) {
ch=*s++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
l=0;
}
}
} else {
for (plane1=0;plane1<plane_limit1;plane1+=plane_size1) {
s1=s;
l1=l;
if (color_bit=Bt(&color,p++))
color_byte=255;
else
color_byte=0;
ptr2=base->body+plane1>>3;
kk1=(h1+y)*base->internal_width+x+w1;
ch=*s1++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
for (i=0;i<i1;i++) {
k1=kk1;
ptr=font_ptr;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
AssignBit(ptr2,k1,color_bit);
k1+=base->internal_width;
}
break;
case ROPB_XOR:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Btc(ptr2,k1);
k1+=base->internal_width;
}
break;
case ROPB_OR:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Bts(ptr2,k1);
k1+=base->internal_width;
}
break;
case ROPB_NAND:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Btr(ptr2,k1);
k1+=base->internal_width;
}
break;
}
if (++l1==FONT_WIDTH) {
ch=*s1++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
l1=0;
}
}
kk1+=i1;
ptr2+=kk1>>3;
for (i=0;i<i2;i++) {
ptr1=ptr2;
ptr=font_ptr;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (j=h1;j<h2;j++) {
bit_mask=~(*ptr<<bit_shift);
*ptr1=*ptr1 & bit_mask | ((*ptr++ & color_byte)<<bit_shift);
ptr1+=base->internal_width>>3;
}
break;
case ROPB_XOR:
if (color_bit)
for (j=h1;j<h2;j++) {
*ptr1^=*ptr++<<bit_shift;
ptr1+=base->internal_width>>3;
}
break;
case ROPB_OR:
if (color_bit)
for (j=h1;j<h2;j++) {
*ptr1|=*ptr++<<bit_shift;
ptr1+=base->internal_width>>3;
}
break;
case ROPB_NAND:
if (color_bit)
for (j=h1;j<h2;j++) {
*ptr1= *ptr1 & (bit_mask | ~(*ptr++<<bit_shift));
ptr1+=base->internal_width>>3;
}
break;
}
ptr2++;
ch=*s1++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
}
kk1+=i2<<3;
ptr1=base->body+plane1>>3;
for (i=0;i<i3;i++) {
ptr=font_ptr;
k1=kk1+i;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
AssignBit(ptr1,k1,color_bit);
k1+=base->internal_width;
}
break;
case ROPB_XOR:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Btc(ptr1,k1);
k1+=base->internal_width;
}
break;
case ROPB_OR:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Bts(ptr1,k1);
k1+=base->internal_width;
}
break;
case ROPB_NAND:
if (color_bit)
for (j=h1;j<h2;j++) {
if (Bt(ptr++,l1))
Btr(ptr1,k1);
k1+=base->internal_width;
}
break;
}
if (++l1==FONT_WIDTH) {
ch=*s1++;
font_ptr=&grfont[(FONT_WIDTH*(FONT_HEIGHT*ch+h1))>>3];
l1=0;
}
}
}
}
return TRUE;
}
return FALSE;
}
public BoolU4 GrBox(GrBitMap *base,I8 x,I8 y,I8 w,I8 h)
{ //Clipping but not transformation
I8 i,i1,i2,i3,j,k1,kk1,w1,h1,w2,h2,plane1,bit_mask,bit_shift,p,dist;
U2 *ptr1;
I8 color,color_byte,c,plane_size1,plane_limit1;
BoolU4 draw=TRUE,color_bit;
w1= (x<0)?-x:0;
h1= (y<0)?-y:0;
w2=w;
h2=h;
if (base->flags & BMF_SCREEN_BITMAP) {
x+=base->win_tss->win_pixel_left;
y+=base->win_tss->win_pixel_top;
}
if (base->flags & BMF_LOCATE_NEAREST) { //TODO:Untested
if (base->cur_x>=x && base->cur_y>=y &&
base->cur_x<=x+w && base->cur_y<=y+h) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=0;
} else {
dist=DistI8(x+w>>1,y+h>>1,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
}
if (base->flags & BMF_SCREEN_BITMAP) {
if (x+w1<0) w1=-x;
if (x+w2>base->win_tss->win_pixel_right)
w2=base->win_tss->win_pixel_right-x;
if (y+h1<0) h1=-y;
if (y+h2>base->win_tss->win_pixel_bottom)
h2=base->win_tss->win_pixel_bottom-y;
if (IsPixelCovered(base->win_tss,x+w1,y+h1))
draw=FALSE;
else if (IsPixelCovered(base->win_tss,x+w2,y+h2))
draw=FALSE;
x+=base->left_margin;
y+=base->top_margin;
}
if (x+w2>base->width)
w2=base->width-x;
if (y+h2>base->height)
h2=base->height-y;
if (draw && w1<w2 && h1<h2 && w2<=w && h2<=h) {
if (base->flags & BMF_DONT_DRAW)
return TRUE;
color=base->color;
p=0;
plane_size1=base->plane_size<<3;
switch (base->type) {
case BMT_COLOR4:
plane_limit1=plane_size1*4;
break;
case BMT_MONO:
plane_limit1=plane_size1;
break;
}
i1=(-w1)&7;
if (i1>w2) i1=w2;
i2=(w2-w1-i1)>>3;
i3=w2-w1-i2<<3-i1;
bit_shift=x&7;
bit_mask=-1-255<<bit_shift;
if (color.u1[3]==ROPB_COLLISION) {
color =base->bkcolor&0xFFFFFF;
k1=(h1+y)*base->internal_width+x;
for (j=h1;j<h2;j++) {
for (i=w1;i<w2;i++) {
c=0;
for (plane1=0,p=1;plane1<plane_limit1;
plane1+=plane_size1,p<<=1)
if (Bt(base->body,k1+i+plane1))
c+=p;
if (c!=color)
base->collision_cnt++;
}
k1+=base->internal_width;
}
} else
for (plane1=0;plane1<plane_limit1;
plane1+=plane_size1) {
if (color_bit=Bt(&color,p++))
color_byte=255;
else
color_byte=0;
kk1=(h1+y)*base->internal_width+x+w1+plane1;
for (j=h1;j<h2;j++) {
k1=kk1;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (i=0;i<i1;i++)
AssignBit(base->body,k1++,color_byte);
break;
case ROPB_XOR:
for (i=0;i<i1;i++)
if (color_byte)
Btc(base->body,k1++);
break;
case ROPB_OR:
for (i=0;i<i1;i++)
if (color_byte)
Bts(base->body,k1++);
break;
case ROPB_NAND:
for (i=0;i<i1;i++)
if (color_byte)
Btr(base->body,k1++);
break;
}
ptr1=k1>>3+base->body;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (i=0;i<i2;i++) {
*ptr1=*ptr1 & bit_mask | (color_byte<<bit_shift);
ptr1++;
}
break;
case ROPB_XOR:
for (i=0;i<i2;i++) {
*ptr1^=color_byte<<bit_shift;
ptr1++;
}
break;
case ROPB_OR:
for (i=0;i<i2;i++) {
*ptr1|=color_byte<<bit_shift;
ptr1++;
}
break;
case ROPB_NAND:
for (i=0;i<i2;i++) {
*ptr1= *ptr1 & (bit_mask | ~(color_byte<<bit_shift));
ptr1++;
}
break;
}
k1+=i2<<3;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
for (i=0;i<i3;i++)
AssignBit(base->body,k1++,color_byte);
break;
case ROPB_XOR:
for (i=0;i<i3;i++)
if (color_byte)
Btc(base->body,k1++);
break;
case ROPB_OR:
for (i=0;i<i3;i++)
if (color_byte)
Bts(base->body,k1++);
break;
case ROPB_NAND:
for (i=0;i<i3;i++)
if (color_byte)
Btr(base->body,k1++);
break;
}
kk1+=base->internal_width;
}
}
return TRUE;
}
return FALSE;
}
I8 GrRayLenMinus(GrBitMap *base,I8 x,I8 y)
{
I8 cnt=0,c,x3=x,y3=y,d;
U1 *dst,bit,*dst2;
BoolU4 peek=TRUE,
not_color=(base->flags&BMF_FILL_NOT_COLOR)?TRUE:FALSE;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) peek=FALSE;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) peek=FALSE;
if (y3<0) peek=FALSE;
y3+=base->win_tss->win_pixel_top;
if (y3>base->win_tss->win_pixel_bottom) peek=FALSE;
if (x3>=base->width) peek=FALSE;
if (y3>=base->height) peek=FALSE;
if (IsPixelCovered(base->win_tss,x3,y3)) peek=FALSE;
} else {
if (x3<0) peek=FALSE;
if (x3>=base->width) peek=FALSE;
if (y3<0) peek=FALSE;
if (y3>=base->height) peek=FALSE;
}
if (!peek)
return 0;
switch (base->type) {
case BMT_COLOR4:
dst2=base->body+(base->left_margin+
(y3+base->top_margin)*base->internal_width)>>3;
d=base->plane_size;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
dst=dst2+x3>>3;
bit=1<<(x3&7);
c=0;
if (*dst & bit)
c|=1;
dst+=d;
if (*dst & bit)
c|=2;
dst+=d;
if (*dst & bit)
c|=4;
dst+=d;
if (*dst & bit)
c|=8;
if (not_color) {
if (c!=base->color2) {
cnt++;
x--;
} else
break;
} else {
if (c==base->color2) {
cnt++;
x--;
} else
break;
}
}
return cnt;
case BMT_MONO:
d=base->internal_width*(y3+base->top_margin)+
base->left_margin;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
if (not_color) {
if (Bt(base->body,d+x3)!=base->color2) {
cnt++;
x--;
} else
break;
} else {
if (Bt(base->body,d+x3)==base->color2) {
cnt++;
x--;
} else
break;
}
}
return cnt;
}
}
I8 GrRayLen(GrBitMap *base,I8 *x1,I8 y)
{
I8 cnt=0,d,c,c2,x=*x1,x2=x,x3=x,y3=y;
BoolU4 peek=TRUE,
not_color=(base->flags&BMF_FILL_NOT_COLOR)?TRUE:FALSE;
U1 *dst,bit,not_bit,*dst2;
U8 color=base->color,bkcolor=base->bkcolor;
double dist;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) peek=FALSE;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) peek=FALSE;
if (y3<0) peek=FALSE;
y3+=base->win_tss->win_pixel_top;
if (y3>base->win_tss->win_pixel_bottom) peek=FALSE;
if (x3>=base->width) peek=FALSE;
if (y3>=base->height) peek=FALSE;
if (IsPixelCovered(base->win_tss,x3,y3)) peek=FALSE;
} else {
if (x3<0) peek=FALSE;
if (x3>=base->width) peek=FALSE;
if (y3<0) peek=FALSE;
if (y3>=base->height) peek=FALSE;
}
if (!peek)
return 0;
switch (base->type) {
case BMT_COLOR4:
dst2=base->body+(base->left_margin+
(y3+base->top_margin)*base->internal_width)>>3;
d=base->plane_size;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
dst=dst2+x3>>3;
bit=1<<(x3&7);
not_bit=~bit;
c=0;
if (*dst & bit)
c|=1;
dst+=d;
if (*dst & bit)
c|=2;
dst+=d;
if (*dst & bit)
c|=4;
dst+=d;
if (*dst & bit)
c|=8;
if (not_color && c!=base->color2 ||
!not_color && c==base->color2) {
if (base->flags & BMF_LOCATE_NEAREST) {
dist=DistI8(x3,y3,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
dst=dst2+x3>>3;
c=color.u1[0];
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
if (c & 1)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 2)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 4)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 8)
*dst|=bit;
else
*dst&=not_bit;
break;
case ROPB_COLLISION:
c2=0;
if (*dst&bit)
c2+=1;
dst+=d;
if (*dst&bit)
c2+=2;
dst+=d;
if (*dst&bit)
c2+=4;
dst+=d;
if (*dst&bit)
c2+=8;
if (c2!=bkcolor.u1[0])
base->collision_cnt++;
break;
case ROPB_XOR:
if (c & 1) *dst^=bit;
dst+=d;
if (c & 2) *dst^=bit;
dst+=d;
if (c & 4) *dst^=bit;
dst+=d;
if (c & 8) *dst^=bit;
break;
case ROPB_OR:
if (c & 1) *dst|=bit;
dst+=d;
if (c & 2) *dst|=bit;
dst+=d;
if (c & 4) *dst|=bit;
dst+=d;
if (c & 8) *dst|=bit;
break;
case ROPB_NAND:
if (c & 1) *dst&=not_bit;
dst+=d;
if (c & 2) *dst&=not_bit;
dst+=d;
if (c & 4) *dst&=not_bit;
dst+=d;
if (c & 8) *dst&=not_bit;
break;
}
cnt++;
x++;
} else
break;
}
*x1=x-1;
x=x2-1;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
dst=dst2+x3>>3;
bit=1<<(x3&7);
not_bit=~bit;
c=0;
if (*dst & bit)
c|=1;
dst+=d;
if (*dst & bit)
c|=2;
dst+=d;
if (*dst & bit)
c|=4;
dst+=d;
if (*dst & bit)
c|=8;
if (not_color && c!=base->color2 ||
!not_color && c==base->color2) {
if (base->flags & BMF_LOCATE_NEAREST) {
dist=DistI8(x3,y3,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
dst=dst2+x3>>3;
c=color.u1[0];
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
if (c & 1)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 2)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 4)
*dst|=bit;
else
*dst&=not_bit;
dst+=d;
if (c & 8)
*dst|=bit;
else
*dst&=not_bit;
break;
case ROPB_COLLISION:
c2=0;
if (*dst&bit)
c2+=1;
dst+=d;
if (*dst&bit)
c2+=2;
dst+=d;
if (*dst&bit)
c2+=4;
dst+=d;
if (*dst&bit)
c2+=8;
if (c2!=bkcolor.u1[0])
base->collision_cnt++;
break;
case ROPB_XOR:
if (c & 1) *dst^=bit;
dst+=d;
if (c & 2) *dst^=bit;
dst+=d;
if (c & 4) *dst^=bit;
dst+=d;
if (c & 8) *dst^=bit;
break;
case ROPB_OR:
if (c & 1) *dst|=bit;
dst+=d;
if (c & 2) *dst|=bit;
dst+=d;
if (c & 4) *dst|=bit;
dst+=d;
if (c & 8) *dst|=bit;
break;
case ROPB_NAND:
if (c & 1) *dst&=not_bit;
dst+=d;
if (c & 2) *dst&=not_bit;
dst+=d;
if (c & 4) *dst&=not_bit;
dst+=d;
if (c & 8) *dst&=not_bit;
break;
}
cnt++;
x--;
} else
break;
}
return cnt;
case BMT_MONO:
d=base->internal_width*(y3+base->top_margin)+
base->left_margin;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
c=Bt(base->body,d+x3);
if (not_color && c!=base->color2 ||
!not_color && c==base->color2) {
if (base->flags & BMF_LOCATE_NEAREST) {
dist=DistI8(x3,y3,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
c=color&0xFFFFFF;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
AssignBit(base->body,d+x3,c);
break;
case ROPB_COLLISION:
if (c) {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=Bt(base->body,d+x3);
else
base->collision_cnt+=!Bt(base->body,d+x3);
} else {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=!Bt(base->body,d+x3);
else
base->collision_cnt+=Bt(base->body,d+x3);
}
break;
case ROPB_XOR:
if (c)
Btc(base->body,d+x3);
break;
case ROPB_OR:
if (c)
Bts(base->body,d+x3);
break;
case ROPB_NAND:
if (c)
Btr(base->body,d+x3);
break;
}
cnt++;
x++;
} else
break;
}
*x1=x-1;
x=x2-1;
while (TRUE) {
x3=x;
if (base->flags & BMF_SCREEN_BITMAP) {
if (x3<0) break;
x3+=base->win_tss->win_pixel_left;
if (x3>base->win_tss->win_pixel_right) break;
if (x3>=base->width) break;
if (IsPixelCovered(base->win_tss,x3,y3)) break;
} else {
if (x3<0) break;
if (x3>=base->width) break;
}
c=Bt(base->body,d+x3);
if (not_color && c!=base->color2 ||
!not_color && c==base->color2) {
if (base->flags & BMF_LOCATE_NEAREST) {
dist=DistI8(x3,y3,base->cur_x,base->cur_y);
if (dist<=base->nearest_dist) {
base->nearest_sub_grelem=base->cur_sub_grelem;
base->nearest_dist=dist;
}
}
c=color&0xFFFFFF;
switch (color.u1[3]) {
case ROPB_EQU:
case ROPB_TRANSPARENT:
AssignBit(base->body,d+x3,c);
break;
case ROPB_COLLISION:
if (c) {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=Bt(base->body,d+x3);
else
base->collision_cnt+=!Bt(base->body,d+x3);
} else {
if (bkcolor&0xFFFFFF)
base->collision_cnt+=!Bt(base->body,d+x3);
else
base->collision_cnt+=Bt(base->body,d+x3);
}
break;
case ROPB_XOR:
if (c)
Btc(base->body,d+x3);
break;
case ROPB_OR:
if (c)
Bts(base->body,d+x3);
break;
case ROPB_NAND:
if (c)
Btr(base->body,d+x3);
break;
}
cnt++;
x--;
} else
break;
}
return cnt;
}
}