簡體   English   中英

UWP中的直接2D SVG渲染

[英]Direct 2D SVG Rendering in UWP

我正在嘗試在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 我怎樣才能解決這個問題?

在引發異常之前,此代碼將發出以下診斷信息:

D2D調試錯誤-解析SVG文檔時遇到錯誤。

當我嘗試讀取流內容時,我發現它已關閉(通過在下一個lambda中調用stream->Position; ), 實際上該內容不存在 然后,我研究了文檔。 DataWriter::Close方法參考

備注

DataWriter擁有傳遞給其構造函數的流的所有權。 調用此方法還會調用關聯的流。 調用此方法后,對大多數其他DataWriter方法的調用將失敗。 如果您不希望在關閉閱讀器時關閉關聯的流,請在調用此方法之前調用DataWriter.DetachStream

因此,在您的示例中, writer在超出范圍時將Close stream ,並且SVG解析器將無法讀取任何內容。 因此,您的代碼應如下所示:

auto stream{ref new Windows::Storage::Streams::InMemoryRandomAccessStream{}};
auto writer{ref new Windows::Storage::Streams::DataWriter{stream}}; // takes ownership of stream
const auto & sz_svg{"<svg><circle r=\"300\" cy=\"509\" cx=\"370\" style=\"fill:#ffff00;stroke:#000000;stroke-width:5\"/></svg>"};
for(const char * p{sz_svg}; '\0' != *p; ++p)
{
    writer->WriteByte(static_cast< unsigned char >(*p));
}
create_task(writer->StoreAsync()).get(); // mandatory
//create_task(writer->FlushAsync()).get(); // not necessary since underlaying memory stream does not require flushing
writer->DetachStream(); // release ownership of stream, the value returned is not used since we already have stream variable

PS他們應該為構造函數寫那句話...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM