From aee5a3a45e91ee11ec94b491f785961c5b35681d Mon Sep 17 00:00:00 2001 From: attila Date: Mon, 9 Oct 2023 22:13:06 +0200 Subject: [PATCH] SVGParser: Add support for multiple coords per text element --- .../drawables/juce_SVGParser.cpp | 62 +++++++++++++------ 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index 756e232919..2a3e5e51e8 100644 --- a/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -1067,12 +1067,10 @@ private: if (! xml->hasTagName ("text") && ! xml->hasTagNameIgnoringNamespace ("tspan")) return nullptr; - Array xCoords, yCoords, dxCoords, dyCoords; + Array xCoords, yCoords; getCoordList (xCoords, getInheritedAttribute (xml, "x"), true, true); getCoordList (yCoords, getInheritedAttribute (xml, "y"), true, false); - getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true); - getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false); auto font = getFont (xml); auto anchorStr = getStyleAttribute (xml, "text-anchor"); @@ -1084,29 +1082,55 @@ private: { if (e->isTextElement()) { - auto text = e->getText().trim(); + auto fullText = e->getText(); - auto dt = new DrawableText(); - dc->addAndMakeVisible (dt); + const auto subtextElements = [&] + { + std::vector> result; - dt->setText (text); - dt->setFont (font, true); + if (xCoords.size() == 1) + { + result.emplace_back (fullText, xCoords[0], yCoords[0]); + return result; + } - if (additonalTransform != nullptr) - dt->setDrawableTransform (transform.followedBy (*additonalTransform)); - else - dt->setDrawableTransform (transform); + if (xCoords.size() != yCoords.size() || fullText.length() != yCoords.size()) + { + jassertfalse; + result.emplace_back (fullText, xCoords[0], yCoords[0]); + return result; + } - dt->setColour (parseColour (xml, "fill", Colours::black) - .withMultipliedAlpha (parseSafeFloat (getStyleAttribute (xml, "fill-opacity", "1")))); + for (int i = 0; i < xCoords.size(); ++i) + result.emplace_back (fullText.substring (i, i + 1), xCoords[i], yCoords[i]); - Rectangle bounds (xCoords[0], yCoords[0] - font.getAscent(), - font.getStringWidthFloat (text), font.getHeight()); + return result; + }(); - if (anchorStr == "middle") bounds.setX (bounds.getX() - bounds.getWidth() / 2.0f); - else if (anchorStr == "end") bounds.setX (bounds.getX() - bounds.getWidth()); + for (const auto& [text, x, y] : subtextElements) + { + auto dt = new DrawableText(); + dc->addAndMakeVisible (dt); - dt->setBoundingBox (bounds); + dt->setText (text); + dt->setFont (font, true); + + if (additonalTransform != nullptr) + dt->setDrawableTransform (transform.followedBy (*additonalTransform)); + else + dt->setDrawableTransform (transform); + + dt->setColour (parseColour (xml, "fill", Colours::black) + .withMultipliedAlpha (parseSafeFloat (getStyleAttribute (xml, "fill-opacity", "1")))); + + Rectangle bounds (x, y - font.getAscent(), + font.getStringWidthFloat (text), font.getHeight()); + + if (anchorStr == "middle") bounds.setX (bounds.getX() - bounds.getWidth() / 2.0f); + else if (anchorStr == "end") bounds.setX (bounds.getX() - bounds.getWidth()); + + dt->setBoundingBox (bounds); + } } else if (e->hasTagNameIgnoringNamespace ("tspan")) {