girl

package
v1.3.25 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2023 License: BSD-3-Clause Imports: 48 Imported by: 13

README

GiRl

GiRl is the GoGi render library -- renders to an image.RGBA using styles defined in GiSt styles.

The original rendering design borrowed heavily from: https://github.com/fogleman/gg

And was subsequently integrated with https://github.com/srwiley/rasterx which, provides SVG compliant and fast rendering.

The svg package provides Node types, which can be created by parsing a standard SVG file, that use this rendering library to render standard SVG images. These are used for the icons in GoGi.

The basic structure for rendering is in two objects:

  • girl.Paint has the styles, and methods for drawing.

  • girl.State has all the underlying rendering state, and the Paint methods take state as the first arg.

This is useful for allowing multiple different painters to all render onto a common back-end image controlled by the girl.State object. In GoGi, the Viewport2D has the shared girl.State, while each Widget or SVG Node has its own girl.Paint object and styles.

It would be easy to use GiRl separate from the broader GoGi system -- there are just two "hooks" that need to be set, both in the gist style system:

  • ThePrefs needs to be set a preferences object that satisfies the Prefs interface to provide user-settable preferences (just for colors and fonts).

  • Context is passed to styling functions that for some color names that refer to a current color -- it is optional and will be ignored if nil.

In addition, the styles need a properly initialized units.Context to be passed to the ToDots method that converts all the various units into concrete physical pixels that will be rendered.

Text layout

The complex task of laying out text is handled by the girl.Text system, which has spans of runes, with full styling information that handles all the standard HTML-style markup, including underlining, super / subscripts, rotation, etc.

This framework is sufficient for all forms of bidirectional / vertical text layout etc, but only the left-right case has been implemented at this point.

Styling, Formatting / Layout, and Rendering are each handled separately as three different levels in the stack -- this simplifies many things to separate in this way, and makes the final render pass maximally efficient and high-performance, at the potential cost of some memory redundancy.

Documentation

Overview

Package GiRl is the GoGi render library -- renders to an image.RGBA using styles defined in GiSt styles

Original rendering borrows heavily from: https://github.com/fogleman/gg and has been integrated with https://github.com/srwiley/rasterx which provides fully SVG compliant and fast rendering.

Index

Constants

View Source
const MaxDx float32 = math.Pi / 8

MaxDx is the Maximum radians a cubic splice is allowed to span in ellipse parametric when approximating an off-axis ellipse.

Variables

View Source
var FontExts = map[string]struct{}{
	".ttf": {},
	".ttc": {},
	".otf": {},
}
View Source
var FontFallbacks = map[string]string{
	"serif":            "Times New Roman",
	"times":            "Times New Roman",
	"Times New Roman":  "Liberation Serif",
	"Liberation Serif": "NotoSerif",
	"sans-serif":       "NotoSans",
	"NotoSans":         "Go",
	"courier":          "Courier",
	"Courier":          "Courier New",
	"Courier New":      "NotoSansMono",
	"NotoSansMono":     "Go Mono",
	"monospace":        "NotoSansMono",
	"cursive":          "Comic Sans",
	"Comic Sans":       "Comic Sans MS",
	"fantasy":          "Impact",
	"Impact":           "Impac",
}

FontFallbacks are a list of fallback fonts to try, at the basename level. Make sure there are no loops! Include Noto versions of everything in this because they have the most stretch options, so they should be in the mix if they have been installed, and include "Go" options last.

View Source
var FontInfoExample = "AaBbCcIiPpQq12369$€¢?.:/()àáâãäåæç日本中国⇧⌘"

FontInfoExample is example text to demonstrate fonts -- from Inkscape plus extra

View Source
var GoFonts = map[string]GoFontInfo{
	"gofont/goregular":         {"Go", goregular.TTF},
	"gofont/gobold":            {"Go Bold", gobold.TTF},
	"gofont/gobolditalic":      {"Go Bold Italic", gobolditalic.TTF},
	"gofont/goitalic":          {"Go Italic", goitalic.TTF},
	"gofont/gomedium":          {"Go Medium", gomedium.TTF},
	"gofont/gomediumitalic":    {"Go Medium Italic", gomediumitalic.TTF},
	"gofont/gomono":            {"Go Mono", gomono.TTF},
	"gofont/gomonobold":        {"Go Mono Bold", gomonobold.TTF},
	"gofont/gomonobolditalic":  {"Go Mono Bold Italic", gomonobolditalic.TTF},
	"gofont/gomonoitalic":      {"Go Mono Italic", gomonoitalic.TTF},
	"gofont/gosmallcaps":       {"Go Small Caps", gosmallcaps.TTF},
	"gofont/gosmallcapsitalic": {"Go Small Caps Italic", gosmallcapsitalic.TTF},
}
View Source
var TextFontRenderMu sync.Mutex

TextFontRenderMu mutex is required because multiple different goroutines associated with different windows can (and often will be) call font stuff at the same time (curFace.GlyphAdvance, rendering font) at the same time, on the same font face -- and that turns out not to work!

View Source
var URLHandler = func(url string) bool {
	if oswin.TheApp != nil {
		oswin.TheApp.OpenURL(url)
		return true
	}
	return false
}

URLHandler is used to handle URL links, if non-nil -- set this to your own handler to process URL's, depending on TextLinkHandler -- the default version of this function just calls oswin.TheApp.OpenURL -- setting this to nil will prevent any links from being open that way, and your own function will have full responsibility for links if set (i.e., the return value is ignored)

