20 #include <LLVG_MATRIX_impl.h>
25 #if defined VG_FEATURE_FONT
26 #include <freetype/internal/ftobjs.h>
41 #if !defined MICROVG_CONFIGURATION_VERSION
42 #error "Undefined MICROVG_CONFIGURATION_VERSION, it must be defined in microvg_configuration.h"
45 #if defined MICROVG_CONFIGURATION_VERSION && MICROVG_CONFIGURATION_VERSION != 2
46 #error "Version of the configuration file microvg_configuration.h is not compatible with this implementation."
49 #if defined VG_FEATURE_FONT_COMPLEX_LAYOUT
58 #define MIN_HIGH_SURROGATE ((unsigned short)0xD800)
59 #define MAX_HIGH_SURROGATE ((unsigned short)0xDBFF)
60 #define MIN_LOW_SURROGATE ((unsigned short)0xDC00)
61 #define MAX_LOW_SURROGATE ((unsigned short)0xDFFF)
62 #define MIN_SUPPLEMENTARY_CODE_POINT 0x010000
64 #define GET_NEXT_CHARACTER(t,l,o) ((o) >= (l) ? (unsigned short)0 : (t)[o])
66 #ifdef VG_FEATURE_FONT_COMPLEX_LAYOUT
67 #define IS_SIMPLE_LAYOUT (!(face->face_flags & FT_FACE_FLAG_COMPLEX_LAYOUT))
69 #define IS_SIMPLE_LAYOUT true
70 #endif // VG_FEATURE_FONT_COMPLEX_LAYOUT
76 static jfloat g_identity_matrix[LLVG_MATRIX_SIZE];
78 #if defined VG_FEATURE_FONT
82 static unsigned short *current_text;
83 static unsigned int current_length;
84 static int current_offset;
85 static FT_UInt previous_glyph_index;
88 #if defined VG_FEATURE_FONT_COMPLEX_LAYOUT
90 static hb_glyph_info_t *glyph_info;
91 static hb_glyph_position_t *glyph_pos;
92 static unsigned int glyph_count;
93 static int current_glyph;
94 static hb_buffer_t *buf;
101 void MICROVG_HELPER_initialize(
void) {
102 LLVG_MATRIX_IMPL_identity(g_identity_matrix);
108 unsigned short highPart = GET_NEXT_CHARACTER(textCharRam, length, *offset);
113 if (*offset < (length - 1)) {
115 unsigned short lowPart = GET_NEXT_CHARACTER(textCharRam, length, *(offset) + 1);
117 if ((lowPart >= MIN_LOW_SURROGATE) && (lowPart <= MAX_LOW_SURROGATE)) {
123 ret += ((int)lowPart - (
int)MIN_LOW_SURROGATE);
124 ret += (int)MIN_SUPPLEMENTARY_CODE_POINT;
134 ret = 0x0000FFFF & (int)highPart;
140 #if defined VG_FEATURE_FONT
142 void MICROVG_HELPER_layout_configure(
int faceHandle,
unsigned short *text,
int length){
143 face = (FT_Face) faceHandle;
148 if(IS_SIMPLE_LAYOUT){
151 current_length = length;
153 previous_glyph_index = 0;
156 #if defined VG_FEATURE_FONT_COMPLEX_LAYOUT
157 static hb_font_t *hb_font;
158 static jint current_faceHandle = 0;
160 if(faceHandle != current_faceHandle){
161 if(0 != current_faceHandle){
162 hb_font_destroy(hb_font);
165 FT_Set_Pixel_Sizes (face, 0, face->units_per_EM);
166 hb_font = hb_ft_font_create(face, NULL);
167 current_faceHandle = faceHandle;
170 buf = hb_buffer_create();
171 hb_buffer_add_utf16(buf, (
const uint16_t *)text, length, 0, -1);
173 hb_buffer_guess_segment_properties(buf);
175 hb_shape(hb_font, buf, NULL, 0);
177 glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count);
178 glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count);
181 #endif // VG_FEATURE_FONT_COMPLEX_LAYOUT
186 #if defined VG_FEATURE_FONT
188 bool MICROVG_HELPER_layout_load_glyph(
int *glyph_idx,
int *x_advance,
int *y_advance,
int *x_offset,
int *y_offset){
199 if(IS_SIMPLE_LAYOUT){
203 FT_UInt glyph_index = FT_Get_Char_Index(face, next_char);
205 int error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE);
206 if(FT_ERR(Ok) != error) {
207 MEJ_LOG_ERROR_MICROVG(
"Error while loading glyphid %d: 0x%x, refer to fterrdef.h\n",glyph_index, error);
210 *x_advance = face->glyph->advance.x;
213 if (FT_HAS_KERNING(face) && previous_glyph_index && glyph_index){
215 FT_Get_Kerning(face, previous_glyph_index, glyph_index, FT_KERNING_UNSCALED, &delta);
218 *x_advance += delta.x;
221 previous_glyph_index = glyph_index;
223 *glyph_idx = glyph_index;
229 #if defined VG_FEATURE_FONT_COMPLEX_LAYOUT
231 if(((
unsigned int) 0) != glyph_count){
233 *glyph_idx = glyph_info[current_glyph].codepoint;
234 *x_advance = glyph_pos[current_glyph].x_advance/64;
235 *y_advance = glyph_pos[current_glyph].y_advance/64;
236 *x_offset = glyph_pos[current_glyph].x_offset/64;
237 *y_offset = glyph_pos[current_glyph].y_offset/64;
243 int error = FT_Load_Glyph(face, *glyph_idx, FT_LOAD_NO_SCALE);
244 if(FT_ERR(Ok) != error) {
245 MEJ_LOG_ERROR_MICROVG(
"Error while loading glyphid %d: 0x%x, refer to fterrdef.h\n", *glyph_idx, error);
250 hb_buffer_destroy(buf);
253 #endif // VG_FEATURE_FONT_COMPLEX_LAYOUT
261 jfloat* MICROVG_HELPER_check_matrix(jfloat* matrix) {
262 return (NULL == matrix) ? g_identity_matrix : matrix;
266 uint32_t MICROVG_HELPER_apply_alpha(uint32_t color, uint32_t alpha) {
267 uint32_t color_alpha = (((color >> 24) & (uint32_t)0xff) * alpha) / (uint32_t)255;
268 return (color & (uint32_t)0xffffff) | (color_alpha << 24);
int MICROVG_HELPER_get_utf(unsigned short *textCharRam, int length, int *offset)
Gets the UTF character from a text buffer at the given offset and updates the offset to point to the ...
MicroEJ MicroVG library low level API: helper to implement library natives methods.
MicroEJ MicroVG library low level API: enable some features according to the hardware capacities...
#define MIN_HIGH_SURROGATE