bool TextSupervisor::LoadFont(const std::string &filename, const std::string &font_name, uint32 size) { // Make sure that the font name is not already taken if(IsFontValid(font_name) == true) { IF_PRINT_WARNING(VIDEO_DEBUG) << "a font with the desired reference name already existed: " << font_name << std::endl; return false; } if(size == 0) { IF_PRINT_WARNING(VIDEO_DEBUG) << "attempted to load a font of point size zero" << font_name << std::endl; return false; } // Attempt to load the font TTF_Font *font = TTF_OpenFont(filename.c_str(), size); if(font == NULL) { IF_PRINT_WARNING(VIDEO_DEBUG) << "call to TTF_OpenFont() failed to load the font file: " << filename << std::endl; return false; } // Create a new FontProperties object for this font and set all of the properties according to SDL_ttf FontProperties *fp = new FontProperties; fp->ttf_font = font; fp->height = TTF_FontHeight(font); fp->line_skip = TTF_FontLineSkip(font); fp->ascent = TTF_FontAscent(font); fp->descent = TTF_FontDescent(font); // Create the glyph cache for the font and add it to the font map fp->glyph_cache = new std::vector<FontGlyph *>; _font_map[font_name] = fp; return true; } // bool TextSupervisor::LoadFont(...)
Font::Font(const char *aaddress, int alength, int apointSize, int astyle, float afgRed, float afgGreen, float afgBlue, float abgRed, float abgGreen, float abgBlue) : height(), ascent(), descent(), lineSkip(), address( aaddress), length(alength), pointSize(apointSize), style(astyle), fgRed( afgRed), fgGreen(afgGreen), fgBlue(afgBlue), bgRed(abgRed), bgGreen( abgGreen), bgBlue(abgBlue), ttfFont(), foreground(), background() { int i; ttfFont = open_font(address, pointSize); TTF_SetFontStyle(ttfFont, style); foreground.r = (Uint8) (255 * fgRed); foreground.g = (Uint8) (255 * fgGreen); foreground.b = (Uint8) (255 * fgBlue); background.r = (Uint8) (255 * bgRed); background.g = (Uint8) (255 * bgGreen); background.b = (Uint8) (255 * bgBlue); height = TTF_FontHeight(ttfFont); ascent = TTF_FontAscent(ttfFont); descent = TTF_FontDescent(ttfFont); lineSkip = TTF_FontLineSkip(ttfFont); for (i = minGlyph; i <= maxGlyph; i++) { glyphs[i].pic = NULL; glyphs[i].tex = 0; } }
void GlyphFont::InitFont() { mTtfFont = TTF_OpenFont(mFilename, mPointSize); if(mTtfFont == NULL) printf("Can't open font file\n"); // 0 = TTF_STYLE_NORMAL // 1 = TTF_STYLE_BOLD // 2 = TTF_STYLE_ITALIC // 4 = TTF_STYLE_UNDERLINE // 8 = TTF_STYLE_STRIKETHROUGH TTF_SetFontStyle(mTtfFont, mStyle); mColor.r = (Uint8)(mRed * 255); mColor.g = (Uint8)(mGreen * 255); mColor.b = (Uint8)(mBlue * 255); mHeight = TTF_FontHeight(mTtfFont); mAscent = TTF_FontAscent(mTtfFont); mDescent = TTF_FontDescent(mTtfFont); mLineSkip = TTF_FontLineSkip(mTtfFont); for(int i = sMinGlyph; i <= sMaxGlyph; i++) { mGlyphs[i].Surface = NULL; mGlyphs[i].Texture = 0; } }
void Font::InitFont( void ) { Initialized = false; if( TTFont ) TTF_CloseFont( TTFont ); TTFont = TTF_OpenFont( Name.c_str(), PointSize ); if( ! TTFont ) { // FIXME: Use TTF_Error output? fprintf( stderr, "Can't open font file: %s\n", Name.c_str() ); return; } Height = TTF_FontHeight( TTFont ); Ascent = TTF_FontAscent( TTFont ); Descent = TTF_FontDescent( TTFont ); LineSkip = TTF_FontLineSkip( TTFont ); for( int i = 0; i < 256; i ++ ) { Glyphs[ i ].Pic = NULL; Glyphs[ i ].Tex = 0; } LoadedTime.Reset(); Initialized = 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(); }
float CText::GetDescent(FontType font, float size) { assert(font != FONT_BUTTON); CachedFont* cf = GetOrOpenFont(font, size); assert(cf != nullptr); Math::IntPoint wndSize; wndSize.y = TTF_FontDescent(cf->font); Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize); return ifSize.y; }
JNIEXPORT jint JNICALL Java_sdljava_x_swig_SWIG_1SDLTTFJNI_TTF_1FontDescent(JNIEnv *jenv, jclass jcls, jlong jarg1) { jint jresult = 0 ; TTF_Font *arg1 = (TTF_Font *) 0 ; int result; (void)jenv; (void)jcls; arg1 = *(TTF_Font **)&jarg1; result = (int)TTF_FontDescent(arg1); jresult = (jint)result; return jresult; }
KFontProperties::KFontProperties(const TTF_Font *_Font, const KFile *file, int ptSize) : fontPath(file->getAbsolutePath().c_str()), familyName(TTF_FontFaceFamilyName(_Font)), styleName(TTF_FontFaceStyleName(_Font)), ttf_Style(TTF_GetFontStyle(_Font)), height(TTF_FontHeight(_Font)), ascent(TTF_FontAscent(_Font)), descent(TTF_FontDescent(_Font)), lineSkip(TTF_FontLineSkip(_Font)), faces(TTF_FontFaces(_Font)), monospace(TTF_FontFaceIsFixedWidth(_Font)), firstGlyph(getFirstGlyph(_Font)), lastGlyph(getLastGlyph(_Font)), totalGlyphs(getTotalGlyphs(_Font)), glyphRanges(getRanges(_Font)), pointSize(ptSize) { }
// // 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); }
void FontTTF::loadMetrics(TTF_Font *font) { _cellHeight = TTF_FontHeight(font); _cellWidth = 0; int x1, x2, y1, y2, advance; for( int i = 0; i < 256; ++i ) { TTF_GlyphMetrics(font, static_cast<Uint16>(i), &x1, &x2, &y1, &y2, &advance); // Only handle visible characters (>32) and the 'space' character (32). _fontWidth[i] = i >= 32 ? advance : 0; if(_fontWidth[i] > _cellWidth) { _cellWidth = advance; } } // Set a tab to be the width of 4 spaces. _fontWidth[9] = _fontWidth[32] * 4; _fontAscent = TTF_FontAscent(font); _fontDescent = TTF_FontDescent(font); _fontHeight = _fontAscent - _fontDescent; _lineSkip = TTF_FontLineSkip(font); }
int main(int argc, char* argv[]) { if ( argc < 4 ) { fprintf(stderr, "usage: tool_font filename.ttf chars.txt ptsize <style> <supersample>\n"); return -1; } char szFont[256]; strcpy(szFont, argv[1]); *strstr(szFont, ".ttf") = 0; int nFontSize = atol(argv[3]); int nStyle = TTF_STYLE_NORMAL; if ( argc > 3 ) { for ( int i = 0 ; argv[4][i] != 0 ; i++ ) { switch ( argv[4][i] ) { case 'b': nStyle |= TTF_STYLE_BOLD; break; case 'i': nStyle |= TTF_STYLE_ITALIC; break; case 'u': nStyle |= TTF_STYLE_UNDERLINE; break; } } } float fScale = 1.0f; if ( argc > 5 ) { fScale = 1.0f/atof(argv[6]); } SDL_Init(SDL_INIT_VIDEO); TTF_Init(); TTF_Font* pFont = TTF_OpenFont(argv[1], nFontSize/fScale); if ( !pFont ) { fprintf(stderr, "could not open %s @ %d points\n", argv[1], nFontSize); return -1; } int nAscent = TTF_FontAscent(pFont); int nDescent = TTF_FontDescent(pFont); int nHeight = TTF_FontHeight(pFont); char szStyle[4] = { 0 }; char* pchStyle = szStyle; if ( nStyle & TTF_STYLE_BOLD ) *pchStyle++ = 'b'; if ( nStyle & TTF_STYLE_ITALIC ) *pchStyle++ = 'i'; if ( nStyle & TTF_STYLE_UNDERLINE ) *pchStyle++ = 'u'; TTF_SetFontStyle(pFont, nStyle); char achGlyphs[1024]; int cGlyphs = 0; FILE* fpChars = fopen(argv[2], "r"); while ( EOF != (achGlyphs[cGlyphs++] = fgetc(fpChars)) ); fclose(fpChars); cGlyphs--; SDL_Rect* aRects = new SDL_Rect[cGlyphs]; SDL_Surface** apSurfaces = new SDL_Surface*[cGlyphs]; for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { SDL_Color color = { 255, 255, 255, 0 }; char szGlyph[2] = { 0 }; szGlyph[0] = achGlyphs[iGlyph]; apSurfaces[iGlyph] = TTF_RenderText_Blended(pFont, szGlyph, color); // char szFile[128]; // sprintf(szFile, "textures/fonts/%s/%d.raw", argv[1], szGlyph[0]); // FILE* fp = fopen(szFile, "wb"); // fwrite(apSurfaces[iGlyph]->pixels, apSurfaces[iGlyph]->pitch*apSurfaces[iGlyph]->h, 1, fp); // fclose(fp); } struct DIMS { int w, h; }; DIMS aDims[] = { 64, 64, 64, 128, 64, 256, 128, 64, 128, 128, 128, 256, 256, 64, 256, 128, 256, 256, 64, 512, 128, 512, 256, 512, 512, 64, 512, 128, 512, 256, 512, 512, 64, 1024, 128, 1024, 256, 1024, 256, 1024, 512, 1024, 1024, 64, 1024, 128, 1024, 256, 1024, 512, 1024, 1024, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048, 2048, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048, 2048, /* 512, 64, 512, 128, 512, 256, 512, 512, 64, 512, 128, 512, 256, 512, 1024, 64, 1024, 128, 1024, 256, 1024, 512, 64, 1024, 128, 1024, 256, 1024, 512, 1024, 2048, 64, 2048, 128, 2048, 256, 2048, 1024, 2048, 2048, 64, 2048, 128, 2048, 256, 2048, 512, 2048, 1024, 2048 */ }; int cDims = sizeof(aDims)/sizeof(DIMS); for ( int iDims = 0 ; iDims < cDims ; ++iDims ) { int nWidth = aDims[iDims].w; int nHeight = aDims[iDims].h; SDL_Surface* pSurfaceGeneric = SDL_CreateRGBSurface(SDL_SWSURFACE, nWidth, nHeight, 32, 0, 0, 0, 0); SDL_Surface* pSurface = SDL_ConvertSurface(pSurfaceGeneric, apSurfaces[0]->format, 0); SDL_FillRect(pSurface, NULL, SDL_MapRGBA(pSurface->format, 0,0,0,0)); bool* aabyUsage = new bool[nHeight*nWidth]; memset(aabyUsage, 0, nHeight*nWidth*sizeof(bool)); bool bFit = true; for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { if ( !Fit(aabyUsage, pSurface, apSurfaces[iGlyph], &aRects[iGlyph], fScale) ) { bFit = false; break; } } if ( bFit ) { fprintf(stderr, "glyphs fit into %d x %d texture\n", nWidth, nHeight); char szFile[256]; sprintf(szFile, "textures/fonts/%s%d%s.png", szFont, nFontSize, szStyle); for ( int y = 0 ; y < pSurface->h ; ++y ) { for ( int x = 0 ; x < pSurface->w ; ++x ) { unsigned char r = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0]; unsigned char g = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1]; unsigned char b = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2]; unsigned char a = (r+g+b)/3; r = g = b = 255; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0] = r; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1] = g; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2] = b; ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 3] = a; } } ILuint iImage = 0; ilInit(); ilGenImages(1, &iImage); ilBindImage(iImage); ilTexImage(pSurface->w, pSurface->h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pSurface->pixels); // ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE); iluFlipImage(); iluImageParameter(ILU_FILTER, ILU_SCALE_LANCZOS3); iluScale(pSurface->w*fScale, pSurface->h*fScale, 1); ilSaveImage(szFile); int nDescent = TTF_FontDescent(pFont); char szFontFile[256]; sprintf(szFontFile, "fonts/%s%d%s.font", szFont, nFontSize, szStyle); FILE* fp = fopen(szFontFile, "w"); fprintf(fp, "<font name=\"%s\" height=\"%d\" lineskip=\"%d\" shader=\"%s,srcalpha,invsrcalpha\">\n", szFont, int(TTF_FontHeight(pFont)*fScale), int(TTF_FontLineSkip(pFont)*fScale), szFile); for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph ) { int xmin, xmax, ymin, ymax, adv; TTF_GlyphMetrics(pFont, achGlyphs[iGlyph], &xmin, &xmax, &ymin, &ymax, &adv); fprintf(fp, "%c<glyph ascii=\"%d\" adv=\"%d\" dims=\"%d,%d\" origin=\"%d,%d\" u0=\"%f\" v0=\"%f\" u1=\"%f\" v1=\"%f\"/>\n", 9, achGlyphs[iGlyph], int(adv*fScale), int(aRects[iGlyph].w*fScale), int(aRects[iGlyph].h*fScale), int(xmin*fScale), int(-nDescent*fScale), float(aRects[iGlyph].x)/float(pSurface->w), float(aRects[iGlyph].y)/float(pSurface->h), float(aRects[iGlyph].x+aRects[iGlyph].w)/float(pSurface->w), float(aRects[iGlyph].y+aRects[iGlyph].h)/float(pSurface->h)); } fprintf(fp, "</font>\n"); fclose(fp); // FILE* fp = fopen("textures/fonts/blockup.raw", "wb"); // fwrite(pSurface->pixels, pSurface->pitch*pSurface->h, 1, fp); // fclose(fp); return 0; } delete [] aabyUsage; SDL_FreeSurface(pSurface); SDL_FreeSurface(pSurfaceGeneric); } return 0; }
static PyObject* font_get_descent (PyObject* self) { TTF_Font* font = PyFont_AsFont (self); return PyInt_FromLong (TTF_FontDescent (font)); }
int LOBJECT_METHOD(getFontDescent, TTF_Font * font){ int result = TTF_FontDescent(font); state.push_integer(result); return 1; }
double MLIFont::GetLineDescent() { EnsureUIThread(); CheckScale(); return (double)TTF_FontDescent(pTtfFont) / GetFontScale(); }
/* * create_font */ int create_font(char *filename, FONT **font, int size, int style, SDL_Color color) { TTF_Font* ttffont; SDL_Surface* character_surface; int ret_code = BUILD_FONT_OK; int rc; Uint16 ii; /* * Allocate the memory required for the font object. */ (*font) = (FONT *) DT_MALLOC(sizeof(FONT)); /* * Set the font attributes. */ memcpy(&((*font)->color), &color, sizeof(SDL_Color)); (*font)->pointsize = size; (*font)->style = style; /* * The font loading may fail if the file does not exist or permissions are * incorrect etc. */ ttffont = TTF_OpenFont(filename, (*font)->pointsize); if (ttffont == NULL) { DT_DEBUG_LOG("Error opening font (%s): %s\n", filename, TTF_GetError()); ret_code = BUILD_FONT_LOAD_FAIL; goto EXIT_LABEL; } /* * Set the style of the font to whatever we passed in. */ TTF_SetFontStyle(ttffont, (*font)->style); /* * Retrieve the font information to store in our font structure. */ (*font)->ascent = TTF_FontAscent(ttffont); (*font)->descent = TTF_FontDescent(ttffont); (*font)->height = TTF_FontHeight(ttffont); (*font)->lineskip = TTF_FontLineSkip(ttffont); /* * For each possible glyph, attempt to load the font character and create a * texture for it. If any of these fail we attempt to close down gracefully * and exit the function. */ for (ii = ' '; ii <= '~'; ii++) { character_surface = TTF_RenderGlyph_Blended(ttffont, ii, (*font)->color); if (NULL == character_surface) { DT_DEBUG_LOG("Error rendering glyph %c whilst creating font (%s): %s\n", (char) ii, filename, TTF_GetError()); ret_code = BUILD_FONT_RENDER_FAIL; goto EXIT_LABEL; } /* * Retrieve the metric info from the font object and store it in our local * structure. */ TTF_GlyphMetrics(ttffont, ii, &((*font)->glyphs[ii].minx), &((*font)->glyphs[ii].maxx), &((*font)->glyphs[ii].miny), &((*font)->glyphs[ii].maxy), &((*font)->glyphs[ii].advance)); /* * This function can fail if opengl cannot allocate any more memory for * textures. */ rc = SDL_GL_LoadTexture(character_surface, &((*font)->glyphs[ii].texid), false); if (LOAD_TEXTURE_OK != rc) { DT_DEBUG_LOG("Failed creating texture for glyph %c from font %s\n", (char) ii, TTF_GetError()); SDL_FreeSurface(character_surface); ret_code = BUILD_FONT_CREATE_TEXTURE_FAIL; goto EXIT_LABEL; } /* * Set the texture coordinates for the glyph (note this is the same for all * glyphs). */ (*font)->glyphs[ii].texcoord[0] = 0.0f; (*font)->glyphs[ii].texcoord[1] = 0.0f; (*font)->glyphs[ii].texcoord[2] = 1.0f; (*font)->glyphs[ii].texcoord[3] = 1.0f; /* * The surface used for that character is no longer required. */ SDL_FreeSurface(character_surface); } EXIT_LABEL: if (NULL != ttffont) { TTF_CloseFont(ttffont); } return ret_code; }
int SDLFont::getDescent() { return TTF_FontDescent(this->fontContext); }
void SimKit::TTFVFont::get_font_metrics(int *out_height, int *out_ascent, int *out_descent, int *out_skip) { if (out_height) *out_height = TTF_FontHeight(this->rfont); if (out_ascent) *out_ascent = TTF_FontAscent(this->rfont); if (out_descent) *out_descent = TTF_FontDescent(this->rfont); if (out_skip) *out_skip = TTF_FontLineSkip(this->rfont); };
XFontStruct* XLoadQueryFont(Display* display, _Xconst char* name) { // https://tronche.com/gui/x/xlib/graphics/font-metrics/XLoadQueryFont.html Font fontId = XLoadFont(display, name); if (fontId == None) { return NULL; } TTF_Font* font = GET_FONT(fontId); SET_X_SERVER_REQUEST(display, X_QueryFont); XFontStruct* fontStruct = malloc(sizeof(XFontStruct)); if (fontStruct == NULL) { handleOutOfMemory(0, display, 0, 0); TTF_CloseFont(font); return NULL; } fontStruct->fid = fontId; fontStruct->ascent = TTF_FontAscent(font); fontStruct->descent = abs(TTF_FontDescent(font)); fontStruct->per_char = NULL; unsigned int numChars = 0; unsigned int i; for (i = 0; i < 65536 /* 2^16 */; i++) { if (TTF_GlyphIsProvided(font, (Uint16) i)) { if (numChars == 0) { fontStruct->min_char_or_byte2 = i; } fontStruct->max_char_or_byte2 = i; numChars++; } } // if (numChars >= 256) { // fontStruct->min_byte1 = fontStruct->min_char_or_byte2 / 256; // fontStruct->max_byte1 = fontStruct->max_char_or_byte2 / 256; // fontStruct->min_char_or_byte2 = 0; // } else { fontStruct->min_byte1 = 0; fontStruct->max_byte1 = 0; // } // TODO: This is debugging fontStruct->max_char_or_byte2 = 255; // Build per_char int monospace = TTF_FontFaceIsFixedWidth(font); XCharStruct charStruct; if (!monospace) { fontStruct->per_char = malloc(sizeof(XCharStruct) * numChars); if (fontStruct->per_char == NULL) { handleOutOfMemory(0, display, 0, 0); XFreeFont(display, fontStruct); return NULL; } charStruct = fontStruct->per_char[0]; } if (fillXCharStruct(font, fontStruct->min_char_or_byte2, &charStruct) == False) { XFreeFont(display, fontStruct); return NULL; } fontStruct->max_bounds = charStruct; fontStruct->min_bounds = charStruct; if (monospace) { fontStruct->per_char = NULL; } else { int counter = 1; for (i = fontStruct->min_char_or_byte2 + 1; i < 65536 /* 2^16 */; ++i) { if (TTF_GlyphIsProvided(font, (Uint16) i)) { charStruct = fontStruct->per_char[counter]; if (fillXCharStruct(font, i, &charStruct) == False) { XFreeFont(display, fontStruct); return NULL; } // I think rbearing (aka. advance) is the value that matters here if (fontStruct->max_bounds.rbearing < charStruct.rbearing) { fontStruct->max_bounds = charStruct; } else if (fontStruct->min_bounds.rbearing > charStruct.rbearing) { fontStruct->max_bounds = charStruct; } counter++; } } } return fontStruct; }
static mrb_value mrb_sdl2_ttf_font_get_descent(mrb_state *mrb, mrb_value self) { return mrb_fixnum_value(TTF_FontDescent(mrb_sdl2_font_get_ptr(mrb, self))); }