Functions

func FindEllipseCenter

func FindEllipseCenter(rx, ry *float32, rotX, startX, startY, endX, endY float32, sweep, largeArc bool) (cx, cy float32)

FindEllipseCenter locates the center of the Ellipse if it exists. If it does not exist, the radius values will be increased minimally for a solution to be possible while preserving the rx to rb ratio. rx and rb arguments are pointers that can be checked after the call to see if the values changed. This method uses coordinate transformations to reduce the problem to finding the center of a circle that includes the origin and an arbitrary point. The center of the circle is then transformed back to the original coordinates and returned.

func FontAlts

func FontAlts(fams string) (fns []string, serif, mono bool)

FontAlts generates a list of all possible alternative fonts that actually exist in font library for a list of font families, and a guess as to whether the font is a serif (vs sans) or monospaced (vs proportional) font. Only deals with base names.

func FontFaceName

func FontFaceName(fam string, str gist.FontStretch, wt gist.FontWeights, sty gist.FontStyles) string

FontFaceName returns the best full FaceName to use for the given font family(ies) (comma separated) and modifier parameters

func FontSerifMonoGuess

func FontSerifMonoGuess(fns []string) (serif, mono bool)

FontSerifMonoGuess looks at a list of alternative font names and tires to guess if the font is a serif (vs sans) or monospaced (vs proportional) font.

func FontStyleCSS

func FontStyleCSS(fs *gist.Font, tag string, cssAgg ki.Props, unit *units.Context, ctxt gist.Context) bool

FontStyleCSS looks for "tag" name props in cssAgg props, and applies those to style if found, and returns true -- false if no such tag found

func NextRuneAt

func NextRuneAt(str string, idx int) rune

NextRuneAt returns the next rune starting from given index -- could be at that index or some point thereafter -- returns utf8.RuneError if no valid rune could be found -- this should be a standard function!

func OpenFont

func OpenFont(fs *gist.Font, ctxt *units.Context)

OpenFont loads the font specified by the font style from the font library. This is the primary method to use for loading fonts, as it uses a robust fallback method to finding an appropriate font, and falls back on the builtin Go font as a last resort. The Face field will have the resulting font. The font size is always rounded to nearest integer, to produce better-looking results (presumably). The current metrics and given unit.Context are updated based on the properties of the font.

func OpenFontFace

func OpenFontFace(name, path string, size int, strokeWidth int) (*gist.FontFace, error)

OpenFontFace loads a font file at given path, with given raw size in display dots, and if strokeWidth is > 0, the font is drawn in outline form (stroked) instead of filled (supported in SVG). loadFontMu must be locked prior to calling

func OpenGoFont

func OpenGoFont(name, path string, size int, strokeWidth int) (*gist.FontFace, error)

func SetHTMLSimpleTag

func SetHTMLSimpleTag(tag string, fs *gist.Font, ctxt *units.Context, cssAgg ki.Props) bool

SetHTMLSimpleTag sets the styling parameters for simple html style tags that only require updating the given font spec values -- returns true if handled https://www.w3schools.com/cssref/css_default_values.asp

Types

type FontInfo

type FontInfo struct {
	Name    string           `desc:"official regularized name of font"`
	Stretch gist.FontStretch `xml:"stretch" desc:"stretch: normal, expanded, condensed, etc"`
	Weight  gist.FontWeights `xml:"weight" desc:"weight: normal, bold, etc"`
	Style   gist.FontStyles  `xml:"style" desc:"style -- normal, italic, etc"`
	Example string           `desc:"example text -- styled according to font params in chooser"`
}

FontInfo contains basic font information for choosing a given font -- displayed in the font chooser dialog.

func (FontInfo) Label

func (fi FontInfo) Label() string

Label satisfies the Labeler interface

type FontLib

type FontLib struct {
	FontPaths  []string                          `desc:"list of font paths to search for fonts"`
	FontsAvail map[string]string                 `desc:"map of font name to path to file"`
	FontInfo   []FontInfo                        `desc:"information about each font -- this list should be used for selecting valid regularized font names"`
	Faces      map[string]map[int]*gist.FontFace `desc:"double-map of cached fonts, by font name and then integer font size within that"`
}

FontLib holds the fonts available in a font library. The font name is regularized so that the base "Regular" font is the root term of a sequence of other font names that describe the stretch, weight, and style, e.g., "Arial" as the base name, "Arial Bold", "Arial Bold Italic" etc. Thus, each font name specifies a particular font weight and style. When fonts are loaded into the library, the names are appropriately regularized.

var FontLibrary FontLib

FontLibrary is the gi font library, initialized from fonts available on font paths

func (*FontLib) AddFontPaths

func (fl *FontLib) AddFontPaths(paths ...string) bool

func (*FontLib) DeleteFont

func (fl *FontLib) DeleteFont(fontnm string)

DeleteFont removes given font from list of available fonts -- if not supported etc

func (*FontLib) Font

func (fl *FontLib) Font(fontnm string, size int) (*gist.FontFace, error)

Font gets a particular font, specified by the official regularized font name (see FontsAvail list), at given dots size (integer), using a cache of loaded fonts.

func (*FontLib) FontAvail

func (fl *FontLib) FontAvail(fontnm string) bool

FontAvail determines if a given font name is available (case insensitive)

func (*FontLib) FontsAvailFromPath

func (fl *FontLib) FontsAvailFromPath(path string) error

FontsAvailFromPath scans for all fonts we can use on a given path, gathering info into FontsAvail and FontInfo.

func (*FontLib) GoFontsAvail

func (fl *FontLib) GoFontsAvail()

func (*FontLib) Init

func (fl *FontLib) Init()

Init initializes the font library if it hasn't been yet

func (*FontLib) InitFontPaths

func (fl *FontLib) InitFontPaths(paths ...string)

InitFontPaths initializes font paths to system defaults, only if no paths have yet been set

func (*FontLib) OpenAllFonts

func (fl *FontLib) OpenAllFonts(size int)

OpenAllFonts attempts to load all fonts that were found -- call this before displaying the font chooser to eliminate any bad fonts.

func (*FontLib) UpdateFontsAvail

func (fl *FontLib) UpdateFontsAvail() bool

UpdateFontsAvail scans for all fonts we can use on the FontPaths

type GoFontInfo

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

type Paint

type Paint struct {
	gist.Paint
}

Paint provides the styling parameters and methods for rendering on to an RGBA image -- all dynamic rendering state is maintained in the State. Text rendering is handled separately in TextRender, but it depends minimally on styling parameters in FontStyle

func NewPaint

func NewPaint() Paint

func (*Paint) AsMask

func (pc *Paint) AsMask(rs *State) *image.Alpha

AsMask returns an *image.Alpha representing the alpha channel of this context. This can be useful for advanced clipping operations where you first render the mask geometry and then use it as a mask.

func (*Paint) BoundingBox

func (pc *Paint) BoundingBox(rs *State, minX, minY, maxX, maxY float32) image.Rectangle

BoundingBox computes the bounding box for an element in pixel int coordinates, applying current transform

func (*Paint) BoundingBoxFromPoints

func (pc *Paint) BoundingBoxFromPoints(rs *State, points []mat32.Vec2) image.Rectangle

BoundingBoxFromPoints computes the bounding box for a slice of points

func (*Paint) Clear

func (pc *Paint) Clear(rs *State)

Clear fills the entire image with the current fill color.

func (*Paint) ClearPath

func (pc *Paint) ClearPath(rs *State)

ClearPath clears the current path. There is no current point after this operation.

func (*Paint) Clip

func (pc *Paint) Clip(rs *State)

Clip updates the clipping region by intersecting the current clipping region with the current path as it would be filled by pc.Fill(). The path is cleared after this operation.

func (*Paint) ClipPreserve

func (pc *Paint) ClipPreserve(rs *State)

ClipPreserve updates the clipping region by intersecting the current clipping region with the current path as it would be filled by pc.Fill(). The path is preserved after this operation.

func (*Paint) ClosePath

func (pc *Paint) ClosePath(rs *State)

ClosePath adds a line segment from the current point to the beginning of the current subpath. If there is no current point, this is a no-op.

func (*Paint) CubicTo

func (pc *Paint) CubicTo(rs *State, x1, y1, x2, y2, x3, y3 float32)

CubicTo adds a cubic bezier curve to the current path starting at the current point. If there is no current point, it first performs MoveTo(x1, y1).

func (*Paint) DrawArc

func (pc *Paint) DrawArc(rs *State, x, y, r, angle1, angle2 float32)

func (*Paint) DrawCircle

func (pc *Paint) DrawCircle(rs *State, x, y, r float32)

func (*Paint) DrawEllipse

func (pc *Paint) DrawEllipse(rs *State, x, y, rx, ry float32)

func (*Paint) DrawEllipticalArc

func (pc *Paint) DrawEllipticalArc(rs *State, cx, cy, rx, ry, angle1, angle2 float32)

DrawEllipticalArc draws arc between angle1 and angle2 along an ellipse, using quadratic bezier curves -- centers of ellipse are at cx, cy with radii rx, ry -- see DrawEllipticalArcPath for a version compatible with SVG A/a path drawing, which uses previous position instead of two angles

func (*Paint) DrawEllipticalArcPath

func (pc *Paint) DrawEllipticalArcPath(rs *State, cx, cy, ocx, ocy, pcx, pcy, rx, ry, angle float32, largeArc, sweep bool) (lx, ly float32)

DrawEllipticalArcPath is draws an arc centered at cx,cy with radii rx, ry, through given angle, either via the smaller or larger arc, depending on largeArc -- returns in lx, ly the last points which are then set to the current cx, cy for the path drawer

func (*Paint) DrawImage

func (pc *Paint) DrawImage(rs *State, fmIm image.Image, x, y float32)

DrawImage draws the specified image at the specified point.

func (*Paint) DrawImageAnchored

func (pc *Paint) DrawImageAnchored(rs *State, fmIm image.Image, x, y, ax, ay float32)

DrawImageAnchored draws the specified image at the specified anchor point. The anchor point is x - w * ax, y - h * ay, where w, h is the size of the image. Use ax=0.5, ay=0.5 to center the image at the specified point.

func (*Paint) DrawImageScaled added in v1.2.0

func (pc *Paint) DrawImageScaled(rs *State, fmIm image.Image, x, y, w, h float32)

DrawImageScaled draws the specified image starting at given upper-left point, such that the size of the image is rendered as specified by w, h parameters (an additional scaling is applied to the transform matrix used in rendering)

