Documentation ¶
Overview ¶
Package paint is the rendering package for Cogent Core. It renders to an image.RGBA using styles defined in styles.
Original rendering borrows heavily from: https://github.com/fogleman/gg and has been integrated with raster, which provides fully SVG compliant and fast rendering.
Index ¶
- Constants
- Variables
- func ClampBorderRadius(r styles.SideFloats, w, h float32) styles.SideFloats
- func EdgeBlurFactors(sigma, radiusFactor float32) []float32
- func FindEllipseCenter(rx, ry *float32, rotX, startX, startY, endX, endY float32, ...) (cx, cy float32)
- func FontAlts(fams string) (fns []string, serif, mono bool)
- func FontFaceName(fam string, str styles.FontStretch, wt styles.FontWeights, ...) string
- func FontSerifMonoGuess(fns []string) (serif, mono bool)
- func FontStyleCSS(fs *styles.FontRender, tag string, cssAgg map[string]any, unit *units.Context, ...) bool
- func GaussianBlur(src image.Image, sigma float64) *image.RGBA
- func GaussianBlurKernel1D(sigma float64) *convolution.Kernel
- func NextRuneAt(str string, idx int) rune
- func OpenFont(fs *styles.FontRender, uc *units.Context) styles.Font
- func OpenFontFace(bytes []byte, name, path string, size int, strokeWidth int) (*styles.FontFace, error)
- func SetHTMLSimpleTag(tag string, fs *styles.FontRender, ctxt *units.Context, cssAgg map[string]any) bool
- func TextWrapSizeEstimate(csz math32.Vector2, nChars int, ratio float32, fs *styles.Font) math32.Vector2
- type Context
- func (pc *Context) AsMask() *image.Alpha
- func (pc *Context) BlitBox(pos, size math32.Vector2, img image.Image)
- func (pc *Context) BlurBox(pos, size math32.Vector2, blurRadius float32)
- func (pc *Context) BoundingBox(minX, minY, maxX, maxY float32) image.Rectangle
- func (pc *Context) BoundingBoxFromPoints(points []math32.Vector2) image.Rectangle
- func (pc *Context) Clear()
- func (pc *Context) ClearPath()
- func (pc *Context) Clip()
- func (pc *Context) ClipPreserve()
- func (pc *Context) ClosePath()
- func (pc *Context) CubicTo(x1, y1, x2, y2, x3, y3 float32)
- func (pc *Context) DrawArc(x, y, r, angle1, angle2 float32)
- func (pc *Context) DrawBorder(x, y, w, h float32, bs styles.Border)
- func (pc *Context) DrawBox(pos, size math32.Vector2, img image.Image, op draw.Op)
- func (pc *Context) DrawCircle(x, y, r float32)
- func (pc *Context) DrawEllipse(x, y, rx, ry float32)
- func (pc *Context) DrawEllipticalArc(cx, cy, rx, ry, angle1, angle2 float32)
- func (pc *Context) DrawEllipticalArcPath(cx, cy, ocx, ocy, pcx, pcy, rx, ry, angle float32, largeArc, sweep bool) (lx, ly float32)
- func (pc *Context) DrawImage(fmIm image.Image, x, y float32)
- func (pc *Context) DrawImageAnchored(fmIm image.Image, x, y, ax, ay float32)
- func (pc *Context) DrawImageScaled(fmIm image.Image, x, y, w, h float32)
- func (pc *Context) DrawLine(x1, y1, x2, y2 float32)
- func (pc *Context) DrawPolygon(points []math32.Vector2)
- func (pc *Context) DrawPolygonPxToDots(points []math32.Vector2)
- func (pc *Context) DrawPolyline(points []math32.Vector2)
- func (pc *Context) DrawPolylinePxToDots(points []math32.Vector2)
- func (pc *Context) DrawRectangle(x, y, w, h float32)
- func (pc *Context) DrawRegularPolygon(n int, x, y, r, rotation float32)
- func (pc *Context) DrawRoundedRectangle(x, y, w, h float32, r styles.SideFloats)
- func (pc *Context) DrawRoundedShadowBlur(blurSigma, radiusFactor, x, y, w, h float32, r styles.SideFloats)
- func (pc *Context) DrawStandardBox(st *styles.Style, pos math32.Vector2, size math32.Vector2, pabg image.Image)
- func (pc *Context) Fill()
- func (pc *Context) FillBox(pos, size math32.Vector2, img image.Image)
- func (pc *Context) FillPreserve()
- func (pc *Context) FillStrokeClear()
- func (pc *Context) Identity()
- func (pc *Context) InvertY()
- func (pc *Context) LineTo(x, y float32)
- func (pc *Context) MoveTo(x, y float32)
- func (pc *Context) NewSubPath()
- func (pc *Context) QuadraticTo(x1, y1, x2, y2 float32)
- func (pc *Context) ResetClip()
- func (pc *Context) Rotate(angle float32)
- func (pc *Context) RotateAbout(angle, x, y float32)
- func (pc *Context) SVGEnd() string
- func (pc *Context) SVGFillStyle() string
- func (pc *Context) SVGPath() string
- func (pc *Context) SVGStart() string
- func (pc *Context) SVGStrokeStyle() string
- func (pc *Context) Scale(x, y float32)
- func (pc *Context) ScaleAbout(sx, sy, x, y float32)
- func (pc *Context) SetMask(mask *image.Alpha) error
- func (pc *Context) SetPixel(x, y int)
- func (pc *Context) Shear(x, y float32)
- func (pc *Context) ShearAbout(sx, sy, x, y float32)
- func (pc *Context) Stroke()
- func (pc *Context) StrokePreserve()
- func (pc *Context) StrokeWidth() float32
- func (pc *Context) TransformPoint(x, y float32) math32.Vector2
- func (pc *Context) Translate(x, y float32)
- type FontInfo
- type FontLib
- func (fl *FontLib) AddFontPaths(paths ...string) bool
- func (fl *FontLib) DeleteFont(fontnm string)
- func (fl *FontLib) Font(fontnm string, size int) (*styles.FontFace, error)
- func (fl *FontLib) FontAvail(fontnm string) bool
- func (fl *FontLib) FontsAvailFromFS(fsys fs.FS, root string) error
- func (fl *FontLib) Init()
- func (fl *FontLib) InitFontPaths(paths ...string)
- func (fl *FontLib) OpenAllFonts(size int)
- func (fl *FontLib) UpdateFontsAvail() bool
- type Rune
- type Span
- func (sr *Span) AppendRune(r rune, face font.Face, clr image.Image, bg image.Image, ...)
- func (sr *Span) AppendString(str string, face font.Face, clr image.Image, bg image.Image, ...)
- func (sr *Span) FindWrapPosLR(trgSize, curSize float32) int
- func (sr *Span) HasDecoUpdate(bg image.Image, deco styles.TextDecorations)
- func (sr *Span) Init(capsz int)
- func (sr *Span) IsNewPara() bool
- func (sr *Span) IsValid() error
- func (sr *Span) LastFont() (face font.Face, color image.Image)
- func (sr *Span) Len() int
- func (sr *Span) RenderBg(pc *Context, tpos math32.Vector2)
- func (sr *Span) RenderLine(pc *Context, tpos math32.Vector2, deco styles.TextDecorations, ascPct float32)
- func (sr *Span) RenderUnderline(pc *Context, tpos math32.Vector2)
- func (sr *Span) RuneEndPos(idx int) math32.Vector2
- func (sr *Span) RuneRelPos(idx int) math32.Vector2
- func (sr *Span) SetBackground(bg image.Image)
- func (sr *Span) SetNewPara()
- func (sr *Span) SetRenders(sty *styles.FontRender, uc *units.Context, noBG bool, rot, scalex float32)
- func (sr *Span) SetRunePosLR(letterSpace, wordSpace, chsz float32, tabSize int)
- func (sr *Span) SetRunePosTB(letterSpace, wordSpace, chsz float32, tabSize int)
- func (sr *Span) SetRunePosTBRot(letterSpace, wordSpace, chsz float32, tabSize int)
- func (sr *Span) SetRunes(str []rune, sty *styles.FontRender, ctxt *units.Context, noBG bool, ...)
- func (sr *Span) SetString(str string, sty *styles.FontRender, ctxt *units.Context, noBG bool, ...)
- func (sr *Span) SizeHV() math32.Vector2
- func (sr *Span) SplitAtLR(idx int) *Span
- func (sr *Span) TrimSpaceLR()
- func (sr *Span) TrimSpaceLeftLR()
- func (sr *Span) TrimSpaceRightLR()
- func (sr *Span) UpdateColors(sty *styles.FontRender)
- func (sr *Span) ZeroPosLR()
- type State
- func (rs *State) Init(width, height int, img *image.RGBA)
- func (rs *State) PopBounds()
- func (rs *State) PopClip()
- func (rs *State) PopTransform()
- func (rs *State) PushBounds(b image.Rectangle)
- func (rs *State) PushBoundsGeom(total image.Rectangle, radius styles.SideFloats)
- func (rs *State) PushClip()
- func (rs *State) PushTransform(tf math32.Matrix2)
- func (rs *State) Size() math32.Vector2
- type Text
- func (tr *Text) InsertSpan(at int, ns *Span)
- func (tr *Text) Layout(txtSty *styles.Text, fontSty *styles.FontRender, ctxt *units.Context, ...) math32.Vector2
- func (tr *Text) LayoutStdLR(txtSty *styles.Text, fontSty *styles.FontRender, ctxt *units.Context, ...) math32.Vector2
- func (tx *Text) PosToRune(pos math32.Vector2) (si, ri int, ok bool)
- func (tr *Text) Render(pc *Context, pos math32.Vector2)
- func (tr *Text) RenderTopPos(pc *Context, tpos math32.Vector2)
- func (tx *Text) RuneEndPos(idx int) (pos math32.Vector2, si, ri int, ok bool)
- func (tx *Text) RuneRelPos(idx int) (pos math32.Vector2, si, ri int, ok bool)
- func (tx *Text) RuneSpanPos(idx int) (si, ri int, ok bool)
- func (tx *Text) SetBackground(bg image.Image)
- func (tr *Text) SetHTML(str string, font *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, ...)
- func (tr *Text) SetHTMLBytes(str []byte, font *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, ...)
- func (tr *Text) SetHTMLNoPre(str []byte, font *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, ...)
- func (tr *Text) SetHTMLPre(str []byte, font *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, ...)
- func (tr *Text) SetRunes(str []rune, fontSty *styles.FontRender, ctxt *units.Context, ...)
- func (tr *Text) SetString(str string, fontSty *styles.FontRender, ctxt *units.Context, ...)
- func (tr *Text) SetStringRot90(str string, fontSty *styles.FontRender, ctxt *units.Context, ...)
- func (tx *Text) SpanPosToRuneIndex(si, ri int) (idx int, ok bool)
- func (tx *Text) String() string
- func (tr *Text) Transform(mat math32.Matrix2, fontSty *styles.FontRender, ctxt *units.Context)
- func (tr *Text) UpdateBBox()
- func (tx *Text) UpdateColors(sty *styles.FontRender)
- type TextLink
Constants ¶
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 ¶
var FontExts = map[string]struct{}{
".ttf": {},
".ttc": {},
".otf": {},
}
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": "Roboto",
"courier": "Courier",
"Courier": "Courier New",
"Courier New": "NotoSansMono",
"NotoSansMono": "Roboto 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 "Roboto" options last.
var FontInfoExample = "AaBbCcIiPpQq12369$€¢?.:/()àáâãäåæç日本中国⇧⌘"
FontInfoExample is example text to demonstrate fonts -- from Inkscape plus extra
var FontPaths []string
FontPaths contains the filepaths in which fonts are stored for the current platform.
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!
Functions ¶
func ClampBorderRadius ¶ added in v0.2.1
func ClampBorderRadius(r styles.SideFloats, w, h float32) styles.SideFloats
ClampBorderRadius returns the given border radius clamped to fit based on the given width and height of the object.
func EdgeBlurFactors ¶
EdgeBlurFactors returns multiplicative factors that replicate the effect of a Gaussian kernel applied to a sharp edge transition in the middle of a line segment, with a given Gaussian sigma, and radius = sigma * radiusFactor. The returned line factors go from -radius to +radius. For low-contrast (opacity) cases, radiusFactor = 1 works well, because values beyond 1 sigma are effectively invisible, but 2 looks better for greater contrast cases.
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 ¶
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 styles.FontStretch, wt styles.FontWeights, sty styles.FontStyles) string
FontFaceName returns the best full FaceName to use for the given font family(ies) (comma separated) and modifier parameters
func FontSerifMonoGuess ¶
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 *styles.FontRender, tag string, cssAgg map[string]any, unit *units.Context, ctxt colors.Context) bool
FontStyleCSS looks for "tag" name properties in cssAgg properties, and applies those to style if found, and returns true -- false if no such tag found
func GaussianBlur ¶
GaussianBlur returns a smoothly blurred version of the image using a Gaussian function. Sigma is the standard deviation of the Gaussian function, and a kernel of radius = 4 * Sigma is used.
func GaussianBlurKernel1D ¶
func GaussianBlurKernel1D(sigma float64) *convolution.Kernel
GaussianBlurKernel1D returns a 1D Gaussian kernel. Sigma is the standard deviation, and the radius of the kernel is 4 * sigma.
func NextRuneAt ¶
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 ¶
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. It returns the font style object with Face set to 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(bytes []byte, name, path string, size int, strokeWidth int) (*styles.FontFace, error)
OpenFontFace loads a font face from the given font file bytes, with the given name and path for context, 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 SetHTMLSimpleTag ¶
func SetHTMLSimpleTag(tag string, fs *styles.FontRender, ctxt *units.Context, cssAgg map[string]any) 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
func TextWrapSizeEstimate ¶ added in v0.2.1
func TextWrapSizeEstimate(csz math32.Vector2, nChars int, ratio float32, fs *styles.Font) math32.Vector2
TextWrapSizeEstimate is the size to use for layout during the SizeUp pass, for word wrap case, where the sizing actually matters, based on trying to fit the given number of characters into the given content size with given font height, and ratio of width to height. Ratio is used when csz is 0: 1.618 is golden, and smaller numbers to allow for narrower, taller text columns.
Types ¶
type Context ¶
Context provides the rendering state, styling parameters, and methods for painting. It is the main entry point to the paint API; most things are methods on Context, although Text rendering is handled separately in TextRender. A Context is typically constructed through NewContext, NewContextFromImage, or NewContextFromRGBA, although it can also be constructed directly through a struct literal when an existing State and styles.Paint exist.
func NewContext ¶
NewContext returns a new Context associated with a new image.RGBA with the given width and height.
func NewContextFromImage ¶
NewContextFromImage returns a new Context associated with an image.RGBA copy of the given image.Image. It does not render directly onto the given image; see NewContextFromRGBA for a version that renders directly.
func NewContextFromRGBA ¶
NewContextFromRGBA returns a new Context associated with the given image.RGBA. It renders directly onto the given image; see NewContextFromImage for a version that makes a copy.
func (*Context) AsMask ¶
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 (*Context) BlitBox ¶
BlitBox performs an optimized overwriting fill (blit) of the given rectangular region with the given image.
func (*Context) BlurBox ¶
BlurBox blurs the given already drawn region with the given blur radius. The blur radius passed to this function is the actual Gaussian standard deviation (σ). This means that you need to divide a CSS-standard blur radius value by two before passing it this function (see https://stackoverflow.com/questions/65454183/how-does-blur-radius-value-in-box-shadow-property-affect-the-resulting-blur).
func (*Context) BoundingBox ¶
BoundingBox computes the bounding box for an element in pixel int coordinates, applying current transform
func (*Context) BoundingBoxFromPoints ¶
BoundingBoxFromPoints computes the bounding box for a slice of points
func (*Context) Clear ¶
func (pc *Context) Clear()
Clear fills the entire image with the current fill color.
func (*Context) ClearPath ¶
func (pc *Context) ClearPath()
ClearPath clears the current path. There is no current point after this operation.
func (*Context) Clip ¶
func (pc *Context) Clip()
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 (*Context) ClipPreserve ¶
func (pc *Context) ClipPreserve()
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 (*Context) ClosePath ¶
func (pc *Context) ClosePath()
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 (*Context) CubicTo ¶
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 (*Context) DrawArc ¶
DrawArc draws an arc at the given position with the given radius and angles in radians. Because the y axis points down, angles are clockwise, and the rendering draws segments progressing from angle1 to angle2
func (*Context) DrawBorder ¶
DrawBorder is a higher-level function that draws, strokes, and fills an potentially rounded border box with the given position, size, and border styles.
func (*Context) DrawBox ¶ added in v0.0.10
DrawBox performs an optimized fill/blit of the given rectangular region with the given image, using the given draw operation.
func (*Context) DrawCircle ¶
DrawCircle draws a circle at the given position with the given radius.
func (*Context) DrawEllipse ¶
DrawEllipse draws an ellipse at the given position with the given radii.
func (*Context) DrawEllipticalArc ¶
DrawEllipticalArc draws arc between angle1 and angle2 (radians) along an ellipse. Because the y axis points down, angles are clockwise, and the rendering draws segments progressing from angle1 to angle2 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 (*Context) DrawEllipticalArcPath ¶
func (pc *Context) DrawEllipticalArcPath(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 (*Context) DrawImageAnchored ¶
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 (*Context) DrawImageScaled ¶
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 (*Context) DrawPolygon ¶
func (*Context) DrawPolygonPxToDots ¶
func (*Context) DrawPolyline ¶
func (*Context) DrawPolylinePxToDots ¶
func (*Context) DrawRectangle ¶
DrawRectangle draws (but does not stroke or fill) a standard rectangle with a consistent border
func (*Context) DrawRegularPolygon ¶
DrawRegularPolygon draws a regular polygon with the given number of sides at the given position with the given rotation.
func (*Context) DrawRoundedRectangle ¶
func (pc *Context) DrawRoundedRectangle(x, y, w, h float32, r styles.SideFloats)
DrawRoundedRectangle draws a standard rounded rectangle with a consistent border and with the given x and y position, width and height, and border radius for each corner.
func (*Context) DrawRoundedShadowBlur ¶
func (pc *Context) DrawRoundedShadowBlur(blurSigma, radiusFactor, x, y, w, h float32, r styles.SideFloats)
DrawRoundedShadowBlur draws a standard rounded rectangle with a consistent border and with the given x and y position, width and height, and border radius for each corner. The blurSigma and radiusFactor args add a blurred shadow with an effective Gaussian sigma = blurSigma, and radius = radiusFactor * sigma. This shadow is rendered around the given box size up to given radius. See EdgeBlurFactors for underlying blur factor code. Using radiusFactor = 1 works well for weak shadows, where the fringe beyond 1 sigma is essentially invisible. To match the CSS standard, you then pass blurSigma = blur / 2, radiusFactor = 1. For darker shadows, use blurSigma = blur / 2, radiusFactor = 2, and reserve extra space for the full shadow. The effective blurRadius is clamped to be <= w-2 and h-2.
func (*Context) DrawStandardBox ¶ added in v0.0.10
func (pc *Context) DrawStandardBox(st *styles.Style, pos math32.Vector2, size math32.Vector2, pabg image.Image)
DrawStandardBox draws the CSS standard box model using the given styling information, position, size, and parent actual background. This is used for rendering widgets such as buttons, text fields, etc in a GUI.
func (*Context) Fill ¶
func (pc *Context) Fill()
Fill fills the current path with the current color. Open subpaths are implicitly closed. The path is cleared after this operation.
func (*Context) FillBox ¶
FillBox performs an optimized fill of the given rectangular region with the given image.
func (*Context) FillPreserve ¶
func (pc *Context) FillPreserve()
FillPreserve fills the current path with the current color. Open subpaths are implicitly closed. The path is preserved after this operation.
func (*Context) FillStrokeClear ¶
func (pc *Context) FillStrokeClear()
FillStrokeClear is a convenience final stroke and clear draw for shapes when done
func (*Context) Identity ¶
func (pc *Context) Identity()
Identity resets the current transformation matrix to the identity matrix. This results in no translating, scaling, rotating, or shearing.
func (*Context) InvertY ¶
func (pc *Context) InvertY()
InvertY flips the Y axis so that Y grows from bottom to top and Y=0 is at the bottom of the image.
func (*Context) LineTo ¶
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 (*Context) MoveTo ¶
MoveTo starts a new subpath within the current path starting at the specified point.
func (*Context) NewSubPath ¶
func (pc *Context) NewSubPath()
NewSubPath starts a new subpath within the current path. There is no current point after this operation.
func (*Context) QuadraticTo ¶
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 (*Context) Rotate ¶
Rotate updates the current matrix with a clockwise rotation. Rotation occurs about the origin. Angle is specified in radians.
func (*Context) RotateAbout ¶
RotateAbout updates the current matrix with a clockwise rotation. Rotation occurs about the specified point. Angle is specified in radians.
func (*Context) SVGEnd ¶ added in v0.1.1
SVGEnd returns the end of an SVG based on the current context state
func (*Context) SVGFillStyle ¶ added in v0.1.1
SVGFillStyle returns the style string for current Fill
func (*Context) SVGPath ¶ added in v0.1.1
SVGPath generates an SVG path representation of the current Path
func (*Context) SVGStart ¶ added in v0.1.1
SVGStart returns the start of an SVG based on the current context state
func (*Context) SVGStrokeStyle ¶ added in v0.1.1
SVGStrokeStyle returns the style string for current Stroke
func (*Context) Scale ¶
Scale updates the current matrix with a scaling factor. Scaling occurs about the origin.
func (*Context) ScaleAbout ¶
ScaleAbout updates the current matrix with a scaling factor. Scaling occurs about the specified point.
func (*Context) SetMask ¶
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 (*Context) SetPixel ¶
SetPixel sets the color of the specified pixel using the current stroke color.
func (*Context) Shear ¶
Shear updates the current matrix with a shearing angle. Shearing occurs about the origin.
func (*Context) ShearAbout ¶
ShearAbout updates the current matrix with a shearing angle. Shearing occurs about the specified point.
func (*Context) Stroke ¶
func (pc *Context) Stroke()
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 (*Context) StrokePreserve ¶
func (pc *Context) StrokePreserve()
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 (*Context) StrokeWidth ¶
StrokeWidth obtains the current stoke width subject to transform (or not depending on VecEffNonScalingStroke)
func (*Context) TransformPoint ¶
TransformPoint multiplies the specified point by the current transform matrix, returning a transformed position.
type FontInfo ¶
type FontInfo struct { // official regularized name of font Name string // stretch: normal, expanded, condensed, etc Stretch styles.FontStretch // weight: normal, bold, etc Weight styles.FontWeights // style -- normal, italic, etc Style styles.FontStyles // example text -- styled according to font params in chooser Example string }
FontInfo contains basic font information for choosing a given font -- displayed in the font chooser dialog.
type FontLib ¶
type FontLib struct { // An fs containing available fonts, which are typically embedded through go:embed. // It is initialized to contain of the default fonts located in the fonts directory // (https://github.com/cogentcore/core/tree/main/paint/fonts), but it can be extended by // any packages by using a merged fs package. FontsFS fs.FS // list of font paths to search for fonts FontPaths []string // Map of font name to path to file. If the path starts // with "fs://", it indicates that it is located in // [FontLib.FontsFS]. FontsAvail map[string]string // information about each font -- this list should be used for selecting valid regularized font names FontInfo []FontInfo // double-map of cached fonts, by font name and then integer font size within that Faces map[string]map[int]*styles.FontFace }
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 core font library, initialized from fonts available on font paths
func (*FontLib) AddFontPaths ¶
func (*FontLib) DeleteFont ¶
DeleteFont removes given font from list of available fonts -- if not supported etc
func (*FontLib) Font ¶
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 ¶
FontAvail determines if a given font name is available (case insensitive)
func (*FontLib) FontsAvailFromFS ¶
FontsAvailFromPath scans for all fonts we can use on a given fs, gathering info into FontsAvail and FontInfo. It adds the given root path string to all paths.
func (*FontLib) Init ¶
func (fl *FontLib) Init()
Init initializes the font library if it hasn't been yet
func (*FontLib) InitFontPaths ¶
InitFontPaths initializes font paths to system defaults, only if no paths have yet been set
func (*FontLib) OpenAllFonts ¶
OpenAllFonts attempts to load all fonts that were found -- call this before displaying the font chooser to eliminate any bad fonts.
func (*FontLib) UpdateFontsAvail ¶
UpdateFontsAvail scans for all fonts we can use on the FontPaths
type Rune ¶
type Rune struct { // fully specified font rendering info, includes fully computed font size. // This is exactly what will be drawn, with no further transforms. // If nil, previous one is retained. Face font.Face `json:"-"` // Color is the color to draw characters in. // If nil, previous one is retained. Color image.Image `json:"-"` // background color to fill background of color, for highlighting, // <mark> tag, etc. Unlike Face, Color, this must be non-nil for every case // that uses it, as nil is also used for default transparent background. Background image.Image `json:"-"` // dditional decoration to apply: underline, strike-through, etc. // Also used for encoding a few special layout hints to pass info // from styling tags to separate layout algorithms (e.g., <P> vs <BR>) Deco styles.TextDecorations // relative position from start of Text for the lower-left baseline // rendering position of the font character RelPos math32.Vector2 // size of the rune itself, exclusive of spacing that might surround it Size math32.Vector2 // rotation in radians for this character, relative to its lower-left // baseline rendering position RotRad float32 // scaling of the X dimension, in case of non-uniform scaling, 0 = no separate scaling ScaleX float32 }
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) HasNil ¶
HasNil returns error if any of the key info (face, color) is nil -- only the first element must be non-nil
func (*Rune) RelPosAfterLR ¶
RelPosAfterLR returns the relative position after given rune for LR order: RelPos.X + Size.X
func (*Rune) RelPosAfterRL ¶
RelPosAfterRL returns the relative position after given rune for RL order: RelPos.X - Size.X
func (*Rune) RelPosAfterTB ¶
RelPosAfterTB returns the relative position after given rune for TB order: RelPos.Y + Size.Y
type Span ¶
type Span struct { // text as runes Text []rune // render info for each rune in one-to-one correspondence Render []Rune // position for start of text relative to an absolute coordinate that is provided at the time of rendering. // This typically includes the baseline offset to align all rune rendering there. // Individual rune RelPos are added to this plus the render-time offset to get the final position. RelPos math32.Vector2 // rune position for further edge of last rune. // For standard flat strings this is the overall length of the string. // Used for size / layout computations: you do not add RelPos to this, // as it is in same Text relative coordinates LastPos math32.Vector2 // where relevant, this is the (default, dominant) text direction for the span Dir styles.TextDirections // mask of decorations that have been set on this span -- optimizes rendering passes HasDeco styles.TextDecorations }
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 image.Image, bg image.Image, deco styles.TextDecorations)
AppendRune adds one rune and associated formatting info
func (*Span) AppendString ¶
func (sr *Span) AppendString(str string, face font.Face, clr image.Image, bg image.Image, deco styles.TextDecorations, sty *styles.FontRender, 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 ¶
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 image.Image, deco styles.TextDecorations)
AppendRune adds one rune and associated formatting info
func (*Span) IsValid ¶
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) RenderLine ¶
func (sr *Span) RenderLine(pc *Context, tpos math32.Vector2, deco styles.TextDecorations, ascPct float32)
RenderLine renders overline or line-through -- anything that is a function of ascent
func (*Span) RenderUnderline ¶
RenderUnderline renders the underline for span -- ensures continuity to do it all at once
func (*Span) RuneEndPos ¶
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 ¶
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) SetBackground ¶ added in v0.0.4
SetBackground sets the BackgroundColor of the Runes to given value, if was not previously nil.
func (*Span) SetNewPara ¶
func (sr *Span) SetNewPara()
SetNewPara sets this as starting a new paragraph
func (*Span) SetRenders ¶
func (sr *Span) SetRenders(sty *styles.FontRender, uc *units.Context, noBG bool, rot, scalex float32)
SetRenders sets rendering parameters based on style
func (*Span) SetRunePosLR ¶
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 ¶
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 ¶
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 *styles.FontRender, 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 *styles.FontRender, 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 ¶
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 ¶
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) UpdateColors ¶ added in v0.2.0
func (sr *Span) UpdateColors(sty *styles.FontRender)
UpdateColors sets the font styling colors the first rune based on the given font style parameters.
type State ¶
type State struct { // current transform CurrentTransform math32.Matrix2 // current path Path raster.Path // rasterizer -- stroke / fill rendering engine from raster Raster *raster.Dasher // scan scanner Scanner *scan.Scanner // scan spanner ImgSpanner *scan.ImgSpanner // starting point, for close path Start math32.Vector2 // current point Current math32.Vector2 // is current point current? HasCurrent bool // pointer to image to render into Image *image.RGBA // current mask Mask *image.Alpha // Bounds are the boundaries to restrict drawing to. // This is much faster than using a clip mask for basic // square region exclusion. Bounds image.Rectangle // bounding box of last object rendered; computed by renderer during Fill or Stroke, grabbed by SVG objects LastRenderBBox image.Rectangle // stack of transforms TransformStack []math32.Matrix2 // BoundsStack is a stack of parent bounds. // Every render starts with a push onto this stack, and finishes with a pop. BoundsStack []image.Rectangle // Radius is the border radius of the element that is currently being rendered. // This is only relevant when using [State.PushBoundsGeom]. Radius styles.SideFloats // RadiusStack is a stack of the border radii for the parent elements, // with each one corresponding to the entry with the same index in // [State.BoundsStack]. This is only relevant when using [State.PushBoundsGeom]. RadiusStack []styles.SideFloats // stack of clips, if needed ClipStack []*image.Alpha // if non-nil, SVG output of paint commands is sent here SVGOut io.Writer }
The State holds all the current rendering state information used while painting -- a viewport just has one of these
func (*State) PopBounds ¶
func (rs *State) PopBounds()
PopBounds pops the bounds off the stack and sets the current bounds. This must be equally balanced with corresponding State.PushBounds calls.
func (*State) PopClip ¶
func (rs *State) PopClip()
PopClip pops Mask off the clip stack and set to current mask
func (*State) PopTransform ¶
func (rs *State) PopTransform()
PopTransform pops transform off the stack and set to current transform must protect within render mutex lock (see Lock version)
func (*State) PushBounds ¶
PushBounds pushes the current bounds onto the stack and sets new bounds. This is the essential first step in rendering. See State.PushBoundsGeom for a version that takes more arguments.
func (*State) PushBoundsGeom ¶ added in v0.2.1
func (rs *State) PushBoundsGeom(total image.Rectangle, radius styles.SideFloats)
PushBoundsGeom pushes the current bounds onto the stack and sets new bounds. This is the essential first step in rendering. It also takes the border radius of the current element.
func (*State) PushClip ¶
func (rs *State) PushClip()
PushClip pushes current Mask onto the clip stack
func (*State) PushTransform ¶
PushTransform pushes current transform onto stack and apply new transform on top of it must protect within render mutex lock (see Lock version)
type Text ¶
type Text struct { Spans []Span // bounding box for the rendered text. use Size() method to get the size. BBox math32.Box2 // fontheight computed in last Layout FontHeight float32 // lineheight computed in last Layout LineHeight float32 // whether has had overflow in rendering HasOverflow bool // where relevant, this is the (default, dominant) text direction for the span Dir styles.TextDirections // hyperlinks within rendered text Links []TextLink }
Text contains one or more Span elements, typically with each representing a separate line of text (but they can be anything).
func (*Text) InsertSpan ¶
InsertSpan inserts a new span at given index
func (*Text) Layout ¶ added in v0.0.5
func (tr *Text) Layout(txtSty *styles.Text, fontSty *styles.FontRender, ctxt *units.Context, size math32.Vector2) math32.Vector2
Layout does basic standard layout of text using Text style parameters, assigning relative positions to spans and runes according to given styles, and given size overall box. Nonzero values used to constrain, with the width used as a hard constraint to drive word wrapping (if a word wrap style is present). Returns total resulting size box for text, which can be larger than the given size, if the text requires more size to fit everything. Font face in styles.Font is used for determining line spacing here. Other versions can do more expensive calculations of variable line spacing as needed.
func (*Text) LayoutStdLR ¶
func (tr *Text) LayoutStdLR(txtSty *styles.Text, fontSty *styles.FontRender, ctxt *units.Context, size math32.Vector2) math32.Vector2
LayoutStdLR does basic standard layout of text in LR direction.
func (*Text) PosToRune ¶ added in v0.0.5
PosToRune returns the rune span and rune indexes for given relative X,Y pixel position, if the pixel position lies within the given text area. If not, returns false. It is robust to left-right out-of-range positions, returning the first or last rune index respectively.
func (*Text) Render ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) SetBackground ¶ added in v0.0.4
SetBackground sets the BackgroundColor of the first Render in each Span to given value, if was not nil.
func (*Text) SetHTML ¶
func (tr *Text) SetHTML(str string, font *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, cssAgg map[string]any)
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 *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, cssAgg map[string]any)
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 *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, cssAgg map[string]any)
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 *styles.FontRender, txtSty *styles.Text, ctxt *units.Context, cssAgg map[string]any)
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 *styles.FontRender, ctxt *units.Context, txtSty *styles.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 BackgroundColor in font style, and never renders background color
func (*Text) SetString ¶
func (tr *Text) SetString(str string, fontSty *styles.FontRender, ctxt *units.Context, txtSty *styles.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 BackgroundColor in font style, and never renders background color
func (*Text) SetStringRot90 ¶
func (tr *Text) SetStringRot90(str string, fontSty *styles.FontRender, ctxt *units.Context, txtSty *styles.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 BackgroundColor in font style, and never renders background color
func (*Text) SpanPosToRuneIndex ¶ added in v0.0.10
SpanPosToRuneIndex 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.
func (*Text) Transform ¶ added in v0.1.1
Transform applies given 2D transform matrix to the text character rotations, scaling, and positions, so that the text is rendered according to that transform. The fontSty is the font style used for specifying the font originally.
func (*Text) UpdateBBox ¶ added in v0.1.1
func (tr *Text) UpdateBBox()
UpdateBBox updates the overall text bounding box based on actual glyph bounding boxes.
func (*Text) UpdateColors ¶ added in v0.2.0
func (tx *Text) UpdateColors(sty *styles.FontRender)
UpdateColors sets the font styling colors the first rune based on the given font style parameters.
type TextLink ¶
type TextLink struct { // text label for the link Label string // full URL for the link URL string // Style for rendering this link, set by the controlling widget Style styles.FontRender // additional properties defined for the link, from the parsed HTML attributes Properties map[string]any // span index where link starts StartSpan int // index in StartSpan where link starts StartIndex int // span index where link ends (can be same as EndSpan) EndSpan int // index in EndSpan where link ends (index of last rune in label) EndIndex int }
TextLink represents a hyperlink within rendered text
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package scan provides an anti-aliasing 2-D rasterizer, which is based on the larger Freetype suite of font-related packages, but the raster package is not specific to font rasterization, and can be used standalone without any other Freetype package.
|
Package scan provides an anti-aliasing 2-D rasterizer, which is based on the larger Freetype suite of font-related packages, but the raster package is not specific to font rasterization, and can be used standalone without any other Freetype package. |