Project S Curves
Project S Curves
Need sample code for producing a Project S Curve, similar to those produced by Excel. Any advice would be most appreciated.
Slow, but trying.
Re: Project S Curves
With GDI+ (windows only), sample by danilo :
Code: Select all
EnableExplicit
;>----- START INCLUDE ---------------------------------------
;
;-[ antialiased PB compatible drawing functions using GDI+ ]-
;
; by Danilo, July 2011
;
Prototype DebugEventProc(level, *message.Ascii)
Prototype NotificationHookProc(*token.Long)
Prototype NotificationUnhookProc(token.l)
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugEventCallback.DebugEventProc
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
Structure GdiplusStartupOutput
*NotificationHook.NotificationHookProc
*NotificationUnhook.NotificationUnhookProc
EndStructure
Enumeration ; CompositingMode
#CompositingModeSourceOver = 0 ; // 0
#CompositingModeSourceCopy = 1 ; // 1
EndEnumeration
Enumeration ; QualityMode
#QualityModeInvalid = -1
#QualityModeDefault = 0
#QualityModeLow = 1 ; Best performance
#QualityModeHigh = 2 ; Best rendering quality
EndEnumeration
Enumeration ; CompositingQuality
#CompositingQualityInvalid = #QualityModeInvalid
#CompositingQualityDefault = #QualityModeDefault
#CompositingQualityHighSpeed = #QualityModeLow
#CompositingQualityHighQuality = #QualityModeHigh
#CompositingQualityGammaCorrected
#CompositingQualityAssumeLinear
EndEnumeration
Enumeration ; SmoothingMode
#SmoothingModeInvalid = #QualityModeInvalid
#SmoothingModeDefault = #QualityModeDefault
#SmoothingModeHighSpeed = #QualityModeLow
#SmoothingModeHighQuality = #QualityModeHigh
#SmoothingModeNone
#SmoothingModeAntiAlias
;#if (GDIPVER >= 0x0110)
#SmoothingModeAntiAlias8x4 = #SmoothingModeAntiAlias
#SmoothingModeAntiAlias8x8
;#endif //(GDIPVER >= 0x0110)
EndEnumeration
Enumeration ; InterpolationMode
#InterpolationModeInvalid = #QualityModeInvalid
#InterpolationModeDefault = #QualityModeDefault
#InterpolationModeLowQuality = #QualityModeLow
#InterpolationModeHighQuality = #QualityModeHigh
#InterpolationModeBilinear
#InterpolationModeBicubic
#InterpolationModeNearestNeighbor
#InterpolationModeHighQualityBilinear
#InterpolationModeHighQualityBicubic
EndEnumeration
Enumeration ; PixelOffsetMode
#PixelOffsetModeInvalid = #QualityModeInvalid
#PixelOffsetModeDefault = #QualityModeDefault
#PixelOffsetModeHighSpeed = #QualityModeLow
#PixelOffsetModeHighQuality = #QualityModeHigh
#PixelOffsetModeNone ; No pixel offset
#PixelOffsetModeHalf ; Offset by -0.5, -0.5 For fast anti-alias perf
EndEnumeration
Enumeration ; LineCap
#LineCapFlat = 0
#LineCapSquare = 1
#LineCapRound = 2
#LineCapTriangle = 3
#LineCapNoAnchor = $10 ; corresponds To flat cap
#LineCapSquareAnchor = $11 ; corresponds To square cap
#LineCapRoundAnchor = $12 ; corresponds To round cap
#LineCapDiamondAnchor = $13 ; corresponds To triangle cap
#LineCapArrowAnchor = $14 ; no correspondence
#LineCapCustom = $ff ; custom cap
#LineCapAnchorMask = $f0 ; mask To check For anchor Or Not.
EndEnumeration
Prototype.l GdiplusStartup(*token.Long, *input.GdiplusStartupInput, *output.GdiplusStartupOutput)
Prototype.l GdiplusShutdown(token.l)
Prototype.l GdipCreateFromHDC(*hDC, *graphics)
Prototype.l GdipDeleteGraphics(*graphics)
Prototype.l GdipGraphicsClear(*graphics, color.l)
Prototype.l GdipSetSmoothingMode (*graphics, smoothingMode.l)
Prototype.l GdipSetCompositingMode (*graphics, compositingMode.l)
Prototype.l GdipSetCompositingQuality (*graphics, compositingQuality.l)
Prototype.l GdipSetInterpolationMode (*graphics, interpolationMode.l)
Prototype.l GdipSetPixelOffsetMode (*graphics, pixelOffsetMode.l)
Prototype.l GdipCreatePen1 (color.l, Width.f, unit.l, *pen)
Prototype.l GdipDeletePen (*pen)
Prototype.l GdipSetPenStartCap(*pen, startCap.l)
Prototype.l GdipSetPenEndCap (*pen, endCap.l)
Prototype.l GdipCreateSolidFill(color.l, *brush)
Prototype.l GdipDeleteBrush(*brush)
Prototype.l GdipDrawRectangleI(*graphics, *pen , x.l , y.l , width.l, height.l)
Prototype.l GdipFillRectangleI(*graphics, *brush, x.l , y.l , width.l, height.l)
Prototype.l GdipDrawLineI (*graphics, *pen , x1.l, y1.l, x2.l , y2.l )
Prototype.l GdipDrawPieI (*graphics, *pen , x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipFillPieI (*graphics, *brush, x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipDrawArcI (*graphics, *pen , x.l , y.l , width.l, height.l, startAngle.f, sweepAngle.f)
Prototype.l GdipDrawEllipseI (*graphics, *pen , x.l , y.l , width.l, height.l)
Prototype.l GdipFillEllipseI (*graphics, *pen , x.l , y.l , width.l, height.l)
Prototype.l GdipDrawBezierI (*graphics, *pen , x1.l, y1.l, x2.l , y2.l , x3.l, y3.l, x4.l, y4.l)
Prototype.l GdipDrawPolygonI (*graphics, *pen , *points.POINT, count.l)
Prototype.l GdipFillPolygon2I (*graphics, *brush, *points.POINT, count.l)
Macro DoubleQuote
"
EndMacro
Macro setFunc(_name_)
Global _name_#_._name_
_name_#_ = GetFunction(__dll,DoubleQuote#_name_#DoubleQuote)
EndMacro
Macro toARGB(color)
( (color & $FF00FF00) | ( (color & $FF) << 16 ) | ((color >> 16) & $FF) )
EndMacro
Global __dll,__gdiplusToken.l,__drawingMode.l,__graphics,__lineCapStart,__lineCapEnd
Procedure gInit()
__dll = OpenLibrary(#PB_Any, "gdiplus.dll")
If Not __dll : ProcedureReturn 0 : EndIf
setFunc(GdiplusStartup)
setFunc(GdiplusShutdown)
setFunc(GdipCreateFromHDC)
setFunc(GdipDeleteGraphics)
setFunc(GdipGraphicsClear)
setFunc(GdipSetSmoothingMode)
setFunc(GdipSetCompositingMode)
setFunc(GdipSetCompositingQuality)
setFunc(GdipSetInterpolationMode)
setFunc(GdipSetPixelOffsetMode)
setFunc(GdipCreatePen1)
setFunc(GdipDeletePen)
setFunc(GdipSetPenStartCap)
setFunc(GdipSetPenEndCap)
setFunc(GdipCreateSolidFill)
setFunc(GdipDeleteBrush)
setFunc(GdipDrawRectangleI)
setFunc(GdipFillRectangleI)
setFunc(GdipDrawLineI)
setFunc(GdipDrawPieI)
SetFunc(GdipFillPieI)
setFunc(GdipDrawArcI)
setFunc(GdipDrawEllipseI)
SetFunc(GdipFillEllipseI)
SetFunc(GdipDrawBezierI)
SetFunc(GdipDrawPolygonI)
SetFunc(GdipFillPolygon2I)
; Initialize GDI+.
Protected gdiplusStartupInput.GdiplusStartupInput
gdiplusStartupInput\GdiplusVersion = 1
gdiplusStartupInput\DebugEventCallback = #Null
gdiplusStartupInput\SuppressBackgroundThread = #False
gdiplusStartupInput\SuppressExternalCodecs = #False
If Not GdiplusStartup_(@__gdiplusToken, @gdiplusStartupInput, #Null)
ProcedureReturn #True
EndIf
EndProcedure
Procedure gEnd()
GdiplusShutdown_(__gdiplusToken)
If __dll
CloseLibrary(__dll)
EndIf
EndProcedure
Procedure gStartDrawing( out )
Protected hDC
hDC = StartDrawing(out)
If Not hDC : ProcedureReturn 0 : EndIf
GdipCreateFromHDC_(hDC ,@__graphics)
If Not __graphics
StopDrawing()
ProcedureReturn 0
EndIf
__drawingMode = #PB_2DDrawing_Default
__lineCapStart = #LineCapFlat
__lineCapEnd = #LineCapFlat
GdipSetSmoothingMode_ (__graphics,#SmoothingModeAntiAlias8x8)
GdipSetCompositingMode_ (__graphics,#CompositingModeSourceOver)
GdipSetCompositingQuality_(__graphics,#CompositingQualityGammaCorrected)
GdipSetInterpolationMode_ (__graphics,#InterpolationModeHighQualityBicubic)
GdipSetPixelOffsetMode_ (__graphics,#PixelOffsetModeHighQuality)
ProcedureReturn hDC
EndProcedure
Procedure gStopDrawing()
If __graphics
GdipDeleteGraphics_( __graphics )
__graphics = 0
EndIf
StopDrawing()
EndProcedure
Procedure gDrawingMode( newMode.l )
__drawingMode = newMode
EndProcedure
Procedure gCapMode( lineCapStart.l, lineCapEnd.l )
__lineCapStart = lineCapStart
__lineCapEnd = lineCapEnd
EndProcedure
Procedure gAntiAliasMode( newMode.l )
If __graphics
GdipSetSmoothingMode_(__graphics,newMode)
EndIf
EndProcedure
Procedure gClear(color.l)
If __graphics
GdipGraphicsClear_(__graphics, toARGB(color))
EndIf
EndProcedure
Procedure gBox(x.l, y.l, width.l, height.l, color.l, penwidth.l=1)
If __graphics
If __drawingMode & #PB_2DDrawing_Outlined
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipDrawRectangleI_(__graphics,*pen,x,y,width,height)
GdipDeletePen_(*pen)
Else
Protected *brush
GdipCreateSolidFill_(toARGB(color),@*brush)
GdipFillRectangleI_(__graphics,*brush,x,y,width,height)
GdipDeleteBrush_(*brush)
EndIf
EndIf
EndProcedure
Procedure gLineXY(x1.l, y1.l, x2.l, y2.l, color.l, penwidth.l=1)
If __graphics
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipSetPenStartCap_(*pen, __lineCapStart)
GdipSetPenEndCap_ (*pen, __lineCapEnd )
GdipDrawLineI_(__graphics,*pen,x1,y1,x2,y2)
GdipDeletePen_(*pen)
EndIf
EndProcedure
Procedure gLine(x.l, y.l, width.l, height.l, color.l, penwidth.l=1)
gLineXY(x,y,x+width,y+height,color,penwidth)
EndProcedure
Procedure gPie(x.l, y.l, radiusX.l, radiusY.l, startAngle.f, sweepAngle.f, color.l, penwidth.l=1)
If __graphics
If __drawingMode & #PB_2DDrawing_Outlined
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipDrawPieI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
GdipDeletePen_(*pen)
Else
Protected *brush
GdipCreateSolidFill_(toARGB(color),@*brush)
GdipFillPieI_(__graphics,*brush,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
GdipDeleteBrush_(*brush)
EndIf
EndIf
EndProcedure
Procedure gArc(x.l, y.l, radiusX.l, radiusY.l, startAngle.f, sweepAngle.f, color.l, penwidth.l=1)
If __graphics
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipSetPenStartCap_(*pen, __lineCapStart)
GdipSetPenEndCap_ (*pen, __lineCapEnd )
GdipDrawArcI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2,startAngle,sweepAngle)
GdipDeletePen_(*pen)
EndIf
EndProcedure
Procedure gEllipse(x.l, y.l, radiusX.l, radiusY.l, color.l, penwidth.l=1)
If __graphics
If __drawingMode & #PB_2DDrawing_Outlined
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipDrawEllipseI_(__graphics,*pen,x-radiusX,y-radiusY,radiusX*2,radiusY*2)
GdipDeletePen_(*pen)
Else
Protected *brush
GdipCreateSolidFill_(toARGB(color),@*brush)
GdipFillEllipseI_(__graphics,*brush,x-radiusX,y-radiusY,radiusX*2,radiusY*2)
GdipDeleteBrush_(*brush)
EndIf
EndIf
EndProcedure
Procedure gCircle(x.l, y.l, radius.l, color.l, penwidth.l=1)
gEllipse(x,y,radius,radius,color,penwidth)
EndProcedure
Procedure gBezier(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l, x4.l, y4.l, color.l, penwidth.l=1)
If __graphics
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipSetPenStartCap_(*pen, __lineCapStart)
GdipSetPenEndCap_ (*pen, __lineCapEnd )
GdipDrawBezierI_(__graphics,*pen,x1,y1,x2,y2,x3,y3,x4,y4)
GdipDeletePen_(*pen)
EndIf
EndProcedure
Procedure gPoly(x1.l, y1.l, x2.l, y2.l, x3.l, y3.l, color.l, penwidth.l=1)
If __graphics
Dim points.POINT(3)
points(0)\x = x1
points(0)\y = y1
points(1)\x = x2
points(1)\y = y2
points(2)\x = x3
points(2)\y = y3
If __drawingMode & #PB_2DDrawing_Outlined
Protected *pen
GdipCreatePen1_(toARGB(color),penwidth,2,@*pen)
GdipDrawPolygonI_(__graphics,*pen,@points(),3)
GdipDeletePen_(*pen)
Else
Protected *brush
GdipCreateSolidFill_(toARGB(color),@*brush)
GdipFillPolygon2I_(__graphics,*brush,@points(),3)
GdipDeleteBrush_(*brush)
EndIf
EndIf
EndProcedure
;>----- END INCLUDE -----------------------------------------
;- Program
Global img, currentColor, drawMode
Global startPos.POINT
Global endPos.POINT
Global mainWin, imgWin, modeWin
Define i.l, mouseDown.l, copy
Global currentColor = RGBA($00,$00,$FF,$80)
Global currentPenSize = 15
Procedure redraw(image)
If gStartDrawing( ImageOutput(image) )
If image <> img
DrawImage(ImageID(img),0,0)
EndIf
gCapMode(#LineCapRound,#LineCapRound)
gDrawingMode(#PB_2DDrawing_Outlined)
Select drawMode
Case 0 : gLineXY(startPos\x,startPos\y,endPos\x,endPos\y,currentColor,currentPenSize)
Case 1 : gBox(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
Case 2 : gEllipse(startPos\x,startPos\y,endPos\x-startPos\x,endPos\y-startPos\y,currentColor,currentPenSize)
Case 3 : gCircle(startPos\x,startPos\y,endPos\x-startPos\x,currentColor,currentPenSize)
EndSelect
gStopDrawing()
If IsGadget(imgWin)
SetGadgetState(imgWin,ImageID(image))
EndIf
EndIf
EndProcedure
If gInit()
img = CreateImage(#PB_Any,850,600,24)
If gStartDrawing( ImageOutput(img) )
gClear( RGBA($80,$80,$80,$FF) )
gDrawingMode(#PB_2DDrawing_Outlined)
gBox(50,50,100,100,RGBA($40,$40,$40,$FF),5)
gLineXY(160,50,260,150,RGBA($00,$00,$FF,$FF),5)
gDrawingMode(#PB_2DDrawing_Default)
gPie(320,100,49,49,-90,110,RGBA($FF,$FF,$00,$FF))
gPie(320,100,49,49, 20, 50,RGBA($00,$FF,$FF,$FF))
gPie(320,100,49,49, 70, 60,RGBA($00,$00,$FF,$FF))
gDrawingMode(#PB_2DDrawing_Outlined)
gPie(320,100,50,50,-90,220,RGBA($00,$00,$00,$FF),3)
For i = 0 To 260 Step 20
gArc(430,100,50,50,-90+i,15,RGBA($00,$00,$00,$FF),3)
Next i
gDrawingMode(#PB_2DDrawing_Default)
gEllipse(540,100,50,25,RGBA($FF,$FF,$FF,$FF))
gCircle(540,100,25,RGBA($00,$FF,$00,$FF))
gCircle(540,100,10,RGBA($00,$00,$00,$FF))
gDrawingMode(#PB_2DDrawing_Outlined)
gEllipse(540,100,50,25,RGBA($00,$00,$00,$FF),2)
gCircle(540,100,25,RGBA($00,$00,$00,$FF),2)
gBezier(600,50,800,100,500,100,700,150,RGBA($00,$FF,$FF,$FF),2)
gPoly(710,50,730,150,780,80,RGBA($FF,$00,$FF,$FF),2)
gDrawingMode(#PB_2DDrawing_Default)
gBox(70,100,100,100,RGBA($00,$00,$00,$80))
gPie(340,150,50,50,-90,220,RGBA($00,$00,$00,$80))
gEllipse(570,150,50,25,RGBA($00,$00,$00,$80))
gPoly(730,100,750,200,800,130,RGBA($00,$00,$00,$80))
gCapMode(#LineCapRound,#LineCapArrowAnchor)
gLineXY(190,100,290,200,RGBA($00,$00,$00,$80),15)
For i = 0 To 260 Step 40
gArc(460,150,50,50,-90+i,30,RGBA($00,$00,$00,$80),7)
Next i
gBezier(620,100,820,150,520,150,720,200,RGBA($00,$00,$00,$80),7)
gStopDrawing()
EndIf
mainWin = OpenWindow(#PB_Any,0,0,850,620,"Draw!",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
modeWin = ComboBoxGadget(#PB_Any,0,600,100,20)
AddGadgetItem(modeWin,-1,"Line")
AddGadgetItem(modeWin,-1,"Box")
AddGadgetItem(modeWin,-1,"Ellipse")
AddGadgetItem(modeWin,-1,"Circle")
SetGadgetState(modeWin,0)
imgWin = ImageGadget(#PB_Any,0,00,850,600,ImageID(img))
DisableGadget(imgWin,1)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case modeWin : drawMode = GetGadgetState(modeWin)
EndSelect
Case #WM_LBUTTONDOWN
GetCursorPos_(@startPos)
ScreenToClient_(GadgetID(imgWin),@startPos)
If startPos\y < 600
SetCapture_(WindowID(mainWin))
mouseDown = 1
endPos\x = startPos\x+1
endPos\y = startPos\y+1
If copy : FreeImage(copy) : EndIf
copy = CopyImage(img,#PB_Any)
EndIf
Case #WM_LBUTTONUP
If mouseDown
ReleaseCapture_()
mouseDown = 0
redraw(img)
EndIf
Case #WM_MOUSEMOVE
If mouseDown
GetCursorPos_(@endPos)
ScreenToClient_(GadgetID(imgWin),@endPos)
redraw(copy)
EndIf
EndSelect
ForEver
gEnd()
EndIf
Linux Mint 21.1 Vera base: Ubuntu 22.04 jammy.
PureBasic 6.10 LTS (Linux - x64)
PureBasic 6.10 LTS (Linux - x64)