Page 1 of 1

C++ how to use wide strings and char?

Posted: 18 Aug 2017, 15:26
by Wanderer
I want multilanguage interface, how can I display widestring or char? I tried in xaml in textBlock word "prázdno", Noesis display prOzdno O = rectangle. If I add text in c++ code
NsString text = "prázdno"
in gui I get OOno O = rectangle. I dont use any theme now.

Re: C++ how to use wide strings and char?

Posted: 18 Aug 2017, 17:00
by Athos
The font needs to have a glyph for the given codepoint.
Change the font family of your text to Robot (In Samples folder) and it'll render fine.

Re: C++ how to use wide strings and char?

Posted: 18 Aug 2017, 17:01
by jsantos
We only support UTF8 encoding. So, you need to translate from wide string to UTF8. In windows you can use WideCharToMultiByte and similar functions for that purpose. We also provide a portable function inside UTF8.h.
/// Conversion from UTF16 to UTF8. Returns the numbers of characters needed for the whole text
/// even if they don't fit in the provided buffer.
inline NsSize UTF16To8(const NsUInt16* utf16, NsChar* utf8, NsSize numUTF8Chars);
Please, let me know if this solves your problem.

Re: C++ how to use wide strings and char?

Posted: 18 Aug 2017, 17:07
by jsantos
The font needs to have a glyph for the given codepoint.
Change the font family of your text to Robot (In Samples folder) and it'll render fine.
Indeed you also need a compatible font. Thanks Athos!

Re: C++ how to use wide strings and char?

Posted: 19 Aug 2017, 10:47
by Wanderer
Thanks all for answers. I resolve conversion myself and it is working (using Poco library for text).

I have another questions:
1. When I set up Theme(with ResourceDirectory) and ResourceProvider, how this theme knows where is font located? I checked xaml files but don't find any info how is used font. In tutorials is mentioned only for TextBlock but how use one font for all text?

2. When I have this code
const NsChar * ContainerItem::m_func_GetNameSource() const // is part Noesis Get and Set function for displaying text in GUI by binding
{
	std::wstring ws = L"ľščť";
	std::string text;
	Poco::UnicodeConverter uc;
	uc.toUTF8(ws, text);
	NsString m_NsString_SourceFull = text.c_str();
	return m_NsString_SourceFull.c_str();
}
Program freezes - window appear but nothing is shown. If m_NsString_SourceFull is created with text
NsString m_NsString_SourceFull = "ľščť";
program start ok. But characters are not show right. The best solution I found is m_NsString_SourceFull must be member and make conversion outside GetNameSource() method. Then program never freezes. Question is, why I cannot have conversion inside GetNameSource()?

Re: C++ how to use wide strings and char?

Posted: 19 Aug 2017, 21:51
by sfernandez
In your code m_NsString_SourceFull in getter function is a stack variable, a temporal object, so returning c_str() of that object may result in a crash or accessing corrupted memory.
You should declare it as a member variable, so object persists after returning from the function, something like this:
class YourViewModel: Noesis::BaseComponent ...
{
public:
  ...
  const NsChar* ContainerItem::m_func_GetNameSource() const
  {
	std::wstring ws = L"ľščť";
	std::string text;
	Poco::UnicodeConverter uc;
	uc.toUTF8(ws, text);
	m_NsString_SourceFull = text.c_str();
	return m_NsString_SourceFull.c_str();
  }
  ...
private:
  NsString m_NsString_SourceFull;
  ...
};

Re: C++ how to use wide strings and char?

Posted: 20 Aug 2017, 18:59
by Wanderer
Thanks.

Re: C++ how to use wide strings and char?

Posted: 23 Aug 2017, 20:14
by sfernandez
About the global font, we have a default ttf that is applied when nothing else is specified.

If you want to specify your own global font there are two ways of doing it:

- In the Theme, by defining a ContentControl style with the key RootContainerStyle. If that key is found in the Theme dictionary we wrap View content with a ContentControl and apply that style so everything inherits all the properties set in the style. It could look like this:
<Style x:Key="RootContainerStyle" TargetType="{x:Type ContentControl}">
    <Setter Property="UseLayoutRounding" Value="True"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="FontFamily" Value="Fonts/#Roboto"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="FontStyle" Value="Normal"/>
    <Setter Property="FontWeight" Value="Normal"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContentControl}">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
- Setting these properties in the root of your View yourself. You can create the View with a UserControl root object that will be the container for all your UI. UI elements will inherit all the properties you set in the root UserControl:
<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  UseLayoutRounding="True"
  Foreground="Black"
  FontFamily="Fonts/#Roboto"
  FontSize="12"
  FontStyle="Normal"
  FontWeight="Normal">
    <!--- UI will be added as Content of this control -->
</UserControl>

Re: C++ how to use wide strings and char?

Posted: 23 Aug 2017, 23:01
by Wanderer
Thanks.

If I use both scenario, which fonts will be used? Can I overide theme font by adding this:
<UserControl
  ...
  FontFamily="Fonts/#Roboto"
  FontSize="12"
  FontStyle="Normal"
  FontWeight="Normal">
    <!--- UI will be added as Content of this control -->
</UserControl>
it is possible?

Re: C++ how to use wide strings and char?

Posted: 24 Aug 2017, 11:45
by sfernandez
Yes, you can override it like this, because inherited properties like FontFamily, FontSize, Foreground, etc. use the value set in the nearest ancestor.