func (*Paint) DrawLine

func (pc *Paint) DrawLine(rs *State, x1, y1, x2, y2 float32)

func (*Paint) DrawPolygon

func (pc *Paint) DrawPolygon(rs *State, points []mat32.Vec2)

func (*Paint) DrawPolygonPxToDots

func (pc *Paint) DrawPolygonPxToDots(rs *State, points []mat32.Vec2)

func (*Paint) DrawPolyline

func (pc *Paint) DrawPolyline(rs *State, points []mat32.Vec2)

func (*Paint) DrawPolylinePxToDots

func (pc *Paint) DrawPolylinePxToDots(rs *State, points []mat32.Vec2)

func (*Paint) DrawRectangle

func (pc *Paint) DrawRectangle(rs *State, x, y, w, h float32)

func (*Paint) DrawRegularPolygon

func (pc *Paint) DrawRegularPolygon(rs *State, n int, x, y, r, rotation float32)

func (*Paint) DrawRoundedRectangle

func (pc *Paint) DrawRoundedRectangle(rs *State, x, y, w, h, r float32)

func (*Paint) Fill

func (pc *Paint) Fill(rs *State)

Fill fills the current path with the current color. Open subpaths are implicitly closed. The path is cleared after this operation.

func (*Paint) FillBox

func (pc *Paint) FillBox(rs *State, pos, size mat32.Vec2, clr *gist.ColorSpec)

FillBox is an optimized fill of a square region with a uniform color if the given color spec is a solid color

func (*Paint) FillBoxColor

func (pc *Paint) FillBoxColor(rs *State, pos, size mat32.Vec2, clr color.Color)

FillBoxColor is an optimized fill of a square region with given uniform color

func (*Paint) FillPreserve

func (pc *Paint) FillPreserve(rs *State)

FillPreserve fills the current path with the current color. Open subpaths are implicitly closed. The path is preserved after this operation.

func (*Paint) FillStrokeClear

func (pc *Paint) FillStrokeClear(rs *State)

convenience for final draw for shapes when done

func (*Paint) Identity

func (pc *Paint) Identity()

Identity resets the current transformation matrix to the identity matrix. This results in no translating, scaling, rotating, or shearing.

func (*Paint) InvertY

func (pc *Paint) InvertY(rs *State)

InvertY flips the Y axis so that Y grows from bottom to top and Y=0 is at the bottom of the image.

func (*Paint) LineTo

func (pc *Paint) LineTo(rs *State, x, y float32)

LineTo adds a line segment to the current path starting at the current point. If there is no current point, it is equivalent to MoveTo(x, y)

func (*Paint) MoveTo

func (pc *Paint) MoveTo(rs *State, x, y float32)

MoveTo starts a new subpath within the current path starting at the specified point.

func (*Paint) NewSubPath

func (pc *Paint) NewSubPath(rs *State)

NewSubPath starts a new subpath within the current path. There is no current point after this operation.

func (*Paint) QuadraticTo

func (pc *Paint) QuadraticTo(rs *State, x1, y1, x2, y2 float32)

QuadraticTo adds a quadratic bezier curve to the current path starting at the current point. If there is no current point, it first performs MoveTo(x1, y1)

func (*Paint) ResetClip

func (pc *Paint) ResetClip(rs *State)

ResetClip clears the clipping region.

func (*Paint) Rotate

func (pc *Paint) Rotate(angle float32)

Rotate updates the current matrix with a clockwise rotation. Rotation occurs about the origin. Angle is specified in radians.

func (*Paint) RotateAbout

func (pc *Paint) RotateAbout(angle, x, y float32)

RotateAbout updates the current matrix with a clockwise rotation. Rotation occurs about the specified point. Angle is specified in radians.

func (*Paint) Scale

func (pc *Paint) Scale(x, y float32)

Scale updates the current matrix with a scaling factor. Scaling occurs about the origin.

func (*Paint) ScaleAbout

func (pc *Paint) ScaleAbout(sx, sy, x, y float32)

ScaleAbout updates the current matrix with a scaling factor. Scaling occurs about the specified point.

func (*Paint) SetMask

func (pc *Paint) SetMask(rs *State, mask *image.Alpha) error

SetMask allows you to directly set the *image.Alpha to be used as a clipping mask. It must be the same size as the context, else an error is returned and the mask is unchanged.

func (*Paint) SetPixel

func (pc *Paint) SetPixel(rs *State, x, y int)

SetPixel sets the color of the specified pixel using the current stroke color.

func (*Paint) Shear

func (pc *Paint) Shear(x, y float32)

Shear updates the current matrix with a shearing angle. Shearing occurs about the origin.

func (*Paint) ShearAbout

func (pc *Paint) ShearAbout(sx, sy, x, y float32)

ShearAbout updates the current matrix with a shearing angle. Shearing occurs about the specified point.

func (*Paint) Stroke

func (pc *Paint) Stroke(rs *State)

Stroke strokes the current path with the current color, line width, line cap, line join and dash settings. The path is cleared after this operation.

func (*Paint) StrokePreserve

func (pc *Paint) StrokePreserve(rs *State)

StrokePreserve strokes the current path with the current color, line width, line cap, line join and dash settings. The path is preserved after this operation.

func (*Paint) StrokeWidth

func (pc *Paint) StrokeWidth(rs *State) float32

StrokeWidth obtains the current stoke width subject to transform (or not depending on VecEffNonScalingStroke)

func (*Paint) TransformPoint

func (pc *Paint) TransformPoint(rs *State, x, y float32) mat32.Vec2

TransformPoint multiplies the specified point by the current transform matrix, returning a transformed position.

func (*Paint) Translate

func (pc *Paint) Translate(x, y float32)

Translate updates the current matrix with a translation.

type Rune

type Rune struct {
	Face    font.Face            `` /* 157-byte string literal not displayed */
	Color   color.Color          `json:"-" xml:"-" desc:"color to draw characters in"`
	BgColor color.Color          `` /* 233-byte string literal not displayed */
	Deco    gist.TextDecorations `` /* 217-byte string literal not displayed */
	RelPos  mat32.Vec2           `desc:"relative position from start of Text for the lower-left baseline rendering position of the font character"`
	Size    mat32.Vec2           `desc:"size of the rune itself, exclusive of spacing that might surround it"`
	RotRad  float32              `desc:"rotation in radians for this character, relative to its lower-left baseline rendering position"`
	ScaleX  float32              `desc:"scaling of the X dimension, in case of non-uniform scaling, 0 = no separate scaling"`
}

Rune contains fully explicit data needed for rendering a single rune -- Face and Color can be nil after first element, in which case the last non-nil is used -- likely slightly more efficient to avoid setting all those pointers -- float32 values used to support better accuracy when transforming points

func (*Rune) CurColor

func (rr *Rune) CurColor(curColor color.Color) color.Color

CurColor is convenience for updating current color if non-nil

func (*Rune) CurFace

func (rr *Rune) CurFace(curFace font.Face) font.Face

CurFace is convenience for updating current font face if non-nil

func (*Rune) HasNil

func (rr *Rune) HasNil() error

HasNil returns error if any of the key info (face, color) is nil -- only the first element must be non-nil

func (*Rune) RelPosAfterLR

func (rr *Rune) RelPosAfterLR() float32

RelPosAfterLR returns the relative position after given rune for LR order: RelPos.X + Size.X

func (*Rune) RelPosAfterRL

func (rr *Rune) RelPosAfterRL() float32

RelPosAfterRL returns the relative position after given rune for RL order: RelPos.X - Size.X

func (*Rune) RelPosAfterTB

func (rr *Rune) RelPosAfterTB() float32

RelPosAfterTB returns the relative position after given rune for TB order: RelPos.Y + Size.Y

type Span

type Span struct {
	Text    []rune               `desc:"text as runes"`
	Render  []Rune               `desc:"render info for each rune in one-to-one correspondence"`
	RelPos  mat32.Vec2           `` /* 289-byte string literal not displayed */
	LastPos mat32.Vec2           `` /* 235-byte string literal not displayed */
	Dir     gist.TextDirections  `desc:"where relevant, this is the (default, dominant) text direction for the span"`
	HasDeco gist.TextDecorations `desc:"mask of decorations that have been set on this span -- optimizes rendering passes"`
}

Span contains fully explicit data needed for rendering a span of text as a slice of runes, with rune and Rune elements in one-to-one correspondence (but any nil values will use prior non-nil value -- first rune must have all non-nil). Text can be oriented in any direction -- the only constraint is that it starts from a single starting position. Typically only text within a span will obey kerning. In standard Text context, each span is one line of text -- should not have new lines within the span itself. In SVG special cases (e.g., TextPath), it can be anything. It is NOT synonymous with the HTML <span> tag, as many styling applications of that tag can be accommodated within a larger span-as-line. The first Rune RelPos for LR text should be at X=0 (LastPos = 0 for RL) -- i.e., relpos positions are minimal for given span.

func (*Span) AppendRune

func (sr *Span) AppendRune(r rune, face font.Face, clr, bg color.Color, deco gist.TextDecorations)

AppendRune adds one rune and associated formatting info

func (*Span) AppendString

func (sr *Span) AppendString(str string, face font.Face, clr, bg color.Color, deco gist.TextDecorations, sty *gist.Font, ctxt *units.Context)

AppendString adds string and associated formatting info, optimized with only first rune having non-nil face and color settings

func (*Span) FindWrapPosLR

func (sr *Span) FindWrapPosLR(trgSize, curSize float32) int

FindWrapPosLR finds a position to do word wrapping to fit within trgSize -- RelPos positions must have already been set (e.g., SetRunePosLR)

func (*Span) HasDecoUpdate

func (sr *Span) HasDecoUpdate(bg color.Color, deco gist.TextDecorations)

AppendRune adds one rune and associated formatting info

func (*Span) Init

func (sr *Span) Init(capsz int)

Init initializes a new span with given capacity

func (*Span) IsNewPara

func (sr *Span) IsNewPara() bool

IsNewPara returns true if this span starts a new paragraph

func (*Span) IsValid

func (sr *Span) IsValid() error

IsValid ensures that at least some text is represented and the sizes of Text and Render slices are the same, and that the first render info is non-nil

func (*Span) LastFont

func (sr *Span) LastFont() (face font.Face, color color.Color)

LastFont finds the last font and color from given span

func (*Span) RenderBg

func (sr *Span) RenderBg(rs *State, tpos mat32.Vec2)

RenderBg renders the background behind chars

func (*Span) RenderLine

