如何从文件加载CanvasSvgDocument?

时间:2018-11-15 21:14:03

标签: c++-winrt win2d

在C ++ / winrt项目中,我有大量要从文件加载的小型svg资源。由于在CanvasVirtualControl的每个CreateResources事件中从磁盘重新加载它们会很慢,因此我已经预先加载了它们并将它们的数据存储在数组中。当发生CreateResources时,我的意图是通过使用CanvasSvgDocument方法LoadFromXml(System.string)为每个容器加载一个CanvasSvgDocument。但是,如果我使用resourcecreator创建svgDocument,则在调用LoadFromXml()时会收到无效的参数崩溃。 resourceCreator参数看起来正确(VS预览6现在允许我查看局部变量!),而xml数据字符串参数看起来像有效的svg数据,因此,我对崩溃的最佳猜测是数据字符串的格式错误。文件数据为UTF-8。如果我按照LoadFromXml参数的要求将其转换为std :: wstring,是否仍可以将其理解为字节数据? 例如,我以这种方式创建std :: wstring,它给出了一个指向未签名char文件数据的指针及其长度(以字节为单位):

m_data_string = std::wstring(data, data + dataLength);

触发CreateResources时,将以这种方式引用数据字符串:

m_svg = CanvasSvgDocument(resourceCreator);
m_svg.LoadFromXml(resourceCreator, m_data_string);

但是LoadFromXml崩溃并显示该无效参数错误。我看到数据字符串的长度是正确的,但是当然那是字符数,而不是数据的实际大小。 svg中的UTF-8属性与现在被记录为16位字符的事实之间是否可能存在冲突?如果是这样,将如何从此类数据加载xml文档?

[更新],建议我使用winrt :: to_hstring。我将未签名的char数据读入std :: string,

std::string cstring = std::string("");
cstring.assign(data, data + dataLength);

然后我将其转换为

m_data_string = winrt::to_hstring(cstring);

最后尝试像以前一样加载svg:

m_svg.LoadFromXml(resourceCreator, m_data_string);

它像以前一样崩溃。我注意到在调试器中,转换后的字符串在任何情况下都不会显得很乱-在两种情况下,它在调试器中均以预期的svg数据形式读取。但是,如果此字符串很宽,这是否与svg中将其标识为UTF-8的属性冲突?

[更新]我开始怀疑是否有人使用过CanvasSvgDocument.Draw()来绘制从文件加载的svg。这些文件现在可以加载而不会崩溃,无需更改其内部编码参考。但是-他们不会画画。这些文件(共239个)为UTF-8,svg 1.1,如果在Edge或任何浏览器中打开,则显示效果很好。但是,如果我将文件数据加载到hstring,创建CanvasSvgDocument,然后使用CanvasSvgDocument.LoadFromXml加载它们,则当CanvasSvgDocument的draw方法调用它们时,它们不会绘制。在绘图期间,其他形状的绘图等也可以正常工作。这可能是一个提示:如果在加载后在其中一个svg上调用GetXML(),返回的内容就是这样:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>

即,图纸信息不存在。还是这就是GetXml()打算返回的全部范围?那似乎没有用。因此,也许CanvasSvgDocument.LoadFromXml(ResourceCreator,String)实际上还不能工作? 因此,我再次要问:是否有一种方法可以从文件数据中加载功能强大的CanvasSvgDocument?

1 个答案:

答案 0 :(得分:0)

我的第一个答案是错误的:上面代码中的错误是LoadFromXml()是静态方法,有人在其他地方指出我,我正在丢弃返回的结果。它应该是theSvg = CanvasSvgDocument :: LoadFromXml(string)。 更正了该问题之后,我回到了在参数为宽字符字符串的方法中加载UTF-8数据的问题。毕竟,将内部引用更改为UTF-16并没有帮助。用CanvasSvgDocument :: LoadAsync(filestream)加载svg是可行的,但是如果我想在不重新访问磁盘的情况下加载这些svg,我将需要找到一种从字节缓冲区制作RandomAccessFileStream的方法,然后使用LoadAsync。我认为。除非有其他方法可以使LoadFromXmL()起作用-当前,它会因无效的参数错误而失败。