21 #if defined VG_FEATURE_FONT && (VG_FEATURE_FONT == VG_FEATURE_FONT_FREETYPE_VECTOR)
25 #include <freetype/internal/ftobjs.h>
26 #include <freetype/ftcolor.h>
27 #include "ftvector/ftvector.h"
29 #include <LLVG_FONT_impl.h>
30 #include <LLVG_PATH_impl.h>
31 #include <LLVG_GRADIENT_impl.h>
32 #include <LLVG_MATRIX_impl.h>
42 #define FT_COLOR_TO_INT(x) (*((int *)&(x)))
44 #define DIRECTION_CLOCK_WISE 0
50 extern FT_Library library;
51 extern FT_Renderer renderer;
63 static inline float __get_scale(jfloat size, FT_Face face) {
64 return size / face->units_per_EM;
70 static void __set_renderer(FTVECTOR_draw_glyph_data_t *data) {
71 FT_Parameter params[1];
73 params[0].tag = FT_PARAM_TAG_DRAWER;
75 params[0].data = (
void *)data;
77 FT_Set_Renderer(library, renderer, 1, ¶ms[0]);
85 static float __get_angle(
float advance,
float radius) {
86 float angle = advance / radius;
102 static FT_Error __render_glyph(FT_Face face, FT_UInt glyph_index, FT_Color *palette,
103 FTVECTOR_draw_glyph_data_t *drawer_data) {
104 FT_Error error = FT_ERR(Ok);
106 uint32_t default_color = drawer_data->color;
107 FT_UInt layer_glyph_index;
108 FT_UInt layer_color_index;
109 FT_LayerIterator iterator;
112 FT_Bool have_layers = palette && FT_Get_Color_Glyph_Layer(face, glyph_index, &layer_glyph_index, &layer_color_index,
118 if (layer_color_index != 0xFFFF) {
119 drawer_data->color = VG_FREETYPE_IMPL_convert_color(FT_COLOR_TO_INT(palette[layer_color_index]));
123 layer_glyph_index = glyph_index;
126 if (layer_glyph_index != glyph_index) {
127 error = FT_Load_Glyph(face, layer_glyph_index, FT_LOAD_NO_SCALE);
130 if (FT_ERR(Ok) == error) {
132 error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
134 MEJ_LOG_ERROR_MICROVG(
"Error while loading glyphid %d: 0x%x, refer to fterrdef.h\n", layer_glyph_index,
137 }
while ((layer_glyph_index != glyph_index) && (FT_ERR(Ok) == error) && (FT_ERR(Ok) != FT_Get_Color_Glyph_Layer(face,
147 drawer_data->color = default_color;
157 jint VG_FREETYPE_draw_string(VG_FREETYPE_draw_glyph_t drawer,
const jchar *text, jint faceHandle, jfloat size,
158 const jfloat *matrix, uint32_t color, jfloat letterSpacing, jfloat radius, jint direction,
160 jint result = LLVG_SUCCESS;
161 int length = (int)SNI_getArrayLength(text);
164 FT_Face face = (FT_Face)faceHandle;
168 if (0 != FT_Palette_Select(face, 0, &palette)) {
172 float scale = __get_scale(size, face);
173 float letterSpacingScaled = letterSpacing / scale;
174 float radiusScaled = radius / scale;
175 short baselineposition = face->ascender;
178 float scaled_matrix[LLVG_MATRIX_SIZE];
179 LLVG_MATRIX_IMPL_copy(scaled_matrix, matrix);
180 LLVG_MATRIX_IMPL_scale(scaled_matrix, scale, scale);
182 float working_matrix[LLVG_MATRIX_SIZE];
183 LLVG_MATRIX_IMPL_copy(working_matrix, scaled_matrix);
185 FTVECTOR_draw_glyph_data_t drawer_data;
186 drawer_data.drawer = drawer;
187 drawer_data.matrix = working_matrix;
188 drawer_data.color = color;
189 drawer_data.user_data = user_data;
192 __set_renderer(&drawer_data);
201 int previous_glyph_index = 0;
203 VG_HELPER_layout_configure(faceHandle, text, length);
205 while ((LLVG_SUCCESS == result) && (VG_HELPER_layout_load_glyph(&glyph_index, &glyph_advance_x,
206 &glyph_advance_y, &glyph_offset_x,
210 int charWidth = glyph_advance_x;
212 if (0 == previous_glyph_index) {
214 if (0 == face->glyph->metrics.width) {
215 advance_x -= charWidth;
217 advance_x -= face->glyph->metrics.horiBearingX;
222 LLVG_MATRIX_IMPL_copy(working_matrix, scaled_matrix);
225 LLVG_MATRIX_IMPL_translate(working_matrix, advance_x + glyph_offset_x,
226 baselineposition + advance_y + glyph_offset_y);
228 float sign = (DIRECTION_CLOCK_WISE != direction) ? -1.f : 1.f;
231 float angleDegrees = 90 + __get_angle(advance_x + glyph_offset_x,
232 radiusScaled) + __get_angle(charWidth / 2, radiusScaled);
235 LLVG_MATRIX_IMPL_rotate(working_matrix, sign * angleDegrees);
239 LLVG_MATRIX_IMPL_translate(working_matrix, -charWidth / 2, -sign * radiusScaled);
243 FT_Error error = __render_glyph(face, glyph_index, palette, &drawer_data);
244 if (FT_ERR(Ok) != error) {
245 MEJ_LOG_ERROR_MICROVG(
"Error while rendering glyphid %d: 0x%x, refer to fterrdef.h\n", glyph_index,
247 result = (FT_ERR(Out_Of_Memory) == error) ? LLVG_OUT_OF_MEMORY : LLVG_DATA_INVALID;
252 advance_x += charWidth;
253 advance_x += (int)letterSpacingScaled;
254 advance_y += glyph_advance_y;
256 previous_glyph_index = glyph_index;
264 BSP_DECLARE_WEAK_FCNT jint VG_FREETYPE_IMPL_convert_color(jint color) {
MicroEJ MicroVG library low level API: enable some features according to the hardware capacities.
MicroEJ MicroVG library low level API: helper to implement library natives methods.