https://github.com/ialhashim/topo-blend
Revision 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC, committed by ennetws on 13 March 2015, 18:17:18 UTC
1 parent c702819
Raw File
Tip revision: 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC
Create README.md
Tip revision: 39b1361
font.inl
// Font generated by stb_font_inl_generator.c (4/1 bpp)
//
// Following instructions show how to use the only included font, whatever it is, in
// a generic way so you can replace it with any other font by changing the include.
// To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_consolas_10_usascii_*,
// and separately install each font. Note that the CREATE function call has a
// totally different name; it's just 'stb_font_consolas_10_usascii'.
//
/* // Example usage:

static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS];

static void init(void)
{
    // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2
    static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH];
    STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT);
    ... create texture ...
    // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling
    // if allowed to scale up, use bilerp
}

// This function positions characters on integer coordinates, and assumes 1:1 texels to pixels
// Appropriate if nearest-neighbor sampling is used
static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y
{
    ... use texture ...
    ... turn on alpha blending and gamma-correct alpha blending ...
    glBegin(GL_QUADS);
    while (*str) {
        int char_codepoint = *str++;
        stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
        glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0);
        glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0);
        glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1);
        glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1);
        // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
        x += cd->advance_int;
    }
    glEnd();
}

// This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels
// Appropriate if bilinear filtering is used
static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y
{
    ... use texture ...
    ... turn on alpha blending and gamma-correct alpha blending ...
    glBegin(GL_QUADS);
    while (*str) {
        int char_codepoint = *str++;
        stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
        glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f);
        glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f);
        glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f);
        glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f);
        // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
        x += cd->advance;
    }
    glEnd();
}
*/

#ifndef STB_FONTCHAR__TYPEDEF
#define STB_FONTCHAR__TYPEDEF
typedef struct
{
    // coordinates if using integer positioning
    float s0,t0,s1,t1;
    signed short x0,y0,x1,y1;
    int   advance_int;
    // coordinates if using floating positioning
    float s0f,t0f,s1f,t1f;
    float x0f,y0f,x1f,y1f;
    float advance;
} stb_fontchar;
#endif

#define STB_FONT_consolas_10_usascii_BITMAP_WIDTH         128
#define STB_FONT_consolas_10_usascii_BITMAP_HEIGHT         44
#define STB_FONT_consolas_10_usascii_BITMAP_HEIGHT_POW2    64

#define STB_FONT_consolas_10_usascii_FIRST_CHAR            32
#define STB_FONT_consolas_10_usascii_NUM_CHARS             95

#define STB_FONT_consolas_10_usascii_LINE_SPACING           7

static unsigned int stb__consolas_10_usascii_pixels[]={
    0x000c8000,0x07402001,0x2a885993,0x3114c048,0x3269bb70,0x234772ec,
    0x435102a8,0xaa8722a8,0x49d55d0a,0x0322642b,0x952c43b5,0x1406dc4d,
    0xae8864b1,0x1900644c,0xac5661d4,0x2d1688e9,0x132ba249,0x27a235b7,
    0x6d543b4c,0x1b075151,0x0b0321c8,0x33a2d059,0x21fdd11c,0x572aaa9b,
    0x22093074,0x553bbb25,0x26926b13,0xe8ae1c9d,0x26b10b10,0xa83903b4,
    0x915c4983,0x682c4581,0x43603795,0x392adc9d,0x0dc160ec,0x56e750ea,
    0x3654b149,0x9d50d872,0xd8775c5b,0x75131c80,0x321931a0,0x20751660,
    0x86c0bf26,0x392ad9cd,0x160ea06c,0x56f3a0ea,0x1f41ecf9,0x4750d872,
    0x32993b16,0x755d1c80,0x325b11a0,0x02b87910,0x0d84cd8d,0x2e17b39b,
    0x75160d13,0x9ac40930,0x2770d104,0x75692668,0xa83b01b4,0x91546883,
    0x6824c581,0xc86c346c,0x76ec3ac9,0x806c3701,0x935883dd,0x37603d90,
    0x88eee41e,0x223d2dcd,0xa83a84ee,0x681915c4,0x3f6ad068,0x006e681d,
    0x4d620259,0x00000004,0x40000000,0x3207443a,0xb81b0321,0xb3122683,
    0x0665c45d,0x00006e44,0x00000000,0x75400000,0xc8b906e4,0x4320ecc0,
    0x000046ca,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
    0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x990d5400,
    0x855441df,0x910192da,0x40e216d4,0x435301a8,0x14110aaa,0x416d4355,
    0x55510dda,0x826130a5,0x30a13062,0x4eaf60a1,0x57447558,0x40eb6b0a,
    0x983ad158,0xd8795d04,0x42aba3ab,0x1d9a9a2b,0x2a2160ec,0x334775ca,
    0x8dc5926b,0x2a34361d,0x22d9e883,0x85bdb85a,0x167a5edb,0x4ea5d9b3,
    0x42c12669,0x70ae1a2b,0x4067a625,0x90ae3a0e,0xc84641b5,0xc8d2c950,
    0x35934c89,0x83905d90,0x2b6cb159,0x55da23a6,0x6c0ae6db,0x334570cd,
    0x750cd8b9,0xa857077f,0x8c87f05c,0x1d5a0c9d,0x22d31c8d,0x4c883ecf,
    0x13a93326,0x99af2aeb,0x269f5da4,0x2ba5c04a,0x82c9711a,0x0ba0b306,
    0x99371766,0x1a0c8d89,0x1a3bb4b5,0x3773b2c4,0xd1cadd2a,0x9358a4c9,
    0x200e8962,0x21a27549,0xd8340659,0x91d01900,0x22ecedc5,0x75c345ca,
    0x47b9d36d,0x1391edea,0xadef41bb,0xd10edde9,0x0f6e43b9,0x6e453b6a,
    0x447b760d,0x20f10ddc,0x45eefa86,0x0e89dc0c,0x7f11aed5,0x0004dde8,
    0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
    0x00000000,0x98388000,0x41d82aaa,0x510481aa,0x221dc835,0x4450c4a2,
    0x21aaa8a1,0x14111aaa,0x2a04c02a,0x203511aa,0x02aa21a8,0x44244351,
    0x44182bda,0x882c2dad,0x50dc4dad,0x6ab5d61f,0x55d0ed26,0x2a8ded43,
    0x6c44e89a,0xa8d5742e,0x6d642cac,0x22595b11,0xbbb12c9d,0x1ed80c83,
    0x5d625522,0x0dc69224,0x4e5d6995,0xd0ef265c,0x34550640,0x85710d55,
    0x54122a86,0x95d26913,0x9126d158,0xce886e01,0x22256c0d,0x2a1b8974,
    0x7b3758da,0x67c2f4cb,0x9b50641c,0x40e46cd9,0xa9667c2b,0xe88e4162,
    0xd51b30ed,0x0322c522,0x0b3b10dc,0x3de881db,0x2eaaa1b8,0x2191b195,
    0x04740dc9,0xd1155064,0x2e12e7a2,0x45504742,0x23223b87,0x456ae65a,
    0x700c8b14,0x6c2ba443,0x37024459,0x4195e954,0x68b1930c,0x5a2a8320,
    0x2b86ccda,0x45a95434,0x868a443b,0x9162912b,0x14eed881,0x96ab1a29,
    0x4eed8848,0x906dae55,0x0d255261,0x8aa7bdb1,0xe88e41b6,0x4f77e4ee,
    0x3e60ceea,0x3bbd15ee,0x0000f762,0x00000000,0x00000000,0x00000000,
    0x22020000,0x41442aaa,0x4022222e,0xb7245220,0x20eedc3b,0x3b721ddb,
    0x47bb3001,0x58ae2dbd,0xc892f6ee,0x7dbb11dd,0x41c2cd66,0x2dd5444b,
    0x541503b2,0x10d981aa,0x49869629,0x858a44d1,0x07406449,0x4d6268fc,
    0x89672ae4,0x5c1b0936,0x15ee40db,0x9315c16a,0x76f5401b,0x48836a0d,
    0xb86754b1,0x5ccda9a2,0x8191372e,0x46c0d058,0x96322e1c,0x81d8b148,
    0x80cea83e,0x0dac683c,0x41919054,0x59ac40e8,0x334754a8,0x5d26930b,
    0x68345ded,0x9171b2a0,0x258a44b1,0x40dbb83b,0xb83c8339,0xb0762ae2,
    0x10b6f6a7,0x25cdd83b,0x37761dcd,0xe89e6e41,0x540644cc,0x7f01a3dd,
    0x2258c8b8,0x377e2b14,0x02166b33,0x32e34072,0x44720cec,0x03b01d9d,
    0x00000020,0x0000002e,0x00000000,0x83603a80,0x0005ac2b,0x00000000,
    0x00000000,0x00000000,0x2c000000,0x04c0b86e,0x8549bbb3,0xd9c8ee1c,
    0x11065910,0x016eeeec,0x00000000,0x40000000,0x3a0c8b8c,0x33313223,
    0x0c1d97c1,0x32721b39,0x00376e5c,0x00000000,0x00000000,0xd8b5d370,
    0x5c472321,0x401303bb,0x00130189,0x00000000,0x00000000,0x976b2a00,
    0x01c4a21b,0x00000000,0x00000000,0x00000000,0x0b91f300,0x00000000,
    0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
};