func (sr *Span) RenderLine(rs *State, tpos mat32.Vec2, deco gist.TextDecorations, ascPct float32)

RenderLine renders overline or line-through -- anything that is a function of ascent

func (*Span) RenderUnderline

func (sr *Span) RenderUnderline(rs *State, tpos mat32.Vec2)

RenderUnderline renders the underline for span -- ensures continuity to do it all at once

func (*Span) RuneEndPos

func (sr *Span) RuneEndPos(idx int) mat32.Vec2

RuneEndPos returns the relative ending position of the given rune index (adds Span RelPos and rune RelPos + rune Size.X for LR writing). If index > length, then uses LastPos

func (*Span) RuneRelPos

func (sr *Span) RuneRelPos(idx int) mat32.Vec2

RuneRelPos returns the relative (starting) position of the given rune index (adds Span RelPos and rune RelPos) -- this is typically the baseline position where rendering will start, not the upper left corner. if index > length, then uses LastPos

func (*Span) SetNewPara

func (sr *Span) SetNewPara()

SetNewPara sets this as starting a new paragraph

func (*Span) SetRenders

func (sr *Span) SetRenders(sty *gist.Font, ctxt *units.Context, noBG bool, rot, scalex float32)

SetRenders sets rendering parameters based on style

func (*Span) SetRunePosLR

func (sr *Span) SetRunePosLR(letterSpace, wordSpace, chsz float32, tabSize int)

SetRunePosLR sets relative positions of each rune using a flat left-to-right text layout, based on font size info and additional extra letter and word spacing parameters (which can be negative)

func (*Span) SetRunePosTB

func (sr *Span) SetRunePosTB(letterSpace, wordSpace, chsz float32, tabSize int)

SetRunePosTB sets relative positions of each rune using a flat top-to-bottom text layout -- i.e., letters are in their normal upright orientation, but arranged vertically.

func (*Span) SetRunePosTBRot

func (sr *Span) SetRunePosTBRot(letterSpace, wordSpace, chsz float32, tabSize int)

SetRunePosTBRot sets relative positions of each rune using a flat top-to-bottom text layout, with characters rotated 90 degress based on font size info and additional extra letter and word spacing parameters (which can be negative)

func (*Span) SetRunes

func (sr *Span) SetRunes(str []rune, sty *gist.Font, ctxt *units.Context, noBG bool, rot, scalex float32)

SetRunes initializes to given plain rune string, with given default style parameters that are set for the first render element -- constructs Render slice of same size as Text

func (*Span) SetString

func (sr *Span) SetString(str string, sty *gist.Font, ctxt *units.Context, noBG bool, rot, scalex float32)

SetString initializes to given plain text string, with given default style parameters that are set for the first render element -- constructs Render slice of same size as Text

func (*Span) SizeHV

func (sr *Span) SizeHV() mat32.Vec2

SizeHV computes the size of the text span from the first char to the last position, which is valid for purely horizontal or vertical text lines -- either X or Y will be zero depending on orientation

func (*Span) SplitAtLR

func (sr *Span) SplitAtLR(idx int) *Span

SplitAt splits current span at given index, returning a new span with remainder after index -- space is trimmed from both spans and relative positions updated, for LR direction

func (*Span) TrimSpaceLR

func (sr *Span) TrimSpaceLR()

TrimSpace trims leading and trailing space elements from span, and updates the relative positions accordingly, for LR direction

func (*Span) TrimSpaceLeftLR

func (sr *Span) TrimSpaceLeftLR()

TrimSpaceLeft trims leading space elements from span, and updates the relative positions accordingly, for LR direction

func (*Span) TrimSpaceRightLR

func (sr *Span) TrimSpaceRightLR()

TrimSpaceRight trims trailing space elements from span, and updates the relative positions accordingly, for LR direction

func (*Span) ZeroPosLR

func (sr *Span) ZeroPosLR()

ZeroPos ensures that the positions start at 0, for LR direction

type State

type State struct {
	Paint  Paint           `desc:"communal painter -- for widgets -- SVG have their own"`
	XForm  mat32.Mat2      `desc:"current transform"`
	Path   rasterx.Path    `desc:"current path"`
	Raster *rasterx.Dasher `desc:"rasterizer -- stroke / fill rendering engine from rasterx"`
	//	Scanner        *scanFT.ScannerFT `desc:"scanner for freetype-based rasterx"`
	// CompSpanner    *scanx.CompressSpanner `desc:"spanner for scanx"`
	Scanner        *scanx.Scanner    `desc:"scanner for scanx"`
	ImgSpanner     *scanx.ImgSpanner `desc:"spanner for scanx"`
	Start          mat32.Vec2        `desc:"starting point, for close path"`
	Current        mat32.Vec2        `desc:"current point"`
	HasCurrent     bool              `desc:"is current point current?"`
	Image          *image.RGBA       `desc:"pointer to image to render into"`
	Mask           *image.Alpha      `desc:"current mask"`
	Bounds         image.Rectangle   `` /* 136-byte string literal not displayed */
	LastRenderBBox image.Rectangle   `desc:"bounding box of last object rendered -- computed by renderer during Fill or Stroke, grabbed by SVG objects"`
	XFormStack     []mat32.Mat2      `desc:"stack of transforms"`
	BoundsStack    []image.Rectangle `desc:"stack of bounds -- every render starts with a push onto this stack, and finishes with a pop"`
	ClipStack      []*image.Alpha    `desc:"stack of clips, if needed"`
	PaintBack      Paint             `desc:"backup of paint -- don't need a full stack but sometimes safer to backup and restore"`
	RenderMu       sync.Mutex        `desc:"mutex for overall rendering"`
	RasterMu       sync.Mutex        `desc:"mutex for final rasterx rendering -- only one at a time"`
}

