📄 wingdi.c
字号:
}
#elif(BITS_PER_PIXEL==24 || BITS_PER_PIXEL==32)
{ *(DWORD *)rgbColor=index;
}
#endif
}
//---------------------------------------------------------------------------
void SetColor(HDC dc, TCOLOR RgbColor)
{ ((TWndCanvas *)dc)->Foreground = ColorMapToPixel((RGBQUAD *)&RgbColor);
}
void SetBackColor(HDC dc, TCOLOR RgbColor)
{ ((TWndCanvas *)dc)->Background = ColorMapToPixel((RGBQUAD *)&RgbColor);
}
//---------------------------------------------------------------------------
//GetPixelPosition 获取指定像素的物理地址
void GetPixelPosition( PIXEL **PixelPos, int *BitOffset, TWndCanvas *ACanvas, int X, int Y )
{ X+=ACanvas->VX;
Y+=ACanvas->VY;
#if(BITS_PER_PIXEL==PIXEL_UNIT) /* 8 16 32 */
{ *PixelPos=ACanvas->Vram->FrameBuffer + Y * ACanvas->Vram->UnitPerLine +X;
*BitOffset = 0 ;
}
#elif(BITS_PER_PIXEL==24)
{ *PixelPos=(PIXEL *)((BYTE *)ACanvas->Vram->FrameBuffer + Y * ACanvas->Vram->BytePerLine +X*3 );
*BitOffset = 0 ;
}
#elif(BITS_PER_PIXEL<8)
{ DWORD LineOffset = X << LOG_PIXEL_BITS; //X,Y是相对VRAM的坐标,而不时相对LCD的坐标
*PixelPos = ACanvas->Vram->FrameBuffer + Y * ACanvas->Vram->UnitPerLine + ( X >> LOG_PIXEL_NUM );
*BitOffset = LineOffset & ( PIXEL_UNIT -1 ) ;
}
#endif
}
//-------------------------------------------------------------------------------------
//cmPixelOpt 对指定像素进行逻辑操作(包括按位与、或、异或、复制等)
void cmPixelOpt( PIXEL *desPixelPos, int desBitOffset, PIXEL srcValue, DWORD dwRop)
{
#if(BITS_PER_PIXEL<8)
PIXEL srcMask=(PIXEL)MASK_OFFSET_OPT(BITS_PER_PIXEL,desBitOffset);
PIXEL_OFFSET_OPT(srcValue,BITS_PER_PIXEL,desBitOffset);
SET_PIXEL_LOGIC(&srcValue,*desPixelPos,srcValue,dwRop);
*desPixelPos=(*desPixelPos & ~srcMask)|(srcValue & srcMask);
#elif(BITS_PER_PIXEL==PIXEL_UNIT)
SET_PIXEL_LOGIC(desPixelPos,*desPixelPos,srcValue,dwRop);
#elif(BITS_PER_PIXEL==24)
SET_3BYTE_LOGIC( desPixelPos,srcValue,srcValue>>8,srcValue>>16,dwRop);;
#endif
}
//---------------------------------------------------------------------------
void CanvasCopy(TWndCanvas *TgtCanvas,int tgtx,int tgty,TWndCanvas *SrcCanvas,int srcx,int srcy,int width,int height)
{ int SrcVramUnitPerLine = SrcCanvas->Vram->UnitPerLine;
PIXEL *srcLinePos, *desLinePos;
int srcBitOffset, desBitOffset;
GetPixelPosition( &srcLinePos, &srcBitOffset, SrcCanvas, srcx, srcy);
GetPixelPosition( &desLinePos, &desBitOffset, TgtCanvas, tgtx, tgty);
if(srcx==0 && tgtx==0 && width==SrcCanvas->Vram->Width && width==TgtCanvas->Vram->Width)
{ memcpy(desLinePos,srcLinePos,(DWORD)height * SrcVramUnitPerLine * UNIT_BYTE);
}
else
{ int TgtVramUnitPerLine = TgtCanvas->Vram->UnitPerLine;
int i,j;
#if(BITS_PER_PIXEL==PIXEL_UNIT) /* 8 16 32 */
for(j = 0; j < height; j++ )
{ for(i=0;i<width;i++)
{ desLinePos[i]=srcLinePos[i];
}
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
#elif(BITS_PER_PIXEL==24)
{ BYTE *desPos,*srcPos;
for(j = 0; j < height; j++ )
{ desPos=(BYTE *)desLinePos;
srcPos=(BYTE *)srcLinePos;
for(i=0;i<width;i++)
{ *desPos++ = *srcPos++;
*desPos++ = *srcPos++;
*desPos++ = *srcPos++;
}
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
}
#elif(BITS_PER_PIXEL<8)
PIXEL bitmask,b_bitmask,bits;
PIXEL *ScrHead=srcLinePos;
PIXEL *DesHead=desLinePos;
int totalBits=width<<LOG_PIXEL_BITS;
if(desBitOffset>0)
{ if(totalBits<PIXEL_UNIT-desBitOffset)
{ bitmask=MASK_OFFSET_OPT(totalBits,desBitOffset);
totalBits=0;
}
else
{ bitmask=MASK_OFFSET_OPT(PIXEL_UNIT-desBitOffset,desBitOffset);
totalBits-=(PIXEL_UNIT-desBitOffset);
}
for(j = 0; j < height; j++ )
{ if(desBitOffset<=srcBitOffset)
{ bits=*srcLinePos;
if(desBitOffset<srcBitOffset) bits=PATTERN_SHIFT_LFFT(bits,srcBitOffset-desBitOffset) | PATTERN_SHIFT_RIGHT(*(srcLinePos+1),PIXEL_UNIT+desBitOffset-srcBitOffset);
}
else
{ bits=PATTERN_SHIFT_RIGHT(*srcLinePos,desBitOffset-srcBitOffset);
}
*desLinePos=(*desLinePos)&(~bitmask) | (bits&bitmask);
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
if(desBitOffset<=srcBitOffset)ScrHead++;
DesHead++;
}
srcBitOffset=(desBitOffset>srcBitOffset)?(PIXEL_UNIT+srcBitOffset-desBitOffset):(srcBitOffset-desBitOffset);
desBitOffset=0;
if(srcBitOffset)
{ int srcheadbits=PIXEL_UNIT-srcBitOffset;
width=totalBits>>LOG_UNIT;
if(width)
{ srcLinePos=ScrHead;
desLinePos=DesHead;
for(j = 0; j < height; j++ )
{ for(i = 0; i < width; i++ )
{ desLinePos[i]=PATTERN_SHIFT_LFFT(srcLinePos[i],srcBitOffset) | PATTERN_SHIFT_RIGHT(srcLinePos[i+1],srcheadbits);
}
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
totalBits&=(PIXEL_UNIT-1);
}
if(totalBits)
{ bitmask=MASK_OFFSET_OPT(totalBits,0);
b_bitmask=~bitmask;
srcLinePos=ScrHead+width;
desLinePos=DesHead+width;
for(j = 0; j < height; j++ )
{ bits=PATTERN_SHIFT_LFFT(*srcLinePos,srcBitOffset) | PATTERN_SHIFT_RIGHT(*(srcLinePos+1),srcheadbits);
*desLinePos=( *desLinePos & b_bitmask ) | ( bits & bitmask );
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
}
}
else
{ width=totalBits>>LOG_UNIT;
if(width)
{ srcLinePos=ScrHead;
desLinePos=DesHead;
for(j = 0; j < height; j++ )
{ for(i = 0; i < width; i++ )
{ desLinePos[i]=srcLinePos[i];
}
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
totalBits&=(PIXEL_UNIT-1);
}
if(totalBits>0)
{ bitmask=MASK_OFFSET_OPT(totalBits,0);
b_bitmask=~bitmask;
srcLinePos=ScrHead+width;
desLinePos=DesHead+width;
for(j = 0; j < height; j++ )
{ bits=*srcLinePos;
*desLinePos=( *desLinePos & b_bitmask ) | ( bits & bitmask );
desLinePos+=TgtVramUnitPerLine;
srcLinePos+=SrcVramUnitPerLine;
}
}
}
#endif
}
}
//---------------------------------------------------------------------------
/*注:在桌面(RootWindow)上绘图比较特殊,它直接覆盖性地输出到屏幕而不剪切任何窗口*/
#define CM_ExposeCanvas(ACanvas,x,y,width,height)\
{ if( (ACanvas)->Vram->GroupOperation==0 && (ACanvas)->Owner && (ACanvas)->Owner->unmapcount==0 )\
{ if(!(ACanvas)->Owner->Family->TopWnd->Prev) WriteToLCD(ACanvas,x,y,width,height);\
else\
{ extern BOOL SomeWndNeedPaint;\
TRECT expose_rect;\
SomeWndNeedPaint=true;\
(ACanvas)->Owner->Family->CanvasChanged=true;\
expose_rect.left=(ACanvas)->Vram->Left+(ACanvas)->VX +x;\
expose_rect.top=(ACanvas)->Vram->Top+(ACanvas)->VY +y;\
expose_rect.right=expose_rect.left+width;\
expose_rect.bottom=expose_rect.top+height;\
RegionUnionRect(&(ACanvas)->Vram->ExposeRegion, &expose_rect);\
}\
}\
}
//---------------------------------------------------------------------------
#define WRITE_PIXEL(ACanvas,x,y) \
{ GetPixelPosition( &PixelPos, &BitOffset, (ACanvas), (x), (y) ); \
cmPixelOpt( PixelPos, BitOffset, (ACanvas)->Foreground, (ACanvas)->Mode&0x03 ); \
}
//---------------------------------------------------------------------------
#define PUT_PIXEL(ACanvas,x,y) \
{ if((x)>=(ACanvas)->ClipRect.left && (x)<(ACanvas)->ClipRect.right && (y)>=(ACanvas)->ClipRect.top && (y)<(ACanvas)->ClipRect.bottom)\
{ WRITE_PIXEL(ACanvas,x,y);\
CM_ExposeCanvas(ACanvas,x,y,1,1);\
}\
}
//---------------------------------------------------------------------------
void DrawPixel(HDC dc,int x,int y)
{ int BitOffset;
PIXEL *PixelPos;
PUT_PIXEL((TWndCanvas *)dc,x,y);
}
//---------------------------------------------------------------------------
//用指定的颜色画直线,并与背景色进行逻辑操作(包括按位与、或、异或、复制等)
void DrawHorLine(HDC dc, int x, int y, int width)
{ PIXEL FillColorIndex=((TWndCanvas *)dc)->Foreground;
int HeadBitOffset;
int i;
PIXEL *PixelPos;
DWORD dwRop=((TWndCanvas *)dc)->Mode&0x03;
CHECK_CANVAS_HORLINE((TWndCanvas *)dc,x,y,width);
GetPixelPosition( &PixelPos, &HeadBitOffset, (TWndCanvas *)dc, x, y );
#if(BITS_PER_PIXEL==PIXEL_UNIT) /* 8 16 32 */
{ for(i=0;i<width;i++)
{ SET_PIXEL_LOGIC(PixelPos,*PixelPos,FillColorIndex,dwRop);
PixelPos++;
}
}
#elif(BITS_PER_PIXEL==24)
{ BYTE FillColorByte1=(BYTE)FillColorIndex;
BYTE FillColorByte2=(BYTE)(FillColorIndex>>8);
BYTE FillColorByte3=(BYTE)(FillColorIndex>>16);
for(i=0;i<width;i++)
{ SET_3BYTE_LOGIC(PixelPos,FillColorByte1,FillColorByte2,FillColorByte3,dwRop);
PixelPos=(PIXEL *)((BYTE *)PixelPos+3);
}
}
#elif(BITS_PER_PIXEL<8)
{ PIXEL headbitmask,tailbitmask,newpixel;
int UnitCount,totalBits;
if(FillColorIndex!=0)
{ PIXEL Foreground=FillColorIndex;
for(i=BITS_PER_PIXEL;i<PIXEL_UNIT;i+=BITS_PER_PIXEL)
{ FillColorIndex=(FillColorIndex<<BITS_PER_PIXEL)|Foreground;
}
}
totalBits=width<<LOG_PIXEL_BITS;
if(HeadBitOffset)
{ if(totalBits<PIXEL_UNIT-HeadBitOffset)
{ headbitmask=MASK_OFFSET_OPT(totalBits,HeadBitOffset);
UnitCount=0;
tailbitmask=0;
}
else
{ int otherbits=totalBits-(PIXEL_UNIT-HeadBitOffset);
headbitmask=MASK_OFFSET_OPT(PIXEL_UNIT-HeadBitOffset,HeadBitOffset);
UnitCount=otherbits/PIXEL_UNIT;
tailbitmask=otherbits%PIXEL_UNIT;
if(tailbitmask)
{ tailbitmask=MASK_OFFSET_OPT(tailbitmask,0);
}
}
}
else
{ UnitCount= totalBits/PIXEL_UNIT;
tailbitmask=MASK_OFFSET_OPT((totalBits%PIXEL_UNIT),0);
}
if(HeadBitOffset)
{ SET_PIXEL_LOGIC(&newpixel,*PixelPos,FillColorIndex,dwRop);
*PixelPos++=(*PixelPos & ~headbitmask) | (newpixel & headbitmask);;
}
if(UnitCount)
{ for(i=0;i<UnitCount;i++)
{ SET_PIXEL_LOGIC(PixelPos,*PixelPos,FillColorIndex,dwRop);
PixelPos++;
}
}
if(tailbitmask)
{ SET_PIXEL_LOGIC(&newpixel,*PixelPos,FillColorIndex,dwRop);
*PixelPos=( *PixelPos & ~tailbitmask ) | ( newpixel & tailbitmask );
}
}
#endif
CM_ExposeCanvas((TWndCanvas *)dc,x,y,width,1);
}
//---------------------------------------------------------------------------
void DrawVerLine(HDC dc, int x, int y, int height)
{ VRAM *vram=((TWndCanvas *)dc)->Vram;
int i,BitOffset;
PIXEL FillColorIndex=((TWndCanvas *)dc)->Foreground;
PIXEL *PixelPos;
DWORD dwRop=((TWndCanvas *)dc)->Mode&0x03;
CHECK_CANVAS_VERLINE(((TWndCanvas *)dc),x,y,height);
GetPixelPosition( &PixelPos, &BitOffset, (TWndCanvas *)dc, x, y );
#if(BITS_PER_PIXEL==PIXEL_UNIT) /* 8 16 32 */
{ for(i=0;i<height;i++)
{ SET_PIXEL_LOGIC(PixelPos,*PixelPos,FillColorIndex,dwRop);
PixelPos=GetNextLinePos(PixelPos, vram );
}
}
#elif(BITS_PER_PIXEL==24)
{ BYTE FillColorByte1=(BYTE)FillColorIndex;
BYTE FillColorByte2=(BYTE)(FillColorIndex>>8);
BYTE FillColorByte3=(BYTE)(FillColorIndex>>16);
for(i=0;i<height;i++)
{ SET_3BYTE_LOGIC(PixelPos,FillColorByte1,FillColorByte2,FillColorByte3,dwRop);
PixelPos=GetNextLinePos(PixelPos, vram );
}
}
#elif(BITS_PER_PIXEL<8)
{ PIXEL newpixel,srcMask,b_srcMask;
srcMask=(PIXEL)MASK_OFFSET_OPT(BITS_PER_PIXEL,BitOffset);
PIXEL_OFFSET_OPT(FillColorIndex,BITS_PER_PIXEL,BitOffset);
b_srcMask=~srcMask;
for(i=0;i<height;i++)
{ SET_PIXEL_LOGIC(&newpixel,*PixelPos,FillColorIndex,dwRop);
*PixelPos=(*PixelPos & b_srcMask)|(newpixel & srcMask);
PixelPos=GetNextLinePos(PixelPos, vram );
}
}
#endif
CM_ExposeCanvas((TWndCanvas *)dc,x,y,1,height);
}
//---------------------------------------------------------------------------
void DrawLine(HDC dc, int x1,int y1,int x2,int y2)
{ int dx=x2-x1,dy=y2-y1,stepx,stepy,change;
PIXEL *PixelPos;
int BitOffset;
if(dx==0){DrawVerLine(dc,x1,(y2>y1)?y1:y2,(y2>y1)?y2+1-y1:y1+1-y2);return;}
else if(dx>0)stepx=1; else {dx=-dx;stepx=-1;}
if(dy==0){DrawHorLine(dc,(x2>x1)?x1:x2,y1,(x2>x1)?x2+1-x1:x1+1-x2);return;}
else if (dy>0) stepy=1; else {dy=-dy;stepy=-1;}
if (dx>dy)
{ change=dx>>1;
while (x1!=x2)
{ PUT_PIXEL((TWndCanvas *)dc,x1,y1);
x1+=stepx;change+=dy;
if (change>dx){y1+=stepy;change-=dx;}
}
}
else
{ change=dy>>1;
while (y1!=y2)
{ PUT_PIXEL((TWndCanvas *)dc,x1,y1);
y1+=stepy;change+=dx;
if (change>dy){x1+=stepx; change-=dy;}
}
}
PUT_PIXEL((TWndCanvas *)dc,x2,y2); //the last pixel can not be ignored
}
//---------------------------------------------------------------------------
void DrawRect(HDC dc, int x,int y,int width,int height)
{ //保证拐角点只画一次,否则在异或模式时会失真。
if(width>0 && height>0)
{ DrawHorLine(dc,x,y,width);
DrawHorLine(dc,x,y+height-1,width);
DrawVerLine(dc,x,y+1,height-2);
DrawVerLine(dc,x+width-1,y+1,height-2);
}
}
//---------------------------------------------------------------------------
//画虚线框
void DrawDashedRect(HDC dc, int x,int y,int width,int height)
{ if(width>0 && height>0)
{ BYTE line_pattern=0xaa;
DrawPatternHorLine(dc,x,y,width,line_pattern,true);
DrawPatternHorLine(dc,x,y+height-1,width,line_pattern,true);
DrawPatternVerLine(dc,x,y+1,height-2,line_pattern,true);
DrawPatternVerLine(dc,x+width-1,y+1,height-2,line_pattern,true);
}
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -