Commit Graph

58 Commits

Author SHA1 Message Date
Tyler Denniston
94730febf9 [svg] Handle std input case for filter subregion calculation
From the spec [1], if any inputs of a filter are one of the standard
inputs (SourceGraphic, FillPaint, etc. -- anything except another
filter), then the default filter primitive subregion is equal to the
filter effect region.

[1] https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveSubRegion

Bug: skia:10841
Change-Id: I70632e5119861c46c9e48af944d2c7cfdfc3c351
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354119
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2021-01-14 22:04:48 +00:00
Tyler Denniston
3df6c20a05 [svg] Fix <use> bounds calculation
Previously we were using fX and fY as the top left of the returned
bounds. We need instead to offset the referenced node's bounds by fX,
fY.

While I was here I updated the attribute parsing to the new form and
changed the type of fHref from SkSVGString to SkSVGIRI.

Change-Id: I4bfb91bca62e47f5dabfbb4aad48cbb301a7ea36
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354118
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2021-01-14 21:35:58 +00:00
Florin Malita
3c10618d37 [svg] Add clipPathUnits support
https://www.w3.org/TR/SVG11/masking.html#ClipPathElementClipPathUnitsAttribute

Bug: skia:10842
Change-Id: Idf3b5b6da08dfaee165f0bbb549427f298a40cec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353713
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-14 20:18:15 +00:00
Florin Malita
4ea46b71ac [svg] Fix null text context crash
The input may contain invalid text constructs lacking a root <text> node
e.g.  <svg><tspan>foo</tspan></svg>

Since we don't perform content model validation at the moment and text
contexts are only instantiated for root nodes, we must guard against
this case at render time.

Bug: oss-fuzz:29558
Change-Id: I7e39c1c4048900ce5becb3549802dc66bb1d242b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353711
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-14 19:03:25 +00:00
Florin Malita
491911003e [svg] Mask support
https://www.w3.org/TR/SVG11/masking.html#Masking

Implement masking based on a classic two-layers + kSrcIn blending
approach.

An additional layer is used to filter the mask content (but could be
avoided in a pinch -- see inline comments).

Also consolidate the objectBoundingBox rect resolution logic as
SkSVGRenderContext::resolveOBBRect().

Bug: skia:10842
Change-Id: I273318e97cc28d599d1ecf01706b6117eecb62d5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353631
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-14 18:50:46 +00:00
Tyler Denniston
8f78d55284 Reland "[svg] Perform colorspace conversions for filter effects"
This reverts commit 36acb7b10c.

Reason for revert: artifacts in 1010102 are expected

Original change's description:
> Revert "[svg] Perform colorspace conversions for filter effects"
>
> This reverts commit a0880eda22.
>
> Reason for revert: visual artifacts in 10-bit color depth (10-10-10-2)
>
> Original change's description:
> > [svg] Perform colorspace conversions for filter effects
> >
> > A filter effect can optionally be specified to operate in either sRGB
> > or linearRGB, according to the SVG spec:
> >
> > https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperties
> >
> > This CL adds any necessary conversion steps (SkColorFilters) while
> > constructing the filter DAG. The default filter effect color space is
> > linearRGB. We should now be passing the filters-gauss-* W3C tests.
> >
> > Specific changes:
> > - Tag filter effect results with their colorspace when storing them in
> >   the filter context map
> > - Add an SkColorFolor conversion step as necessary when resolving filter
> >   effect inputs
> >
> > Bug: skia:10841
> > Change-Id: Ide12698ea64c4d40f09df93a60718788809086fa
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353078
> > Commit-Queue: Tyler Denniston <tdenniston@google.com>
> > Reviewed-by: Florin Malita <fmalita@chromium.org>
>
> TBR=fmalita@chromium.org,tdenniston@google.com
>
> Change-Id: Id4a33c49643039cfb2d2867a1513e8ee1d7b181a
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10841
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353630
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

TBR=fmalita@chromium.org,tdenniston@google.com,johnstiles@google.com

