microvg  2.1.0
microvg
freetype_bitmap_helper.c
Go to the documentation of this file.
1 /*
2  * C
3  *
4  * Copyright 2021-2022 MicroEJ Corp. All rights reserved.
5  * Use of this source code is governed by a BSD-style license that can be found with this software.
6  */
7 
15 #include "microvg_configuration.h"
16 
17 #if defined VG_FEATURE_FONT && defined VG_FEATURE_FONT_FREETYPE_BITMAP && (VG_FEATURE_FONT == VG_FEATURE_FONT_FREETYPE_BITMAP)
18 
19 
20 // -----------------------------------------------------------------------------
21 // Includes
22 // -----------------------------------------------------------------------------
23 
24 #include <LLUI_DISPLAY_impl.h>
25 #include <LLVG_FONT_impl.h>
26 
27 #include "microvg_helper.h"
28 #include "freetype_bitmap_helper.h"
29 
30 // -----------------------------------------------------------------------------
31 // Macros
32 // -----------------------------------------------------------------------------
33 
34 // -----------------------------------------------------------------------------
35 // Global Variables
36 // -----------------------------------------------------------------------------
37 
41 static uint32_t image_width;
42 
46 static uint32_t image_height;
47 
48 // -----------------------------------------------------------------------------
49 // Public functions
50 // -----------------------------------------------------------------------------
51 
52 
53 int ft_helper_print_jstring_clipped(MICROUI_GraphicsContext* gc, Freetype_context_type *freetype_context, jchar* string, jint s_size, jint x, jint y, jint color, jint alpha, jfloat size, jint blend, jfloat letterSpacing){
54  FT_UInt previous = 0; // previous glyph index for kerning
55  FT_Bool use_kerning;
56  int res = FREETYPE_OK;
57 
58  // Misra unused variable, to be checked
59  (void)size;
60  (void)blend;
61 
62  image_width = LLUI_DISPLAY_getStrideInPixels(&gc->image);
63  image_height = gc->image.height;
64  use_kerning = FT_HAS_KERNING(freetype_context->face);
65  freetype_context->slot = freetype_context->face->glyph;
66 
67  uint32_t local_x = x;
68  int c=0;
69  for(c=0;c<s_size;c++){
70  freetype_context->glyph_index = FT_Get_Char_Index( freetype_context->face, string[c] );
71  if (!freetype_context->glyph_index){
72  MEJ_LOG_INFO_MICROVG("Warning bad glyph_index = %d \n",freetype_context->glyph_index);
73  }
74 
75  freetype_context->error = FT_Load_Glyph (freetype_context->face, freetype_context->glyph_index, FT_LOAD_RENDER);
76  if(FT_ERR(Ok) != freetype_context->error){
77  MEJ_LOG_INFO_MICROVG("error while loading glyph, errno=%d \n",freetype_context->error);
79  break;
80  }
81 
82  // metrics structure retrieved in 64th pixel unit
83  uint32_t bearing_x = freetype_context->face->glyph->metrics.horiBearingX >> METRICS_DIVISOR;
84  uint32_t bearing_y = freetype_context->face->glyph->metrics.horiBearingY >> METRICS_DIVISOR;
85  uint32_t advance_aux = freetype_context->face->glyph->advance.x >> METRICS_DIVISOR;
86 
87  if (use_kerning && previous && freetype_context->glyph_index){
88  FT_Vector delta;
89  FT_Get_Kerning(freetype_context->face, previous, freetype_context->glyph_index, FT_KERNING_DEFAULT, &delta);
90  local_x += (delta.x >> METRICS_DIVISOR);
91  }
92 
93  ft_helper_write_to_framebuffer_clipped(gc, freetype_context, (local_x + bearing_x), (y - bearing_y), color, alpha);
94 
95  local_x += advance_aux + (uint32_t) letterSpacing;
96 
97  if (local_x > (image_width - (uint32_t) FT_HELPER_X_MIN - (uint32_t) freetype_context->slot->bitmap.width)){
98  MEJ_LOG_INFO_MICROVG("\n FT_HELPER_OUT_RIGHT_SCREEN_LIMIT\n");
99  }
100  previous = freetype_context->glyph_index;
101  }
102  return res;
103 }
104 
105 static void ft_helper_write_to_framebuffer_clipped(MICROUI_GraphicsContext* gc, Freetype_context_type *freetype_context, jint x, jint y, jint color, jint alpha){
106  jint n_rows = freetype_context->slot->bitmap.rows;
107  jint n_cols = freetype_context->slot->bitmap.width;
108  jint original_foreground_color = gc->foreground_color;
109 
110  // Misra unused variable, to be checked
111  (void)alpha;
112 
113  if( (0 > gc->clip_x1) || (image_width < gc->clip_x1) || (0 > gc->clip_x2) || (image_width < gc->clip_x2) ||
114  (0 > gc->clip_y1) || (image_height < gc->clip_y1) || (0 > gc->clip_y2) || (image_height < gc->clip_y2)){
115  MEJ_LOG_INFO_MICROVG("The graphics context clip is out of the screen! \n");
116  MEJ_LOG_INFO_MICROVG("clip_x1 = %d ; clip_x2 = %d ; clip_y1 = %d ; clip_y2 = %d ; \n",gc->clip_x1, gc->clip_x2,gc->clip_y1, gc->clip_y2);
117  } else {
118 
119  // Check if we have an intersection between the glyph area and the Graphics Context's area
120  jint intersec_xmin = max(gc->clip_x1, x);
121  jint intersec_ymin = max(gc->clip_y1, y);
122  jint intersec_xmax = min(gc->clip_x2, x+n_cols-1);
123  jint intersec_ymax = min(gc->clip_y2, y+n_rows-1);
124  jint intersec_width = intersec_xmax - intersec_xmin +1;
125  jint intersec_height = intersec_ymax - intersec_ymin +1;
126 
127  if((0 >= intersec_width) || (0 >= intersec_height)){ //No intersection we leave the function
128  MEJ_LOG_INFO_MICROVG("\n Glyph out of the Graphics Context's area!");
129  } else {
130  jint y_start_bitmap = intersec_ymin-y;
131  jint x_start_bitmap = intersec_xmin-x;
132  for (jint y_bitmap = y_start_bitmap; y_bitmap < (y_start_bitmap + intersec_height); ++y_bitmap) {
133  for (jint x_bitmap = x_start_bitmap; x_bitmap < (x_start_bitmap + intersec_width); ++x_bitmap) {
134  if(0x00 != freetype_context->slot->bitmap.buffer[(y_bitmap * n_cols) + x_bitmap]){
135  FT_Bitmap *bitmap = &freetype_context->slot->bitmap;
136  uint32_t pix_gray_color = bitmap->buffer[(y_bitmap * bitmap->width) + x_bitmap];
137  uint32_t background_argb = LLUI_DISPLAY_readPixel(&gc->image, intersec_xmin + x_bitmap, intersec_ymin + y_bitmap);
138  uint32_t blended_color = LLUI_DISPLAY_blend(color, background_argb, pix_gray_color);
139  gc->foreground_color = blended_color;
140  UI_DRAWING_writePixel(gc, intersec_xmin + x_bitmap, intersec_ymin + y_bitmap);
141  }else{
142  // Black pixel is for background, we let the pixel buffer as it is.
143  }
144  }
145  }
146  // Set back configured color
147  gc->foreground_color = original_foreground_color;
148  }
149  }
150 }
151 
152 void ft_helper_free(Freetype_context_type *freetype_context){
153  FT_Done_Face ( freetype_context->face );
154  FT_Done_FreeType( freetype_context->library );
155 }
156 
157 // -----------------------------------------------------------------------------
158 // EOF
159 // -----------------------------------------------------------------------------
160 
161 #endif // #if (VG_FEATURE_FONT == VG_FEATURE_FONT_FREETYPE_BITMAP)
void ft_helper_free(Freetype_context_type *freetype_context)
Frees all Freetype data context.
MicroEJ MicroVG library low level API: helper to implement library natives methods.
#define FREETYPE_INTERNAL_ERROR
#define METRICS_DIVISOR
#define FREETYPE_OK
Data structure for pack all the variables required by freetype handler.
int ft_helper_print_jstring_clipped(MICROUI_GraphicsContext *gc, Freetype_context_type *freetype_context, jchar *string, jint s_size, jint x, jint y, jint color, jint alpha, jfloat size, jint blend, jfloat letterSpacing)
Prints a string in a buffer respecting the clipping area of the MicroUI Graphics Context.
#define FT_HELPER_X_MIN
Freetype bitmap helper implementation header for VectorGraphics Low Level API.
MicroEJ MicroVG library low level API: enable some features according to the hardware capacities...