Texture TextGenerator::Generate(const std::string &data, int size, float width) { Texture texture; TTF_Font *font = Font(size); if (font) { TTF_SetFontOutline(font, 0); int w = width == 0 ? INT_MAX : g_Graphics()->to_pixels(width); SDL_Surface *surface = TTF_RenderUTF8_Blended_Wrapped(font, data.c_str(), SDL_Color{255, 255, 255, 255}, w); // TODO: fix shadow wrapping TTF_SetFontOutline(font, outline); SDL_Surface *shadowSurface = TTF_RenderUTF8_Blended_Wrapped(font, data.c_str(), SDL_Color{96, 96, 96, 255}, w); if (surface && shadowSurface) { SDL_Rect dest; dest.x = outline; dest.y = outline; dest.w = surface->w; dest.h = surface->h; SDL_BlitSurface(surface, 0, shadowSurface, &dest); texture = Texture(shadowSurface); } if (surface) SDL_FreeSurface(surface); if (shadowSurface) SDL_FreeSurface(shadowSurface); } return texture; }
FontHelper::FontHelper(const string &font, int size, RGBAColor textColor, RGBAColor outlineColor) { this->textColor = textColor; this->outlineColor = outlineColor; if (!TTF_WasInit()) { DEBUG("Initializing font"); if (TTF_Init() == -1) { ERROR("TTF_Init: %s", TTF_GetError()); exit(2); } } this->font = TTF_OpenFont(font.c_str(), size); if (!this->font) { ERROR("TTF_OpenFont %s: %s", font.c_str(), TTF_GetError()); exit(2); } fontOutline = TTF_OpenFont(font.c_str(), size); if (!fontOutline) { ERROR("TTF_OpenFont %s: %s", font.c_str(), TTF_GetError()); exit(2); } TTF_SetFontHinting(this->font, TTF_HINTING_NORMAL); TTF_SetFontHinting(fontOutline, TTF_HINTING_NORMAL); TTF_SetFontOutline(fontOutline, 1); height = 0; // Get maximum line height with a sample text TTF_SizeUTF8(fontOutline, "AZ|¹0987654321", NULL, &height); halfHeight = height/2; }
//Sets the outline around the font //param:fontIndex->The index of the font to modify //param:outlineSize->The size to set the outline void SpriteFont::SetFontOutline(int fontIndex, int outlineSize) { //Try block to make sure index is valid try { //Get the font to modify TTF_Font* font = fontList.at(fontIndex); if(font) { //Get the current style int currentOutline = TTF_GetFontOutline(font); //Save processing by not changing style if they are identical if(currentOutline != outlineSize) { //Otherwise, set the style TTF_SetFontOutline(font, outlineSize); } } else { std::cout<<"SetFontOutline error: Provided index is NULL"<<std::endl; return; } } catch(std::out_of_range problem) { //display invalid index std::cout<<"SetFontOutline error: font index invalid"<<std::endl; return; } }
static mrb_value mrb_sdl2_ttf_font_set_outline(mrb_state *mrb, mrb_value self) { mrb_int outline; mrb_get_args(mrb, "i", &outline); TTF_SetFontOutline(mrb_sdl2_font_get_ptr(mrb, self), outline); return mrb_nil_value(); }
int LOBJECT_METHOD(setFontOutline, TTF_Font * font){ int style = 0; if (state.is_number(1)){ style = state.to_integer(1); } TTF_SetFontOutline(font, style); return 0; }
void Font::printDamages(u16 damages, u16 x, u16 y, Color color) { TTF_SetFontKerning(m_fontLarge, 0); TTF_SetFontHinting(m_fontLarge, TTF_HINTING_NONE); TTF_SetFontOutline(m_fontLarge, 3); print(to_string(damages).c_str(), x - 3, y - 3, FONT_LARGE, Color::black); TTF_SetFontOutline(m_fontLarge, 2); print(to_string(damages).c_str(), x - 2, y - 2, FONT_LARGE, Color::white); TTF_SetFontOutline(m_fontLarge, 0); print(to_string(damages).c_str(), x, y, FONT_LARGE, color); TTF_SetFontHinting(m_fontLarge, TTF_HINTING_NORMAL); TTF_SetFontKerning(m_fontLarge, 1); }
FontAdapter_SDL_ttf::FontAdapter_SDL_ttf(GraphicsContext* gc, const FontDescriptor& fontDescriptor) { const float scaling = 1.2f; if (!TTF_WasInit()) TTF_Init(); int size = (int)(scaling * fontDescriptor.size * gc->GetCombinedScaling()); if (size == 0) size = (int)(scaling * 12 * gc->GetCombinedScaling()); _font1 = TTF_OpenFont(fontDescriptor.bold ? FONTNAME_BOLD : FONTNAME_REGULAR, size); _font2 = TTF_OpenFont(FONTNAME_FALLBACK, size); //_emoji = TTF_OpenFont(FONTNAME_EMOJI, size); int style = fontDescriptor.bold ? TTF_STYLE_BOLD : TTF_STYLE_NORMAL; int hinting = TTF_HINTING_NORMAL; if (_font1 != NULL) { //TTF_SetFontStyle(_font1, style); TTF_SetFontOutline(_font1, 0); TTF_SetFontKerning(_font1, 1); TTF_SetFontHinting(_font1, hinting); } if (_font2 != NULL) { //TTF_SetFontStyle(_font2, style); TTF_SetFontOutline(_font2, 0); TTF_SetFontKerning(_font2, 1); TTF_SetFontHinting(_font2, hinting); } if (_emoji != NULL) { //TTF_SetFontStyle(_emoji, style); TTF_SetFontOutline(_emoji, 0); TTF_SetFontKerning(_emoji, 1); TTF_SetFontHinting(_emoji, hinting); } }
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"); }
void cache_glyphs() { SDL_Color fg={0,0,0,255}; #if RENDER_MODE==1 SDL_Color bg={255,255,255,255}; #endif 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); }
// Load TTF font from file. INT32 I_TTFLoadFont(const char *file, UINT32 ptsize) { TTF_Font *tmpfont = NULL; float fontsize; // If a font is currently loaded, unload it. if (currentfont) { TTF_CloseFont(currentfont); } // Scale the specified font point size for the current resolution. fontsize = (ptsize * 0.005f) * (res.width - res.height); tmpfont = TTF_OpenFont(file, fontsize); if (!tmpfont) return FONTHANDLE; // set pointer for current font currentfont = tmpfont; // set current font point size currentfontpoint = ptsize; // get font properties, and set them currentfontstyle = TTF_GetFontStyle(currentfont); TTF_SetFontStyle(currentfont, currentfontstyle); // these functions only exist in SDL_ttf 2.0.10 onwards #if SDL_TTF_VERSION_ATLEAST(2,0,10) currentfontkerning = TTF_GetFontKerning(currentfont); TTF_SetFontKerning(currentfont, currentfontkerning); currentfonthinting = TTF_GetFontHinting(currentfont); TTF_SetFontHinting(currentfont, currentfonthinting); currentfontoutline = TTF_GetFontOutline(currentfont); TTF_SetFontOutline(currentfont, currentfontoutline); #endif return 0; }
/* THIS CLASS IS DEPENDENT ON THE IMAGE CLASS */ SDL_Texture *renderFont(TTF_Font *fontObject,char *txt,int colour,int flags,int size, bool antialias, int outline, bool kerning){ if(fontObject){ TTF_SetFontStyle(fontObject,flags); SDL_Surface *surface = NULL; SDL_Color colourOb; colourOb.r = (colour & 0xFF0000)>>16; colourOb.g = (colour & 0x00FF00)>>8; colourOb.b = (colour & 0xFF); TTF_SetFontOutline(fontObject, outline); TTF_SetFontKerning(fontObject, (int) kerning); if(antialias) surface = TTF_RenderText_Blended(fontObject,(const char *)txt, colourOb); else surface = TTF_RenderText_Solid(fontObject,(const char *) txt, colourOb); SDL_Texture *tx = NULL; tx = SDL_CreateTextureFromSurface(renderer,surface); SDL_FreeSurface(surface); return tx; } else return NULL;
// // Load a new font and create textures for each glyph // font *ttf_new (const char *name, int pointSize, int style) { uint8 c; font *f; f = (fontp)zalloc(sizeof(*f)); if (!f) { return (NULL); } f->name = strdup(name); f->ttf = TTF_OpenFont(name, pointSize); if (!f->ttf) { DIE("cannot open font file %s", name); } f->foreground.r = 255; f->foreground.g = 255; f->foreground.b = 255; f->background.r = 0; f->background.g = 0; f->background.b = 0; TTF_SetFontStyle(f->ttf, style); TTF_SetFontOutline(f->ttf, 0.5); f->height = TTF_FontHeight(f->ttf); f->ascent = TTF_FontAscent(f->ttf); f->descent = TTF_FontDescent(f->ttf); f->lineSkip = TTF_FontLineSkip(f->ttf); for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) { ttf_create_tex_from_char(f, c); } return (f); }
int main(int argc, char *argv[]) { char *argv0 = argv[0]; SDL_Surface *screen; TTF_Font *font; SDL_Surface *text, *temp; int ptsize; int i, done; int rdiff, gdiff, bdiff; SDL_Color colors[NUM_COLORS]; SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 }; SDL_Color black = { 0x00, 0x00, 0x00, 0 }; SDL_Color *forecol; SDL_Color *backcol; SDL_Rect dstrect; SDL_Event event; int rendersolid; int renderstyle; int outline; int hinting; int kerning; int dump; enum { RENDER_LATIN1, RENDER_UTF8, RENDER_UNICODE } rendertype; char *message, string[128]; /* Look for special execution mode */ dump = 0; /* Look for special rendering types */ rendersolid = 0; renderstyle = TTF_STYLE_NORMAL; rendertype = RENDER_LATIN1; outline = 0; hinting = TTF_HINTING_NORMAL; kerning = 1; /* Default is black and white */ forecol = &black; backcol = &white; for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) { if ( strcmp(argv[i], "-solid") == 0 ) { rendersolid = 1; } else if ( strcmp(argv[i], "-utf8") == 0 ) { rendertype = RENDER_UTF8; } else if ( strcmp(argv[i], "-unicode") == 0 ) { rendertype = RENDER_UNICODE; } else if ( strcmp(argv[i], "-b") == 0 ) { renderstyle |= TTF_STYLE_BOLD; } else if ( strcmp(argv[i], "-i") == 0 ) { renderstyle |= TTF_STYLE_ITALIC; } else if ( strcmp(argv[i], "-u") == 0 ) { renderstyle |= TTF_STYLE_UNDERLINE; } else if ( strcmp(argv[i], "-s") == 0 ) { renderstyle |= TTF_STYLE_STRIKETHROUGH; } else if ( strcmp(argv[i], "-outline") == 0 ) { if ( sscanf (argv[++i], "%d", &outline) != 1 ) { fprintf(stderr, Usage, argv0); return(1); } } else if ( strcmp(argv[i], "-hintlight") == 0 ) { hinting = TTF_HINTING_LIGHT; } else if ( strcmp(argv[i], "-hintmono") == 0 ) { hinting = TTF_HINTING_MONO; } else if ( strcmp(argv[i], "-hintnone") == 0 ) { hinting = TTF_HINTING_NONE; } else if ( strcmp(argv[i], "-nokerning") == 0 ) { kerning = 0; } else if ( strcmp(argv[i], "-dump") == 0 ) { dump = 1; } else if ( strcmp(argv[i], "-fgcol") == 0 ) { int r, g, b; if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) { fprintf(stderr, Usage, argv0); return(1); } forecol->r = (Uint8)r; forecol->g = (Uint8)g; forecol->b = (Uint8)b; } else if ( strcmp(argv[i], "-bgcol") == 0 ) { int r, g, b; if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) { fprintf(stderr, Usage, argv0); return(1); } backcol->r = (Uint8)r; backcol->g = (Uint8)g; backcol->b = (Uint8)b; } else { fprintf(stderr, Usage, argv0); return(1); } } argv += i; argc -= i; /* Check usage */ if ( ! argv[0] ) { fprintf(stderr, Usage, argv0); return(1); } /* Initialize SDL */ if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return(2); } /* Initialize the TTF library */ if ( TTF_Init() < 0 ) { fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError()); SDL_Quit(); return(2); } /* Open the font file with the requested point size */ ptsize = 0; if ( argc > 1 ) { ptsize = atoi(argv[1]); } if ( ptsize == 0 ) { i = 2; ptsize = DEFAULT_PTSIZE; } else { i = 3; } font = TTF_OpenFont(argv[0], ptsize); if ( font == NULL ) { fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", ptsize, argv[0], SDL_GetError()); cleanup(2); } TTF_SetFontStyle(font, renderstyle); TTF_SetFontOutline(font, outline); TTF_SetFontKerning(font, kerning); TTF_SetFontHinting(font, hinting); if( dump ) { for( i = 48; i < 123; i++ ) { SDL_Surface* glyph = NULL; glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol ); if( glyph ) { char outname[64]; sprintf( outname, "glyph-%d.bmp", i ); SDL_SaveBMP( glyph, outname ); } } cleanup(0); } /* Set a 640x480x8 video mode */ screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", SDL_GetError()); cleanup(2); } /* Set a palette that is good for the foreground colored text */ rdiff = backcol->r - forecol->r; gdiff = backcol->g - forecol->g; bdiff = backcol->b - forecol->b; for ( i=0; i<NUM_COLORS; ++i ) { colors[i].r = forecol->r + (i*rdiff)/4; colors[i].g = forecol->g + (i*gdiff)/4; colors[i].b = forecol->b + (i*bdiff)/4; } SDL_SetColors(screen, colors, 0, NUM_COLORS); /* Clear the background to background color */ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, backcol->r, backcol->g, backcol->b)); SDL_UpdateRect(screen, 0, 0, 0, 0); /* Show which font file we're looking at */ sprintf(string, "Font file: %s", argv[0]); /* possible overflow */ if ( rendersolid ) { text = TTF_RenderText_Solid(font, string, *forecol); } else { text = TTF_RenderText_Shaded(font, string, *forecol, *backcol); } if ( text != NULL ) { dstrect.x = 4; dstrect.y = 4; dstrect.w = text->w; dstrect.h = text->h; SDL_BlitSurface(text, NULL, screen, &dstrect); SDL_FreeSurface(text); } /* Render and center the message */ if ( argc > 2 ) { message = argv[2]; } else { message = DEFAULT_TEXT; } switch (rendertype) { case RENDER_LATIN1: if ( rendersolid ) { text = TTF_RenderText_Solid(font,message,*forecol); } else { text = TTF_RenderText_Shaded(font,message,*forecol,*backcol); } break; case RENDER_UTF8: if ( rendersolid ) { text = TTF_RenderUTF8_Solid(font,message,*forecol); } else { text = TTF_RenderUTF8_Shaded(font,message,*forecol,*backcol); } break; case RENDER_UNICODE: { Uint16 unicode_text[BUFSIZ]; int index; #ifdef HAVE_ICONV /* Use iconv to convert the message into utf-16. * "char" and "" are aliases for the local 8-bit encoding */ iconv_t cd; /*ICONV_CONST*/ char *from_str = message; char *to_str = (char*)unicode_text; size_t from_sz = strlen(message) + 1; size_t to_sz = sizeof(unicode_text); size_t res; int i; if ((cd = iconv_open("UTF-16", "char")) == (iconv_t)-1 && (cd = iconv_open("UTF-16", "")) == (iconv_t)-1) { perror("Couldn't open iconv"); exit(1); } res = iconv(cd, &from_str, &from_sz, &to_str, &to_sz); if (res == -1) { perror("Couldn't use iconv"); exit(1); } iconv_close(cd); #else /* Convert the message from ascii into utf-16. * This is unreliable as a test because it always * gives the local ordering. */ for (index = 0; message[index]; index++) { unicode_text[index] = message[index]; } unicode_text[index] = 0; #endif if ( rendersolid ) { text = TTF_RenderUNICODE_Solid(font, unicode_text, *forecol); } else { text = TTF_RenderUNICODE_Shaded(font, unicode_text, *forecol, *backcol); } } break; default: text = NULL; /* This shouldn't happen */ break; } if ( text == NULL ) { fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError()); TTF_CloseFont(font); cleanup(2); } dstrect.x = (screen->w - text->w)/2; dstrect.y = (screen->h - text->h)/2; dstrect.w = text->w; dstrect.h = text->h; printf("Font is generally %d big, and string is %hd big\n", TTF_FontHeight(font), text->h); /* Blit the text surface */ if ( SDL_BlitSurface(text, NULL, screen, &dstrect) < 0 ) { fprintf(stderr, "Couldn't blit text to display: %s\n", SDL_GetError()); TTF_CloseFont(font); cleanup(2); } SDL_UpdateRect(screen, 0, 0, 0, 0); /* Set the text colorkey and convert to display format */ if ( SDL_SetColorKey(text, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0) < 0 ) { fprintf(stderr, "Warning: Couldn't set text colorkey: %s\n", SDL_GetError()); } temp = SDL_DisplayFormat(text); if ( temp != NULL ) { SDL_FreeSurface(text); text = temp; } /* Wait for a keystroke, and blit text on mouse press */ done = 0; while ( ! done ) { if ( SDL_WaitEvent(&event) < 0 ) { fprintf(stderr, "SDL_PullEvent() error: %s\n", SDL_GetError()); done = 1; continue; } switch (event.type) { case SDL_MOUSEBUTTONDOWN: dstrect.x = event.button.x - text->w/2; dstrect.y = event.button.y - text->h/2; dstrect.w = text->w; dstrect.h = text->h; if ( SDL_BlitSurface(text, NULL, screen, &dstrect) == 0 ) { SDL_UpdateRects(screen, 1, &dstrect); } else { fprintf(stderr, "Couldn't blit text to display: %s\n", SDL_GetError()); } break; case SDL_KEYDOWN: case SDL_QUIT: done = 1; break; default: break; } } SDL_FreeSurface(text); TTF_CloseFont(font); cleanup(0); /* Not reached, but fixes compiler warnings */ return 0; }
//------------------------------------------------------------------------------ void CFont::SetFontOutline(int outline, unsigned int FontIndex) { if( outline < 0 || !ValidIndex(FontIndex) ) return; TTF_SetFontOutline(Fonts.at(FontIndex).Font, outline); }
Image *MLIFont::RenderGlyph(uint32_t c) { EnsureUIThread(); CheckScale(); // render char SDL_Color whiteColor = {255, 255, 255, 255}; if (invertedColors) { whiteColor.b = 255 - whiteColor.b; whiteColor.g = 255 - whiteColor.g; whiteColor.a = 255 - whiteColor.a; } string utf8string; utf8::unchecked::append(c, back_inserter(utf8string)); SDL_Surface *pSurface = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), whiteColor); if (pSurface == NULL) { return NULL; } int scaledStrokeWidth = strokeWidth * GetFontScale() + 0.5; // render outlines if (strokeWidth > 0) { SDL_Color blackColor = {0, 0, 0, 255}; if (invertedColors) { blackColor.b = 255 - blackColor.b; blackColor.g = 255 - blackColor.g; blackColor.a = 255 - blackColor.a; } #ifndef MLI_SDL_FONT_OUTLINING SDL_Surface *pSurfaceOutline = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor); SDL_Surface *pSurfaceOutlinedText = SDL_CreateRGBSurface( 0, pSurface->w + scaledStrokeWidth * 2, pSurface->h + scaledStrokeWidth * 2, pSurface->format->BitsPerPixel, pSurface->format->Rmask, pSurface->format->Gmask, pSurface->format->Bmask, pSurface->format->Amask); SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND); SDL_Rect dstRect = {0, 0, pSurface->w, pSurface->h}; for (dstRect.x = 0; dstRect.x <= scaledStrokeWidth * 2; dstRect.x++) { for (dstRect.y = 0; dstRect.y <= scaledStrokeWidth * 2; dstRect.y++) { SDL_BlitSurface(pSurfaceOutline, NULL, pSurfaceOutlinedText, &dstRect); } } dstRect.x = scaledStrokeWidth; dstRect.y = scaledStrokeWidth; SDL_SetSurfaceBlendMode(pSurfaceOutline, SDL_BLENDMODE_BLEND); SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect); SDL_FreeSurface(pSurface); SDL_FreeSurface(pSurfaceOutline); pSurface = pSurfaceOutlinedText; #else TTF_SetFontOutline(pTtfFont, scaledStrokeWidth); SDL_Surface *pSurfaceOutlinedText = TTF_RenderUTF8_Blended(pTtfFont, utf8string.c_str(), blackColor); SDL_SetSurfaceBlendMode(pSurfaceOutlinedText, SDL_BLENDMODE_BLEND); SDL_Rect dstRect = {scaledStrokeWidth, scaledStrokeWidth, pSurface->w, pSurface->h}; SDL_BlitSurface(pSurface, NULL, pSurfaceOutlinedText, &dstRect); SDL_FreeSurface(pSurface); pSurface = pSurfaceOutlinedText; TTF_SetFontOutline(pTtfFont, 0); #endif } // create image Image *pImage = Image::Load(pSurface, true); pImage->FlagFontSource(this); pImage->SetUseScreenScaling(false); return pImage; }
void Bitmap::drawText(const IntRect &rect, const char *str, int align) { guardDisposed(); GUARD_MEGA; std::string fixed = fixupString(str); str = fixed.c_str(); if (*str == '\0') return; if (str[0] == ' ' && str[1] == '\0') return; TTF_Font *font = p->font->getSdlFont(); const Color &fontColor = p->font->getColor(); const Color &outColor = p->font->getOutColor(); SDL_Color c = fontColor.toSDLColor(); c.a = 255; float txtAlpha = fontColor.norm.w; SDL_Surface *txtSurf; if (shState->rtData().config.solidFonts) txtSurf = TTF_RenderUTF8_Solid(font, str, c); else txtSurf = TTF_RenderUTF8_Blended(font, str, c); p->ensureFormat(txtSurf, SDL_PIXELFORMAT_ABGR8888); int rawTxtSurfH = txtSurf->h; if (p->font->getShadow()) applyShadow(txtSurf, *p->format, c); /* outline using TTF_Outline and blending it together with SDL_BlitSurface * FIXME: outline is forced to have the same opacity as the font color */ if (p->font->getOutline()) { SDL_Color co = outColor.toSDLColor(); co.a = 255; SDL_Surface *outline; /* set the next font render to render the outline */ TTF_SetFontOutline(font, OUTLINE_SIZE); if (shState->rtData().config.solidFonts) outline = TTF_RenderUTF8_Solid(font, str, co); else outline = TTF_RenderUTF8_Blended(font, str, co); p->ensureFormat(outline, SDL_PIXELFORMAT_ABGR8888); SDL_Rect outRect = {OUTLINE_SIZE, OUTLINE_SIZE, txtSurf->w, txtSurf->h}; SDL_SetSurfaceBlendMode(txtSurf, SDL_BLENDMODE_BLEND); SDL_BlitSurface(txtSurf, NULL, outline, &outRect); SDL_FreeSurface(txtSurf); txtSurf = outline; /* reset outline to 0 */ TTF_SetFontOutline(font, 0); } int alignX = rect.x; switch (align) { default: case Left : break; case Center : alignX += (rect.w - txtSurf->w) / 2; break; case Right : alignX += rect.w - txtSurf->w; break; } if (alignX < rect.x) alignX = rect.x; int alignY = rect.y + (rect.h - rawTxtSurfH) / 2; float squeeze = (float) rect.w / txtSurf->w; if (squeeze > 1) squeeze = 1; FloatRect posRect(alignX, alignY, txtSurf->w * squeeze, txtSurf->h); Vec2i gpTexSize; shState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize); bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0f; if (fastBlit) { if (squeeze == 1.0f && !shState->config().subImageFix) { /* Even faster: upload directly to bitmap texture. * We have to make sure the posRect lies within the texture * boundaries or texSubImage will generate errors. * If it partly lies outside bounds we have to upload * the clipped visible part of it. */ SDL_Rect btmRect; btmRect.x = btmRect.y = 0; btmRect.w = width(); btmRect.h = height(); SDL_Rect txtRect; txtRect.x = posRect.x; txtRect.y = posRect.y; txtRect.w = posRect.w; txtRect.h = posRect.h; SDL_Rect inters; /* If we have no intersection at all, * there's nothing to upload to begin with */ if (SDL_IntersectRect(&btmRect, &txtRect, &inters)) { bool subImage = false; int subSrcX = 0, subSrcY = 0; if (inters.w != txtRect.w || inters.h != txtRect.h) { /* Clip the text surface */ subSrcX = inters.x - txtRect.x; subSrcY = inters.y - txtRect.y; subImage = true; posRect.x = inters.x; posRect.y = inters.y; posRect.w = inters.w; posRect.h = inters.h; } TEX::bind(p->gl.tex); if (!subImage) { TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_RGBA); } else { GLMeta::subRectImageUpload(txtSurf->w, subSrcX, subSrcY, posRect.x, posRect.y, posRect.w, posRect.h, txtSurf, GL_RGBA); GLMeta::subRectImageEnd(); } } } else { /* Squeezing involved: need to use intermediary TexFBO */ TEXFBO &gpTF = shState->gpTexFBO(txtSurf->w, txtSurf->h); TEX::bind(gpTF.tex); TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_RGBA); GLMeta::blitBegin(p->gl); GLMeta::blitSource(gpTF); GLMeta::blitRectangle(IntRect(0, 0, txtSurf->w, txtSurf->h), posRect, true); GLMeta::blitEnd(); } } else { /* Aquire a partial copy of the destination * buffer we're about to render to */ TEXFBO &gpTex2 = shState->gpTexFBO(posRect.w, posRect.h); GLMeta::blitBegin(gpTex2); GLMeta::blitSource(p->gl); GLMeta::blitRectangle(posRect, Vec2i()); GLMeta::blitEnd(); FloatRect bltRect(0, 0, (float) (gpTexSize.x * squeeze) / gpTex2.width, (float) gpTexSize.y / gpTex2.height); BltShader &shader = shState->shaders().blt; shader.bind(); shader.setTexSize(gpTexSize); shader.setSource(); shader.setDestination(gpTex2.tex); shader.setSubRect(bltRect); shader.setOpacity(txtAlpha); shState->bindTex(); TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_RGBA); TEX::setSmooth(true); Quad &quad = shState->gpQuad(); quad.setTexRect(FloatRect(0, 0, txtSurf->w, txtSurf->h)); quad.setPosRect(posRect); p->bindFBO(); p->pushSetViewport(shader); p->blitQuad(quad); p->popViewport(); } SDL_FreeSurface(txtSurf); p->addTaintedArea(posRect); p->onModified(); }
void SDLFont::setOutline(int outline) { TTF_SetFontOutline(this->fontContext, outline); }
void setup (void) { SDL_Surface * image; TTF_Font *temp1, *temp2; SDL_Color color; SDL_Rect rect, rect2; int g; char buffer_file[8192]; char *systemdata_path = get_systemdata_path (); /* Inicializar el Video SDL */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf (stderr, _("Error: Can't initialize the video subsystem\n" "The error returned by SDL is:\n" "%s\n"), SDL_GetError()); exit (1); } sprintf (buffer_file, "%simages/icon.png", systemdata_path); image = IMG_Load (buffer_file); if (image) { SDL_WM_SetIcon (image, NULL); SDL_FreeSurface (image); } SDL_WM_SetCaption (_("Paddle Puffle"), _("Paddle Puffle")); /* Crear la pantalla de dibujado */ screen = set_video_mode (0); if (screen == NULL) { fprintf (stderr, _("Error: Can't setup 760x480 video mode.\n" "The error returned by SDL is:\n" "%s\n"), SDL_GetError()); exit (1); } use_sound = 1; if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) { fprintf (stdout, _("Warning: Can't initialize the audio subsystem\n" "Continuing...\n")); use_sound = 0; } if (use_sound) { /* Inicializar el sonido */ if (Mix_OpenAudio (22050, AUDIO_S16, 2, 4096) < 0) { fprintf (stdout, _("Warning: Can't initialize the SDL Mixer library\n")); use_sound = 0; } } for (g = 0; g < NUM_IMAGES; g++) { sprintf (buffer_file, "%s%s", systemdata_path, images_names[g]); image = IMG_Load (buffer_file); if (image == NULL) { fprintf (stderr, _("Failed to load data file:\n" "%s\n" "The error returned by SDL is:\n" "%s\n"), buffer_file, SDL_GetError()); SDL_Quit (); exit (1); } images[g] = image; /* TODO: Mostrar la carga de porcentaje */ } /* Pre-Dibujar la pantalla gris */ grey_screen = SDL_CreateRGBSurface (SDL_SWSURFACE | SDL_SRCALPHA, 760, 480, 32, 0, 0, 0, 0); SDL_FillRect (grey_screen, NULL, SDL_MapRGB (grey_screen->format, 0, 0, 0)); /* Negro */ SDL_SetAlpha (grey_screen, SDL_SRCALPHA, 128); /* Alpha al 50 % */ if (use_sound) { for (g = 0; g < NUM_SOUNDS; g++) { sprintf (buffer_file, "%s%s", systemdata_path, sound_names[g]); sounds[g] = Mix_LoadWAV (buffer_file); if (sounds[g] == NULL) { fprintf (stderr, _("Failed to load data file:\n" "%s\n" "The error returned by SDL is:\n" "%s\n"), buffer_file, SDL_GetError ()); SDL_Quit (); exit (1); } Mix_VolumeChunk (sounds[g], MIX_MAX_VOLUME / 2); } /* Cargar la música */ sprintf (buffer_file, "%s%s", systemdata_path, MUS_CARNIE); mus_carnie = Mix_LoadMUS (buffer_file); if (mus_carnie == NULL) { fprintf (stderr, _("Failed to load data file:\n" "%s\n" "The error returned by SDL is:\n" "%s\n"), buffer_file, SDL_GetError ()); SDL_Quit (); exit (1); } } if (TTF_Init () < 0) { fprintf (stderr, _("Error: Can't initialize the SDL TTF library\n" "%s\n"), TTF_GetError ()); SDL_Quit (); exit (1); } /* Tipografias 10, 14, 16, 26 */ sprintf (buffer_file, "%s%s", systemdata_path, "ccfacefront.ttf"); ttf_facefront = SDL_RWFromFile (buffer_file, "rb"); if (ttf_facefront == NULL) { fprintf (stderr, _("Failed to load font file 'CCFaceFront'\n" "The error returned by SDL is:\n" "%s\n"), TTF_GetError ()); SDL_Quit (); exit (1); } SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); temp1 = TTF_OpenFontRW (ttf_facefront, 0, 10); SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf14_normal = TTF_OpenFontRW (ttf_facefront, 0, 14); SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf16_normal = TTF_OpenFontRW (ttf_facefront, 0, 16); SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf26_normal = TTF_OpenFontRW (ttf_facefront, 0, 26); if (!temp1 || !ttf14_normal || !ttf16_normal || !ttf26_normal) { SDL_Quit (); exit (1); } SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf20_normal = TTF_OpenFontRW (ttf_facefront, 0, 20); SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf20_outline = TTF_OpenFontRW (ttf_facefront, 0, 20); SDL_RWseek (ttf_facefront, 0, RW_SEEK_SET); ttf16_outline = TTF_OpenFontRW (ttf_facefront, 1, 16); if (!ttf20_normal || !ttf20_outline || !ttf16_outline) { SDL_Quit (); exit (1); } TTF_SetFontStyle (temp1, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf14_normal, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf16_normal, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf26_normal, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf16_outline, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf20_outline, TTF_STYLE_ITALIC); TTF_SetFontStyle (ttf20_normal, TTF_STYLE_ITALIC); TTF_SetFontOutline (ttf16_outline, OUTLINE_TEXT); TTF_SetFontOutline (ttf20_outline, OUTLINE_TEXT); /* Generar textos */ bind_textdomain_codeset (PACKAGE, "UTF-8"); color.r = color.g = color.b = 0; /* Negro */ for (g = 0; g < NUM_TEXTS; g++) { switch (text_info [g]) { case 10: temp2 = temp1; break; case 14: temp2 = ttf14_normal; break; case 16: temp2 = ttf16_normal; break; case 26: temp2 = ttf26_normal; break; default: temp2 = ttf16_normal; } texts[g] = draw_text (temp2, _(text_strings[g]), &color); } /* Copiar la palabra "Tickets" en el background */ /* También copiar el nombre del juego al titulo y al fondo */ rect.x = 607 + ((135 - texts[TEXT_TICKETS]->w) / 2); rect.y = 38; rect.w = texts[TEXT_TICKETS]->w; rect.h = texts[TEXT_TICKETS]->h; rect2.x = 191; rect2.y = 96; rect2.w = images[IMG_TITLE]->w; rect2.h = images[IMG_TITLE]->h; for (g = IMG_BACKGROUND_NORMAL; g <= IMG_BACKGROUND_FAIL_1; g++) { SDL_BlitSurface (texts[TEXT_TICKETS], NULL, images[g], &rect); SDL_BlitSurface (images[IMG_TITLE], NULL, images[g], &rect2); } /* X = 84.35, Y = 50.85 */ rect2.x = 84; rect2.y = 51; SDL_BlitSurface (images[IMG_TITLE], NULL, images[IMG_TITLE_OPENING], &rect2); TTF_CloseFont (temp1); /* Generador de números aleatorios */ srand ((unsigned int) getpid ()); }
int main(int argc, char *argv[]) { char *argv0 = argv[0]; SDL_Window *window; SDL_Renderer *renderer; TTF_Font *font; SDL_Surface *text; Scene scene; int ptsize; int i, done; SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 }; SDL_Color black = { 0x00, 0x00, 0x00, 0 }; SDL_Color *forecol; SDL_Color *backcol; SDL_Event event; int rendersolid; int renderstyle; int outline; int hinting; int kerning; int dump; enum { RENDER_LATIN1, RENDER_UTF8, RENDER_UNICODE } rendertype; char *message, string[128]; /* Look for special execution mode */ dump = 0; /* Look for special rendering types */ rendersolid = 0; renderstyle = TTF_STYLE_NORMAL; rendertype = RENDER_LATIN1; outline = 0; hinting = TTF_HINTING_NORMAL; kerning = 1; /* Default is black and white */ forecol = &black; backcol = &white; for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) { if ( strcmp(argv[i], "-solid") == 0 ) { rendersolid = 1; } else if ( strcmp(argv[i], "-utf8") == 0 ) { rendertype = RENDER_UTF8; } else if ( strcmp(argv[i], "-unicode") == 0 ) { rendertype = RENDER_UNICODE; } else if ( strcmp(argv[i], "-b") == 0 ) { renderstyle |= TTF_STYLE_BOLD; } else if ( strcmp(argv[i], "-i") == 0 ) { renderstyle |= TTF_STYLE_ITALIC; } else if ( strcmp(argv[i], "-u") == 0 ) { renderstyle |= TTF_STYLE_UNDERLINE; } else if ( strcmp(argv[i], "-s") == 0 ) { renderstyle |= TTF_STYLE_STRIKETHROUGH; } else if ( strcmp(argv[i], "-outline") == 0 ) { if ( sscanf (argv[++i], "%d", &outline) != 1 ) { fprintf(stderr, Usage, argv0); return(1); } } else if ( strcmp(argv[i], "-hintlight") == 0 ) { hinting = TTF_HINTING_LIGHT; } else if ( strcmp(argv[i], "-hintmono") == 0 ) { hinting = TTF_HINTING_MONO; } else if ( strcmp(argv[i], "-hintnone") == 0 ) { hinting = TTF_HINTING_NONE; } else if ( strcmp(argv[i], "-nokerning") == 0 ) { kerning = 0; } else if ( strcmp(argv[i], "-dump") == 0 ) { dump = 1; } else if ( strcmp(argv[i], "-fgcol") == 0 ) { int r, g, b; if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) { fprintf(stderr, Usage, argv0); return(1); } forecol->r = (Uint8)r; forecol->g = (Uint8)g; forecol->b = (Uint8)b; } else if ( strcmp(argv[i], "-bgcol") == 0 ) { int r, g, b; if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) { fprintf(stderr, Usage, argv0); return(1); } backcol->r = (Uint8)r; backcol->g = (Uint8)g; backcol->b = (Uint8)b; } else { fprintf(stderr, Usage, argv0); return(1); } } argv += i; argc -= i; /* Check usage */ if ( ! argv[0] ) { fprintf(stderr, Usage, argv0); return(1); } /* Initialize the TTF library */ if ( TTF_Init() < 0 ) { fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError()); SDL_Quit(); return(2); } /* Open the font file with the requested point size */ ptsize = 0; if ( argc > 1 ) { ptsize = atoi(argv[1]); } if ( ptsize == 0 ) { i = 2; ptsize = DEFAULT_PTSIZE; } else { i = 3; } font = TTF_OpenFont(argv[0], ptsize); if ( font == NULL ) { fprintf(stderr, "Couldn't load %d pt font from %s: %s\n", ptsize, argv[0], SDL_GetError()); cleanup(2); } TTF_SetFontStyle(font, renderstyle); TTF_SetFontOutline(font, outline); TTF_SetFontKerning(font, kerning); TTF_SetFontHinting(font, hinting); if( dump ) { for( i = 48; i < 123; i++ ) { SDL_Surface* glyph = NULL; glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol ); if( glyph ) { char outname[64]; sprintf( outname, "glyph-%d.bmp", i ); SDL_SaveBMP( glyph, outname ); } } cleanup(0); } /* Create a window */ if (SDL_CreateWindowAndRenderer(WIDTH, HEIGHT, 0, &window, &renderer) < 0) { fprintf(stderr, "SDL_CreateWindowAndRenderer() failed: %s\n", SDL_GetError()); cleanup(2); } /* Show which font file we're looking at */ sprintf(string, "Font file: %s", argv[0]); /* possible overflow */ if ( rendersolid ) { text = TTF_RenderText_Solid(font, string, *forecol); } else { text = TTF_RenderText_Shaded(font, string, *forecol, *backcol); } if ( text != NULL ) { scene.captionRect.x = 4; scene.captionRect.y = 4; scene.captionRect.w = text->w; scene.captionRect.h = text->h; scene.caption = SDL_CreateTextureFromSurface(renderer, text); SDL_FreeSurface(text); } /* Render and center the message */ if ( argc > 2 ) { message = argv[2]; } else { message = DEFAULT_TEXT; } switch (rendertype) { case RENDER_LATIN1: if ( rendersolid ) { text = TTF_RenderText_Solid(font,message,*forecol); } else { text = TTF_RenderText_Shaded(font,message,*forecol,*backcol); } break; case RENDER_UTF8: if ( rendersolid ) { text = TTF_RenderUTF8_Solid(font,message,*forecol); } else { text = TTF_RenderUTF8_Shaded(font,message,*forecol,*backcol); } break; case RENDER_UNICODE: { Uint16 *unicode_text = SDL_iconv_utf8_ucs2(message); if ( rendersolid ) { text = TTF_RenderUNICODE_Solid(font, unicode_text, *forecol); } else { text = TTF_RenderUNICODE_Shaded(font, unicode_text, *forecol, *backcol); } SDL_free(unicode_text); } break; default: text = NULL; /* This shouldn't happen */ break; } if ( text == NULL ) { fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError()); TTF_CloseFont(font); cleanup(2); } scene.messageRect.x = (WIDTH - text->w)/2; scene.messageRect.y = (HEIGHT - text->h)/2; scene.messageRect.w = text->w; scene.messageRect.h = text->h; scene.message = SDL_CreateTextureFromSurface(renderer, text); printf("Font is generally %d big, and string is %d big\n", TTF_FontHeight(font), text->h); draw_scene(renderer, &scene); /* Wait for a keystroke, and blit text on mouse press */ done = 0; while ( ! done ) { if ( SDL_WaitEvent(&event) < 0 ) { fprintf(stderr, "SDL_PullEvent() error: %s\n", SDL_GetError()); done = 1; continue; } switch (event.type) { case SDL_MOUSEBUTTONDOWN: scene.messageRect.x = event.button.x - text->w/2; scene.messageRect.y = event.button.y - text->h/2; scene.messageRect.w = text->w; scene.messageRect.h = text->h; draw_scene(renderer, &scene); break; case SDL_KEYDOWN: case SDL_QUIT: done = 1; break; default: break; } } SDL_FreeSurface(text); TTF_CloseFont(font); SDL_DestroyTexture(scene.caption); SDL_DestroyTexture(scene.message); cleanup(0); /* Not reached, but fixes compiler warnings */ return 0; }