# Not skipping CQ checks because this is a reland.

Bug: skia:10841
Change-Id: Id6d9e01d9b18ebfb6f9a6cb74518ad5cd73ea00a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353777
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2021-01-14 15:02:23 +00:00
John Stiles
36acb7b10c Revert "[svg] Perform colorspace conversions for filter effects"
This reverts commit a0880eda22.

Reason for revert: visual artifacts in 10-bit color depth (10-10-10-2)

Original change's description:
> [svg] Perform colorspace conversions for filter effects
>
> A filter effect can optionally be specified to operate in either sRGB
> or linearRGB, according to the SVG spec:
>
> https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperties
>
> This CL adds any necessary conversion steps (SkColorFilters) while
> constructing the filter DAG. The default filter effect color space is
> linearRGB. We should now be passing the filters-gauss-* W3C tests.
>
> Specific changes:
> - Tag filter effect results with their colorspace when storing them in
>   the filter context map
> - Add an SkColorFolor conversion step as necessary when resolving filter
>   effect inputs
>
> Bug: skia:10841
> Change-Id: Ide12698ea64c4d40f09df93a60718788809086fa
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353078
> Commit-Queue: Tyler Denniston <tdenniston@google.com>
> Reviewed-by: Florin Malita <fmalita@chromium.org>

TBR=fmalita@chromium.org,tdenniston@google.com

Change-Id: Id4a33c49643039cfb2d2867a1513e8ee1d7b181a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10841
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353630
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
2021-01-13 22:57:16 +00:00
Tyler Denniston
a0880eda22 [svg] Perform colorspace conversions for filter effects
A filter effect can optionally be specified to operate in either sRGB
or linearRGB, according to the SVG spec:

https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperties

This CL adds any necessary conversion steps (SkColorFilters) while
constructing the filter DAG. The default filter effect color space is
linearRGB. We should now be passing the filters-gauss-* W3C tests.

Specific changes:
- Tag filter effect results with their colorspace when storing them in
  the filter context map
- Add an SkColorFolor conversion step as necessary when resolving filter
  effect inputs

Bug: skia:10841
Change-Id: Ide12698ea64c4d40f09df93a60718788809086fa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353078
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2021-01-13 22:15:26 +00:00
Tyler Denniston
7bb85dbb5e [svg] Add plumbing for color-interpolation-filters property
The default colorspace for filter effects is linear RGB, as specified in
https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperties.
Currently we perform all filtering in the destination colorspace. This
CL adds the new presentation attribute with the default setting
(according to the spec) of linear RGB.

This CL does not actually implement any colorspace transformations for
filters.

Bug: skia:10841
Change-Id: Id778ad3fa5cb6e0aed756584a50880edd9d82e2b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352738
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2021-01-13 18:07:14 +00:00
Florin Malita
836c2ca6a1 [svg] Initial mask plumbing
Introduce SkSVGMask and plumb related attributes.

Also consolidate the clip/mask/filter property types - they all support
the same values: <funciri>|none|inherit.

Bug: skia:10842
Change-Id: If45a75cccc19b84d6547237336fe5d562a85d594
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/353436
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-13 17:23:24 +00:00
Florin Malita
fc0ea0a4a5 [svg] TextPath support
- introduce SkSVGTextPath and update the text render logic to
    instantiate new SkSVGTextContexts in onRenderText() overrides
    instead of renderText() root -- this is to observe spec semantics
    [1] requiring <text> and <textPath> to always start a new chunk,
    regardless of their relative nesting.
  - expand SkSVGTextContext to also store PathData when used in the
    scope of a textPath
  - PathData caches SkContourMeasures, for path position lookup
  - update flushChunk() to apply path glyph adjustments [2]:

    * the horizontal glyph position (including relative offset dx),
      adjusted for the glyph center yields a path offset
    * if the offset is outside the path range, the glyph is skipped
    * otherwise the position is determined based on the path matrix
      at the computed offset

   - to support the logic above, the chunk starting position is no
     longer used as a global blob offset but instead is folded into
     individual glyph RSXforms (and the blob always draws at {0,0})

[1] https://www.w3.org/TR/SVG11/text.html#TextLayout
[2] https://www.w3.org/TR/SVG11/text.html#TextpathLayoutRules

Bug: skia:10840
Change-Id: I462eada7c086646afdc1bc84f08ec2368613f1c0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/349397
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-13 14:37:39 +00:00
Tyler Denniston
187d8117cb [svg] Implement feGaussianBlur
This filter implementation should be complete, but note we are still
not quite passing the W3C filters-gauss-* tests because our filters
currently operate in sRGB and not linear RGB (which is quite noticable
in some of the blur tests).

Bug: skia:10841
Change-Id: I706cde879ef6eb47ce586279999536cf67237f13
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352506
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2021-01-12 16:26:16 +00:00
Tyler Denniston
3a92f776b0 [svg] Implement onObjectBoundingBox for circle and path
Also removed an erroneous call to mapToRect() when returning bounds
for SkSVGContainer. The contexts in which we access object bounds are
always such that any transforms have already been applied.

Change-Id: Ieac488e1699d3ebff56038d6ada36737291671eb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345117
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2021-01-12 15:05:16 +00:00
Tyler Denniston
0a145b77f7 [svg] Compute and use filter primitive subregion
Spec: https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveSubRegion

The filter primitive subregion restricts the output of a specific <fe*>
node in a filter DAG. By default it's equal to the union of subregions
of all input filters, or the filter region if no inputs exist. If
x/y/w/h are specified on the <fe*> node, those are used to bound the
primitive subregion instead.

In this CL:
- Implement the computation of the primitive subregion in
  SkSVGFe::resolveFilterSubregion
- Add primitiveUnits to filter context
- Change result registration (by string ID) in filter context to include
  the primitive subregion of that result. This is needed because filters
  referencing previous results need access to those primitive subregions
  to compute the union.

Bug: skia:10841
Change-Id: I66fbb4979e3c65cb5e5cc61f98286ec7ad023438
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344666
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2021-01-11 17:42:57 +00:00
Florin Malita
736c992966 [svg] Deferred text position adjustments
Upcoming textPath changes require position adjustments (relative offset,
rotation) to be applied after mapping to path, at chunk flush time.

Bug: skia:10840
Change-Id: Ifccea2983d5d5c57876d0a25e1da113e4c9cd51a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350018
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-05 21:52:25 +00:00
Florin Malita
2d059fcc22 [svg] Text rotate support
Implement support for text 'rotate' attribute:
https://www.w3.org/TR/SVG11/text.html#TSpanElementRotateAttribute.

Unlike other character-positioning attributes (x/y/dx/dy), rotate

  - is not cumulative
  - only applies to its respective node scope (does not affect other
    fragments in the current chunk)
  - has different padding semantics: if there are fewer rotate
    values than characters, the remaining characters use the last
    specified value from the closest ancestor

To the last point, we now have to discriminate three states:

  - unspecified (default -> 0)
  - explicit value for the given character index
  - implicit value (last value in the closest ancestor)

Local implicit values override implicit ancestor values -- but not
explicit ancestor values.

High level changes:

  - plumb 'rotate' attribute
  - expand per-character position info (ShapeBuffer) to include rotation
  - expand per-glyph position info (RunRec) to include rotation
  - expand PosAttrs to include rotation and add specific inheritance
    rules (see above)
  - pass computed rotation values to RSX blob buffers

Bug: skia:10840
Change-Id: Ia19ec5e8bb6fea06d49a9bd72ace575c2ffd100e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/348877
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2021-01-05 17:43:51 +00:00
Florin Malita
e5a2171d6e [svg] Convert text rendering to RSX form
In preparation of per-character rotation support, switch to RSX text
blobs.

