【发布时间】:2018-03-23 21:33:08
【问题描述】:
我正在尝试调整 https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/D2DSvgImage 的 Direct 2D SVG 示例以绘制 SVG 字符串而不是从文件中绘制。我所做的只是替换代码以从 Assets 文件中打开一个流。以下是相关摘录:
void D2DSvgImageRenderer::CreateDeviceDependentResources()
{
auto d2dContext = m_deviceResources->GetD2DDeviceContext();
StorageFolder^ packageFolder = Windows::ApplicationModel::Package::Current->InstalledLocation;
// Retrieve the SVG file from the app package.
// ORIGINAL create_task(packageFolder->GetFileAsync("Assets\\drawing.svg")).then([=](StorageFile^ file)
create_task([]()
{
// Open the SVG file for reading.
// ORIGINAL return file->OpenAsync(FileAccessMode::Read);
char *svg = "<svg><circle r=\"300\" cy=\"509\" cx=\"370\" style=\"fill:#ffff00;stroke:#000000;stroke-width:5\"/></svg>";
auto stream = ref new Windows::Storage::Streams::InMemoryRandomAccessStream();
auto writer = ref new Windows::Storage::Streams::DataWriter(stream);
auto p = svg;
while (*p != '\0')
{
writer->WriteByte((unsigned char)*p);
p++;
}
create_task(writer->StoreAsync()).get();
create_task(writer->FlushAsync()).get();
return stream;
}).then([=](IRandomAccessStream^ stream)
{
// Wrap the WinRT stream with a COM stream.
ComPtr<IStream> iStream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
stream,
IID_PPV_ARGS(&iStream)
)
);
// Parse the file stream into an SVG document.
DX::ThrowIfFailed(
d2dContext->CreateSvgDocument(
iStream.Get(),
D2D1::SizeF(sc_svgSize, sc_svgSize), // Create the document at a size of 500x500 DIPs.
&m_svgDocument
)
);
});
}
但我总是收到莫名其妙的参数不正确异常,无法调试为什么会这样。 (DirectX 没有提供任何调试方式或提供任何提示,为什么以及哪个参数不正确!?)
我有根据的猜测是,API 从未告诉我们在CreateSvgDocument 中使用InMemoryRandomAccessStream 是严格禁止的隐藏事实。我该如何解决这个问题?
【问题讨论】:
-
你在什么时候得到这个异常?
-
第二个 ThrowIfFailed 即对 CreateSvgDocument 的调用。我可以确认之前通话中的 iStream 内容正确。
-
看来你还没写完呢。您可能需要调用
writer.StoreAsync(),然后调用writer.FlushAsync(),如InMemoryRandomAccessStreamClass usage example 中所述。 -
@VTT 正如前面评论中提到的,我可以完美地回读在
CreateSvgDocument之前创建的iStream:内容确实存在。可以肯定的是,我刚刚测试过,即使使用StoreAsync和FlushAsync,它仍然会崩溃。