shapes

package
v0.0.0-...-7d2fe1b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2024 License: MIT Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const GradientBoundsMax = -GradientBoundsMin
View Source
const GradientBoundsMin swftypes.Twip = math.MinInt16 / 2
View Source
const GradientRatioDivisor = math.MaxUint8
View Source
const PolygonSimplifyTolerance = 0.01

Variables

View Source
var GradientBounds = Rectangle[float64]{
	TopLeft:     math2.NewVector2[float64](GradientBoundsMin.Float64(), GradientBoundsMin.Float64()),
	BottomRight: math2.NewVector2[float64](GradientBoundsMax.Float64(), GradientBoundsMax.Float64()),
}

Functions

func DrawPathListFromSWFMorph

func DrawPathListFromSWFMorph(collection ObjectCollection, startRecords, endRecords subtypes.SHAPERECORDS, startStyles, endStyles StyleList) (DrawPathList, DrawPathList)

func ImageToPNG

func ImageToPNG(im image.Image, fname string) error

func IterateMorphShape

func IterateMorphShape(start, end Shape) (r []records.RecordPair)

func LerpFillable

func LerpFillable(start, end any, ratio float64) any

func NewContourFromEdges

func NewContourFromEdges(edges []records.LineRecord) (p polyclip.Contour)

func NewPolygonFromShape

func NewPolygonFromShape(shape Shape) (g polyclip.Polygon)

func QuantizeBitmap

func QuantizeBitmap(i image.Image) image.Image

Types

type ActivePath

type ActivePath struct {
	Segment PathSegment[types.Twip]
	StyleId int
}

func NewActivePath

func NewActivePath(styleId int, start math.Vector2[types.Twip]) *ActivePath

func (*ActivePath) AddPoint

func (p *ActivePath) AddPoint(point VisitedPoint[types.Twip])

func (*ActivePath) Flip

func (p *ActivePath) Flip()

type Bitmap

type Bitmap struct {
	List DrawPathList

	Transform math2.MatrixTransform
}

func BitmapFillFromSWF

func BitmapFillFromSWF(l DrawPathList, transform types.MATRIX) Bitmap

func (Bitmap) ApplyColorTransform

func (b Bitmap) ApplyColorTransform(transform math2.ColorTransform) Fillable

func (Bitmap) ApplyMatrixTransform

func (b Bitmap) ApplyMatrixTransform(transform math2.MatrixTransform, applyTranslation bool) Fillable

func (Bitmap) Fill

func (b Bitmap) Fill(shape Shape) DrawPathList

type Capper

type Capper func(from, to math.Vector2[float64]) PathSegment[float64]
var ButtCapper Capper = func(from, to math.Vector2[float64]) PathSegment[float64] {
	return PathSegment[float64]{
		{
			Pos:             from,
			IsBezierControl: false,
		},
		{
			Pos:             to,
			IsBezierControl: false,
		},
	}
}
var RoundCapper Capper = func(from, to math.Vector2[float64]) PathSegment[float64] {
	mid := from.AddVector(to).Divide(2)

	ellipseDrawQuarter(mid, from.SubVector(mid)).ToLineRecords(1)
	ellipseDrawQuarter(mid, to.SubVector(mid)).ToLineRecords(1)
	return PathSegment[float64]{
		{
			Pos:             from,
			IsBezierControl: false,
		},
		{
			Pos:             to,
			IsBezierControl: false,
		},
	}
}

type ClipPath

type ClipPath struct {
	Clip ComplexPolygon
}

func NewClipPath

func NewClipPath(shape Shape) *ClipPath

func (*ClipPath) AddShape

func (c *ClipPath) AddShape(shape Shape)

func (*ClipPath) ApplyMatrixTransform

func (c *ClipPath) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) *ClipPath

func (*ClipPath) ClipShape

func (c *ClipPath) ClipShape(o Shape, recover bool) (r Shape)

ClipShape Clips a shape, but attempts to recover original curved records

func (*ClipPath) GetShape

func (c *ClipPath) GetShape() Shape

func (*ClipPath) Intersect

func (c *ClipPath) Intersect(o *ClipPath) *ClipPath

func (*ClipPath) Merge

func (c *ClipPath) Merge(o *ClipPath) *ClipPath

