58 const char* stringValue) {
59 auto parseResult = SkSVGAttributeParser::parse<SkSVGIRI>(stringValue);
60 if (!parseResult.isValid()) {
69 const char* stringValue) {
70 SkString str(stringValue, strlen(stringValue));
77 const char* stringValue) {
78 auto parseResult = SkSVGAttributeParser::parse<SkSVGTransformType>(stringValue);
79 if (!parseResult.isValid()) {
88 const char* stringValue) {
89 auto parseResult = SkSVGAttributeParser::parse<SkSVGLength>(stringValue);
90 if (!parseResult.isValid()) {
99 const char* stringValue) {
102 if (!
parser.parseViewBox(&viewBox)) {
112 const char* stringValue) {
113 auto parseResult = SkSVGAttributeParser::parse<SkSVGObjectBoundingBoxUnits>(stringValue);
114 if (!parseResult.isValid()) {
123 const char* stringValue) {
126 if (!
parser.parsePreserveAspectRatio(&par)) {
134SkString TrimmedString(
const char* first,
const char* last) {
139 while (first <= last && *first <=
' ') { first++; }
140 while (first <= last && *last <=
' ') { last--; }
143 return SkString(first, SkTo<size_t>(last - first + 1));
149 StyleIterator(
const char* str) : fPos(str) { }
151 std::tuple<SkString, SkString>
next() {
155 const char*
sep = this->nextSeparator();
156 SkASSERT(*sep ==
';' || *sep ==
'\0');
158 const char* valueSep = strchr(fPos,
':');
159 if (valueSep && valueSep < sep) {
160 name = TrimmedString(fPos, valueSep - 1);
161 value = TrimmedString(valueSep + 1, sep - 1);
164 fPos = *
sep ?
sep + 1 :
nullptr;
167 return std::make_tuple(
name, value);
171 const char* nextSeparator()
const {
172 const char*
sep = fPos;
173 while (*sep !=
';' && *sep !=
'\0') {
185 const char* stringValue) {
188 StyleIterator iter(stringValue);
190 std::tie(
name, value) = iter.next();
191 if (
name.isEmpty()) {
194 set_string_attribute(node,
name.c_str(),
value.c_str());
201struct SortedDictionaryEntry {
206struct AttrParseInfo {
211SortedDictionaryEntry<AttrParseInfo> gAttributeParseInfo[] = {
215 SetObjectBoundingBoxUnitsAttribute }},
221 SetPreserveAspectRatioAttribute }},
239SortedDictionaryEntry<sk_sp<SkSVGNode>(*)()> gTagFactories[] = {
280struct ConstructionContext {
281 ConstructionContext(
SkSVGIDMapper* mapper) : fParent(nullptr), fIDMapper(mapper) {}
282 ConstructionContext(
const ConstructionContext& other,
const sk_sp<SkSVGNode>& newParent)
283 : fParent(newParent.
get()), fIDMapper(other.fIDMapper) {}
290 if (node->parseAndSetAttribute(
name, value)) {
295 const int attrIndex =
SkStrSearch(&gAttributeParseInfo[0].fKey,
296 SkTo<int>(std::size(gAttributeParseInfo)),
297 name,
sizeof(gAttributeParseInfo[0]));
299#if defined(SK_VERBOSE_SVG_PARSING)
305 SkASSERT(SkTo<size_t>(attrIndex) < std::size(gAttributeParseInfo));
306 const auto& attrInfo = gAttributeParseInfo[attrIndex].fValue;
307 if (!attrInfo.fSetter(node, attrInfo.fAttr, value)) {
308#if defined(SK_VERBOSE_SVG_PARSING)
309 SkDebugf(
"could not parse attribute: '%s=\"%s\"'\n",
name, value);
321 while ((
name = attrIter.next(&value))) {
323 if (!strcmp(
name,
"id")) {
327 set_string_attribute(svgNode,
name, value);
333 const char* elem =
dom.getName(xmlNode);
341 ctx.fParent->appendChild(std::move(
txt));
348 auto make_node = [](
const ConstructionContext& ctx,
const char* elem) ->
sk_sp<SkSVGNode> {
349 if (strcmp(elem,
"svg") == 0) {
355 const int tagIndex =
SkStrSearch(&gTagFactories[0].fKey,
356 SkTo<int>(std::size(gTagFactories)),
357 elem,
sizeof(gTagFactories[0]));
359#if defined(SK_VERBOSE_SVG_PARSING)
360 SkDebugf(
"unhandled element: <%s>\n", elem);
364 SkASSERT(SkTo<size_t>(tagIndex) < std::size(gTagFactories));
366 return gTagFactories[tagIndex].fValue();
369 auto node = make_node(ctx, elem);
374 parse_node_attributes(
dom, xmlNode, node, ctx.fIDMapper);
376 ConstructionContext localCtx(ctx, node);
377 for (
auto* child =
dom.getFirstChild(xmlNode,
nullptr); child;
378 child =
dom.getNextSibling(child)) {
381 node->appendChild(std::move(childNode));
391 fFontMgr = std::move(fmgr);
396 fResourceProvider = std::move(rp);
401 fTextShapingFactory = f;
408 if (!xmlDom.
build(str)) {
413 ConstructionContext ctx(&mapper);
415 auto root = construct_svg_node(xmlDom, ctx, xmlDom.
getRootNode());
421 sk_sp<SkData> load(
const char[],
const char[])
const override {
return nullptr; }
424 auto resource_provider = fResourceProvider ? fResourceProvider
425 : sk_make_sp<NullResourceProvider>();
431 std::move(resource_provider),
433 std::move(factory)));
441 : fRoot(
std::move(root))
442 , fFontMgr(
std::move(fmgr))
443 , fTextShapingFactory(
std::move(fact))
444 , fResourceProvider(
std::move(rp))
445 , fIDMapper(
std::move(mapper))
463 fTextShapingFactory));
479 fTextShapingFactory),
485 return fContainerSize;
495 return this->fIDMapper.
find(idStr);
500 return set_string_attribute(
sk_ref_sp(
this), attributeName, attributeValue);
static float next(float f)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
sk_sp< T > sk_ref_sp(T *obj)
SkSVGWrapperValue< SkSVGPreserveAspectRatio, SkSVGValue::Type::kPreserveAspectRatio > SkSVGPreserveAspectRatioValue
SkSVGWrapperValue< SkSVGObjectBoundingBoxUnits, SkSVGValue::Type::kObjectBoundingBoxUnits > SkSVGObjectBoundingBoxUnitsValue
SkSVGWrapperValue< SkSVGViewBoxType, SkSVGValue::Type::kViewBox > SkSVGViewBoxValue
SkSVGWrapperValue< SkSVGStringType, SkSVGValue::Type::kString > SkSVGStringValue
SkSVGWrapperValue< SkSVGTransformType, SkSVGValue::Type::kTransform > SkSVGTransformValue
SkSVGWrapperValue< SkSVGLength, SkSVGValue::Type::kLength > SkSVGLengthValue
int SkStrSearch(const char *const *base, int count, const char target[], size_t target_len, size_t elemSize)
const Node * getRootNode() const
const Node * build(SkStream &)
static sk_sp< SkSVGCircle > Make()
static sk_sp< SkSVGClipPath > Make()
Builder & setTextShapingFactory(sk_sp< SkShapers::Factory >)
sk_sp< SkSVGDOM > make(SkStream &) const
Builder & setFontManager(sk_sp< SkFontMgr >)
Builder & setResourceProvider(sk_sp< skresources::ResourceProvider >)
void renderNode(SkCanvas *, SkSVGPresentationContext &, const char *id) const
sk_sp< SkSVGNode > * findNodeById(const char *id)
void render(SkCanvas *) const
void setContainerSize(const SkSize &)
const SkSize & containerSize() const
static sk_sp< SkSVGDefs > Make()
static sk_sp< SkSVGEllipse > Make()
static sk_sp< SkSVGFeBlend > Make()
static sk_sp< SkSVGFeColorMatrix > Make()
static sk_sp< SkSVGFeComposite > Make()
static sk_sp< SkSVGFeDiffuseLighting > Make()
static sk_sp< SkSVGFeDisplacementMap > Make()
static sk_sp< SkSVGFeDistantLight > Make()
static sk_sp< SkSVGFeFlood > Make()
static sk_sp< SkSVGFeGaussianBlur > Make()
static sk_sp< SkSVGFeImage > Make()
static sk_sp< SkSVGFeMorphology > Make()
static sk_sp< SkSVGFeOffset > Make()
static sk_sp< SkSVGFePointLight > Make()
static sk_sp< SkSVGFeSpecularLighting > Make()
static sk_sp< SkSVGFeSpotLight > Make()
static sk_sp< SkSVGFeTurbulence > Make()
static sk_sp< SkSVGFilter > Make()
static sk_sp< SkSVGG > Make()
static sk_sp< SkSVGImage > Make()
static sk_sp< SkSVGLine > Make()
static sk_sp< SkSVGLinearGradient > Make()
static sk_sp< SkSVGMask > Make()
void setAttribute(SkSVGAttribute, const SkSVGValue &)
static sk_sp< SkSVGPath > Make()
static sk_sp< SkSVGPattern > Make()
static sk_sp< SkSVGPoly > MakePolygon()
static sk_sp< SkSVGPoly > MakePolyline()
static sk_sp< SkSVGRadialGradient > Make()
static sk_sp< SkSVGRect > Make()
static sk_sp< SkSVGSVG > Make(Type t=Type::kInner)
static sk_sp< SkSVGStop > Make()
static sk_sp< SkSVGTSpan > Make()
static sk_sp< SkSVGTextLiteral > Make()
static sk_sp< SkSVGTextPath > Make()
static sk_sp< SkSVGText > Make()
static sk_sp< SkSVGUse > Make()
V * find(const K &key) const
SKSHAPER_API sk_sp< Factory > Factory()
const myers::Point & get(const myers::Segment &)
#define TRACE_EVENT0(category_group, name)