Working on interpretting the svg path commands. I got the easy ones done so far, straight lines lol. I've done bezier curve examples before so I think I can handle that one, but the arc is tricking me.
large-arc-flag and sweep-flag allows to chose which arc must be drawn as 4 possible arcs can be drawn out of the other parameters.
- large-arc-flag allows a choice of large arc (1) or small arc (0),
- sweep-flag allows a choice of a clockwise arc (1) or counterclockwise arc (0)
I think I understand the sweep-flag, but the large arc flag I can't understand what it does exactly. Looking at a
demo online I can see what it's doing but not how or why.
If anyone wants to help build this I welcome it. I have no real need for this, just thought it'd be fun to do. If completed, I'll incorporate my direct draw to memblock functions (written in DBP i'll have to convert them) and then the svg files can be loaded into an actual image.
// Project: svg
// Created: 2023-12-14
#option_explicit
SetErrorMode(2)
SetWindowTitle( "svg" )
SetWindowSize( 1024, 768, 0 )
SetVirtualResolution( 1024, 768 )
SetSyncRate( 0, 0 )
UseNewDefaultFonts( 1 )
svg as string // svg path
i as integer // for loop stuff
j as integer // for loop stuff
px as integer // path's current X position
py as integer // path's current Y position
cmd as string // command, a single letter
jCmd as string // command, a single letter
cmdParams as string // the parameters following the command character
cx as integer // end point X of current command operation
cy as integer // end point Y of current command operation
strokeColor as integer // path color
fx as integer // starting point X
fy as integer // starting point Y
setF as integer // flag to check if starting point set
sc as integer // stroke color to show close path command
sc = makeColor(0,255,0)
strokeColor = makeColor(255, 0, 0)
`svg = "M 10 10 h 10 m 0 10 h 10 m 0 10 h 10 M 40 20 h 10 m 0 10 h 10 m 0 10 h 10 m 0 10 h 10 M 50 50 h 10 m-20 10 h 10 m-20 10 h 10 m-20 10 h 10"
svg = "M 10,10 h 10 m 0,10 h 10 m 0,10 h 10 M 40,20 h 10 m 0,10 h 10 m 0,10 h 10 m 0,10 h 10 M 50,50 h 10 m-20,10 h 10 m-20,10 h 10 m-20,10 h 10"
svg = "M 110 10 l 80 80 v -80 h -40 Z"
do
for i = 1 to len(svg)
cmd = mid(svg, i, 1)
if (asc(cmd) >= 65 and asc(cmd) <= 90) or (asc(cmd) >= 97 and asc(cmd) <= 122) // command character
for j = i+1 to len(svg)
jCmd = mid(svg, j, 1)
if (asc(jCmd) >= 65 and asc(jCmd) <= 90) or (asc(jCmd) >= 97 and asc(jCmd) <= 122) // command character
exit
endif
next j
cmdParams = trimString(mid(svg, i+1, j-i-1), " ")
if cmd = "M" // set current point in world coordinates from origin ([0,0] by default)
px = val(GetStringToken(cmdParams, " ,", 1))
py = val(GetStringToken(cmdParams, " ,", 2))
endif
if cmd = "m" // set current point relative to current position
px = px + val(GetStringToken(cmdParams, " ,", 1))
py = py + val(GetStringToken(cmdParams, " ,", 2))
endif
if cmd = "l" // draw line from current point to relative position
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cx = val(GetStringToken(cmdParams, " ,", 1))
cy = val(GetStringToken(cmdParams, " ,", 2))
drawLine(px, py, px+cx, py+cy, strokeColor, strokeColor)
inc px, cx
inc py, cy
endif
if cmd = "L" // draw line from current point to world position
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cx = val(GetStringToken(cmdParams, " ,", 1))
cy = val(GetStringToken(cmdParams, " ,", 2))
drawLine(px, py, cx, cy, strokeColor, strokeColor)
px = cx
py = cy
endif
if cmd = "h" // draw a horizontal line from current position to relative end point (px + cx)
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cx = val(cmdParams)
drawLine(px, py, px+cx, py, strokeColor, strokeColor)
inc px, cx
endif
if cmd = "H" // horizontal line from current position to world position
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cx = val(cmdParams)
drawLine(px, py, cx, py, strokeColor, strokeColor)
px = cx
endif
if cmd = "v" // draw a vertical line from current position to relative end point (py + cy)
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cy = val(cmdParams)
drawLine(px, py, px, py+cy, strokeColor, strokeColor)
inc py, cy
endif
if cmd = "V" // vertical line from current position to world position
if setF = 0 : fx = px : fy = py : setF = 1 : endif
cy = val(cmdParams)
drawLine(px, py, px, cy, strokeColor, strokeColor)
py = cy
endif
if cmd = "Z" or cmd = "z" // close path
if px <> fx or py <> fy
drawLine(px, py, fx, fy, sc, sc)
endif
endif
endif
next i
Sync()
loop