//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "PenObject.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- __fastcall TPenObject::TPenObject(TTablet *pTablet) { short d; FTablet = pTablet; FBasicThick = 0; data[0] = data[1] = NULL; d = MAX_PEN_WIDTH; count[0] = d*d; if ((data[0] = (sPen *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(sPen)*count[0]))==NULL) return; d = MAX_PEN_WIDTH-1; count[1] = d*d; if ((data[1] = (sPen *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(sPen)*count[1]))==NULL) { HeapFree(GetProcessHeap(), 0, data[0]); data[0] = NULL; return; } FBasicThick = 12; FBrush = false; FShape = 0; FThick = 12; FThickRatio = 1.0; start = FALSE; FMoveRatio = 8; FPenDrawFunc = NULL; _make_data(); } //--------------------------------------------------------------------------- __fastcall TPenObject::~TPenObject() { if (data[0]) { HeapFree(GetProcessHeap(), 0, data[0]); data[0] = NULL; } if (data[1]) { HeapFree(GetProcessHeap(), 0, data[1]); data[1] = NULL; } } //--------------------------------------------------------------------------- // Private Function //--------------------------------------------------------------------------- static int compare(const void *a, const void *b) { sPen *ap = (sPen *)a, *bp = (sPen *)b; if (ap->ratioratio) return -1; else if (ap->ratio>bp->ratio) return 1; else { if (ap->yy) return -1; else if (ap->y>bp->y) return 1; return 0; } } //--------------------------------------------------------------------------- void __fastcall TPenObject::_make_data() { short x, y, d; double dx, dy, h; sPen *dp; d = MAX_PEN_WIDTH; h = d/2.0-0.5; dp = data[0]; switch (FShape) { case 0: for (y=0; yratio = 2.0*sqrt(dx*dx+dy*dy); dp->x = dx-0.5; dp->y = dy-0.5; dp++; } } break; case 1: for (y=0; yratio = 2.0*fabs(fabs(dx)>fabs(dy) ? dx : dy); dp->x = dx-0.5; dp->y = dy-0.5; dp++; } } break; } qsort(data[0], count[0], sizeof(sPen), &compare); d = MAX_PEN_WIDTH-1; h = d/2.0-0.5; dp = data[1]; switch (FShape) { case 0: for (y=0; yratio = 2.0*sqrt(dx*dx+dy*dy); dp->x = dx; dp->y = dy; dp++; } } break; case 1: for (y=0; yratio = 2.0*fabs(fabs(dx)>fabs(dy) ? dx : dy); dp->x = dx; dp->y = dy; dp++; } } break; } qsort(data[1], count[1], sizeof(sPen), &compare); } //--------------------------------------------------------------------------- int __fastcall TPenObject::GetThick() { if (FTablet->prsNew > FTablet->MaxNPressure) FTablet->prsNew = FTablet->MaxNPressure; return FBrush && FCursor ? (FThick-1)*FTablet->prsNew/FTablet->MaxNPressure+1 : FThick; } //--------------------------------------------------------------------------- void __fastcall TPenObject::SetBasicThick(int Value) { if (FBasicThick!=Value) FBasicThick = Value; FThick = FBasicThick*FThickRatio; } //--------------------------------------------------------------------------- void __fastcall TPenObject::SetShape(int Value) { if (FShape!=Value) { FShape = Value; _make_data(); } } //--------------------------------------------------------------------------- void __fastcall TPenObject::SetThickRatio(double Value) { if (FThickRatio!=Value) { FThickRatio = Value; FThick = FBasicThick*FThickRatio; } } //--------------------------------------------------------------------------- // Public Function //--------------------------------------------------------------------------- bool __fastcall TPenObject::isCreate() { return FBasicThick ? true : false; } //--------------------------------------------------------------------------- void __fastcall TPenObject::SetPixels(sPenDraw &draw, int X, int Y) { RECT rcInvalidate; if (FPenDrawFunc==NULL) return; draw.cp.x = X; draw.cp.y = Y; if (FTablet->prsNew > FTablet->MaxNPressure) FTablet->prsNew = FTablet->MaxNPressure; draw.cw = FBrush && FCursor==1 ? (FThick-1)*FTablet->prsNew/FTablet->MaxNPressure+1 : FThick; point(draw); rcInvalidate.left = draw.cp.x-32; rcInvalidate.top = draw.cp.y-32; rcInvalidate.right = draw.cp.x+32; rcInvalidate.bottom = draw.cp.y+32; #ifndef dogtest draw.Image->RectPaint(rcInvalidate); #endif } //--------------------------------------------------------------------------- void __fastcall TPenObject::MoveTo(sPenDraw &draw, int X, int Y) { draw.cp.x = draw.fp.x = X; draw.cp.y = draw.fp.y = Y; if (FTablet->prsNew > FTablet->MaxNPressure) FTablet->prsNew = FTablet->MaxNPressure; draw.cw = draw.fw = FBrush && FCursor==1 ? (FThick-1)*FTablet->prsNew/FTablet->MaxNPressure+1 : FThick; } //--------------------------------------------------------------------------- void __fastcall TPenObject::LineTo(sPenDraw &draw, int X, int Y) { int t, dx, dy; double pwl, pwx, pwy, s; TRect rcInvalidate; if (FPenDrawFunc==NULL) return; t = (draw.cw-1)/FMoveRatio+1; draw.sp.x = X; draw.sp.y = Y; dx = draw.sp.x-draw.fp.x; dy = draw.sp.y-draw.fp.y; if (FBrush) { if (FTablet->prsNew > FTablet->MaxNPressure) FTablet->prsNew = FTablet->MaxNPressure; draw.sw = FCursor==1 ? (FThick-1)*FTablet->prsNew/FTablet->MaxNPressure+1 : FThick; pwl = draw.sw-draw.fw; if (dx==0) pwx = pwl; else pwx = pwl/abs(dx); if (dy==0) pwy = pwl; else pwy = pwl/abs(dy); if (draw.fp.x==draw.sp.x) { if (draw.fp.ydraw.sp.y) { for (draw.cp.y=draw.fp.y; draw.cp.y>draw.sp.y; draw.cp.y-=t) { draw.cp.x = draw.fp.x; draw.cw = draw.fw+(draw.fp.y-draw.cp.y)*pwy+0.5; point(draw); t = (draw.cw-1)/FMoveRatio+1; } } else { draw.cp = draw.fp; draw.cw = draw.fw; point(draw); } } else if (draw.fp.y==draw.sp.y) { if (draw.fp.xdraw.sp.x; draw.cp.x-=t) { draw.cp.y = draw.fp.y; draw.cw = draw.fw+(draw.fp.x-draw.cp.x)*pwx+0.5; point(draw); t = (draw.cw-1)/FMoveRatio+1; } } } else { s = (double)dy/dx; if (fabs(s)>1.0) { if (draw.fp.ydraw.sp.y; draw.cp.y-=t) { draw.cp.x = draw.fp.x+double(draw.cp.y-draw.fp.y)/s+0.5; draw.cw = draw.fw+(draw.fp.y-draw.cp.y)*pwy+0.5; point(draw); t = (draw.cw-1)/FMoveRatio+1; } } } else { if (draw.fp.xdraw.sp.x; draw.cp.x-=t) { draw.cp.y = draw.fp.y+double(draw.cp.x-draw.fp.x)*s+0.5; draw.cw = draw.fw+(draw.fp.x-draw.cp.x)*pwx+0.5; point(draw); t = (draw.cw-1)/FMoveRatio+1; } } } } draw.fw = draw.sw; } else { if (draw.fp.x==draw.sp.x) { if (draw.fp.ydraw.sp.y) { for (draw.cp.y=draw.fp.y; draw.cp.y>draw.sp.y; draw.cp.y-=t) { draw.cp.x = draw.fp.x; point(draw); } } else { draw.cp = draw.fp; draw.cw = draw.fw; point(draw); } } else if (draw.fp.y==draw.sp.y) { if (draw.fp.xdraw.sp.x; draw.cp.x-=t) { draw.cp.y = draw.fp.y; point(draw); } } } else { s = (double)dy/dx; if (fabs(s)>1.0) { if (draw.fp.ydraw.sp.y; draw.cp.y-=t) { draw.cp.x = draw.fp.x+double(draw.cp.y-draw.fp.y)/s+0.5; point(draw); } } } else { if (draw.fp.xdraw.sp.x; draw.cp.x-=t) { draw.cp.y = draw.fp.y+double(draw.cp.x-draw.fp.x)*s+0.5; point(draw); } } } } } rcInvalidate.Left = min(draw.fp.x, draw.sp.x)-32; rcInvalidate.Top = min(draw.fp.y, draw.sp.y)-32; rcInvalidate.Right = max(draw.fp.x, draw.sp.x)+32; rcInvalidate.Bottom = max(draw.fp.y, draw.sp.y)+32; #ifndef dogtest draw.Image->RectPaint(rcInvalidate); #endif draw.fp = draw.sp; } //---------------------------------------------------------------------------