Repository navigation
CMYK destinations: draw into a pair of images, blend subtractively - #40
Merged
Merged
Conversation
Canvas.ResetPair draws into two images at once: everything is rasterized once and composited into both, each image with its paint (Paint.Second, nil for the same). Two images of premultiplied ink amounts, (C, M, Y, A) and (K, K, K, A), make a CMYK destination with alpha; compositing treats the channels alike, and gradients, meshes and images interpolate each channel on its own, so one shader per image paints CMYK. The fast paths that write the destination directly take the second image along (the glyph mask blit) or step aside for a pair (the analytic rows of opaque strokes); a paint is invisible or opaque only when it is in both images. LayerShader.Subtractive blends layers of ink amounts on their complements (PDF 2.0, 11.3.5), α − c in premultiplied colours; the non-separable modes then blend (C, M, Y) as (R, G, B). LayerShader.Black makes the shader that of the K image: Hue, Saturation and Color take K from the backdrop, Luminosity from the source. Tests: a scene of fills, strokes (analytic rows among them), dashes, rectangles, shaders, clips and cached glyphs drawn as a pair gives the bytes of each image drawn alone; every blend mode, subtractive and for the K image, within a level of the formula in floating point. For timzifer/cera#209. Closes #39.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #39. For timzifer/cera#209.
API (additions only)
Why a pair of RGBA images
A CMYK destination with alpha is two images of the same rectangle, (C, M, Y, A) and (K, K, K, A), premultiplied ink amounts (0 = no ink, so a transparent backdrop is paper). Everything stilus does per pixel treats the four channels alike — over, coverage, clips and masks, gradients, meshes, image sampling — so it is exact on ink amounts, and the existing SWAR and SIMD paths stay as they are. Only blending needs to know about ink (
Subtractive), and only the non-separable modes need K apart (Black, PDF 2.0 11.3.5.3). The K image carries K in all three channels, so separable modes give the same K in each.Canvas
paintreturns apairBlitter(BlitRun/BlitCoverage forwarded to both) when a second image is set; rasterization, clips, the stroker, shapes and unions are untouched.seg.solid) step aside for a pair and go through the blitter. Opaque/invisible tests look at both paints.Resetdrops the second image.LayerShader
mode()maps the blend mode for the K image (Luminosity → Normal, Hue/Saturation/Color →blendBackdrop, B = cb, an internal value). WithSubtractivethe generic path complements source and backdrop (α − c), blends, and complements back; Multiply/Screen's integer fast path is for additive layers only. Normal is unchanged.Tests (
cmyk_test.go)TestCanvasPair: fills of curves, opaque (analytic) and translucent strokes, a dashed stroke, pixel-aligned and offset rectangles, a shader fill, cached glyphs blitted directly and through the mask shader, under a fractional clip rectangle and a clip path and without clips: the pair gives byte for byte what each image gives drawn alone; with no second paint both get the first.TestLayerShaderSubtractive: 400 random premultiplied pixel pairs, all 16 modes, subtractive and (for the non-separable) as the K image, againsts·(1−αb) + αs·αb·(1 − B(1 − cb, 1 − cs))in floating point, within one level.go test ./...green. Benchmarks of the single-image paths (glyph cache, border stroke, layer shader, rectangle fill) show only this machine's spread.Luminosity soft masks of CMYK groups and the conversion of a pair to
image.CMYKare left to the caller (cera).