Better stroke width based on matrix?

This commit is contained in:
DataHoarder 2023-11-24 09:59:01 +01:00
parent 116c3b5b56
commit 6ab2e3ddae
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
25 changed files with 176 additions and 113 deletions

View file

@ -37,8 +37,8 @@ func NewRenderer(frameRate float64, display shapes.Rectangle[float64]) *Renderer
"; https://git.gammaspectra.live/WeebDataHoarder/swf2ass-go",
"Title: swf2ass",
"ScriptType: v4.00+",
"; TODO: maybe set WrapStyle: 2",
"WrapStyle: 0",
//TODO: WrapStyle: 0 or 2?
"WrapStyle: 2",
"ScaledBorderAndShadow: yes",
"YCbCr Matrix: PC.709",
fmt.Sprintf("PlayResX: %d", width),

View file

@ -3,6 +3,7 @@ package tag
import (
"fmt"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/shapes"
)
@ -10,7 +11,7 @@ type BlurGaussianTag struct {
Blur float64
}
func (t *BlurGaussianTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *BlurGaussianTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
if lineStyleRecord, ok := record.(*shapes.LineStyleRecord); ok {
t.Blur = lineStyleRecord.Blur
} else if fillStyleRecord, ok := record.(*shapes.FillStyleRecord); ok {
@ -21,9 +22,9 @@ func (t *BlurGaussianTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
return t
}
func (t *BlurGaussianTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *BlurGaussianTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &BlurGaussianTag{}
t2.FromStyleRecord(record)
t2.FromStyleRecord(record, transform)
return t2
}

View file

@ -3,6 +3,7 @@ package tag
import (
"fmt"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/shapes"
)
@ -10,7 +11,7 @@ type BlurTag struct {
Blur int64
}
func (t *BlurTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *BlurTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
if lineStyleRecord, ok := record.(*shapes.LineStyleRecord); ok {
t.Blur = int64(lineStyleRecord.Blur)
} else if fillStyleRecord, ok := record.(*shapes.FillStyleRecord); ok {
@ -21,9 +22,9 @@ func (t *BlurTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
return t
}
func (t *BlurTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *BlurTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &BlurTag{}
t2.FromStyleRecord(record)
t2.FromStyleRecord(record, transform)
return t2
}

View file

@ -5,26 +5,29 @@ import (
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/shapes"
"strconv"
)
type BorderTag struct {
Size math.Vector2[float64]
}
func (t *BorderTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *BorderTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
if lineStyleRecord, ok := record.(*shapes.LineStyleRecord); ok {
t.Size = math.NewVector2(lineStyleRecord.Width, lineStyleRecord.Width)
w := lineStyleRecord.StrokeWidth(transform)
t.Size = math.NewVector2(w, w)
} else if fillStyleRecord, ok := record.(*shapes.FillStyleRecord); ok && fillStyleRecord.Border != nil {
t.Size = math.NewVector2(fillStyleRecord.Border.Width, fillStyleRecord.Border.Width)
w := fillStyleRecord.Border.StrokeWidth(transform)
t.Size = math.NewVector2(w, w)
} else {
t.Size = math.NewVector2[float64](0, 0)
}
return t
}
func (t *BorderTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *BorderTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &BorderTag{}
t2.FromStyleRecord(record)
t2.FromStyleRecord(record, transform)
return t2
}
@ -40,8 +43,8 @@ func (t *BorderTag) Encode(event time.EventTime) string {
if t.Size.X == 0 {
return "\\bord0"
}
return fmt.Sprintf("\\bord%.02F", t.Size.X)
return fmt.Sprintf("\\bord%s", strconv.FormatFloat(t.Size.X, 'f', -1, 64))
} else {
return fmt.Sprintf("\\xbord%.02F\\ybord%.02F", t.Size.X, t.Size.Y)
return fmt.Sprintf("\\xbord%s\\ybord%s", strconv.FormatFloat(t.Size.X, 'f', -1, 64), strconv.FormatFloat(t.Size.Y, 'f', -1, 64))
}
}

View file

@ -69,14 +69,14 @@ func (t *ContainerTag) TransitionMatrixTransform(event Event, transform math.Mat
return container
}
func (t *ContainerTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *ContainerTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
container := t.Clone(false)
index := event.GetEnd() - event.GetStart()
for _, tag := range container.Tags {
if colorTag, ok := tag.(StyleTag); ok {
newTag := colorTag.TransitionStyleRecord(event, record)
newTag := colorTag.TransitionStyleRecord(event, record, transform)
if newTag == nil {
return nil
}
@ -134,7 +134,7 @@ func (t *ContainerTag) FromMatrixTransform(transform math.MatrixTransform) Posit
panic("not supported")
}
func (t *ContainerTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *ContainerTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
panic("not supported")
}
@ -293,36 +293,31 @@ func ContainerTagFromPathEntry(path shapes.DrawPath, clip *shapes.ClipPath, colo
return nil
}
container.TryAppend((&BorderTag{}).FromStyleRecord(path.Style))
if bakeMatrixTransforms {
container.BakeTransforms = &matrixTransform
container.TryAppend((&PositionTag{}).FromMatrixTransform(matrixTransform))
} else {
container.TryAppend((&PositionTag{}).FromMatrixTransform(matrixTransform))
container.TryAppend((&MatrixTransformTag{}).FromMatrixTransform(matrixTransform))
}
container.TryAppend((&BlurGaussianTag{}).FromStyleRecord(path.Style))
container.TryAppend((&BorderTag{}).FromStyleRecord(path.Style, matrixTransform))
container.TryAppend((&BlurGaussianTag{}).FromStyleRecord(path.Style, matrixTransform))
{
lineColorTag := &LineColorTag{}
lineColorTag.FromStyleRecord(path.Style)
lineColorTag.FromStyleRecord(path.Style, matrixTransform)
container.TryAppend(lineColorTag.ApplyColorTransform(colorTransform))
}
{
fillColorTag := &FillColorTag{}
fillColorTag.FromStyleRecord(path.Style)
fillColorTag.FromStyleRecord(path.Style, matrixTransform)
container.TryAppend(fillColorTag.ApplyColorTransform(colorTransform))
}
if bakeMatrixTransforms {
container.BakeTransforms = &matrixTransform
container.TryAppend((&PositionTag{}).FromMatrixTransform(matrixTransform))
drawTag := DrawingTag(NewDrawTag(path.Commands, settings.GlobalSettings.ASSDrawingScale))
container.TryAppend(drawTag)
} else {
container.TryAppend((&PositionTag{}).FromMatrixTransform(matrixTransform))
container.TryAppend((&MatrixTransformTag{}).FromMatrixTransform(matrixTransform))
container.TryAppend(NewDrawTag(path.Commands, settings.GlobalSettings.ASSDrawingScale))
}
container.TryAppend(NewDrawTag(path.Commands, settings.GlobalSettings.ASSDrawingScale))
return container
}

View file

@ -12,7 +12,7 @@ type FillColorTag struct {
OriginalColor *math.Color
}
func (t *FillColorTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *FillColorTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
if fillStyleRecord, ok := record.(*shapes.FillStyleRecord); ok {
if color, ok := fillStyleRecord.Fill.(math.Color); ok {
t.Color = &color
@ -27,9 +27,9 @@ func (t *FillColorTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
return t
}
func (t *FillColorTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
t2 := &LineColorTag{}
t2.FromStyleRecord(record)
func (t *FillColorTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &FillColorTag{}
t2.FromStyleRecord(record, transform)
return t2
}

View file

@ -12,7 +12,7 @@ type LineColorTag struct {
OriginalColor *math.Color
}
func (t *LineColorTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *LineColorTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
if lineStyleRecord, ok := record.(*shapes.LineStyleRecord); ok {
t.Color = &lineStyleRecord.Color
t.OriginalColor = &lineStyleRecord.Color
@ -26,9 +26,9 @@ func (t *LineColorTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
return t
}
func (t *LineColorTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *LineColorTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &LineColorTag{}
t2.FromStyleRecord(record)
t2.FromStyleRecord(record, transform)
return t2
}

View file

@ -90,10 +90,10 @@ func (t *PositionTag) Encode(event time.EventTime) string {
start = event.GetDurationFromStartOffset(t.Start).Milliseconds() - 1
end = event.GetDurationFromStartOffset(t.Start).Milliseconds()
}
return fmt.Sprintf("\\move(%s,%s,%s,%s,%d,%d)", strconv.FormatFloat(t.From.X, 'f', 0, 64), strconv.FormatFloat(t.From.Y, 'f', 0, 64), strconv.FormatFloat(t.To.X, 'f', 0, 64), strconv.FormatFloat(t.To.Y, 'f', 0, 64), start, end)
return fmt.Sprintf("\\move(%s,%s,%s,%s,%d,%d)", strconv.FormatFloat(t.From.X, 'f', -1, 64), strconv.FormatFloat(t.From.Y, 'f', -1, 64), strconv.FormatFloat(t.To.X, 'f', -1, 64), strconv.FormatFloat(t.To.Y, 'f', -1, 64), start, end)
}
return fmt.Sprintf("\\pos(%s,%s)", strconv.FormatFloat(t.From.X, 'f', 0, 64), strconv.FormatFloat(t.From.Y, 'f', 0, 64))
return fmt.Sprintf("\\pos(%s,%s)", strconv.FormatFloat(t.From.X, 'f', -1, 64), strconv.FormatFloat(t.From.Y, 'f', -1, 64))
}
func (t *PositionTag) Equals(tag Tag) bool {

View file

@ -4,6 +4,7 @@ import (
"fmt"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"strconv"
)
type ScaleTag struct {
@ -16,7 +17,7 @@ func (t *ScaleTag) TransitionMatrixTransform(event Event, transform math.MatrixT
func (t *ScaleTag) Encode(event time.EventTime) string {
//TODO: precision?
return fmt.Sprintf("\\fscx%.5F\\fscy%.5F", t.Scale.X, t.Scale.Y)
return fmt.Sprintf("\\fscx%s\\fscy%s", strconv.FormatFloat(t.Scale.X, 'f', -1, 64), strconv.FormatFloat(t.Scale.Y, 'f', -1, 64))
}
func (t *ScaleTag) Equals(tag Tag) bool {

View file

@ -3,6 +3,7 @@ package tag
import (
"fmt"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/shapes"
)
@ -10,15 +11,15 @@ type ShadowTag struct {
Depth float64
}
func (t *ShadowTag) FromStyleRecord(record shapes.StyleRecord) StyleTag {
func (t *ShadowTag) FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
//TODO?
t.Depth = 0
return t
}
func (t *ShadowTag) TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag {
func (t *ShadowTag) TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag {
t2 := &ShadowTag{}
t2.FromStyleRecord(record)
t2.FromStyleRecord(record, transform)
return t2
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/ass/time"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"strconv"
)
type ShearingTag struct {
@ -16,7 +17,7 @@ func (t *ShearingTag) TransitionMatrixTransform(event Event, transform math.Matr
func (t *ShearingTag) Encode(event time.EventTime) string {
//TODO: precision?
return fmt.Sprintf("\\fax%.5F\\fay%.5F", t.Shear.X, t.Shear.Y)
return fmt.Sprintf("\\fax%s\\fay%s", strconv.FormatFloat(t.Shear.X, 'f', -1, 64), strconv.FormatFloat(t.Shear.Y, 'f', -1, 64))
}
func (t *ShearingTag) Equals(tag Tag) bool {

View file

@ -18,8 +18,8 @@ type Event interface {
type StyleTag interface {
Tag
TransitionStyleRecord(event Event, record shapes.StyleRecord) StyleTag
FromStyleRecord(record shapes.StyleRecord) StyleTag
TransitionStyleRecord(event Event, record shapes.StyleRecord, transform math.MatrixTransform) StyleTag
FromStyleRecord(record shapes.StyleRecord, transform math.MatrixTransform) StyleTag
}
type PositioningTag interface {

View file

@ -92,6 +92,7 @@ func (d *MorphShapeDefinition) GetShapeList(ratio float64) (list shapes.DrawPath
list = append(list, shapes.DrawPathStroke(&shapes.LineStyleRecord{
Width: math2.Lerp(c1LineStyle.Width, c2LineStyle.Width, ratio),
Color: math2.LerpColor(c1LineStyle.Color, c2LineStyle.Color, ratio),
//TODO: blur
}, &shape, nil))
} else {
panic("unsupported")

View file

@ -120,6 +120,16 @@ func (m MatrixTransform) GetMatrix() mat.Matrix {
return m.matrix
}
// MinimumStrokeWidth
// Given a matrix, calculates the scale for stroke widths.
// TODO: Verify the actual behavior; I think it's more like the average between scaleX and scaleY.
// Does not yet support vertical/horizontal stroke scaling flags.
func (m MatrixTransform) MinimumStrokeWidth() float64 {
sx := math.Sqrt(m.GetA()*m.GetA() + m.GetB()*m.GetB())
sy := math.Sqrt(m.GetC()*m.GetC() + m.GetD()*m.GetD())
return max(sx, sy)
}
func (m MatrixTransform) GetMatrixWithoutTranslation() mat.Matrix {
return m.matrix.Slice(0, 2, 0, 2)
}

View file

@ -106,6 +106,16 @@ func (v Vector2[T]) SubVector(b Vector2[T]) Vector2[T] {
}
}
func (v Vector2[T]) Normals() (a, b Vector2[T]) {
return Vector2[T]{
X: -v.Y,
Y: v.X,
}, Vector2[T]{
X: v.Y,
Y: -v.X,
}
}
func (v Vector2[T]) Abs() Vector2[T] {
x := v.X
if x < 0 {

View file

@ -6,7 +6,7 @@ import (
)
type ActivePath struct {
Segment PathSegment
Segment PathSegment[types.Twip]
StyleId int
}
@ -17,7 +17,7 @@ func NewActivePath(styleId int, start math.Vector2[types.Twip]) *ActivePath {
}
}
func (p *ActivePath) AddPoint(point VisitedPoint) {
func (p *ActivePath) AddPoint(point VisitedPoint[types.Twip]) {
p.Segment.AddPoint(point)
}

View file

@ -22,6 +22,20 @@ func (p DrawPath) ApplyMatrixTransform(transform math.MatrixTransform, applyTran
}
}
func (p DrawPath) ApplyColorTransform(transform math.ColorTransform) (r DrawPath) {
if p.Clip == nil {
return DrawPath{
Style: p.Style.ApplyColorTransform(transform),
Commands: p.Commands,
}
}
return DrawPath{
Style: p.Style.ApplyColorTransform(transform),
Commands: p.Commands,
Clip: p.Clip,
}
}
func DrawPathFill(record *FillStyleRecord, shape *Shape, clip *ClipPath) DrawPath {
return DrawPath{
Style: record,

View file

@ -42,11 +42,8 @@ func (l DrawPathList) Fill(shape *Shape) (r DrawPathList) {
func (l DrawPathList) ApplyColorTransform(transform math.ColorTransform) Fillable {
r := make(DrawPathList, 0, len(l))
for _, e := range l {
r = append(r, DrawPath{
Style: e.Style.ApplyColorTransform(transform),
Commands: e.Commands,
})
for i := range l {
r = append(r, l[i].ApplyColorTransform(transform))
}
return r
}

View file

@ -0,0 +1,29 @@
package shapes
import (
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
)
type LineStyleRecord struct {
Width float64
Color math.Color
Blur float64
}
func (r *LineStyleRecord) StrokeWidth(transform math.MatrixTransform) float64 {
// Flash renders strokes with a 1px minimum width.
minWidth := transform.MinimumStrokeWidth()
return 0.5 * max(r.Width, minWidth)
}
func (r *LineStyleRecord) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord {
return r
}
func (r *LineStyleRecord) ApplyColorTransform(transform math.ColorTransform) StyleRecord {
return &LineStyleRecord{
Width: r.Width,
Color: transform.ApplyToColor(r.Color),
Blur: r.Blur,
}
}

View file

@ -1,17 +1,16 @@
package shapes
import (
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/swf/types"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/records"
"slices"
)
type PathSegment []VisitedPoint
type PathSegment[T ~float64 | ~int64] []VisitedPoint[T]
func NewPathSegment(start math.Vector2[types.Twip]) PathSegment {
return PathSegment{
VisitedPoint{
func NewPathSegment[T ~float64 | ~int64](start math.Vector2[T]) PathSegment[T] {
return PathSegment[T]{
VisitedPoint[T]{
Pos: start,
IsBezierControl: false,
},
@ -23,39 +22,39 @@ func NewPathSegment(start math.Vector2[types.Twip]) PathSegment {
// Flash fill paths are dual-sided, with fill style 1 indicating the positive side
// and fill style 0 indicating the negative. We have to flip fill style 0 paths
// in order to link them to fill style 1 paths.
func (s *PathSegment) Flip() {
func (s *PathSegment[T]) Flip() {
slices.Reverse(*s)
}
func (s *PathSegment) AddPoint(p VisitedPoint) {
func (s *PathSegment[T]) AddPoint(p VisitedPoint[T]) {
*s = append(*s, p)
}
func (s *PathSegment) Start() math.Vector2[types.Twip] {
func (s *PathSegment[T]) Start() math.Vector2[T] {
return (*s)[0].Pos
}
func (s *PathSegment) End() math.Vector2[types.Twip] {
func (s *PathSegment[T]) End() math.Vector2[T] {
return (*s)[len(*s)-1].Pos
}
func (s *PathSegment) IsEmpty() bool {
func (s *PathSegment[T]) IsEmpty() bool {
return len(*s) <= 1
}
func (s *PathSegment) IsClosed() bool {
func (s *PathSegment[T]) IsClosed() bool {
return s.Start().Equals(s.End())
}
func (s *PathSegment) Swap(o *PathSegment) {
func (s *PathSegment[T]) Swap(o *PathSegment[T]) {
*s, *o = *o, *s
}
func (s *PathSegment) Merge(o PathSegment) {
func (s *PathSegment[T]) Merge(o PathSegment[T]) {
*s = append(*s, o[1:]...)
}
func (s *PathSegment) TryMerge(o *PathSegment, isDirected bool) bool {
func (s *PathSegment[T]) TryMerge(o *PathSegment[T], isDirected bool) bool {
if o.End().Equals(s.Start()) {
s.Swap(o)
s.Merge(*o)
@ -77,7 +76,7 @@ func (s *PathSegment) TryMerge(o *PathSegment, isDirected bool) bool {
return false
}
func (s *PathSegment) GetShape() *Shape {
func (s *PathSegment[T]) GetShape() *Shape {
if s.IsEmpty() {
panic("not possible")
}
@ -88,7 +87,7 @@ func (s *PathSegment) GetShape() *Shape {
points := *s
next := func() VisitedPoint {
next := func() VisitedPoint[T] {
point := points[0]
points = points[1:]
return point

View file

@ -1,21 +1,24 @@
package shapes
import "slices"
import (
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/swf/types"
"slices"
)
type PendingPathMap map[int]*PendingPath
type PendingPathMap map[int]*PendingPath[types.Twip]
func (m PendingPathMap) MergePath(p *ActivePath, directed bool) {
if _, ok := m[p.StyleId]; !ok {
m[p.StyleId] = &PendingPath{}
m[p.StyleId] = &PendingPath[types.Twip]{}
}
m[p.StyleId].MergePath(&p.Segment, directed)
}
type PendingPath []*PathSegment
type PendingPath[T ~float64 | ~int64] []*PathSegment[T]
func (p *PendingPath) MergePath(newSegment *PathSegment, directed bool) {
func (p *PendingPath[T]) MergePath(newSegment *PathSegment[T], directed bool) {
if !newSegment.IsEmpty() {
var merged *PathSegment
var merged *PathSegment[T]
for i, segment := range *p {
if segment.TryMerge(newSegment, directed) {
@ -33,7 +36,7 @@ func (p *PendingPath) MergePath(newSegment *PathSegment, directed bool) {
}
}
func (p *PendingPath) GetShape() *Shape {
func (p *PendingPath[T]) GetShape() *Shape {
shape := &Shape{}
for _, segment := range *p {
shape = shape.Merge(segment.GetShape())

View file

@ -246,7 +246,7 @@ func (c *ShapeConverter) HandleNode(node subtypes.SHAPERECORD) {
}
func (c *ShapeConverter) VisitPoint(pos math.Vector2[types.Twip], isBezierControlPoint bool) {
point := VisitedPoint{
point := VisitedPoint[types.Twip]{
Pos: pos,
IsBezierControl: isBezierControlPoint,
}
@ -322,7 +322,7 @@ func (c *ShapeConverter) FlushLayer() {
//wrap around all segments, even if closed. ASS does NOT like them otherwise. so we draw everything backwards to have border around the line, not just on one side
//TODO: using custom line borders later using fills this can be removed
var newSegments PendingPath
var newSegments PendingPath[types.Twip]
for _, segment := range *path {
other := slices.Clone(*segment)
other.Flip()

View file

@ -34,7 +34,7 @@ func StyleListFromSWFItems(collection ObjectCollection, fillStyles subtypes.FILL
for _, s := range lineStyles.LineStyles {
r.LineStyles = append(r.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.Width), types.TwipFactor).Float64(),
Width: types.Twip(s.Width).Float64(),
Color: math.Color{
R: s.Color.R(),
G: s.Color.G(),
@ -48,7 +48,7 @@ func StyleListFromSWFItems(collection ObjectCollection, fillStyles subtypes.FILL
if !s.Flag.HasFill {
r.LineStyles = append(r.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.Width), types.TwipFactor).Float64(),
Width: types.Twip(s.Width).Float64(),
Color: math.Color{
R: s.Color.R(),
G: s.Color.G(),
@ -62,7 +62,7 @@ func StyleListFromSWFItems(collection ObjectCollection, fillStyles subtypes.FILL
case types.Color:
r.LineStyles = append(r.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.Width), types.TwipFactor).Float64(),
Width: types.Twip(s.Width).Float64(),
Color: math.Color{
R: fillEntry.R(),
G: fillEntry.G(),
@ -75,7 +75,7 @@ func StyleListFromSWFItems(collection ObjectCollection, fillStyles subtypes.FILL
color := fillEntry.GetItems()[0].Color
r.LineStyles = append(r.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.Width), types.TwipFactor).Float64(),
Width: types.Twip(s.Width).Float64(),
Color: color,
})
}
@ -96,7 +96,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
for _, s := range lineStyles.LineStyles {
start.LineStyles = append(start.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.StartWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.StartWidth).Float64(),
Color: math.Color{
R: s.StartColor.R(),
G: s.StartColor.G(),
@ -107,7 +107,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
end.LineStyles = append(end.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.EndWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.EndWidth).Float64(),
Color: math.Color{
R: s.EndColor.R(),
G: s.EndColor.G(),
@ -121,7 +121,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
if !s.Flag.HasFill {
start.LineStyles = append(start.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.StartWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.StartWidth).Float64(),
Color: math.Color{
R: s.StartColor.R(),
G: s.StartColor.G(),
@ -131,7 +131,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
})
end.LineStyles = append(end.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.EndWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.EndWidth).Float64(),
Color: math.Color{
R: s.EndColor.R(),
G: s.EndColor.G(),
@ -146,7 +146,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
case types.Color:
start.LineStyles = append(start.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.StartWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.StartWidth).Float64(),
Color: math.Color{
R: fillEntry.R(),
G: fillEntry.G(),
@ -159,7 +159,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
color := fillEntry.GetItems()[0].Color
start.LineStyles = append(start.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.StartWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.StartWidth).Float64(),
Color: color,
})
}
@ -167,7 +167,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
case types.Color:
end.LineStyles = append(end.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.EndWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.EndWidth).Float64(),
Color: math.Color{
R: fillEntry.R(),
G: fillEntry.G(),
@ -180,7 +180,7 @@ func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes
color := fillEntry.GetItems()[0].Color
end.LineStyles = append(end.LineStyles, &LineStyleRecord{
//TODO: any reason for max(types.TwipFactor)?
Width: max(types.Twip(s.EndWidth), types.TwipFactor).Float64(),
Width: types.Twip(s.EndWidth).Float64(),
Color: color,
})
}

View file

@ -11,20 +11,7 @@ import (
type StyleRecord interface {
ApplyColorTransform(transform math.ColorTransform) StyleRecord
}
type LineStyleRecord struct {
Width float64
Color math.Color
Blur float64
}
func (r *LineStyleRecord) ApplyColorTransform(transform math.ColorTransform) StyleRecord {
return &LineStyleRecord{
Width: r.Width,
Color: transform.ApplyToColor(r.Color),
Blur: r.Blur,
}
ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord
}
type Fillable interface {
@ -74,6 +61,17 @@ func (r *FillStyleRecord) Flatten(s *Shape) DrawPathList {
}
}
func (r *FillStyleRecord) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord {
if r.Border != nil {
return &FillStyleRecord{
Fill: r.Fill,
Border: r.Border.ApplyMatrixTransform(transform, applyTranslation).(*LineStyleRecord),
Blur: r.Blur, //TODO: scale blur?
}
}
return r
}
func (r *FillStyleRecord) ApplyColorTransform(transform math.ColorTransform) StyleRecord {
fill := r.Fill
if color, ok := fill.(math.Color); ok {

View file

@ -1,12 +1,11 @@
package shapes
import (
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/swf/types"
"git.gammaspectra.live/WeebDataHoarder/swf2ass-go/types/math"
)
type VisitedPoint struct {
Pos math.Vector2[types.Twip]
type VisitedPoint[T ~float64 | ~int64] struct {
Pos math.Vector2[T]
IsBezierControl bool
}