Merge pull request #790 from gavin-ts/fix-shape-get-inside-placement
fix shape get inside placement
This commit is contained in:
commit
088ba0f4a7
24 changed files with 117 additions and 41 deletions
|
|
@ -863,6 +863,11 @@ func drawShape(writer io.Writer, targetShape d2target.Shape, sketchRunner *d2ske
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to examine GetInsidePlacement
|
||||||
|
// padX, padY := s.GetDefaultPadding()
|
||||||
|
// innerTL := s.GetInsidePlacement(s.GetInnerBox().Width, s.GetInnerBox().Height, padX, padY)
|
||||||
|
// fmt.Fprint(writer, renderOval(&innerTL, 5, 5, "fill:red;"))
|
||||||
|
|
||||||
// Closes the class=shape
|
// Closes the class=shape
|
||||||
fmt.Fprint(writer, `</g>`)
|
fmt.Fprint(writer, `</g>`)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -46,7 +47,7 @@ type Shape interface {
|
||||||
GetInnerBox() *geo.Box
|
GetInnerBox() *geo.Box
|
||||||
|
|
||||||
// placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft
|
// placing a rectangle of the given size and padding inside the shape, return the position relative to the shape's TopLeft
|
||||||
GetInsidePlacement(width, height, padding float64) geo.Point
|
GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point
|
||||||
|
|
||||||
GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64)
|
GetDimensionsToFit(width, height, paddingX, paddingY float64) (float64, float64)
|
||||||
GetDefaultPadding() (paddingX, paddingY float64)
|
GetDefaultPadding() (paddingX, paddingY float64)
|
||||||
|
|
@ -58,8 +59,9 @@ type Shape interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type baseShape struct {
|
type baseShape struct {
|
||||||
Type string
|
Type string
|
||||||
Box *geo.Box
|
Box *geo.Box
|
||||||
|
FullShape *Shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s baseShape) Is(shapeType string) bool {
|
func (s baseShape) Is(shapeType string) bool {
|
||||||
|
|
@ -86,8 +88,9 @@ func (s baseShape) GetInnerBox() *geo.Box {
|
||||||
return s.Box
|
return s.Box
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s baseShape) GetInsidePlacement(_, _, padding float64) geo.Point {
|
func (s baseShape) GetInsidePlacement(_, _, paddingX, paddingY float64) geo.Point {
|
||||||
return *geo.NewPoint(s.Box.TopLeft.X+padding, s.Box.TopLeft.Y+padding)
|
innerTL := (*s.FullShape).GetInnerBox().TopLeft
|
||||||
|
return *geo.NewPoint(innerTL.X+paddingX/2, innerTL.Y+paddingY/2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the minimum shape dimensions needed to fit content (width x height)
|
// return the minimum shape dimensions needed to fit content (width x height)
|
||||||
|
|
@ -156,12 +159,14 @@ func NewShape(shapeType string, box *geo.Box) Shape {
|
||||||
return NewText(box)
|
return NewText(box)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return shapeSquare{
|
shape := shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: shapeType,
|
Type: shapeType,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeCallout struct {
|
type shapeCallout struct {
|
||||||
|
|
@ -17,12 +18,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCallout(box *geo.Box) Shape {
|
func NewCallout(box *geo.Box) Shape {
|
||||||
return shapeCallout{
|
shape := shapeCallout{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CALLOUT_TYPE,
|
Type: CALLOUT_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTipWidth(box *geo.Box) float64 {
|
func getTipWidth(box *geo.Box) float64 {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeCircle struct {
|
type shapeCircle struct {
|
||||||
|
|
@ -11,18 +12,20 @@ type shapeCircle struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCircle(box *geo.Box) Shape {
|
func NewCircle(box *geo.Box) Shape {
|
||||||
return shapeCircle{
|
shape := shapeCircle{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CIRCLE_TYPE,
|
Type: CIRCLE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeCircle) GetInnerBox() *geo.Box {
|
func (s shapeCircle) GetInnerBox() *geo.Box {
|
||||||
width := s.Box.Width
|
width := s.Box.Width
|
||||||
height := s.Box.Height
|
height := s.Box.Height
|
||||||
insideTL := s.GetInsidePlacement(width, height, 0)
|
insideTL := s.GetInsidePlacement(width, height, 0, 0)
|
||||||
tl := s.Box.TopLeft.Copy()
|
tl := s.Box.TopLeft.Copy()
|
||||||
width -= 2 * (insideTL.X - tl.X)
|
width -= 2 * (insideTL.X - tl.X)
|
||||||
height -= 2 * (insideTL.Y - tl.Y)
|
height -= 2 * (insideTL.Y - tl.Y)
|
||||||
|
|
@ -38,7 +41,7 @@ func (s shapeCircle) GetDimensionsToFit(width, height, paddingX, paddingY float6
|
||||||
return diameter, diameter
|
return diameter, diameter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeCircle) GetInsidePlacement(width, height, padding float64) geo.Point {
|
func (s shapeCircle) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
|
||||||
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(s.Box.Width/2-width/2), s.Box.TopLeft.Y+math.Ceil(s.Box.Height/2-height/2))
|
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(s.Box.Width/2-width/2), s.Box.TopLeft.Y+math.Ceil(s.Box.Height/2-height/2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Class is basically a rectangle
|
// Class is basically a rectangle
|
||||||
|
|
@ -10,7 +11,7 @@ type shapeClass struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClass(box *geo.Box) Shape {
|
func NewClass(box *geo.Box) Shape {
|
||||||
return shapeClass{
|
shape := shapeClass{
|
||||||
shapeSquare{
|
shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CLASS_TYPE,
|
Type: CLASS_TYPE,
|
||||||
|
|
@ -18,6 +19,8 @@ func NewClass(box *geo.Box) Shape {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeClass) GetDefaultPadding() (paddingX, paddingY float64) {
|
func (s shapeClass) GetDefaultPadding() (paddingX, paddingY float64) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The percentage values of the cloud's wide inner box
|
// The percentage values of the cloud's wide inner box
|
||||||
|
|
@ -32,18 +33,20 @@ type shapeCloud struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCloud(box *geo.Box) Shape {
|
func NewCloud(box *geo.Box) Shape {
|
||||||
return shapeCloud{
|
shape := shapeCloud{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CLOUD_TYPE,
|
Type: CLOUD_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeCloud) GetInnerBox() *geo.Box {
|
func (s shapeCloud) GetInnerBox() *geo.Box {
|
||||||
width := s.Box.Width
|
width := s.Box.Width
|
||||||
height := s.Box.Height
|
height := s.Box.Height
|
||||||
insideTL := s.GetInsidePlacement(width, height, 0)
|
insideTL := s.GetInsidePlacement(width, height, 0, 0)
|
||||||
aspectRatio := width / height
|
aspectRatio := width / height
|
||||||
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
|
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
|
||||||
width *= CLOUD_WIDE_INNER_WIDTH
|
width *= CLOUD_WIDE_INNER_WIDTH
|
||||||
|
|
@ -72,17 +75,17 @@ func (s shapeCloud) GetDimensionsToFit(width, height, paddingX, paddingY float64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeCloud) GetInsidePlacement(width, height, padding float64) geo.Point {
|
func (s shapeCloud) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
|
||||||
r := s.Box
|
r := s.Box
|
||||||
width += padding
|
width += paddingX
|
||||||
height += padding
|
height += paddingY
|
||||||
aspectRatio := width / height
|
aspectRatio := width / height
|
||||||
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
|
if aspectRatio > CLOUD_WIDE_ASPECT_BOUNDARY {
|
||||||
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+padding/2))
|
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_WIDE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_WIDE_INNER_Y+paddingY/2))
|
||||||
} else if aspectRatio < CLOUD_TALL_ASPECT_BOUNDARY {
|
} else if aspectRatio < CLOUD_TALL_ASPECT_BOUNDARY {
|
||||||
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+padding/2))
|
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_TALL_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_TALL_INNER_Y+paddingY/2))
|
||||||
} else {
|
} else {
|
||||||
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+padding/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+padding/2))
|
return *geo.NewPoint(r.TopLeft.X+math.Ceil(r.Width*CLOUD_SQUARE_INNER_X+paddingX/2), r.TopLeft.Y+math.Ceil(r.Height*CLOUD_SQUARE_INNER_Y+paddingY/2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeCode struct {
|
type shapeCode struct {
|
||||||
|
|
@ -9,7 +10,7 @@ type shapeCode struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCode(box *geo.Box) Shape {
|
func NewCode(box *geo.Box) Shape {
|
||||||
return shapeCode{
|
shape := shapeCode{
|
||||||
shapeSquare: shapeSquare{
|
shapeSquare: shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CODE_TYPE,
|
Type: CODE_TYPE,
|
||||||
|
|
@ -17,6 +18,8 @@ func NewCode(box *geo.Box) Shape {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeCode) GetDefaultPadding() (paddingX, paddingY float64) {
|
func (s shapeCode) GetDefaultPadding() (paddingX, paddingY float64) {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeCylinder struct {
|
type shapeCylinder struct {
|
||||||
|
|
@ -16,12 +17,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCylinder(box *geo.Box) Shape {
|
func NewCylinder(box *geo.Box) Shape {
|
||||||
return shapeCylinder{
|
shape := shapeCylinder{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: CYLINDER_TYPE,
|
Type: CYLINDER_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArcHeight(box *geo.Box) float64 {
|
func getArcHeight(box *geo.Box) float64 {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeDiamond struct {
|
type shapeDiamond struct {
|
||||||
|
|
@ -12,12 +13,14 @@ type shapeDiamond struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDiamond(box *geo.Box) Shape {
|
func NewDiamond(box *geo.Box) Shape {
|
||||||
return shapeDiamond{
|
shape := shapeDiamond{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: DIAMOND_TYPE,
|
Type: DIAMOND_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeDiamond) GetInnerBox() *geo.Box {
|
func (s shapeDiamond) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeDocument struct {
|
type shapeDocument struct {
|
||||||
|
|
@ -19,12 +20,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDocument(box *geo.Box) Shape {
|
func NewDocument(box *geo.Box) Shape {
|
||||||
return shapeDocument{
|
shape := shapeDocument{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: DOCUMENT_TYPE,
|
Type: DOCUMENT_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeDocument) GetInnerBox() *geo.Box {
|
func (s shapeDocument) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeHexagon struct {
|
type shapeHexagon struct {
|
||||||
|
|
@ -12,12 +13,14 @@ type shapeHexagon struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHexagon(box *geo.Box) Shape {
|
func NewHexagon(box *geo.Box) Shape {
|
||||||
return shapeHexagon{
|
shape := shapeHexagon{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: HEXAGON_TYPE,
|
Type: HEXAGON_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeHexagon) GetInnerBox() *geo.Box {
|
func (s shapeHexagon) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeImage struct {
|
type shapeImage struct {
|
||||||
|
|
@ -9,12 +10,14 @@ type shapeImage struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewImage(box *geo.Box) Shape {
|
func NewImage(box *geo.Box) Shape {
|
||||||
return shapeImage{
|
shape := shapeImage{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: IMAGE_TYPE,
|
Type: IMAGE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeImage) IsRectangular() bool {
|
func (s shapeImage) IsRectangular() bool {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeOval struct {
|
type shapeOval struct {
|
||||||
|
|
@ -11,18 +12,20 @@ type shapeOval struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOval(box *geo.Box) Shape {
|
func NewOval(box *geo.Box) Shape {
|
||||||
return shapeOval{
|
shape := shapeOval{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: OVAL_TYPE,
|
Type: OVAL_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeOval) GetInnerBox() *geo.Box {
|
func (s shapeOval) GetInnerBox() *geo.Box {
|
||||||
width := s.Box.Width
|
width := s.Box.Width
|
||||||
height := s.Box.Height
|
height := s.Box.Height
|
||||||
insideTL := s.GetInsidePlacement(width, height, 0)
|
insideTL := s.GetInsidePlacement(width, height, 0, 0)
|
||||||
tl := s.Box.TopLeft.Copy()
|
tl := s.Box.TopLeft.Copy()
|
||||||
width -= 2 * (insideTL.X - tl.X)
|
width -= 2 * (insideTL.X - tl.X)
|
||||||
height -= 2 * (insideTL.Y - tl.Y)
|
height -= 2 * (insideTL.Y - tl.Y)
|
||||||
|
|
@ -38,7 +41,7 @@ func (s shapeOval) GetDimensionsToFit(width, height, paddingX, paddingY float64)
|
||||||
return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight)
|
return math.Ceil(math.Sqrt2 * paddedWidth), math.Ceil(math.Sqrt2 * paddedHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point {
|
func (s shapeOval) GetInsidePlacement(width, height, paddingX, paddingY float64) geo.Point {
|
||||||
// showing the top left arc of the ellipse (drawn with '*')
|
// showing the top left arc of the ellipse (drawn with '*')
|
||||||
// ┌──────────────────* ┬
|
// ┌──────────────────* ┬
|
||||||
// │ * │ │ry
|
// │ * │ │ry
|
||||||
|
|
@ -56,8 +59,8 @@ func (s shapeOval) GetInsidePlacement(width, height, padding float64) geo.Point
|
||||||
// r is the ellipse radius on the line between node.TopLeft and the ellipse center
|
// r is the ellipse radius on the line between node.TopLeft and the ellipse center
|
||||||
// see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo
|
// see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo
|
||||||
r := rx * ry / math.Sqrt(math.Pow(rx*sin, 2)+math.Pow(ry*cos, 2))
|
r := rx * ry / math.Sqrt(math.Pow(rx*sin, 2)+math.Pow(ry*cos, 2))
|
||||||
// we want to offset r-padding away from the center
|
// we want to offset r-padding/2 away from the center
|
||||||
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-padding)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-padding)))
|
return *geo.NewPoint(s.Box.TopLeft.X+math.Ceil(rx-cos*(r-paddingX/2)), s.Box.TopLeft.Y+math.Ceil(ry-sin*(r-paddingY/2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeOval) Perimeter() []geo.Intersectable {
|
func (s shapeOval) Perimeter() []geo.Intersectable {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapePackage struct {
|
type shapePackage struct {
|
||||||
|
|
@ -21,12 +22,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPackage(box *geo.Box) Shape {
|
func NewPackage(box *geo.Box) Shape {
|
||||||
return shapePackage{
|
shape := shapePackage{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: PACKAGE_TYPE,
|
Type: PACKAGE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapePackage) GetInnerBox() *geo.Box {
|
func (s shapePackage) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapePage struct {
|
type shapePage struct {
|
||||||
|
|
@ -18,12 +19,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPage(box *geo.Box) Shape {
|
func NewPage(box *geo.Box) Shape {
|
||||||
return shapePage{
|
shape := shapePage{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: PAGE_TYPE,
|
Type: PAGE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapePage) GetInnerBox() *geo.Box {
|
func (s shapePage) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeParallelogram struct {
|
type shapeParallelogram struct {
|
||||||
|
|
@ -14,12 +15,14 @@ type shapeParallelogram struct {
|
||||||
const parallelWedgeWidth = 26.
|
const parallelWedgeWidth = 26.
|
||||||
|
|
||||||
func NewParallelogram(box *geo.Box) Shape {
|
func NewParallelogram(box *geo.Box) Shape {
|
||||||
return shapeParallelogram{
|
shape := shapeParallelogram{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: PARALLELOGRAM_TYPE,
|
Type: PARALLELOGRAM_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeParallelogram) GetInnerBox() *geo.Box {
|
func (s shapeParallelogram) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapePerson struct {
|
type shapePerson struct {
|
||||||
|
|
@ -12,12 +13,14 @@ type shapePerson struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPerson(box *geo.Box) Shape {
|
func NewPerson(box *geo.Box) Shape {
|
||||||
return shapePerson{
|
shape := shapePerson{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: PERSON_TYPE,
|
Type: PERSON_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeQueue struct {
|
type shapeQueue struct {
|
||||||
|
|
@ -12,12 +13,14 @@ type shapeQueue struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQueue(box *geo.Box) Shape {
|
func NewQueue(box *geo.Box) Shape {
|
||||||
return shapeQueue{
|
shape := shapeQueue{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: QUEUE_TYPE,
|
Type: QUEUE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArcWidth(box *geo.Box) float64 {
|
func getArcWidth(box *geo.Box) float64 {
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeRealSquare struct {
|
type shapeRealSquare struct {
|
||||||
|
|
@ -11,12 +12,14 @@ type shapeRealSquare struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRealSquare(box *geo.Box) Shape {
|
func NewRealSquare(box *geo.Box) Shape {
|
||||||
return shapeRealSquare{
|
shape := shapeRealSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: REAL_SQUARE_TYPE,
|
Type: REAL_SQUARE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeRealSquare) AspectRatio1() bool {
|
func (s shapeRealSquare) AspectRatio1() bool {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeSquare struct {
|
type shapeSquare struct {
|
||||||
|
|
@ -9,12 +10,14 @@ type shapeSquare struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSquare(box *geo.Box) Shape {
|
func NewSquare(box *geo.Box) Shape {
|
||||||
return shapeSquare{
|
shape := shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: SQUARE_TYPE,
|
Type: SQUARE_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeSquare) IsRectangular() bool {
|
func (s shapeSquare) IsRectangular() bool {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeStep struct {
|
type shapeStep struct {
|
||||||
|
|
@ -12,12 +13,14 @@ type shapeStep struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStep(box *geo.Box) Shape {
|
func NewStep(box *geo.Box) Shape {
|
||||||
return shapeStep{
|
shape := shapeStep{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: STEP_TYPE,
|
Type: STEP_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
const STEP_WEDGE_WIDTH = 35.0
|
const STEP_WEDGE_WIDTH = 35.0
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
"oss.terrastruct.com/d2/lib/svg"
|
"oss.terrastruct.com/d2/lib/svg"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type shapeStoredData struct {
|
type shapeStoredData struct {
|
||||||
|
|
@ -14,12 +15,14 @@ type shapeStoredData struct {
|
||||||
const storedDataWedgeWidth = 15.
|
const storedDataWedgeWidth = 15.
|
||||||
|
|
||||||
func NewStoredData(box *geo.Box) Shape {
|
func NewStoredData(box *geo.Box) Shape {
|
||||||
return shapeStoredData{
|
shape := shapeStoredData{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: STORED_DATA_TYPE,
|
Type: STORED_DATA_TYPE,
|
||||||
Box: box,
|
Box: box,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeStoredData) GetInnerBox() *geo.Box {
|
func (s shapeStoredData) GetInnerBox() *geo.Box {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Table is basically a rectangle
|
// Table is basically a rectangle
|
||||||
|
|
@ -10,7 +11,7 @@ type shapeTable struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTable(box *geo.Box) Shape {
|
func NewTable(box *geo.Box) Shape {
|
||||||
return shapeTable{
|
shape := shapeTable{
|
||||||
shapeSquare{
|
shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: TABLE_TYPE,
|
Type: TABLE_TYPE,
|
||||||
|
|
@ -18,6 +19,8 @@ func NewTable(box *geo.Box) Shape {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeTable) GetDefaultPadding() (paddingX, paddingY float64) {
|
func (s shapeTable) GetDefaultPadding() (paddingX, paddingY float64) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package shape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"oss.terrastruct.com/d2/lib/geo"
|
"oss.terrastruct.com/d2/lib/geo"
|
||||||
|
"oss.terrastruct.com/util-go/go2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Text is basically a rectangle
|
// Text is basically a rectangle
|
||||||
|
|
@ -10,7 +11,7 @@ type shapeText struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewText(box *geo.Box) Shape {
|
func NewText(box *geo.Box) Shape {
|
||||||
return shapeText{
|
shape := shapeText{
|
||||||
shapeSquare: shapeSquare{
|
shapeSquare: shapeSquare{
|
||||||
baseShape: &baseShape{
|
baseShape: &baseShape{
|
||||||
Type: TEXT_TYPE,
|
Type: TEXT_TYPE,
|
||||||
|
|
@ -18,6 +19,8 @@ func NewText(box *geo.Box) Shape {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
shape.FullShape = go2.Pointer(Shape(shape))
|
||||||
|
return shape
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shapeText) GetDefaultPadding() (paddingX, paddingY float64) {
|
func (s shapeText) GetDefaultPadding() (paddingX, paddingY float64) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue