3.4. VectorFont Library
3.4.1. Vector Fonts Description
Vector fonts, also known as outline fonts, define glyphs with vector images instead of bitmaps. The main advantage of vector fonts is that they can be scaled to any size with the same quality (no pixelation).
3.4.2. Aim of the Library
The VectorFont Foundation Library has been designed as an extension of the MicroUI library to handle vector fonts. It provides methods to draw strings with TrueType fonts and apply different sizes, colors, opacity levels, and gradients at runtime.
The main advantages of using TrueType fonts over MicroUI fonts:
- no need to embed a font for each size; the font height can be changed at runtime without loss of quality;
- rendered by GPU.
Note
This library does not depend on the VGLite library; however, a part of its implementation (C code) depends on the vg_lite
library.
3.4.3. Importing the Library
The library can be retrieved by adding the following dependency to your module.ivy
:
<dependency org="ej.api" name="vector-font" rev="0.2.0"/>
3.4.4. The Java API
3.4.4.1. Font Loading
A TrueType font are loaded by the static method TrueTypeFont.getTrueTypeFont(string fontPath)
.
For instance, to load LiberationSans_Bold.tff
from src/resources/ttf/ directory:
VectorFont font = VectorFont.getTrueTypeFont("/ttf/LiberationSans_Bold.ttf");
As for all resources, the fonts need to be referenced in a .resources.list
file to be embedded in the application.
For instance, here is the content of src/resources/ttf/fonts.resources.list
:
# Resources list
/ttf/LiberationSans_Bold.ttf
Note
A loaded font is cached, so getting the same font several times does not increase memory usage.
3.4.4.2. Text Drawing
All the drawing methods are static methods of VectorFontPainter
. This class is the equivalent of Painter
in
MicroUI.
Strings can be drawn on a straight baseline with drawString
methods or on a curved baseline (a circle arc) with
drawStringArc
. As in MicroUI drawing methods, x
and y
coordinates refer to the top-left corner of the string
bounding box. The height of the font can be set with the size
argument. It is the height of the glyph in pixels, including spacing.
drawString(GraphicsContext gc, VectorFont font, float size, String string, int x, int y);
The string width can be obtained by calling stringWidth
on the font:
font.stringWidth(float size, String string);
When drawing string on an arc, x
and y
coordinates refer to the top-left corner of the circle, and diameter
is the diameter of this circle in pixels. angle
is the angle in degrees of the first character of the string in
the counterclockwise direction.
drawStringArc(GraphicsContext gc, VectorFont font, int size, String string, int x, int y, int diameter, float angle);
The orientation of the string can be changed with the out
parameter.
drawStringArc(GraphicsContext gc, VectorFont font, float size, String string, int x, int y, int diameter, float angle, boolean out);
There are several variations for each of these methods to change opacity or use gradient colors.
Note
You can implement your transformation algorithm for a custom string, drawing the string character by character with Single Character Drawing.
3.4.4.3. Changing Color, Opacity and Using Gradients
The color used to draw a string is the color set to the GraphicContext
. Opacity can be changed by passing an alpha
value as the argument. This value is an integer from 0
(fully transparent) to 255
(fully opaque). When not set, the
color is considered opaque.
drawString(GraphicsContext gc, VectorFont font, String string, int size, int x, int y, int opacity);
drawStringArc(GraphicsContext gc, VectorFont font, String string, int size, int x, int y, int diameter, float angle, int opacity);
A multiple linear gradient can be applied to the text using the LinearGradient
class. The gradient is defined between two points
(startX, startY)
and (endX, endY)
.
LinearGradient gradient = new LinearGradient(int startX, int startY, int endX, int endY, int[] fractions, int[] colors);
The colors
array contains the colors in ARGB format to apply from start to end, and the fractions
array defines the
positions of the colors to apply along the gradient line 0
meaning the start and 255
the end. The length of fractions
is the same as colors
and it contains integers in ascending order from 0
to 255
.
The gradient can then be applied to the text, passing it as the argument:
drawStringArc(GraphicsContext gc, VectorFont font, float size, String string, int x, int y, int diameter, float angle, LinearGradient gradient);
drawStringArc(GraphicsContext gc, VectorFont font, float size, String string, int x, int y, int diameter, float angle, LinearGradient gradient, boolean out);
LinearGradient
should be closed when not used anymore to free memory using its close()
method.
Warning
The same instance of LinearGradient
must not be used in several threads at the same time. This class is not thread-safe to avoid synchronization overhead.
3.4.4.4. Using char[]
Instead of String
Each of these methods also exists, taking a character array as the argument instead of a string. These methods avoid a copy
of the internal char[]
of String
and can pass a subarray using offset
and length
arguments.
// drawString equivalents
drawChars(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y);
drawChars(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int opacity);
drawChars(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, LinearGradient gradient);
// drawStringArc equivalents
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle);
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle, boolean out);
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle, int opacity);
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle, int opacity, boolean out);
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle, LinearGradient gradient);
drawCharsArc(GraphicsContext gc, VectorFont font, float size, char[] chars, int offset, int length, int x, int y, int diameter, float angle, LinearGradient gradient, boolean out);
3.4.4.5. Single Character Drawing
It is also possible to draw a single character using the drawChar
method. As for drawString
, you can define the opacity or the gradient to apply.
drawChar(GraphicsContext gc, VectorFont font, float size, char character, Matrix matrix, int opacity);
drawChar(GraphicsContext gc, VectorFont font, float size, char character, Matrix matrix, LinearGradient gradient);
Matrix
is a 2D transformation matrix, just like vg_lite_matrix
from VG Lite Library. It is used to set the position, orientation, and scale of the character in
the graphic context. The following transformations can be applied:
identity
: To set a matrix to identity.translate
: Translates a matrix.init
: A shortcut foridentity
+translate
.scale
: Scales a matrix.
For drawing a string character by character, you may need to know the width of the characters. The character width can be obtained by calling charWidth
on the font:
font.charWidth(float size, char character);
For example, the following code draws the given string at the position (x, y)
:
public void drawCustomString(GraphicsContext gc, VectorFont font, float size, String string, int x, int y) {
final char[] characters = string.toCharArray();
final Matrix matrix = new Matrix();
final int alpha = 255;
matrix.init(x, y);
int advance = 0;
for (char character : characters) {
VectorFontPainter.drawChar(gc, font, size, character, matrix, alpha);
advance += font.charWidth(size, character);
matrix.translate(advance, 0);
}
}