From f7d0f25c07ac1878249e8d5d80dc0541337da9ae Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 22 Sep 2015 14:46:28 +0200 Subject: [PATCH] Start making stb_truetype more C89-compliant --- deps/stb/stb_truetype.h | 1563 +++++++++++++++++++-------------------- 1 file changed, 781 insertions(+), 782 deletions(-) diff --git a/deps/stb/stb_truetype.h b/deps/stb/stb_truetype.h index 13d4b9f58f..194ceb5450 100644 --- a/deps/stb/stb_truetype.h +++ b/deps/stb/stb_truetype.h @@ -1,401 +1,259 @@ -// stb_truetype.h - v1.06 - public domain -// authored from 2009-2014 by Sean Barrett / RAD Game Tools -// -// This library processes TrueType files: -// parse files -// extract glyph metrics -// extract glyph shapes -// render glyphs to one-channel bitmaps with antialiasing (box filter) -// -// Todo: -// non-MS cmaps -// crashproof on bad data -// hinting? (no longer patented) -// cleartype-style AA? -// optimize: use simple memory allocator for intermediates -// optimize: build edge-list directly from curves -// optimize: rasterize directly from curves? -// -// ADDITIONAL CONTRIBUTORS -// -// Mikko Mononen: compound shape support, more cmap formats -// Tor Andersson: kerning, subpixel rendering -// -// Bug/warning reports/fixes: -// "Zer" on mollyrocket (with fix) -// Cass Everitt -// stoiko (Haemimont Games) -// Brian Hook -// Walter van Niftrik -// David Gow -// David Given -// Ivan-Assen Ivanov -// Anthony Pesch -// Johan Duparc -// Hou Qiming -// Fabian "ryg" Giesen -// Martins Mozeiko -// Cap Petschulat -// Omar Cornut -// github:aloucks -// Peter LaValle -// -// Misc other: -// Ryan Gordon -// -// VERSION HISTORY -// -// 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) -// also more precise AA rasterizer, except if shapes overlap -// remove need for STBTT_sort -// 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC -// 1.04 (2015-04-15) typo in example -// 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes -// 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ -// 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match -// non-oversampled; STBTT_POINT_SIZE for packed case only -// 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 -// 0.8 (2014-05-25) fix a few more warnings -// 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back -// 0.6c (2012-07-24) improve documentation -// 0.6b (2012-07-20) fix a few more warnings -// 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, -// stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty -// 0.5 (2011-12-09) bugfixes: -// subpixel glyph renderer computed wrong bounding box -// first vertex of shape can be off-curve (FreeSans) -// 0.4b (2011-12-03) fixed an error in the font baking example -// 0.4 (2011-12-01) kerning, subpixel rendering (tor) -// bugfixes for: -// codepoint-to-glyph conversion using table fmt=12 -// codepoint-to-glyph conversion using table fmt=4 -// stbtt_GetBakedQuad with non-square texture (Zer) -// 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) -// 0.2 (2009-03-11) Fix unsigned/signed char warnings -// 0.1 (2009-03-09) First public release -// -// LICENSE -// -// This software is in the public domain. Where that dedication is not -// recognized, you are granted a perpetual, irrevokable license to copy -// and modify this file as you see fit. -// -// USAGE -// -// Include this file in whatever places neeed to refer to it. In ONE C/C++ -// file, write: -// #define STB_TRUETYPE_IMPLEMENTATION -// before the #include of this file. This expands out the actual -// implementation into that C/C++ file. -// -// To make the implementation private to the file that generates the implementation, -// #define STBTT_STATIC -// -// 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 -// -// Render a unicode codepoint to a bitmap -// stbtt_GetCodepointBitmap() -- allocates and returns a bitmap -// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide -// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be -// -// Character advance/positioning -// stbtt_GetCodepointHMetrics() -// stbtt_GetFontVMetrics() -// stbtt_GetCodepointKernAdvance() -// -// Starting with version 1.06, the rasterizer was replaced with a new, -// faster and generally-more-precise rasterizer. The new rasterizer more -// accurately measures pixel coverage for anti-aliasing, except in the case -// where multiple shapes overlap, in which case it overestimates the AA pixel -// coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If -// this turns out to be a problem, you can re-enable the old rasterizer with -// #define STBTT_RASTERIZER_VERSION 1 -// which will incur about a 15% speed hit. -// -// ADDITIONAL DOCUMENTATION -// -// Immediately after this block comment are a series of sample programs. -// -// After the sample programs is the "header file" section. This section -// includes documentation for each API function. -// -// Some important concepts to understand to use this library: -// -// Codepoint -// Characters are defined by unicode codepoints, e.g. 65 is -// uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is -// the hiragana for "ma". -// -// Glyph -// A visual character shape (every codepoint is rendered as -// some glyph) -// -// Glyph index -// A font-specific integer ID representing a glyph -// -// Baseline -// Glyph shapes are defined relative to a baseline, which is the -// bottom of uppercase characters. Characters extend both above -// and below the baseline. -// -// Current Point -// As you draw text to the screen, you keep track of a "current point" -// which is the origin of each character. The current point's vertical -// position is the baseline. Even "baked fonts" use this model. -// -// Vertical Font Metrics -// The vertical qualities of the font, used to vertically position -// and space the characters. See docs for stbtt_GetFontVMetrics. -// -// Font Size in Pixels or Points -// The preferred interface for specifying font sizes in stb_truetype -// is to specify how tall the font's vertical extent should be in pixels. -// If that sounds good enough, skip the next paragraph. -// -// Most font APIs instead use "points", which are a common typographic -// measurement for describing font size, defined as 72 points per inch. -// stb_truetype provides a point API for compatibility. However, true -// "per inch" conventions don't make much sense on computer displays -// since they different monitors have different number of pixels per -// inch. For example, Windows traditionally uses a convention that -// there are 96 pixels per inch, thus making 'inch' measurements have -// nothing to do with inches, and thus effectively defining a point to -// be 1.333 pixels. Additionally, the TrueType font data provides -// an explicit scale factor to scale a given font's glyphs to points, -// but the author has observed that this scale factor is often wrong -// for non-commercial fonts, thus making fonts scaled in points -// according to the TrueType spec incoherently sized in practice. -// -// ADVANCED USAGE -// -// Quality: -// -// - Use the functions with Subpixel at the end to allow your characters -// to have subpixel positioning. Since the font is anti-aliased, not -// hinted, this is very import for quality. (This is not possible with -// baked fonts.) -// -// - Kerning is now supported, and if you're supporting subpixel rendering -// then kerning is worth using to give your text a polished look. -// -// Performance: -// -// - Convert Unicode codepoints to glyph indexes and operate on the glyphs; -// if you don't do this, stb_truetype is forced to do the conversion on -// every call. -// -// - There are a lot of memory allocations. We should modify it to take -// a temp buffer and allocate from the temp buffer (without freeing), -// should help performance a lot. -// -// NOTES -// -// The system uses the raw data found in the .ttf file without changing it -// and without building auxiliary data structures. This is a bit inefficient -// on little-endian systems (the data is big-endian), but assuming you're -// caching the bitmaps or glyph shapes this shouldn't be a big deal. -// -// It appears to be very hard to programmatically determine what font a -// given file is in a general way. I provide an API for this, but I don't -// recommend it. -// -// -// SOURCE STATISTICS (based on v0.6c, 2050 LOC) -// -// Documentation & header file 520 LOC \___ 660 LOC documentation -// Sample code 140 LOC / -// Truetype parsing 620 LOC ---- 620 LOC TrueType -// Software rasterization 240 LOC \ . -// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation -// Bitmap management 100 LOC / -// Baked bitmap interface 70 LOC / -// Font name matching & access 150 LOC ---- 150 -// C runtime library abstraction 60 LOC ---- 60 -// -// -// PERFORMANCE MEASUREMENTS FOR 1.06: -// -// 32-bit 64-bit -// Previous release: 8.83 s 7.68 s -// Pool allocations: 7.72 s 6.34 s -// Inline sort : 6.54 s 5.65 s -// New rasterizer : 5.63 s 5.00 s +/* + * stb_truetype.h - v1.06 - public domain + * authored from 2009-2014 by Sean Barrett / RAD Game Tools + * + * This library processes TrueType files: + * parse files + * extract glyph metrics + * extract glyph shapes + * render glyphs to one-channel bitmaps with antialiasing (box filter) + * + * Todo: + * non-MS cmaps + * crashproof on bad data + * hinting? (no longer patented) + * cleartype-style AA? + * optimize: use simple memory allocator for intermediates + * optimize: build edge-list directly from curves + * optimize: rasterize directly from curves? + * + * ADDITIONAL CONTRIBUTORS + * + * Mikko Mononen: compound shape support, more cmap formats + * Tor Andersson: kerning, subpixel rendering + * + * Bug/warning reports/fixes: + * "Zer" on mollyrocket (with fix) + * Cass Everitt + * stoiko (Haemimont Games) + * Brian Hook + * Walter van Niftrik + * David Gow + * David Given + * Ivan-Assen Ivanov + * Anthony Pesch + * Johan Duparc + * Hou Qiming + * Fabian "ryg" Giesen + * Martins Mozeiko + * Cap Petschulat + * Omar Cornut + * github:aloucks + * Peter LaValle + * + * Misc other: + * Ryan Gordon + * + * VERSION HISTORY + * + * 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) + * also more precise AA rasterizer, except if shapes overlap + * remove need for STBTT_sort + * 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC + * 1.04 (2015-04-15) typo in example + * 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes + * 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ + * 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match + * non-oversampled; STBTT_POINT_SIZE for packed case only + * 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 + * 0.8 (2014-05-25) fix a few more warnings + * 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back + * 0.6c (2012-07-24) improve documentation + * 0.6b (2012-07-20) fix a few more warnings + * 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, + * stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty + * 0.5 (2011-12-09) bugfixes: + * subpixel glyph renderer computed wrong bounding box + * first vertex of shape can be off-curve (FreeSans) + * 0.4b (2011-12-03) fixed an error in the font baking example + * 0.4 (2011-12-01) kerning, subpixel rendering (tor) + * bugfixes for: + * codepoint-to-glyph conversion using table fmt=12 + * codepoint-to-glyph conversion using table fmt=4 + * stbtt_GetBakedQuad with non-square texture (Zer) + * 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) + * 0.2 (2009-03-11) Fix unsigned/signed char warnings + * 0.1 (2009-03-09) First public release + * + * LICENSE + * + * This software is in the public domain. Where that dedication is not + * recognized, you are granted a perpetual, irrevokable license to copy + * and modify this file as you see fit. + * + * USAGE + * + * Include this file in whatever places neeed to refer to it. In ONE C/C++ + * file, write: + * #define STB_TRUETYPE_IMPLEMENTATION + * before the #include of this file. This expands out the actual + * implementation into that C/C++ file. + * + * To make the implementation private to the file that generates the implementation, + * #define STBTT_STATIC + * + * 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 + * + * Render a unicode codepoint to a bitmap + * stbtt_GetCodepointBitmap() -- allocates and returns a bitmap + * stbtt_MakeCodepointBitmap() -- renders into bitmap you provide + * stbtt_GetCodepointBitmapBox() -- how big the bitmap must be + * + * Character advance/positioning + * stbtt_GetCodepointHMetrics() + * stbtt_GetFontVMetrics() + * stbtt_GetCodepointKernAdvance() + * + * Starting with version 1.06, the rasterizer was replaced with a new, + * faster and generally-more-precise rasterizer. The new rasterizer more + * accurately measures pixel coverage for anti-aliasing, except in the case + * where multiple shapes overlap, in which case it overestimates the AA pixel + * coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If + * this turns out to be a problem, you can re-enable the old rasterizer with + * #define STBTT_RASTERIZER_VERSION 1 + * which will incur about a 15% speed hit. + * + * ADDITIONAL DOCUMENTATION + * + * Immediately after this block comment are a series of sample programs. + * + * After the sample programs is the "header file" section. This section + * includes documentation for each API function. + * + * Some important concepts to understand to use this library: + * + * Codepoint + * Characters are defined by unicode codepoints, e.g. 65 is + * uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is + * the hiragana for "ma". + * + * Glyph + * A visual character shape (every codepoint is rendered as + * some glyph) + * + * Glyph index + * A font-specific integer ID representing a glyph + * + * Baseline + * Glyph shapes are defined relative to a baseline, which is the + * bottom of uppercase characters. Characters extend both above + * and below the baseline. + * + * Current Point + * As you draw text to the screen, you keep track of a "current point" + * which is the origin of each character. The current point's vertical + * position is the baseline. Even "baked fonts" use this model. + * + * Vertical Font Metrics + * The vertical qualities of the font, used to vertically position + * and space the characters. See docs for stbtt_GetFontVMetrics. + * + * Font Size in Pixels or Points + * The preferred interface for specifying font sizes in stb_truetype + * is to specify how tall the font's vertical extent should be in pixels. + * If that sounds good enough, skip the next paragraph. + * + * Most font APIs instead use "points", which are a common typographic + * measurement for describing font size, defined as 72 points per inch. + * stb_truetype provides a point API for compatibility. However, true + * "per inch" conventions don't make much sense on computer displays + * since they different monitors have different number of pixels per + * inch. For example, Windows traditionally uses a convention that + * there are 96 pixels per inch, thus making 'inch' measurements have + * nothing to do with inches, and thus effectively defining a point to + * be 1.333 pixels. Additionally, the TrueType font data provides + * an explicit scale factor to scale a given font's glyphs to points, + * but the author has observed that this scale factor is often wrong + * for non-commercial fonts, thus making fonts scaled in points + * according to the TrueType spec incoherently sized in practice. + * + * ADVANCED USAGE + * + * Quality: + * + * - Use the functions with Subpixel at the end to allow your characters + * to have subpixel positioning. Since the font is anti-aliased, not + * hinted, this is very import for quality. (This is not possible with + * baked fonts.) + * + * - Kerning is now supported, and if you're supporting subpixel rendering + * then kerning is worth using to give your text a polished look. + * + * Performance: + * + * - Convert Unicode codepoints to glyph indexes and operate on the glyphs; + * if you don't do this, stb_truetype is forced to do the conversion on + * every call. + * + * - There are a lot of memory allocations. We should modify it to take + * a temp buffer and allocate from the temp buffer (without freeing), + * should help performance a lot. + * + * NOTES + * + * The system uses the raw data found in the .ttf file without changing it + * and without building auxiliary data structures. This is a bit inefficient + * on little-endian systems (the data is big-endian), but assuming you're + * caching the bitmaps or glyph shapes this shouldn't be a big deal. + * + * It appears to be very hard to programmatically determine what font a + * given file is in a general way. I provide an API for this, but I don't + * recommend it. + * + * + * SOURCE STATISTICS (based on v0.6c, 2050 LOC) + * + * Documentation & header file 520 LOC \___ 660 LOC documentation + * Sample code 140 LOC / + * Truetype parsing 620 LOC ---- 620 LOC TrueType + * Software rasterization 240 LOC \ . + * Curve tesselation 120 LOC \__ 550 LOC Bitmap creation + * Bitmap management 100 LOC / + * Baked bitmap interface 70 LOC / + * Font name matching & access 150 LOC ---- 150 + * C runtime library abstraction 60 LOC ---- 60 + * + * + * PERFORMANCE MEASUREMENTS FOR 1.06: + * + * 32-bit 64-bit + * Previous release: 8.83 s 7.68 s + * Pool allocations: 7.72 s 6.34 s + * Inline sort : 6.54 s 5.65 s + * New rasterizer : 5.63 s 5.00 s +*/ -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -//// -//// SAMPLE PROGRAMS -//// -// -// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless -// -#if 0 -#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation -#include "stb_truetype.h" +/* SAMPLE PROGRAMS + * Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless + */ -unsigned char ttf_buffer[1<<20]; -unsigned char temp_bitmap[512*512]; +/* INTEGRATION WITH YOUR CODEBASE */ -stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs -GLuint ftex; - -void my_stbtt_initfont(void) -{ - fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb")); - stbtt_BakeFontBitmap(ttf_buffer,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits! - // can free ttf_buffer at this point - glGenTextures(1, &ftex); - glBindTexture(GL_TEXTURE_2D, ftex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap); - // can free temp_bitmap at this point - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -} - -void my_stbtt_print(float x, float y, char *text) -{ - // assume orthographic projection with units = screen pixels, origin at top left - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, ftex); - glBegin(GL_QUADS); - while (*text) { - if (*text >= 32 && *text < 128) { - stbtt_aligned_quad q; - stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 - glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); - glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); - glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); - glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); - } - ++text; - } - glEnd(); -} -#endif -// -// -////////////////////////////////////////////////////////////////////////////// -// -// Complete program (this compiles): get a single bitmap, print as ASCII art -// -#if 0 -#include -#define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation -#include "stb_truetype.h" - -char ttf_buffer[1<<25]; - -int main(int argc, char **argv) -{ - stbtt_fontinfo font; - unsigned char *bitmap; - int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); - - fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); - - 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) - putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); - putchar('\n'); - } - return 0; -} -#endif -// -// Output: -// -// .ii. -// @@@@@@. -// V@Mio@@o -// :i. V@V -// :oM@@M -// :@@@MM@M -// @@o o@M -// :@@. M@M -// @@@o@@@@ -// :M@@V:@@. -// -////////////////////////////////////////////////////////////////////////////// -// -// Complete program: print "Hello World!" banner, with bugs -// -#if 0 -char buffer[24<<20]; -unsigned char screen[20][79]; - -int main(int arg, char **argv) -{ - stbtt_fontinfo font; - int i,j,ascent,baseline,ch=0; - float scale, xpos=2; // leave a little padding in case the character extends left - char *text = "Heljo World!"; // intentionally misspelled to show 'lj' brokenness - - fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); - stbtt_InitFont(&font, buffer, 0); - - scale = stbtt_ScaleForPixelHeight(&font, 15); - stbtt_GetFontVMetrics(&font, &ascent,0,0); - baseline = (int) (ascent*scale); - - while (text[ch]) { - int advance,lsb,x0,y0,x1,y1; - float x_shift = xpos - (float) floor(xpos); - stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); - stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); - stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); - // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong - // because this API is really for baking character bitmaps into textures. if you want to render - // a sequence of characters, you really need to render each bitmap to a temp buffer, then - // "alpha blend" that into the working buffer - xpos += (advance * scale); - if (text[ch+1]) - xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); - ++ch; - } - - for (j=0; j < 20; ++j) { - for (i=0; i < 78; ++i) - putchar(" .:ioVM@"[screen[j][i]>>5]); - putchar('\n'); - } - - return 0; -} -#endif - - -////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -//// -//// INTEGRATION WITH YOUR CODEBASE -//// -//// The following sections allow you to supply alternate definitions -//// of C library functions used by stb_truetype. +/* The following sections allow you to supply alternate definitions + * of C library functions used by stb_truetype. */ #ifdef STB_TRUETYPE_IMPLEMENTATION - // #define your own (u)stbtt_int8/16/32 before including to override this + /* #define your own (u)stbtt_int8/16/32 before including to override this */ #ifndef stbtt_uint8 typedef unsigned char stbtt_uint8; typedef signed char stbtt_int8; @@ -408,7 +266,7 @@ int main(int arg, char **argv) typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; - // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h + /* #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h */ #ifndef STBTT_ifloor #include #define STBTT_ifloor(x) ((int) floor(x)) @@ -420,7 +278,7 @@ int main(int arg, char **argv) #define STBTT_sqrt(x) sqrt(x) #endif - // #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 #include #define STBTT_malloc(x,u) ((void)(u),malloc(x)) @@ -443,12 +301,7 @@ int main(int arg, char **argv) #endif #endif -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -//// -//// INTERFACE -//// -//// +/* INTERFACE */ #ifndef __STB_INCLUDE_STB_TRUETYPE_H__ #define __STB_INCLUDE_STB_TRUETYPE_H__ @@ -463,134 +316,148 @@ int main(int arg, char **argv) extern "C" { #endif -////////////////////////////////////////////////////////////////////////////// -// -// TEXTURE BAKING API -// -// If you use this API, you only have to call two functions ever. -// +/* TEXTURE BAKING API */ + +/* If you use this API, you only have to call two functions ever. */ typedef struct { - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + uint16_t x0,y0,x1,y1; /* coordinates of bbox in bitmap */ float xoff,yoff,xadvance; } stbtt_bakedchar; -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata); // you allocate this, it's num_chars long -// if return is positive, the first unused row of the bitmap -// if return is negative, returns the negative of the number of characters that fit -// if return is 0, no characters fit and no rows were used -// This uses a very crappy packing. +STBTT_DEF int stbtt_BakeFontBitmap( + const unsigned char *data, int offset, /* font location (use offset=0 for plain .ttf) */ + float pixel_height, /* height of font in pixels */ + unsigned char *pixels, int pw, int ph, /* bitmap to be filled in */ + int first_char, int num_chars, /* characters to bake */ + stbtt_bakedchar *chardata); /* you allocate this, it's num_chars long */ + +/* if return is positive, the first unused row of the bitmap + * if return is negative, returns the negative of the number of characters that fit + * if return is 0, no characters fit and no rows were used + * This uses a very crappy packing. + */ typedef struct { - float x0,y0,s0,t0; // top-left - float x1,y1,s1,t1; // bottom-right + float x0,y0,s0,t0; /* top-left */ + float x1,y1,s1,t1; /* bottom-right */ } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier -// Call GetBakedQuad with char_index = 'character - first_char', and it -// creates the quad you need to draw and advances the current position. -// -// The coordinate system used assumes y increases downwards. -// -// Characters will extend both above and below the current position; -// see discussion of "BASELINE" above. -// -// It's inefficient; you might want to c&p it and optimize it. +STBTT_DEF void stbtt_GetBakedQuad( + stbtt_bakedchar *chardata, int pw, int ph, /* same data as above */ + int char_index, /* character to display */ + float *xpos, float *ypos, /* pointers to current position in screen pixel space */ + stbtt_aligned_quad *q, /* output: quad to draw */ + int opengl_fillrule); /* true if opengl fill rule; false if DX9 or earlier */ +/* Call GetBakedQuad with char_index = 'character - first_char', and it + * creates the quad you need to draw and advances the current position. */ +/* The coordinate system used assumes y increases downwards. + * + * Characters will extend both above and below the current position; + * see discussion of "BASELINE" above. + * + * It's inefficient; you might want to c&p it and optimize it. + */ -////////////////////////////////////////////////////////////////////////////// -// -// NEW TEXTURE BAKING API -// -// This provides options for packing multiple fonts into one atlas, not -// perfectly but better than nothing. +/* NEW TEXTURE BAKING API */ + +/* This provides options for packing multiple fonts into one atlas, not + * perfectly but better than nothing. */ typedef struct { - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap + unsigned short x0,y0,x1,y1; /* coordinates of bbox in bitmap */ float xoff,yoff,xadvance; float xoff2,yoff2; } stbtt_packedchar; typedef struct stbtt_pack_context stbtt_pack_context; -STBTT_DEF 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. +STBTT_DEF 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. + */ STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); -// Cleans up the packing context and frees all memory. + +/* Cleans up the packing context and frees all memory. */ #define STBTT_POINT_SIZE(x) (-(x)) STBTT_DEF 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); -// 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. -// -// font_size is the full height of the character from ascender to descender, -// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed -// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() -// and pass that result as 'font_size': -// ..., 20 , ... // font max minus min y is 20 pixels tall -// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + +/* 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. + * + * font_size is the full height of the character from ascender to descender, + * as computed by stbtt_ScaleForPixelHeight. To use a point size as computed + * by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() + * and pass that result as 'font_size': + * ..., 20 , ... // font max minus min y is 20 pixels tall + * ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + */ typedef struct { float font_size; int first_unicode_char_in_range; int num_chars_in_range; - stbtt_packedchar *chardata_for_range; // output + stbtt_packedchar *chardata_for_range; /* output */ } stbtt_pack_range; -STBTT_DEF 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. +STBTT_DEF 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. + */ -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -// 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 +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, + unsigned int v_oversample); -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int align_to_integer); +/* 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 + */ -// this is an opaque structure that you shouldn't mess with which holds -// all the context needed from PackBegin to PackEnd. -struct stbtt_pack_context { +STBTT_DEF void stbtt_GetPackedQuad( + stbtt_packedchar *chardata, int pw, int ph, /* same data as above */ + int char_index, /* character to display */ + float *xpos, float *ypos, /* pointers to current position in screen pixel space */ + stbtt_aligned_quad *q, /* output: quad to draw */ + int align_to_integer); + +/* this is an opaque structure that you shouldn't mess with which holds + * all the context needed from PackBegin to PackEnd. */ +struct stbtt_pack_context +{ void *user_allocator_context; void *pack_info; int width; @@ -602,23 +469,21 @@ struct stbtt_pack_context { void *nodes; }; -////////////////////////////////////////////////////////////////////////////// -// -// FONT LOADING -// -// +/* FONT LOADING */ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); -// Each .ttf/.ttc file may have more than one font. Each font has a sequential -// index number starting from 0. Call this function to get the font offset for -// a given index; it returns -1 if the index is out of range. A regular .ttf -// file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. You can just skip -// this step if you know it's that kind of font. +/* Each .ttf/.ttc file may have more than one font. Each font has a sequential + * index number starting from 0. Call this function to get the font offset for + * a given index; it returns -1 if the index is out of range. A regular .ttf + * file will only define one font and it always be at offset 0, so it will + * return '0' for index 0, and -1 for all other indices. You can just skip + * this step if you know it's that kind of font. + */ -// The following structure is defined publically so you can declare one on -// the stack or as a global or etc, but you should treat it as opaque. +/* The following structure is defined publically so you can declare one on + * the stack or as a global or etc, but you should treat it as opaque. + */ typedef struct stbtt_fontinfo { void * userdata; @@ -633,28 +498,24 @@ typedef struct stbtt_fontinfo } stbtt_fontinfo; STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); + // Given an offset into the file that defines a font, this function builds // the necessary cached info for the rest of the system. You must allocate // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't // need to do anything special to free it, because the contents are pure // value data with no additional data structures. Returns 0 on failure. - -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER TO GLYPH-INDEX CONVERSIOn +/* CHARACTER TO GLYPH-INDEX CONVERSION */ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); + // If you're going to perform multiple operations on the same character // and you want a speed-up, call this function with the character you're // going to process, then use glyph-based functions instead of the // codepoint-based functions. -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER PROPERTIES -// +/* CHARACTER PROPERTIES */ STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); // computes a scale factor to produce a font whose "height" is 'pixels' tall. @@ -697,28 +558,26 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, in // as above, but takes one or more glyph indices for greater efficiency -////////////////////////////////////////////////////////////////////////////// -// // GLYPH SHAPES (you probably don't need these, but they have to go before // the bitmaps for C declaration-order reasons) -// #ifndef STBTT_vmove // you can predefine these to use different values (but why?) - enum { - STBTT_vmove=1, - STBTT_vline, - STBTT_vcurve - }; +enum +{ + STBTT_vmove=1, + STBTT_vline, + STBTT_vcurve +}; #endif -#ifndef stbtt_vertex // you can predefine this to use different values - // (we share this with other code at RAD) - #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file - typedef struct - { - stbtt_vertex_type x,y,cx,cy; - unsigned char type,padding; - } stbtt_vertex; +#ifndef stbtt_vertex // you can predefine this to use different values (we share this with other code at RAD) +#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + +typedef struct +{ + stbtt_vertex_type x,y,cx,cy; + unsigned char type,padding; +} stbtt_vertex; #endif STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); @@ -739,15 +598,14 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); // frees the data allocated above -////////////////////////////////////////////////////////////////////////////// -// // BITMAP RENDERING -// STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); // frees the bitmap allocated below -STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, + float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); + // allocates a large-enough single-channel 8bpp bitmap and renders the // specified character/glyph at the specified scale into it, with // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). @@ -756,39 +614,56 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl // // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, + float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel // shift for the character -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); + // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the // width and height and positioning info for it first. -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel // shift for the character -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, + float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); // get the bbox of the bitmap centered around the glyph origin; so the // bitmap width is ix1-ix0, height is iy1-iy0, and location to place // the bitmap top left is (leftSideBearing*scale,iy0). // (Note that the bitmap uses y-increases-down, but the shape uses // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, + float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel // shift for the character // the following functions are equivalent to the above functions, but operate // on glyph indices instead of Unicode codepoints (for efficiency) -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, + float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); + +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, + float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); + +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); + +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); + +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, + float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); + +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, + float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); // @TODO: don't expose this structure @@ -798,10 +673,9 @@ typedef struct unsigned char *pixels; } stbtt__bitmap; -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, + float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); -////////////////////////////////////////////////////////////////////////////// -// // Finding the right font... // // You should really just solve this offline, keep your own tables @@ -834,10 +708,14 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char * #define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); -// returns 1/0 whether the first string interpreted as utf8 is identical to -// the second string interpreted as big-endian utf16... useful for strings from next func -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); +/* returns 1/0 whether the first string interpreted as UTF8 is identical to + * the second string interpreted as big-endian UTF16... useful for strings from next func + */ + +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, + int *length, int platformID, int encodingID, int languageID, int nameID); + // returns the string (which may be big-endian double byte, e.g. for unicode) // and puts the length in bytes in *length. // @@ -845,14 +723,18 @@ STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *l // http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html // http://www.microsoft.com/typography/otspec/name.htm -enum { // platformID +enum +{ + /* platformID */ STBTT_PLATFORM_ID_UNICODE =0, STBTT_PLATFORM_ID_MAC =1, STBTT_PLATFORM_ID_ISO =2, STBTT_PLATFORM_ID_MICROSOFT =3 }; -enum { // encodingID for STBTT_PLATFORM_ID_UNICODE +enum +{ + /* encodingID for STBTT_PLATFORM_ID_UNICODE */ STBTT_UNICODE_EID_UNICODE_1_0 =0, STBTT_UNICODE_EID_UNICODE_1_1 =1, STBTT_UNICODE_EID_ISO_10646 =2, @@ -860,22 +742,29 @@ enum { // encodingID for STBTT_PLATFORM_ID_UNICODE STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 }; -enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT +enum +{ + /* encodingID for STBTT_PLATFORM_ID_MICROSOFT */ STBTT_MS_EID_SYMBOL =0, STBTT_MS_EID_UNICODE_BMP =1, STBTT_MS_EID_SHIFTJIS =2, STBTT_MS_EID_UNICODE_FULL =10 }; -enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes +enum +{ + /* encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes */ STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 }; -enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... - // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs +enum +{ + /* languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + * problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + */ STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, @@ -884,7 +773,8 @@ enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D }; -enum { // languageID for STBTT_PLATFORM_ID_MAC +enum +{ /* languageID for STBTT_PLATFORM_ID_MAC */ STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, @@ -898,14 +788,9 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC } #endif -#endif // __STB_INCLUDE_STB_TRUETYPE_H__ +#endif /* __STB_INCLUDE_STB_TRUETYPE_H__ */ -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -//// -//// IMPLEMENTATION -//// -//// +/* IMPLEMENTATION */ #ifdef STB_TRUETYPE_IMPLEMENTATION @@ -919,10 +804,7 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS #define STBTT_RASTERIZER_VERSION 2 #endif -////////////////////////////////////////////////////////////////////////// -// // accessors to parse data from file -// // on platforms that don't allow misaligned reads, if we want to allow // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE @@ -952,21 +834,27 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS static int stbtt__isfont(const stbtt_uint8 *font) { - // check the version number - if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 - if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! - if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF - if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 + /* check the version number */ + if (stbtt_tag4(font, '1',0,0,0)) + return 1; /* TrueType 1 */ + if (stbtt_tag(font, "typ1")) + return 1; /* TrueType with type 1 font -- we don't support this! */ + if (stbtt_tag(font, "OTTO")) + return 1; /* OpenType with CFF */ + if (stbtt_tag4(font, 0,1,0,0)) + return 1; /* OpenType 1.0 */ return 0; } -// @OPTIMIZE: binary search +/* @OPTIMIZE: binary search */ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) { + stbtt_int32 i; stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); stbtt_uint32 tabledir = fontstart + 12; - stbtt_int32 i; - for (i=0; i < num_tables; ++i) { + + for (i=0; i < num_tables; ++i) + { stbtt_uint32 loc = tabledir + 16*i; if (stbtt_tag(data+loc+0, tag)) return ttULONG(data+loc+8); @@ -976,14 +864,16 @@ static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) { - // if it's just a font, there's only one valid index + /* if it's just a font, there's only one valid index */ if (stbtt__isfont(font_collection)) return index == 0 ? 0 : -1; - // check if it's a TTC - if (stbtt_tag(font_collection, "ttcf")) { - // version 1? - if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { + /* check if it's a TTC */ + if (stbtt_tag(font_collection, "ttcf")) + { + /* version 1? */ + if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) + { stbtt_int32 n = ttLONG(font_collection+8); if (index >= n) return -1; @@ -1009,6 +899,7 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) return 0; @@ -1161,21 +1052,27 @@ static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) { int g1,g2; - if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range - if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + if (glyph_index >= info->numGlyphs) + return -1; /* glyph index out of range */ + if (info->indexToLocFormat >= 2) + return -1; /* unknown index->glyph map format */ - if (info->indexToLocFormat == 0) { + if (info->indexToLocFormat == 0) + { g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { + } + else + { g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); } - return g1==g2 ? -1 : g1; // if length is 0, return -1 + return g1==g2 ? -1 : g1; /* if length is 0, return -1 */ } -STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) +STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, + int glyph_index, int *x0, int *y0, int *x1, int *y1) { int g = stbtt__GetGlyfOffset(info, glyph_index); if (g < 0) return 0; @@ -1187,7 +1084,8 @@ STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int return 1; } -STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) +STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, + int codepoint, int *x0, int *y0, int *x1, int *y1) { return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); } @@ -1443,15 +1341,23 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s return num_vertices; } -STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) +STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, + int glyph_index, int *advanceWidth, int *leftSideBearing) { stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); - } else { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); + if (glyph_index < numOfLongHorMetrics) + { + if (advanceWidth) + *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); + if (leftSideBearing) + *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); + } + else + { + if (advanceWidth) + *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); + if (leftSideBearing) + *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); } } @@ -1487,24 +1393,27 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { - if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + if (!info->kern) /* if no kerning table, don't waste time looking up both codepoint->glyphs */ return 0; return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); } -STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) +STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, + int codepoint, int *advanceWidth, int *leftSideBearing) { stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); } -STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) +STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, + int *ascent, int *descent, int *lineGap) { if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); if (descent) *descent = ttSHORT(info->data+info->hhea + 6); if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); } -STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) +STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, + int *x0, int *y0, int *x1, int *y1) { *x0 = ttSHORT(info->data + info->head + 36); *y0 = ttSHORT(info->data + info->head + 38); @@ -1529,22 +1438,25 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) STBTT_free(v, info->userdata); } -////////////////////////////////////////////////////////////////////////////// -// -// antialiasing software rasterizer -// +/* antialiasing software rasterizer */ -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, + int glyph, float scale_x, float scale_y,float shift_x, float shift_y, + int *ix0, int *iy0, int *ix1, int *iy1) { int x0,y0,x1,y1; - if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { - // e.g. space character + if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) + { + /* e.g. space character */ if (ix0) *ix0 = 0; if (iy0) *iy0 = 0; if (ix1) *ix1 = 0; if (iy1) *iy1 = 0; - } else { - // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + } + else + { + /* move to integral bboxes + * (treating pixels as little squares, what pixels get touched)? */ if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); @@ -1552,24 +1464,25 @@ STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int g } } -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, + int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); } -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, + float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); } -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, + int *ix0, int *iy0, int *ix1, int *iy1) { stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); } -////////////////////////////////////////////////////////////////////////////// -// -// Rasterizer +/* Rasterizer */ typedef struct stbtt__hheap_chunk { @@ -1592,7 +1505,8 @@ static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) } else { if (hh->num_remaining_in_head_chunk == 0) { int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) + STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); if (c == NULL) return NULL; c->next = hh->head; @@ -1654,13 +1568,13 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); if (!z) return z; - // round dx down to avoid overshooting + /* round dx down to avoid overshooting */ if (dxdy < 0) z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); else z->dx = STBTT_ifloor(STBTT_FIX * dxdy); - z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); /* use z->dx so when we offset later it's by the same amount */ z->x -= off_x * STBTT_FIX; z->ey = e->y1; @@ -1673,7 +1587,6 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i { stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - //STBTT_assert(e->y0 <= start_point); if (!z) return z; z->fdx = dxdy; z->fdy = (1/dxdy); @@ -1690,16 +1603,19 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i #endif #if STBTT_RASTERIZER_VERSION == 1 -// note: this routine clips fills that extend off the edges... ideally this -// wouldn't happen, but it could happen if the truetype glyph bounding boxes -// are wrong, or if the user supplies a too-small bitmap +/* note: this routine clips fills that extend off the edges... ideally this + * wouldn't happen, but it could happen if the truetype glyph bounding boxes + * 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) { - // non-zero winding fill + /* non-zero winding fill */ int x0=0, w=0; - while (e) { - if (w == 0) { + while (e) + { + if (w == 0) + { // if we're currently at zero, we need to record the edge start point x0 = e->x; w += e->direction; } else { @@ -1735,14 +1651,15 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac } } -static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, + int vsubsample, int off_x, int off_y, void *userdata) { + unsigned char scanline_data[512], *scanline; stbtt__hheap hh = { 0 }; stbtt__active_edge *active = NULL; int y,j=0; - int max_weight = (255 / vsubsample); // weight per vertical scanline - int s; // vertical subsample index - unsigned char scanline_data[512], *scanline; + int max_weight = (255 / vsubsample); /* weight per vertical scanline */ + int s; /* vertical subsample index */ if (result->w > 512) scanline = (unsigned char *) STBTT_malloc(result->w, userdata); @@ -1835,9 +1752,11 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, #elif STBTT_RASTERIZER_VERSION == 2 -// the edge passed in here does not cross the vertical line at x or the vertical line at x+1 -// (i.e. it has already been clipped to those) -static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) +/* the edge passed in here does not cross the vertical line at x or the vertical line at x+1 + * (i.e. it has already been clipped to those) + */ +static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, + float x0, float y0, float x1, float y1) { if (y0 == y1) return; assert(y0 < y1); @@ -1870,18 +1789,20 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg ; else { assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); - scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position + scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); /* coverage = 1 - average x position */ } } -static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) +static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, + int len, stbtt__active_edge *e, float y_top) { float y_bottom = y_top+1; - while (e) { - // brute force every pixel + while (e) + { + /* brute force every pixel */ - // compute intersection points with top & bottom + /* compute intersection points with top & bottom */ assert(e->ey >= y_top); if (e->fdx == 0) { @@ -2023,8 +1944,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, } } -// directly AA rasterize edges w/o supersampling -static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +/* directly AA rasterize edges w/o supersampling */ +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__hheap hh = { 0 }; stbtt__active_edge *active = NULL; @@ -2041,17 +1963,20 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, y = off_y; e[n].y0 = (float) (off_y + result->h) + 1; - while (j < result->h) { - // find center of pixel for this scanline + while (j < result->h) + { float scan_y_top = y + 0.0f; float scan_y_bottom = y + 1.0f; stbtt__active_edge **step = &active; + /* find center of pixel for this scanline */ + STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); - // update all active edges; - // remove all active edges that terminate before the top of this scanline + /* update all active edges, + * remove all active edges that terminate + * before the top of this scanline */ while (*step) { stbtt__active_edge * z = *step; if (z->ey <= scan_y_top) { @@ -2064,23 +1989,26 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, } } - // insert all edges that start before the bottom of this scanline - while (e->y0 <= scan_y_bottom) { + /* insert all edges that start before the bottom of this scanline */ + while (e->y0 <= scan_y_bottom) + { stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); assert(z->ey >= scan_y_top); - // insert at front + + /* insert at front */ z->next = active; active = z; ++e; } - // now process all active edges + /* now process all active edges */ if (active) stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); { float sum = 0; - for (i=0; i < result->w; ++i) { + for (i=0; i < result->w; ++i) + { float k; int m; sum += scanline2[i]; @@ -2091,12 +2019,16 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, result->pixels[j*result->stride + i] = (unsigned char) m; } } - // advance all the edges + + /* advance all the edges */ + step = &active; - while (*step) { + + while (*step) + { stbtt__active_edge *z = *step; - z->fx += z->fdx; // advance to position for current scanline - step = &((*step)->next); // advance through list + z->fx += z->fdx; /* advance to position for current scanline */ + step = &((*step)->next); /* advance through list */ } ++y; @@ -2205,7 +2137,9 @@ 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, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, + float scale_x, float scale_y, float shift_x, float shift_y, + int off_x, int off_y, int invert, void *userdata) { float y_scale_inv = invert ? -scale_y : scale_y; stbtt__edge *e; @@ -2217,14 +2151,14 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou #else #error "Unrecognized value of STBTT_RASTERIZER_VERSION" #endif - // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */ - // now we have to blow out the windings into explicit edge lists + /* now we have to blow out the windings into explicit edge lists */ n = 0; for (i=0; i < windings; ++i) n += wcount[i]; - e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // 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; @@ -2235,10 +2169,10 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou j = wcount[i]-1; for (k=0; k < wcount[i]; j=k++) { int a=k,b=j; - // skip the edge if horizontal + /* skip the edge if horizontal */ if (p[j].y == p[k].y) continue; - // add edge from j to k to the list + /* add edge from j to k to the list */ e[n].invert = 0; if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { e[n].invert = 1; @@ -2252,11 +2186,11 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou } } - // now sort the edges by their highest point (should snap to integer, and then by x) - //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + /* now sort the edges by their highest point (should snap to integer, and then by x) */ stbtt__sort_edges(e, n); - // 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, userdata); STBTT_free(e, userdata); @@ -2264,15 +2198,16 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou static void stbtt__add_point(stbtt__point *points, int n, float x, float y) { - if (!points) return; // during first pass, it's unallocated + if (!points) return; /* during first pass, it's unallocated */ points[n].x = x; points[n].y = y; } -// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching -static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) +/* tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching */ +static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, + float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) { - // midpoint + /* midpoint */ float mx = (x0 + 2*x1 + x2)/4; float my = (y0 + 2*y1 + y2)/4; // versus directly drawn line @@ -2290,8 +2225,9 @@ static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x return 1; } -// returns number of contours -static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +/* Returns number of contours */ +static 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; @@ -2299,7 +2235,7 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness_squared = objspace_flatness * objspace_flatness; int i,n=0,start=0, pass; - // count how many "moves" there are to get the contour count + /* count how many "moves" there are to get the contour count */ for (i=0; i < num_verts; ++i) if (vertices[i].type == STBTT_vmove) ++n; @@ -2314,19 +2250,25 @@ static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, return 0; } - // make two passes through the points so we don't need to realloc - for (pass=0; pass < 2; ++pass) { + /* make two passes through the points so we don't need to realloc */ + for (pass=0; pass < 2; ++pass) + { float x=0,y=0; - if (pass == 1) { + + if (pass == 1) + { points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); if (points == NULL) goto error; } num_points = 0; n= -1; - for (i=0; i < num_verts; ++i) { - switch (vertices[i].type) { + + for (i=0; i < num_verts; ++i) + { + switch (vertices[i].type) + { case STBTT_vmove: - // start the next contour + /* start the next contour */ if (n >= 0) (*contour_lengths)[n] = num_points - start; ++n; @@ -2360,12 +2302,15 @@ error: return NULL; } -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) +STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, + stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, + float shift_x, float shift_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, userdata); - if (windings) { + if (windings) + { stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); STBTT_free(winding_lengths, userdata); STBTT_free(windings, userdata); @@ -2377,7 +2322,8 @@ STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) STBTT_free(bitmap, userdata); } -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, + float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) { int ix0,iy0,ix1,iy1; stbtt__bitmap gbm; @@ -2385,14 +2331,16 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) return NULL; + if (scale_y == 0) + { + if (scale_x == 0) + return NULL; scale_y = scale_x; } stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); - // now we get the size + /* now we get the size */ gbm.w = (ix1 - ix0); gbm.h = (iy1 - iy0); gbm.pixels = NULL; // in case we error @@ -2414,12 +2362,15 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info return gbm.pixels; } -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) +STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, + int glyph, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); } -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, + float scale_x, float scale_y, float shift_x, float shift_y, int glyph) { int ix0,iy0; stbtt_vertex *vertices; @@ -2438,19 +2389,26 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne STBTT_free(vertices, info->userdata); } -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) +STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) { stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); } -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) +STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, + float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, + int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, + stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); } -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, + int out_w, int out_h, int out_stride, float scale_x, float scale_y, + float shift_x, float shift_y, int codepoint) { - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, + shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); } STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) @@ -2458,29 +2416,32 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, fl return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); } -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) +STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, + unsigned char *output, int out_w, int out_h, + int out_stride, float scale_x, float scale_y, int codepoint) { - stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, + out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); } -////////////////////////////////////////////////////////////////////////////// -// -// bitmap baking -// -// This is SUPER-CRAPPY packing to keep source code small +/* bitmap baking + * + * This is SUPER-CRAPPY packing to keep source code small + */ -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata) +STBTT_DEF int stbtt_BakeFontBitmap( + const unsigned char *data, int offset, /* font location (use offset=0 for plain .ttf) */ + float pixel_height, /* height of font in pixels */ + unsigned char *pixels, int pw, int ph, /* bitmap to be filled in */ + int first_char, int num_chars, /* characters to bake */ + stbtt_bakedchar *chardata) { float scale; int x,y,bottom_y, i; stbtt_fontinfo f; if (!stbtt_InitFont(&f, data, offset)) return -1; - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + STBTT_memset(pixels, 0, pw*ph); /* background of 0 around pixels */ x=y=1; bottom_y = 1; @@ -2494,8 +2455,8 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo gw = x1-x0; gh = y1-y0; if (x + gw + 1 >= pw) - y = bottom_y, x = 1; // advance to next row - if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + y = bottom_y, x = 1; /* advance to next row */ + if (y + gh + 1 >= ph) /* check if it fits vertically AFTER potentially moving to next row */ return -i; STBTT_assert(x+gw < pw); STBTT_assert(y+gh < ph); @@ -2514,7 +2475,9 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo return bottom_y; } -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +STBTT_DEF 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; @@ -2535,10 +2498,7 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int *xpos += b->xadvance; } -////////////////////////////////////////////////////////////////////////////// -// -// rectangle packing replacement routines if you don't have stb_rect_pack.h -// +/* rectangle packing replacement routines if you don't have stb_rect_pack.h */ #ifndef STB_RECT_PACK_VERSION #ifdef _MSC_VER @@ -2549,16 +2509,12 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int typedef int stbrp_coord; -//////////////////////////////////////////////////////////////////////////////////// -// // -// // -// COMPILER WARNING ?!?!? // -// // -// // -// if you get a compile warning due to these symbols being defined more than // -// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // -// // -//////////////////////////////////////////////////////////////////////////////////// +/* + * COMPILER WARNING ?!?!? + * + * if you get a compile warning due to these symbols being defined more than + * once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" + */ typedef struct { @@ -2577,7 +2533,8 @@ typedef struct int id,w,h,was_packed; } stbrp_rect; -static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) +static void stbrp_init_target(stbrp_context *con, int pw, int ph, + stbrp_node *nodes, int num_nodes) { con->width = pw; con->height = ph; @@ -2588,20 +2545,26 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no STBTT__NOTUSED(num_nodes); } -static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) +static void stbrp_pack_rects(stbrp_context *con, + stbrp_rect *rects, int num_rects) { int i; - for (i=0; i < num_rects; ++i) { - if (con->x + rects[i].w > con->width) { + for (i=0; i < num_rects; ++i) + { + if (con->x + rects[i].w > con->width) + { con->x = 0; con->y = con->bottom_y; } + if (con->y + rects[i].h > con->height) break; + rects[i].x = con->x; rects[i].y = con->y; rects[i].was_packed = 1; con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) con->bottom_y = con->y + rects[i].h; } @@ -2610,20 +2573,23 @@ static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rect } #endif -////////////////////////////////////////////////////////////////////////////// -// -// bitmap baking -// -// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If -// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. +/* bitmap baking + * + * This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If + * stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. + */ -STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) +STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, + int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { - stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); + stbrp_context *context = (stbrp_context *) + STBTT_malloc(sizeof(*context) ,alloc_context); int num_nodes = pw - padding; - stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + stbrp_node *nodes = (stbrp_node *) + STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); - if (context == NULL || nodes == NULL) { + if (context == NULL || nodes == NULL) + { if (context != NULL) STBTT_free(context, alloc_context); if (nodes != NULL) STBTT_free(nodes , alloc_context); return 0; @@ -2642,7 +2608,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + STBTT_memset(pixels, 0, pw*ph); /* background of 0 around pixels */ return 1; } @@ -2653,7 +2619,8 @@ STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) STBTT_free(spc->pack_info, spc->user_allocator_context); } -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) +STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, + unsigned int h_oversample, unsigned int v_oversample) { STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); @@ -2665,19 +2632,23 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) -static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) +static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, + int stride_in_bytes, unsigned int kernel_width) { + int j; unsigned char buffer[STBTT_MAX_OVERSAMPLE]; int safe_w = w - kernel_width; - int j; - for (j=0; j < h; ++j) { + + for (j=0; j < h; ++j) + { int i; unsigned int total; STBTT_memset(buffer, 0, kernel_width); total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide + /* make kernel_width a constant in common cases + * so compiler can optimize out the divide */ switch (kernel_width) { case 2: for (i=0; i <= safe_w; ++i) { @@ -2724,38 +2695,44 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i unsigned char buffer[STBTT_MAX_OVERSAMPLE]; int safe_h = h - kernel_width; int j; - for (j=0; j < w; ++j) { + for (j=0; j < w; ++j) + { int i; unsigned int total; STBTT_memset(buffer, 0, kernel_width); total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { + /* make kernel_width a constant in common cases so compiler can optimize out the divide */ + switch (kernel_width) + { case 2: - for (i=0; i <= safe_h; ++i) { + for (i=0; i <= safe_h; ++i) + { total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; pixels[i*stride_in_bytes] = (unsigned char) (total / 2); } break; case 3: - for (i=0; i <= safe_h; ++i) { + for (i=0; i <= safe_h; ++i) + { total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; pixels[i*stride_in_bytes] = (unsigned char) (total / 3); } break; case 4: - for (i=0; i <= safe_h; ++i) { + for (i=0; i <= safe_h; ++i) + { total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; pixels[i*stride_in_bytes] = (unsigned char) (total / 4); } break; default: - for (i=0; i <= safe_h; ++i) { + for (i=0; i <= safe_h; ++i) + { total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); @@ -2763,7 +2740,8 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i break; } - for (; i < h; ++i) { + for (; i < h; ++i) + { STBTT_assert(pixels[i*stride_in_bytes] == 0); total -= buffer[i & STBTT__OVER_MASK]; pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); @@ -2778,15 +2756,17 @@ static float stbtt__oversample_shift(int oversample) if (!oversample) return 0.0f; - // The prefilter is a box filter of width "oversample", - // which shifts phase by (oversample - 1)/2 pixels in - // oversampled space. We want to shift in the opposite - // direction to counter this. + /* The prefilter is a box filter of width "oversample", + * which shifts phase by (oversample - 1)/2 pixels in + * oversampled space. We want to shift in the opposite + * direction to counter this. */ return (float)-(oversample - 1) / (2.0f * (float)oversample); } -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, + int font_index, stbtt_pack_range *ranges, int num_ranges) { + stbrp_rect *rects; stbtt_fontinfo info; float recip_h = 1.0f / spc->h_oversample; float recip_v = 1.0f / spc->v_oversample; @@ -2794,9 +2774,8 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd float sub_y = stbtt__oversample_shift(spc->v_oversample); int i,j,k,n, return_value = 1; stbrp_context *context = (stbrp_context *) spc->pack_info; - stbrp_rect *rects; - // flag all characters as NOT packed + /* flag all characters as NOT packed */ for (i=0; i < num_ranges; ++i) for (j=0; j < ranges[i].num_chars_in_range; ++j) ranges[i].chardata_for_range[j].x0 = @@ -2838,13 +2817,14 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); for (j=0; j < ranges[i].num_chars_in_range; ++j) { stbrp_rect *r = &rects[k]; - if (r->was_packed) { + if (r->was_packed) + { stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; int advance, lsb, x0,y0,x1,y1; int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j); stbrp_coord pad = (stbrp_coord) spc->padding; - // pad on left and top + /* pad on left and top */ r->x += pad; r->y += pad; r->w -= pad; @@ -2883,9 +2863,9 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd bc->yoff = (float) y0 * recip_v + sub_y; bc->xoff2 = (x0 + r->w) * recip_h + sub_x; bc->yoff2 = (y0 + r->h) * recip_v + sub_y; - } else { - return_value = 0; // if any fail, report failure } + else + return_value = 0; /* if any fail, report failure */ ++k; } @@ -2906,7 +2886,9 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); } -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, + int ph, int char_index, float *xpos, float *ypos, + stbtt_aligned_quad *q, int align_to_integer) { float ipw = 1.0f / pw, iph = 1.0f / ph; stbtt_packedchar *b = chardata + char_index; @@ -2934,17 +2916,14 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i } -////////////////////////////////////////////////////////////////////////////// -// -// font name matching -- recommended not to use this -// +/* font name matching -- recommended not to use this */ -// check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string +/* check if a UTF8 string contains a prefix which is the UTF16 string; if so return length of matching UTF8 string */ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) { stbtt_int32 i=0; - // convert utf16 to utf8 and compare the results while converting + /* convert UTF16 to UTF8 and compare the results while converting */ while (len2) { stbtt_uint16 ch = s2[0]*256 + s2[1]; if (ch < 0x80) { @@ -2963,7 +2942,7 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; - s2 += 2; // plus another 2 below + s2 += 2; /* plus another 2 below */ len2 -= 2; } else if (ch >= 0xdc00 && ch < 0xe000) { return -1; @@ -2984,9 +2963,10 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); } -// returns results in whatever encoding you request... but note that 2-byte encodings -// will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) +/* returns results in whatever encoding you request... but note that 2-byte encodings + * will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare */ +STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, + int *length, int platformID, int encodingID, int languageID, int nameID) { stbtt_int32 i,count,stringOffset; stbtt_uint8 *fc = font->data; @@ -3013,42 +2993,55 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 count = ttUSHORT(fc+nm+2); stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); - for (i=0; i < count; ++i) { + for (i=0; i < count; ++i) + { stbtt_uint32 loc = nm + 6 + 12 * i; stbtt_int32 id = ttUSHORT(fc+loc+6); - if (id == target_id) { - // find the encoding + if (id == target_id) + { + /* find the encoding */ stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); - // is this a Unicode encoding? - if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { + /* is this a Unicode encoding? */ + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) + { stbtt_int32 slen = ttUSHORT(fc+loc+8); stbtt_int32 off = ttUSHORT(fc+loc+10); - // check if there's a prefix match + /* check if there's a prefix match */ stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); - if (matchlen >= 0) { - // check for target_id+1 immediately following, with same encoding & language - if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { + if (matchlen >= 0) + { + /* check for target_id+1 immediately following, with same encoding & language */ + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id + && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding + && ttUSHORT(fc+loc+12+4) == language) + { slen = ttUSHORT(fc+loc+12+8); off = ttUSHORT(fc+loc+12+10); - if (slen == 0) { + + if (slen == 0) + { if (matchlen == nlen) return 1; - } else if (matchlen < nlen && name[matchlen] == ' ') { + } + else if (matchlen < nlen && name[matchlen] == ' ') + { ++matchlen; if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) return 1; } - } else { - // if nothing immediately following + } + else + { + /* if nothing immediately following */ if (matchlen == nlen) return 1; } } } - // @TODO handle other encodings + /* @TODO handle other encodings */ } } return 0; @@ -3058,23 +3051,29 @@ static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *nam { stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); stbtt_uint32 nm,hd; - if (!stbtt__isfont(fc+offset)) return 0; + if (!stbtt__isfont(fc+offset)) + return 0; - // check italics/bold/underline flags in macStyle... - if (flags) { + /* check italics/bold/underline flags in macStyle... */ + if (flags) + { hd = stbtt__find_table(fc, offset, "head"); if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; } nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return 0; + if (!nm) + return 0; - if (flags) { - // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (flags) + { + /* if we checked the macStyle flags, then just check the family and ignore the subfamily */ if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } else { + } + else + { if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; @@ -3094,4 +3093,4 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const } } -#endif // STB_TRUETYPE_IMPLEMENTATION +#endif /* STB_TRUETYPE_IMPLEMENTATION */