The State holds all the current rendering state information used while painting -- a viewport just has one of these

func (*State) BackupPaint

func (rs *State) BackupPaint()

BackupPaint copies style settings from Paint to PaintBack

func (*State) Init

func (rs *State) Init(width, height int, img *image.RGBA)

Init initializes State -- must be called whenever image size changes

func (*State) Lock

func (rs *State) Lock()

Lock locks the render mutex -- must lock prior to rendering!

func (*State) PopBounds

func (rs *State) PopBounds()

PopBounds pops bounds off the stack and set to current bounds must be equally balanced with corresponding PushBounds

func (*State) PopClip

func (rs *State) PopClip()

PopClip pops Mask off the clip stack and set to current mask

func (*State) PopXForm

func (rs *State) PopXForm()

PopXForm pops xform off the stack and set to current xform must protect within render mutex lock (see Lock version)

func (*State) PopXFormLock

func (rs *State) PopXFormLock()

PopXFormLock pops xform off the stack and set to current xform protects within render mutex lock (see Lock version)

func (*State) PushBounds

func (rs *State) PushBounds(b image.Rectangle)

PushBounds pushes current bounds onto stack and set new bounds this is the essential first step in rendering! any further actual rendering should always be surrounded by Lock() / Unlock() calls

func (*State) PushClip

func (rs *State) PushClip()

PushClip pushes current Mask onto the clip stack

func (*State) PushXForm

func (rs *State) PushXForm(xf mat32.Mat2)

PushXForm pushes current xform onto stack and apply new xform on top of it must protect within render mutex lock (see Lock version)

func (*State) PushXFormLock

func (rs *State) PushXFormLock(xf mat32.Mat2)

PushXFormLock pushes current xform onto stack and apply new xform on top of it protects within render mutex lock

func (*State) RestorePaint

func (rs *State) RestorePaint()

RestorePaint restores style settings from PaintBack to Paint

func (*State) Unlock

func (rs *State) Unlock()

Unlock unlocks the render mutex, locked with PushBounds -- call this prior to children rendering etc.

type Text

type Text struct {
	Spans []Span
	Size  mat32.Vec2          `desc:"last size of overall rendered text"`
	Dir   gist.TextDirections `desc:"where relevant, this is the (default, dominant) text direction for the span"`
	Links []TextLink          `desc:"hyperlinks within rendered text"`
}

Text contains one or more Span elements, typically with each representing a separate line of text (but they can be anything).

func (*Text) InsertSpan

func (tr *Text) InsertSpan(at int, ns *Span)

InsertSpan inserts a new span at given index

func (*Text) LayoutStdLR

func (tr *Text) LayoutStdLR(txtSty *gist.Text, fontSty *gist.Font, ctxt *units.Context, size mat32.Vec2) mat32.Vec2

LayoutStdLR does basic standard layout of text in LR direction, assigning relative positions to spans and runes according to given styles, and given size overall box (nonzero values used to constrain). Returns total resulting size box for text. Font face in gist.Font is used for determining line spacing here -- other versions can do more expensive calculations of variable line spacing as needed.

func (*Text) Render

func (tr *Text) Render(rs *State, pos mat32.Vec2)

Render does text rendering into given image, within given bounds, at given absolute position offset (specifying position of text baseline) -- any applicable transforms (aside from the char-specific rotation in Render) must be applied in advance in computing the relative positions of the runes, and the overall font size, etc. todo: does not currently support stroking, only filling of text -- probably need to grab path from font and use paint rendering for stroking

func (*Text) RenderTopPos

func (tr *Text) RenderTopPos(rs *State, tpos mat32.Vec2)

RenderTopPos renders at given top position -- uses first font info to compute baseline offset and calls overall Render -- convenience for simple widget rendering without layouts

func (*Text) RuneEndPos

func (tx *Text) RuneEndPos(idx int) (pos mat32.Vec2, si, ri int, ok bool)

RuneEndPos returns the relative ending position of the given rune index, counting progressively through all spans present(adds Span RelPos and rune RelPos + rune Size.X for LR writing). If index > length, then uses LastPos. Returns also the index of the span that holds that char (-1 = no spans at all) and the rune index within that span, and false if index is out of range.

func (*Text) RuneRelPos

func (tx *Text) RuneRelPos(idx int) (pos mat32.Vec2, si, ri int, ok bool)

RuneRelPos returns the relative (starting) position of the given rune index, counting progressively through all spans present (adds Span RelPos and rune RelPos) -- this is typically the baseline position where rendering will start, not the upper left corner. If index > length, then uses LastPos. Returns also the index of the span that holds that char (-1 = no spans at all) and the rune index within that span, and false if index is out of range.

func (*Text) RuneSpanPos

func (tx *Text) RuneSpanPos(idx int) (si, ri int, ok bool)

RuneSpanPos returns the position (span, rune index within span) within a sequence of spans of a given absolute rune index, starting in the first span -- returns false if index is out of range (and returns the last position).

