int LcdFont::getRenderWidth(const char * text, const bool utf8_encoded) { pthread_mutex_lock(&renderer->render_mutex); // fribidi #if defined (ENABLE_FRIBIDI) std::string Text = fribidiShapeChar(text, utf8_encoded); text = Text.c_str(); #endif FT_Error err; #ifdef FT_NEW_CACHE_API FTC_ScalerRec scaler; scaler.face_id = font.face_id; scaler.width = font.width; scaler.height = font.height; scaler.pixel = true; err = FTC_Manager_LookupSize(renderer->cacheManager, &scaler, &size); #else err = FTC_Manager_Lookup_Size(renderer->cacheManager, &font.font, &face, &size); #endif if (err != 0) { dprintf(DEBUG_NORMAL, "LcdFont::getRenderWidth: FTC_Manager_Lookup_Size failed! (0x%x)\n", err); pthread_mutex_unlock(&renderer->render_mutex); return -1; } int x=0; for (; *text; text++) { FTC_SBit glyph; int unicode_value = UTF8ToUnicode(text, utf8_encoded); if (unicode_value == -1) break; #ifdef FT_NEW_CACHE_API int index = FT_Get_Char_Index(size->face, unicode_value); #else int index=FT_Get_Char_Index(face, unicode_value); #endif if (!index) continue; if (getGlyphBitmap(index, &glyph)) { dprintf(DEBUG_NORMAL, "LcdFont::getRenderWidth: failed to get glyph bitmap.\n"); continue; } x+=glyph->xadvance+1; } pthread_mutex_unlock(&renderer->render_mutex); return x; }
void LcdFont::RenderString(int x, int y, const int width, const char * text, const int color, const int selected, const bool utf8_encoded) { int err; pthread_mutex_lock(&renderer->render_mutex); #ifdef FT_NEW_CACHE_API FTC_ScalerRec scaler; scaler.face_id = font.face_id; scaler.width = font.width; scaler.height = font.height; scaler.pixel = true; if ((err = FTC_Manager_LookupSize(renderer->cacheManager, &scaler, &size)) != 0) #else if ((err=FTC_Manager_Lookup_Size(renderer->cacheManager, &font.font, &face, &size))!=0) #endif { printf("FTC_Manager_Lookup_Size failed! (%d)\n",err); pthread_mutex_unlock(&renderer->render_mutex); return; } int left=x, step_y=(size->metrics.height >> 6 )*3/4 + 4; int pos =0; for (; *text; text++) { pos++; FTC_SBit glyph; //if ((x + size->metrics.x_ppem > (left+width)) || (*text=='\n')) if (x + size->metrics.x_ppem > (left+width)) { //width clip break; } if (*text=='\n') { x = left; y += step_y; } int unicode_value = UTF8ToUnicode(text, utf8_encoded); if (unicode_value == -1) break; #ifdef FT_NEW_CACHE_API int index = FT_Get_Char_Index(size->face, unicode_value); #else int index = FT_Get_Char_Index(face, unicode_value); #endif if (!index) continue; if (getGlyphBitmap(index, &glyph)) { printf("failed to get glyph bitmap.\n"); continue; } int rx=x+glyph->left; int ry=y-glyph->top; if(pos==selected) { framebuffer->draw_fill_rect(x-2,y-glyph->height-2, x+glyph->width+2, y+2, CLCDDisplay::PIXEL_INV ); } for (int ay=0; ay<glyph->height; ay++) { int ax=0; int w=glyph->width; int xpos = rx; for (; ax<w; ax++) { unsigned char c = glyph->buffer[ay*abs(glyph->pitch)+(ax>>3)]; if((c>>(7-(ax&7)))&1) framebuffer->draw_point(xpos,ry, color); xpos ++; } ry++; } x+=glyph->xadvance+1; } pthread_mutex_unlock(&renderer->render_mutex); }