[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>
diff --git a/modules/svg/src/SkSVGAttributeParser.cpp b/modules/svg/src/SkSVGAttributeParser.cpp
index 2a408e8..1f8cb66 100644
--- a/modules/svg/src/SkSVGAttributeParser.cpp
+++ b/modules/svg/src/SkSVGAttributeParser.cpp
@@ -5,8 +5,6 @@
* found in the LICENSE file.
*/
-#include <vector>
-
#include "include/private/SkTPin.h"
#include "include/utils/SkParse.h"
#include "modules/svg/include/SkSVGAttributeParser.h"
@@ -920,20 +918,30 @@
}
// https://www.w3.org/TR/SVG11/types.html#DataTypeCoordinates
-template <>
-bool SkSVGAttributeParser::parse(std::vector<SkSVGLength>* lengths) {
- SkASSERT(lengths->empty());
+template <typename T>
+bool SkSVGAttributeParser::parseList(std::vector<T>* vals) {
+ SkASSERT(vals->empty());
- SkSVGLength length;
+ T v;
for (;;) {
- if (!this->parse(&length)) {
+ if (!this->parse(&v)) {
break;
}
- lengths->push_back(length);
+ vals->push_back(v);
this->parseCommaWspToken();
}
- return !lengths->empty() && this->parseEOSToken();
+ return !vals->empty() && this->parseEOSToken();
+}
+
+template <>
+bool SkSVGAttributeParser::parse(std::vector<SkSVGLength>* lengths) {
+ return this->parseList(lengths);
+}
+
+template <>
+bool SkSVGAttributeParser::parse(std::vector<SkSVGNumberType>* numbers) {
+ return this->parseList(numbers);
}