fix wrong git ignore
This commit is contained in:
149
internal/pdf/contentstream/draw/bezier_curve.go
Normal file
149
internal/pdf/contentstream/draw/bezier_curve.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package draw
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model"
|
||||
)
|
||||
|
||||
// Cubic bezier curves are defined by:
|
||||
// R(t) = P0*(1-t)^3 + P1*3*t*(1-t)^2 + P2*3*t^2*(1-t) + P3*t^3
|
||||
// where P0 is the current point, P1, P2 control points and P3 the final point.
|
||||
type CubicBezierCurve struct {
|
||||
P0 Point // Starting point.
|
||||
P1 Point // Control point 1.
|
||||
P2 Point // Control point 2.
|
||||
P3 Point // Final point.
|
||||
}
|
||||
|
||||
func NewCubicBezierCurve(x0, y0, x1, y1, x2, y2, x3, y3 float64) CubicBezierCurve {
|
||||
curve := CubicBezierCurve{}
|
||||
curve.P0 = NewPoint(x0, y0)
|
||||
curve.P1 = NewPoint(x1, y1)
|
||||
curve.P2 = NewPoint(x2, y2)
|
||||
curve.P3 = NewPoint(x3, y3)
|
||||
return curve
|
||||
}
|
||||
|
||||
// Add X,Y offset to all points on a curve.
|
||||
func (curve CubicBezierCurve) AddOffsetXY(offX, offY float64) CubicBezierCurve {
|
||||
curve.P0.X += offX
|
||||
curve.P1.X += offX
|
||||
curve.P2.X += offX
|
||||
curve.P3.X += offX
|
||||
|
||||
curve.P0.Y += offY
|
||||
curve.P1.Y += offY
|
||||
curve.P2.Y += offY
|
||||
curve.P3.Y += offY
|
||||
|
||||
return curve
|
||||
}
|
||||
|
||||
func (curve CubicBezierCurve) GetBounds() model.PdfRectangle {
|
||||
minX := curve.P0.X
|
||||
maxX := curve.P0.X
|
||||
minY := curve.P0.Y
|
||||
maxY := curve.P0.Y
|
||||
|
||||
// 1000 points.
|
||||
for t := 0.0; t <= 1.0; t += 0.001 {
|
||||
Rx := curve.P0.X*math.Pow(1-t, 3) +
|
||||
curve.P1.X*3*t*math.Pow(1-t, 2) +
|
||||
curve.P2.X*3*math.Pow(t, 2)*(1-t) +
|
||||
curve.P3.X*math.Pow(t, 3)
|
||||
Ry := curve.P0.Y*math.Pow(1-t, 3) +
|
||||
curve.P1.Y*3*t*math.Pow(1-t, 2) +
|
||||
curve.P2.Y*3*math.Pow(t, 2)*(1-t) +
|
||||
curve.P3.Y*math.Pow(t, 3)
|
||||
|
||||
if Rx < minX {
|
||||
minX = Rx
|
||||
}
|
||||
if Rx > maxX {
|
||||
maxX = Rx
|
||||
}
|
||||
if Ry < minY {
|
||||
minY = Ry
|
||||
}
|
||||
if Ry > maxY {
|
||||
maxY = Ry
|
||||
}
|
||||
}
|
||||
|
||||
bounds := model.PdfRectangle{}
|
||||
bounds.Llx = minX
|
||||
bounds.Lly = minY
|
||||
bounds.Urx = maxX
|
||||
bounds.Ury = maxY
|
||||
return bounds
|
||||
}
|
||||
|
||||
type CubicBezierPath struct {
|
||||
Curves []CubicBezierCurve
|
||||
}
|
||||
|
||||
func NewCubicBezierPath() CubicBezierPath {
|
||||
bpath := CubicBezierPath{}
|
||||
bpath.Curves = []CubicBezierCurve{}
|
||||
return bpath
|
||||
}
|
||||
|
||||
func (this CubicBezierPath) AppendCurve(curve CubicBezierCurve) CubicBezierPath {
|
||||
this.Curves = append(this.Curves, curve)
|
||||
return this
|
||||
}
|
||||
|
||||
func (bpath CubicBezierPath) Copy() CubicBezierPath {
|
||||
bpathcopy := CubicBezierPath{}
|
||||
bpathcopy.Curves = []CubicBezierCurve{}
|
||||
for _, c := range bpath.Curves {
|
||||
bpathcopy.Curves = append(bpathcopy.Curves, c)
|
||||
}
|
||||
return bpathcopy
|
||||
}
|
||||
|
||||
func (bpath CubicBezierPath) Offset(offX, offY float64) CubicBezierPath {
|
||||
for i, c := range bpath.Curves {
|
||||
bpath.Curves[i] = c.AddOffsetXY(offX, offY)
|
||||
}
|
||||
return bpath
|
||||
}
|
||||
|
||||
func (bpath CubicBezierPath) GetBoundingBox() Rectangle {
|
||||
bbox := Rectangle{}
|
||||
|
||||
minX := 0.0
|
||||
maxX := 0.0
|
||||
minY := 0.0
|
||||
maxY := 0.0
|
||||
for idx, c := range bpath.Curves {
|
||||
curveBounds := c.GetBounds()
|
||||
if idx == 0 {
|
||||
minX = curveBounds.Llx
|
||||
maxX = curveBounds.Urx
|
||||
minY = curveBounds.Lly
|
||||
maxY = curveBounds.Ury
|
||||
continue
|
||||
}
|
||||
|
||||
if curveBounds.Llx < minX {
|
||||
minX = curveBounds.Llx
|
||||
}
|
||||
if curveBounds.Urx > maxX {
|
||||
maxX = curveBounds.Urx
|
||||
}
|
||||
if curveBounds.Lly < minY {
|
||||
minY = curveBounds.Lly
|
||||
}
|
||||
if curveBounds.Ury > maxY {
|
||||
maxY = curveBounds.Ury
|
||||
}
|
||||
}
|
||||
|
||||
bbox.X = minX
|
||||
bbox.Y = minY
|
||||
bbox.Width = maxX - minX
|
||||
bbox.Height = maxY - minY
|
||||
return bbox
|
||||
}
|
||||
Reference in New Issue
Block a user