30 #include "../idlib/precompiled.h"
36 #include "../ft2/fterrors.h"
37 #include "../ft2/ftsystem.h"
38 #include "../ft2/ftimage.h"
39 #include "../ft2/freetype.h"
40 #include "../ft2/ftoutln.h"
42 #define _FLOOR(x) ((x) & -64)
43 #define _CEIL(x) (((x)+63) & -64)
44 #define _TRUNC(x) ((x) >> 6)
46 FT_Library ftLibrary =
NULL;
57 void R_GetGlyphInfo(FT_GlyphSlot glyph,
int *left,
int *
right,
int *
width,
int *
top,
int *
bottom,
int *
height,
int *pitch) {
59 *left = _FLOOR( glyph->metrics.horiBearingX );
60 *right = _CEIL( glyph->metrics.horiBearingX + glyph->metrics.width );
61 *width = _TRUNC(*right - *left);
63 *top = _CEIL( glyph->metrics.horiBearingY );
64 *bottom = _FLOOR( glyph->metrics.horiBearingY - glyph->metrics.height );
65 *height = _TRUNC( *top - *bottom );
66 *pitch = ( qtrue ? (*width+3) & -4 : (*width+7) >> 3 );
74 FT_Bitmap *R_RenderGlyph(FT_GlyphSlot glyph,
glyphInfo_t* glyphOut) {
78 R_GetGlyphInfo(glyph, &left, &right, &width, &top, &bottom, &height, &pitch);
80 if ( glyph->format == ft_glyph_format_outline ) {
88 bit2->pixel_mode = ft_pixel_mode_grays;
91 bit2->num_grays = 256;
93 memset( bit2->buffer, 0, size );
95 FT_Outline_Translate( &glyph->outline, -left, -bottom );
97 FT_Outline_Get_Bitmap( ftLibrary, &glyph->outline, bit2 );
100 glyphOut->
pitch = pitch;
101 glyphOut->
top = (glyph->metrics.horiBearingY >> 6) + 1;
107 common->
Printf(
"Non-outline fonts are not supported\n" );
117 glyphInfo_t *RE_ConstructGlyphInfo(
unsigned char *imageOut,
int *xOut,
int *yOut,
int *maxHeight, FT_Face face,
const unsigned char c, qboolean calcHeight ) {
121 float scaled_width, scaled_height;
127 FT_Load_Glyph(face, FT_Get_Char_Index( face, c), FT_LOAD_DEFAULT );
128 bitmap = R_RenderGlyph(face->glyph, &glyph);
130 glyph.
xSkip = (face->glyph->metrics.horiAdvance >> 6) + 1;
135 if (glyph.
height > *maxHeight) {
136 *maxHeight = glyph.
height;
154 scaled_width = glyph.
pitch;
155 scaled_height = glyph.
height;
158 if (*xOut + scaled_width + 1 >= 255) {
159 if (*yOut + *maxHeight + 1 >= 255) {
167 *yOut += *maxHeight + 1;
169 }
else if (*yOut + *maxHeight + 1 >= 255) {
177 src = bitmap->buffer;
178 dst = imageOut + (*yOut * 256) + *xOut;
180 if (bitmap->pixel_mode == ft_pixel_mode_mono) {
181 for (i = 0; i < glyph.
height; i++) {
183 unsigned char *_src =
src;
184 unsigned char *_dst =
dst;
185 unsigned char mask = 0x80;
186 unsigned char val = *_src;
187 for (j = 0; j < glyph.
pitch; j++) {
207 for (i = 0; i < glyph.
height; i++) {
208 memcpy( dst, src, glyph.
pitch );
219 glyph.
s = (
float)*xOut / 256;
220 glyph.
t = (
float)*yOut / 256;
221 glyph.
s2 = glyph.
s + (
float)scaled_width / 256;
222 glyph.
t2 = glyph.
t + (
float)scaled_height / 256;
224 *xOut += scaled_width + 1;
244 int i = fdFile[fdOffset]+(fdFile[fdOffset+1]<<8)+(fdFile[fdOffset+2]<<16)+(fdFile[fdOffset+3]<<24);
262 me.
fred[0] = fdFile[fdOffset+3];
263 me.
fred[1] = fdFile[fdOffset+2];
264 me.
fred[2] = fdFile[fdOffset+1];
265 me.
fred[3] = fdFile[fdOffset+0];
267 me.
fred[0] = fdFile[fdOffset+0];
268 me.
fred[1] = fdFile[fdOffset+1];
269 me.
fred[2] = fdFile[fdOffset+2];
270 me.
fred[3] = fdFile[fdOffset+3];
284 #ifdef BUILD_FREETYPE
286 int j, k, xOut, yOut, lastStart, imageNumber;
287 int scaledSize, newSize, maxHeight, left, satLevels;
288 unsigned char *out, *imageBuff;
296 int i,
len, fontCount;
316 memset( &font, 0,
sizeof( font ) );
318 for ( fontCount = 0; fontCount < 3; fontCount++ ) {
320 if ( fontCount == 0) {
322 }
else if ( fontCount == 1 ) {
328 float glyphScale = 1.0f;
329 glyphScale *= 48.0f / pointSize;
331 idStr::snPrintf( name,
sizeof(name),
"%s/fontImage_%i.dat", fontName, pointSize );
334 if ( fontCount == 0 ) {
337 else if ( fontCount == 1 ) {
348 common->
Warning(
"RegisterFont: couldn't find font: '%s'", name );
354 fdFile =
reinterpret_cast<unsigned char*
>(faceData);
380 if (mh < outFont->glyphs[i].height) {
383 if (mw < outFont->glyphs[i].xSkip) {
387 if (fontCount == 0) {
390 }
else if (fontCount == 1) {
404 #ifndef BUILD_FREETYPE
405 common->
Warning(
"RegisterFont: couldn't load FreeType code %s", name );
408 if (ftLibrary ==
NULL) {
409 common->
Warning(
"RegisterFont: FreeType not initialized." );
420 if ( FT_New_Memory_Face( ftLibrary, faceData, len, 0, &face ) ) {
421 common->
Warning(
"RegisterFont: FreeType2, unable to allocate new face." );
426 if ( FT_Set_Char_Size( face, pointSize << 6, pointSize << 6, dpi, dpi) ) {
427 common->
Warning(
"RegisterFont: FreeType2, Unable to set face char size." );
438 common->
Warning(
"RegisterFont: Mem_Alloc failure during output image creation." );
441 memset( out, 0, 1024*1024 );
446 glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (
unsigned char)i, qtrue);
455 while ( i <= GLYPH_END ) {
457 glyph = RE_ConstructGlyphInfo(out, &xOut, &yOut, &maxHeight, face, (
unsigned char)i, qfalse);
459 if (xOut == -1 || yOut == -1 || i == GLYPH_END) {
464 scaledSize = 256*256;
465 newSize = scaledSize * 4;
470 for ( k = 0; k < (scaledSize) ; k++ ) {
480 for ( k = 0; k < (scaledSize) ; k++ ) {
481 imageBuff[left++] = 255;
482 imageBuff[left++] = 255;
483 imageBuff[left++] = 255;
484 imageBuff[left++] = ((
float)out[k] * max);
487 idStr::snprintf( name,
sizeof(name),
"fonts/fontImage_%i_%i.tga", imageNumber++, pointSize );
488 if (r_saveFontData->integer) {
493 image = R_CreateImage(name, imageBuff, 256, 256, qfalse, qfalse, GL_CLAMP);
494 h = RE_RegisterShaderFromImage(name, LIGHTMAP_2D, image, qfalse);
495 for (j = lastStart; j <
i; j++) {
496 font.glyphs[
j].glyph = h;
497 idStr::Copynz( font.glyphs[j].shaderName, name,
sizeof( font.glyphs[j].shaderName ) );
500 memset( out, 0, 1024*1024 );
506 memcpy( &font.glyphs[i], glyph,
sizeof(
glyphInfo_t ) );
511 registeredFont[registeredFontCount].glyphScale = glyphScale;
512 font.glyphScale = glyphScale;
513 memcpy( ®isteredFont[registeredFontCount++], &font,
sizeof(
fontInfo_t ) );
515 if ( r_saveFontData->integer ) {
532 #ifdef BUILD_FREETYPE
533 if ( FT_Init_FreeType( &ftLibrary ) ) {
534 common->
Printf(
"R_InitFreeType: Unable to initialize FreeType.\n" );
546 #ifdef BUILD_FREETYPE
548 FT_Done_FreeType( ftLibrary );
static int snPrintf(char *dest, int size, const char *fmt,...) id_attribute((format(printf
glyphInfo_t glyphs[GLYPHS_PER_FONT]
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
idFileSystem * fileSystem
GLenum GLsizei GLenum GLenum const GLvoid * image
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
void R_DoneFreeType(void)
virtual void FreeFile(void *buffer)=0
fontInfo_t fontInfoMedium
virtual int WriteFile(const char *relativePath, const void *buffer, int size, const char *basePath="fs_savepath")=0
GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte * bitmap
virtual bool RegisterFont(const char *fontName, fontInfoEx_t &font)
static void Copynz(char *dest, const char *src, int destsize)
void R_WriteTGA(const char *filename, const byte *data, int width, int height, bool flipVertical=false)
virtual void Printf(const char *fmt,...) id_attribute((format(printf
GLenum GLsizei GLsizei height
GLdouble GLdouble GLdouble top
idDeclManager * declManager
void R_InitFreeType(void)
const int GLYPHS_PER_FONT
void SetSort(float s) const
void * Mem_Alloc(const int size)
char * va(const char *fmt,...)
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf