Updated stb_truetype, fixed compiler warnings. Compiles with -Wall now.

This commit is contained in:
Mikko Mononen 2010-02-05 08:01:30 +00:00
parent fa66b9a9f3
commit 8561fb6d00
5 changed files with 354 additions and 134 deletions

View File

@ -168,6 +168,16 @@
6B324AD6111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD6111C00D700EBD2FD /* PBXTextBookmark */; 6B324AD6111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD6111C00D700EBD2FD /* PBXTextBookmark */;
6B324AD7111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD7111C00D700EBD2FD /* PBXTextBookmark */; 6B324AD7111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD7111C00D700EBD2FD /* PBXTextBookmark */;
6B324AD8111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD8111C00D700EBD2FD /* PBXTextBookmark */; 6B324AD8111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD8111C00D700EBD2FD /* PBXTextBookmark */;
6B324ADA111C012300EBD2FD /* PBXTextBookmark */ = 6B324ADA111C012300EBD2FD /* PBXTextBookmark */;
6B324ADB111C012300EBD2FD /* PBXTextBookmark */ = 6B324ADB111C012300EBD2FD /* PBXTextBookmark */;
6B324ADD111C014A00EBD2FD /* PBXTextBookmark */ = 6B324ADD111C014A00EBD2FD /* PBXTextBookmark */;
6B324ADE111C014A00EBD2FD /* PBXTextBookmark */ = 6B324ADE111C014A00EBD2FD /* PBXTextBookmark */;
6B324AE0111C020F00EBD2FD /* PBXTextBookmark */ = 6B324AE0111C020F00EBD2FD /* PBXTextBookmark */;
6B324AE1111C020F00EBD2FD /* PBXTextBookmark */ = 6B324AE1111C020F00EBD2FD /* PBXTextBookmark */;
6B324AE6111C07AB00EBD2FD /* PBXTextBookmark */ = 6B324AE6111C07AB00EBD2FD /* PBXTextBookmark */;
6B324AE7111C07AB00EBD2FD /* PBXTextBookmark */ = 6B324AE7111C07AB00EBD2FD /* PBXTextBookmark */;
6B324AE8111C07AB00EBD2FD /* PBXTextBookmark */ = 6B324AE8111C07AB00EBD2FD /* PBXTextBookmark */;
6B324AE9111C07AB00EBD2FD /* PBXTextBookmark */ = 6B324AE9111C07AB00EBD2FD /* PBXTextBookmark */;
6B69739F10FFCA4500984788 = 6B69739F10FFCA4500984788 /* PBXTextBookmark */; 6B69739F10FFCA4500984788 = 6B69739F10FFCA4500984788 /* PBXTextBookmark */;
6B6973A210FFCA4500984788 = 6B6973A210FFCA4500984788 /* PBXTextBookmark */; 6B6973A210FFCA4500984788 = 6B6973A210FFCA4500984788 /* PBXTextBookmark */;
6B8DE70D10B01BBF00DF20FB = 6B8DE70D10B01BBF00DF20FB /* PBXTextBookmark */; 6B8DE70D10B01BBF00DF20FB = 6B8DE70D10B01BBF00DF20FB /* PBXTextBookmark */;
@ -778,7 +788,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */; fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 217"; name = "imguiRenderGL.cpp: 217";
rLen = 0; rLen = 0;
rLoc = 5230; rLoc = 5234;
rType = 0; rType = 0;
vrLen = 474; vrLen = 474;
vrLoc = 4904; vrLoc = 4904;
@ -808,7 +818,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */; fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 217"; name = "imguiRenderGL.cpp: 217";
rLen = 0; rLen = 0;
rLoc = 5230; rLoc = 5234;
rType = 0; rType = 0;
vrLen = 474; vrLen = 474;
vrLoc = 4904; vrLoc = 4904;
@ -848,7 +858,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */; fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 667"; name = "stb_truetype.h: 667";
rLen = 0; rLen = 0;
rLoc = 27261; rLoc = 27273;
rType = 0; rType = 0;
vrLen = 975; vrLen = 975;
vrLoc = 26909; vrLoc = 26909;
@ -878,7 +888,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */; fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 667"; name = "stb_truetype.h: 667";
rLen = 0; rLen = 0;
rLoc = 27261; rLoc = 27273;
rType = 0; rType = 0;
vrLen = 975; vrLen = 975;
vrLoc = 26909; vrLoc = 26909;
@ -958,7 +968,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */; fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 218"; name = "imguiRenderGL.cpp: 218";
rLen = 0; rLen = 0;
rLoc = 5173; rLoc = 5177;
rType = 0; rType = 0;
vrLen = 529; vrLen = 529;
vrLoc = 5014; vrLoc = 5014;
@ -1086,7 +1096,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */; fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 218"; name = "imguiRenderGL.cpp: 218";
rLen = 0; rLen = 0;
rLoc = 5173; rLoc = 5177;
rType = 0; rType = 0;
vrLen = 529; vrLen = 529;
vrLoc = 5014; vrLoc = 5014;
@ -1131,6 +1141,99 @@
vrLen = 1033; vrLen = 1033;
vrLoc = 2157; vrLoc = 2157;
}; };
6B324ADA111C012300EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
rLen = 1;
rLoc = 631;
rType = 1;
};
6B324ADB111C012300EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 632";
rLen = 99;
rLoc = 26099;
rType = 0;
vrLen = 982;
vrLoc = 25496;
};
6B324ADD111C014A00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
comments = "warning: 'y' may be used uninitialized in this function";
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
rLen = 1;
rLoc = 1331;
rType = 1;
};
6B324ADE111C014A00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 1332";
rLen = 0;
rLoc = 50386;
rType = 0;
vrLen = 705;
vrLoc = 50169;
};
6B324AE0111C020F00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
comments = "warning: multi-line comment";
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
rLen = 1;
rLoc = 64;
rType = 1;
};
6B324AE1111C020F00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 65";
rLen = 0;
rLoc = 2715;
rType = 0;
vrLen = 984;
vrLoc = 2229;
};
6B324AE6111C07AB00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 641";
rLen = 0;
rLoc = 26733;
rType = 0;
vrLen = 909;
vrLoc = 26283;
};
6B324AE7111C07AB00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 218";
rLen = 0;
rLoc = 5177;
rType = 0;
vrLen = 470;
vrLoc = 5073;
};
6B324AE8111C07AB00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 641";
rLen = 0;
rLoc = 26733;
rType = 0;
vrLen = 909;
vrLoc = 26283;
};
6B324AE9111C07AB00EBD2FD /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 24";
rLen = 0;
rLoc = 1047;
rType = 0;
vrLen = 735;
vrLoc = 837;
};
6B555DAE100B211D00247EA3 /* imguiRenderGL.h */ = { 6B555DAE100B211D00247EA3 /* imguiRenderGL.h */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {915, 492}}"; sepNavIntBoundsRect = "{{0, 0}, {915, 492}}";
@ -1140,16 +1243,16 @@
}; };
6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */ = { 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {815, 7020}}"; sepNavIntBoundsRect = "{{0, 0}, {815, 6992}}";
sepNavSelRange = "{5173, 0}"; sepNavSelRange = "{1047, 0}";
sepNavVisRange = "{5073, 597}"; sepNavVisRange = "{837, 735}";
}; };
}; };
6B555DF6100B273500247EA3 /* stb_truetype.h */ = { 6B555DF6100B273500247EA3 /* stb_truetype.h */ = {
uiCtxt = { uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {815, 26848}}"; sepNavIntBoundsRect = "{{0, 0}, {1258, 29344}}";
sepNavSelRange = "{2449, 0}"; sepNavSelRange = "{26733, 0}";
sepNavVisRange = "{2157, 1033}"; sepNavVisRange = "{26283, 909}";
}; };
}; };
6B624169103434880002E346 /* RecastMeshDetail.cpp */ = { 6B624169103434880002E346 /* RecastMeshDetail.cpp */ = {
@ -1362,7 +1465,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */; fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 673"; name = "stb_truetype.h: 673";
rLen = 0; rLen = 0;
rLoc = 27352; rLoc = 27364;
rType = 0; rType = 0;
vrLen = 857; vrLen = 857;
vrLoc = 26962; vrLoc = 26962;

View File

@ -281,14 +281,13 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>13</integer> <integer>55</integer>
<integer>12</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 126}, {358, 643}}</string> <string>{{0, 606}, {358, 643}}</string>
</dict> </dict>
<key>PBXTopSmartGroupGIDs</key> <key>PBXTopSmartGroupGIDs</key>
<array/> <array/>
@ -323,7 +322,7 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>stb_truetype.h</string> <string>imguiRenderGL.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
<dict> <dict>
<key>Split0</key> <key>Split0</key>
@ -331,11 +330,11 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string> <string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>stb_truetype.h</string> <string>imguiRenderGL.cpp</string>
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>6B324AD8111C00D700EBD2FD</string> <string>6B324AE9111C07AB00EBD2FD</string>
<key>history</key> <key>history</key>
<array> <array>
<string>6B8DE70D10B01BBF00DF20FB</string> <string>6B8DE70D10B01BBF00DF20FB</string>
@ -393,11 +392,11 @@
<string>6B324AC4111C00D700EBD2FD</string> <string>6B324AC4111C00D700EBD2FD</string>
<string>6B324AC5111C00D700EBD2FD</string> <string>6B324AC5111C00D700EBD2FD</string>
<string>6B324AC6111C00D700EBD2FD</string> <string>6B324AC6111C00D700EBD2FD</string>
<string>6B324AC7111C00D700EBD2FD</string>
<string>6B324AC8111C00D700EBD2FD</string> <string>6B324AC8111C00D700EBD2FD</string>
<string>6B324AC9111C00D700EBD2FD</string> <string>6B324AC9111C00D700EBD2FD</string>
<string>6B324ACA111C00D700EBD2FD</string> <string>6B324ACA111C00D700EBD2FD</string>
<string>6B324ACB111C00D700EBD2FD</string> <string>6B324AE6111C07AB00EBD2FD</string>
<string>6B324AE7111C07AB00EBD2FD</string>
</array> </array>
<key>prevStack</key> <key>prevStack</key>
<array> <array>
@ -471,6 +470,7 @@
<string>6B324AD5111C00D700EBD2FD</string> <string>6B324AD5111C00D700EBD2FD</string>
<string>6B324AD6111C00D700EBD2FD</string> <string>6B324AD6111C00D700EBD2FD</string>
<string>6B324AD7111C00D700EBD2FD</string> <string>6B324AD7111C00D700EBD2FD</string>
<string>6B324AE8111C07AB00EBD2FD</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -484,18 +484,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {876, 399}}</string> <string>{{0, 0}, {876, 423}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string> <string>11 76 1256 702 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXNavigatorGroup</string> <string>PBXNavigatorGroup</string>
<key>Proportion</key> <key>Proportion</key>
<string>399pt</string> <string>423pt</string>
</dict> </dict>
<dict> <dict>
<key>Proportion</key> <key>Proportion</key>
<string>257pt</string> <string>233pt</string>
<key>Tabs</key> <key>Tabs</key>
<array> <array>
<dict> <dict>
@ -563,7 +563,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {876, 230}}</string> <string>{{10, 27}, {876, 206}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string> <string>11 76 1256 702 0 0 1280 778 </string>
</dict> </dict>

View File

@ -1,4 +1,4 @@
// stb_truetype.h - v0.2 - public domain - 2009 Sean Barrett / RAD Game Tools // stb_truetype.h - v0.3 - public domain - 2009 Sean Barrett / RAD Game Tools
// //
// This library processes TrueType files: // This library processes TrueType files:
// parse files // parse files
@ -7,13 +7,20 @@
// render glyphs to one-channel bitmaps with antialiasing (box filter) // render glyphs to one-channel bitmaps with antialiasing (box filter)
// //
// Todo: // Todo:
// non-MS cmaps
// crashproof on bad data // crashproof on bad data
// hinting // hinting
// subpixel positioning when rendering bitmap // subpixel positioning when rendering bitmap
// cleartype-style AA // cleartype-style AA
// //
// ADDITIONAL CONTRIBUTORS
//
// Mikko Mononen: compound shape support, more cmap formats
//
// VERSIONS // VERSIONS
// //
// 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
// userdata, malloc-from-userdata, non-zero fill (STB)
// 0.2 (2009-03-11) Fix unsigned/signed char warnings // 0.2 (2009-03-11) Fix unsigned/signed char warnings
// 0.1 (2009-03-09) First public release // 0.1 (2009-03-09) First public release
// //
@ -57,12 +64,12 @@
// recommend it. // recommend it.
// //
// //
// SOURCE STATISTICS (based on v.1, 1700 LOC) // SOURCE STATISTICS (based on v0.3, 1800 LOC)
// //
// Documentation & header file 350 LOC \___ 500 LOC documentation // Documentation & header file 350 LOC \___ 500 LOC documentation
// Sample code 140 LOC / // Sample code 140 LOC /
// Truetype parsing 480 LOC ---- 500 LOC TrueType // Truetype parsing 580 LOC ---- 600 LOC TrueType
// Software rasterization 240 LOC \ // Software rasterization 240 LOC \ .
// Curve tesselation 120 LOC \__ 500 LOC Bitmap creation // Curve tesselation 120 LOC \__ 500 LOC Bitmap creation
// Bitmap management 70 LOC / // Bitmap management 70 LOC /
// Baked bitmap interface 70 LOC / // Baked bitmap interface 70 LOC /
@ -130,18 +137,18 @@ void my_stbtt_print(float x, float y, char *text)
#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
#include "stb_truetype.h" #include "stb_truetype.h"
char ttf_buffer[1<<20]; char ttf_buffer[1<<25];
int main(int arg, char **argv) int main(int argc, char **argv)
{ {
stbtt_fontinfo font; stbtt_fontinfo font;
unsigned char *bitmap; unsigned char *bitmap;
int w,h,i,j; int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
fread(ttf_buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
stbtt_InitFont(&font, ttf_buffer, 0); stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, 20), 'a', &w, &h, 0,0); bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
for (j=0; j < h; ++j) { for (j=0; j < h; ++j) {
for (i=0; i < w; ++i) for (i=0; i < w; ++i)
@ -242,8 +249,8 @@ int main(int arg, char **argv)
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc #ifndef STBTT_malloc
#include <malloc.h> #include <malloc.h>
#define STBTT_malloc(x) malloc(x) #define STBTT_malloc(x,u) malloc(x)
#define STBTT_free(x) free(x) #define STBTT_free(x,u) free(x)
#endif #endif
#ifndef STBTT_assert #ifndef STBTT_assert
@ -335,6 +342,7 @@ extern int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// the stack or as a global or etc. // the stack or as a global or etc.
typedef struct typedef struct
{ {
void *userdata;
unsigned char *data; // pointer to .ttf file unsigned char *data; // pointer to .ttf file
int fontstart; // offset of start of font int fontstart; // offset of start of font
@ -431,7 +439,7 @@ extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbt
// returns # of vertices and fills *vertices with the pointer to them // returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates // these are expressed in "unscaled" coordinates
extern void stbtt_FreeShape(stbtt_vertex *vertices); extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
// frees the data allocated above // frees the data allocated above
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -439,7 +447,7 @@ extern void stbtt_FreeShape(stbtt_vertex *vertices);
// BITMAP RENDERING // BITMAP RENDERING
// //
extern void stbtt_FreeBitmap(unsigned char *bitmap); extern void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
// frees the bitmap allocated below // frees the bitmap allocated below
extern unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); extern unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
@ -477,7 +485,7 @@ typedef struct
unsigned char *pixels; unsigned char *pixels;
} stbtt__bitmap; } stbtt__bitmap;
extern void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert); extern void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert, void *userdata);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
@ -577,6 +585,7 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC
} }
#endif #endif
#endif // __STB_INCLUDE_STB_TRUETYPE_H__
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -629,7 +638,7 @@ static int stbtt__isfont(const stbtt_uint8 *font)
} }
// @OPTIMIZE: binary search // @OPTIMIZE: binary search
static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, char *tag) static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
{ {
stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
stbtt_uint32 tabledir = fontstart + 12; stbtt_uint32 tabledir = fontstart + 12;
@ -693,10 +702,16 @@ int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontsta
for (i=0; i < numTables; ++i) { for (i=0; i < numTables; ++i) {
stbtt_uint32 encoding_record = cmap + 4 + 8 * i; stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
// find an encoding we understand: // find an encoding we understand:
if (ttUSHORT(data+encoding_record) == 3 && ttUSHORT(data+encoding_record+2) == 1) { switch(ttUSHORT(data+encoding_record)) {
// MS/Unicode case STBTT_PLATFORM_ID_MICROSOFT:
info->index_map = cmap + ttULONG(data+encoding_record+4); switch (ttUSHORT(data+encoding_record+2)) {
break; case STBTT_MS_EID_UNICODE_BMP:
case STBTT_MS_EID_UNICODE_FULL:
// MS/Unicode
info->index_map = cmap + ttULONG(data+encoding_record+4);
break;
}
break;
} }
} }
if (info->index_map == 0) if (info->index_map == 0)
@ -760,7 +775,7 @@ int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
} }
search += 2; search += 2;
item = (search - endCount) >> 1; item = (stbtt_uint16) ((search - endCount) >> 1);
STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
@ -773,6 +788,25 @@ int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
return unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item); return unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item);
return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
} else if (format == 12) {
stbtt_uint16 ngroups = ttUSHORT(data+index_map+6);
stbtt_int32 low,high;
low = 0; high = (stbtt_int32)ngroups;
// Binary search the right group.
while (low <= high) {
stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
if ((stbtt_uint32) unicode_codepoint < start_char)
high = mid-1;
else if ((stbtt_uint32) unicode_codepoint > end_char)
low = mid+1;
else {
stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
return start_glyph + unicode_codepoint-start_char;
}
}
return 0; // not found
} }
// @TODO // @TODO
STBTT_assert(0); STBTT_assert(0);
@ -833,8 +867,8 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
stbtt_int16 numberOfContours; stbtt_int16 numberOfContours;
stbtt_uint8 *endPtsOfContours; stbtt_uint8 *endPtsOfContours;
stbtt_uint8 *data = info->data; stbtt_uint8 *data = info->data;
stbtt_vertex *vertices; stbtt_vertex *vertices=0;
int num_vertices; int num_vertices=0;
int g = stbtt__GetGlyfOffset(info, glyph_index); int g = stbtt__GetGlyfOffset(info, glyph_index);
*pvertices = NULL; *pvertices = NULL;
@ -844,7 +878,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
numberOfContours = ttSHORT(data + g); numberOfContours = ttSHORT(data + g);
if (numberOfContours > 0) { if (numberOfContours > 0) {
stbtt_uint8 flags,flagcount; stbtt_uint8 flags=0,flagcount;
stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off; stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off;
stbtt_int16 x,y,cx,cy,sx,sy; stbtt_int16 x,y,cx,cy,sx,sy;
stbtt_uint8 *points; stbtt_uint8 *points;
@ -855,7 +889,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
m = n + numberOfContours; // a loose bound on how many vertices we might need m = n + numberOfContours; // a loose bound on how many vertices we might need
vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0])); vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
if (vertices == 0) if (vertices == 0)
return 0; return 0;
@ -889,7 +923,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
x += (flags & 16) ? dx : -dx; // ??? x += (flags & 16) ? dx : -dx; // ???
} else { } else {
if (!(flags & 16)) { if (!(flags & 16)) {
x += (stbtt_int16) (points[0]*256 + points[1]); x = x + (stbtt_int16) (points[0]*256 + points[1]);
points += 2; points += 2;
} }
} }
@ -905,7 +939,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
y += (flags & 32) ? dy : -dy; // ??? y += (flags & 32) ? dy : -dy; // ???
} else { } else {
if (!(flags & 32)) { if (!(flags & 32)) {
y += (stbtt_int16) (points[0]*256 + points[1]); y = y + (stbtt_int16) (points[0]*256 + points[1]);
points += 2; points += 2;
} }
} }
@ -957,9 +991,88 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
else else
stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
} }
} else if (numberOfContours == -1) {
// Compound shapes.
int more = 1;
stbtt_uint8 *comp = data + g + 10;
num_vertices = 0;
vertices = 0;
while (more) {
stbtt_uint16 flags, gidx;
int comp_num_verts = 0, i;
stbtt_vertex *comp_verts = 0, *tmp = 0;
float mtx[6] = {1,0,0,1,0,0}, m, n;
flags = ttSHORT(comp); comp+=2;
gidx = ttSHORT(comp); comp+=2;
if (flags & 2) { // XY values
if (flags & 1) { // shorts
mtx[4] = ttSHORT(comp); comp+=2;
mtx[5] = ttSHORT(comp); comp+=2;
} else {
mtx[4] = ttCHAR(comp); comp+=1;
mtx[5] = ttCHAR(comp); comp+=1;
}
}
else {
// @TODO handle matching point
STBTT_assert(0);
}
if (flags & (1<<3)) { // WE_HAVE_A_SCALE
mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
} else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
} else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
}
// Find transformation scales.
m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
// Get indexed glyph.
comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
if (comp_num_verts > 0) {
// Transform vertices.
for (i = 0; i < comp_num_verts; ++i) {
stbtt_vertex* v = &comp_verts[i];
stbtt_vertex_type x,y;
x=v->x; y=v->y;
v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
x=v->cx; y=v->cy;
v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
}
// Append vertices.
tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
if (!tmp) {
if (vertices) STBTT_free(vertices, info->userdata);
if (comp_verts) STBTT_free(comp_verts, info->userdata);
return 0;
}
if (num_vertices > 0) memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
if (vertices) STBTT_free(vertices, info->userdata);
vertices = tmp;
STBTT_free(comp_verts, info->userdata);
num_vertices += comp_num_verts;
}
// More components ?
more = flags & (1<<5);
}
} else if (numberOfContours < 0) { } else if (numberOfContours < 0) {
// @TODO handle compound contours // @TODO other compound variations?
STBTT_assert(0); STBTT_assert(0);
} else {
// numberOfCounters == 0, do nothing
} }
*pvertices = vertices; *pvertices = vertices;
@ -1006,9 +1119,9 @@ float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
return (float) height / fheight; return (float) height / fheight;
} }
void stbtt_FreeShape(stbtt_vertex *v) void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
{ {
STBTT_free(v); STBTT_free(v, info->userdata);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -1035,6 +1148,7 @@ void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, floa
typedef struct stbtt__edge { typedef struct stbtt__edge {
float x0,y0, x1,y1; float x0,y0, x1,y1;
int invert;
} stbtt__edge; } stbtt__edge;
typedef struct stbtt__active_edge typedef struct stbtt__active_edge
@ -1049,9 +1163,9 @@ typedef struct stbtt__active_edge
#define FIX (1 << FIXSHIFT) #define FIX (1 << FIXSHIFT)
#define FIXMASK (FIX-1) #define FIXMASK (FIX-1)
static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_point) static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_point, void *userdata)
{ {
stbtt__active_edge *z = (stbtt__active_edge *) STBTT_malloc(sizeof(*z)); // @TODO: make a pool of these!!! stbtt__active_edge *z = (stbtt__active_edge *) STBTT_malloc(sizeof(*z), userdata); // @TODO: make a pool of these!!!
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(e->y0 <= start_point); STBTT_assert(e->y0 <= start_point);
if (!z) return z; if (!z) return z;
@ -1064,7 +1178,7 @@ static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_poi
z->x -= off_x * FIX; z->x -= off_x * FIX;
z->ey = e->y1; z->ey = e->y1;
z->next = 0; z->next = 0;
z->valid = 1; z->valid = e->invert ? 1 : -1;
return z; return z;
} }
@ -1073,46 +1187,47 @@ static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_poi
// are wrong, or if the user supplies a too-small bitmap // are wrong, or if the user supplies a too-small bitmap
static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
{ {
// @TODO: convert this from xor fill to non-zero winding // non-zero winding fill
int x0=0, w=0;
while (e) { while (e) {
int x0,x1,i,j; if (w == 0) {
// if we're currently at zero, we need to record the edge start point
x0 = e->x; w += e->valid;
} else {
int x1 = e->x; w += e->valid;
// if we went to zero, we need to draw
if (w == 0) {
int i = x0 >> FIXSHIFT;
int j = x1 >> FIXSHIFT;
x0 = e->x; e = e->next; if (i < len && j >= 0) {
if (!e) if (i == j) {
return; // unbalanced number of edges // x0,x1 are the same pixel, so compute combined coverage
scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> FIXSHIFT);
} else {
if (i >= 0) // add antialiasing for x0
scanline[i] = scanline[i] + (stbtt_uint8) (((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT);
else
i = -1; // clip
x1 = e->x; e = e->next; if (j < len) // add antialiasing for x1
STBTT_assert(x1 >= x0); scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT);
else
j = len; // clip
i = x0 >> FIXSHIFT; for (++i; i < j; ++i) // fill pixels between x0 and x1
j = x1 >> FIXSHIFT; scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
}
if (i < len && j >= 0) { }
if (i == j) {
// x0,x1 are the same pixel, so compute combined coverage
scanline[i] += (x1 - x0) * max_weight >> FIXSHIFT;
} else {
if (i >= 0) // add antialiasing for x0
scanline[i] += ((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT;
else
i = -1; // clip
if (j < len) // add antialiasing for x1
scanline[j] += ((x1 & FIXMASK) * max_weight) >> FIXSHIFT;
else
j = len; // clip
for (++i; i < j; ++i) // fill pixels between x0 and x1
scanline[i] += max_weight;
} }
} }
if (!e) e = e->next;
return;
} }
} }
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y) static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{ {
stbtt__active_edge *active = NULL; stbtt__active_edge *active = NULL;
int y,j=0; int y,j=0;
@ -1121,7 +1236,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
unsigned char scanline_data[512], *scanline; unsigned char scanline_data[512], *scanline;
if (result->w > 512) if (result->w > 512)
scanline = (unsigned char *) STBTT_malloc(result->w); scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
else else
scanline = scanline_data; scanline = scanline_data;
@ -1143,7 +1258,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
*step = z->next; // delete from list *step = z->next; // delete from list
STBTT_assert(z->valid); STBTT_assert(z->valid);
z->valid = 0; z->valid = 0;
STBTT_free(z); STBTT_free(z, userdata);
} else { } else {
z->x += z->dx; // advance to position for current scanline z->x += z->dx; // advance to position for current scanline
step = &((*step)->next); // advance through list step = &((*step)->next); // advance through list
@ -1172,7 +1287,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
// insert all edges that start before the center of this scanline -- omit ones that also end on this scanline // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
while (e->y0 <= scan_y) { while (e->y0 <= scan_y) {
if (e->y1 > scan_y) { if (e->y1 > scan_y) {
stbtt__active_edge *z = new_active(e, off_x, scan_y); stbtt__active_edge *z = new_active(e, off_x, scan_y, userdata);
// find insertion point // find insertion point
if (active == NULL) if (active == NULL)
active = z; active = z;
@ -1206,11 +1321,11 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (active) { while (active) {
stbtt__active_edge *z = active; stbtt__active_edge *z = active;
active = active->next; active = active->next;
STBTT_free(z); STBTT_free(z, userdata);
} }
if (scanline != scanline_data) if (scanline != scanline_data)
STBTT_free(scanline); STBTT_free(scanline, userdata);
} }
static int stbtt__edge_compare(const void *p, const void *q) static int stbtt__edge_compare(const void *p, const void *q)
@ -1228,7 +1343,7 @@ typedef struct
float x,y; float x,y;
} stbtt__point; } stbtt__point;
static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, int off_x, int off_y, int invert) static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, int off_x, int off_y, int invert, void *userdata)
{ {
float y_scale_inv = invert ? -scale_y : scale_y; float y_scale_inv = invert ? -scale_y : scale_y;
stbtt__edge *e; stbtt__edge *e;
@ -1241,7 +1356,7 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
for (i=0; i < windings; ++i) for (i=0; i < windings; ++i)
n += wcount[i]; n += wcount[i];
e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1)); // add an extra one as a sentinel e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
if (e == 0) return; if (e == 0) return;
n = 0; n = 0;
@ -1256,8 +1371,11 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
if (p[j].y == p[k].y) if (p[j].y == p[k].y)
continue; continue;
// add edge from j to k to the list // add edge from j to k to the list
if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) e[n].invert = 0;
if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
e[n].invert = 1;
a=j,b=k; a=j,b=k;
}
e[n].x0 = p[a].x * scale_x; e[n].x0 = p[a].x * scale_x;
e[n].y0 = p[a].y * y_scale_inv * vsubsample; e[n].y0 = p[a].y * y_scale_inv * vsubsample;
e[n].x1 = p[b].x * scale_x; e[n].x1 = p[b].x * scale_x;
@ -1270,9 +1388,9 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou
STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
// now, traverse the scanlines and find the intersections on each scanline, use xor winding rule // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y); stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
STBTT_free(e); STBTT_free(e, userdata);
} }
static void stbtt__add_point(stbtt__point *points, int n, float x, float y) static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
@ -1304,7 +1422,7 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x
} }
// returns number of contours // returns number of contours
stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours) stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
{ {
stbtt__point *points=0; stbtt__point *points=0;
int num_points=0; int num_points=0;
@ -1320,7 +1438,7 @@ stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float o
*num_contours = n; *num_contours = n;
if (n == 0) return 0; if (n == 0) return 0;
*contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n); *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
if (*contour_lengths == 0) { if (*contour_lengths == 0) {
*num_contours = 0; *num_contours = 0;
@ -1329,9 +1447,9 @@ stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float o
// make two passes through the points so we don't need to realloc // make two passes through the points so we don't need to realloc
for (pass=0; pass < 2; ++pass) { for (pass=0; pass < 2; ++pass) {
float x,y; float x=0,y=0;
if (pass == 1) { if (pass == 1) {
points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0])); points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
if (points == NULL) goto error; if (points == NULL) goto error;
} }
num_points = 0; num_points = 0;
@ -1366,28 +1484,28 @@ stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float o
return points; return points;
error: error:
STBTT_free(points); STBTT_free(points, userdata);
STBTT_free(*contour_lengths); STBTT_free(*contour_lengths, userdata);
*contour_lengths = 0; *contour_lengths = 0;
*num_contours = 0; *num_contours = 0;
return NULL; return NULL;
} }
void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert) void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, int x_off, int y_off, int invert, void *userdata)
{ {
float scale = scale_x > scale_y ? scale_y : scale_x; float scale = scale_x > scale_y ? scale_y : scale_x;
int winding_count, *winding_lengths; int winding_count, *winding_lengths;
stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count); stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
if (windings) { if (windings) {
stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, x_off, y_off, invert); stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, x_off, y_off, invert, userdata);
STBTT_free(winding_lengths); STBTT_free(winding_lengths, userdata);
STBTT_free(windings); STBTT_free(windings, userdata);
} }
} }
void stbtt_FreeBitmap(unsigned char *bitmap) void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
{ {
STBTT_free(bitmap); STBTT_free(bitmap, userdata);
} }
unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
@ -1416,14 +1534,14 @@ unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, f
if (yoff ) *yoff = iy0; if (yoff ) *yoff = iy0;
if (gbm.w && gbm.h) { if (gbm.w && gbm.h) {
gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h); gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
if (gbm.pixels) { if (gbm.pixels) {
gbm.stride = gbm.w; gbm.stride = gbm.w;
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0, iy0, 1); stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0, iy0, 1, info->userdata);
} }
} }
STBTT_free(vertices); STBTT_free(vertices, info->userdata);
return gbm.pixels; return gbm.pixels;
} }
@ -1441,9 +1559,9 @@ void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, in
gbm.stride = out_stride; gbm.stride = out_stride;
if (gbm.w && gbm.h) if (gbm.w && gbm.h)
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0,iy0, 1); stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, ix0,iy0, 1, info->userdata);
STBTT_free(vertices); STBTT_free(vertices, info->userdata);
} }
unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
@ -1492,10 +1610,10 @@ extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font
STBTT_assert(x+gw < pw); STBTT_assert(x+gw < pw);
STBTT_assert(y+gh < ph); STBTT_assert(y+gh < ph);
stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
chardata[i].x0 = x; chardata[i].x0 = (stbtt_int16) x;
chardata[i].y0 = y; chardata[i].y0 = (stbtt_int16) y;
chardata[i].x1 = x + gw; chardata[i].x1 = (stbtt_int16) (x + gw);
chardata[i].y1 = y + gh; chardata[i].y1 = (stbtt_int16) (y + gh);
chardata[i].xadvance = scale * advance; chardata[i].xadvance = scale * advance;
chardata[i].xoff = (float) x0; chardata[i].xoff = (float) x0;
chardata[i].yoff = (float) y0; chardata[i].yoff = (float) y0;
@ -1509,19 +1627,20 @@ extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font
void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
{ {
float d3d_bias = opengl_fillrule ? 0 : -0.5f; float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
stbtt_bakedchar *b = chardata + char_index; stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5); int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5);
int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5); int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5);
q->x0 = round_x - 0.5f + d3d_bias; q->x0 = round_x + d3d_bias;
q->y0 = round_y - 0.5f + d3d_bias; q->y0 = round_y + d3d_bias;
q->x1 = round_x + b->x1 - b->x0 + 0.5f + d3d_bias; q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
q->y1 = round_y + b->y1 - b->y0 + 0.5f + d3d_bias; q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
q->s0 = (b->x0 - 0.5f) / pw; q->s0 = b->x0 * ipw;
q->t0 = (b->y0 - 0.5f) / pw; q->t0 = b->y0 * ipw;
q->s1 = (b->x1 + 0.5f) / ph; q->s1 = b->x1 * iph;
q->t1 = (b->y1 + 0.5f) / ph; q->t1 = b->y1 * iph;
*xpos += b->xadvance; *xpos += b->xadvance;
} }
@ -1685,5 +1804,3 @@ int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *nam
} }
#endif // STB_TRUETYPE_IMPLEMENTATION #endif // STB_TRUETYPE_IMPLEMENTATION
#endif // __STB_INCLUDE_STB_TRUETYPE_H__

View File

@ -21,8 +21,8 @@
#include "imgui.h" #include "imgui.h"
#include "SDL.h" #include "SDL.h"
#include "SDL_opengl.h" #include "SDL_opengl.h"
#define STBTT_malloc(x) malloc(x) #define STBTT_malloc(x,y) malloc(x)
#define STBTT_free(x) free(x) #define STBTT_free(x,y) free(x)
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h" #include "stb_truetype.h"