ioxml2eps

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2024 License: BSD-2-Clause-Views Imports: 8 Imported by: 0

Documentation

Overview

Abstract: The sketch is the object which manages the underlying IO

xml goop. It provides the API to the user programme providing
a bit of insulation from the underlying madness in the XML.

One of the must bizarre things about the XML is the fact that
a line has a defined source and target point, complete with
a value, but this value isn't accurate if in the drawing
the line is "attached" to another object. From an interactive
point of view, this makes sense as it allows the point to follow
the movement of the object, but when rendering the line these
end points must be ignored, and the real values computed based
on an x,y "precentage" relative to the attached drawing thing's
dimensions.

To deal with this, um, feature, we must map the drawing things
so when we need to paint a line we can look up and compute the
"attachment" point.

Date: 17 March 2022 Author: E. Scott Daniels

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BoundingBox

func BoundingBox(pts []*RealPoint) (minPt *RealPoint, maxPt *RealPoint)

Given a list of real points, return the two points representing the min x,y and max x,y pair.

func InvertColours added in v1.2.0

func InvertColours(state bool)

Call to set the invert colour state.

func IsColourInverted added in v1.2.0

func IsColourInverted() bool

Call to get inverted colour state

Types

type Alignment

type Alignment int

type Array

type Array struct {
	Kind   string  `xml:"as,attr"`
	Points []Point `xml:"mxPoint"`
}

In the case of a multi point line, the inner points are defined in an array, rather than just defining them at the geom level (sheesh).

type Colour

type Colour struct {
	// contains filtered or unexported fields
}

func NewColour

func NewColour(colour string) (c *Colour)

func (*Colour) Composite

func (c *Colour) Composite() int64

Return the composite value as an integer.

func (*Colour) RGB

func (c *Colour) RGB() (int, int, int)

Return the red green and blue values.

func (*Colour) RgbPct

func (c *Colour) RgbPct() (float64, float64, float64)

Return the red green and blue values as floating percentages of 255.

If invert colours flag is true, then black and white are inverted.

func (*Colour) SetColour

func (c *Colour) SetColour(colour string)

