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>
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>
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>
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>
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>
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>
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>
- 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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
- 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>
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>
- 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>
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>
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>
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>
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>
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>
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>
A couple of render-time decisions require knowledge of object bounding
boxes, such as gradients (whose default coordinate space is
"objectBoundingBox". This CL adds the current node being rendered to the
render context so that it can be accessed down-stack (for example, when
gradients are being resolved and added to the paint as Skia shaders).
Each node will overload the bounds computation, for now it just returns
empty bounds for all nodes. TBD if we want to cache bounds somewhere,
either inside the node object or in a separate cache.
Bug: skia:10842
Change-Id: I40061ffedcb840e4dd28dba6351421f5b4fc904b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/329221
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This fixes the aspect ratio for pretty much all tests.
Since we're going to rebaseline everything, also have dm use a white
background (to match other user agents).
Bug: skia:10842
Change-Id: Iab2afd61560af540539c216d1c3673f19fe0fe51
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328982
Commit-Queue: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Specifying gradientUnits will allow gradient coordinates to be specified
relative to object bounding boxes, as seen in test 'coords-units-01-b'.
Not yet used with this CL.
Bug: skia:10842
Change-Id: I6038cf3995a94c7e3a7ac73ad8305872353a403c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/328977
Reviewed-by: Florin Malita <fmalita@chromium.org>
Auto-Submit: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Tyler Denniston <tdenniston@google.com>
Move the SVG rendering code to modules/svg, and componentize.
Also split into include/src/utils.
As external clients still reference the old header locations,
introduce temporary forwarding headers to facilitate the migration.
This reverts commit d6cf56fd34.
TBR=
Change-Id: Ibadd7c8dc0464ec0c27841530ade0c2098305d20
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327344
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Florin Malita <fmalita@google.com>
This reverts commit 6fc4106a9d.
Reason for revert: Blocking the Android roll
Original change's description:
> [svg] Relocate out of experimental
>
> Move the SVG rendering code to modules/svg, and componentize.
> Also split into include/src/utils.
>
> As external clients still reference the old header locations,
> introduce temporary forwarding headers to facilitate the migration.
>
> Change-Id: Ib289dbdcd80c16a01c47805e7242f2e08bebc165
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326948
> Reviewed-by: Tyler Denniston <tdenniston@google.com>
> Commit-Queue: Florin Malita <fmalita@google.com>
TBR=fmalita@chromium.org,fmalita@google.com,tdenniston@google.com
Change-Id: I386cf77a15a9e1d392029804abaf937dae53f435
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/327342
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Move the SVG rendering code to modules/svg, and componentize.
Also split into include/src/utils.
As external clients still reference the old header locations,
introduce temporary forwarding headers to facilitate the migration.
Change-Id: Ib289dbdcd80c16a01c47805e7242f2e08bebc165
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326948
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>