PeachDrawing.Core

PeachDrawing.Core

Canvas Class

Adapter for platform specific graphics rendering object - used to render graphics and text in platform specific context.
The core HTML Renderer components use this class for rendering logic, extending this class in different platform: WinForms, WPF, Metro, PDF, etc.

public abstract class Canvas : System.IDisposable

Inheritance System.Object → Canvas

Implements System.IDisposable

Properties  
CurrentTransform The accumulated transform of every PushTransform(Matrix3x2) in effect, mapping this graphics’ current user space to the layout space it started in (the space page content is laid out in). Identity for a graphics that does not track transforms. Bookkeeping only, read by callers (gradient/pattern objectBoundingBox math, an SVG backdrop repaint, context-fill/ context-stroke’s coordinate-space mapping) - it plays no part in what this graphics actually draws, which a concrete backend positions its own way. A tile this graphics hands out (CreateTile(double, double)’s Graphics, or BeginRasterSurface(Rect, Nullable<double>)’s) starts seeded from this value, not System.Numerics.Matrix3x2.Identity, precisely so a reader can still relate the tile’s own coordinate space back to whatever space content outside the tile is measured in.
FlattensTransparency Whether the document being written forbids transparency (PDF/A-1, PDF/X-1a/X-3) and was asked to flatten it instead of rejecting it (PdfGenerateConfig.TransparencyPolicy). The painter then renders what needs transparency as an opaque bitmap.
InvisibleText While true, text this graphics draws is laid out and embedded as usual but paints nothing (PDF text render mode 3), so it stays selectable and searchable over content drawn some other way - a bitmap of the same text, say. Backends with no notion of text extraction (a raster graphics) draw no text at all while it is set. Everything other than text is unaffected; callers set it around the text-only pass and clear it afterwards.
IsOffscreenTile Whether this instance paints into an offscreen tile (e.g. one returned by CreateTile(double, double), used for group opacity and SVG pattern/mask content) rather than directly into the real page’s own content stream. Tagged-PDF output does not emit marked-content sequences into tile content streams in the current implementation (doing so correctly needs /MCR with /Stm//StmOwn pointing at the tile’s own content stream, not yet wired up) - callers use this to skip MCID/BDC emission while still creating the struct element itself, so the tree shape stays well-formed even though this particular occurrence contributes no reachable MCID. Defaults to false.
PixelsPerPoint The scale between this graphics context’s own coordinate space and true points (1/72 inch): a backend whose coordinates are inflated relative to a point (for example a layout space running at a higher pixels-per-inch than 72) reports that inflation here. 1.0 (the base, no-op default) is correct for any Canvas whose coordinate space is not inflated this way; a backend whose space is overrides this with its real value. A caller that needs to compute a transform matrix whose *linear* (scale/rotation) part won’t itself be divided by this factor before use - a backend may divide only a matrix’s translation, not M11/M12/M21/M22 - reads this to pre-divide that part itself (an SVG viewBox-to-viewport transform is such a case: its “scale” is a ratio of an inflated length to a never-inflated, dimensionless user unit, so it is not already scale-neutral the way an ordinary scale() transform is).
PrefersRasterGroups Whether group effects (opacity, blend modes, colour functions) are best done by rendering the element into a tight bitmap and compositing that, rather than through CreateTile(double, double). True for a raster graphics, whose tile would otherwise span from the page origin; false for a PDF graphics, where a tile is a cheap vector Form XObject.
TileCacheOwner Identity of the document that owns forms created by CreateTile(double, double). A tile may be reused on another page of that document, but never in another document. Null for graphics contexts without a PDF document (including test and measure-only graphics).
TransformScale How much the transforms pushed so far magnify a unit along each axis: the lengths of the images of the unit x and y vectors under the accumulated linear part. A raster region renders at the physical resolution the document asked for <em>after</em> those transforms are applied, so it needs this to pick its pixel pitch; a graphics that does not track transforms reports no magnification.
Methods  
BeginArtifact() Begins an artifact marked-content sequence - marks the content that follows as not part of the document’s logical structure (e.g. a decorative <hr>). Must be paired with EndMarkedContent().
BeginLayer(LayerOptions) Begins an isolated group of drawing that is composited onto this canvas as one piece when the returned layer is disposed: with the given opacity, blend mode and colour transform applied to the group as a whole rather than to each shape in it. This is what CSS opacity or SVG group opacity means - content that overlaps inside the group does not blend with itself. Draw onto Canvas in this canvas’s own coordinates.
BeginMarkedContent(string, int) Begins a tagged marked-content sequence in the page content stream, associated with the given PDF structure type (e.g. “/H1”, “/P”) and marked-content identifier. Only called when tagged PDF output is enabled. Must be paired with EndMarkedContent(), wrapping a whole leaf box’s own paint calls - never part of one.
BeginRasterSurface(Rect, Nullable<double>) Asks this graphics for a pixel surface to paint an effect PDF cannot express as vector content (a blur, a cross-channel colour filter, ...) into. The returned region has this graphics’ own coordinate system, so the same paint code that would have drawn to this graphics draws to it unchanged; when finished, hand the surface back through DrawRaster(RasterSurface).
BeginVariableText() Begins the /Tx marked-content sequence ISO 32000-1 §12.7.3.3 requires around the value drawn into an interactive form field’s appearance stream, and EndVariableText() closes it. It is what tells a PDF reader which part of the generated appearance to replace when the user edits the field - without it the reader draws the new value over the generated one instead of in place of it. Deliberately a pair of its own rather than reusing EndMarkedContent(): these two must sit outside any text object, while that one has a caller that is legitimately inside one.
CountShapedGlyphs(string, Font, Nullable<ShapeSettings>) The number of glyphs str shapes into once GSUB substitution is applied - always <= str’s character count, less whenever a ligature merges more than one character into a single glyph (single substitution never changes the count). Used to size the per-glyph letter-spacing gap count a word’s box must reserve (the PDF Tc operator adds one gap per glyph actually shown, not per source character), so it stays in sync with what DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>) paints for the same text/font/features.
CreateTile(double, double) Creates a fresh, independent (width x height) drawing surface for tile-based content (e.g. an SVG <pattern>’s cell): draw into the returned Graphics using ordinary Canvas calls, then use the returned Image with DrawImage(Image, Rect) - repeated calls tile it, each one a real reference to the same underlying vector content (a PDF Form XObject), never rasterized. Null when creating one isn’t supported in the current rendering context (e.g. a measure-only pass with no real PDF page to own the new object).
Dispose() Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
DrawGlyphs(IReadOnlyList<GlyphPlacement>, Font, PaintColor) Draws each of glyphs at its own explicit position, addressed directly by font glyph index rather than by Unicode character - unlike DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>), this never re-shapes/re-maps through cmap/GSUB, so it can draw a glyph with no Unicode mapping at all (e.g. an OpenType MATH table’s stretchy-operator assembly parts or pre-sized size variants, which are reached only via MathVariantsTable glyph ids, not through any character). Each GlyphPlacement’s X/Y is that glyph’s own baseline origin (not a bounding-box corner), in the same working unit space as DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>)’s own point parameter - unlike that method, there is no separate ascent-relative adjustment, since every glyph here already carries its own exact target baseline position.
DrawImage(Image, Rect) Draws the specified Image at the specified location and with the specified size.
DrawImage(Image, Rect, ImageSampling) Draws image into destRect, reading its pixels as sampling says.
DrawImage(Image, Rect, Rect) Draws the specified portion of the specified Image at the specified location and with the specified size.
DrawImage(Image, Rect, Rect, ImageSampling) Draws part of image into destRect, reading its pixels as sampling says.
DrawImageAlphaMasked(Image, Image, Rect, bool) Draws image (a tile from CreateTile(double, double)) at destRect with maskImage (another same-adapter tile) attached as an /Alpha-subtype soft mask (ISO 32000-1 §11.6.4.3) - unlike DrawImageMasked(Image, Image, Rect)’s /Luminosity mask, which derives mask values from the mask tile’s rendered COLOR converted to grayscale, this derives them directly from the mask tile’s own computed ALPHA, disregarding whatever color it painted with. The motivating future use case is SVG’s SourceAlpha filter input and feComposite, both of which are defined in terms of a source’s alpha channel specifically, not a luminosity conversion of it. When invert is true, the mask’s /TR is set to 1 - x (a PDF Type 4 function), for a complemented alpha mask without needing a second tile painted with inverted alpha. A no-op if either image wasn’t created via CreateTile(double, double) on this same Canvas.
DrawImageBlendedOver(Image, Image, Rect, PaintBlendMode) Paints bottom normally at destRect, then top on top of it at the same rect composited with blendMode - both same-adapter tiles from CreateTile(double, double), sized/positioned identically in their own local coordinate systems. The motivating future use case is SVG’s feBlend, which blends two independently-rendered filter inputs together inside a fresh tile rather than blending freshly-painted content against whatever the page already has underneath it (which is what PushBlendMode(PaintBlendMode)/PopBlendMode() do). A no-op if either image wasn’t created via CreateTile(double, double) on this same Canvas.
DrawImageMasked(Image, Image, Rect) Draws image (a tile from CreateTile(double, double)) at destRect with maskImage (another same-adapter tile, sharing image’s own local width/height) applied as a luminosity soft mask, scoped to just this one placement. White areas of maskImage are fully visible, black fully transparent, matching PDF’s/SVG’s own <mask> semantics. Deliberately NOT a “push mask, draw normally, pop mask” pair (which an earlier version of this API was): a tile’s own content is Y-flipped relative to its own (small) size, not the page’s, so positioning it correctly requires the same explicit destRect placement DrawImage(Image, Rect) already uses for pattern tiles - relying on whatever transform happens to be ambient in the page’s own content stream at some arbitrary “push” point silently mispositions the mask relative to the content it’s meant to mask. A no-op if either image wasn’t created via CreateTile(double, double) on this same Canvas.
DrawImageWithColorMatrix(Image, Rect, ColorMatrix) Draws image (a tile from CreateTile(double, double)) at destRect, composited through a CSS/SVG filter color-matrix transform (grayscale(), sepia(), saturate(), hue-rotate(), invert(), brightness(), contrast(), or feColorMatrix) expressed as matrix. Only representable when IsChannelIndependent is true - see ColorMatrix’s remarks for why a PDF ExtGState transfer function (the mechanism this goes through) cannot express a matrix that mixes color channels, and what a caller needs instead for one that does. A no-op if image wasn’t created via CreateTile(double, double) on this same Canvas.
DrawImageWithOpacity(Image, Rect, double, PaintBlendMode) Draws image (a tile from CreateTile(double, double)) at destRect, composited as a single flattened result at constant opacity - the mechanism behind CSS/SVG group opacity. Unlike simply multiplying the alpha of each shape painted into the tile, this flattens the tile’s own (possibly overlapping) content once before applying opacity to the flattened result, so overlapping content doesn’t double-darken where it overlaps. A no-op if image wasn’t created via CreateTile(double, double) on this same Canvas. blendMode composites the flattened tile against the destination with a non-Normal PDF blend mode in the same gs as opacity - the mechanism behind CSS mix-blend-mode combined with group opacity, a single ExtGState rather than two nested ones.
DrawLine(Pen, double, double, double, double) Draws a line connecting the two points specified by the coordinate pairs.
DrawPath(Brush, GraphicsPath) Fills the interior of a GraphicsPath.
DrawPath(Pen, GraphicsPath) Draws a GraphicsPath.
DrawPolygon(Brush, PaintPoint[]) Fills the interior of a polygon defined by an array of points specified by PaintPoint structures.
DrawRaster(RasterSurface) Draws a surface obtained from BeginRasterSurface(Rect, Nullable<double>) into this graphics at the rectangle the surface itself records, so its physical size is exact. Honours this graphics’ current transform, clip and blend mode.
DrawRectangle(Brush, double, double, double, double) Fills the interior of a rectangle specified by a pair of coordinates, a width, and a height.
DrawRectangle(Pen, double, double, double, double) Draws a rectangle specified by a coordinate pair, a width, and a height.
DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>) Draw the given string using the given font and foreground color at given location.
DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>, string) Same as the other DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>) overload, plus logicalText: the true logical-order (pre-bidi-mirroring) source text str was derived from, when the two differ - null (the default) means they’re the same (the overwhelming common case: LTR text, or any word that was never reversed/mirrored for RTL display) and the real implementation should behave identically to the other overload. A word whose own Text WAS reversed/mirrored for RTL display (CssLayoutEngine.MirrorWordTextIfNeeded’s ordinary path - not an Arabic-family joining word, which never mutates its own text at all) passes its own stable PreMirrorText here, so the PDF’s ToUnicode CMap records each glyph’s true source character(s) rather than whichever reversed/mirrored character happens to occupy that glyph’s position in the *painted* string - see this overload’s own introduction for the real-world extraction corruption this fixes (a parenthesized RTL word extracting with its parentheses in the wrong position, confirmed against real MuPDF/PDFium output). A default (non-abstract) implementation forwarding to the other overload - ignoring logicalText - is deliberate: only a real PDF-writing backend needs to act on it; every other implementation (test mocks recording draw calls, measuring-only contexts) is unaffected by this overload’s mere existence and needs no changes to keep compiling/behaving identically.
EndMarkedContent() Ends a marked-content sequence started by BeginMarkedContent(string, int) or BeginArtifact().
EndVariableText() Closes the sequence BeginVariableText() opened.
GetClip() Gets a Rectangle structure that bounds the clipping region of this Graphics.
GetConicGradientBrush(PaintPoint, double, PaintColor[], double[]) Convenience wrapper for GetConicGradientBrush(PaintPoint, double, PaintColor[], double[]) on the RenderContext this graphics was built from.
GetGraphicsPath() Get GraphicsPath object.
GetInkCrossings(string, Font, PaintPoint, double, double, double, Nullable<ShapeSettings>) The horizontal ranges in which str’s glyph ink crosses the horizontal band between bandTop and bandBottom — what text-decoration-skip-ink ([CSS Text
Decoration 4 §2.5](https://www.w3.org/TR/css-text-decor-4/#text-decoration-skip-ink-property ‘https://www.w3.org/TR/css-text-decor-4/#text-decoration-skip-ink-property’)) removes from an underline or overline drawn through that band.  
GetLinearGradientBrush(Rect, PaintColor, PaintColor, double) Get linear gradient color brush from color1 to color2.
GetPen(Brush) Get a pen that strokes with the given brush, e.g. for an SVG stroke="url(#gradient)".
GetPen(PaintColor) Get color pen.
GetSolidBrush(PaintColor) Get solid color brush.
GetTextOutline(string, Font, PaintPoint, double, Nullable<ShapeSettings>) Builds the vector outline of a glyph run as a fillable/strokeable GraphicsPath, with the text baseline at baselineOrigin (user-space units) and glyphs advancing left-to-right. Unlike DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>) (a single-color PDF text show), the returned path can be filled with a gradient/pattern brush or stroked - used by the SVG renderer for gradient/pattern fill, stroke, and <textPath> on text. Returns null when the font produces no glyph outlines (a CID-keyed CFF font, or a bitmap font, neither of which this engine can decode outlines from) - the caller’s cue to fall back to DrawString(string, Font, PaintColor, PaintPoint, Size, double, FontPalette, Nullable<ShapeSettings>).
MeasureString(string, Font, double, int, double) Measure the width of string under max width restriction calculating the number of characters that can fit and the width those characters take.
Not relevant for platforms that don’t render HTML on UI element.
MeasureString(string, Font, Nullable<ShapeSettings>) Measure the width and height of string str when drawn on device context HDC using the given font font.
PopAntiAlias() Undoes the latest PushAntiAlias(bool). Does nothing when there is none to undo.
PopBlendMode() Pop the most recent PushBlendMode(PaintBlendMode), restoring the prior blend mode.
PopClip() Pop the latest clip push.
PopTransform() Pop the most recent PushTransform(Matrix3x2), restoring the prior transform state.
PushAntiAlias(bool) Turns anti-aliasing of the shapes drawn from now on on or off, until the matching PopAntiAlias(). Calls nest: each PushAntiAlias is undone by one PopAntiAlias, like PushClip(Rect) and PushTransform(Matrix3x2). This replaces the untyped SetAntiAliasSmoothingMode()/ReturnPreviousSmoothingMode(object) pair, which it is built on by default.
PushBlendMode(PaintBlendMode) Push a PDF blend mode for subsequent drawing, saving state so it can later be undone by PopBlendMode() (stack-shaped, same convention as PushClip(Rect)/ PopClip()). Used e.g. to composite a fill against the content underneath it via Difference for a true color inversion (CSS outline-color: invert).
PushClip(GraphicsPath) Push the clipping region of this Graphics to intersection of the current clip and the given (possibly non-rectangular) path. Used for SVG clip-path, where the clip region isn’t necessarily axis-aligned.
PushClip(Rect) Push the clipping region of this Graphics to interception of current clipping rectangle and the given rectangle.
PushClipExclude(Rect) Push the clipping region of this Graphics to exclude the given rectangle from the current clipping rectangle.
PushTransform(Matrix3x2) Push a 2D affine transform (composed before/with the current transform), saving state so it can later be undone by PopTransform(). Used to implement the CSS transform property.
ResumeClipping() Resumes the suspended clips.
ReturnPreviousSmoothingMode(object) Return to previous smooth mode before anti-alias was set as returned from SetAntiAliasSmoothingMode().
SetAntiAliasSmoothingMode() Set the graphics smooth mode to use anti-alias.
Use ReturnPreviousSmoothingMode(object) to return back the mode used.
SuspendClipping() Restore the clipping region to the initial clip.