type Complex

type Complex interface {
	Draw() Shape
}

type ComplexPolygon

type ComplexPolygon struct {
	Pol polyclip.Polygon
}

func (ComplexPolygon) Draw

func (p ComplexPolygon) Draw() Shape

func (ComplexPolygon) GetShape

func (p ComplexPolygon) GetShape() (r Shape)

func (ComplexPolygon) Intersect

func (ComplexPolygon) Merge

type DrawPath

type DrawPath struct {
	Style StyleRecord
	Shape Shape
}

func DrawPathFill

func DrawPathFill(record *FillStyleRecord, shape Shape) DrawPath

func DrawPathStroke

func DrawPathStroke(record *LineStyleRecord, shape Shape) DrawPath

func (DrawPath) ApplyColorTransform

func (p DrawPath) ApplyColorTransform(transform math.ColorTransform) (r DrawPath)

func (DrawPath) ApplyMatrixTransform

func (p DrawPath) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) (r DrawPath)

type DrawPathList

type DrawPathList []DrawPath

func ConvertBitmapBytesToDrawPathList

func ConvertBitmapBytesToDrawPathList(imageData []byte, alphaData []byte) (DrawPathList, error)

func ConvertBitmapToDrawPathList

func ConvertBitmapToDrawPathList(i image.Image) (r DrawPathList)

func DrawPathListFromSWF

func DrawPathListFromSWF(collection ObjectCollection, records subtypes.SHAPERECORDS, styles StyleList) DrawPathList

func (DrawPathList) ApplyColorTransform

func (l DrawPathList) ApplyColorTransform(transform math.ColorTransform) Fillable

func (DrawPathList) ApplyFunction

func (l DrawPathList) ApplyFunction(f func(p DrawPath) DrawPath) (r DrawPathList)

func (DrawPathList) ApplyMatrixTransform

func (l DrawPathList) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) Fillable

func (DrawPathList) Fill

func (l DrawPathList) Fill(shape Shape) (r DrawPathList)

func (DrawPathList) Merge

type Ellipse

type Ellipse[T ~float64 | ~int64] struct {
	Center, Radius math.Vector2[T]
}

func NewCircle

func NewCircle[T ~float64 | ~int64](center math.Vector2[T], radius T) Ellipse[T]

func (Ellipse[T]) Draw

func (r Ellipse[T]) Draw() Shape

type FillStyleRecord

type FillStyleRecord struct {
	// Fill can be math.Color or Fillable
	Fill   any
	Border *LineStyleRecord
	Blur   float64
	// contains filtered or unexported fields
}

func FillStyleRecordFromSWF

func FillStyleRecordFromSWF(collection ObjectCollection, fillType swfsubtypes.FillStyleType, color swftypes.Color, gradient swfsubtypes.GRADIENT, focalGradient swfsubtypes.FOCALGRADIENT, gradientMatrix, bitmapMatrix swftypes.MATRIX, bitmapId uint16) (r *FillStyleRecord)

func FillStyleRecordFromSWFMORPHFILLSTYLE

func FillStyleRecordFromSWFMORPHFILLSTYLE(collection ObjectCollection, fillStyle swfsubtypes.MORPHFILLSTYLE) (start, end *FillStyleRecord)

func LerpFillStyle

func LerpFillStyle(start, end *FillStyleRecord, ratio float64) *FillStyleRecord

func (*FillStyleRecord) ApplyColorTransform

func (r *FillStyleRecord) ApplyColorTransform(transform math.ColorTransform) StyleRecord

func (*FillStyleRecord) ApplyMatrixTransform

func (r *FillStyleRecord) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord

func (*FillStyleRecord) Flatten

func (r *FillStyleRecord) Flatten(s Shape) DrawPathList

Flatten Creates a fill that is only composed of FillStyleRecord with Fill being math.Color

func (*FillStyleRecord) IsFlat

func (r *FillStyleRecord) IsFlat() bool

type Fillable

type Fillable interface {
	Fill(shape Shape) DrawPathList
	ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) Fillable
	ApplyColorTransform(transform math.ColorTransform) Fillable
}

type Gradient

type Gradient struct {
	Records []GradientItem

	Transform         math2.MatrixTransform
	SpreadMode        swfsubtypes.GradientSpreadMode
	InterpolationMode swfsubtypes.GradientInterpolationMode

	Interpolation func(self Gradient, overlap, blur float64, gradientSlices int, bb Rectangle[float64]) DrawPathList
}

func LerpGradient

func LerpGradient(start, end Gradient, ratio float64) Gradient

func LinearGradientFromSWF

func LinearGradientFromSWF(records []swfsubtypes.GRADRECORD, transform types.MATRIX, spreadMode swfsubtypes.GradientSpreadMode, interpolationMode swfsubtypes.GradientInterpolationMode) Gradient

func RadialGradientFromSWF

func RadialGradientFromSWF(records []swfsubtypes.GRADRECORD, transform types.MATRIX, spreadMode swfsubtypes.GradientSpreadMode, interpolationMode swfsubtypes.GradientInterpolationMode) Gradient

func (Gradient) ApplyColorTransform

func (g Gradient) ApplyColorTransform(transform math2.ColorTransform) Fillable

func (Gradient) ApplyMatrixTransform

func (g Gradient) ApplyMatrixTransform(transform math2.MatrixTransform, applyTranslation bool) Fillable

func (Gradient) Fill

func (g Gradient) Fill(shape Shape) DrawPathList

func (Gradient) GetInterpolatedDrawPaths

func (g Gradient) GetInterpolatedDrawPaths(overlap, blur float64, gradientSlices int, bb Rectangle[float64]) DrawPathList

func (Gradient) GetItems

func (g Gradient) GetItems() []GradientItem

func (Gradient) Interpolate

func (g Gradient) Interpolate(gradientSlices int) (result []GradientSlice)

type GradientItem

type GradientItem struct {
	Ratio uint8
	Color math2.Color
}

func GradientItemFromSWF

func GradientItemFromSWF(ratio uint8, color swftypes.Color) GradientItem

type GradientSlice

type GradientSlice struct {
	Start, End float64
	Color      math2.Color
}

type Joiner

type Joiner func(from, to math.Vector2[float64]) PathSegment[float64]
var StraightJoiner Joiner = func(from, to math.Vector2[float64]) PathSegment[float64] {
	return PathSegment[float64]{
		{
			Pos:             from,
			IsBezierControl: false,
		},
		{
			Pos:             to,
			IsBezierControl: false,
		},
	}
}

type LineStyleRecord

type LineStyleRecord struct {
	Width float64
	Color math.Color
	Blur  float64
}

func LerpLineStyle

func LerpLineStyle(start, end *LineStyleRecord, ratio float64) *LineStyleRecord

func LineStyleRecordFromSWF

func LineStyleRecordFromSWF(width uint16, blur float64, hasFill bool, c swftypes.Color, fill *FillStyleRecord) (r *LineStyleRecord)

func LineStyleRecordFromSWFMORPHLINESTYLE

func LineStyleRecordFromSWFMORPHLINESTYLE(lineStyle swfsubtypes.MORPHLINESTYLE) (start, end *LineStyleRecord)

func LineStyleRecordFromSWFMORPHLINESTYLE2

func LineStyleRecordFromSWFMORPHLINESTYLE2(collection ObjectCollection, lineStyle swfsubtypes.MORPHLINESTYLE2) (start, end *LineStyleRecord)

func (*LineStyleRecord) ApplyColorTransform

func (r *LineStyleRecord) ApplyColorTransform(transform math.ColorTransform) StyleRecord

func (*LineStyleRecord) ApplyMatrixTransform

func (r *LineStyleRecord) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord

func (*LineStyleRecord) StrokeWidth

func (r *LineStyleRecord) StrokeWidth(transform math.MatrixTransform) float64

type MedianCutQuantizer

type MedianCutQuantizer struct {
	NumColor int
}

MedianCutQuantizer constructs a palette with a maximum of NumColor colors by iteratively splitting clusters of color points mapped on a three-dimensional (RGB) Euclidian space. Once the number of clusters is within the specified bounds, the resulting color is computed by averaging those within each grouping.

func (*MedianCutQuantizer) Quantize

func (q *MedianCutQuantizer) Quantize(dst *image.Paletted, r image.Rectangle, src image.Image, sp image.Point)

