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 */;
6B324AD7111C00D700EBD2FD /* PBXTextBookmark */ = 6B324AD7111C00D700EBD2FD /* 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 */;
6B6973A210FFCA4500984788 = 6B6973A210FFCA4500984788 /* PBXTextBookmark */;
6B8DE70D10B01BBF00DF20FB = 6B8DE70D10B01BBF00DF20FB /* PBXTextBookmark */;
@ -778,7 +788,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 217";
rLen = 0;
rLoc = 5230;
rLoc = 5234;
rType = 0;
vrLen = 474;
vrLoc = 4904;
@ -808,7 +818,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 217";
rLen = 0;
rLoc = 5230;
rLoc = 5234;
rType = 0;
vrLen = 474;
vrLoc = 4904;
@ -848,7 +858,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 667";
rLen = 0;
rLoc = 27261;
rLoc = 27273;
rType = 0;
vrLen = 975;
vrLoc = 26909;
@ -878,7 +888,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 667";
rLen = 0;
rLoc = 27261;
rLoc = 27273;
rType = 0;
vrLen = 975;
vrLoc = 26909;
@ -958,7 +968,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 218";
rLen = 0;
rLoc = 5173;
rLoc = 5177;
rType = 0;
vrLen = 529;
vrLoc = 5014;
@ -1086,7 +1096,7 @@
fRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */;
name = "imguiRenderGL.cpp: 218";
rLen = 0;
rLoc = 5173;
rLoc = 5177;
rType = 0;
vrLen = 529;
vrLoc = 5014;
@ -1131,6 +1141,99 @@
vrLen = 1033;
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 */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {915, 492}}";
@ -1140,16 +1243,16 @@
};
6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {815, 7020}}";
sepNavSelRange = "{5173, 0}";
sepNavVisRange = "{5073, 597}";
sepNavIntBoundsRect = "{{0, 0}, {815, 6992}}";
sepNavSelRange = "{1047, 0}";
sepNavVisRange = "{837, 735}";
};
};
6B555DF6100B273500247EA3 /* stb_truetype.h */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {815, 26848}}";
sepNavSelRange = "{2449, 0}";
sepNavVisRange = "{2157, 1033}";
sepNavIntBoundsRect = "{{0, 0}, {1258, 29344}}";
sepNavSelRange = "{26733, 0}";
sepNavVisRange = "{26283, 909}";
};
};
6B624169103434880002E346 /* RecastMeshDetail.cpp */ = {
@ -1362,7 +1465,7 @@
fRef = 6B555DF6100B273500247EA3 /* stb_truetype.h */;
name = "stb_truetype.h: 673";
rLen = 0;
rLoc = 27352;
rLoc = 27364;
rType = 0;
vrLen = 857;
vrLoc = 26962;

View File

@ -281,14 +281,13 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>13</integer>
<integer>12</integer>
<integer>55</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 126}, {358, 643}}</string>
<string>{{0, 606}, {358, 643}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -323,7 +322,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>stb_truetype.h</string>
<string>imguiRenderGL.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -331,11 +330,11 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>stb_truetype.h</string>
<string>imguiRenderGL.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6B324AD8111C00D700EBD2FD</string>
<string>6B324AE9111C07AB00EBD2FD</string>
<key>history</key>
<array>
<string>6B8DE70D10B01BBF00DF20FB</string>
@ -393,11 +392,11 @@
<string>6B324AC4111C00D700EBD2FD</string>
<string>6B324AC5111C00D700EBD2FD</string>
<string>6B324AC6111C00D700EBD2FD</string>
<string>6B324AC7111C00D700EBD2FD</string>
<string>6B324AC8111C00D700EBD2FD</string>
<string>6B324AC9111C00D700EBD2FD</string>
<string>6B324ACA111C00D700EBD2FD</string>
<string>6B324ACB111C00D700EBD2FD</string>
<string>6B324AE6111C07AB00EBD2FD</string>
<string>6B324AE7111C07AB00EBD2FD</string>
</array>
<key>prevStack</key>
<array>
@ -471,6 +470,7 @@
<string>6B324AD5111C00D700EBD2FD</string>
<string>6B324AD6111C00D700EBD2FD</string>
<string>6B324AD7111C00D700EBD2FD</string>
<string>6B324AE8111C07AB00EBD2FD</string>
</array>
</dict>
<key>SplitCount</key>
@ -484,18 +484,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {876, 399}}</string>
<string>{{0, 0}, {876, 423}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>399pt</string>
<string>423pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>257pt</string>
<string>233pt</string>
<key>Tabs</key>
<array>
<dict>
@ -563,7 +563,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {876, 230}}</string>
<string>{{10, 27}, {876, 206}}</string>
<key>RubberWindowFrame</key>
<string>11 76 1256 702 0 0 1280 778 </string>
</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:
// parse files
@ -7,13 +7,20 @@
// render glyphs to one-channel bitmaps with antialiasing (box filter)
//
// Todo:
// non-MS cmaps
// crashproof on bad data
// hinting
// subpixel positioning when rendering bitmap
// cleartype-style AA
//
// ADDITIONAL CONTRIBUTORS
//
// Mikko Mononen: compound shape support, more cmap formats
//
// 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.1 (2009-03-09) First public release
//
@ -57,12 +64,12 @@
// 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
// Sample code 140 LOC /
// Truetype parsing 480 LOC ---- 500 LOC TrueType
// Software rasterization 240 LOC \
// Truetype parsing 580 LOC ---- 600 LOC TrueType
// Software rasterization 240 LOC \ .
// Curve tesselation 120 LOC \__ 500 LOC Bitmap creation
// Bitmap management 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
#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;
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);
bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, 20), 'a', &w, &h, 0,0);
stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
for (j=0; j < h; ++j) {
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
#ifndef STBTT_malloc
#include <malloc.h>
#define STBTT_malloc(x) malloc(x)
#define STBTT_free(x) free(x)
#define STBTT_malloc(x,u) malloc(x)
#define STBTT_free(x,u) free(x)
#endif
#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.
typedef struct
{
void *userdata;
unsigned char *data; // pointer to .ttf file
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
// 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
//////////////////////////////////////////////////////////////////////////////
@ -439,7 +447,7 @@ extern void stbtt_FreeShape(stbtt_vertex *vertices);
// BITMAP RENDERING
//
extern void stbtt_FreeBitmap(unsigned char *bitmap);
extern void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
// 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);
@ -477,7 +485,7 @@ typedef struct
unsigned char *pixels;
} 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 // __STB_INCLUDE_STB_TRUETYPE_H__
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@ -629,7 +638,7 @@ static int stbtt__isfont(const stbtt_uint8 *font)
}
// @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_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) {
stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
// find an encoding we understand:
if (ttUSHORT(data+encoding_record) == 3 && ttUSHORT(data+encoding_record+2) == 1) {
// MS/Unicode
info->index_map = cmap + ttULONG(data+encoding_record+4);
break;
switch(ttUSHORT(data+encoding_record)) {
case STBTT_PLATFORM_ID_MICROSOFT:
switch (ttUSHORT(data+encoding_record+2)) {
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)
@ -760,7 +775,7 @@ int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
}
search += 2;
item = (search - endCount) >> 1;
item = (stbtt_uint16) ((search - endCount) >> 1);
STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 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 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
STBTT_assert(0);
@ -833,8 +867,8 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
stbtt_int16 numberOfContours;
stbtt_uint8 *endPtsOfContours;
stbtt_uint8 *data = info->data;
stbtt_vertex *vertices;
int num_vertices;
stbtt_vertex *vertices=0;
int num_vertices=0;
int g = stbtt__GetGlyfOffset(info, glyph_index);
*pvertices = NULL;
@ -844,7 +878,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
numberOfContours = ttSHORT(data + g);
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_int16 x,y,cx,cy,sx,sy;
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);
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)
return 0;
@ -889,7 +923,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
x += (flags & 16) ? dx : -dx; // ???
} else {
if (!(flags & 16)) {
x += (stbtt_int16) (points[0]*256 + points[1]);
x = x + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
}
}
@ -905,7 +939,7 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
y += (flags & 32) ? dy : -dy; // ???
} else {
if (!(flags & 32)) {
y += (stbtt_int16) (points[0]*256 + points[1]);
y = y + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
}
}
@ -957,10 +991,89 @@ int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_verte
else
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) {
// @TODO handle compound contours
// @TODO other compound variations?
STBTT_assert(0);
}
} else {
// numberOfCounters == 0, do nothing
}
*pvertices = vertices;
return num_vertices;
@ -1006,9 +1119,9 @@ float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
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 {
float x0,y0, x1,y1;
int invert;
} stbtt__edge;
typedef struct stbtt__active_edge
@ -1049,9 +1163,9 @@ typedef struct stbtt__active_edge
#define FIX (1 << FIXSHIFT)
#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);
STBTT_assert(e->y0 <= start_point);
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->ey = e->y1;
z->next = 0;
z->valid = 1;
z->valid = e->invert ? 1 : -1;
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
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) {
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 (!e)
return; // unbalanced number of edges
if (i < len && j >= 0) {
if (i == j) {
// 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;
STBTT_assert(x1 >= x0);
if (j < len) // add antialiasing for x1
scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT);
else
j = len; // clip
i = x0 >> FIXSHIFT;
j = x1 >> FIXSHIFT;
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;
for (++i; i < j; ++i) // fill pixels between x0 and x1
scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
}
}
}
}
if (!e)
return;
e = e->next;
}
}
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;
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;
if (result->w > 512)
scanline = (unsigned char *) STBTT_malloc(result->w);
scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
else
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
STBTT_assert(z->valid);
z->valid = 0;
STBTT_free(z);
STBTT_free(z, userdata);
} else {
z->x += z->dx; // advance to position for current scanline
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
while (e->y0 <= 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
if (active == NULL)
active = z;
@ -1206,11 +1321,11 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (active) {
stbtt__active_edge *z = active;
active = active->next;
STBTT_free(z);
STBTT_free(z, userdata);
}
if (scanline != scanline_data)
STBTT_free(scanline);
STBTT_free(scanline, userdata);
}
static int stbtt__edge_compare(const void *p, const void *q)
@ -1228,7 +1343,7 @@ typedef struct
float x,y;
} 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;
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)
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;
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)
continue;
// 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;
}
e[n].x0 = p[a].x * scale_x;
e[n].y0 = p[a].y * y_scale_inv * vsubsample;
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);
// 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)
@ -1304,7 +1422,7 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x
}
// 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;
int num_points=0;
@ -1320,7 +1438,7 @@ stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float o
*num_contours = n;
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) {
*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
for (pass=0; pass < 2; ++pass) {
float x,y;
float x=0,y=0;
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;
}
num_points = 0;
@ -1366,28 +1484,28 @@ stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float o
return points;
error:
STBTT_free(points);
STBTT_free(*contour_lengths);
STBTT_free(points, userdata);
STBTT_free(*contour_lengths, userdata);
*contour_lengths = 0;
*num_contours = 0;
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;
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) {
stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, x_off, y_off, invert);
STBTT_free(winding_lengths);
STBTT_free(windings);
stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, x_off, y_off, invert, userdata);
STBTT_free(winding_lengths, userdata);
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)
@ -1416,14 +1534,14 @@ unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, f
if (yoff ) *yoff = iy0;
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) {
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;
}
@ -1441,9 +1559,9 @@ void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, in
gbm.stride = out_stride;
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)
@ -1492,10 +1610,10 @@ extern int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font
STBTT_assert(x+gw < pw);
STBTT_assert(y+gh < ph);
stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
chardata[i].x0 = x;
chardata[i].y0 = y;
chardata[i].x1 = x + gw;
chardata[i].y1 = y + gh;
chardata[i].x0 = (stbtt_int16) x;
chardata[i].y0 = (stbtt_int16) y;
chardata[i].x1 = (stbtt_int16) (x + gw);
chardata[i].y1 = (stbtt_int16) (y + gh);
chardata[i].xadvance = scale * advance;
chardata[i].xoff = (float) x0;
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)
{
float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5);
int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5);
q->x0 = round_x - 0.5f + d3d_bias;
q->y0 = round_y - 0.5f + d3d_bias;
q->x1 = round_x + b->x1 - b->x0 + 0.5f + d3d_bias;
q->y1 = round_y + b->y1 - b->y0 + 0.5f + d3d_bias;
q->x0 = round_x + d3d_bias;
q->y0 = round_y + d3d_bias;
q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
q->s0 = (b->x0 - 0.5f) / pw;
q->t0 = (b->y0 - 0.5f) / pw;
q->s1 = (b->x1 + 0.5f) / ph;
q->t1 = (b->y1 + 0.5f) / ph;
q->s0 = b->x0 * ipw;
q->t0 = b->y0 * ipw;
q->s1 = b->x1 * iph;
q->t1 = b->y1 * iph;
*xpos += b->xadvance;
}
@ -1685,5 +1804,3 @@ int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *nam
}
#endif // STB_TRUETYPE_IMPLEMENTATION
#endif // __STB_INCLUDE_STB_TRUETYPE_H__

View File

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