TBR=
Bug: skia:10840
Change-Id: Ia7de0983d1445e61e97caae9404d472cc3736730
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/348880
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Florin Malita <fmalita@google.com>
2020-12-30 17:13:07 +00:00
Florin Malita
735ac97eb4 [svg] Relative postioning support for text
Introduce support for relative position adjustments [1]:

  - plumb dx, dy attributes
  - extend ScopedPosResolver to also handle the new attributes
  - introduce ShapeBuffer to store both utf8 text and position
    adjustments for shaping (replaces prev 'filtered' array).
  - position adjustments are cumulative (relative adjustments affect
    all following characters)
  - utf8 encoding is variable length; for simplicity, ensure that the
    pos adjustment array and the utf8 array are always the same size by
    repeating the pos adjustment times number of utf8 bytes
  - introduce a temporary buffer for retrieving utf8 cluster information
    from SkShaper
  - post-shaping, use the utf8 cluster info to map back to character
    indices and apply the associated position adjutment

[1] https://www.w3.org/TR/SVG11/text.html#TSpanElementDXAttribute

Bug: skia:10840
Change-Id: Ia9f227f91723400711ff2b5d260976290da1e2e5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/346636
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-12-22 19:19:12 +00:00
Florin Malita
dec78021f5 Reland "[svg] Absolute positioning support for text"
This reverts commit e2f6245352.

Reason for revert: relanding with fixes

Original change's description:
> Revert "[svg] Absolute positioning support for text"
>
> This reverts commit febb1b87a5.
>
> Reason for revert: breaking the android roll
>
> Original change's description:
> > [svg] Absolute positioning support for text
> >
> > Implement per-character position attribute lookup based on [1]:
> >
> >   - convert "x" and "y" attributes to arrays
> >   - introduce ScopedPosResolver to handle positioning attribute lookup
> >     and fallback
> >   - push a new resolver every time we enter a text positioning element
> >     scope (<text>, <tspan>, etc).
> >   - flush/reposition a new text chunk every time we encounter explicit
> >     absolute positions
> >
> > The position attribute fallback logic is complex enough to warrant a
> > unit test.
> >
> > [1] https://www.w3.org/TR/SVG11/text.html#TSpanElementXAttribute
> >
> > Bug: skia:10840
> > Change-Id: I66c478fea4a179fdb8b1a6a9ff00c4dd9509f8d2
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345161
> > Commit-Queue: Florin Malita <fmalita@chromium.org>
> > Commit-Queue: Florin Malita <fmalita@google.com>
> > Reviewed-by: Tyler Denniston <tdenniston@google.com>
>
> TBR=fmalita@chromium.org,fmalita@google.com,tdenniston@google.com
>
> Change-Id: I80e3396d555369fe835ee73102135061f63e8bf0
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10840
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345417
> Reviewed-by: Derek Sollenberger <djsollen@google.com>
> Commit-Queue: Derek Sollenberger <djsollen@google.com>

TBR=djsollen@google.com,fmalita@chromium.org,fmalita@google.com,tdenniston@google.com

# Not skipping CQ checks because this is a reland.

Bug: skia:10840
Change-Id: I4c6f6a9f19c0f7598bdcf34e915f43c139b995a9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345420
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
2020-12-18 02:09:18 +00:00
Derek Sollenberger
e2f6245352 Revert "[svg] Absolute positioning support for text"
This reverts commit febb1b87a5.

Reason for revert: breaking the android roll

Original change's description:
> [svg] Absolute positioning support for text
>
> Implement per-character position attribute lookup based on [1]:
>
>   - convert "x" and "y" attributes to arrays
>   - introduce ScopedPosResolver to handle positioning attribute lookup
>     and fallback
>   - push a new resolver every time we enter a text positioning element
>     scope (<text>, <tspan>, etc).
>   - flush/reposition a new text chunk every time we encounter explicit
>     absolute positions
>
> The position attribute fallback logic is complex enough to warrant a
> unit test.
>
> [1] https://www.w3.org/TR/SVG11/text.html#TSpanElementXAttribute
>
> Bug: skia:10840
> Change-Id: I66c478fea4a179fdb8b1a6a9ff00c4dd9509f8d2
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345161
> Commit-Queue: Florin Malita <fmalita@chromium.org>
> Commit-Queue: Florin Malita <fmalita@google.com>
> Reviewed-by: Tyler Denniston <tdenniston@google.com>

