diff --git a/stb_rect_pack.h b/stb_rect_pack.h index 5462379..6a9e8d3 100644 --- a/stb_rect_pack.h +++ b/stb_rect_pack.h @@ -1,4 +1,4 @@ -// stb_rect_pack.h - v0.03 - public domain - rectangle packing +// stb_rect_pack.h - v0.04 - public domain - rectangle packing // Sean Barrett 2014 // // Useful for e.g. packing rectangular textures into an atlas. @@ -19,7 +19,11 @@ // Please note: better rectangle packers are welcome! Please // implement them to the same API, but with a different init // function. - +// +// Version history: +// +// 0.04: fixed minor bug in STBRP_LARGE_RECTS support +// 0.01: initial release ////////////////////////////////////////////////////////////////////////////// // diff --git a/stb_truetype.h b/stb_truetype.h index 4b7db1a..f57ec09 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v0.99 - public domain +// stb_truetype.h - v1.00 - public domain // authored from 2009-2014 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -40,6 +40,7 @@ // // VERSION HISTORY // +// 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling // 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) // 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID // 0.8b (2014-07-07) fix a warning @@ -61,7 +62,7 @@ // updated Hello World! sample to use kerning and subpixel // fixed some warnings // 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) -// userdata, malloc-from-userdata, non-zero fill (STB) +// userdata, malloc-from-userdata, non-zero fill (stb) // 0.2 (2009-03-11) Fix unsigned/signed char warnings // 0.1 (2009-03-09) First public release // @@ -79,11 +80,18 @@ // before the #include of this file. This expands out the actual // implementation into that C/C++ file. // -// Simple 3D API (don't ship this, but it's fine for tools and quick start, -// and you can cut and paste from it to move to more advanced) +// Simple 3D API (don't ship this, but it's fine for tools and quick start) // stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture // stbtt_GetBakedQuad() -- compute quad to draw for a given char // +// Improved 3D API (more shippable): +// #include "stb_rect_pack.h" -- optional, but you really want it +// stbtt_PackBegin() +// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackFontRanges() +// stbtt_PackEnd() +// stbtt_GetPackedQuad() +// // "Load" a font file from a memory buffer (you have to keep the buffer loaded) // stbtt_InitFont() // stbtt_GetFontOffsetForIndex() -- use for TTC font collections @@ -484,21 +492,51 @@ typedef struct typedef struct stbtt_pack_context stbtt_pack_context; typedef struct { - float font_size; // if positive, pixel height; if negative, points + float font_size; int first_unicode_char_in_range; int num_chars_in_range; stbtt_packedchar *chardata_for_range; // output } stbtt_pack_range; -extern int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context); -// returns 0 if the allocations fail +extern int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); +// Initializes a packing context stored in the passed-in stbtt_pack_context. +// Future calls using this context will pack characters into the bitmap passed +// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is +// the distance from one row to the next (or 0 to mean they are packed tightly +// together). "padding" is // the amount of padding to leave between each +// character (normally you want '1' for bitmaps you'll use as textures with +// bilinear filtering). +// +// Returns 0 on failure, 1 on success. + +extern void stbtt_PackEnd (stbtt_pack_context *spc); +// Cleans up the packing context and frees all memory. + +extern int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float pixel_height, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); +// Creates character bitmaps from the font_index'th font found in fontdata (use +// font_index=0 if you don't know what that is). It creates num_chars_in_range +// bitmaps for characters with unicode values starting at first_unicode_char_in_range +// and increasing. Data for how to render them is stored in chardata_for_range; +// pass these to stbtt_GetPackedQuad to get back renderable quads. + +extern int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +// Creates character bitmaps from multiple ranges of characters stored in +// ranges. This will usually create a better-packed bitmap than multiple +// calls to stbtt_PackFontRange. + extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -extern void stbtt_PackEnd (stbtt_pack_context *spc); -extern int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); -extern int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); - +// Oversampling a font increases the quality by allowing higher-quality subpixel +// positioning, and is especially valuable at smaller text sizes. +// +// This function sets the amount of oversampling for all following calls to +// stbtt_PackFontRange(s). The default (no oversampling) is achieved by +// h_oversample=1, v_oversample=1. The total number of pixels required is +// h_oversample*v_oversample larger than the default; for example, 2x2 +// oversampling requires 4x the storage of 1x1. For best results, render +// oversampled textures with bilinear filtering. Look at the readme in +// stb/tests/oversample for information about oversampled fonts extern void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display diff --git a/tests/oversample/main.c b/tests/oversample/main.c index f9f4d76..bc6bd0f 100644 --- a/tests/oversample/main.c +++ b/tests/oversample/main.c @@ -2,11 +2,8 @@ #include #include -#define STB_DEFINE #define STB_WINMAIN -#define STB_NO_REGISTRY #include "stb_wingraph.h" -#include "stb.h" #define STB_TRUETYPE_IMPLEMENTATION #define STB_RECT_PACK_IMPLEMENTATION @@ -22,11 +19,12 @@ #include #include +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #define SIZE_X 1024 #define SIZE_Y 768 -stbtt_packedchar chardata[3][128]; +stbtt_packedchar chardata[6][128]; int sx=SIZE_X, sy=SIZE_Y; @@ -36,19 +34,40 @@ unsigned char temp_bitmap[BITMAP_W][BITMAP_H]; unsigned char ttf_buffer[1 << 25]; GLuint font_tex; +float scale[2] = { 24.0f, 14.0f }; + +int sf[6] = { 0,1,2, 0,1,2 }; + void load_fonts(void) { stbtt_pack_context pc; - FILE *f = fopen("c:/windows/fonts/times.ttf", "rb"); - if (!f) exit(0); + int i; + FILE *f; + char filename[256]; + char *win = getenv("windir"); + if (win == NULL) win = getenv("SystemRoot"); + + f = fopen(stb_wingraph_commandline, "rb"); + if (!f) { + if (win == NULL) + sprintf(filename, "arial.ttf", win); + else + sprintf(filename, "%s/fonts/arial.ttf", win); + f = fopen(filename, "rb"); + if (!f) exit(0); + } + fread(ttf_buffer, 1, 1<<25, f); stbtt_PackBegin(&pc, temp_bitmap[0], BITMAP_W, BITMAP_H, 0, 1, NULL); - stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[0]+32); - stbtt_PackSetOversampling(&pc, 2, 2); - stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[1]+32); - stbtt_PackSetOversampling(&pc, 3, 1); - stbtt_PackFontRange(&pc, ttf_buffer, 0, 24.0, 32, 95, chardata[2]+32); + for (i=0; i < 2; ++i) { + stbtt_PackSetOversampling(&pc, 1, 1); + stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+0]+32); + stbtt_PackSetOversampling(&pc, 2, 2); + stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+1]+32); + stbtt_PackSetOversampling(&pc, 3, 1); + stbtt_PackFontRange(&pc, ttf_buffer, 0, scale[i], 32, 95, chardata[i*3+2]+32); + } stbtt_PackEnd(&pc); glGenTextures(1, &font_tex); @@ -58,6 +77,8 @@ void load_fonts(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } +int black_on_white; + void draw_init(void) { glDisable(GL_CULL_FACE); @@ -66,7 +87,10 @@ void draw_init(void) glDisable(GL_DEPTH_TEST); glViewport(0,0,sx,sy); - glClearColor(0,0,0,0); + if (black_on_white) + glClearColor(255,255,255,0); + else + glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); @@ -100,41 +124,64 @@ void print(float x, float y, int font, char *text) glEnd(); } -int font=0; +int font=3; int translating; int rotating=0; +int srgb=0; float rotate_t, translate_t; int show_tex; void draw_world(void) { + int sfont = sf[font]; float x = 20; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor3f(1,1,1); - if (font==1) - print(100, 50, font, "2x2 oversampled text at 1:1"); - else if (font == 2) - print(100, 50, font, "3x1 oversampled text at 1:1"); - else if (integer_align) - print(100, 50, font, "1:1 text, one texel = one pixel, snapped to integer coordinates"); + if (black_on_white) + glColor3f(0,0,0); else - print(100, 50, font, "1:1 text, one texel = one pixel"); + glColor3f(1,1,1); - print(100, 80, font, "O: toggle oversampling"); - print(100,105, font, "T: toggle translation"); - print(100,130, font, "R: toggle rotation"); - print(100,155, font, "P: toggle pixel-snap (only non-oversampled)"); - print(100,180, font, "V: view font texture"); + + print(80, 30, sfont, "Controls:"); + print(100, 60, sfont, "S: toggle font size"); + print(100, 85, sfont, "O: toggle oversampling"); + print(100,110, sfont, "T: toggle translation"); + print(100,135, sfont, "R: toggle rotation"); + print(100,160, sfont, "P: toggle pixel-snap (only non-oversampled)"); + print(100,185, sfont, "G: toggle srgb gamma-correction"); + if (black_on_white) + print(100,210, sfont, "B: toggle to white-on-black"); + else + print(100,210, sfont, "B: toggle to black-on-white"); + print(100,235, sfont, "V: view font texture"); + + print(80, 300, sfont, "Current font:"); + + if (!show_tex) { + if (font < 3) + print(100, 350, sfont, "Font height: 24 pixels"); + else + print(100, 350, sfont, "Font height: 14 pixels"); + } + + if (font%3==1) + print(100, 325, sfont, "2x2 oversampled text at 1:1"); + else if (font%3 == 2) + print(100, 325, sfont, "3x1 oversampled text at 1:1"); + else if (integer_align) + print(100, 325, sfont, "1:1 text, one texel = one pixel, snapped to integer coordinates"); + else + print(100, 325, sfont, "1:1 text, one texel = one pixel"); if (show_tex) { glBegin(GL_QUADS); - drawBoxTC(200,200, 200+BITMAP_W,200+BITMAP_H, 0,0,1,1); + drawBoxTC(200,400, 200+BITMAP_W,300+BITMAP_H, 0,0,1,1); glEnd(); } else { glMatrixMode(GL_MODELVIEW); - glTranslatef(200,250,0); + glTranslatef(200,350,0); if (translating) x += fmod(translate_t*8,30); @@ -198,7 +245,10 @@ int winproc(void *data, stbwingraph_event *e) return STBWINGRAPH_winproc_exit; break; case 'o': case 'O': - font = (font+1) % 3; + font = (font+1) % 3 + (font/3)*3; + break; + case 's': case 'S': + font = (font+3) % 6; break; case 't': case 'T': translating = !translating; @@ -211,9 +261,19 @@ int winproc(void *data, stbwingraph_event *e) case 'p': case 'P': integer_align = !integer_align; break; + case 'g': case 'G': + srgb = !srgb; + if (srgb) + glEnable(GL_FRAMEBUFFER_SRGB_EXT); + else + glDisable(GL_FRAMEBUFFER_SRGB_EXT); + break; case 'v': case 'V': show_tex = !show_tex; break; + case 'b': case 'B': + black_on_white = !black_on_white; + break; } break; diff --git a/tests/oversample/oversample.exe b/tests/oversample/oversample.exe new file mode 100644 index 0000000..0040693 Binary files /dev/null and b/tests/oversample/oversample.exe differ diff --git a/tests/oversample/stb_wingraph.h b/tests/oversample/stb_wingraph.h index d48065f..ee16923 100644 --- a/tests/oversample/stb_wingraph.h +++ b/tests/oversample/stb_wingraph.h @@ -791,6 +791,8 @@ void stbwingraph_SwapBuffers(void *win) #ifdef STB_WINMAIN void stbwingraph_main(void); +char *stb_wingraph_commandline; + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { { @@ -808,6 +810,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine else if (strstr(buffer, " -full ") || strstr(buffer, " -fullscreen ")) stbwingraph_request_fullscreen = TRUE; } + stb_wingraph_commandline = lpCmdLine; stbwingraph_DefineClass(hInstance, "appicon"); stbwingraph_main();