type ObjectCollection

type ObjectCollection map[uint16]ObjectDefinition

func (ObjectCollection) Add

func (ObjectCollection) Clone

func (ObjectCollection) Get

func (o ObjectCollection) Get(objectId uint16) ObjectDefinition

type ObjectDefinition

type ObjectDefinition interface {
	GetObjectId() uint16
	GetSafeObject() ObjectDefinition
	GetShapeList(p ObjectProperties) DrawPathList
}

type ObjectProperties

type ObjectProperties struct {
	Ratio      float64
	Visible    bool
	PlaceFrame int64
	// Data can be any value internal to the object itself
	Data any
}

type PathSegment

type PathSegment[T ~float64 | ~int64] []VisitedPoint[T]

func NewPathSegment

func NewPathSegment[T ~float64 | ~int64](start math.Vector2[T]) PathSegment[T]

func (*PathSegment[T]) AddPoint

func (s *PathSegment[T]) AddPoint(p VisitedPoint[T])

func (*PathSegment[T]) End

func (s *PathSegment[T]) End() math.Vector2[T]

func (*PathSegment[T]) Flip

func (s *PathSegment[T]) Flip()

Flip Flips the direction of the path segment. 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 (*PathSegment[T]) GetShape

func (s *PathSegment[T]) GetShape() (shape Shape)

func (*PathSegment[T]) IsClosed

func (s *PathSegment[T]) IsClosed() bool

func (*PathSegment[T]) IsEmpty

func (s *PathSegment[T]) IsEmpty() bool

func (*PathSegment[T]) Merge

func (s *PathSegment[T]) Merge(o PathSegment[T])

func (*PathSegment[T]) Start

func (s *PathSegment[T]) Start() math.Vector2[T]

func (*PathSegment[T]) Swap

func (s *PathSegment[T]) Swap(o *PathSegment[T])

func (*PathSegment[T]) TryMerge

func (s *PathSegment[T]) TryMerge(o *PathSegment[T], isDirected bool) bool

type PendingPath

type PendingPath[T ~float64 | ~int64] []*PathSegment[T]

func (*PendingPath[T]) GetShape

func (p *PendingPath[T]) GetShape() (shape Shape)

func (*PendingPath[T]) MergePath

func (p *PendingPath[T]) MergePath(newSegment *PathSegment[T], directed bool)

type PendingPathMap

type PendingPathMap map[int]*PendingPath[types.Twip]

func (PendingPathMap) MergePath

func (m PendingPathMap) MergePath(p *ActivePath, directed bool)

type RecordCorrespondence

type RecordCorrespondence struct {
	Original  records.Record
	Flattened []records.Record
}

type Rectangle

type Rectangle[T ~float64 | ~int64] struct {
	TopLeft, BottomRight math.Vector2[T]
}

func NewSquare

func NewSquare[T ~float64 | ~int64](topLeft math.Vector2[T], size T) Rectangle[T]

func RectangleFromSWF

func RectangleFromSWF(rect types.RECT) Rectangle[float64]

func RectangleToType

func RectangleToType[T ~int64 | ~float64, T2 ~int64 | ~float64](r Rectangle[T]) Rectangle[T2]

func (Rectangle[T]) Area

func (r Rectangle[T]) Area() T

func (Rectangle[T]) Divide

func (r Rectangle[T]) Divide(size T) Rectangle[T]

func (Rectangle[T]) Draw

func (r Rectangle[T]) Draw() Shape

func (Rectangle[T]) DrawOpen

func (r Rectangle[T]) DrawOpen() []records.Record

func (Rectangle[T]) Height

func (r Rectangle[T]) Height() T

func (Rectangle[T]) InBounds

func (r Rectangle[T]) InBounds(pos math.Vector2[T]) bool

func (Rectangle[T]) Multiply

func (r Rectangle[T]) Multiply(size T) Rectangle[T]

func (Rectangle[T]) Width

func (r Rectangle[T]) Width() T

type Shape

type Shape []records.Record

func (Shape) ApplyMatrixTransform

func (s Shape) ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) (newShape Shape)

func (Shape) BoundingBox

func (s Shape) BoundingBox() Rectangle[float64]

func (Shape) End

