Does CanvasDrawingSession.DrawSvg() work in C++/winrt? - c++-winrt

I've loaded a series of svg images by creating and storing a CanvasSvgDocument for each, and using its LoadAsync() method to load the svg:
nextSvg = CanvasSvgDocument(resourceCreator.Device());
auto fileStream = co_await nextFile.OpenReadAsync();
co_await nextSvg.LoadAsync(resourceCreator.Device(),fileStream);
This appears to load the svg, but when I use that stored svg in a drawing session nothing appears in the CanvasControl. Other items draw fine: shapes, lines, etc. - just not svgs:
session.DrawSvg(m_svg, boxSize, top, left);
In an attempt to discover the problem I've tried using GetXml() on the svg document in the hope that would show me its contents. The result is an abbreviated svg with no drawing information. I provide that here in case it's a hint:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
Perhaps that is all that GetXml() is supposed to return?
I have successfully drawn svgs if they loaded as imagesources; the resulting bitmap image works. But is it possible that session.DrawSvg() is just not completely implemented yet in Win2D? I'd rather render the svg directly this way if it can be done.
[Update] p.s. The svgs are version 1.1 svgs converted from pdfs by one of the online conversion services. As I mentioned, they render fine if opened in Edge or other browsers.
[Update2] Thinking perhaps there is something in the svgs that Win2D doesn't like, I tried creating a simple one using as a model an online example - it just has a rectangle and a circle, as follows. But it also does not draw:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 140"
preserveAspectRatio="xMidYMid meet">
<title>Scalable Vector Graphics (SVG) Demo</title>
<circle cx="100" cy="100" r="50" stroke="#000" stroke-width="1" fill="#ccc" />
<rect x="200" y="50" width="250" height="100" rx="5" ry="5"
stroke="#000" stroke-width="1" fill="#ccc" />
</svg>
[Update] It appears that the problem lies in the way the svg is read from the Storage File. I'll post my own answer as soon as I have enough that it might be useful to someone.

The answer is that my code contains an egregious error: As was pointed out to me at GitHub, LoadAsync() is a static method. In my first line above, I create a CanvasSvgDocument, but in the third line I ignore the results of LoadAsync. LoadASync is also a constructor, so the proper code is
auto fileStream = co_await nextFile.OpenReadAsync();
nextSvg = co_await CanvasSvgDocument::LoadAsync(resourceCreator.Device(),fileStream);
That works! Only trouble is that what I really want is to use LoadFromXaml(), another static method, and there is a different issue with that to be addressed later. Probably also my error.

Related

Blob has no text() function in Safari 14 on iOS

I'm using a WKWebView on iOS to render an SVG. The SVG is created like this simplified example in a third-party library:
var svgBlob = new Blob(['<?xml version="1.0" standalone="no"?>\r\n' + '<svg height="100" width="100"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /></svg>'], { type: "image/svg+xml" });
My code then tries to obtain the raw SVG text like this:
var svgText = await svgBlob.text();
On Safari 15 and higher, everything works as expected—-the SVG data is returned—-but on Safari 14, I get the error svgBlob.text() is not a function. Upon further inspection, svgBlob is in fact a blob, has a size, a type, and a slice function, but no other properties. The text property/function doesn't even exist.
MDN indicates that this API has existed on Safari on iOS since v14, and there are no caveats listed.
Is there some sort of trick to making this work?

How to change color of SVG on react native?

As title explains the problem, I have an SVG file on my view:
<SvgUri source={require("./assets/icons/eva-icons/arrow-back.svg")} width="50" height="50"/>
How can I change the color of the svg that I am loading? fill attribute does not change anything.
Ok so it seems that the eva-icons are not fully supported by SvgUri. This is caused by a different svg/xml structure, so I opened the icon in Affinity Designer (you can probably choose any SVG Editor), then I modified the arrow-back icon (exchanged the color) and exported it again. Now it is working. You can just pass any color as fill option:
Here is the modified version of the arrow-back.svg:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 16 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"><path d="M15,6.001l-11.86,0l3.63,-4.36c0.149,-0.18 0.231,-0.406 0.231,-0.64c0,-0.549 -0.452,-1.001 -1.001,-1.001c-0.297,0 -0.58,0.133 -0.77,0.361l-5,6c-0.034,0.048 -0.064,0.098 -0.09,0.15c0,0.05 0,0.08 -0.07,0.13c-0.045,0.115 -0.069,0.237 -0.07,0.36c0.001,0.124 0.025,0.246 0.07,0.36c0,0.05 0,0.08 0.07,0.13c0.026,0.052 0.056,0.103 0.09,0.15l5,6c0.19,0.229 0.473,0.361 0.77,0.36c0.234,0.001 0.46,-0.081 0.64,-0.23c0.229,-0.19 0.362,-0.472 0.362,-0.77c0,-0.233 -0.082,-0.46 -0.232,-0.64l-3.63,-4.36l11.86,0c0.549,0 1,-0.451 1,-1c0,-0.548 -0.451,-1 -1,-1Z" style="fill:#f00;fill-rule:nonzero;"/></svg>
Here is the output:

Clicking on stroke of dynamic path using Selenium