func (*Text) SetHTML

func (tr *Text) SetHTML(str string, font *gist.Font, txtSty *gist.Text, ctxt *units.Context, cssAgg ki.Props)

SetHTML sets text by decoding all standard inline HTML text style formatting tags in the string and sets the per-character font information appropriately, using given font style info. <P> and <BR> tags create new spans, with <P> marking start of subsequent span with DecoParaStart. Critically, it does NOT deal at all with layout (positioning) except in breaking lines into different spans, but not with word wrapping -- only sets font, color, and decoration info, and strips out the tags it processes -- result can then be processed by different layout algorithms as needed. cssAgg, if non-nil, should contain CSSAgg properties -- will be tested for special css styling of each element.

func (*Text) SetHTMLBytes

func (tr *Text) SetHTMLBytes(str []byte, font *gist.Font, txtSty *gist.Text, ctxt *units.Context, cssAgg ki.Props)

SetHTMLBytes does SetHTML with bytes as input -- more efficient -- use this if already in bytes

func (*Text) SetHTMLNoPre

func (tr *Text) SetHTMLNoPre(str []byte, font *gist.Font, txtSty *gist.Text, ctxt *units.Context, cssAgg ki.Props)

This is the No-Pre parser that uses the golang XML decoder system, which strips all whitespace and is thus unsuitable for any Pre case

func (*Text) SetHTMLPre

func (tr *Text) SetHTMLPre(str []byte, font *gist.Font, txtSty *gist.Text, ctxt *units.Context, cssAgg ki.Props)

SetHTMLPre sets preformatted HTML-styled text by decoding all standard inline HTML text style formatting tags in the string and sets the per-character font information appropriately, using given font style info. Only basic styling tags, including <span> elements with style parameters (including class names) are decoded. Whitespace is decoded as-is, including LF \n etc, except in WhiteSpacePreLine case which only preserves LF's

func (*Text) SetRunes

func (tr *Text) SetRunes(str []rune, fontSty *gist.Font, ctxt *units.Context, txtSty *gist.Text, noBG bool, rot, scalex float32)

SetRunes is for basic text rendering with a single style of text (see SetHTML for tag-formatted text) -- configures a single Span with the entire string, and does standard layout (LR currently). rot and scalex are general rotation and x-scaling to apply to all chars -- alternatively can apply these per character after Be sure that OpenFont has been run so a valid Face is available. noBG ignores any BgColor in font style, and never renders background color

func (*Text) SetString

func (tr *Text) SetString(str string, fontSty *gist.Font, ctxt *units.Context, txtSty *gist.Text, noBG bool, rot, scalex float32)

SetString is for basic text rendering with a single style of text (see SetHTML for tag-formatted text) -- configures a single Span with the entire string, and does standard layout (LR currently). rot and scalex are general rotation and x-scaling to apply to all chars -- alternatively can apply these per character after. Be sure that OpenFont has been run so a valid Face is available. noBG ignores any BgColor in font style, and never renders background color

func (*Text) SetStringRot90

func (tr *Text) SetStringRot90(str string, fontSty *gist.Font, ctxt *units.Context, txtSty *gist.Text, noBG bool, scalex float32)

SetStringRot90 is for basic text rendering with a single style of text (see SetHTML for tag-formatted text) -- configures a single Span with the entire string, and does TB rotated layout (-90 deg). Be sure that OpenFont has been run so a valid Face is available. noBG ignores any BgColor in font style, and never renders background color

func (*Text) SpanPosToRuneIdx

func (tx *Text) SpanPosToRuneIdx(si, ri int) (idx int, ok bool)

SpanPosToRuneIdx returns the absolute rune index for a given span, rune index position -- i.e., the inverse of RuneSpanPos. Returns false if given input position is out of range, and returns last valid index in that case.

type TextLink struct {
	Label     string   `desc:"text label for the link"`
	URL       string   `desc:"full URL for the link"`
	Props     ki.Props `desc:"properties defined for the link"`
	StartSpan int      `desc:"span index where link starts"`
	StartIdx  int      `desc:"index in StartSpan where link starts"`
	EndSpan   int      `desc:"span index where link ends (can be same as EndSpan)"`
	EndIdx    int      `desc:"index in EndSpan where link ends (index of last rune in label)"`
	Widget    ki.Ki    `desc:"the widget that owns this text link -- only set prior to passing off to handler function"`
}

TextLink represents a hyperlink within rendered text

func (*TextLink) Bounds

func (tl *TextLink) Bounds(tr *Text, pos mat32.Vec2) image.Rectangle

Bounds returns the bounds of the link

type TextLinkHandlerFunc

type TextLinkHandlerFunc func(tl TextLink) bool

TextLinkHandlerFunc is a function that handles TextLink links -- returns true if the link was handled, false if not (in which case it might be passed along to someone else)

var TextLinkHandler TextLinkHandlerFunc

TextLinkHandler is used to handle TextLink links, if non-nil -- set this to your own handler to get first crack at all the text link clicks -- if this function returns false (or is nil) then the URL is sent to URLHandler (the default one just calls oswin.TheApp.OpenURL)

type URLHandlerFunc

type URLHandlerFunc func(url string) bool

URLHandlerFunc is a function that handles URL links -- returns true if the link was handled, false if not (in which case it might be passed along to someone else).

Jump to

Keyboard shortcuts

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