Problem with translation and displayed strings

#1

Hello,

I have a problem with fonts when implementing translations (Chinese) :

  • In the source code, where a string should be displayed I use TRANS(“some text to translate”)

  • I have a language.txt file

  • My language.txt is encoded in the UTF 8 format (I’m sure about that) and contains some chinese translations.

  • In the Application::initialise I have :

    const File traductionFile(“some/path/to/lang.txt”);
    const String content = traductionFile.loadFileAsString();
    LocalisedStrings::setCurrentMappings(new LocalisedStrings(content, false));

  • In the LookAndFeel I use a font that can display Chinese (Microsoft YaHei)

But it was not enough and I had to redefine the Label drawing. In a separate empty project, when I draw using TextLayout, it works…
In the main project we are working on since many years, it just displays messy characters everywhere.

Someone have any ideas or clues ?
If there is an option in the projucer or a flag which changed, which could explain why we don’t have the same behavior between a new project and the old one?

0 Likes

#2

Which platform are you trying to build for?

0 Likes

#3

Thank you for your answer :slight_smile:

I only tried on Windows 10 for now. But we will use it on both Mac OS and Windows

0 Likes

#4

Try adding /utf-8 to the compiler options (you can configure this manually or add it in the corresponding field in the projucer) and make sure all files are utf-8 encoded. That did it for me

0 Likes

#5

I didn’t have to append /utf-8 on any platform except windows by the way.

0 Likes

#6

Sadly it not worked for me. I guess it’s because the chineses characters are stored in the translation file.

0 Likes

#7

@Blueteal if you get it working, can you share a basic snippet that shows the necessary steps?

0 Likes

#8

Is your translation file utf-8 encoded?

0 Likes

#9

The OP said it so in their first post:

0 Likes

#10

Which exact versions of JUCE (the ideal would be a commit SHA1 from the JUCE repository) are you using for the new project and the old one? Are you using the same version or different versions? Without knowing more about the JUCE code you are using, we can’t really help.

0 Likes

#11

It works now ! There was a lot of small problems, so to sum up how to make it works :

  • Use the translate("EnglishString") / TRANS("EnglishString") in the source code for each displayed strings (The projucer can convert a string to ASCII escaped chars if you want to include some “éô无标题的” (CharPointer_UTF8 ("\xc3\xa9\xc3\xb4\xe6\x97\xa0\xe6\xa0\x87\xe9\xa2\x98\xe7\x9a\x84") in your source code)
  • Use the projucer tools to scan and create a translation file content
  • Make sure this file is UTF8 encoded (Notepad++ displays the encodage in the bottom of the window, and you can convert the file to UTF8 with it)
  • At starting of the application (in initialise for example) load the translation file
//juce::File is good to load UTF8 / ASCII files, so make sure it's the case
const File translationFile("Some/Path/to/translation/file.txt");
LocalisedStrings::setCurrentMappings(new LocalisedStrings(translationFile, false)); //idk if there is a leak here, but it not triggers a juce assert on the application quit

The LookAndFeel use lot of methods from the Graphics object. But it may not works (prints some squares), and you will need to redefine methods to use a TextLayout :


class CustomLookAndFeel : public LookAndFeel_V4 {
public:
	void drawLabel(Graphics& g, Label& label) override {
		g.fillAll(label.findColour(Label::backgroundColourId));

		if (!label.isBeingEdited()) {
			drawText(
				g, 
				label.getText(), 
				label.getBounds(), 
				label.getJustificationType(), 
				label.findColour(Label::textColourId), 
				label.findColour(Label::outlineColourId)
			);
		}
		else if (label.isEnabled()) {
			g.setColour(label.findColour(Label::outlineColourId));
		}

		g.drawRect(label.getLocalBounds());
	}

	static void drawText(Graphics& g, 
		const String& txt, 
		const Rectangle<int>& bounds, 
		Justification justification, 
		Colour colour, 
		Colour outlineColour, 
		bool isEnabled = true) {

		//Use a font that can display all your translation
		//Microsoft YaHei can display chinese but is Windows specific
		//For Mac you can use "Arial Unicode MS"
		const juce::Font font("Microsoft YaHei", bounds.getHeight()*0.9, 0);
		const float alpha = isEnabled ? 1.0f : 0.5f;

		g.setColour(colour.withMultipliedAlpha(alpha));
		juce::Rectangle<int> textArea = bounds; // (label.getBorderSize().subtractedFrom(label.getLocalBounds()));

		juce::TextLayout textLayout;
		juce::AttributedString str(txt); 
		str.setJustification(justification);
		str.setColour(colour.withMultipliedAlpha(alpha));
		str.setFont(font);
		textLayout.createLayout(str, textArea.getWidth());

		textLayout.draw(g, textArea.toFloat());

		g.setColour(outlineColour.withMultipliedAlpha(alpha));
	};
};

I had some issues using Font("font name", height, 0) so I created a typeface and then use it to get a font.

I hope this can help people a bit confused about how to add translations in their app with juce.

Anyway, thanks a lot for your answers ! :slight_smile:

2 Likes