Как загрузить CanvasSvgDocument из файла?

В проекте C ++ / winrt у меня есть большое количество небольших ресурсов svg, которые нужно загрузить из файла. Поскольку было бы медленно перезагружать их все с диска при каждом событии CreateResources из CanvasVirtualControl, я загрузил их заранее и сохранил данные для каждого в массиве. Когда происходит CreateResources, я намерен загрузить CanvasSvgDocument для каждого из них с помощью метода CanvasSvgDocument LoadFromXml (System.string). Однако, если я создаю svgDocument с помощью создателя ресурсов, я получаю сбой неверного аргумента при вызове LoadFromXml (). Аргумент resourceCreator выглядит правильно (VS Preview 6 теперь позволяет мне видеть локальные переменные!), А аргумент строки данных xml выглядит как действительные данные svg, поэтому мое лучшее предположение о сбое - это строка данных неправильного формата. Данные файла - UTF-8. Если я конвертирую это в std :: wstring, как я должен для аргумента LoadFromXml, можно ли его по-прежнему понимать как байтовые данные? Например, я создаю std :: wstring таким образом, учитывая указатель на данные файла без знака char и его длину в байтах:

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

Когда запускается CreateResources, на эту строку данных ссылаются следующим образом:

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

Но LoadFromXml вылетает с ошибкой недопустимого параметра. Я вижу, что длина строки данных правильная, но, конечно, это количество символов, а не фактический размер данных. Мог ли быть конфликт между атрибутом UTF-8 в svg и тем фактом, что он теперь записан как 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. Но если эта hstring имеет широкие символы, разве это не будет конфликтом с атрибутом в svg, который идентифицирует его как UTF-8?

[Обновление] Я начинаю задаваться вопросом, использовал ли кто-нибудь когда-нибудь CanvasSvgDocument.Draw () для рисования svg, загруженного из файла. Файлы теперь загружаются без сбоев без каких-либо изменений в их внутренней кодировке. Но - они не рисуют. Эти файлы - 239 из них - имеют формат UTF-8, svg 1.1, и они хорошо отображаются при открытии в Edge или любом браузере. Но если я загружаю данные файла в hstring, создаю CanvasSvgDocument, а затем использую CanvasSvgDocument.LoadFromXml для их загрузки, они не будут отображаться при вызове методом рисования CanvasSvgDocument. Другое рисование фигур и т. Д. Отлично работает во время сеанса рисования. Вот что может быть подсказкой: если я вызываю GetXML () для одного из этих SVG после его загрузки, то возвращается только следующее:

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

То есть информации о рисовании там нет. Или это все, что должен вернуть GetXml ()? Это бесполезно. Так что, возможно, CanvasSvgDocument.LoadFromXml (ResourceCreator, String) еще не работает? Итак, я снова задаюсь вопросом: есть ли способ загрузить функциональный CanvasSvgDocument из файловых данных?


person user3743210    schedule 15.11.2018    source источник
comment
std::wstring(data, data + dataLength) неверно. Он не конвертируется из UTF-8 в UTF-16; он просто расширяет кодовые единицы UTF-8, создавая тарабарщину. Вместо этого используйте winrt :: to_hstring .   -  person IInspectable    schedule 16.11.2018
comment
Спасибо, IInspectable - я могу использовать to_hstring, но все равно получаю такой же сбой. Я обновлю выше, чтобы показать, что я имею в виду.   -  person user3743210    schedule 16.11.2018
comment
Я экспериментировал с одним файлом svg: вручную изменил кодировку = UTF-8 на чтение кодировки = UTF-16. Теперь этот файл загрузится. Если в ходе дальнейшей работы будет установлено, что эти файлы теперь можно использовать в обычном режиме, я отправлю ответ, что файл svg не может быть загружен с помощью CanvasSvgDocument.LoadFromXml (), если он внутренне идентифицирован как UTF-8. SVG можно правильно преобразовать в широкую строку, но внутреннее упоминание UTF-8 вызовет конфликт.   -  person user3743210    schedule 16.11.2018
comment
Как именно происходит сбой кода? Отображает ли он диалоговое окно подтверждения неудачной отладки? Возникает ли исключение? В последнем случае, каков стек вызовов в момент сбоя? Вы пробовали использовать вместо него LoadElementFromXml? По-видимому, для этого не требуется полный XML-документ, поэтому это может быть для вас способом безопасно удалить элемент encoding из файлов (-ов) SVG XML (если я не читаю документацию неправильно).   -  person IInspectable    schedule 16.11.2018
comment
Спасибо - это была ошибка недопустимого параметра. Оказалось, что это противоречие между строкой широких символов и ее внутренней ссылкой на UTF-8. Я отвечу на вопрос и покажу, что я сделал, чтобы это исправить.   -  person user3743210    schedule 16.11.2018
comment
И обратите внимание на мое обновление выше: теперь вопрос снова открыт.   -  person user3743210    schedule 18.11.2018
comment
Возможно, лучше всего просто открыть проблему в репозитории Win2D GitHub.   -  person IInspectable    schedule 19.11.2018


Ответы (1)


Мой первый ответ здесь был неправильным: ошибка в моем приведенном выше коде заключается в том, что LoadFromXml () является статическим методом, и кто-то указал мне в другом месте, я отбрасывал возвращенный результат. Это должно быть theSvg = CanvasSvgDocument :: LoadFromXml (строка). Исправив это, я вернулся к проблеме загрузки данных UTF-8 в метод, аргументом которого является строка с широкими символами. Изменение внутренней ссылки на UTF-16 в конце концов не помогает. Загрузка svg с помощью CanvasSvgDocument :: LoadAsync (filestream) работает, но если я хочу загрузить их без повторного доступа к диску, мне нужно будет найти способ сделать RandomAccessFileStream из буфера байтов, а затем использовать LoadAsync. Я думаю. Если нет другого способа заставить LoadFromXmL () работать - в настоящее время он не работает с ошибкой недопустимого аргумента.

person user3743210    schedule 16.11.2018
comment
Похоже, что, хотя это решило проблему с загрузкой, полученный SVG не будет отображаться. Я попытался открыть svg в текстовом редакторе и сохранить его как 16-битный текст с прямым порядком байтов, пометив его как UTF-16LE, но он не загружается. Может не быть способа использовать 8-битный SVG из файловых данных с помощью LoadFromXML. Загрузка их непосредственно из файла с помощью LoadAsync работает за счет чтения сотен из них с диска в каждом CreateResources. Если я найду лучшее решение, я расширю свой ответ выше. А может, кто-нибудь еще ... - person user3743210; 17.11.2018
comment
Оказывается, я ошибся - теперь я могу загружать svgs из 8-битных файлов, не меняя их внутреннюю ссылку на кодировку на UTF-16. Но они не будут рисовать с помощью CanvasSvgDocument- ›Draw. Я добавлю еще к своему вопросу выше. Возможно, потребуется задать новый вопрос. - person user3743210; 18.11.2018