first commit

This commit is contained in:
Your Name
2022-10-20 20:29:11 +08:00
commit 4d531f8044
3238 changed files with 1387862 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
set (FNT_SOURCES
fnt.cxx
fntTXF.cxx
fntBitmap.cxx
)
add_library(PLIBFont STATIC ${FNT_SOURCES})
target_link_libraries(PLIBFont SimGearCore )
# we use <osg/GL> in fnt.h, so we need to use it
target_include_directories(PLIBFont PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${OPENSCENEGRAPH_INCLUDE_DIRS})
target_include_directories(PLIBFont PRIVATE ${PLIB_INCLUDE_DIR})
+2
View File
@@ -0,0 +1,2 @@
This is PLIB's 'fnt' library, extracted and modified
- added UTF8 path support, especially for Windows
+257
View File
@@ -0,0 +1,257 @@
/*
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For further information visit http://plib.sourceforge.net
$Id: fnt.cxx 1939 2004-08-05 00:41:53Z puggles $
*/
#include "fntLocal.h"
#include <simgear/misc/sg_path.hxx>
#include <simgear/debug/logstream.hxx>
fntFont:: fntFont () {}
fntFont::~fntFont () {}
int fntTexFont::load ( const SGPath& path, GLenum mag, GLenum min )
{
if (path.extension() == "txf") {
return loadTXF ( path, mag, min ) ;
} else {
const auto ps = path.utf8Str();
fntSetError ( SG_WARN,
"fnt::load: Error - Unrecognised file format for '%s'", ps.c_str() ) ;
return FNT_FALSE ;
}
}
float fntTexFont::low_putch ( sgVec3 curpos, float pointsize,
float italic, char c )
{
unsigned int cc = (unsigned char) c ;
/* Auto case-convert if character is absent from font. */
if ( ! exists [ cc ] )
{
if ( cc >= 'A' && cc <= 'Z' )
cc = cc - 'A' + 'a' ;
else
if ( cc >= 'a' && cc <= 'z' )
cc = cc - 'a' + 'A' ;
if ( cc == ' ' )
{
curpos [ 0 ] += pointsize / 2.0f ;
return pointsize / 2.0f ;
}
}
/*
We might want to consider making some absent characters from
others (if they exist): lowercase 'l' could be made into digit '1'
or letter 'O' into digit '0'...or vice versa. We could also
make 'b', 'd', 'p' and 'q' by mirror-imaging - this would
save a little more texture memory in some fonts.
*/
if ( ! exists [ cc ] )
return 0.0f ;
glBegin ( GL_TRIANGLE_STRIP ) ;
glTexCoord2f ( t_left [cc], t_bot[cc] ) ;
glVertex3f ( curpos[0] + v_left [cc] * pointsize,
curpos[1] + v_bot [cc] * pointsize,
curpos[2] ) ;
glTexCoord2f ( t_left [cc], t_top[cc] ) ;
glVertex3f ( curpos[0] + (italic + v_left [cc]) * pointsize,
curpos[1] + v_top [cc] * pointsize,
curpos[2] ) ;
glTexCoord2f ( t_right[cc], t_bot[cc] ) ;
glVertex3f ( curpos[0] + v_right[cc] * pointsize,
curpos[1] + v_bot [cc] * pointsize,
curpos[2] ) ;
glTexCoord2f ( t_right[cc], t_top[cc] ) ;
glVertex3f ( curpos[0] + (italic + v_right[cc]) * pointsize,
curpos[1] + v_top [cc] * pointsize,
curpos[2] ) ;
glEnd () ;
float ww = ( gap + ( fixed_pitch ? width : widths[cc] ) ) * pointsize ;
curpos[0] += ww ;
return ww ;
}
void fntTexFont::setGlyph ( char c, float wid,
float tex_left, float tex_right,
float tex_bot , float tex_top ,
float vtx_left, float vtx_right,
float vtx_bot , float vtx_top )
{
unsigned int cc = (unsigned char) c ;
exists[cc] = FNT_TRUE ;
widths[cc] = wid;
t_left[cc] = tex_left ; t_right[cc] = tex_right ;
t_bot [cc] = tex_bot ; t_top [cc] = tex_top ;
v_left[cc] = vtx_left ; v_right[cc] = vtx_right ;
v_bot [cc] = vtx_bot ; v_top [cc] = vtx_top ;
}
int fntTexFont::getGlyph ( char c, float* wid,
float *tex_left, float *tex_right,
float *tex_bot , float *tex_top ,
float *vtx_left, float *vtx_right,
float *vtx_bot , float *vtx_top )
{
unsigned int cc = (unsigned char) c ;
if ( ! exists[cc] ) return FNT_FALSE ;
if ( wid != NULL ) *wid = widths [cc] ;
if ( tex_left != NULL ) *tex_left = t_left [cc] ;
if ( tex_right != NULL ) *tex_right = t_right[cc] ;
if ( tex_bot != NULL ) *tex_bot = t_bot [cc] ;
if ( tex_top != NULL ) *tex_top = t_top [cc] ;
if ( vtx_left != NULL ) *vtx_left = v_left [cc] ;
if ( vtx_right != NULL ) *vtx_right = v_right[cc] ;
if ( vtx_bot != NULL ) *vtx_bot = v_bot [cc] ;
if ( vtx_top != NULL ) *vtx_top = v_top [cc] ;
return FNT_TRUE ;
}
void fntTexFont::getBBox ( const char *s,
float pointsize, float italic,
float *left, float *right,
float *bot , float *top )
{
float h_pos = 0.0f ;
float v_pos = 0.0f ;
float l, r, b, t ;
l = r = b = t = 0.0f ;
while ( *s != '\0' )
{
if ( *s == '\n' )
{
h_pos = 0.0f ;
v_pos -= 1.333f ;
s++ ;
continue ;
}
unsigned int cc = (unsigned char) *(s++) ;
if ( ! exists [ cc ] )
{
if ( cc >= 'A' && cc <= 'Z' )
cc = cc - 'A' + 'a' ;
else
if ( cc >= 'a' && cc <= 'z' )
cc = cc - 'a' + 'A' ;
if ( cc == ' ' )
{
r += 0.5f ;
h_pos += 0.5f ;
continue ;
}
}
if ( ! exists [ cc ] )
continue ;
if ( italic >= 0 )
{
if ( l > h_pos + v_left [cc] ) l = h_pos + v_left [cc] ;
if ( r < gap + h_pos + v_right[cc]+italic ) r = gap + h_pos + v_right[cc] + italic ;
}
else
{
if ( l > h_pos + v_left [cc]+italic ) l = h_pos + v_left [cc] + italic ;
if ( r < gap + h_pos + v_right[cc] ) r = gap + h_pos + v_right[cc] ;
}
if ( b > v_pos + v_bot [cc] ) b = v_pos + v_bot [cc] ;
if ( t < v_pos + v_top [cc] ) t = v_pos + v_top [cc] ;
h_pos += gap + ( fixed_pitch ? width : widths[cc] ) ;
}
if ( left != NULL ) *left = l * pointsize ;
if ( right != NULL ) *right = r * pointsize ;
if ( top != NULL ) *top = t * pointsize ;
if ( bot != NULL ) *bot = b * pointsize ;
}
void fntTexFont::puts ( sgVec3 curpos, float pointsize, float italic, const char *s )
{
SGfloat origx = curpos[0] ;
if ( ! bound )
bind_texture () ;
while ( *s != '\0' )
{
if (*s == '\n')
{
curpos[0] = origx ;
curpos[1] -= pointsize ;
}
else
low_putch ( curpos, pointsize, italic, *s ) ;
s++ ;
}
}
void fntInit ()
{
/* Empty right now */
}
void fntSetError(int level, const char* format, ...)
{
const int bufferLength = 2048;
char buffer[2048];
va_list args;
va_start (args, format);
vsnprintf(buffer,bufferLength,format, args);
va_end (args);
SG_LOG(SG_GUI, static_cast<sgDebugPriority>(level), buffer);
}
+357
View File
@@ -0,0 +1,357 @@
/*
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For further information visit http://plib.sourceforge.net
$Id: fnt.h 1923 2004-04-06 12:53:17Z sjbaker $
*/
#ifndef _FNT_H_
#define _FNT_H_ 1
#include <stdio.h>
#include <plib/sg.h>
#include <osg/GL>
#define FNTMAX_CHAR 256
#define FNT_TRUE 1
#define FNT_FALSE 0
class SGPath;
class fntFont
{
public:
fntFont () ;
virtual ~fntFont () ;
virtual void getBBox ( const char *s, float pointsize, float italic,
float *left, float *right,
float *bot , float *top ) = 0 ;
virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) = 0 ;
virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) = 0 ;
virtual void begin () = 0 ;
virtual void end () = 0 ;
virtual int load ( const SGPath& fname, GLenum mag = GL_NEAREST,
GLenum min = GL_LINEAR_MIPMAP_LINEAR ) = 0 ;
virtual void setFixedPitch ( int fix ) = 0 ;
virtual int isFixedPitch () const = 0 ;
virtual void setWidth ( float w ) = 0 ;
virtual void setGap ( float g ) = 0 ;
virtual float getWidth () const = 0 ;
virtual float getGap () const = 0 ;
virtual int hasGlyph ( char c ) const = 0 ;
} ;
class fntTexFont : public fntFont
{
private:
GLuint texture ;
int bound ;
int fixed_pitch ;
float width ; /* The width of a character in fixed-width mode */
float gap ; /* Set the gap between characters */
int exists [ FNTMAX_CHAR ] ; /* TRUE if character exists in tex-map */
/*
The quadrilaterals that describe the characters
in the font are drawn with the following texture
and spatial coordinates. The texture coordinates
are in (S,T) space, with (0,0) at the bottom left
of the image and (1,1) at the top-right.
The spatial coordinates are relative to the current
'cursor' position. They should be scaled such that
1.0 represent the height of a capital letter. Hence,
characters like 'y' which have a descender will be
given a negative v_bot. Most capitals will have
v_bot==0.0 and v_top==1.0.
*/
/* Nominal baseline widths */
float widths [ FNTMAX_CHAR ] ;
/* Texture coordinates */
float t_top [ FNTMAX_CHAR ] ; /* Top edge of each character [0..1] */
float t_bot [ FNTMAX_CHAR ] ; /* Bottom edge of each character [0..1] */
float t_left [ FNTMAX_CHAR ] ; /* Left edge of each character [0..1] */
float t_right [ FNTMAX_CHAR ] ; /* Right edge of each character [0..1] */
/* Vertex coordinates. */
float v_top [ FNTMAX_CHAR ] ;
float v_bot [ FNTMAX_CHAR ] ;
float v_left [ FNTMAX_CHAR ] ;
float v_right [ FNTMAX_CHAR ] ;
void bind_texture ()
{
glEnable ( GL_TEXTURE_2D ) ;
#ifdef GL_VERSION_1_1
glBindTexture ( GL_TEXTURE_2D, texture ) ;
#else
/* For ancient SGI machines */
glBindTextureEXT ( GL_TEXTURE_2D, texture ) ;
#endif
}
float low_putch ( sgVec3 curpos, float pointsize, float italic, char c ) ;
int loadTXF ( const SGPath& path, GLenum mag = GL_NEAREST,
GLenum min = GL_LINEAR_MIPMAP_LINEAR ) ;
public:
fntTexFont ()
{
bound = FNT_FALSE ;
fixed_pitch = FNT_TRUE ;
texture = 0 ;
width = 1.0f ;
gap = 0.1f ;
memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ;
}
fntTexFont ( const SGPath& path, GLenum mag = GL_NEAREST,
GLenum min = GL_LINEAR_MIPMAP_LINEAR ) : fntFont ()
{
bound = FNT_FALSE ;
fixed_pitch = FNT_TRUE ;
texture = 0 ;
width = 1.0f ;
gap = 0.1f ;
memset ( exists, FNT_FALSE, FNTMAX_CHAR * sizeof(int) ) ;
load ( path, mag, min ) ;
}
~fntTexFont ()
{
if ( texture != 0 )
{
#ifdef GL_VERSION_1_1
glDeleteTextures ( 1, &texture ) ;
#else
/* For ancient SGI machines */
glDeleteTexturesEXT ( 1, &texture ) ;
#endif
}
}
int load ( const SGPath& path, GLenum mag = GL_NEAREST,
GLenum min = GL_LINEAR_MIPMAP_LINEAR ) override ;
void setFixedPitch ( int fix ) { fixed_pitch = fix ; }
int isFixedPitch () const { return fixed_pitch ; }
void setWidth ( float w ) { width = w ; }
void setGap ( float g ) { gap = g ; }
float getWidth () const { return width ; }
float getGap () const { return gap ; }
void setGlyph ( char c, float wid,
float tex_left, float tex_right,
float tex_bot , float tex_top ,
float vtx_left, float vtx_right,
float vtx_bot , float vtx_top ) ;
void setGlyph ( char c,
float tex_left, float tex_right,
float tex_bot , float tex_top ,
float vtx_left, float vtx_right,
float vtx_bot , float vtx_top ) /* deprecated */
{
setGlyph ( c, vtx_right,
tex_left, tex_right, tex_bot, tex_top,
vtx_left, vtx_right, vtx_bot, vtx_top ) ;
}
int getGlyph ( char c, float* wid,
float *tex_left = NULL, float *tex_right = NULL,
float *tex_bot = NULL, float *tex_top = NULL,
float *vtx_left = NULL, float *vtx_right = NULL,
float *vtx_bot = NULL, float *vtx_top = NULL) ;
int getGlyph ( char c,
float *tex_left = NULL, float *tex_right = NULL,
float *tex_bot = NULL, float *tex_top = NULL,
float *vtx_left = NULL, float *vtx_right = NULL,
float *vtx_bot = NULL, float *vtx_top = NULL) /* deprecated */
{
return getGlyph ( c, NULL,
tex_left, tex_right, tex_bot, tex_top,
vtx_left, vtx_right, vtx_bot, vtx_top ) ;
}
int hasGlyph ( char c ) const { return exists[ (GLubyte) c ] ; }
void getBBox ( const char *s, float pointsize, float italic,
float *left, float *right,
float *bot , float *top ) ;
void begin ()
{
bind_texture () ;
bound = FNT_TRUE ;
}
void end ()
{
bound = FNT_FALSE ;
}
void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ;
void putch ( sgVec3 curpos, float pointsize, float italic, char c )
{
if ( ! bound )
bind_texture () ;
low_putch ( curpos, pointsize, italic, c ) ;
}
} ;
class fntBitmapFont : public fntFont
{
protected:
const GLubyte **data;
int first;
int count;
int height;
float xorig, yorig;
int fix;
float wid, gap;
public:
// data is a null-terminated list of glyph images:
// data[i][0] - image width
// data[i][1..n] - packed bitmap
fntBitmapFont ( const GLubyte **data, int first, int height,
float xorig, float yorig ) ;
virtual ~fntBitmapFont () ;
virtual void getBBox ( const char *s, float pointsize, float italic,
float *left, float *right,
float *bot , float *top ) ;
virtual void putch ( sgVec3 curpos, float pointsize, float italic, char c ) ;
virtual void puts ( sgVec3 curpos, float pointsize, float italic, const char *s ) ;
virtual void begin () ;
virtual void end () ;
virtual int load ( const SGPath& fname, GLenum mag, GLenum min ) override { return -1; }
virtual void setFixedPitch ( int f ) { fix = f; }
virtual int isFixedPitch () const { return fix; }
virtual void setWidth ( float w ) { wid = w; }
virtual void setGap ( float g ) { gap = g; }
virtual float getWidth () const { return wid; }
virtual float getGap () const { return gap; }
virtual int hasGlyph ( char c ) const ;
};
/* Builtin Bitmap Fonts */
#define FNT_BITMAP_8_BY_13 0
#define FNT_BITMAP_9_BY_15 1
#define FNT_BITMAP_HELVETICA_10 2
#define FNT_BITMAP_HELVETICA_12 3
#define FNT_BITMAP_HELVETICA_18 4
#define FNT_BITMAP_TIMES_ROMAN_10 5
#define FNT_BITMAP_TIMES_ROMAN_24 6
fntBitmapFont *fntGetBitmapFont(int id);
class fntRenderer
{
fntFont *font ;
sgVec3 curpos ;
float pointsize ;
float italic ;
public:
fntRenderer ()
{
start2f ( 0.0f, 0.0f ) ;
font = NULL ;
pointsize = 10 ;
italic = 0 ;
}
void start3fv ( sgVec3 pos ) { sgCopyVec3 ( curpos, pos ) ; }
void start2fv ( sgVec2 pos ) { sgCopyVec2 ( curpos, pos ) ; curpos[2]=0.0f ; }
void start2f ( float x, float y ) { sgSetVec3 ( curpos, x, y, 0.0f ) ; }
void start3f ( float x, float y, float z ) { sgSetVec3 ( curpos, x, y, z ) ; }
void getCursor ( float *x, float *y, float *z ) const
{
if ( x != NULL ) *x = curpos [ 0 ] ;
if ( y != NULL ) *y = curpos [ 1 ] ;
if ( z != NULL ) *z = curpos [ 2 ] ;
}
void setFont ( fntFont *f ) { font = f ; }
fntFont *getFont () const { return font ; }
void setSlant ( float i ) { italic = i ; }
void setPointSize ( float p ) { pointsize = p ; }
float getSlant () const { return italic ; }
float getPointSize () const { return pointsize ; }
void begin () { font->begin () ; }
void end () { font->end () ; }
void putch ( char c ) { font->putch ( curpos, pointsize, italic, c ) ; }
void puts ( const char *s ) { font->puts ( curpos, pointsize, italic, s ) ; }
} ;
void fntInit () ;
#endif
+1017
View File
File diff suppressed because it is too large Load Diff
+112
View File
@@ -0,0 +1,112 @@
/*
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For further information visit http://plib.sourceforge.net
$Id: fntLocal.h 1727 2002-11-09 21:27:21Z ude $
*/
#include "fnt.h"
extern int _fntIsSwapped ;
extern FILE *_fntCurrImageFd ;
inline void _fnt_swab_short ( unsigned short *x )
{
if ( _fntIsSwapped )
*x = (( *x >> 8 ) & 0x00FF ) |
(( *x << 8 ) & 0xFF00 ) ;
}
inline void _fnt_swab_int ( unsigned int *x )
{
if ( _fntIsSwapped )
*x = (( *x >> 24 ) & 0x000000FF ) |
(( *x >> 8 ) & 0x0000FF00 ) |
(( *x << 8 ) & 0x00FF0000 ) |
(( *x << 24 ) & 0xFF000000 ) ;
}
inline void _fnt_swab_int_array ( int *x, int leng )
{
if ( ! _fntIsSwapped )
return ;
for ( int i = 0 ; i < leng ; i++ )
{
*x = (( *x >> 24 ) & 0x000000FF ) |
(( *x >> 8 ) & 0x0000FF00 ) |
(( *x << 8 ) & 0x00FF0000 ) |
(( *x << 24 ) & 0xFF000000 ) ;
x++ ;
}
}
inline unsigned char _fnt_readByte ()
{
unsigned char x ;
fread ( & x, sizeof(unsigned char), 1, _fntCurrImageFd ) ;
return x ;
}
inline unsigned short _fnt_readShort ()
{
unsigned short x ;
fread ( & x, sizeof(unsigned short), 1, _fntCurrImageFd ) ;
_fnt_swab_short ( & x ) ;
return x ;
}
inline unsigned int _fnt_readInt ()
{
unsigned int x ;
fread ( & x, sizeof(unsigned int), 1, _fntCurrImageFd ) ;
_fnt_swab_int ( & x ) ;
return x ;
}
#define FNT_BYTE_FORMAT 0
#define FNT_BITMAP_FORMAT 1
struct TXF_Glyph
{
unsigned short ch ;
unsigned char w ;
unsigned char h ;
signed char x_off ;
signed char y_off ;
signed char step ;
signed char unknown ;
short x ;
short y ;
sgVec2 tx0 ; sgVec2 vx0 ;
sgVec2 tx1 ; sgVec2 vx1 ;
sgVec2 tx2 ; sgVec2 vx2 ;
sgVec2 tx3 ; sgVec2 vx3 ;
} ;
void fntSetError(int, const char* format, ...);
Vendored Executable
+341
View File
@@ -0,0 +1,341 @@
/*
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For further information visit http://plib.sourceforge.net
$Id: fntTXF.cxx 1735 2002-12-01 18:21:48Z sjbaker $
*/
#include "fntLocal.h"
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
FILE *_fntCurrImageFd ;
int _fntIsSwapped = FALSE ;
static void tex_make_mip_maps ( GLubyte *image, int xsize,
int ysize, int zsize )
{
GLubyte *texels [ 20 ] ; /* One element per level of MIPmap */
for ( int l = 0 ; l < 20 ; l++ )
texels [ l ] = NULL ;
texels [ 0 ] = image ;
int lev ;
for ( lev = 0 ; (( xsize >> (lev+1) ) != 0 ||
( ysize >> (lev+1) ) != 0 ) ; lev++ )
{
/* Suffix '1' is the higher level map, suffix '2' is the lower level. */
int l1 = lev ;
int l2 = lev+1 ;
int w1 = xsize >> l1 ;
int h1 = ysize >> l1 ;
int w2 = xsize >> l2 ;
int h2 = ysize >> l2 ;
if ( w1 <= 0 ) w1 = 1 ;
if ( h1 <= 0 ) h1 = 1 ;
if ( w2 <= 0 ) w2 = 1 ;
if ( h2 <= 0 ) h2 = 1 ;
texels [ l2 ] = new GLubyte [ w2 * h2 * zsize ] ;
for ( int x2 = 0 ; x2 < w2 ; x2++ )
for ( int y2 = 0 ; y2 < h2 ; y2++ )
for ( int c = 0 ; c < zsize ; c++ )
{
int x1 = x2 + x2 ;
int x1_1 = ( x1 + 1 ) % w1 ;
int y1 = y2 + y2 ;
int y1_1 = ( y1 + 1 ) % h1 ;
int t1 = texels [ l1 ] [ (y1 * w1 + x1 ) * zsize + c ] ;
int t2 = texels [ l1 ] [ (y1_1 * w1 + x1 ) * zsize + c ] ;
int t3 = texels [ l1 ] [ (y1 * w1 + x1_1) * zsize + c ] ;
int t4 = texels [ l1 ] [ (y1_1 * w1 + x1_1) * zsize + c ] ;
texels [ l2 ] [ (y2 * w2 + x2) * zsize + c ] =
( t1 + t2 + t3 + t4 ) / 4 ;
}
}
texels [ lev+1 ] = NULL ;
if ( ! ((xsize & (xsize-1))==0) ||
! ((ysize & (ysize-1))==0) )
{
fntSetError ( SG_ALERT,
"TXFloader: TXF Map is not a power-of-two in size!" ) ;
}
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ) ;
int map_level = 0 ;
#ifdef PROXY_TEXTURES_ARE_NOT_BROKEN
int ww ;
do
{
glTexImage2D ( GL_PROXY_TEXTURE_2D,
map_level, zsize, xsize, ysize, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, NULL ) ;
glGetTexLevelParameteriv ( GL_PROXY_TEXTURE_2D, 0,GL_TEXTURE_WIDTH, &ww ) ;
if ( ww == 0 )
{
delete [] texels [ 0 ] ;
xsize >>= 1 ;
ysize >>= 1 ;
for ( int l = 0 ; texels [ l ] != NULL ; l++ )
texels [ l ] = texels [ l+1 ] ;
if ( xsize < 64 && ysize < 64 )
{
fntSetError ( SG_ALERT,
"FNT: OpenGL will not accept a font texture?!?" ) ;
}
}
} while ( ww == 0 ) ;
#endif
for ( int i = 0 ; texels [ i ] != NULL ; i++ )
{
int w = xsize>>i ;
int h = ysize>>i ;
if ( w <= 0 ) w = 1 ;
if ( h <= 0 ) h = 1 ;
glTexImage2D ( GL_TEXTURE_2D,
map_level, zsize, w, h, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid *) texels[i] ) ;
map_level++ ;
delete [] texels [ i ] ;
}
}
int fntTexFont::loadTXF ( const SGPath& path, GLenum mag, GLenum min )
{
FILE *fd ;
const auto ps = path.utf8Str();
#if defined(SG_WINDOWS)
std::wstring fp = path.wstr();
fd = _wfopen(fp.c_str(), L"rb");
#else
fd = fopen(ps.c_str(), "rb");
#endif
if ( fd == nullptr )
{
fntSetError ( SG_WARN,
"fntLoadTXF: Failed to open '%s' for reading.", ps.c_str() ) ;
return FNT_FALSE ;
}
_fntCurrImageFd = fd ;
unsigned char magic [ 4 ] ;
if ( (int)fread ( &magic, sizeof (unsigned int), 1, fd ) != 1 )
{
fntSetError ( SG_WARN,
"fntLoadTXF: '%s' an empty file!", ps.c_str() ) ;
return FNT_FALSE ;
}
if ( magic [ 0 ] != 0xFF || magic [ 1 ] != 't' ||
magic [ 2 ] != 'x' || magic [ 3 ] != 'f' )
{
fntSetError ( SG_WARN,
"fntLoadTXF: '%s' is not a 'txf' font file.", ps.c_str() ) ;
return FNT_FALSE ;
}
_fntIsSwapped = FALSE ;
int endianness = _fnt_readInt () ;
_fntIsSwapped = ( endianness != 0x12345678 ) ;
int format = _fnt_readInt () ;
int tex_width = _fnt_readInt () ;
int tex_height = _fnt_readInt () ;
int max_height = _fnt_readInt () ;
_fnt_readInt () ;
int num_glyphs = _fnt_readInt () ;
int w = tex_width ;
int h = tex_height ;
float xstep = 0.5f / (float) w ;
float ystep = 0.5f / (float) h ;
int i, j ;
/*
Load the TXF_Glyph array
*/
TXF_Glyph glyph ;
for ( i = 0 ; i < num_glyphs ; i++ )
{
glyph . ch = _fnt_readShort () ;
glyph . w = _fnt_readByte () ;
glyph . h = _fnt_readByte () ;
glyph . x_off = _fnt_readByte () ;
glyph . y_off = _fnt_readByte () ;
glyph . step = _fnt_readByte () ;
glyph . unknown = _fnt_readByte () ;
glyph . x = _fnt_readShort () ;
glyph . y = _fnt_readShort () ;
setGlyph ( (char) glyph.ch,
(float) glyph.step / (float) max_height,
(float) glyph.x / (float) w + xstep,
(float)( glyph.x + glyph.w ) / (float) w + xstep,
(float) glyph.y / (float) h + ystep,
(float)( glyph.y + glyph.h ) / (float) h + ystep,
(float) glyph.x_off / (float) max_height,
(float)( glyph.x_off + glyph.w ) / (float) max_height,
(float) glyph.y_off / (float) max_height,
(float)( glyph.y_off + glyph.h ) / (float) max_height ) ;
}
exists [ static_cast<int>(' ') ] = FALSE ;
/*
Load the image part of the file
*/
int ntexels = w * h ;
unsigned char *teximage ;
unsigned char *texbitmap ;
switch ( format )
{
case FNT_BYTE_FORMAT:
{
unsigned char *orig = new unsigned char [ ntexels ] ;
if ( (int)fread ( orig, 1, ntexels, fd ) != ntexels )
{
fntSetError ( SG_WARN,
"fntLoadTXF: Premature EOF in '%s'.", ps.c_str() ) ;
return FNT_FALSE ;
}
teximage = new unsigned char [ 2 * ntexels ] ;
for ( i = 0 ; i < ntexels ; i++ )
{
teximage [ i*2 ] = orig [ i ] ;
teximage [ i*2 + 1 ] = orig [ i ] ;
}
delete [] orig ;
}
break ;
case FNT_BITMAP_FORMAT:
{
int stride = (w + 7) >> 3;
texbitmap = new unsigned char [ stride * h ] ;
if ( (int)fread ( texbitmap, 1, stride * h, fd ) != stride * h )
{
delete [] texbitmap ;
fntSetError ( SG_WARN,
"fntLoadTXF: Premature EOF in '%s'.", ps.c_str() ) ;
return FNT_FALSE ;
}
teximage = new unsigned char [ 2 * ntexels ] ;
for ( i = 0 ; i < 2 * ntexels ; i++ )
teximage [ i ] = 0 ;
for (i = 0; i < h; i++)
for (j = 0; j < w; j++)
if (texbitmap[i * stride + (j >> 3)] & (1 << (j & 7)))
{
teximage[(i * w + j) * 2 ] = 255;
teximage[(i * w + j) * 2 + 1] = 255;
}
delete [] texbitmap ;
}
break ;
default:
fntSetError ( SG_WARN,
"fntLoadTXF: Unrecognised format type in '%s'.", ps.c_str() ) ;
return FNT_FALSE ;
}
fclose ( fd ) ;
fixed_pitch = FALSE ;
#ifdef GL_VERSION_1_1
glGenTextures ( 1, & texture ) ;
glBindTexture ( GL_TEXTURE_2D, texture ) ;
#else
/* This is only useful on some ancient SGI hardware */
glGenTexturesEXT ( 1, & texture ) ;
glBindTextureEXT ( GL_TEXTURE_2D, texture ) ;
#endif
tex_make_mip_maps ( teximage, w, h, 2 ) ;
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag ) ;
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min ) ;
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ) ;
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ) ;
#ifdef GL_VERSION_1_1
glBindTexture ( GL_TEXTURE_2D, 0 ) ;
#else
glBindTextureEXT ( GL_TEXTURE_2D, 0 ) ;
#endif
return FNT_TRUE ;
}