static int GetCharacterOffsets(void *_font, const char *text, int *byteOffsets, int *pixelOffsets, int maxOffsets) { TTF_Font *font = (TTF_Font *)_font; int i = 0; int bytes = 0; int pixels = 0; int advance; Uint16 ch; while ( *text && i < maxOffsets ) { byteOffsets[i] = bytes; pixelOffsets[i] = pixels; ++i; ch = UTF8_to_UNICODE(text, &advance); text += advance; bytes += advance; TTF_GlyphMetrics(font, ch, NULL, NULL, NULL, NULL, &advance); pixels += advance; } if ( i < maxOffsets ) { byteOffsets[i] = bytes; pixelOffsets[i] = pixels; } return i; }
IntRect Bitmap::textSize(const char *str) { guardDisposed(); GUARD_MEGA; TTF_Font *font = p->font->getSdlFont(); std::string fixed = fixupString(str); str = fixed.c_str(); int w, h; TTF_SizeUTF8(font, str, &w, &h); /* If str is one character long, *endPtr == 0 */ const char *endPtr; uint16_t ucs2 = utf8_to_ucs2(str, &endPtr); /* For cursive characters, returning the advance * as width yields better results */ if (p->font->getItalic() && *endPtr == '\0') TTF_GlyphMetrics(font, ucs2, 0, 0, 0, 0, &w); return IntRect(0, 0, w, h); }
static mrb_value mrb_sdl2_ttf_font_get_glyph_metric(mrb_state *mrb, mrb_value self) { int minx, maxx, miny, maxy, advance; mrb_value character; Uint16 ch; mrb_value result; mrb_get_args(mrb, "b", &character); if (mrb_obj_is_kind_of(mrb, character, mrb_class_get_under(mrb, mrb->object_class, "String"))) { ch = *RSTRING_PTR(character); } else if (mrb_obj_is_kind_of(mrb, character, mrb_class_get_under(mrb, mrb->object_class, "Integer"))) { ch = (Uint16) character.value.i; } result = mrb_hash_new_capa(mrb, 5); if (TTF_GlyphMetrics(mrb_sdl2_font_get_ptr(mrb, self), ch, &minx, &maxx, &miny, &maxy, &advance) == -1) { mruby_sdl2_raise_error(mrb); return mrb_false_value(); } mrb_hash_set(mrb, result, mrb_str_new_cstr(mrb, "minx"), mrb_fixnum_value(minx)); mrb_hash_set(mrb, result, mrb_str_new_cstr(mrb, "maxx"), mrb_fixnum_value(maxx)); mrb_hash_set(mrb, result, mrb_str_new_cstr(mrb, "miny"), mrb_fixnum_value(miny)); mrb_hash_set(mrb, result, mrb_str_new_cstr(mrb, "maxy"), mrb_fixnum_value(maxy)); mrb_hash_set(mrb, result, mrb_str_new_cstr(mrb, "advance"), mrb_fixnum_value(advance)); return result; }
unsigned int Font::getWidthFromCharacter( char c ) const { int minx, maxx, miny, maxy, advance; TTF_GlyphMetrics( _d->ttfFont, c, &minx, &maxx, &miny, &maxy, &advance ); return advance; }
static void cache_glyphs() { int top = 999; int bottom = -999; start_color(); for(int ch = 0; ch < 128; ch++) { for(int color = 0; color < 16; color++) { //I hate this kind of ternary use SDL_Surface * sglyph = (fontblending ? TTF_RenderGlyph_Blended : TTF_RenderGlyph_Solid)(font, ch, windowsPalette[color]); if(sglyph != NULL) { int minx, maxx, miny, maxy, advance; if(color==0 && 0 == TTF_GlyphMetrics(font, ch, &minx, &maxx, &miny, &maxy, &advance) ) { int t = TTF_FontAscent(font)-maxy; int b = t + sglyph->h; if(t < top) top = t; if(b > bottom) bottom = b; } glyph_height[ch] = sglyph->h; glyph_cache[ch][color] = SDL_CreateTextureFromSurface(renderer,sglyph); } SDL_FreeSurface(sglyph); } } int height = bottom - top; int delta = (fontheight - height) / 2; ttf_height_hack = delta - top; }
Font_FT::Glyph::Glyph(TTF_Font *font_, const unsigned char &c, SDL_Surface *source, SDL_Surface *render_target, const SDL_Rect &dstrect, const int &total_width, const int &total_height, const float &vratio) : m_glyph_width(0) { int minx, maxy, glyph_width; TTF_GlyphMetrics(font_, c, &minx, 0, 0, &maxy, &glyph_width); m_glyph_width = glyph_width / vratio; m_upper_left_point.x = float(minx) / vratio; m_upper_left_point.y = float(TTF_FontAscent(font_) - maxy) / vratio; m_lower_right_point.x = m_upper_left_point.x + source->w / vratio; m_lower_right_point.y = m_upper_left_point.y + source->h / vratio; SDL_Rect dstrect2 = {dstrect.x, dstrect.y, Uint16(source->w), Uint16(source->h)}; m_upper_left_texel.x = float(dstrect2.x) / float(total_width); m_upper_left_texel.y = float(dstrect2.y) / float(total_height); m_lower_right_texel.x = float(dstrect2.x + source->w) / float(total_width); m_lower_right_texel.y = float(dstrect2.y + source->h) / float(total_height); SDL_BlitSurface(source, 0, render_target, &dstrect2); SDL_FreeSurface(source); }
Glyph *font_getGlyphInfo(int start, int count) { int i; Glyph *first; Glyph *current; int minx, maxx, miny, maxy; first = malloc(sizeof(Glyph)); if (!first) { error_print("Unable to allocate memory for glyph info."); return NULL; } current = first; for (i = 0; i < (start + count); i++) { TTF_GlyphMetrics(font, start + count, &minx, &maxx, &miny, &maxy, NULL); current->w = maxx - minx; current->h = maxy - miny; current->x = 0; current->y = 0; current->next = NULL; if (i + 1 < (start + count)) { current->next = malloc(sizeof(Glyph)); if (!current->next) { error_print("Unable to allocate memory for glyph info."); // todo: add destruction code here return NULL; } current = current->next; } } return first; }
bool Init() { TTF_Init(); PokemonNormal.sdlColor = { 0, 0, 0, 0 }; PokemonNormal.ttfFont = TTF_OpenFont("Fonts/PokemonRed.ttf", 16); if (PokemonNormal.ttfFont == NULL) { printf("Failure to load \"Fonts/PokemonRed.ttf\"\n"); return 1; } int i; for (i = 0; i < 256; i++) { if (TTF_GlyphMetrics(PokemonNormal.ttfFont, i, &PokemonNormal.aoChar[i].iMinX, &PokemonNormal.aoChar[i].iMaxX, &PokemonNormal.aoChar[i].iMinY, &PokemonNormal.aoChar[i].iMaxY, &PokemonNormal.aoChar[i].iAdvance) == -1) { printf("%s\n", TTF_GetError()); return 1; } } return 0; }
SDL_Surface *addOverlayLetter(SDL_Surface *image, const char *text) { const char *font_path = "../Resources/Helvetica.ttf"; const unsigned int font_size = 128; TTF_Font *overlay_font = loadFont(font_path, font_size); // TODO: check this succeeded! //TTF_SetFontOutline(overlay_font, 1); SDL_Rect text_loc; SDL_Color text_color = { 0xFF, 0xFF, 0xFF }; int text_minx, text_maxx, text_miny, text_maxy, text_advance; TTF_GlyphMetrics(overlay_font, text[0], &text_minx, &text_maxx, &text_miny, &text_maxy, &text_advance); // Center the letter in the image text_loc.w = image->w; text_loc.h = image->h; text_loc.x = text_minx - 8; text_loc.y = text_miny; // Blitting SDL_Surface *overlay = TTF_RenderText_Blended(overlay_font, text, text_color); overlay = SDL_DisplayFormatAlpha(overlay); SDL_SetAlpha(overlay, SDL_SRCALPHA | SDL_RLEACCEL, 10); SDL_BlitSurface(overlay, &text_loc, image, NULL); SDL_FreeSurface(overlay); TTF_CloseFont(overlay_font); return image; }
void Font::loadChar(int c) { GLfloat texcoord[4]; char letter[2] = { 0, 0 }; if ((minGlyph <= c) && (c <= maxGlyph) && (NULL == glyphs[c].pic)) { SDL_Surface *g0 = NULL; SDL_Surface *g1 = NULL; letter[0] = c; TTF_GlyphMetrics(ttfFont, (Uint16) c, &glyphs[c].minx, &glyphs[c].maxx, &glyphs[c].miny, &glyphs[c].maxy, &glyphs[c].advance); g0 = TTF_RenderText_Shaded(ttfFont, letter, foreground, background); if (g0) { g1 = SDL_ConvertSurface(g0,g0->format,0); SDL_FreeSurface(g0); } if (g1) { glyphs[c].pic = g1; glyphs[c].tex = 0; // loadTextureColorKey(g1, texcoord, 0, 0, 0); glyphs[c].texMinX = texcoord[0]; glyphs[c].texMinY = texcoord[1]; glyphs[c].texMaxX = texcoord[2]; glyphs[c].texMaxY = texcoord[3]; } } }
static void cache_glyphs() { int top=999, bottom=-999; start_color(); for(int ch=0; ch<128; ch++) { for(int color=0; color<16; color++) { SDL_Surface * glyph = glyph_cache[ch][color] = (fontblending?TTF_RenderGlyph_Blended:TTF_RenderGlyph_Solid)(font, ch, windowsPalette[color]); int minx, maxx, miny, maxy, advance; if(glyph!=NULL && color==0 && 0==TTF_GlyphMetrics(font, ch, &minx, &maxx, &miny, &maxy, &advance) ) { int t = TTF_FontAscent(font)-maxy; int b = t + glyph->h; if(t<top) top = t; if(b>bottom) bottom = b; } } } int height = bottom - top; int delta = (fontheight-height)/2; ttf_height_hack = delta - top; }
void ONScripterLabel::drawGlyph( SDL_Surface *dst_surface, FontInfo *info, SDL_Color &color, char* text, int xy[2], bool shadow_flag, AnimationInfo *cache_info, SDL_Rect *clip, SDL_Rect &dst_rect ) { unsigned short unicode; if (IS_TWO_BYTE(text[0])){ unsigned index = ((unsigned char*)text)[0]; index = index << 8 | ((unsigned char*)text)[1]; unicode = onsLocaleConv( index ); } else{ if ((text[0] & 0xe0) == 0xa0 || (text[0] & 0xe0) == 0xc0) unicode = ((unsigned char*)text)[0] - 0xa0 + 0xff60; else unicode = text[0]; } int minx, maxx, miny, maxy, advanced; #if 0 if (TTF_GetFontStyle( (TTF_Font*)info->ttf_font ) != (info->is_bold?TTF_STYLE_BOLD:TTF_STYLE_NORMAL) ) TTF_SetFontStyle( (TTF_Font*)info->ttf_font, (info->is_bold?TTF_STYLE_BOLD:TTF_STYLE_NORMAL)); #endif TTF_GlyphMetrics( (TTF_Font*)info->ttf_font, unicode, &minx, &maxx, &miny, &maxy, &advanced ); //printf("min %d %d %d %d %d %d\n", minx, maxx, miny, maxy, advanced,TTF_FontAscent((TTF_Font*)info->ttf_font) ); SDL_Surface *tmp_surface = renderGlyph( (TTF_Font*)info->ttf_font, unicode ); bool rotate_flag = false; if ( info->getTateyokoMode() == FontInfo::TATE_MODE && IS_ROTATION_REQUIRED(text) ) rotate_flag = true; dst_rect.x = xy[0] + minx; dst_rect.y = xy[1] + TTF_FontAscent((TTF_Font*)info->ttf_font) - maxy; if ( rotate_flag ) dst_rect.x += miny - minx; if ( info->getTateyokoMode() == FontInfo::TATE_MODE && IS_TRANSLATION_REQUIRED(text) ){ dst_rect.x += info->font_size_xy[0]/2; dst_rect.y -= info->font_size_xy[0]/2; } if ( shadow_flag ){ dst_rect.x += shade_distance[0]; dst_rect.y += shade_distance[1]; } if ( tmp_surface ){ if (rotate_flag){ dst_rect.w = tmp_surface->h; dst_rect.h = tmp_surface->w; } else{ dst_rect.w = tmp_surface->w; dst_rect.h = tmp_surface->h; } if (cache_info) cache_info->blendBySurface( tmp_surface, dst_rect.x, dst_rect.y, color, clip, rotate_flag ); if (dst_surface) alphaBlend32( dst_surface, dst_rect, tmp_surface, color, clip, rotate_flag ); } }
Bool fillXCharStruct(TTF_Font* font, unsigned int character, XCharStruct* charStruct) { int minX, maxX, minY, maxY, advance; if (TTF_GlyphMetrics(font, (Uint16) character, &minX, &maxX, &minY, &maxY, &advance) == -1) { LOG("Failed to determine metrics for character '%u': %s\n", character, TTF_GetError()); return False; } charStruct->width = (short) advance; charStruct->rbearing = (short) maxX; return True; }
void load_font(char *fname, int size) { char *p; free_font(); font=TTF_OpenFont(fname, size); if(!font) { printf("TTF_OpenFont: %s\n", TTF_GetError()); exit(3); } /* print some metrics and attributes */ printf("size : %d\n",size); printf("TTF_FontHeight : %d\n",TTF_FontHeight(font)); printf("TTF_FontAscent : %d\n",TTF_FontAscent(font)); printf("TTF_FontDescent : %d\n",TTF_FontDescent(font)); printf("TTF_FontLineSkip : %d\n",TTF_FontLineSkip(font)); printf("TTF_FontFaceIsFixedWidth: %d\n",TTF_FontFaceIsFixedWidth(font)); { char *str=TTF_FontFaceFamilyName(font); if(!str) str="(null)"; printf("TTF_FontFaceFamilyName : \"%s\"\n",str); } { char *str=TTF_FontFaceStyleName(font); if(!str) str="(null)"; printf("TTF_FontFaceStyleName : \"%s\"\n",str); } if(TTF_GlyphIsProvided(font,'g')) { int minx, maxx, miny, maxy, advance; TTF_GlyphMetrics(font,'g', &minx, &maxx, &miny, &maxy, &advance); printf("TTF_GlyphMetrics('g'):\n\tminx=%d\n\tmaxx=%d\n\tminy=%d\n\tmaxy=%d\n\tadvance=%d\n", minx, maxx, miny, maxy, advance); } else printf("TTF_GlyphMetrics('g'): unavailable in font!\n"); /* set window title and icon name, using filename and stuff */ p=strrchr(fname,'/'); if(!p) p=strrchr(fname,'\\'); if(!p) p=strrchr(fname,':'); if(!p) p=fname; else p++; /* cache new glyphs */ cache_glyphs(); }
void Font::CalculateHeights() { height = TTF_FontHeight(font); ascent_height = TTF_FontAscent(font); int miny, maxy; TTF_GlyphMetrics(font, 'M', NULL, NULL, &miny, &maxy, NULL); capital_height = maxy - miny + 1; }
void SimKit::TTFVFont::get_glyph_data(const Uint32 ch, SDL_Rect *out_glyph_box, int *out_advance) { int minx, maxx, miny, maxy, advance; TTF_GlyphMetrics(this->rfont, ch, &minx, &maxx, &miny, &maxy, &advance); if (out_advance) *out_advance = advance; if (out_glyph_box) { out_glyph_box->x = minx; out_glyph_box->y = -maxy; //SDL uses top-left coords, OpenGL and FreeType use bottom-left coords out_glyph_box->w = maxx - minx; out_glyph_box->h = maxy - miny; } };
/** * Initializes the required font metrics. */ static Code initialize_font_metrics(void) { int width; int height; Font *font = global_monospaced_font; if (TTF_GlyphMetrics(font, 'A', NULL, NULL, NULL, NULL, &width)) { log_message("Could not assess the width of a font."); return CODE_ERROR; } height = TTF_FontHeight(font); global_monospaced_font_width = width; global_monospaced_font_height = height; return CODE_OK; }
// determines the dimensions to create the most economical texture size, // based on the font starting char and count. glyphs are organised into a 2d // array // returns dimensions in *width and *height // todo: change to use font_getGlyphInfo() int font_determineDimensions(int start_char, int count, int *width, int *height, int *per_row) { int minx, maxx, miny, maxy, advance; int cur_row_width, max_row_width; int cur_max_height; int glyphs[*per_row][*per_row]; int x, y; // set to 0 *width = 0; *height = 0; max_row_width = 0; // cycle through all characters starting with start_char for (y = 0; y < *per_row; y++) { // reset for the next row cur_row_width = 0; cur_max_height = 0; for (x = 0; x < *per_row; x++ ) { if ((x+(*per_row * y)) < count) { // make sure we don't do too many chars (due to the rounding above) glyphs[x][y] = start_char + (x + (x * y)); // get the metrics if (TTF_GlyphMetrics(font, glyphs[x][y], &minx, &maxx, &miny, &maxy, &advance)){ error_print("Failed to get Glyph metrics."); return 0; } // increment the row width by the glyph width cur_row_width += advance + (GLYPH_PADDING * 2); // is this the highest character in the row if (maxy + (GLYPH_PADDING * 2) > cur_max_height) { cur_max_height = maxy + (GLYPH_PADDING * 2) + 20; // todo: 20 is a temp fix... } } } *height += cur_max_height; // use highest char as row height and add to total // is this the widest row so far? if (cur_row_width > max_row_width) max_row_width = cur_row_width + 20; // todo: 20 is a temp fix... } *width = max_row_width; // set the widest row as the width return 1; }
GlyphMetrics SDLFont::getGlyph(Uint16 ch) { GlyphMetrics metrics; int minx, miny, maxx, maxy, advance; int error = TTF_GlyphMetrics(this->fontContext, ch, &minx, &maxx, &miny, &maxy, &advance); metrics.minx = minx; metrics.miny = miny; metrics.maxx = maxx; metrics.maxy = maxy; metrics.advance = advance; return metrics; }
texture *font_impl::get_glyph(const wchar_t ch) const { shared_pointer<texture> tex = glyph_textures[ch]; if (!tex.ptr()) { int minx, maxx, miny, maxy, advance; if (TTF_GlyphMetrics(static_cast<TTF_Font *>(ttf_font_ptr), ch, &minx, &maxx, &miny, &maxy, &advance) == -1) throw runtime_exception(L"Error getting glyph metrics: %hs", TTF_GetError()); SDL_Color c; c.r = static_cast<Uint8>(fg[color::COMPONENT_RED] * 255.0f); c.g = static_cast<Uint8>(fg[color::COMPONENT_GREEN] * 255.0f); c.b = static_cast<Uint8>(fg[color::COMPONENT_BLUE] * 255.0f); SDL_Surface *surf1 = TTF_RenderGlyph_Blended(static_cast<TTF_Font *>(ttf_font_ptr), ch, c); SDL_Surface *surf2 = SDL_CreateRGBSurface(SDL_SWSURFACE, nearest_power_2(minx + surf1->w), texture_height, 32, surf1->format->Rmask, surf1->format->Gmask, surf1->format->Bmask, surf1->format->Amask); if (!surf2) throw runtime_exception(L"Unable to create SDL surface: %hs", SDL_GetError()); SDL_Rect dest; dest.x = minx > 0 ? minx : 0; dest.y = (surf2->h - font_height) + (font_ascent - maxy); dest.w = surf1->w; dest.h = surf1->h; clear_pixel_alpha(surf2); src_alpha_blit(surf1, surf2, dest.x, dest.y); string glyph_id = string::format(L"%ls %d: %lc", face.w_string(), size, ch); tex = new texture(FONT_TEXTURE_CATEGORY, surf2, texture::TEXTURE_ENV_REPLACE | texture::TEXTURE_WRAP_CLAMP | texture::TEXTURE_FILTER_LINEAR, texture::TEXTURE_COLORMAP, glyph_id.w_string()); glyph_textures[ch] = tex; glyph_pct_x[ch] = static_cast<float>(advance) / static_cast<float>(surf2->w); glyph_pct_y[ch] = static_cast<float>(font_height) / static_cast<float>(surf2->h); glyph_widths[ch] = static_cast<float>(advance); SDL_FreeSurface(surf2); SDL_FreeSurface(surf1); } return tex.ptr(); } // font_impl::get_glyph()
// Get real text dimensions -- the textshape will completely contain the // rendered text but won't match its size. This function can be used to // get the true position and dimensions of the rendered text. // // The fifth argument, b, is the baseline of the text void TextShape::getTextDimensions(int *x, int *y, int *w, int *h, int *b, int *yOff) { if (textShapeFont[fontSize] == NULL) { textShapeFont[fontSize] = FONT_LoadTTF("FreeSans.ttf", fontSize); } assert(textShapeFont[fontSize] != NULL); int realH = 0; Uint16 *ch = unicodeStr; int overallMaxY = 0; while (*ch != '\0') { int minx, maxx, miny, maxy, advance; int err = TTF_GlyphMetrics(textShapeFont[fontSize], *ch, &minx, &maxx, &miny, &maxy, &advance); if (!err) { realH = std::max(realH, maxy - miny + 1); overallMaxY = std::max(overallMaxY, maxy); } else { printf("warning: TTF_GlyphMetrics returned an error\n"); } ch++; } int ascent = TTF_FontAscent(textShapeFont[fontSize]); int realYOffset = ascent - overallMaxY; // Can't get width from the individual glyphs due to kerning issues, // just call TTF_SizeUNICODE int textw, dummy; // Get text size: TTF_SizeUNICODE(textShapeFont[fontSize], unicodeStr, &textw, &dummy); if (x) *x = xpos + cxoff; if (y) *y = ypos + cyoff; if (w) *w = textw; if (h) *h = realH; if (b) *b = ypos + overallMaxY + cxoff; if (yOff) *yOff = realYOffset; }
void cache_glyphs() { int i; char title[800]; SDL_Color fg={0,0,0,255}; #if RENDER_MODE==1 SDL_Color bg={255,255,255,255}; #endif free_glyphs(); if(!font) return; if(style!=TTF_GetFontStyle(font)) TTF_SetFontStyle(font,style); if(kerning != !!TTF_GetFontKerning(font)) TTF_SetFontKerning(font,kerning); if(hinting != TTF_GetFontHinting(font)) TTF_SetFontHinting(font,hinting); if(outline != TTF_GetFontOutline(font)) TTF_SetFontOutline(font,outline); for(i=0; i<128; i++) { /* cache rendered surface */ #if RENDER_MODE==0 text[i]=TTF_RenderGlyph_Solid(font,i+start_glyph,fg); #elif RENDER_MODE==1 text[i]=TTF_RenderGlyph_Shaded(font,i+start_glyph,fg,bg); #elif RENDER_MODE==2 text[i]=TTF_RenderGlyph_Blended(font,i+start_glyph,fg); #endif if(!text[i]) { printf("TTF_RenderGlyph_Shaded: %s\n", TTF_GetError()); exit(4); } /* cache metrics */ TTF_GlyphMetrics(font, i+start_glyph, &gm[i].minx, &gm[i].maxx, &gm[i].miny, &gm[i].maxy, &gm[i].advance); } sprintf(title,"%s-%s:%d+0x%04x",TTF_FontFaceFamilyName(font), TTF_FontFaceStyleName(font),font_size,start_glyph); SDL_WM_SetCaption(title,"latin1"); }
// // Given a single character, make it into an opengl texture // static void ttf_create_tex_from_char (font *f, uint8 c) { static char text[2]; int e; // // Load the glyph info // e = TTF_GlyphMetrics(f->ttf, c, &f->glyphs[c].minx, &f->glyphs[c].maxx, &f->glyphs[c].miny, &f->glyphs[c].maxy, &f->glyphs[c].advance); if (e != 0) { ERR("error loading font glyph %u %s", c, f->name); return; } text[0] = c; text[1] = '\0'; SDL_Surface *g0 = TTF_RenderText_Shaded(f->ttf, text, f->foreground, f->background); if (!g0) { ERR("error rendering font glyph %u %s", c, f->name); return; } SDL_Surface *g1 = SDL_DisplayFormat(g0); SDL_FreeSurface(g0); if (!g1) { ERR("error getting display format for font glyph %u %s", c, f->name); return; } GLfloat texcoord [4]; f->glyphs[c].image = g1; f->glyphs[c].tex = ttf_set_color_key(g1, texcoord, 0, 0, 0); f->glyphs[c].texMinX = texcoord[0]; f->glyphs[c].texMinY = texcoord[1]; f->glyphs[c].texMaxX = texcoord[2]; f->glyphs[c].texMaxY = texcoord[3]; }
int Font::UnicodeTextMaxAdvance(const char16_t *text, int w) { int count = 0; int adv; while (w > 0) { if (text[count] == u'\0') break; TTF_GlyphMetrics(mFont, text[count], NULL, NULL, NULL, NULL, &adv); if (w < adv) break; w -= adv; ++ count; } return count; }
static void OutputChar(Uint16 t, int x, int y, unsigned char color) { color &= 0xf; SDL_Surface * glyph = t<0x80?glyph_cache[t][color]:(fontblending?TTF_RenderGlyph_Blended:TTF_RenderGlyph_Solid)(font, t, windowsPalette[color]); if(glyph) { int minx=0, maxy=0, dx=0, dy = 0; if( 0==TTF_GlyphMetrics(font, t, &minx, NULL, NULL, &maxy, NULL)) { dx = minx; dy = TTF_FontAscent(font)-maxy+ttf_height_hack; SDL_Rect rect; rect.x = x+dx; rect.y = y+dy; rect.w = fontwidth; rect.h = fontheight; SDL_BlitSurface(glyph, NULL, screen, &rect); } if(t>=0x80) SDL_FreeSurface(glyph); } }
static void OutputChar(char t, int x, int y, int n, unsigned char color) { unsigned char ch = t & 0x7f; color &= 0xf; SDL_Surface * glyph = glyph_cache[ch][color]; if(glyph) { int minx=0, maxy=0, dx=0, dy = 0; if( 0==TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL)) { dx = minx; dy = TTF_FontAscent(font)-maxy+ttf_height_hack; SDL_Rect rect; rect.x = x+dx; rect.y = y+dy; rect.w = fontwidth; rect.h = fontheight; SDL_BlitSurface(glyph, NULL, screen, &rect); } } }
static void OutputFontChar(Uint16 t, int x, int y, unsigned char color) { color &= 0xf; bool created = false; SDL_Texture * glyph; int height = 0; if(t < 0x80) { glyph = glyph_cache[t][color]; height = glyph_height[t]; } else { //create the texture instead SDL_Surface *sglyph = (fontblending ? TTF_RenderGlyph_Blended : TTF_RenderGlyph_Solid) (font, t, windowsPalette[color]); glyph = SDL_CreateTextureFromSurface(renderer,sglyph); height = sglyph->h; SDL_FreeSurface(sglyph); created = true; } if(glyph) { int minx = 0, miny = 0, maxy = 0, dx = 0, dy = 0; if( 0 == TTF_GlyphMetrics(font, t, &minx, NULL, &miny, &maxy, NULL)) { dx = minx; dy = TTF_FontAscent(font) - maxy + ttf_height_hack; SDL_Rect rect; rect.x = x + dx; rect.y = y + dy; //these are not fontwidth/fontheight... rect.w = fontwidth; rect.h = height; SDL_RenderCopy(renderer,glyph,NULL,&rect); } if(created) { SDL_DestroyTexture(glyph); } } }
int Font::Load( const char *file, int size ) { // SDL_ttf segfaults if the font is not present... if ( File::Exists( file ) ) { f = TTF_OpenFont( file, size ); if ( f ) { col = Color(CF_COLOR_WHITE); TTF_SetFontStyle( f, TTF_STYLE_BOLD ); // this is an ugly hack and rather error prone... int minx, maxx; TTF_GlyphMetrics( f, 'w', &minx, &maxx, 0, 0, 0 ); width = maxx - minx; height = TTF_FontHeight( f ); return 0; } } return -1; }
int LOBJECT_METHOD(getGlyphMetrics, TTF_Font * font){ if (state.is_number(1)){ Uint16 glyph = static_cast<Uint16>(state.to_integer(1)); int minx = 0; int maxx = 0; int miny = 0; int maxy = 0; int advance = 0; int result = TTF_GlyphMetrics(font, glyph, &minx, &maxx, &miny, &maxy, &advance); if (result == 0){ state.push_integer(minx); state.push_integer(maxx); state.push_integer(miny); state.push_integer(maxy); state.push_integer(advance); return 5; }else{ state.push_boolean(false); return 1; } } return 0; }
void Font::LoadChar( char c ) { GLfloat texcoord[ 4 ] = { 0.0f, 0.0f, 0.0f, 0.0f }; char letter[ 2 ] = { 0, 0 }; if( ! Glyphs[ (unsigned char) c ].Pic ) { SDL_Surface *g0 = NULL; SDL_Surface *g1 = NULL; letter[ 0 ] = c; TTF_GlyphMetrics( TTFont, (Uint16) c, &Glyphs[ (unsigned char) c ].MinX, &Glyphs[ (unsigned char) c ].MaxX, &Glyphs[ (unsigned char) c ].MinY, &Glyphs[ (unsigned char) c ].MaxY, &Glyphs[ (unsigned char) c ].Advance ); SDL_Color foreground = { 255, 255, 255, 255 }; g0 = TTF_RenderText_Blended( TTFont, letter, foreground ); if( g0 ) { g1 = SDL_DisplayFormatAlpha( g0 ); SDL_FreeSurface( g0 ); } if( g1 ) { Glyphs[ (unsigned char) c ].Pic = g1; Glyphs[ (unsigned char) c ].Tex = Raptor::Game->Gfx.LoadTexture( g1, texcoord ); // FIXME? Glyphs[ (unsigned char) c ].TexMinX = texcoord[ 0 ]; Glyphs[ (unsigned char) c ].TexMinY = texcoord[ 1 ]; Glyphs[ (unsigned char) c ].TexMaxX = texcoord[ 2 ]; Glyphs[ (unsigned char) c ].TexMaxY = texcoord[ 3 ]; } } }