void Freetype::drawText(const char *txt, unsigned int x, unsigned int y) { int error; while (*txt) { FT_UInt glyph_index; glyph_index = FT_Get_Char_Index(_face, *txt); if ((error = FT_Load_Glyph(_face, glyph_index, FT_LOAD_DEFAULT))) continue; if ((error = FT_Render_Glyph(_face->glyph, FT_RENDER_MODE_NORMAL))) continue; my_draw_bitmap(&_slot->bitmap, x + _slot->bitmap_left, y - _slot->bitmap_top, _slot, _size); x += _slot->advance.x >> 6; y += _slot->advance.y >> 6; x += _padding; txt++; } }
void FT_RenderText(){ FT_GlyphSlot slot = face->glyph; /* a small shortcut */ int pen_x, pen_y, n; bool error; pen_x = 300; pen_y = 200; char text[] = "Hello World!"; int num_chars = sizeof(text); for ( n = 0; n < num_chars; n++ ){ /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, text[n], FT_LOAD_RENDER ); if ( error ){ continue; /* ignore errors */ printf("Error"); } /* now, draw to our target surface */ my_draw_bitmap( &slot->bitmap, pen_x + slot->bitmap_left, pen_y - slot->bitmap_top ); /* increment pen position */ pen_x += slot->advance.x >> 6; pen_y += slot->advance.y >> 6; /* not useful for now */ } }
int createText(){ //"/usr/share/cups/fonts/FreeMono.ttf"; FT_Error error; FT_Library library; FT_Face face; error = FT_Init_FreeType(&library); if(error) printf("FT_Init_FreeType error= %d\n",error); error = FT_New_Face(library, FontFileName, 0, &face); if(error==FT_Err_Unknown_File_Format){ printf("unknown FT_Err_Unknown_File_Format\n"); }else if(error){ printf("error %d\n",error); } error = FT_Set_Char_Size( face, /* handle to face object */ 0, /* char_width in 1/64th of points */ 16*64, /* char_height in 1/64th of points */ 200, /* horizontal device resolution */ 300 ); /* vertical device resolution */ if(error) printf("FT_Set_Char_Size error= %d\n",error); FT_GlyphSlot slot = face->glyph; /* a small shortcut */ int i,num_chars = strlen(Text); for ( i = 0; i < num_chars; i++ ) { FT_UInt glyph_index; /* retrieve glyph index from character code */ glyph_index = FT_Get_Char_Index(face, Text[i]); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_DEFAULT ); if ( error ) continue; /* ignore errors */ /* convert to an anti-aliased bitmap */ error = FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL ); if ( error ) continue; /* now, draw to our target surface */ my_draw_bitmap( &slot->bitmap, Px + slot->bitmap_left, Py - slot->bitmap_top ); /* increment pen position */ Px += slot->advance.x >> 6; Py += slot->advance.y >> 6; /* not useful for now */ } return 0; }
// lookup glyph and extract all the shapes required to draw the outline long int Ttt::render_char(FT_Face face, wchar_t c, long int offset, int linescale) { int error; int glyph_index; FT_Outline outline; FT_Outline_Funcs func_interface; error = FT_Set_Pixel_Sizes(face, 4096, linescale ? linescale : 64); if(error) handle_ft_error("FT_Set_Pixel_Sizes", error, __LINE__); /* lookup glyph */ glyph_index = FT_Get_Char_Index(face, (FT_ULong)c); if(!glyph_index) handle_ft_error("FT_Get_Char_Index", 0, __LINE__); /* load glyph */ error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); if(error) handle_ft_error("FT_Load_Glyph", error, __LINE__); error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO); if(error) handle_ft_error("FT_Render_Glyph", error, __LINE__); if(linescale > 0) // this is for the "zigzag" fill of letters? my_draw_bitmap(&face->glyph->bitmap, face->glyph->bitmap_left + offset, face->glyph->bitmap_top, linescale); error = FT_Set_Pixel_Sizes(face, 0, 64); if(error) handle_ft_error("FT_Set_Pixel_Sizes", error, __LINE__); error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); if(error) handle_ft_error("FT_Load_Glyph", error, __LINE__); /* shortcut to the outline for our desired character */ outline = face->glyph->outline; /* set up entries in the interface used by FT_Outline_Decompose() */ func_interface.shift = 0; func_interface.delta = 0; func_interface.move_to = move_to_wrapper; func_interface.line_to = line_to_wrapper; func_interface.conic_to = conic_to_wrapper; func_interface.cubic_to = cubic_to_wrapper; /* offset the outline to the correct position in x */ FT_Outline_Translate( &outline, offset, 0L ); /* plot the current character */ error = FT_Outline_Decompose( &outline, &func_interface, NULL); if(error) handle_ft_error("FT_Outline_Decompose", error, __LINE__); /* save advance in a global */ advance.x = face->glyph->advance.x; advance.y = face->glyph->advance.y; /* FT_Bool use_kerning = FT_HAS_KERNING( face ); std::cout << " not using kerning \n"; if ( use_kerning && previous ) { FT_Vector kerning; error = FT_Get_Kerning( face, // handle to face object previous_glyph_index, // left glyph index glyph_index, // right glyph index FT_KERNING_DEFAULT, // kerning mode FT_KERNING_DEFAULT , FT_KERNING_UNFITTED , FT_KERNING_UNSCALED &kerning ); // target vector std::cout << " kerning x-advance: " << kerning.x << "\n"; } */ /* FT_Vector kerning; error = FT_Get_Kerning( face, // handle to face object left, // left glyph index right, // right glyph index kerning_mode, // kerning mode FT_KERNING_DEFAULT , FT_KERNING_UNFITTED , FT_KERNING_UNSCALED &kerning ); // target vector */ // delete glyph with FT_Done_Glyph? previous = true; // we have a prev glyph, for kerning previous_glyph_index = glyph_index; /* offset will get bumped up by the x size of the char just plotted */ return face->glyph->advance.x; }
char generate_glyph(FT_Face* face, int* height, unsigned int unicode) { int idx; int glyph_index = 0; int error; // fprintf(stderr, "uni:%d\n", unicode); do { glyph_index = FT_Get_Char_Index( (*face), unicode); if (glyph_index == 0) face++; } while (*face && glyph_index==0); if (glyph_index == 0) face--; // fprintf(stderr, "glyph:%d\n", glyph_index); if ((unicode != 0) && (glyph_index == 0)) { #ifndef TTF2C printf("Glyph not found (%d)\n", unicode); #endif return 0; } error = FT_Load_Glyph((*face), glyph_index, FT_LOAD_DEFAULT|FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT|FT_LOAD_TARGET_MONO); // If it failed, try to load without the autohinter if (error) error = FT_Load_Glyph((*face), glyph_index, FT_LOAD_DEFAULT|FT_LOAD_RENDER|FT_LOAD_TARGET_MONO); if (error) { fprintf(stderr,"Error loading 0x%04X\n",unicode); exit(0); } error = FT_Render_Glyph( (*face)->glyph, /* glyph slot */ /*render_mode*/FT_RENDER_MODE_MONO ); /* render mode */ if (error) { fprintf(stderr,"Error rendering %d\n", unicode); exit(0); } genglyphs[genfont.numglyphs].i = unicode; genglyphs[genfont.numglyphs].size.width = (*face)->glyph->bitmap.width; genglyphs[genfont.numglyphs].size.height = (*face)->glyph->bitmap.rows; genglyphs[genfont.numglyphs].top = (*face)->glyph->bitmap_top; genglyphs[genfont.numglyphs].left = (*face)->glyph->bitmap_left; genglyphs[genfont.numglyphs].advance.x = (*face)->glyph->advance.x >> 6; genglyphs[genfont.numglyphs].advance.y = (*face)->glyph->advance.y >> 6; genglyphs[genfont.numglyphs].pitch = (*face)->glyph->bitmap.pitch; if (*height < genglyphs[genfont.numglyphs].top) *height = genglyphs[genfont.numglyphs].top; int len = genglyphs[genfont.numglyphs].size.height * genglyphs[genfont.numglyphs].pitch; genglyphs[genfont.numglyphs].data = malloc(len); memcpy((uint8_t*)genglyphs[genfont.numglyphs].data, (*face)->glyph->bitmap.buffer, len); #ifndef TTF2C printf("Symbol #%d\n", genglyphs[genfont.numglyphs].i); #endif optimize_glyph(&genglyphs[genfont.numglyphs], (uint8_t*)genglyphs[genfont.numglyphs].data); #ifndef TTF2C my_draw_bitmap(&genglyphs[genfont.numglyphs]); #endif genfont.numglyphs++; return 1; }
void Console_draw(const console* cons, char* buffer_out,int width,int height) { int buffer_depth; int num_line; int num_car; int real_line; int i,j,c; int cur_posx = cons->attr.posx; int cur_posy = cons->attr.posy; const char* buffer_current = NULL; FT_GlyphSlot slot = cons->ft_face->glyph; switch(cons->attr.mode) { case RGB: buffer_depth = 3; break; case ARGB: buffer_depth = 4; break; default: return; } if(cons->attr.background!=0) { for(i=0; i<cons->attr.height; i++) { for(j=0; j<cons->attr.width; j++) { for(c=0; c<buffer_depth; c++) { buffer_out[ (cur_posx+j)*(buffer_depth) + (cur_posy+i)*(buffer_depth)*width + c] = cons->attr.background_color[c]; } } } } for(num_line = 0 ; num_line < cons->nb_line ; num_line ++) { if(cons->line_top>0) real_line = (num_line + cons->line_top) % (cons->nb_line); else real_line = num_line; for(num_car = 0 ; cons->buffer[real_line][num_car]!=0; num_car++) { if(FT_Load_Char(cons->ft_face,cons->buffer[real_line][num_car], FT_LOAD_RENDER)) continue; my_draw_bitmap( buffer_out, width, height, &slot->bitmap, cur_posx + slot->bitmap_left, cur_posy - slot->bitmap_top + cons->attr.textsize, buffer_depth, cons->attr.color); cur_posx += slot->advance.x >> 6; // cur_posx += cons->ft_face->max_advance_width; } cur_posx = cons->attr.posx; cur_posy += cons->attr.textsize; // cur_posy += cons->ft_face->max_advance_height; } }