111 lines
3.2 KiB
Go
111 lines
3.2 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"
|
|
)
|
|
|
|
func interpolateLinearGradient(self Gradient, overlap, blur float64, gradientSlices int, bb Rectangle[float64]) DrawPathList {
|
|
//items is max size 8 to 15 depending on SWF version
|
|
|
|
height0 := GradientBoundsMin.Float64()
|
|
height1 := GradientBoundsMax.Float64()
|
|
|
|
switch self.SpreadMode {
|
|
case swfsubtypes.GradientSpreadPad:
|
|
height0 = min(height0, bb.TopLeft.Y)
|
|
height1 = max(height1, bb.BottomRight.Y)
|
|
}
|
|
|
|
topLeft0 := math.NewVector2(GradientBoundsMin.Float64(), height0)
|
|
topLeft1 := math.NewVector2(GradientBoundsMax.Float64(), height0)
|
|
bottomRight0 := math.NewVector2(GradientBoundsMin.Float64(), height1)
|
|
bottomRight1 := math.NewVector2(GradientBoundsMax.Float64(), height1)
|
|
|
|
//TODO: more spreadMode, generalize
|
|
|
|
vOverlap := math.NewVector2(overlap, 0).Divide(2)
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
var paths DrawPathList
|
|
for _, item := range items {
|
|
if item.Start == 0 {
|
|
switch self.SpreadMode {
|
|
case swfsubtypes.GradientSpreadPad:
|
|
if bb.TopLeft.X < topLeft0.X {
|
|
paths = append(paths, DrawPathFill(
|
|
&FillStyleRecord{
|
|
Fill: item.Color,
|
|
Blur: blur,
|
|
},
|
|
Rectangle[float64]{
|
|
TopLeft: math.NewVector2(bb.TopLeft.X, height0),
|
|
BottomRight: math.NewVector2(topLeft0.X, height1).AddVector(vOverlap),
|
|
}.Draw(),
|
|
))
|
|
}
|
|
}
|
|
}
|
|
paths = append(paths, DrawPathFill(
|
|
&FillStyleRecord{
|
|
Fill: item.Color,
|
|
Blur: blur,
|
|
},
|
|
Rectangle[float64]{
|
|
TopLeft: math.LerpVector2(topLeft0, topLeft1, item.Start).SubVector(vOverlap),
|
|
BottomRight: math.LerpVector2(bottomRight0, bottomRight1, item.End).AddVector(vOverlap),
|
|
}.Draw(),
|
|
))
|
|
if item.End == 1 {
|
|
switch self.SpreadMode {
|
|
case swfsubtypes.GradientSpreadPad:
|
|
if bb.BottomRight.X > bottomRight1.X {
|
|
paths = append(paths, DrawPathFill(
|
|
&FillStyleRecord{
|
|
Fill: item.Color,
|
|
Blur: blur,
|
|
},
|
|
Rectangle[float64]{
|
|
TopLeft: math.NewVector2(topLeft1.X, height0).SubVector(vOverlap),
|
|
BottomRight: math.NewVector2(bb.BottomRight.X, height1),
|
|
}.Draw(),
|
|
))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return paths
|
|
}
|
|
|
|
func LinearGradientFromSWF(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,
|
|
Transform: math.MatrixTransformFromSWF(transform, 1),
|
|
SpreadMode: spreadMode,
|
|
InterpolationMode: interpolationMode,
|
|
Interpolation: interpolateLinearGradient,
|
|
}
|
|
}
|