TT_Error ConvertRaster( int index ) { outlines[index].second_pass = 0; outlines[index].high_precision = 0; if ( gray_render ) return TT_Get_Outline_Pixmap( engine, &outlines[index], &Bit ); else return TT_Get_Outline_Bitmap( engine, &outlines[index], &Bit ); }
static TT_Error Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph) { TT_UShort index; TT_Glyph_Metrics metrics; TT_Outline outline; int x_offset; int y_offset; TT_Error error; /* Load the glyph */ index = TT_Char_Index(font->map, UNICODE(ch)); error = TT_Load_Glyph(font->inst, font->glyph, index, TTLOAD_DEFAULT); if ( error ) return error; /* Get the bounding box */ TT_Get_Glyph_Metrics(font->glyph, &metrics); glyph->minx = (metrics.bbox.xMin & -64) / 64; glyph->maxx = ((metrics.bbox.xMax + 63) & -64) / 64; glyph->miny = (metrics.bbox.yMin & -64) / 64; glyph->maxy = ((metrics.bbox.yMax + 63) & -64) / 64; glyph->advance = (metrics.advance & -64) / 64; /* Adjust for bold and italic text */ if ( font->style & TTF_STYLE_BOLD ) { glyph->maxx += font->glyph_overhang; } if ( font->style & TTF_STYLE_ITALIC ) { glyph->maxx += round(font->glyph_italics); } /* Get the bitmap memory */ glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7; glyph->bitmap.rows = font->height; glyph->bitmap.cols = glyph->bitmap.width/8; glyph->bitmap.flow = TT_Flow_Down; glyph->bitmap.size = (glyph->bitmap.rows * glyph->bitmap.cols); if ( glyph->bitmap.size ) { glyph->bitmap.bitmap = malloc(glyph->bitmap.size); if ( ! glyph->bitmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->bitmap.bitmap, 0, glyph->bitmap.size); } else { glyph->bitmap.bitmap = 0; } /* Get the pixmap memory */ glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3; glyph->pixmap.rows = font->height; glyph->pixmap.cols = glyph->pixmap.width; glyph->pixmap.flow = TT_Flow_Down; glyph->pixmap.size = (glyph->pixmap.rows * glyph->pixmap.cols); if ( glyph->pixmap.size ) { glyph->pixmap.bitmap = malloc(glyph->pixmap.size); if ( ! glyph->pixmap.bitmap ) { error = TT_Err_Out_Of_Memory; goto was_error; } memset(glyph->pixmap.bitmap, 0, glyph->pixmap.size); } else { glyph->pixmap.bitmap = 0; } /* Render the glyph into the bitmap and pixmap */ error = TT_Get_Glyph_Outline(font->glyph, &outline); /* Handle the italic style */ if ( font->style & TTF_STYLE_ITALIC ) { TT_Matrix shear; shear.xx = 1<<16; shear.xy = (int)(font->glyph_italics*(1<<16))/font->height; shear.yx = 0; shear.yy = 1<<16; TT_Transform_Outline(&outline, &shear); } x_offset = -glyph->minx * 64; y_offset = -round(font->descent) * 64; TT_Translate_Outline(&outline, x_offset, y_offset); error += TT_Get_Outline_Bitmap(engine, &outline, &glyph->bitmap); error += TT_Get_Outline_Pixmap(engine, &outline, &glyph->pixmap); /* Handle the bold style */ if ( font->style & TTF_STYLE_BOLD ) { int row, col; int offset; int pixel; Uint8 *pixmap; /* The bitmap is easy, just render another copy */ for ( offset=0; offset < font->glyph_overhang; ++offset ) { TT_Translate_Outline(&outline, 64, 0); error += TT_Get_Outline_Bitmap(engine, &outline,&glyph->bitmap); } x_offset += font->glyph_overhang*64; /* The pixmap is a little harder, we have to add and clamp */ for ( row=glyph->pixmap.rows-1; row >= 0; --row ) { pixmap = (Uint8 *)glyph->pixmap.bitmap + row*glyph->pixmap.cols; for (offset=1; offset<=font->glyph_overhang; ++offset) { for (col=glyph->pixmap.cols-1; col > 0; --col) { pixel=(pixmap[col]+pixmap[col-1]); if ( pixel > 4 ) { pixel = 4; } pixmap[col] = (Uint8)pixel; } } } } TT_Translate_Outline(&outline, -x_offset, -y_offset); was_error: if ( error ) { if ( glyph->bitmap.bitmap ) { free(glyph->bitmap.bitmap); glyph->bitmap.bitmap = 0; } if ( glyph->pixmap.bitmap ) { free(glyph->pixmap.bitmap); glyph->pixmap.bitmap = 0; } return error; } /* We're done, mark this glyph cached */ glyph->cached = ch; return TT_Err_Ok; }