|
@@ -573,8 +573,6 @@ static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode*
|
|
|
if (!node->node.image.href || !strlen(node->node.image.href)) return nullptr;
|
|
|
auto picture = Picture::gen();
|
|
|
|
|
|
- TaskScheduler::async(false); //force to load a picture on the same thread
|
|
|
-
|
|
|
const char* href = node->node.image.href;
|
|
|
if (!strncmp(href, "data:", sizeof("data:") - 1)) {
|
|
|
href += sizeof("data:") - 1;
|
|
@@ -586,14 +584,12 @@ static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode*
|
|
|
auto size = b64Decode(href, strlen(href), &decoded);
|
|
|
if (picture->load(decoded, size, mimetype, false) != Result::Success) {
|
|
|
free(decoded);
|
|
|
- TaskScheduler::async(true);
|
|
|
return nullptr;
|
|
|
}
|
|
|
} else {
|
|
|
auto size = svgUtilURLDecode(href, &decoded);
|
|
|
if (picture->load(decoded, size, mimetype, false) != Result::Success) {
|
|
|
free(decoded);
|
|
|
- TaskScheduler::async(true);
|
|
|
return nullptr;
|
|
|
}
|
|
|
}
|
|
@@ -605,7 +601,6 @@ static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode*
|
|
|
const char *dot = strrchr(href, '.');
|
|
|
if (dot && !strcmp(dot, ".svg")) {
|
|
|
TVGLOG("SVG", "Embedded svg file is disabled.");
|
|
|
- TaskScheduler::async(true);
|
|
|
return nullptr;
|
|
|
}
|
|
|
string imagePath = href;
|
|
@@ -614,13 +609,10 @@ static unique_ptr<Picture> _imageBuildHelper(SvgLoaderData& loaderData, SvgNode*
|
|
|
imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1)) + imagePath;
|
|
|
}
|
|
|
if (picture->load(imagePath) != Result::Success) {
|
|
|
- TaskScheduler::async(true);
|
|
|
return nullptr;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- TaskScheduler::async(true);
|
|
|
-
|
|
|
float w, h;
|
|
|
Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
|
|
|
if (picture->size(&w, &h) == Result::Success && w > 0 && h > 0) {
|
|
@@ -900,6 +892,41 @@ static void _updateInvalidViewSize(const Scene* scene, Box& vBox, float& w, floa
|
|
|
if (!validHeight) h *= vBox.h;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static void _loadFonts(Array<FontFace>& fonts)
|
|
|
+{
|
|
|
+ if (fonts.empty()) return;
|
|
|
+
|
|
|
+ static constexpr struct {
|
|
|
+ const char* prefix;
|
|
|
+ size_t len;
|
|
|
+ } prefixes[] = {
|
|
|
+ {"data:font/ttf;base64,", sizeof("data:font/ttf;base64,") - 1},
|
|
|
+ {"data:application/font-ttf;base64,", sizeof("data:application/font-ttf;base64,") - 1}
|
|
|
+ };
|
|
|
+
|
|
|
+ for (uint32_t i = 0; i < fonts.count; ++i) {
|
|
|
+ auto p = &fonts[i];
|
|
|
+ if (!p->name) continue;
|
|
|
+
|
|
|
+ size_t shift = 0;
|
|
|
+ for (const auto& prefix : prefixes) {
|
|
|
+ if (p->srcLen > prefix.len && !memcmp(p->src, prefix.prefix, prefix.len)) {
|
|
|
+ shift = prefix.len;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (shift == 0) {
|
|
|
+ TVGLOG("SVG", "The embedded font \"%s\" data not loaded properly.", p->name);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ auto size = b64Decode(p->src + shift, p->srcLen - shift, &p->decoded);
|
|
|
+
|
|
|
+ if (Text::load(p->name, p->decoded, size) != Result::Success) TVGERR("SVG", "Error while loading the ttf font named \"%s\".", p->name);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/************************************************************************/
|
|
|
/* External Class Implementation */
|
|
|
/************************************************************************/
|
|
@@ -910,6 +937,8 @@ Scene* svgSceneBuild(SvgLoaderData& loaderData, Box vBox, float w, float h, Aspe
|
|
|
|
|
|
if (!loaderData.doc || (loaderData.doc->type != SvgNodeType::Doc)) return nullptr;
|
|
|
|
|
|
+ _loadFonts(loaderData.fonts);
|
|
|
+
|
|
|
auto docNode = _sceneBuildHelper(loaderData, loaderData.doc, vBox, svgPath, false, 0);
|
|
|
|
|
|
if (!(viewFlag & SvgViewFlag::Viewbox)) _updateInvalidViewSize(docNode.get(), vBox, w, h, viewFlag);
|