raw-buffer-api #1

Merged
sashakoshka merged 9 commits from raw-buffer-api into main 2023-01-14 19:04:35 -07:00
8 changed files with 115 additions and 284 deletions
Showing only changes of commit e83dde2d21 - Show all commits

View File

@ -1,116 +1,30 @@
package artist package artist
import "image"
import "image/color" import "image/color"
import "git.tebibyte.media/sashakoshka/tomo"
// ShadingProfile contains shading information that can be used to draw chiseled // Chiseled is a pattern that has a highlight section and a shadow section.
// objects. type Chiseled struct {
type ShadingProfile struct { Highlight Pattern
Highlight Pattern Shadow Pattern
Shadow Pattern
Stroke Pattern
Fill Pattern
StrokeWeight int
ShadingWeight int
} }
// Engraved reverses the shadown and highlight colors of the ShadingProfile to // AtWhen satisfies the Pattern interface.
// produce a new ShadingProfile with an engraved appearance. func (chiseled Chiseled) AtWhen (x, y, width, height int) (c color.RGBA) {
func (profile ShadingProfile) Engraved () (reversed ShadingProfile) { var highlighted bool
reversed = profile // FIXME: this doesn't work quite right, the
reversed.Highlight = profile.Shadow // slope of the line is somewhat off.
reversed.Shadow = profile.Highlight bottomCorner :=
return float64(x) < float64(y) *
} (float64(width) / float64(height))
if bottomCorner {
// ChiseledRectangle draws a rectangle with a chiseled/embossed appearance, highlighted = float64(x) < float64(height) - float64(y)
// according to the ShadingProfile passed to it. } else {
func ChiseledRectangle ( highlighted = float64(width) - float64(x) > float64(y)
destination tomo.Canvas,
profile ShadingProfile,
bounds image.Rectangle,
) (
updatedRegion image.Rectangle,
) {
// FIXME: this breaks when the bounds are smaller than the border or
// shading weight
stroke := profile.Stroke
highlight := profile.Highlight
shadow := profile.Shadow
fill := profile.Fill
strokeWeight := profile.StrokeWeight
shadingWeight := profile.ShadingWeight
data, stride := destination.Buffer()
bounds = bounds.Canon()
updatedRegion = bounds
strokeWeightVector := image.Point { strokeWeight, strokeWeight }
shadingWeightVector := image.Point { shadingWeight, shadingWeight }
shadingBounds := bounds
shadingBounds.Min = shadingBounds.Min.Add(strokeWeightVector)
shadingBounds.Max = shadingBounds.Max.Sub(strokeWeightVector)
shadingBounds = shadingBounds.Canon()
fillBounds := shadingBounds
fillBounds.Min = fillBounds.Min.Add(shadingWeightVector)
fillBounds.Max = fillBounds.Max.Sub(shadingWeightVector)
fillBounds = fillBounds.Canon()
width := float64(bounds.Dx())
height := float64(bounds.Dy())
yy := 0
for y := bounds.Min.Y; y < bounds.Max.Y; y ++ {
xx := 0
for x := bounds.Min.X; x < bounds.Max.X; x ++ {
var pixel color.RGBA
point := image.Point { x, y }
switch {
case point.In(fillBounds):
pixel = fill.AtWhen (
xx - strokeWeight - shadingWeight,
yy - strokeWeight - shadingWeight,
fillBounds.Dx(), fillBounds.Dy())
case point.In(shadingBounds):
var highlighted bool
// FIXME: this doesn't work quite right, the
// slope of the line is somewhat off.
bottomCorner :=
float64(xx) < float64(yy) *
(width / height)
if bottomCorner {
highlighted =
float64(xx) <
height - float64(yy)
} else {
highlighted =
width - float64(xx) >
float64(yy)
}
shadingSource := shadow
if highlighted {
shadingSource = highlight
}
pixel = shadingSource.AtWhen (
xx - strokeWeight,
yy - strokeWeight,
shadingBounds.Dx(),
shadingBounds.Dy())
default:
pixel = stroke.AtWhen (
xx, yy, bounds.Dx(), bounds.Dy())
}
data[x + y * stride] = pixel
xx ++
}
yy ++
} }
return if highlighted {
return chiseled.Highlight.AtWhen(x, y, width, height)
} else {
return chiseled.Shadow.AtWhen(x, y, width, height)
}
} }

View File

@ -3,6 +3,7 @@ package artist
import "image" import "image"
import "image/color" import "image/color"
// Border represents a border that can be fed to MultiBorder.
type Border struct { type Border struct {
Weight int Weight int
Stroke Pattern Stroke Pattern