TBR=fmalita@chromium.org,fmalita@google.com,tdenniston@google.com

Change-Id: I80e3396d555369fe835ee73102135061f63e8bf0
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10840
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345417
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Derek Sollenberger <djsollen@google.com>
2020-12-17 19:21:37 +00:00
Florin Malita
febb1b87a5 [svg] Absolute positioning support for text
Implement per-character position attribute lookup based on [1]:

  - convert "x" and "y" attributes to arrays
  - introduce ScopedPosResolver to handle positioning attribute lookup
    and fallback
  - push a new resolver every time we enter a text positioning element
    scope (<text>, <tspan>, etc).
  - flush/reposition a new text chunk every time we encounter explicit
    absolute positions

The position attribute fallback logic is complex enough to warrant a
unit test.

[1] https://www.w3.org/TR/SVG11/text.html#TSpanElementXAttribute

Bug: skia:10840
Change-Id: I66c478fea4a179fdb8b1a6a9ff00c4dd9509f8d2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/345161
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-12-17 17:31:25 +00:00
Florin Malita
adc6889228 [svg] Refactor text rendering context plumbing
Instead of relying on RenderContext to pass text rendering options
downstack, introduce a dedicated virtual (onRenderText) and pass options
explicitly.

Root text nodes bridge from onRender() -> onRenderText().

This removes some complexity from RenderContext and incidentally fixes
xml:space = preserve (the value was being dropped during local ctx
copying).

Bug: skia:10840
Change-Id: Ic5fd9e0f9382f52f65108521574fcb2a422b97aa
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344559
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
2020-12-15 16:54:42 +00:00
Tyler Denniston
dcf288ba82 [svg] Fix filter region bounds
When the filter units are objectBoundingBox, values are fractions/pcts
of the object's bounding box, which we were miscomputing.

Also adding in a small tweak to return bounds for <polygon> elements
(will be needed for future filter tests).

Bug: skia:10841
Change-Id: I7fcac21258570d872672c42e99a9739a65c53e30
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/343520
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-15 16:15:19 +00:00
Tyler Denniston
62a683e476 [svg] Prep work for filter primitive subregion
- Add primitiveUnits attribute to SkSVGFilter class
- Add optional x, y, width, height attributes to filter effect base
  class (SkSVGFe)
- Add function to return list of inputs for all filter effects
- Add function to compute filter primitive subregion and use it in all
  filter effect classes.

Currently the "primitive subregion" just returns the entire filter
effect region, so there should be no diffs on gold with this change.

Bug: skia:10841
Change-Id: I1de283bebe302c0710d6b09d62a2472787820a49
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/343107
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-11 18:21:21 +00:00
Tyler Denniston
b2d1a3bdd7 [svg] Minor cleanups
- Consolidate SVGColor resolution into one method in render context, now
  that it's a shared type.
- Remove all instances of `~TypeName() override = default;`. The only
  thing this provides is slight/unreliable protection against someone
  inadvertently removing 'virtual' from the base class destructor. In
  our case that is SkRefCnt, which I'm assuming has very low risk of
  that happening.
- Clean up some .h copy/paste issues of the form
  `#endif  // Typename_DEFINED`

Change-Id: I67fb40b2828b010fb7fdd83046bc1eae1a476267
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/343421
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-11 16:25:20 +00:00
Tyler Denniston
8ed044363f [svg] Add feFlood filter node
Several related W3C tests still won't pass until we implement the filter
primitive subregion.

