Note: The tutorial, the discussed features and methods are referring to the latest MT4j version from the Google Code SVN respository and may not be available/supported in the stable release package from the download area.
IntroductionThis article discusses the font system and text rendering possibilities in MT4j and how to use them. Goals
FontsLoading and rendering fonts and text in a 3D environment (as in MT4j) is fundamentally different from a 2D environment. In a 2D environment, the font characters' pixels can be directly rendered onto the screen while when using a 3D graphics pipeline, other strategies have to be applied. There are basically two different approaches, each having different pros and cons: Vector Fonts and Bitmap Fonts. Vector / Geometric FontsVector font characters are rendered using many small geometric primitives like triangles and lines.
Bitmap / Texture FontsAn image of each font character is created and mapped onto a rectangle as a texture.
SummaryIf we want to render a component containing text, we should first think about how the text will be used to decide whether we want to go with a vector or a bitmap font.
If in doubt just switch between vector and bitmap fonts and check which one performs better. Loading FontsFonts in MT4j can be loaded using the FontManager singleton class and its createFont(..) method. The FontManager contains different font factory classes which are responsible for loading the desired fonts. Which font factory is used to load the font depends on the font's file suffix. The FontManager also contains an internal cache that caches fonts with the same name, color, size and anti-aliasing setting so that calling FontManger.getInstance().createFont(pa, "arial.ttf", 24); two times in our code will return the already cached font the second time. This will reduce the loading time significantly. So for speed and memory reasons it is advisable to re-use the same fonts where possible. It might also be advisable to load the fonts at the start of the application rather than at runtime to avoid delays.
When loading a font, we can specify the font, font size, color and anti-aliasing. (anti-aliasing setting is only available in a version greater than 0.9) Loading Vector fontsA Vector font will be created if a font is loaded from a TTF font file with the suffix ".ttf. Also, SVG (Scalable Vector Graphics) font files with the suffix ".svg" can be loaded as vector fonts. Example: FontManager.getInstance().createFont(mtApplication, "arial.ttf", 24); This will try to load the "arial.ttf" font contained in the "./data" or "./src/data" directory as a vector font. The font size will be 24, the color will be black and anti-aliasing enabled by default. You can also specify a different color: IFont font = FontManager.getInstance().createFont(mtApplication, "somefont.svg", 50, //Font size new MTColor(255,255,255), //Font fill color new MTColor(255,255,255)); //Font outline color This will create a white vector font from an svg font file. Loading Bitmap FontsBitmap fonts can be created by using the installed system fonts which doesent require us to provide an extra font file to load from. Thus, to load a bitmap font, we just specify the font name without a file suffix. A list of available system fonts can be accessed by the method PFont.list(). For the MT4j application to be portable and runnable across different platforms and operating systems we need to make sure that the desired font is supported on all these systems! This example code prints out all available system fonts: for (String fontName : PFont.list()) { System.out.println(fontName); }
IFont font = FontManager.getInstance().createFont(mtApplication, "SansSerif", 12, false); TIP: We can force the use of a bitmap font factory instead of the default vector font factory for font creation from a .ttf True Type Font file. This allows to load bitmap fonts from a .ttf file packaged alongside the application, independent of the fonts installed on the target system. To accomplish this we just register a bitmap font factory for the suffix ".ttf": FontManager.getInstance().registerFontFactory(".ttf", new BitmapFontFactory()); Anti-AliasingPer default, vector and bitmap fonts will be drawn anti-aliased to look smoother. The anti-aliasing for bitmap fonts is done by java internally and then rendered into an image. As vector fonts, anti-aliased bitmap fonts look nice at medium or larger font sizes. At small font sizes the anti-aliasing may make the font look too soft or blurry. Here it makes sense to switch off anti-aliasing for a crisper look. Again, some experimentation what setting looks best is in order. Text componentsNow that we know how to load a font we want to use them to render texts or labels. At the moment, MT4j provides two components capable of rendering text. Text AreaThe most used text component is probably the MTTextArea class. It allows to render multiple lines of text using different wrapping modes. The text area's constructor takes a loaded font as an argument.
=> A line break will be added if the width of a text line exceeds the width of the text area. The text is also clipped to the dimensions of the text area if the text exceeds the height of the text area.
=> The text area's size is fitted to the text of the text area. The dimensions will shrink or expand dynamically when characters are added or removed. Which mode will be used depends on which constructor is used to instantiate the MTTextArea. If we use a constructor which specifies a fixed width and height of the textarea the clipping and word wrapping will be enabled automatically. If no dimensions are specified, the expand mode is used. MTTextArea texta = new MTTextArea(0,0, 200,600, font , mtApplication); This will create a text area with 200 units width and 600 units height. Word wrapping and clipping will be enabled. Relevant methods:
MTTextArea text = new MTTextArea(mtApplication, FontManager.getInstance().createFont(mtApplication, "SansSerif", 18)); This creates a text area at the origin, with a minimum size that will expand if font characters are added. Text FieldThe MTTextField class allows to display a single line of text. It is useful for labels or user input text fields. Line breaks are irgnored and the text is clipped to the dimensions of the text field. If the text exceeds the width of the field, the text is scrolled to the left. MTTextField field = new MTTextField(50, 50, 150, 30, FontManager.getInstance().createFont(mtApplication, "SansSerif", 18), mtApplication); field.setText("ABCDEFGHIJKLMNOPQRSTUV\nWXYZ"); getCanvas().addChild(field); |