{"id":137,"date":"2014-10-29T14:55:42","date_gmt":"2014-10-29T13:55:42","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=137"},"modified":"2015-08-21T23:53:07","modified_gmt":"2015-08-21T22:53:07","slug":"how-to-draw-russian-cyrillic-characters-in-libgdx","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-draw-russian-cyrillic-characters-in-libgdx\/","title":{"rendered":"How to draw russian (cyrillic) characters in LibGDX"},"content":{"rendered":"<p style=\"text-align: justify;\">When we develop for mobile devices, we have to keep in mind that propably our program will be used in several countries for users of diferent languages. A tool to facilitate the use of our software for these users is to translate our application into the local language of each user. This process is known as Internacionalization (I18N) and Localization (L10N). To know more about how to implement this in LibGDX, you can go to <a title=\"LibGDX - Internacionalization and Localization\" href=\"https:\/\/github.com\/libgdx\/libgdx\/wiki\/Internationalization-and-Localization\" target=\"_blank\">Official Wiki<\/a>.<\/p>\n<p style=\"text-align: justify;\">On the other hand, one of the options provided to us\u00a0<a title=\"LibGDX official site\" href=\"libgdx.badlogicgames.com\" target=\"_blank\">LibGDX<\/a>\u00a0is to can work with TrueType fonts (.ttf) through the extension <a title=\"LibGDX \/ Gdx-freetype\" href=\"https:\/\/github.com\/libgdx\/libgdx\/wiki\/Gdx-freetype\" target=\"_blank\">gdx-freetype<\/a>. To know more about how to use these fonts, you can go to <a title=\"LibGDX FeeType\" href=\"https:\/\/github.com\/libgdx\/libgdx\/wiki\/Gdx-freetype\" target=\"_blank\">LibGDX Wiki<\/a>.<\/p>\n<p style=\"text-align: justify;\">By combining both tools (I18N \/ L10N and TTF fonts), we find that:<\/p>\n<ol>\n<li style=\"text-align: justify;\">Each language uses a particular alphabet. This is, in brief, the set of letters and spellings that are used to represent the language in written form.<\/li>\n<li style=\"text-align: justify;\">Typically, a font supports only a given set of letters or spellings.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">As result of the above two points, probably we need to use more than one TTF font for showing our program in determined languages. Next, we are going to show an use case by using as example the text \u00ab<em>Hello World!<\/em>\u00bb translated to spanish and russian. It&#8217;s possible to work with other alphabets in a similar way.<\/p>\n<h4 style=\"text-align: justify;\">Important:<\/h4>\n<ol>\n<li style=\"text-align: justify;\">This is not a tutorial about internacionalization nor localization. It simply shows how to draw texts in LibGDX from diferent alphabets with TTF fonts.<\/li>\n<li style=\"text-align: justify;\">Gdx-freetype works with UTF-8, so we need to use this encoding for the files of our project.<\/li>\n<li style=\"text-align: justify;\">You can get source code at\u00a0<a title=\"Give me source code!\" href=\"https:\/\/github.com\/angelnavarro\/Gdx-Freetype-Example\" target=\"_blank\">GitHub<\/a>.<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h3 style=\"text-align: justify;\">Creating the project (gdx-freetype)<\/h3>\n<p style=\"text-align: justify;\">The first step is to create the project in LibGDX. We know we will work with TTF fonts, so it&#8217;s needed the check of the <em>gdx-freetype<\/em> extension.<\/p>\n<p style=\"text-align: justify;\">In this case I will call the project <em>Gdx-Freetype-Example<\/em>. Note:<\/p>\n<ol>\n<li style=\"text-align: justify;\">In this project we will not use the physics library <code>Box2d<\/code>. Then unckeck that option.<\/li>\n<li style=\"text-align: justify;\">We enable the extension <code>Freetype<\/code>, in section \u00abExtensions\u00bb.<\/li>\n<li style=\"text-align: justify;\"><code>Freetype<\/code> does not support HTML project, so we have to uncheck this project generation.<\/li>\n<\/ol>\n<figure id=\"attachment_85\" aria-describedby=\"caption-attachment-85\" style=\"width: 258px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_project_generator.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-85\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_project_generator-258x300.png\" alt=\"freetype_project_generator\" width=\"258\" height=\"300\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_project_generator-258x300.png 258w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_project_generator.png 620w\" sizes=\"(max-width: 258px) 100vw, 258px\" \/><\/a><figcaption id=\"caption-attachment-85\" class=\"wp-caption-text\">LibGDX Project Generator<\/figcaption><\/figure>\n<p>For this project I have used this values:<\/p>\n<ul>\n<li><strong>Name:<\/strong> <code>Gdx-Freetype-Example<\/code><\/li>\n<li><strong>Package:<\/strong> <code>com.pixnbgames.gdx_freetype_example<\/code><\/li>\n<li><strong>Game class:<\/strong> <code>GdxGameFreetypeExampleGame<\/code><\/li>\n<\/ul>\n<p style=\"text-align: justify;\">If we have done it well, when we import this project in our IDE, we can see the <code>gdx-freetype<\/code> as dependeces of the project:<\/p>\n<figure id=\"attachment_87\" aria-describedby=\"caption-attachment-87\" style=\"width: 238px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_libs.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-medium wp-image-87\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_libs-238x300.png\" alt=\"gdx-freetype libs\" width=\"238\" height=\"300\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_libs-238x300.png 238w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_libs.png 359w\" sizes=\"(max-width: 238px) 100vw, 238px\" \/><\/a><figcaption id=\"caption-attachment-87\" class=\"wp-caption-text\">gdx-freetype libs<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<h3 style=\"text-align: justify;\">Selecting fonts<\/h3>\n<p style=\"text-align: justify;\">I have said that we will work with Spanish and Russian languages. In this example, we simply are going to draw a welcome message on screen:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><strong>Spanish:<\/strong> \u00a1Hola Mundo!<\/li>\n<li style=\"text-align: justify;\"><strong>Russian:<\/strong>\u00a0\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440!<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">If we see the message translated to russian, it can be a little bit strange for us. This is because, while Spanish uses the <a title=\"Latin Alphabet\" href=\"http:\/\/en.wikipedia.org\/wiki\/Latin_alphabet\" target=\"_blank\">latin alphabet<\/a>, Russian language uses a variant of <a title=\"Russian Alphabet\" href=\"http:\/\/en.wikipedia.org\/wiki\/Russian_alphabet\" target=\"_blank\">cyrillic alphabet<\/a>.<\/p>\n<p style=\"text-align: justify;\">Normally, a TTF font supports only a set of all existing alphabets, so we have to select several fonts depending of the language we have to represent. In this case, we will use this fonts:<\/p>\n<ul>\n<li><strong>Spanish:<\/strong> <a title=\"Goodfish Font Family\" href=\"http:\/\/www.1001fonts.com\/goodfish-font.html\" target=\"_blank\">Goodfish Font Family<\/a><\/li>\n<li><strong>Russian:<\/strong>\u00a0<a title=\"Imperial One\" href=\"http:\/\/www.dafont.com\/imperial-one.font\" target=\"_blank\">Imperial One<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3>Add fonts to our LibGDX project<\/h3>\n<p style=\"text-align: justify;\">When we download these fonts, we can have more than one TTF file. Each of these TTF file is for a font style (bold, italic, &#8230;) For this example, we only use a file from each font (\u00ab<em>goodfish rg.ttf<\/em>\u00bb from <em>Goodish<\/em> y \u00ab<em>Imperial Web.ttf<\/em>\u00bb from <em>Imperial One<\/em>).<\/p>\n<p style=\"text-align: justify;\">These TTF files are another resource of our project, so we add them to directory \u00ab<em>assets\/<\/em>\u00bb on the android project. To keep a good organization for our resources, we can create a specific folder, for example called \u00ab<em>fonts\/<\/em>\u00ab, inside directory \u00ab<em>assets\/<\/em>\u00bb and add here our fonts:<\/p>\n<figure id=\"attachment_90\" aria-describedby=\"caption-attachment-90\" style=\"width: 220px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_assets_fonts.png\"><img decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-90\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_assets_fonts.png\" alt=\"android\/assets\/font\" width=\"220\" height=\"206\" \/><\/a><figcaption id=\"caption-attachment-90\" class=\"wp-caption-text\">android\/assets\/font<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<h3>Generate TTF font for LibGDX<\/h3>\n<p style=\"text-align: justify;\">Before render text with our\u00a0TTF fonts, we need to generate <a href=\"https:\/\/github.com\/libgdx\/libgdx\/wiki\/Bitmap-fonts\" target=\"_blank\">Bitmap<\/a>\u00a0fonts. We create the class <code>FontFactory<\/code> for centralization of font generation. The source code of this class is so long to paste it here, so we will see it by parts.<\/p>\n<p style=\"text-align: justify;\">At first place, we have two static variables of type <code>String<\/code> with the name of TTF files:<\/p>\n<pre lang=\"Java\" line=\"13\">public static final String SPANISH_FONT_NAME = \"fonts\/goodfish rg.ttf\";\r\npublic static final String RUSSIAN_FONT_NAME = \"fonts\/Imperial Web.ttf\";\r\n<\/pre>\n<p style=\"text-align: justify;\">Next, we will have a static variable to contain russian characters. Why is this? By default, LibGDX will generate a font with characters contained in the string <code>FreeTypeFontGenerator.DEFAULT_CHARS<\/code>. This <code>String<\/code> contains only the latin characters, so if we want to generate other kind of chars we have to say to LibGDX which chars are these. In this example, we will use the below <code>String<\/code> that contains the russian alphabet:<\/p>\n<pre lang=\"Java\" line=\"17\">public static final String RUSSIAN_CHARACTERS = \"\u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\"\r\n                                              + \"\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\"\r\n                                              + \"1234567890.,:;_\u00a1!\u00bf?\\\"'+-*\/()[]={}\";\r\n<\/pre>\n<p>Generated fonts are stored at two local variables:<\/p>\n<pre lang=\"Java\" line=\"24\">private BitmapFont esFont;\r\nprivate BitmapFont ruFont;\r\n<\/pre>\n<p>The next method is responsible of generating of <code>Bitmap<\/code> font:<\/p>\n<pre lang=\"Java\" line=\"54\">private BitmapFont generateFont(String fontName, String characters) {\r\n\t\r\n    \/\/ Configure font parameters\r\n    FreeTypeFontParameter parameter = new FreeTypeFontParameter();\r\n    parameter.characters = characters;\r\n    parameter.size = 24;\r\n\r\n    \/\/ Generate font\r\n    FreeTypeFontGenerator generator = new FreeTypeFontGenerator( Gdx.files.internal(fontName) );\r\n    BitmapFont font = generator.generateFont(parameter);\r\n\r\n    \/\/ Dispose resources\r\n    generator.dispose();\r\n\r\n    return font;\r\n}\r\n<\/pre>\n<p>and it will be called from <code>initialize()<\/code>:<\/p>\n<pre lang=\"Java\" line=\"37\">public void initialize() {\r\n    \/\/ If fonts are already generated, dispose it!\r\n    if (esFont != null) esFont.dispose();\r\n    if (ruFont != null) ruFont.dispose();\r\n    \r\n    esFont = generateFont(SPANISH_FONT_NAME, FreeTypeFontGenerator.DEFAULT_CHARS);\r\n    ruFont = generateFont(RUSSIAN_FONT_NAME, RUSSIAN_CHARACTERS);\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">At last, we use the method <code>getFont()<\/code> to get the font setted for the language which we receive by param:<\/p>\n<pre lang=\"Java\" line=\"77\">public BitmapFont getFont(Locale locale) {\r\n    if      (\"es\".equals(locale.getLanguage())) return esFont;\r\n    else if (\"ru\".equals(locale.getLanguage())) return ruFont;\r\n    else throw new IllegalArgumentException(\"Not supported language\");\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Drawing text on screen<\/h3>\n<p style=\"text-align: justify;\">in the main class,\u00a0<code>GdxGameFreetypeExampleGame<\/code>, we&#8217;ll draw the message \u00abHello World!\u00bb translated in both Spanish and Russian. The messages are stored in two static variables:<\/p>\n<pre lang=\"Java\" line=\"14\">public static final String SPANISH_MESSAGE = \"\u00a1Hola Mundo!\";\r\npublic static final String RUSSIAN_MESSAGE = \"\u041f\u0440\u0438\u0432\u0435\u0442 \u043c\u0438\u0440!\";\r\n<\/pre>\n<p style=\"text-align: justify;\">Also we have two <code>Locale <\/code>objects to store localization fon Spain and Russian:<\/p>\n<pre lang=\"Java\" line=\"21\">private Locale esLocale;\r\nprivate Locale ruLocale;\r\n<\/pre>\n<p style=\"text-align: justify;\">In method\u00a0<code>create()<\/code>, we initialize our font factory and <code>Locale<\/code> objects for Spain and Russia:<\/p>\n<pre lang=\"Java\" line=\"25\">public void create () {\r\n    batch = new SpriteBatch();\r\n    \r\n    \/\/ Initialize FontFactory\r\n    FontFactory.getInstance().initialize();\r\n    \r\n    \/\/ Initialize locales\r\n    esLocale = new Locale(\"es\", \"ES\");\r\n    ruLocale = new Locale(\"ru\", \"RU\");\r\n}\r\n<\/pre>\n<p style=\"text-align: justify;\">At last, we draw in the method <code>render()<\/code> using our <code>BitmapFont<\/code> from <code>FontFactory<\/code>:<\/p>\n<pre lang=\"Java\" line=\"37\">public void render () {\r\n    \/\/ Clear screen\r\n    Gdx.gl.glClearColor(0, 0, 1, 1);\r\n    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);\r\n    \r\n    \/\/ Draw with fonts\r\n    batch.begin();\r\n    FontFactory.getInstance().getFont(esLocale).draw(batch, SPANISH_MESSAGE, 110.f, 150.f);\r\n    FontFactory.getInstance().getFont(ruLocale).draw(batch, RUSSIAN_MESSAGE, 70.f, 100.f);\r\n    batch.end();\r\n}\r\n<\/pre>\n<h3 style=\"text-align: justify;\">Result<\/h3>\n<p style=\"text-align: justify;\">The result of executing our code is similar to this:<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_example.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-129\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_example-300x253.png\" alt=\"freetype_example\" width=\"300\" height=\"253\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_example-300x253.png 300w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2014\/10\/freetype_example.png 358w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">As you can see, the message is correctly show in both languages; each of them with the font we have set for it.<\/p>\n<h2 style=\"text-align: justify;\">Improvements:<\/h2>\n<p style=\"text-align: justify;\">Below there are some improvements which I have not handled in order to don&#8217;t do this tutorial too long \ud83d\ude42<\/p>\n<ul>\n<li style=\"text-align: justify;\">Although in this example we show a string in two languages, normally when we have a localized application we only load one of the possible languages, so would only be necessary to generate a font ever.<\/li>\n<li style=\"text-align: justify;\">There are fonts which support several languages. Using any of these fonts, we can use same font for different languages. By this we can save disk space, something very appreciated in mobile devices.<\/li>\n<\/ul>\n<h2 style=\"text-align: justify;\">Source code<\/h2>\n<p style=\"text-align: justify;\">You can get the source code at <a title=\"Give me source code\" href=\"https:\/\/github.com\/angelnavarro\/Gdx-Freetype-Example\" target=\"_blank\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When we develop for mobile devices, we have to keep in mind that propably our program will be used in several countries for users of diferent languages. A tool to facilitate the use of our software for these users is <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/how-to-draw-russian-cyrillic-characters-in-libgdx\/\">Seguir leyendo <span class=\"screen-reader-text\">  How to draw russian (cyrillic) characters in LibGDX<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":129,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[16,17,15],"language":[4],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/137"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=137"}],"version-history":[{"count":20,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/137\/revisions"}],"predecessor-version":[{"id":157,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/137\/revisions\/157"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media\/129"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=137"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}