Bug: skia:10841
Change-Id: I9e4beb9da8aa769f23a979ad5116a38fcda85ca4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/343105
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-11 15:02:20 +00:00
Tyler Denniston
04e03bc181 [svg] Convert stop-color and stop-opacity to presentation attrs
These are somewhat the first presentation attributes of their kind,
in that they are non-inherited but also not applied via canvas layers.

Implementation-wise the main difference is that these attributes are
not propagated through the fInherited field of the render context's
presentation attribute list.

Change-Id: I0909507b0ecbd21732b3f80c46a343f5a0a9bf7a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340661
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-09 21:37:17 +00:00
Tyler Denniston
7416571f4e [svg] Split out SkSVGColor from paint
This color type will be shared in paint, stop-color, and flood-color
attributes (mainly so they can use 'currentColor').

Change-Id: Ib4200ea729a91a0db5da069c68d64e5e8e3f5010
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/340617
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-09 21:28:07 +00:00
Florin Malita
9c1f1be078 [svg] xml:space support
Add xml:space attribute and implement related white space filters.

(https://www.w3.org/TR/SVG11/text.html#WhiteSpace)

Bug: skia:10840
Change-Id: I52fda50fae1cd7cf8b0dd7c1a2ee2e667ffa947b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/342299
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
2020-12-09 20:07:25 +00:00
Florin Malita
7dc984aff0 [svg] Text shaping and layout
Introduce proper text shaping via SkShaper/drawTextBlob (to replace
SkTextUtils::DrawString).

Also add basic text layout support (text chunk alignment and default
fragment advances -- see [1]).

[1] https://www.w3.org/TR/SVG11/text.html#TextLayoutIntroduction

Bug: skia:10840
Change-Id: I246f899d2926d1e365dac06b414c8e1ab4371e1e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341736
Reviewed-by: Ben Wagner <bungeman@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
2020-12-08 20:48:43 +00:00
Florin Malita
512ff75a0b [svg] Initial <tspan> support
Introduce classes to support text node nesting:

  - TextContainer -- base class for nestable text containers
    (<text>, <tspan> etc)
  - TextLiteral -- actual text string/payload

Example structure mapping:

  <text>Foo<tspan>Bar</tspan>Baz</text>

  TextContainer[text]
    TextLiteral["Foo"]
    TextContainer[tspan]
      TextLiteral["Bar"]
    TextLiteral["Baz"]

Also add text layout state (SkSVGTextContenxt) to SkSVGRenderContext.
This will be used to track layout across a text subtree.

For now we don't touch rendering, so the output is quite garbled for
non-trivial text (no advance propagation -> things draw on top of each
other).

Bug: skia:10840
Change-Id: Ic6d3990ec8635b586f5d3d226be070fbf134e391
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/341236
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-12-07 15:29:19 +00:00
Tyler Denniston
041f6656dc [svg] Remove kInherit from several SVG types
We can now remove kInherit from all of the SVG types, but this CL does
just a few to get us started / prove the concept.

SkSVGPaint, SkSVGClip and SkSVGLineCap now do not contain kInherit as an
enum value. Also, SkSVGLineCap (and eventually others) can be a bare
enum class now.

Change-Id: I7de001459bcb1f5586d66b975f92fecedb125dde
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335827
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-12-03 17:36:54 +00:00
Tyler Denniston
4c6f57a23e [svg] Use new code path for rest of presentation attrs
This is another necessary step in order to remove kInherit from all of
the base SVG type enums.

Change-Id: I2185e744f7b27369f7bad36591f896d3a9982b42
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335817
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-30 21:27:04 +00:00
Florin Malita
9a5aa0a295 [svg] Handle zero-radius radial gradients
Per [1]:

"A value of zero will cause the area to be painted as a single color
using the color and opacity of the last gradient stop."

[1] https://www.w3.org/TR/SVG11/pservers.html#RadialGradientElementRAttribute

Bug: skia:10981
Change-Id: I5c4c8444c4dd72d2224b1d8b2536e7aa8c1f4712
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/337180
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-11-22 19:12:10 +00:00
Tyler Denniston
79832e3151 [svg] Parse "inherit" generically for SkSVGProperty
This generic parsing will allow us to later remove kInherit and
"inherit" parsing from all other specific SVG types.

Also convert "filter" presentation attribute to new-style parsing
for compatibility with the setter.

Change-Id: Id917e12d77cdefb1a8f1404cac1e0c4e486d8b53
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335660
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-11-18 16:51:55 +00:00
Tyler Denniston
75c38f94ef [svg] Add SkSVGProperty class for presentation attributes
This CL adds a new SkSVGProperty<T,B> class and uses it instead of
SkTLazy for the presentation attributes. Ideally this will form the
foundation for improvements to our presentation attribute parsing
as well as correctness for inherited/non-inherited properties.

Change-Id: Ie1cdb3db9674c55376e127cc1a8b8cb303a1bd13
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/334837
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-17 18:11:24 +00:00
Florin Malita
7006e15df5 [svg] Allow clients to pass a custom SkFontMgr
Introduce a Builder helper and plumb the client-provided SkFontMgr for
font resolution.

Also clean up some of the legacy SkSVGDom factories.

Bug: skia:10840
Change-Id: I6e1eabe7c257cb75dfdb5bf67054f93f25769027
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333577
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-11-11 01:51:44 +00:00
Tyler Denniston
a0a5146ba9 [svg] Use new parsing for gradient classes
- Added new SVG_OPTIONAL_ATTR macro for lazy properties
- Added SkSVGIRI type -- we need explicit types now to be able to
  dispatch via the templated parse function
- Converted several attribute parse functions to templated version

Change-Id: I270d35983083f368e36afd96a62c768161d49942
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333518
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-10 19:04:49 +00:00
Tyler Denniston
b25caae788 [svg] Implement feComposite, basic filter result storage
- Plumbing to store filter results by id and resolve them as inputs
  when referenced
- Added implementation of feComposite filter
- Added call to resolve input in feColorMatrix
- Bugfix to SkSVGFilterType operator==

The tests filters-color-01-b and filters-composite-03-b should now be
passing.

Bug: skia:10841
Change-Id: I2cd099c60ac21710f25184806c5cc537656b42af
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332723
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-10 14:00:56 +00:00
Florin Malita
8c42567377 [svg] Convert most presentation attributes to new style parsing
Change-Id: Ib430ce05f7e336ae82a51ee45194338e90d77c58
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332751
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-11-06 19:29:54 +00:00
Tyler Denniston
70bb18d7c9 [svg] Implement feColorMatrix filter
Supporting this filter will also allow us to start implementing and
testing the filter result DAG via the filters-color-01-b test. That test
is one of the simplest that involves filter result storage, so it's a
good candidate to start with.

Bug: skia:10841
Change-Id: Id8317ccfb78031cc6af83c9f3e3f382dcb6dee98
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332599
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-06 18:40:24 +00:00
Florin Malita
401321d98e [svg] Minor parser tweaks
- remove the custom-func SkSVGAttributeParser::parse version and always
  dispatch via SkSVGAttributeParser::parse<T>(T*) - this should
  avoid adding any other parse helper declarations in the future
- relocate the turbulence parse helpers to SkSVGAttributeParser (while
  keeping the definition in SkSVGFETurbulence.cpp)
- update ParseResult initialization to use move semantics

Change-Id: I8ed9811671a6fbc5971f9d1f14e7b9c07da7dec0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332540
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-11-05 17:12:06 +00:00
Tyler Denniston
57154998a8 [svg] Add plumbing for bottom-up attribute parsing
One significant source of boilerplate in the SVG frontend is the
plumbing to ensure type safety all the way down from the XML layer to
the SkSVGNode layer. This is mostly an artifact of the top-down parsing
approach currently used by the SkDOM -> SkSVGDom building process.

One way to help remove some boilerplate is to perform attribute parsing
bottom-up, where each SVG node knows how to parse and populate its own
attribute values from a string-valued KV pair.

Additionally, bottom-up parsing allows us to support the case of the
same SVG attribute name having different meanings on different nodes
(e.g. the "type" attribute has different meaning on <feTurbulence>
versus <feColorMatrix>).

This CL adds some initial work to start us down that road, and ports the
attributes previously added for <feTurbulence> to use the new code path.

Change-Id: I2973cfab96891475d05ebf1228117626ca48ef4d
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/331477
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-04 21:48:03 +00:00
Tyler Denniston
dada960d79 [svg] Add feTurbulence filter (incomplete)
This was the simplest one to start with. I need to add support for the
"filter effect subregion" in order to handle tile stitching property,
so this isn't quite complete. But I believe this is enough for the
basic filters-turb-01-f test to pass, which gives us a baseline for
further filter work.

Summary of changes:
- Added attribute type and parsing for SVG integer datatype
- Added new node class for feTurbulence
- Added several new properties and parsing for feTurbulence

Bug: skia:10841
Change-Id: I8c877a5e1a837bfd527782253062eeb58febdde6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330621
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-03 15:41:41 +00:00
Tyler Denniston
b5e29be9c4 [svg] New layer for image filter if one is set
Prior to rendering a node, check the filter presentation attribute and
create a new canvas layer with a corresponding SkImageFilter set.

Also added the computation of the filter effect region and added a naive
(and incomplete) construction of the image filter DAG for a
<filter> element.

Bug: skia:10841
Change-Id: Ie94299757e059c39540ad316cddf438df5726d97
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330619
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-11-02 21:54:25 +00:00
Tyler Denniston
df208a341b [svg] Add several skeleton classes for filters
Added:

- SkSVGFilter: This corresponds to a <filter> element. Also added some
  of the attributes of this element.
- SkSVGFe: This will be the base class of all <fe*> elements.
- SkSVGFilterContext: This will hold the contextual mapping of string id
  -> image filter result, for constructing pipelines.

Bug: skia:10841
Change-Id: I15a29d39411a6255ab4e11f022baa10554b2bce6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330618
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-10-30 20:41:41 +00:00
Tyler Denniston
b3cafbc45b [svg] Add 'filter' presentation attribute and parsing
Not yet used by anything.

Bug: skia:10841
Change-Id: I6ed0a434cf670d73f06eaf0bbfe70d727ffe4950
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330617
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
2020-10-30 19:50:11 +00:00
Tyler Denniston
30e327e19e [svg] Rename gradient units type to object bounding box units
It turns out that "userSpaceOnUse | objectBoundingBox" can be specified
as the unit type for multiple elements, such as clips, masks, filters
etc. and is not specific to gradients.

The full list:
https://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBoxUnits

Bug: skia:10842
Change-Id: I995d588862fb43b9f130f0455d7af8de47046af4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330616
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-10-30 18:56:40 +00:00
Florin Malita
056385b1c6 [svg] Convert text-anchor to a presentation attribute
https://www.w3.org/TR/SVG11/text.html#TextAnchorProperty

Bug: skia:10840
Change-Id: Iff647b62243c42150e873f06215401b5e33705fd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330125
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
2020-10-28 14:10:01 +00:00
Tyler Denniston
f548a028ce [svg] Implement gradientUnits="objectBoundingBox"
Currently only works properly when filling rects, since that is the only
node that implements bounds computation with this CL.

Summary of changes:

- Scale gradient coords by object bounds when units are
  kObjectBoundingBox.
- Make fGradientUnits protected instead of private.
- Change default value of fGradientUnits to kObjectBoundingBox, which
  is the default according to the spec.
- Change SkSVGNode::onObjectBoundingBox to take a full render context
  instead of length context.
- Implement bounds computation for SkSVGRect, SkSVGContainer and
  SkSVGUse.

Bug: skia:10842
Change-Id: I2e999985e67644e50da7f681fde190bcf4823eec
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329223
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
2020-10-27 19:56:28 +00:00