In SVG you can have things which are only clickable at the stroke, e.g. because there is no fill or because of pointer-events: stroke.
Example:
document.querySelector("#path1").addEventListener("click", function(e) {
console.log("Click1!")
})
document.querySelector("#path2").addEventListener("click", function(e) {
console.log("Click2!")
})
#path1:hover {
stroke: red;
}
#path2:hover {
stroke: green;
}
<svg height="300" width="300">
<path d="M64,116 C100,100 400,100 96,39" stroke="blue" stroke-width="7" fill="none" id="path1" />
<path d="M134,186 C100,100 400,100 126,69" stroke="blue" stroke-width="7" fill="none" id="path2" />
</svg>
In my project I want to write Selenium tests for I have a dynamically generated SVG <path>s which I want to click at using Selenium, the problem is that the center of the element1 is not necessarily clickable (since only the stroke of the path is).
Some ideas I had:
Clicking at a fixed offset: A possibility but since the generated path is highly dynamic it would mean a lot of tinkering with the offset value to get it right and possibly having to change the test a lot of the future.
Triggering click event through code: Would work but make the test less useful since this way it would not test whether the stroke of the path is indeed clickable. Certain bugs could evade being detected by the test this way.
Setting a non-none fill through code or replacing/adding filled a rect around the <path>: Setting fill might not guarantee either that the center is clickable. A <rect> would work but then the clickable areas of multiple paths would overlap which could mean that the wrong path gets the click.
None of these approaches are ideal. Are there any other possibilities?
(I am using Selenium for Python but I am OK with solutions with Selenium for other programming languages since normally it's easy to port.)
1) This is the default position Selenium clicks at if using the function where no offset is specified, or rather it's the center of the visible area of the element since the newest version of the WebDriver protocol but in my use case everything can be assumed to be fully visible.
P.S.
Demo showing why setting fill to something other than none wouldn't help (or pointer-events to all):
document.querySelector("#path1").addEventListener("click", function(e) {
console.log("Click1!")
})
document.querySelector("#path2").addEventListener("click", function(e) {
console.log("Click2!")
})
#path1:hover {
stroke: red;
}
#path2:hover {
stroke: green;
}
<svg height="300" width="300">
<path d="M64,116 C100,100 400,100 96,39" stroke="blue" stroke-width="7" fill="turquoise" id="path1" />
<path d="M134,186 C100,100 400,100 126,69" stroke="blue" stroke-width="7" fill="yellow" id="path2" />
</svg>

SVG edit only shows half of SVG image file in XAML?

I am using a C# library which doesn't support the viewBox parameter in SVG files, but without it I get my images cut-off as they can't scale properly, details below ...
I am trying to use some SVG files in a mobile application, using the xamarin forms platform and this nuget plugin. The plugin has a very limited support, so I have had to manually change the svg files. When generated, the Google+ image has the following first tag, however, when I use this file, I get the following error message:
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><title>Google_Round</title><
System.Exception: Invalid parameters to context creation
at CoreGraphics.CGContext.set_Handle (IntPtr value) [0x00010] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/CoreGraphics/CGContext.cs:161
at CoreGraphics.CGContext..ctor (IntPtr handle, Boolean owns) [0x00006] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/CoreGraphics/CGContext.cs:141
at CoreGraphics.CGBitmapContext..ctor (IntPtr data, nint width, nint height, nint bitsPerComponent, nint bytesPerRow, CoreGraphics.CGColorSpace colorSpace, CGImageAlphaInfo bitmapInfo) [0x00000] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/CoreGraphics/CGBitmapContext.cs:62
at NGraphics.iOS.Custom.ApplePlatform.CreateImageCanvas (Size size, Double scale, Boolean transparency) [0x0005c] in :0
at SVG.Forms.Plugin.iOS.SvgImageRenderer.OnElementChanged (Xamarin.Forms.Platform.iOS.ElementChangedEventArgs`1 e) [0x0010f] in :0
If I Change that first tag, to a copy of the first tag from a known workign example, I have the following SVG File.
<?xml version="1.0"?>
<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" height="300" width="300" version="1.1" fill-opacity="0"> xml:space="preserve">
<path fill="#54534A" d="M2204.344,4414.691v-122.67h81.643h81.642l-1.237,6.804c-0.619,3.505-1.649,10.515-2.474,15.462l-1.443,8.659
h-61.438h-61.644v38.141v38.141h54.635h54.635v16.493v16.494h-54.635h-54.635v36.079v36.08h60.613h60.407l1.443,10.515
c0.825,5.979,2.062,13.401,2.68,16.493l1.237,5.979h-80.818h-80.612V4414.691z"/>
<!-- Various Strokes omitted -->
</g>
</svg>
This gives me the following display of what would otherwise be a full G+ icon. I assume it is because I have lost the viewBox info from the file. How else can I include this information to ensure my svg scales appropriately, without causing the plugin to fail?
set property Stretch="Uniform" in a Path and control this path via margin.

How to create loading mask on a XUL panel using JQuery or JScript

does anyone know how to create a loading mask over a XUL panel with JQuery or normal Javascript?
i am developing a firefox extension and i need the loading mask over some of the panels to avoid the user from making any further input while information is being submitted.
First of, i don't really know if mozilla supports loading masks over XUL panels because all the JQuery scripts i tried so far make the panel disappear instead of masking it.
thanks for reading
XUL uses box layout which makes typical techniques from HTML like absolutely positioned divs malfunction. You should use a XUL <stack> tag (see https://developer.mozilla.org/en/XUL/stack) and put both your content and your half-transparent layer as its children. When you make the half-transparent layer visible it will appear on top of the content. For example:
<stack flex="1">
<hbox id="content" align="center" pack="center">
<button label="Click here" oncommand="document.getElementById('busy').hidden = false;"/>
</hbox>
<hbox id="busy" hidden="true"/>
</stack>
And some CSS code:
#busy {
background-color: black;
opacity: 0.5;
}