func (s Shape) End() math.Vector2[float64]

func (Shape) Equals

func (s Shape) Equals(o Shape) bool

func (Shape) Flatten

func (s Shape) Flatten() (r Shape)

Flatten Converts all non-linear records into line segments and returns a new Shape

func (Shape) FlattenWithCorrespondence

func (s Shape) FlattenWithCorrespondence() (r Shape, ix []RecordCorrespondence)

func (Shape) IsClosed

func (s Shape) IsClosed() bool

func (Shape) IsFlat

func (s Shape) IsFlat() bool

func (Shape) Merge

func (s Shape) Merge(o Shape) (r Shape)

func (Shape) Reverse

func (s Shape) Reverse() (r Shape)

func (Shape) Start

func (s Shape) Start() math.Vector2[float64]

func (Shape) String

func (s Shape) String() (r string)

type ShapeConverter

type ShapeConverter struct {
	Collection ObjectCollection
	Styles     StyleList

	FillStyle0 *ActivePath
	FillStyle1 *ActivePath
	LineStyle  *ActivePath

	Position math.Vector2[types.Twip]

	Fills, Strokes PendingPathMap

	Commands DrawPathList

	Finished bool
}

func NewMorphShapeConverter

func NewMorphShapeConverter(collection ObjectCollection, styles StyleList) *ShapeConverter

func NewShapeConverter

func NewShapeConverter(collection ObjectCollection, styles StyleList) *ShapeConverter

func (*ShapeConverter) Convert

func (c *ShapeConverter) Convert(elements subtypes.SHAPERECORDS) DrawPathList

func (*ShapeConverter) ConvertMorph

func (c *ShapeConverter) ConvertMorph(start, end subtypes.SHAPERECORDS) (startList, endList subtypes.SHAPERECORDS)

ConvertMorph We step through both the start records and end records, interpolating edges pairwise. Fill style/line style changes should only appear in the start records. However, StyleChangeRecord move_to can appear it both start and end records, and not necessarily in matching pairs; therefore, we have to keep track of the pen position in case one side is missing a move_to; it will implicitly use the last pen position.

func (*ShapeConverter) FlushLayer

func (c *ShapeConverter) FlushLayer()

func (*ShapeConverter) FlushPaths

func (c *ShapeConverter) FlushPaths()

func (*ShapeConverter) HandleNode

func (c *ShapeConverter) HandleNode(node subtypes.SHAPERECORD)

func (*ShapeConverter) VisitPoint

func (c *ShapeConverter) VisitPoint(pos math.Vector2[types.Twip], isBezierControlPoint bool)

type StrokeConverter

type StrokeConverter struct {
	HalfWidth  float64
	MiterLimit float64
	Cap        Capper
	Join       Joiner

	Position math.Vector2[float64]

	Segment [2]PathSegment[float64]
}

func (*StrokeConverter) Close

func (c *StrokeConverter) Close() PathSegment[float64]

func (*StrokeConverter) Line

func (c *StrokeConverter) Line(v math.Vector2[float64])

type StyleList

type StyleList struct {
	FillStyles []*FillStyleRecord
	LineStyles []*LineStyleRecord
}

func StyleListFromSWFItems

func StyleListFromSWFItems(collection ObjectCollection, fillStyles subtypes.FILLSTYLEARRAY, lineStyles subtypes.LINESTYLEARRAY) (r StyleList)

func StyleListFromSWFMorphItems

func StyleListFromSWFMorphItems(collection ObjectCollection, fillStyles subtypes.MORPHFILLSTYLEARRAY, lineStyles subtypes.MORPHLINESTYLEARRAY) (start, end StyleList)

func (StyleList) GetFillStyle

func (l StyleList) GetFillStyle(i int) *FillStyleRecord

func (StyleList) GetLineStyle

func (l StyleList) GetLineStyle(i int) *LineStyleRecord

type StyleRecord

type StyleRecord interface {
	ApplyColorTransform(transform math.ColorTransform) StyleRecord
	ApplyMatrixTransform(transform math.MatrixTransform, applyTranslation bool) StyleRecord
}

type VisitedPoint

type VisitedPoint[T ~float64 | ~int64] struct {
	Pos math.Vector2[T]

	IsBezierControl bool
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL