Properly deal with svg elements
This commit is contained in:
@@ -408,6 +408,22 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track SVG nesting depth. Must be checked before the svgDepth>0 guard below so that
|
||||||
|
// nested <svg> elements increment the counter rather than being swallowed as unknowns.
|
||||||
|
if (strcmp(name, "svg") == 0) {
|
||||||
|
self->svgDepth += 1;
|
||||||
|
self->depth += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inside SVG: only process <image> elements (raster images); skip everything else.
|
||||||
|
// SVG child elements like <path>, <rect>, <circle>, <text> must not reach the layout
|
||||||
|
// engine — they would accumulate path data and exhaust heap on large inline SVG.
|
||||||
|
if (self->svgDepth > 0 && !matches(name, IMAGE_TAGS, NUM_IMAGE_TAGS)) {
|
||||||
|
self->depth += 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Extract class, style, and id attributes
|
// Extract class, style, and id attributes
|
||||||
std::string classAttr;
|
std::string classAttr;
|
||||||
std::string styleAttr;
|
std::string styleAttr;
|
||||||
@@ -1319,6 +1335,12 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip SVG text content (path data, coordinates, etc.) — it would be treated as words
|
||||||
|
// and exhaust heap on EPUBs with large inline SVG elements.
|
||||||
|
if (self->svgDepth > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Collect footnote link display text (for the number label)
|
// Collect footnote link display text (for the number label)
|
||||||
// Remove leading/trailing whitespace and square brackets from the
|
// Remove leading/trailing whitespace and square brackets from the
|
||||||
// footnote link text to normalize noterefs like "[1]" → "1"
|
// footnote link text to normalize noterefs like "[1]" → "1"
|
||||||
@@ -1559,6 +1581,10 @@ void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* n
|
|||||||
|
|
||||||
self->depth -= 1;
|
self->depth -= 1;
|
||||||
|
|
||||||
|
if (strcmp(name, "svg") == 0 && self->svgDepth > 0) {
|
||||||
|
self->svgDepth -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Pop list entries whose ul/ol is now out of scope
|
// Pop list entries whose ul/ol is now out of scope
|
||||||
while (!self->listStack.empty() && self->listStack.back().depth >= self->depth) {
|
while (!self->listStack.empty() && self->listStack.back().depth >= self->depth) {
|
||||||
self->listStack.pop_back();
|
self->listStack.pop_back();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class ChapterHtmlSlimParser final : public Print {
|
|||||||
int underlineUntilDepth = INT_MAX;
|
int underlineUntilDepth = INT_MAX;
|
||||||
int strikethroughUntilDepth = INT_MAX;
|
int strikethroughUntilDepth = INT_MAX;
|
||||||
int preUntilDepth = INT_MAX; // set when inside a <pre> element; enables \n → line-break handling
|
int preUntilDepth = INT_MAX; // set when inside a <pre> element; enables \n → line-break handling
|
||||||
|
int svgDepth = 0; // nesting counter for <svg> elements; text inside SVG is skipped (path data etc.)
|
||||||
// buffer for building up words from characters, will auto break if longer than this
|
// buffer for building up words from characters, will auto break if longer than this
|
||||||
// leave one char at end for null pointer
|
// leave one char at end for null pointer
|
||||||
char partWordBuffer[MAX_WORD_SIZE + 1] = {};
|
char partWordBuffer[MAX_WORD_SIZE + 1] = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user