"Not quite a String"-bug report

Hey,

unless i made a mistake somewhere, when reading a string from an xml file into a juce::String the first character is being ignored if it’s an empty space or a ‘\n’

would be cool if it was possible to actually start a text with any sort of empty character. this is useful for example when you have 2 neighboring texts and want their lines to align with each other, but one of them starts a bit further down than the other text.

How are you reading the XML to a string?

This code works for me (although the newline isn’t parsed):

const auto textElement = R"(
    <test>    This line has leading whitespace.</test>
)";
auto xml = juce::parseXML(textElement);
DBG(xml->getChildElement(0)->getAttributeValue(0));

const auto textProperty = R"(
    <test text="\nThis line also has leading whitespace."></test>
)";
xml = juce::parseXML(textProperty);
DBG(xml->getAttributeValue(0));
    This line has leading whitespace.
\nThis line also has leading whitespace.

i’m loading an xml from binaryData with:

juce::XmlDocument::parse(String(data, sizeInBytes));

then i convert that to a valueTree because it has the better workflow:

const auto vt = ValueTree::fromXml(*xml);

then at some point in my code while traversing through all the children i read strings from all the properties called “text” because that’s how my xml file works:

child.getProperty("text").toString()

and all this mostly works perfectly, but for some reason that “single space or \n”-beginning of one of the texts doesn’t end up in the string that i use in the end.

this is the part of the xml file that caused this to happen btw:
image
line 35. when i have the underscore there it works, which is why i’m doing that atm, but both spaces as well as just adding a line break will not add a line break to the string in the code, even though it does so for the other line breaks… as if line breaks are only registered if there was a “real” character before.

EDIT: wait wait wait. i think it has something to do with the fact that i store the string by using a component’s “setName” function. i only just noticed that it does a whole lot more than just replacing some string and i wouldn’t be surprised if it also changed the input string at some point. i’ll try rewriting that now.

EDIT 2: ok no. even when using a normal String to store and load the string it won’t draw correctly. when I DBG that string tho i notice that it is a correctly parsed string. so the error must happen even after that. the only thing i could think of that could still go wrong here is, that Graphics’ drawFittedText() maybe ignores the first line if it’s empty or something like that?

EDIT 3: i don’t understand a lot of that class’s code as it’s very lowlevel but maybe it’s because of this:


the GlyphArrangement.cpp method addFittedText’ trim-method removes all the whitespace characters. idk but maybe it also removes the line break in this very specific case where a string starts with no visible character before its first line break.

EDIT 4: if it is because of this method i’d suggest removing the trimmed call entirely. when using justification top removing the first line breaks doesn’t produce the desired behaviour and i suppose it would be the same if using justification bottom with line breaks at the end. people who wanna have trimmed strings can trim their strings themselves, can’t they? it would certainly be easier than having everyone trying to calculate y-offsets for their strings manually to compensate for their strings being trimmed.

EDIT 5: nvm, must be something else, because replacing that line with

auto trimmed = text;

produces the same results.