static signed short stb__consolas_10_usascii_x[95]={ 0,2,1,0,0,0,0,2,1,1,0,0,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0, };
static signed short stb__consolas_10_usascii_y[95]={ 7,0,0,0,-1,0,0,0,-1,-1,0,1,5,3,
5,0,0,0,0,0,0,0,0,0,0,0,2,2,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,-1,0,8,0,2,0,2,0,2,0,2,0,0,
0,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,-1,-1,-1,3, };
static unsigned short stb__consolas_10_usascii_w[95]={ 0,2,4,6,5,6,6,2,4,4,5,6,3,4,
3,5,6,5,5,5,6,5,5,5,5,5,2,3,5,5,4,4,6,6,5,5,6,5,4,5,5,5,5,6,
4,6,5,6,5,6,6,5,6,5,6,6,6,6,5,4,5,3,5,6,4,5,5,5,5,5,6,6,5,5,
5,6,5,6,5,6,5,5,6,5,5,5,6,6,6,6,5,5,2,4,6, };
static unsigned short stb__consolas_10_usascii_h[95]={ 0,8,3,7,10,8,8,3,11,11,5,6,4,2,
3,9,8,7,7,8,7,8,8,7,8,7,6,7,7,3,7,8,10,7,7,8,7,7,7,8,7,7,8,7,
7,7,7,8,7,9,7,8,7,8,7,7,7,7,7,11,9,11,4,2,3,6,8,6,8,6,7,8,7,7,
10,7,7,5,5,6,8,8,5,6,8,6,5,5,5,8,5,11,11,11,3, };
static unsigned short stb__consolas_10_usascii_s[95]={ 125,116,71,23,34,20,33,63,25,6,120,
67,43,83,59,66,46,90,109,71,12,59,104,6,110,121,125,19,30,53,1,
77,46,83,115,53,102,96,66,1,77,71,119,59,123,52,46,97,34,53,20,
14,7,65,116,109,102,95,89,1,60,30,47,88,66,61,40,74,27,55,82,
7,1,14,40,27,40,94,101,48,84,78,80,42,72,36,87,36,113,90,107,
19,16,11,76, };
static unsigned short stb__consolas_10_usascii_t[95]={ 8,1,37,30,1,13,13,37,1,1,30,
30,37,37,37,1,13,22,22,13,30,13,1,30,1,22,1,30,30,37,30,
13,1,22,22,13,22,22,22,13,22,22,1,22,13,22,22,1,22,1,22,
13,22,13,13,13,13,13,13,1,1,1,37,37,37,30,13,30,13,30,13,
13,22,22,1,22,22,30,30,30,1,1,30,30,1,30,30,37,30,1,30,
1,1,1,37, };
static unsigned short stb__consolas_10_usascii_a[95]={ 88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
88,88,88,88,88,88,88, };

// Call this function with
//    font: NULL or array length
//    data: NULL or specified size
//    height: STB_FONT_consolas_10_usascii_BITMAP_HEIGHT or STB_FONT_consolas_10_usascii_BITMAP_HEIGHT_POW2
//    return value: spacing between lines
static void stb_font_consolas_10_usascii(stb_fontchar font[STB_FONT_consolas_10_usascii_NUM_CHARS],
                unsigned char data[STB_FONT_consolas_10_usascii_BITMAP_HEIGHT][STB_FONT_consolas_10_usascii_BITMAP_WIDTH],
                int height)
{
    int i,j;
    if (data != 0) {
        unsigned int *bits = stb__consolas_10_usascii_pixels;
        unsigned int bitpack = *bits++, numbits = 32;
        for (i=0; i < STB_FONT_consolas_10_usascii_BITMAP_WIDTH*height; ++i)
            data[0][i] = 0;  // zero entire bitmap
        for (j=1; j < STB_FONT_consolas_10_usascii_BITMAP_HEIGHT-1; ++j) {
            for (i=1; i < STB_FONT_consolas_10_usascii_BITMAP_WIDTH-1; ++i) {
                unsigned int value;
                if (numbits==0) bitpack = *bits++, numbits=32;
                value = bitpack & 1;
                bitpack >>= 1, --numbits;
                if (value) {
                    if (numbits < 3) bitpack = *bits++, numbits = 32;
                    data[j][i] = (bitpack & 7) * 0x20 + 0x1f;
                    bitpack >>= 3, numbits -= 3;
                } else {
                    data[j][i] = 0;
                }
            }
        }
    }

    // build font description
    if (font != 0) {
        float recip_width = 1.0f / STB_FONT_consolas_10_usascii_BITMAP_WIDTH;
        float recip_height = 1.0f / height;
        for (i=0; i < STB_FONT_consolas_10_usascii_NUM_CHARS; ++i) {
            // pad characters so they bilerp from empty space around each character
            font[i].s0 = (stb__consolas_10_usascii_s[i]) * recip_width;
            font[i].t0 = (stb__consolas_10_usascii_t[i]) * recip_height;
            font[i].s1 = (stb__consolas_10_usascii_s[i] + stb__consolas_10_usascii_w[i]) * recip_width;
            font[i].t1 = (stb__consolas_10_usascii_t[i] + stb__consolas_10_usascii_h[i]) * recip_height;
            font[i].x0 = stb__consolas_10_usascii_x[i];
            font[i].y0 = stb__consolas_10_usascii_y[i];
            font[i].x1 = stb__consolas_10_usascii_x[i] + stb__consolas_10_usascii_w[i];
            font[i].y1 = stb__consolas_10_usascii_y[i] + stb__consolas_10_usascii_h[i];
            font[i].advance_int = (stb__consolas_10_usascii_a[i]+8)>>4;
            font[i].s0f = (stb__consolas_10_usascii_s[i] - 0.5f) * recip_width;
            font[i].t0f = (stb__consolas_10_usascii_t[i] - 0.5f) * recip_height;
            font[i].s1f = (stb__consolas_10_usascii_s[i] + stb__consolas_10_usascii_w[i] + 0.5f) * recip_width;
            font[i].t1f = (stb__consolas_10_usascii_t[i] + stb__consolas_10_usascii_h[i] + 0.5f) * recip_height;
            font[i].x0f = stb__consolas_10_usascii_x[i] - 0.5f;
            font[i].y0f = stb__consolas_10_usascii_y[i] - 0.5f;
            font[i].x1f = stb__consolas_10_usascii_x[i] + stb__consolas_10_usascii_w[i] + 0.5f;
            font[i].y1f = stb__consolas_10_usascii_y[i] + stb__consolas_10_usascii_h[i] + 0.5f;
            font[i].advance = stb__consolas_10_usascii_a[i]/16.0f;
        }
    }
}

