diff --git a/include/tools.bm b/include/tools.bm index 9930375..88d8e3e 100644 --- a/include/tools.bm +++ b/include/tools.bm @@ -238,6 +238,53 @@ sub ditheredgradient (x1 as long,y1 as long,x2 as long,y2 as long,fcol as _unsig exit sub end if + ' 3. Define a standard 4x4 Bayer Dithering Matrix (scaled 0 to 15) + dim bayer(3,3) as integer + bayer(0,0)=0:bayer(0,2)=8:bayer(0,1)=2:bayer(0,3)=10 + bayer(2,0)=12:bayer(2,2)=4:bayer(2,1)=14:bayer(2,3)=6 + bayer(1,0)=3:bayer(1,2)=11:bayer(1,1)=1:bayer(1,3)=9 + bayer(3,0)=15:bayer(3,2)=7:bayer(3,1)=13:bayer(3,3)=5 + + ' 4. Loop through every single pixel on the canvas layer + dim x as long,y as long + dim t as single + + for y=0 to canvash-1 + for x=0 to canvasw-1 + ' Project current pixel onto the line vector to get interpolation factor 't' + t=((x-x1)*dx+(y-y1)*dy)/linelensq + + ' Clamp t strictly between 0.0 and 1.0 + if t<0 then t=0 + if t>1 then t=1 + + ' Compare t directly against the normalized dither matrix value. + ' Adding 0.5 ensures pure fcol at t=0 and pure bcol at t=1 without edge bleeding. + if t >= (bayer(x mod 4, y mod 4) + 0.5) / 16.0 then + pset (x,y),bcol + else + pset (x,y),fcol + end if + next x + next y +end sub + +sub old_ditheredgradient (x1 as long,y1 as long,x2 as long,y2 as long,fcol as _unsigned long,bcol as _unsigned long) + ' 1. Get canvas boundaries from the active drawing layer + dim canvasw as integer:canvasw=_width(layers(1).ihandle) + dim canvash as integer:canvash=_height(layers(1).ihandle) + + ' 2. Calculate vector properties of the drawn line + dim dx as single:dx=x2-x1 + dim dy as single:dy=y2-y1 + dim linelensq as single:linelensq=(dx*dx)+(dy*dy) + + ' If the user didn't drag the mouse anywhere, just paint a solid pixel and exit + if linelensq=0 then + pset (x1,y1),fcol + exit sub + end if + ' 3. Extract RGB components of Foreground and Background colors dim fr as integer:fr=_red(fcol) dim fg as integer:fg=_green(fcol) diff --git a/pixler.bas b/pixler.bas index 885e2e0..c93f51b 100644 --- a/pixler.bas +++ b/pixler.bas @@ -238,6 +238,8 @@ sub redraw filledpolygon numarr(),state.fcolor case "floodfill" floodfill numarr(0),numarr(1),numarr(2) + case "gradient" + ditheredgradient numarr(0),numarr(1),numarr(2),numarr(3),state.fcolor,state.bcolor case "" ' blank line do nothing case else @@ -466,6 +468,8 @@ sub canvas do.floodfill canx,cany,drawcol case 10 do.eyedropper canx,cany + case 11 + do.gradient state.startx,state.starty,canx,cany end select end sub @@ -729,6 +733,26 @@ sub do.eyedropper(x as long,y as long) end if end sub +sub do.gradient(sx as long,sy as long,ex as long,ey as long) + dim osource as long + dim odest as long + if state.isdrawing then + osource=_source + odest=_dest + if mouseclicked or rmouseclicked then + _dest layers(1).ihandle + addcommand"gradient ("+tst(sx)+","+tst(sy)+","+tst(ex)+","+tst(ey)+")" + state.isdrawing=0 + ditheredgradient sx,sy,ex,ey,state.fcolor,state.bcolor + else + _dest layers(2).ihandle + thickline sx,sy,ex,ey,state.fcolor + end if + _source osource + _dest odest + end if +end sub + function icon (index as long) static init as integer static icons() as long diff --git a/test.pxl b/test.pxl new file mode 100644 index 0000000..74d84c7 --- /dev/null +++ b/test.pxl @@ -0,0 +1,4 @@ +canvas (1024,780) +fcolor (FF0D2B45) +bcolor (FFFFECD6) +gradient (85,74,200,137)