102 lines
2.7 KiB
Go
102 lines
2.7 KiB
Go
package shapes
|
|
|
|
import (
|
|
swfsubtypes "git.gammaspectra.live/WeebDataHoarder/swf-go/subtypes"
|
|
"git.gammaspectra.live/WeebDataHoarder/swf-go/types"
|
|
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/settings"
|
|
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
|
|
math2 "math"
|
|
)
|
|
|
|
func interpolateRadialGradient(self Gradient, overlap, blur float64, gradientSlices int, bb Rectangle[float64]) DrawPathList {
|
|
//items is max size 8 to 15 depending on SWF version
|
|
size := GradientBounds.Width()
|
|
|
|
//TODO spreadMode
|
|
|
|
items := self.Interpolate(gradientSlices)
|
|
|
|
if !settings.GlobalSettings.GradientApplyOverlapOnTransparency {
|
|
for _, i := range items {
|
|
if i.Color.Alpha != 255 {
|
|
//transparency! remove overlaps
|
|
blur = 0
|
|
overlap = 0
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
radius := size / 2
|
|
|
|
var maxRadius float64
|
|
|
|
switch self.SpreadMode {
|
|
case swfsubtypes.GradientSpreadPad:
|
|
r := max(math2.Abs(bb.TopLeft.X), math2.Abs(bb.TopLeft.Y), math2.Abs(bb.BottomRight.X), math2.Abs(bb.BottomRight.Y))
|
|
maxRadius = math.NewVector2(r, r).Length()
|
|
}
|
|
|
|
center := math.NewVector2[float64](0, 0)
|
|
|
|
var paths DrawPathList
|
|
for _, item := range items {
|
|
//Create concentric circles to cut out a shape
|
|
var shape Shape
|
|
radiusStart := math.Lerp(0, radius, item.Start) - overlap/4
|
|
radiusEnd := math.Lerp(0, radius, item.End) + overlap/4
|
|
start := NewCircle(center, radiusStart).Draw()
|
|
if radiusStart <= 0 {
|
|
start = nil
|
|
}
|
|
end := NewCircle(center, radiusEnd).Draw()
|
|
shape = append(shape, end...)
|
|
shape = append(shape, start.Reverse()...)
|
|
paths = append(paths, DrawPathFill(
|
|
&FillStyleRecord{
|
|
Fill: item.Color,
|
|
Blur: blur,
|
|
},
|
|
shape,
|
|
))
|
|
if item.End == 1 {
|
|
if maxRadius > radius {
|
|
var shape Shape
|
|
start := NewCircle(center, radiusEnd).Draw()
|
|
if radiusEnd <= 0 {
|
|
start = nil
|
|
}
|
|
end := NewCircle(center, maxRadius).Draw()
|
|
shape = append(shape, end...)
|
|
shape = append(shape, start.Reverse()...)
|
|
paths = append(paths, DrawPathFill(
|
|
&FillStyleRecord{
|
|
Fill: item.Color,
|
|
Blur: blur,
|
|
},
|
|
shape,
|
|
))
|
|
}
|
|
}
|
|
}
|
|
return paths
|
|
}
|
|
|
|
func RadialGradientFromSWF(records []swfsubtypes.GRADRECORD, transform types.MATRIX, spreadMode swfsubtypes.GradientSpreadMode, interpolationMode swfsubtypes.GradientInterpolationMode) Gradient {
|
|
items := make([]GradientItem, 0, len(records))
|
|
for _, r := range records {
|
|
items = append(items, GradientItemFromSWF(r.Ratio, r.Color))
|
|
}
|
|
|
|
//TODO: interpolationMode, spreadMode
|
|
|
|
return Gradient{
|
|
Records: items,
|
|
//TODO: do we need to scale this to pixel world from twips?
|
|
Transform: math.MatrixTransformFromSWF(transform, 1),
|
|
SpreadMode: spreadMode,
|
|
InterpolationMode: interpolationMode,
|
|
Interpolation: interpolateRadialGradient,
|
|
}
|
|
}
|