#ifndef STB_SOMEFONT_CREATE
#define STB_SOMEFONT_CREATE              stb_font_consolas_10_usascii
#define STB_SOMEFONT_BITMAP_WIDTH        STB_FONT_consolas_10_usascii_BITMAP_WIDTH
#define STB_SOMEFONT_BITMAP_HEIGHT       STB_FONT_consolas_10_usascii_BITMAP_HEIGHT
#define STB_SOMEFONT_BITMAP_HEIGHT_POW2  STB_FONT_consolas_10_usascii_BITMAP_HEIGHT_POW2
#define STB_SOMEFONT_FIRST_CHAR          STB_FONT_consolas_10_usascii_FIRST_CHAR
#define STB_SOMEFONT_NUM_CHARS           STB_FONT_consolas_10_usascii_NUM_CHARS
#define STB_SOMEFONT_LINE_SPACING        STB_FONT_consolas_10_usascii_LINE_SPACING
#endif

GLuint fontTexture;
bool fontReady = false;
static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS];
char gl_text_buf[64];
double font_color[4];

static void initFont(QImage & fontImage)
{
	if(!fontReady){
		static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH];
		STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT);
		glGenTextures(1, &fontTexture);
		glBindTexture(GL_TEXTURE_2D, fontTexture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glPixelTransferf(GL_RED_BIAS, 1);glPixelTransferf(GL_GREEN_BIAS, 1);glPixelTransferf(GL_BLUE_BIAS, 1);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fontImage.width(), fontImage.height(), 
            0, GL_ALPHA, GL_UNSIGNED_BYTE, fontImage.bits());
		fontReady = true;
	}
}

static int stringWidthGL(const char *str)
{
	int len = 0;
	while (*str) {
		int char_codepoint = *str++;
		stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
		len += cd->advance_int;
	}
	return len;
}

static int stringHeightGL()
{
	return 2 * STB_SOMEFONT_LINE_SPACING;
}

static void drawStringGL(int x, int y, const char *str, bool isShadow = false)
{
	int startX = x;

	while (*str) {
		int char_codepoint = *str++;

		// Line break
		if(char_codepoint == '\n'){
			x = startX;
			y += STB_SOMEFONT_LINE_SPACING * 1.75;
			continue;
		}

		// Tab
		if(char_codepoint == '\t'){
			x += STB_SOMEFONT_LINE_SPACING * 4;
			continue;
		}

		stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];

		if(isShadow){
			float shadowDist = 1;
			glColor4d(0,0,0,1);
			glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0+shadowDist, y + cd->y0+shadowDist);
			glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1+shadowDist, y + cd->y0+shadowDist);
			glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1+shadowDist, y + cd->y1+shadowDist);
			glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0+shadowDist, y + cd->y1+shadowDist);
		}
		if(isShadow) glColor4dv(font_color);

		glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0);
		glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0);
		glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1);
		glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1);

		x += cd->advance_int;
	}
}
back to top