Set the colour represented by the struct. Arg is expected as a string (0xrrggbb, #rrggbb, or the hidous rgb(r,b,b) representation that io.draw shoves into their embedded HTML).

func (*Colour) String

func (c *Colour) String() string

The string interface is in the form that Postscript colour command wants

type DFile

type DFile struct {
	Version string     `xml:"version,attr"`
	Dgrams  []*Diagram `xml:"diagram"`
	// contains filtered or unexported fields
}

The mkFile layer. The only interesting thing it contains is the diagam. Even though there is a "page" attribute inside of the mxGraphModel object, "pages" seem to be managed with separate diagram objects. (The XML organisation is simply mind boggling.) So, we manage an array of Dgram objects.

func (*DFile) Next

func (df *DFile) Next() bool

Select the next page; return false if it cannot be selected

func (*DFile) NextPage

func (df *DFile) NextPage() *Diagram

Get the next page if we can. If there isn't a next page then return nil.

func (*DFile) Page

func (df *DFile) Page() *Diagram

Get the currently selected page

func (*DFile) PageCount

func (df *DFile) PageCount() int

func (*DFile) Select

func (df *DFile) Select(n int)

Select a spdcific page

type DThing

type DThing struct {
	Id       string   `xml:"id,attr"`
	Value    string   `xml:"value,attr"`
	StyleStr string   `xml:"style,attr"`
	Source   string   `xml:"source,attr"`
	Target   string   `xml:"target,attr"`
	Geom     Geometry `xml:"mxGeometry"`
	// contains filtered or unexported fields
}

A single drawing thing.

func (*DThing) AddAttachments

func (dt *DThing) AddAttachments(src, target *DThing)

Set the reference for src and/or target drawing things.

func (*DThing) AttachPoint

func (dt *DThing) AttachPoint(pX, pY float64) (x, y int)

Given a "percentage" for x and y compute a real x,y pair based on this drawing thing's height and width. If the drawing thing is rotated the computed point must then be rotated round the center of the drawing thing. We cannot depend on postscript rotation for this.

func (*DThing) Attachments

func (dt *DThing) Attachments() (src, target string)

Return the source and target drawing thing IDs that are referenced.

func (*DThing) BoundingBox

func (dt *DThing) BoundingBox() (minPt *RealPoint, maxPt *RealPoint)

Return the bounding box as two real points: min(x,y) and max(x,y)

func (*DThing) Centre

func (dt *DThing) Centre() (x int, y int)

Return the object's center assuming x,y is lleft.

func (*DThing) Dimensions

func (dt *DThing) Dimensions() (w int, h int)

Return the width, height of the element.

func (*DThing) Kind

func (dt *DThing) Kind() DthingKind

Return the kind of thing.

func (*DThing) Paint

func (dt *DThing) Paint(out io.Writer)

A drawing thing can paint itself, but it does require a certain amount of "soul searching" in order to discover what kind of thing that it is. To that end, and because there really isn't the need to manage specifically typed drawing things (e.g. dt_pgram) there are just a bunch of single function paint methods hung off of the DThing object.

func (*DThing) PaintCallOut added in v1.1.3

func (dt *DThing) PaintCallOut(out io.Writer)
	A callout is a commic style "thought" bubble
		_______  ......
        |      |     ^
        |      |     h
		|___  _|     V
           |/ .........

	Stype parameters are obtuse in the xml:
		position:	The percentage of the width of the left side of the "gap".
		position2: the X value as a percentaege of the width of the tip
					of the decender.
		base:		The length of the gap
		size:		The distance between the box's bottom and the tip of
					the decender.

	The postscript code wants x, y, width, height, x2,y2, x3, y3, x4,y4
	where x2,y2 is the point to the left of the gap, x3,y3 is the point of
	the decender, x4,y4 is the point of the right side of the gap.

	To postscript, height is the height of the box portion, not the overall
	thing.

func (*DThing) PaintCircle

func (dt *DThing) PaintCircle(out io.Writer)

The drawing thing's x,y is the upper left corner and the radius is computed by the boundng box. We can use this to draw ellipses/ovals as the bounding box constrains the circle properly.

func (*DThing) PaintCloud

func (dt *DThing) PaintCloud(out io.Writer)

Painting a cloud. x,y is upper left corner.

func (*DThing) PaintCylinder

func (dt *DThing) PaintCylinder(out io.Writer)

x,y of the cyl is upper left.

func (*DThing) PaintDashedLine

func (dt *DThing) PaintDashedLine(out io.Writer)

There is no need to handle dashed line differently.

func (*DThing) PaintFlexArrow

func (dt *DThing) PaintFlexArrow(out io.Writer)

func (*DThing) PaintHex added in v1.1.3

func (dt *DThing) PaintHex(out io.Writer)

Paint a hexagon; size in style is the "outset" of each right/left point. x,y is the upper left corner.

func (*DThing) PaintLine

func (dt *DThing) PaintLine(out io.Writer)

Paint the line and any associated arrows. Lines are complicated. Fiddling with the arrows, and the direction they need to point is only half of it. Seems that bleeding io.draw can't set source/target points correctly if the line is "attached" to an object. The "attachment point must be computed as a relationship to the attached object (because, I suppose, it is too tough to add the correct point coordinates when they write the XML).

If the line width is > 1 and there is an arrow, the end of the line must be pulled back to the edge of the arrow to prevent it from "showing" as the arrow comes to a point.

The diagram.io tool's representation of where text is placed for a line is just backwards. "top" puts the text under the line and left justified seems to move the text to the right. We do our own thing that limits the damage.

func (*DThing) PaintPGram

func (dt *DThing) PaintPGram(out io.Writer)

func (*DThing) PaintRect

func (dt *DThing) PaintRect(out io.Writer)

x,y is upper left corner

func (*DThing) PaintReport

func (dt *DThing) PaintReport(out io.Writer)

Paint a "report/ouput" thing

func (*DThing) PaintRhomb

func (dt *DThing) PaintRhomb(out io.Writer)

The user interface of diagrams.net calls it a diamond, but internally it is labeled a rhombus. The x,y point is upper left corner of the bounding box.

func (*DThing) PaintRoundRect

func (dt *DThing) PaintRoundRect(out io.Writer)

x,y is upper left

func (*DThing) PaintStep added in v1.1.3

func (dt *DThing) PaintStep(out io.Writer)
	A step (process step?)  is a chevron looking box:
		_______
        \      \
		/______/

	The "size" style parameter, if set, defines the 'indention' amount. If not set
	(why why why would it not be set???) we have to pick some magic default. When
	it is set there seem to be no units, so again we have to guess.

func (*DThing) PaintStorage

func (dt *DThing) PaintStorage(out io.Writer)

Paint a "storage" thing

func (*DThing) PaintTangle

func (dt *DThing) PaintTangle(out io.Writer)

Paint a triangle (always right facing). The tangle functions print the "point" at x,y so we must adjust x by the width and rotate accordingly.

func (*DThing) PaintText

func (dt *DThing) PaintText(out io.Writer)

Paint a text thing.

func (*DThing) PaintTrap added in v1.1.3

func (dt *DThing) PaintTrap(out io.Writer)

Paint a trapezoid.

func (*DThing) Points

func (dt *DThing) Points() []Point

Return the drawing thing's points. Youi'd think that points for a DThing would be easy, but io.D can't seem to set the source and target points correctly if the thing is "attached" to another thing. While mostly lines, we need to see of there is a source or targed defined in the thing's style and if there is we need to compute the point(s) and sub them into the array.

func (*DThing) RealPoints

func (dt *DThing) RealPoints() []*RealPoint

func (*DThing) Style

func (dt *DThing) Style() *Style

func (*DThing) XY

func (dt *DThing) XY() (int, int)

Return the x,y coordinate of the Drawing Thing.

postscript 0,0 is lowerleft while io.draw is upper left; we tranlate meaning y values become negative

type Diagram

type Diagram struct {
	Id   string  `xml:"id,attr"`
	Page []Model `xml:"mxGraphModel"`
}

The diagram contains one or more models which seems to be a page. (Though creating a new page in the tool crates a new diagram rather than adding a page to the diagram; sheesh!)

type Drawing

type Drawing struct {
	Things []DThing `xml:"mxCell"`
}

The drawing contains multiple drawing things which it calls cells.

type DthingKind

type DthingKind string

Drawing objets (mxCell) generally don't have a "type". Where you might expect to find a kind="circle" or type="rect" attr in the style string, none exists. So, a convoluted set of rules are needed to "map" a style to an object kind these rules are based on the syle string and implemented in style, but the kind of thing constants and API make sense to be here.

Line things, and maybe others, need to be able to find other drawing things in order to compute real src and target points when they are "attached". To that end, the object supports references for src and target things when they are defined.

type Geometry

type Geometry struct {
	X        string  `xml:"x,attr"`
	Y        string  `xml:"y,attr"`
	Width    string  `xml:"width,attr"`
	Height   string  `xml:"height,attr"`
	Points   []Point `xml:"mxPoint"` // seems to define the end points only (src and target)
	InnerPts Array   `xml:"Array"`
}

A drawing thing's geometry is described by the attributes in this portion.

func (*Geometry) AllPoints

func (gm *Geometry) AllPoints() []Point

Return all points from the drawing thing's geometry in a single array. The first point is the "source" and the last is the "target" if this matters to the caller.

func (*Geometry) HeightWidth

func (gm *Geometry) HeightWidth() (height, width int)

func (*Geometry) WidthHeight

func (gm *Geometry) WidthHeight() (width, height int)

type Model

type Model struct {
	Id       string  `xml:"id,attr"`
	PgHeight string  `xml:"pageHeight,attr"`
	PgWidth  string  `xml:"pageWidth,attr"`
	Slate    Drawing `xml:"root"`
}

The model's attibutes describe the overall page which is likely bigger than the bounding box. The drawing ("root") and height/width are the only things that seem useful:

dx="884" dy="695" grid="1" gridSize="10" guides="1" tooltips="1" connect="1"
arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100"
math="0" shadow="0">

func (*Model) LetterScale

func (m *Model) LetterScale() (float64, float64)

Given the drawings h/w compute the x,y scales to scale the drawing to a US-Letter sized page

type Point

type Point struct {
	X    string `xml:"x,attr"`
	Y    string `xml:"y,attr"`
	Kind string `xml:"as,attr"` // srcPoint or targetPoint
}

func (*Point) RealPt

func (pt *Point) RealPt() *RealPoint

Return a real point.

func (*Point) Set

func (pt *Point) Set(x, y int)

func (*Point) XY

func (pt *Point) XY() (x, y int)

func (*Point) XYf64

func (pt *Point) XYf64() (xf, yf float64)

type Position

type Position int

type RealPoint

type RealPoint struct {
	// contains filtered or unexported fields
}

------------------------- drawing support --------------------------------------------

Not to be confused with a layout Point which manages things
read from the XML as strings.

func NewRealPoint

func NewRealPoint(x int, y int) *RealPoint

func (*RealPoint) Paint

func (pt *RealPoint) Paint() string

Return the string needed to paint the point as a small square centered on the point's coordinates..

func (*RealPoint) PullBack

func (pt *RealPoint) PullBack(anchor *RealPoint, dist int) *RealPoint

Given a point, and an anchor point on the same line, compute the coords of the point dist units away from the point in the direction of the anchor point.

func (*RealPoint) Rotate

func (pt *RealPoint) Rotate(centre *RealPoint, angle float64) *RealPoint

Rotate the point angle degrees round the centre point. Returns a new point (old point left intact)

func (*RealPoint) SlideOver

func (pt *RealPoint) SlideOver(dist int, angle float64) *RealPoint

Given a point, compute a new point that is orthognal to pt at a distance of d. The angle assumes that a line runs through the point at the indicated angle (degrees).

func (*RealPoint) String

func (pt *RealPoint) String() string

Point as a string: "x,y"

func (*RealPoint) XY

func (pt *RealPoint) XY() (int, int)

Return the x,y coordinate of the point

type Sketch

type Sketch struct {
	// contains filtered or unexported fields
}

func NewSketch

func NewSketch(fname string) (*Sketch, error)

Opens the named file and loads the XML drawing. After it is loaded, all pages are searched to create a map of the drawing things. The map is traversed to set any references that the drawing things have to other DTs.

func (*Sketch) BoundingBox

func (sk *Sketch) BoundingBox() (minPt *RealPoint, maxPt *RealPoint)

Returns the bounding box which contains all of the elements.

func (*Sketch) EleCount

func (sk *Sketch) EleCount() int

Return the count of elements.

func (*Sketch) Element

func (sk *Sketch) Element(e int) *DThing

------ current page oriented things ------------------------------------------

Returns the sketch element 'e' or nil if e is out of range.

func (*Sketch) FirstSketch

func (sk *Sketch) FirstSketch()

------------ page oriented things -------------------------------------------

Select the first sketch in the file.

func (*Sketch) NextSketch

func (sk *Sketch) NextSketch() bool

Select the next page; return false if no more pages.

func (*Sketch) PageScale

func (sk *Sketch) PageScale() (float64, float64)

Returns the x,y scale for the page.

func (*Sketch) Pages

func (sk *Sketch) Pages() int

Returns the number of pages in the drawing.

func (*Sketch) SelectPage

func (sk *Sketch) SelectPage(p int)

If the drawing has multiple pages, allow the desird page to be selected. If p goes out of bounds, no change is made.

func (*Sketch) SelectSketch

func (sk *Sketch) SelectSketch(p int)

Select the desired sketch from the file.

type Style

type Style struct {
	// contains filtered or unexported fields
}

func (*Style) Add

func (s *Style) Add(sKey StyleKey, value string)

Allows a style to be updated with a key/value pair after it has been created by parsing a string. This is needed for things like adding font selection via means other than the style string in either the XML or embedded HTML.

func (*Style) Align

func (s *Style) Align() Alignment

func (*Style) ArrowKind

func (s *Style) ArrowKind() (srcKind arrowKind, targetKind arrowKind)

Dig out the arrow type for both ends and return. If the type is not defined (none) or is not recognised, arrowNone is returned.

func (*Style) ArrowLoc

func (s *Style) ArrowLoc() (atSrc, atTarget bool)

A line may have an arrow at one or both ends. This method returns atSrc true if there is an arrow at the point which is marked as the start, and similarly if an arrow is applied to the point marked as the target.

The IO.draw XML seems to treat EndArrow as the source and StartArrow as the target.

func (*Style) DtKind

func (s *Style) DtKind() DthingKind

Look at the style for the thing and determine what kind of a thing it is. Returns a dThing constant.

Bloody thing can't set a shape= for everything. In some cases there is a single token description (e.g. ellipse) with shape= set sometimes, but not always. Lots of edge cases.

func (*Style) DumpSettings

func (s *Style) DumpSettings()

--------------------------- debugging ------------------------------------------------

Dump the map; mostly for debugging

func (*Style) FillColour

func (s *Style) FillColour() string

func (*Style) FloatValue added in v1.1.3

func (s *Style) FloatValue(key StyleKey, defVal float32) (val float32)

Returns the value from style, or the default if missing.

func (*Style) FontColour

func (s *Style) FontColour() string

Pick out the colurs as postscript values (tripples).

func (*Style) FontSz

func (s *Style) FontSz() int

func (*Style) IntValue added in v1.1.3

func (s *Style) IntValue(key StyleKey, defVal int) (val int)

Return the value for the given key as an int or the default value if it's not there.

func (*Style) IsSet

func (s *Style) IsSet(sk StyleKey) bool

Return true if the key is set in the map.

func (*Style) IsSetWith

func (s *Style) IsSetWith(sk StyleKey, val string) bool

Return true if the key is set in the map and has the given value.

func (*Style) LabelPos

func (s *Style) LabelPos() Position

Return the horizontal label position.

func (*Style) LineColour

func (s *Style) LineColour() string

func (*Style) Rotation

func (s *Style) Rotation() int

Return the rotation amount (degrees)

func (*Style) Size added in v1.1.3

func (s *Style) Size() int

Return the size. If found in style, it is >= 0 if missing, and caller must use its own default, -1 is returned.

func (*Style) VAlign

func (s *Style) VAlign() Alignment

func (*Style) Value

func (s *Style) Value(key StyleKey) (val string, isThere bool)

------------------ value functions ---------------------------------------------------

Given a key, fetch the value. The return bool is false if the key isn't in the style.

func (*Style) VertLabelPos

func (s *Style) VertLabelPos() Position

Return the vertical label position.

type StyleKey

type StyleKey string

The style settings are keyed off of the names in the XML. To insulate the code as best we can from changes to the XML names, the style key name constants should be used to interact with the settings map. There are also synonyms because some of the embedded HTML has different strings associated with the same style setting.

type StyleStack

type StyleStack struct {
	// contains filtered or unexported fields
}

The stack is a first on first off stack.

func NewStyleStack

func NewStyleStack(defStyle *Style) *StyleStack

func (*StyleStack) Clear

func (ss *StyleStack) Clear()

Clear the whole stack keeping the base (not removable)

func (*StyleStack) Dump

func (ss *StyleStack) Dump()

func (*StyleStack) Len

func (ss *StyleStack) Len() int

Returns the number of things on the stack. Mostly for testing.

func (*StyleStack) Pop

func (ss *StyleStack) Pop()

Pop the most recently added style from the stack. The base style cannot be popped.

func (*StyleStack) Push

func (ss *StyleStack) Push(new *Style)

Push the style onto the top of the stack. If the stack size needs to be increased, it will be.

func (*StyleStack) Value

func (ss *StyleStack) Value(sKey StyleKey) (string, bool)

Return the value for the given key. Styles stack, and we return the most recently defined style on the stack staring with the top style. If the style isn't defined on the stack, then the booliean returned is set to false.

Jump to

Keyboard shortcuts

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