Skip to content

Instantly share code, notes, and snippets.

@fowlmouth
Created May 1, 2015 23:06
Show Gist options
  • Save fowlmouth/98f4ca4ed2204593f035 to your computer and use it in GitHub Desktop.
Save fowlmouth/98f4ca4ed2204593f035 to your computer and use it in GitHub Desktop.
/* Generated by Nim Compiler v0.11.0 */
/* (c) 2015 Andreas Rumpf */
/* The generated code is subject to the original license. */
/* Compiled for: Windows, i386, vcc */
/* Command for C compiler:
cl.exe /c /nologo /IC:\nim\lib /Foc:\users\phowl_000\src\nimx\test\nimcache\nimx_font.obj c:\users\phowl_000\src\nimx\test\nimcache\nimx_font.c */
#define NIM_INTBITS 32
#include "nimbase.h"
#include <string.h>
#include <math.h>
typedef struct GlHEX3Aobjecttype745214 GlHEX3Aobjecttype745214;
typedef struct CharinfoHEX3Aobjecttype748061 CharinfoHEX3Aobjecttype748061;
typedef struct TY748509 TY748509;
typedef struct TGenericSeq TGenericSeq;
typedef struct FontHEX3Aobjecttype748072 FontHEX3Aobjecttype748072;
typedef struct TNimType TNimType;
typedef struct TNimNode TNimNode;
typedef struct RectpackerHEX3Aobjecttype742017 RectpackerHEX3Aobjecttype742017;
typedef struct NimStringDesc NimStringDesc;
typedef struct Table748078 Table748078;
typedef struct Keyvaluepairseq748081 Keyvaluepairseq748081;
typedef struct stbtt_fontinfo stbtt_fontinfo;
typedef struct Point742046 Point742046;
typedef struct Tcell46746 Tcell46746;
typedef struct Tcellseq46762 Tcellseq46762;
typedef struct Tgcheap48616 Tgcheap48616;
typedef struct Tcellset46758 Tcellset46758;
typedef struct Tpagedesc46754 Tpagedesc46754;
typedef struct Tmemregion28610 Tmemregion28610;
typedef struct Tsmallchunk27840 Tsmallchunk27840;
typedef struct Tllchunk28604 Tllchunk28604;
typedef struct Tbigchunk27842 Tbigchunk27842;
typedef struct Tintset27817 Tintset27817;
typedef struct Ttrunk27813 Ttrunk27813;
typedef struct Tavlnode28608 Tavlnode28608;
typedef struct Tgcstat48614 Tgcstat48614;
typedef struct Keyvaluepair748084 Keyvaluepair748084;
typedef struct TY750008 TY750008;
typedef struct Point93017 Point93017;
typedef struct Rect742007 Rect742007;
typedef struct Tbasechunk27838 Tbasechunk27838;
typedef struct Tfreecell27830 Tfreecell27830;
typedef NI16 Bakedcharinfo748035[672];
struct CharinfoHEX3Aobjecttype748061 {
Bakedcharinfo748035 bakedchars;
NU32 texture;
NU16 texwidth;
NU16 texheight;
};
struct TGenericSeq {
NI len;
NI reserved;
};
typedef N_NIMCALL_PTR(void, TY3289) (void* p, NI op);
typedef N_NIMCALL_PTR(void*, TY3294) (void* p);
struct TNimType {
NI size;
NU8 kind;
NU8 flags;
TNimType* base;
TNimNode* node;
void* finalizer;
TY3289 marker;
TY3294 deepcopy;
};
struct TNimNode {
NU8 kind;
NI offset;
TNimType* typ;
NCSTRING name;
NI len;
TNimNode** sons;
};
struct NimStringDesc {
TGenericSeq Sup;
NIM_CHAR data[SEQ_DECL_SIZE];
};
struct Table748078 {
Keyvaluepairseq748081* data;
NI counter;
};
struct FontHEX3Aobjecttype748072 {
Table748078 chars;
NF size;
NIM_BOOL ishorizontal;
NimStringDesc* filepath;
};
struct stbtt_fontinfo {
void* userdata;
NU8* data;
int fontstart;
int numGlyphs;
int loca;
int head;
int glyf;
int hhea;
int hmtx;
int kern;
int index_map;
int indexToLocFormat;
};
typedef NU8 fonttype743087[999999999];
typedef NimStringDesc* TY748204[1];
typedef int TY748213[96];
struct Point742046 {
NI32 Field0;
NI32 Field1;
};
struct Tcell46746 {
NI refcount;
TNimType* typ;
};
struct Tcellseq46762 {
NI len;
NI cap;
Tcell46746** d;
};
struct Tcellset46758 {
NI counter;
NI max;
Tpagedesc46754* head;
Tpagedesc46754** data;
};
typedef Tsmallchunk27840* TY28622[512];
typedef Ttrunk27813* Ttrunkbuckets27815[256];
struct Tintset27817 {
Ttrunkbuckets27815 data;
};
struct Tmemregion28610 {
NI minlargeobj;
NI maxlargeobj;
TY28622 freesmallchunks;
Tllchunk28604* llmem;
NI currmem;
NI maxmem;
NI freemem;
NI lastsize;
Tbigchunk27842* freechunkslist;
Tintset27817 chunkstarts;
Tavlnode28608* root;
Tavlnode28608* deleted;
Tavlnode28608* last;
Tavlnode28608* freeavlnodes;
};
struct Tgcstat48614 {
NI stackscans;
NI cyclecollections;
NI maxthreshold;
NI maxstacksize;
NI maxstackcells;
NI cycletablesize;
NI64 maxpause;
};
struct Tgcheap48616 {
void* stackbottom;
NI cyclethreshold;
Tcellseq46762 zct;
Tcellseq46762 decstack;
Tcellset46758 cycleroots;
Tcellseq46762 tempstack;
NI recgclock;
Tmemregion28610 region;
Tgcstat48614 stat;
};
typedef NimStringDesc* TY749448[3];
struct Keyvaluepair748084 {
NI Field0;
NI32 Field1;
CharinfoHEX3Aobjecttype748061* Field2;
};
struct TY750008 {
CharinfoHEX3Aobjecttype748061* Field0;
NI Field1;
};
struct Point93017 {
NF32 Field0;
NF32 Field1;
};
typedef NF32 Matrix4723005[16];
struct GlHEX3Aobjecttype745214 {
char dummy;
};
struct Rect742007 {
NI32 Field0;
NI32 Field1;
NI32 Field2;
NI32 Field3;
};
struct RectpackerHEX3Aobjecttype742017 {
RectpackerHEX3Aobjecttype742017* c1;
RectpackerHEX3Aobjecttype742017* c2;
Rect742007 rect;
NIM_BOOL occupied;
};
typedef NI TY27820[16];
struct Tpagedesc46754 {
Tpagedesc46754* next;
NI key;
TY27820 bits;
};
struct Tbasechunk27838 {
NI prevsize;
NI size;
NIM_BOOL used;
};
struct Tsmallchunk27840 {
Tbasechunk27838 Sup;
Tsmallchunk27840* next;
Tsmallchunk27840* prev;
Tfreecell27830* freelist;
NI free;
NI acc;
NF data;
};
struct Tllchunk28604 {
NI size;
NI acc;
Tllchunk28604* next;
};
struct Tbigchunk27842 {
Tbasechunk27838 Sup;
Tbigchunk27842* next;
Tbigchunk27842* prev;
NI align;
NF data;
};
struct Ttrunk27813 {
Ttrunk27813* next;
NI key;
TY27820 bits;
};
typedef Tavlnode28608* TY28614[2];
struct Tavlnode28608 {
TY28614 link;
NI key;
NI upperbound;
NI level;
};
struct Tfreecell27830 {
Tfreecell27830* next;
NI zerofield;
};
struct TY748509 {
TGenericSeq Sup;
NU8 data[SEQ_DECL_SIZE];
};
struct Keyvaluepairseq748081 {
TGenericSeq Sup;
Keyvaluepair748084 data[SEQ_DECL_SIZE];
};
N_NIMCALL(GlHEX3Aobjecttype745214*, preparetexture_748104)(CharinfoHEX3Aobjecttype748061** i);
N_NIMCALL(GlHEX3Aobjecttype745214*, sharedgl_746004)(void);
N_NIMCALL(NU32, createtexture_745391)(GlHEX3Aobjecttype745214* gl);
N_STDCALL(void, glbindtexture_160607)(NU32 target, NU32 texture);
N_STDCALL(void, gltexparameteri_290607)(NU32 target, NU32 pname, NI32 param);
static N_INLINE(void, nimFrame)(TFrame* s);
N_NOINLINE(void, stackoverflow_20001)(void);
static N_INLINE(void, popFrame)(void);
N_NIMCALL(TY748509*, newseq_748504)(NI len);
N_NIMCALL(CharinfoHEX3Aobjecttype748061*, bakechars_748115)(FontHEX3Aobjecttype748072* f, NI32 start);
N_NIMCALL(void, TMP672)(void* p, NI op);
N_NIMCALL(void*, newObj)(TNimType* typ, NI size);
N_NIMCALL(NI, mulInt)(NI a, NI b);
N_NIMCALL(NI, addInt)(NI a, NI b);
N_NIMCALL(RectpackerHEX3Aobjecttype742017*, newpacker_742026)(NI32 width, NI32 height);
N_NIMCALL(NimStringDesc*, readfile_13434)(NimStringDesc* filename);
N_NIMCALL(int, stbtt_InitFont)(stbtt_fontinfo* info, fonttype743087 data, int fontstart);
N_NIMCALL(void, logi_718009)(NimStringDesc** a, NI aLen0);
N_NIMCALL(NimStringDesc*, copyString)(NimStringDesc* src);
N_NIMCALL(float, stbtt_ScaleForPixelHeight)(stbtt_fontinfo* info, float height);
N_NIMCALL(void, stbttgetfontvmetrics_743900)(stbtt_fontinfo* info, int* ascent, int* descent, int* linegap);
N_NIMCALL(NI, subInt)(NI a, NI b);
N_NIMCALL(int, stbtt_FindGlyphIndex)(stbtt_fontinfo* info, int unicodecodepoint);
N_NOINLINE(void, raiseIndexError)(void);
N_NIMCALL(void, stbtt_GetGlyphHMetrics)(stbtt_fontinfo* info, int glyphindex, int* advancewidth, int* leftsidebearing);
N_NIMCALL(void, stbtt_GetGlyphBitmapBox)(stbtt_fontinfo* info, int glyph, float scalex, float scaley, int* ix0, int* iy0, int* ix1, int* iy1);
N_NIMCALL(Point742046, packandgrow_742122)(RectpackerHEX3Aobjecttype742017** p, NI32 width, NI32 height);
static N_INLINE(NI, chckRange)(NI i, NI a, NI b);
N_NOINLINE(void, raiseRangeError)(NI64 val);
N_NIMCALL(NI32, width_742058)(RectpackerHEX3Aobjecttype742017* p);
N_NIMCALL(NI32, height_742068)(RectpackerHEX3Aobjecttype742017* p);
N_NIMCALL(void, stbtt_MakeGlyphBitmap)(stbtt_fontinfo* info, NU8* output, int outw, int outh, int outstride, float scalex, float scaley, int glyph);
N_STDCALL(void, glteximage2d_418407)(NU32 target, NI32 level, NI32 internalformat, NI32 width, NI32 height, NI32 border, NU32 format, NU32 type_418416, void* pixels);
N_NIMCALL(void, inittable_748691)(NI initialsize, Table748078* Result);
N_NIMCALL(FontHEX3Aobjecttype748072*, newfontwithfile_748677)(NimStringDesc* pathtottfile, NF size);
N_NIMCALL(void, nimGCvisit)(void* d, NI op);
N_NIMCALL(void, TMP709)(void* p, NI op);
N_NIMCALL(NimStringDesc*, copyStringRC1)(NimStringDesc* src);
static N_INLINE(void, nimGCunrefNoCycle)(void* p);
static N_INLINE(Tcell46746*, usrtocell_50246)(void* usr);
static N_INLINE(void, rtladdzct_51804)(Tcell46746* c);
N_NOINLINE(void, addzct_50217)(Tcellseq46762* s, Tcell46746* c);
N_NIMCALL(NimStringDesc*, findfontfileforface_749406)(NimStringDesc* face);
N_NIMCALL(NimStringDesc*, HEX2F_126492)(NimStringDesc* head, NimStringDesc* tail);
static N_INLINE(void, appendString)(NimStringDesc* dest, NimStringDesc* src);
N_NIMCALL(NimStringDesc*, rawNewString)(NI space);
static N_INLINE(NIM_BOOL, fileexists_124808)(NimStringDesc* filename);
N_NIMCALL(NIM_BOOL, nosexistsFile)(NimStringDesc* filename);
N_NOINLINE(void, raiseOverflow)(void);
N_NIMCALL(FontHEX3Aobjecttype748072*, newfontwithface_749604)(NimStringDesc* face, NF size);
N_NIMCALL(NF, systemfontsize_749808)(void);
N_NIMCALL(FontHEX3Aobjecttype748072*, systemfontofsize_749818)(NF size);
N_NIMCALL(FontHEX3Aobjecttype748072*, systemfont_749864)(void);
static N_INLINE(void, asgnRefNoCycle)(void** dest, void* src);
N_NIMCALL(NIM_BOOL, haskey_750202)(Table748078 t, NI32 key);
static N_INLINE(NI, rawget_750214)(Table748078 t, NI32 key, NI* hc);
static N_INLINE(NI, hash_737804)(NI x);
static N_INLINE(NIM_BOOL, isfilled_739211)(NI hcode);
static N_INLINE(NI, nexttry_739420)(NI h, NI maxhash);
N_NIMCALL(void, HEX5BHEX5DHEX3D_750245)(Table748078* t, NI32 key, CharinfoHEX3Aobjecttype748061* val);
N_NIMCALL(void, enlarge_750282)(Table748078* t);
static N_INLINE(NI, rawgetknownhc_750336)(Table748078 t, NI32 key, NI hc);
N_NIMCALL(void, rawinsert_750362)(Table748078* t, Keyvaluepairseq748081** data, NI32 key, CharinfoHEX3Aobjecttype748061* val, NI hc, NI h);
N_NIMCALL(CharinfoHEX3Aobjecttype748061*, HEX5BHEX5D_750457)(Table748078 t, NI32 key);
N_NIMCALL(void, chunkandcharindexforrune_750004)(FontHEX3Aobjecttype748072* f, NI r, TY750008* Result);
static N_INLINE(NF, HEX2F_88002)(NI x, NI y);
N_NIMCALL(NI, modInt)(NI a, NI b);
N_NIMCALL(void, unsureAsgnRef)(void** dest, void* src);
static N_INLINE(void, HEX2FHEX3D_750587)(NF32* x, NF32 y);
N_NIMCALL(void, getquaddataforrune_750497)(FontHEX3Aobjecttype748072* f, NI r, NF32* quad, NU32* texture, Point93017* pt);
static N_INLINE(void, HEX2BHEX3D_93329)(NF32* x, NF32 y);
N_NIMCALL(Point93017, sizeofstring_750646)(FontHEX3Aobjecttype748072* f, NimStringDesc* s);
N_NIMCALL(Point93017, newsize_93141)(NF32 w, NF32 h);
N_NIMCALL(void, getclosestcursorpositiontopointinstring_750690)(FontHEX3Aobjecttype748072* f, NimStringDesc* s, Point93017 p, NI* position, NF32* offset);
N_NIMCALL(NF32, cursoroffsetforpositioninstring_750748)(FontHEX3Aobjecttype748072* f, NimStringDesc* s, NI position);
STRING_LITERAL(TMP675, "Could not init font", 19);
STRING_LITERAL(TMP710, "Ubuntu-R", 8);
NIM_CONST TY748204 preferredfonts_749009 = {((NimStringDesc*) &TMP710)}
;
STRING_LITERAL(TMP711, "/usr/share/fonts/truetype/ubuntu-font-family", 44);
NIM_CONST TY748204 fontsearchpaths_749206 = {((NimStringDesc*) &TMP711)}
;
STRING_LITERAL(TMP713, ".ttf", 4);
STRING_LITERAL(TMP714, "Tried font \'", 12);
STRING_LITERAL(TMP715, "\' with no luck", 14);
STRING_LITERAL(TMP718, "WARNING: Could not create system font", 37);
NIM_CONST Point93017 TMP762 = {0.0,
0.0}
;
extern TFrame* frameptr_17042;
TNimType NTI748061; /* CharInfo:ObjectType */
extern TNimType NTI112; /* int16 */
TNimType NTI748035; /* BakedCharInfo */
extern TNimType NTI141631; /* GLuint */
extern TNimType NTI122; /* uint16 */
TNimType NTI748060; /* CharInfo */
TNimType NTI748072; /* Font:ObjectType */
extern TNimType NTI748078; /* Table */
extern TNimType NTI128; /* float */
extern TNimType NTI138; /* bool */
extern TNimType NTI149; /* string */
TNimType NTI748071; /* Font */
extern Tgcheap48616 gch_48644;
FontHEX3Aobjecttype748072* sysfont_749004;
static N_INLINE(void, nimFrame)(TFrame* s) {
NI LOC1;
LOC1 = 0;
{
if (!(frameptr_17042 == NIM_NIL)) goto LA4;
LOC1 = ((NI) 0);
}
goto LA2;
LA4: ;
{
LOC1 = ((NI) ((NI16)((*frameptr_17042).calldepth + ((NI16) 1))));
}
LA2: ;
(*s).calldepth = ((NI16) (LOC1));
(*s).prev = frameptr_17042;
frameptr_17042 = s;
{
if (!((*s).calldepth == ((NI16) 2000))) goto LA9;
stackoverflow_20001();
}
LA9: ;
}
static N_INLINE(void, popFrame)(void) {
frameptr_17042 = (*frameptr_17042).prev;
}
N_NIMCALL(GlHEX3Aobjecttype745214*, preparetexture_748104)(CharinfoHEX3Aobjecttype748061** i) {
GlHEX3Aobjecttype745214* result;
nimfr("prepareTexture", "font.nim")
result = 0;
nimln(57, "font.nim");
result = sharedgl_746004();
nimln(58, "font.nim");
(*(*i)).texture = createtexture_745391(result);
nimln(175, "portable_gl.nim");
glbindtexture_160607(((NU32) 3553), (*(*i)).texture);
nimln(189, "portable_gl.nim");
gltexparameteri_290607(((NU32) 3553), ((NU32) 10241), ((NI32) 9729));
popFrame();
return result;
}
N_NIMCALL(void, TMP672)(void* p, NI op) {
CharinfoHEX3Aobjecttype748061* a;
NI LOC1;
a = (CharinfoHEX3Aobjecttype748061*)p;
LOC1 = 0;
for (LOC1 = 0; LOC1 < 672; LOC1++) {
}
}
static N_INLINE(NI, chckRange)(NI i, NI a, NI b) {
NI result;
{ result = 0;
{
NIM_BOOL LOC3;
LOC3 = 0;
LOC3 = (a <= i);
if (!(LOC3)) goto LA4;
LOC3 = (i <= b);
LA4: ;
if (!LOC3) goto LA5;
result = i;
goto BeforeRet;
}
goto LA1;
LA5: ;
{
raiseRangeError(((NI64) (i)));
}
LA1: ;
}BeforeRet: ;
return result;
}
N_NIMCALL(CharinfoHEX3Aobjecttype748061*, bakechars_748115)(FontHEX3Aobjecttype748072* f, NI32 start) {
CharinfoHEX3Aobjecttype748061* result;
NI32 startchar;
NI32 TMP673;
NI32 endchar;
NI32 TMP674;
RectpackerHEX3Aobjecttype742017* rectpacker;
NimStringDesc* rawdata;
stbtt_fontinfo fontinfo;
float scale;
int ascent;
int descent;
int linegap;
TY748213 glyphindexes;
NI32 width;
NI32 height;
TY748509* tempbitmap;
NI32 TMP692;
GlHEX3Aobjecttype745214* gl;
nimfr("bakeChars", "font.nim")
{ result = 0;
nimln(63, "font.nim");
result = (CharinfoHEX3Aobjecttype748061*) newObj((&NTI748060), sizeof(CharinfoHEX3Aobjecttype748061));
nimln(65, "font.nim");
TMP673 = mulInt(start, ((NI32) 96));
startchar = (NI32)(TMP673);
nimln(66, "font.nim");
TMP674 = addInt(startchar, ((NI32) 96));
endchar = (NI32)(TMP674);
nimln(68, "font.nim");
rectpacker = newpacker_742026(((NI32) 32), ((NI32) 32));
nimln(123, "font.nim");
rawdata = readfile_13434((*f).filepath);
memset((void*)(&fontinfo), 0, sizeof(fontinfo));
nimln(126, "font.nim");
{
int LOC3;
TY748204 LOC6;
LOC3 = 0;
LOC3 = stbtt_InitFont((&fontinfo), (*(fonttype743087*) ((&rawdata->data))), ((int) 0));
if (!(LOC3 == ((NI32) 0))) goto LA4;
nimln(127, "font.nim");
memset((void*)LOC6, 0, sizeof(LOC6));
LOC6[0] = copyString(((NimStringDesc*) &TMP675));
logi_718009(LOC6, 1);
nimln(128, "font.nim");
result = NIM_NIL;
goto BeforeRet;
}
LA4: ;
nimln(130, "font.nim");
scale = stbtt_ScaleForPixelHeight((&fontinfo), ((float) ((*f).size)));
ascent = 0;
descent = 0;
linegap = 0;
nimln(132, "font.nim");
stbttgetfontvmetrics_743900((&fontinfo), (&ascent), (&descent), (&linegap));
nimln(133, "font.nim");
ascent = ((int) (((NF32)(((float) (ascent))) * (NF32)(scale))));
nimln(134, "font.nim");
descent = ((int) (((NF32)(((float) (descent))) * (NF32)(scale))));
nimln(135, "font.nim");
linegap = ((int) (((NF32)(((float) (linegap))) * (NF32)(scale))));
memset((void*)glyphindexes, 0, sizeof(glyphindexes));
{
NI32 i_748424;
NI32 HEX3Atmp_748632;
NI res_748635;
i_748424 = 0;
HEX3Atmp_748632 = 0;
nimln(139, "font.nim");
HEX3Atmp_748632 = subInt(endchar, 1);
nimln(1598, "system.nim");
res_748635 = ((NI) (startchar));
{
nimln(1599, "system.nim");
while (1) {
int g;
NI32 TMP676;
int advance;
int lsb;
int x0;
int y0;
int x1;
int y1;
NI32 gw;
NI32 TMP677;
NI32 gh;
NI32 TMP678;
NI32 TMP679;
NI32 TMP680;
Point742046 LOC10;
NI32 x;
NI32 y;
NI c;
NI32 TMP681;
NI32 TMP682;
NI TMP683;
NI TMP684;
NI32 TMP685;
NI TMP686;
NI TMP687;
NI TMP688;
NI TMP689;
NI TMP690;
NI TMP691;
if (!(res_748635 <= ((NI) (HEX3Atmp_748632)))) goto LA9;
nimln(1600, "system.nim");
i_748424 = ((NI32) (res_748635));
nimln(140, "font.nim");
g = stbtt_FindGlyphIndex((&fontinfo), i_748424);
nimln(141, "font.nim");
TMP676 = subInt(i_748424, startchar);
if ((NU)((NI32)(TMP676)) > (NU)(95)) raiseIndexError();
glyphindexes[((NI32)(TMP676))- 0] = g;
advance = 0;
lsb = 0;
x0 = 0;
y0 = 0;
x1 = 0;
y1 = 0;
nimln(143, "font.nim");
stbtt_GetGlyphHMetrics((&fontinfo), g, (&advance), (&lsb));
nimln(144, "font.nim");
stbtt_GetGlyphBitmapBox((&fontinfo), g, scale, -(scale), (&x0), (&y0), (&x1), (&y1));
nimln(145, "font.nim");
TMP677 = subInt(x1, x0);
gw = (NI32)(TMP677);
nimln(146, "font.nim");
TMP678 = subInt(y0, y1);
TMP679 = addInt((NI32)(TMP678), ((NI32) 2));
gh = (NI32)(TMP679);
nimln(147, "font.nim");
TMP680 = addInt(gh, ((NI32) 1));
LOC10 = packandgrow_742122(&rectpacker, gw, (NI32)(TMP680));
x = LOC10.Field0;
y = LOC10.Field1;
nimln(149, "font.nim");
TMP681 = subInt(i_748424, startchar);
TMP682 = mulInt((NI32)(TMP681), ((NI32) 7));
c = ((NI) ((NI32)(TMP682)));
nimln(150, "font.nim");
TMP683 = addInt(c, ((NI) 0));
if ((NU)((NI)(TMP683)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP683))- 0] = ((NI16)chckRange(x0, ((NI16) -32768), ((NI16) 32767)));
nimln(151, "font.nim");
TMP684 = addInt(c, ((NI) 1));
if ((NU)((NI)(TMP684)) > (NU)(671)) raiseIndexError();
TMP685 = subInt(ascent, y0);
(*result).bakedchars[((NI)(TMP684))- 0] = ((NI16)chckRange((NI32)(TMP685), ((NI16) -32768), ((NI16) 32767)));
nimln(152, "font.nim");
TMP686 = addInt(c, ((NI) 2));
if ((NU)((NI)(TMP686)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP686))- 0] = ((NI16) (((NF32)(scale) * (NF32)(((float) (advance))))));
nimln(153, "font.nim");
TMP687 = addInt(c, ((NI) 3));
if ((NU)((NI)(TMP687)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP687))- 0] = ((NI16)chckRange(x, ((NI16) -32768), ((NI16) 32767)));
nimln(154, "font.nim");
TMP688 = addInt(c, ((NI) 4));
if ((NU)((NI)(TMP688)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP688))- 0] = ((NI16)chckRange(y, ((NI16) -32768), ((NI16) 32767)));
nimln(155, "font.nim");
TMP689 = addInt(c, ((NI) 5));
if ((NU)((NI)(TMP689)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP689))- 0] = ((NI16)chckRange(gw, ((NI16) -32768), ((NI16) 32767)));
nimln(156, "font.nim");
TMP690 = addInt(c, ((NI) 6));
if ((NU)((NI)(TMP690)) > (NU)(671)) raiseIndexError();
(*result).bakedchars[((NI)(TMP690))- 0] = ((NI16)chckRange(gh, ((NI16) -32768), ((NI16) 32767)));
nimln(1619, "system.nim");
TMP691 = addInt(res_748635, ((NI) 1));
res_748635 = (NI)(TMP691);
} LA9: ;
}
}
nimln(158, "font.nim");
width = width_742058(rectpacker);
nimln(159, "font.nim");
height = height_742068(rectpacker);
nimln(160, "font.nim");
(*result).texwidth = ((NU16) (width));
nimln(161, "font.nim");
(*result).texheight = ((NU16) (height));
nimln(162, "font.nim");
TMP692 = mulInt(width, height);
tempbitmap = newseq_748504(((NI)chckRange((NI32)(TMP692), ((NI) 0), ((NI) 2147483647))));
{
NI32 i_748561;
NI32 HEX3Atmp_748646;
NI res_748649;
i_748561 = 0;
HEX3Atmp_748646 = 0;
nimln(164, "font.nim");
HEX3Atmp_748646 = subInt(endchar, 1);
nimln(1598, "system.nim");
res_748649 = ((NI) (startchar));
{
nimln(1599, "system.nim");
while (1) {
NI c;
NI32 TMP693;
NI32 TMP694;
NI TMP703;
if (!(res_748649 <= ((NI) (HEX3Atmp_748646)))) goto LA13;
nimln(1600, "system.nim");
i_748561 = ((NI32) (res_748649));
nimln(165, "font.nim");
TMP693 = subInt(i_748561, startchar);
TMP694 = mulInt((NI32)(TMP693), ((NI32) 7));
c = ((NI) ((NI32)(TMP694)));
nimln(166, "font.nim");
{
NI TMP695;
NI x;
NI TMP696;
NI y;
NI TMP697;
int w;
NI TMP698;
int h;
NI TMP699;
NI TMP700;
NI TMP701;
NI32 TMP702;
TMP695 = addInt(c, ((NI) 2));
if ((NU)((NI)(TMP695)) > (NU)(671)) raiseIndexError();
if (!(((NI16) 0) < (*result).bakedchars[((NI)(TMP695))- 0])) goto LA16;
nimln(167, "font.nim");
TMP696 = addInt(c, ((NI) 3));
if ((NU)((NI)(TMP696)) > (NU)(671)) raiseIndexError();
x = ((NI) ((*result).bakedchars[((NI)(TMP696))- 0]));
nimln(168, "font.nim");
TMP697 = addInt(c, ((NI) 4));
if ((NU)((NI)(TMP697)) > (NU)(671)) raiseIndexError();
y = ((NI) ((*result).bakedchars[((NI)(TMP697))- 0]));
nimln(169, "font.nim");
TMP698 = addInt(c, ((NI) 5));
if ((NU)((NI)(TMP698)) > (NU)(671)) raiseIndexError();
w = ((int) ((*result).bakedchars[((NI)(TMP698))- 0]));
nimln(170, "font.nim");
TMP699 = addInt(c, ((NI) 6));
if ((NU)((NI)(TMP699)) > (NU)(671)) raiseIndexError();
h = ((int) ((*result).bakedchars[((NI)(TMP699))- 0]));
nimln(171, "font.nim");
TMP700 = mulInt(y, ((NI) (width)));
TMP701 = addInt(x, (NI)(TMP700));
if ((NU)((NI)(TMP701)) >= (NU)(tempbitmap->Sup.len)) raiseIndexError();
TMP702 = subInt(i_748561, startchar);
if ((NU)((NI32)(TMP702)) > (NU)(95)) raiseIndexError();
stbtt_MakeGlyphBitmap((&fontinfo), (&tempbitmap->data[(NI)(TMP701)]), w, h, width, scale, scale, glyphindexes[((NI32)(TMP702))- 0]);
}
LA16: ;
nimln(1619, "system.nim");
TMP703 = addInt(res_748649, ((NI) 1));
res_748649 = (NI)(TMP703);
} LA13: ;
}
}
nimln(173, "font.nim");
gl = preparetexture_748104(&result);
nimln(192, "portable_gl.nim");
if ((NU)(((NI) 0)) >= (NU)(tempbitmap->Sup.len)) raiseIndexError();
glteximage2d_418407(((NU32) 3553), ((NI32) 0), ((NI32) 6406), width, height, ((NI32) 0), ((NU32) 6406), ((NU32) 5121), ((void*) ((&tempbitmap->data[((NI) 0)]))));
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(void, TMP709)(void* p, NI op) {
FontHEX3Aobjecttype748072* a;
a = (FontHEX3Aobjecttype748072*)p;
nimGCvisit((void*)(*a).chars.data, op);
nimGCvisit((void*)(*a).filepath, op);
}
static N_INLINE(Tcell46746*, usrtocell_50246)(void* usr) {
Tcell46746* result;
nimfr("usrToCell", "gc.nim")
result = 0;
nimln(118, "gc.nim");
result = ((Tcell46746*) ((NI)((NU32)(((NI) (usr))) - (NU32)(((NI)sizeof(Tcell46746))))));
popFrame();
return result;
}
static N_INLINE(void, rtladdzct_51804)(Tcell46746* c) {
nimfr("rtlAddZCT", "gc.nim")
nimln(199, "gc.nim");
addzct_50217((&gch_48644.zct), c);
popFrame();
}
static N_INLINE(void, nimGCunrefNoCycle)(void* p) {
Tcell46746* c;
nimfr("nimGCunrefNoCycle", "gc.nim")
nimln(233, "gc.nim");
c = usrtocell_50246(p);
nimln(235, "gc.nim");
{
nimln(167, "gc.nim");
(*c).refcount -= ((NI) 8);
nimln(168, "gc.nim");
if (!((NU32)((*c).refcount) < (NU32)(((NI) 8)))) goto LA3;
nimln(236, "gc.nim");
rtladdzct_51804(c);
}
LA3: ;
popFrame();
}
N_NIMCALL(FontHEX3Aobjecttype748072*, newfontwithfile_748677)(NimStringDesc* pathtottfile, NF size) {
FontHEX3Aobjecttype748072* result;
NimStringDesc* LOC1;
nimfr("newFontWithFile", "font.nim")
result = 0;
nimln(178, "font.nim");
result = (FontHEX3Aobjecttype748072*) newObj((&NTI748071), sizeof(FontHEX3Aobjecttype748072));
nimln(179, "font.nim");
(*result).ishorizontal = NIM_TRUE;
nimln(180, "font.nim");
LOC1 = 0;
LOC1 = (*result).filepath; (*result).filepath = copyStringRC1(pathtottfile);
if (LOC1) nimGCunrefNoCycle(LOC1);
nimln(181, "font.nim");
(*result).size = size;
nimln(182, "font.nim");
inittable_748691(((NI) 64), (&(*result).chars));
popFrame();
return result;
}
static N_INLINE(void, appendString)(NimStringDesc* dest, NimStringDesc* src) {
memcpy(((NCSTRING) ((&(*dest).data[((*dest).Sup.len)- 0]))), ((NCSTRING) ((*src).data)), (NI)((*src).Sup.len + ((NI) 1)));
(*dest).Sup.len += (*src).Sup.len;
}
static N_INLINE(NIM_BOOL, fileexists_124808)(NimStringDesc* filename) {
NIM_BOOL result;
nimfr("fileExists", "os.nim")
result = 0;
nimln(426, "os.nim");
nimln(427, "os.nim");
result = nosexistsFile(filename);
popFrame();
return result;
}
N_NIMCALL(NimStringDesc*, findfontfileforface_749406)(NimStringDesc* face) {
NimStringDesc* result;
nimfr("findFontFileForFace", "font.nim")
{ result = 0;
{
NimStringDesc* sp_749446;
NI i_749453;
sp_749446 = 0;
nimln(1703, "system.nim");
i_749453 = ((NI) 0);
nimln(1704, "system.nim");
{
if (!(((NI) (i_749453)) <= ((NI) 0))) goto LA4;
{
nimln(1705, "system.nim");
while (1) {
NimStringDesc* f;
NimStringDesc* LOC8;
NimStringDesc* LOC9;
TY749448 LOC15;
NI TMP716;
nimln(1706, "system.nim");
sp_749446 = fontsearchpaths_749206[(i_749453)- 0];
nimln(215, "font.nim");
LOC8 = 0;
LOC9 = 0;
LOC9 = HEX2F_126492(sp_749446, face);
LOC8 = rawNewString(LOC9->Sup.len + 4);
appendString(LOC8, LOC9);
appendString(LOC8, ((NimStringDesc*) &TMP713));
f = LOC8;
nimln(216, "font.nim");
{
NIM_BOOL LOC12;
LOC12 = 0;
LOC12 = fileexists_124808(f);
if (!LOC12) goto LA13;
nimln(217, "font.nim");
result = copyString(f);
goto BeforeRet;
}
LA13: ;
nimln(218, "font.nim");
memset((void*)LOC15, 0, sizeof(LOC15));
LOC15[0] = copyString(((NimStringDesc*) &TMP714));
LOC15[1] = copyString(f);
LOC15[2] = copyString(((NimStringDesc*) &TMP715));
logi_718009(LOC15, 3);
nimln(1707, "system.nim");
{
if (!(((NI) 0) <= ((NI) (i_749453)))) goto LA18;
goto LA6;
}
LA18: ;
nimln(1708, "system.nim");
TMP716 = addInt(i_749453, ((NI) 1));
if (TMP716 < 0 || TMP716 > 0) raiseOverflow();
i_749453 = (NI)(TMP716);
}
} LA6: ;
}
LA4: ;
}
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(FontHEX3Aobjecttype748072*, newfontwithface_749604)(NimStringDesc* face, NF size) {
FontHEX3Aobjecttype748072* result;
NimStringDesc* path;
nimfr("newFontWithFace", "font.nim")
result = 0;
nimln(230, "font.nim");
path = findfontfileforface_749406(face);
nimln(231, "font.nim");
{
if (!!((path == NIM_NIL))) goto LA3;
nimln(232, "font.nim");
result = newfontwithfile_748677(path, size);
}
LA3: ;
popFrame();
return result;
}
N_NIMCALL(NF, systemfontsize_749808)(void) {
NF result;
nimfr("systemFontSize", "font.nim")
result = 0;
nimln(234, "font.nim");
result = 1.6000000000000000e+001;
popFrame();
return result;
}
N_NIMCALL(FontHEX3Aobjecttype748072*, systemfontofsize_749818)(NF size) {
FontHEX3Aobjecttype748072* result;
nimfr("systemFontOfSize", "font.nim")
result = 0;
{
NimStringDesc* f_749832;
NI i_749848;
f_749832 = 0;
nimln(1703, "system.nim");
i_749848 = ((NI) 0);
nimln(1704, "system.nim");
{
if (!(((NI) (i_749848)) <= ((NI) 0))) goto LA4;
{
nimln(1705, "system.nim");
while (1) {
NI TMP717;
nimln(1706, "system.nim");
f_749832 = preferredfonts_749009[(i_749848)- 0];
nimln(238, "font.nim");
result = newfontwithface_749604(f_749832, size);
nimln(239, "font.nim");
{
if (!!((result == NIM_NIL))) goto LA10;
nimln(240, "font.nim");
goto LA1;
}
LA10: ;
nimln(1707, "system.nim");
{
if (!(((NI) 0) <= ((NI) (i_749848)))) goto LA14;
goto LA6;
}
LA14: ;
nimln(1708, "system.nim");
TMP717 = addInt(i_749848, ((NI) 1));
if (TMP717 < 0 || TMP717 > 0) raiseOverflow();
i_749848 = (NI)(TMP717);
}
} LA6: ;
}
LA4: ;
} LA1: ;
popFrame();
return result;
}
static N_INLINE(void, asgnRefNoCycle)(void** dest, void* src) {
nimfr("asgnRefNoCycle", "gc.nim")
nimln(251, "gc.nim");
{
Tcell46746* c;
if (!!((src == NIM_NIL))) goto LA3;
nimln(252, "gc.nim");
c = usrtocell_50246(src);
nimln(169, "gc.nim");
(*c).refcount += ((NI) 8);
}
LA3: ;
nimln(254, "gc.nim");
{
Tcell46746* c;
if (!!(((*dest) == NIM_NIL))) goto LA7;
nimln(255, "gc.nim");
c = usrtocell_50246((*dest));
nimln(256, "gc.nim");
{
nimln(167, "gc.nim");
(*c).refcount -= ((NI) 8);
nimln(168, "gc.nim");
if (!((NU32)((*c).refcount) < (NU32)(((NI) 8)))) goto LA11;
nimln(257, "gc.nim");
rtladdzct_51804(c);
}
LA11: ;
}
LA7: ;
nimln(258, "gc.nim");
(*dest) = src;
popFrame();
}
N_NIMCALL(FontHEX3Aobjecttype748072*, systemfont_749864)(void) {
FontHEX3Aobjecttype748072* result;
nimfr("systemFont", "font.nim")
result = 0;
nimln(243, "font.nim");
{
NF LOC5;
if (!(sysfont_749004 == NIM_NIL)) goto LA3;
nimln(244, "font.nim");
LOC5 = 0;
LOC5 = systemfontsize_749808();
asgnRefNoCycle((void**) (&sysfont_749004), systemfontofsize_749818(LOC5));
}
LA3: ;
nimln(245, "font.nim");
result = sysfont_749004;
nimln(246, "font.nim");
{
TY748204 LOC10;
if (!(result == NIM_NIL)) goto LA8;
nimln(247, "font.nim");
memset((void*)LOC10, 0, sizeof(LOC10));
LOC10[0] = copyString(((NimStringDesc*) &TMP718));
logi_718009(LOC10, 1);
}
LA8: ;
popFrame();
return result;
}
static N_INLINE(NI, hash_737804)(NI x) {
NI result;
nimfr("hash", "hashes.nim")
result = 0;
nimln(107, "hashes.nim");
result = x;
popFrame();
return result;
}
static N_INLINE(NIM_BOOL, isfilled_739211)(NI hcode) {
NIM_BOOL result;
nimfr("isFilled", "tables.nim")
result = 0;
nimln(92, "tables.nim");
result = !((hcode == ((NI) 0)));
popFrame();
return result;
}
static N_INLINE(NI, nexttry_739420)(NI h, NI maxhash) {
NI result;
NI TMP720;
nimfr("nextTry", "tables.nim")
result = 0;
nimln(141, "tables.nim");
TMP720 = addInt(h, ((NI) 1));
result = (NI)((NI)(TMP720) & maxhash);
popFrame();
return result;
}
static N_INLINE(NI, rawget_750214)(Table748078 t, NI32 key, NI* hc) {
NI result;
NI h;
NI TMP721;
nimfr("rawGet", "tables.nim")
{ result = 0;
nimln(156, "tables.nim");
(*hc) = hash_737804(((NI) (key)));
nimln(157, "tables.nim");
{
if (!((*hc) == ((NI) 0))) goto LA3;
nimln(158, "tables.nim");
(*hc) = ((NI) 314159265);
}
LA3: ;
nimln(144, "tables.nim");
h = (NI)((*hc) & (t.data ? (t.data->Sup.len-1) : -1));
{
nimln(145, "tables.nim");
while (1) {
NIM_BOOL LOC7;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC7 = 0;
LOC7 = isfilled_739211(t.data->data[h].Field0);
if (!LOC7) goto LA6;
nimln(150, "tables.nim");
{
NIM_BOOL LOC10;
LOC10 = 0;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC10 = (t.data->data[h].Field0 == (*hc));
if (!(LOC10)) goto LA11;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC10 = (t.data->data[h].Field1 == key);
LA11: ;
if (!LOC10) goto LA12;
nimln(151, "tables.nim");
result = h;
goto BeforeRet;
}
LA12: ;
nimln(152, "tables.nim");
h = nexttry_739420(h, (t.data ? (t.data->Sup.len-1) : -1));
} LA6: ;
}
nimln(153, "tables.nim");
TMP721 = subInt(((NI) -1), h);
result = (NI)(TMP721);
}BeforeRet: ;
popFrame();
return result;
}
static N_INLINE(NI, rawgetknownhc_750336)(Table748078 t, NI32 key, NI hc) {
NI result;
NI h;
NI TMP728;
nimfr("rawGetKnownHC", "tables.nim")
{ result = 0;
nimln(144, "tables.nim");
h = (NI)(hc & (t.data ? (t.data->Sup.len-1) : -1));
{
nimln(145, "tables.nim");
while (1) {
NIM_BOOL LOC3;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC3 = 0;
LOC3 = isfilled_739211(t.data->data[h].Field0);
if (!LOC3) goto LA2;
nimln(150, "tables.nim");
{
NIM_BOOL LOC6;
LOC6 = 0;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC6 = (t.data->data[h].Field0 == hc);
if (!(LOC6)) goto LA7;
if ((NU)(h) >= (NU)(t.data->Sup.len)) raiseIndexError();
LOC6 = (t.data->data[h].Field1 == key);
LA7: ;
if (!LOC6) goto LA8;
nimln(151, "tables.nim");
result = h;
goto BeforeRet;
}
LA8: ;
nimln(152, "tables.nim");
h = nexttry_739420(h, (t.data ? (t.data->Sup.len-1) : -1));
} LA2: ;
}
nimln(153, "tables.nim");
TMP728 = subInt(((NI) -1), h);
result = (NI)(TMP728);
}BeforeRet: ;
popFrame();
return result;
}
static N_INLINE(NF, HEX2F_88002)(NI x, NI y) {
NF result;
nimfr("/", "system.nim")
result = 0;
nimln(2856, "system.nim");
result = ((NF)(((double) (x))) / (NF)(((double) (y))));
popFrame();
return result;
}
N_NIMCALL(void, chunkandcharindexforrune_750004)(FontHEX3Aobjecttype748072* f, NI r, TY750008* Result) {
NI32 chunkstart;
NF LOC1;
NF LOC2;
NI TMP729;
nimfr("chunkAndCharIndexForRune", "font.nim")
nimln(258, "font.nim");
LOC1 = 0;
LOC1 = HEX2F_88002(r, ((NI) 96));
LOC2 = 0;
LOC2 = floor(LOC1);
chunkstart = ((NI32) (LOC2));
nimln(259, "font.nim");
TMP729 = modInt(r, ((NI) 96));
(*Result).Field1 = ((NI) ((NI)(TMP729)));
nimln(272, "font.nim");
{
NIM_BOOL LOC5;
CharinfoHEX3Aobjecttype748061* LOC8;
LOC5 = 0;
LOC5 = haskey_750202((*f).chars, chunkstart);
if (!!(LOC5)) goto LA6;
nimln(273, "font.nim");
LOC8 = 0;
LOC8 = bakechars_748115(f, chunkstart);
HEX5BHEX5DHEX3D_750245((&(*f).chars), chunkstart, LOC8);
}
LA6: ;
nimln(274, "font.nim");
unsureAsgnRef((void**) (&(*Result).Field0), HEX5BHEX5D_750457((*f).chars, chunkstart));
popFrame();
}
static N_INLINE(void, HEX2FHEX3D_750587)(NF32* x, NF32 y) {
nimfr("/=", "system.nim")
nimln(3008, "system.nim");
(*x) = ((NF32)((*x)) / (NF32)(y));
popFrame();
}
static N_INLINE(void, HEX2BHEX3D_93329)(NF32* x, NF32 y) {
nimfr("+=", "system.nim")
nimln(2992, "system.nim");
(*x) = ((NF32)((*x)) + (NF32)(y));
popFrame();
}
N_NIMCALL(void, getquaddataforrune_750497)(FontHEX3Aobjecttype748072* f, NI r, NF32* quad, NU32* texture, Point93017* pt) {
TY750008 LOC1;
CharinfoHEX3Aobjecttype748061* chunk;
NI charindexinchunk;
NI16* bc;
NI c;
NI TMP730;
NF32 x0;
NI TMP731;
NF32 x1;
NI TMP732;
NF32 y0;
NI TMP733;
NF32 y1;
NI TMP734;
NF32 s0;
NI TMP735;
NF32 t0;
NI TMP736;
NF32 s1;
NI TMP737;
NF32 t1;
NI TMP738;
NI TMP739;
nimfr("getQuadDataForRune", "font.nim")
nimln(277, "font.nim");
memset((void*)(&LOC1), 0, sizeof(LOC1));
chunkandcharindexforrune_750004(f, r, (&LOC1));
chunk = 0;
chunk = LOC1.Field0;
charindexinchunk = 0;
charindexinchunk = LOC1.Field1;
nimln(278, "font.nim");
bc = (*chunk).bakedchars;
nimln(279, "font.nim");
TMP730 = mulInt(charindexinchunk, ((NI) 7));
c = (NI)(TMP730);
nimln(281, "font.nim");
TMP731 = addInt(c, ((NI) 0));
if ((NU)((NI)(TMP731)) > (NU)(671)) raiseIndexError();
x0 = ((NF32)((*pt).Field0) + (NF32)(((NF32) (bc[((NI)(TMP731))- 0]))));
nimln(282, "font.nim");
TMP732 = addInt(c, ((NI) 5));
if ((NU)((NI)(TMP732)) > (NU)(671)) raiseIndexError();
x1 = ((NF32)(x0) + (NF32)(((NF32) (bc[((NI)(TMP732))- 0]))));
nimln(283, "font.nim");
TMP733 = addInt(c, ((NI) 1));
if ((NU)((NI)(TMP733)) > (NU)(671)) raiseIndexError();
y0 = ((NF32)((*pt).Field1) + (NF32)(((NF32) (bc[((NI)(TMP733))- 0]))));
nimln(284, "font.nim");
TMP734 = addInt(c, ((NI) 6));
if ((NU)((NI)(TMP734)) > (NU)(671)) raiseIndexError();
y1 = ((NF32)(y0) + (NF32)(((NF32) (bc[((NI)(TMP734))- 0]))));
nimln(286, "font.nim");
TMP735 = addInt(c, ((NI) 3));
if ((NU)((NI)(TMP735)) > (NU)(671)) raiseIndexError();
s0 = ((NF32) (bc[((NI)(TMP735))- 0]));
nimln(287, "font.nim");
TMP736 = addInt(c, ((NI) 4));
if ((NU)((NI)(TMP736)) > (NU)(671)) raiseIndexError();
t0 = ((NF32) (bc[((NI)(TMP736))- 0]));
nimln(288, "font.nim");
TMP737 = addInt(c, ((NI) 5));
if ((NU)((NI)(TMP737)) > (NU)(671)) raiseIndexError();
s1 = ((NF32)(((NF32)(s0) + (NF32)(((NF32) (bc[((NI)(TMP737))- 0]))))) / (NF32)(((NF32) ((*chunk).texwidth))));
nimln(289, "font.nim");
TMP738 = addInt(c, ((NI) 6));
if ((NU)((NI)(TMP738)) > (NU)(671)) raiseIndexError();
t1 = ((NF32)(((NF32)(t0) + (NF32)(((NF32) (bc[((NI)(TMP738))- 0]))))) / (NF32)(((NF32) ((*chunk).texheight))));
nimln(290, "font.nim");
HEX2FHEX3D_750587((&s0), ((NF32) ((*chunk).texwidth)));
nimln(291, "font.nim");
HEX2FHEX3D_750587((&t0), ((NF32) ((*chunk).texheight)));
nimln(293, "font.nim");
quad[(((NI) 0))- 0] = x0;
quad[(((NI) 1))- 0] = y0;
quad[(((NI) 2))- 0] = s0;
quad[(((NI) 3))- 0] = t0;
nimln(294, "font.nim");
quad[(((NI) 4))- 0] = x1;
quad[(((NI) 5))- 0] = y0;
quad[(((NI) 6))- 0] = s1;
quad[(((NI) 7))- 0] = t0;
nimln(295, "font.nim");
quad[(((NI) 8))- 0] = x1;
quad[(((NI) 9))- 0] = y1;
quad[(((NI) 10))- 0] = s1;
quad[(((NI) 11))- 0] = t1;
nimln(296, "font.nim");
quad[(((NI) 12))- 0] = x0;
quad[(((NI) 13))- 0] = y1;
quad[(((NI) 14))- 0] = s0;
quad[(((NI) 15))- 0] = t1;
nimln(297, "font.nim");
TMP739 = addInt(c, ((NI) 2));
if ((NU)((NI)(TMP739)) > (NU)(671)) raiseIndexError();
HEX2BHEX3D_93329((&(*pt).Field0), ((NF32) (bc[((NI)(TMP739))- 0])));
nimln(298, "font.nim");
(*texture) = (*chunk).texture;
popFrame();
}
N_NIMCALL(Point93017, sizeofstring_750646)(FontHEX3Aobjecttype748072* f, NimStringDesc* s) {
Point93017 result;
Point93017 pt;
Matrix4723005 quad;
NU32 tex;
nimfr("sizeOfString", "font.nim")
memset((void*)(&result), 0, sizeof(result));
memset((void*)(&pt), 0, sizeof(pt));
memset((void*)quad, 0, sizeof(quad));
tex = 0;
{
NI ch_750656;
NI i_750665;
NI result_750667;
ch_750656 = 0;
nimln(1250, "unicode.nim");
i_750665 = ((NI) 0);
result_750667 = 0;
{
nimln(1252, "unicode.nim");
while (1) {
if (!(i_750665 < (s ? s->Sup.len : 0))) goto LA3;
nimln(56, "unicode.nim");
{
NI TMP740;
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NU32)(((NI) (((NU8)(s->data[i_750665]))))) <= (NU32)(((NI) 127)))) goto LA6;
nimln(57, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = ((NI) (((NU8)(s->data[i_750665]))));
nimln(58, "unicode.nim");
TMP740 = addInt(i_750665, ((NI) 1));
i_750665 = (NI)(TMP740);
}
goto LA4;
LA6: ;
{
NI TMP741;
NI TMP742;
nimln(59, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750665]))))) >> (NU32)(((NI) 5))) == ((NI) 6))) goto LA9;
nimln(61, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
nimln(62, "unicode.nim");
TMP741 = addInt(i_750665, ((NI) 1));
if ((NU)((NI)(TMP741)) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = (NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750665])))) & ((NI) 31))))) << (NU32)(((NI) 6))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP741)])))) & ((NI) 63)))));
nimln(63, "unicode.nim");
TMP742 = addInt(i_750665, ((NI) 2));
i_750665 = (NI)(TMP742);
}
goto LA4;
LA9: ;
{
NI TMP743;
NI TMP744;
NI TMP745;
nimln(64, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750665]))))) >> (NU32)(((NI) 4))) == ((NI) 14))) goto LA12;
nimln(67, "unicode.nim");
nimln(68, "unicode.nim");
nimln(67, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
nimln(68, "unicode.nim");
TMP743 = addInt(i_750665, ((NI) 1));
if ((NU)((NI)(TMP743)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(69, "unicode.nim");
TMP744 = addInt(i_750665, ((NI) 2));
if ((NU)((NI)(TMP744)) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = (NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750665])))) & ((NI) 15))))) << (NU32)(((NI) 12))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP743)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP744)])))) & ((NI) 63)))));
nimln(70, "unicode.nim");
TMP745 = addInt(i_750665, ((NI) 3));
i_750665 = (NI)(TMP745);
}
goto LA4;
LA12: ;
{
NI TMP746;
NI TMP747;
NI TMP748;
NI TMP749;
nimln(71, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750665]))))) >> (NU32)(((NI) 3))) == ((NI) 30))) goto LA15;
nimln(75, "unicode.nim");
nimln(77, "unicode.nim");
nimln(76, "unicode.nim");
nimln(75, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
nimln(76, "unicode.nim");
TMP746 = addInt(i_750665, ((NI) 1));
if ((NU)((NI)(TMP746)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(77, "unicode.nim");
TMP747 = addInt(i_750665, ((NI) 2));
if ((NU)((NI)(TMP747)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(78, "unicode.nim");
TMP748 = addInt(i_750665, ((NI) 3));
if ((NU)((NI)(TMP748)) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = (NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750665])))) & ((NI) 7))))) << (NU32)(((NI) 18))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP746)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP747)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP748)])))) & ((NI) 63)))));
nimln(79, "unicode.nim");
TMP749 = addInt(i_750665, ((NI) 4));
i_750665 = (NI)(TMP749);
}
goto LA4;
LA15: ;
{
NI TMP750;
NI TMP751;
NI TMP752;
NI TMP753;
NI TMP754;
nimln(80, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750665]))))) >> (NU32)(((NI) 2))) == ((NI) 62))) goto LA18;
nimln(85, "unicode.nim");
nimln(88, "unicode.nim");
nimln(87, "unicode.nim");
nimln(86, "unicode.nim");
nimln(85, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
nimln(86, "unicode.nim");
TMP750 = addInt(i_750665, ((NI) 1));
if ((NU)((NI)(TMP750)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(87, "unicode.nim");
TMP751 = addInt(i_750665, ((NI) 2));
if ((NU)((NI)(TMP751)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(88, "unicode.nim");
TMP752 = addInt(i_750665, ((NI) 3));
if ((NU)((NI)(TMP752)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(89, "unicode.nim");
TMP753 = addInt(i_750665, ((NI) 4));
if ((NU)((NI)(TMP753)) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = (NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750665])))) & ((NI) 3))))) << (NU32)(((NI) 24))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP750)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP751)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP752)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP753)])))) & ((NI) 63)))));
nimln(90, "unicode.nim");
TMP754 = addInt(i_750665, ((NI) 5));
i_750665 = (NI)(TMP754);
}
goto LA4;
LA18: ;
{
NI TMP755;
NI TMP756;
NI TMP757;
NI TMP758;
NI TMP759;
NI TMP760;
nimln(91, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750665]))))) >> (NU32)(((NI) 1))) == ((NI) 126))) goto LA21;
nimln(97, "unicode.nim");
nimln(101, "unicode.nim");
nimln(100, "unicode.nim");
nimln(99, "unicode.nim");
nimln(98, "unicode.nim");
nimln(97, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
nimln(98, "unicode.nim");
TMP755 = addInt(i_750665, ((NI) 1));
if ((NU)((NI)(TMP755)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(99, "unicode.nim");
TMP756 = addInt(i_750665, ((NI) 2));
if ((NU)((NI)(TMP756)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(100, "unicode.nim");
TMP757 = addInt(i_750665, ((NI) 3));
if ((NU)((NI)(TMP757)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(101, "unicode.nim");
TMP758 = addInt(i_750665, ((NI) 4));
if ((NU)((NI)(TMP758)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(102, "unicode.nim");
TMP759 = addInt(i_750665, ((NI) 5));
if ((NU)((NI)(TMP759)) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = (NI)((NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750665])))) & ((NI) 1))))) << (NU32)(((NI) 30))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP755)])))) & ((NI) 63))))) << (NU32)(((NI) 24)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP756)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP757)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP758)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP759)])))) & ((NI) 63)))));
nimln(103, "unicode.nim");
TMP760 = addInt(i_750665, ((NI) 6));
i_750665 = (NI)(TMP760);
}
goto LA4;
LA21: ;
{
NI TMP761;
nimln(105, "unicode.nim");
if ((NU)(i_750665) > (NU)(s->Sup.len)) raiseIndexError();
result_750667 = ((NI) (((NU8)(s->data[i_750665]))));
nimln(106, "unicode.nim");
TMP761 = addInt(i_750665, ((NI) 1));
i_750665 = (NI)(TMP761);
}
LA4: ;
nimln(1251, "unicode.nim");
ch_750656 = result_750667;
nimln(305, "font.nim");
getquaddataforrune_750497(f, ch_750656, quad, (&tex), (&pt));
} LA3: ;
}
}
nimln(306, "font.nim");
result = newsize_93141(pt.Field0, ((NF32) ((*f).size)));
popFrame();
return result;
}
N_NIMCALL(void, getclosestcursorpositiontopointinstring_750690)(FontHEX3Aobjecttype748072* f, NimStringDesc* s, Point93017 p, NI* position, NF32* offset) {
Point93017 pt;
Point93017 closestpoint;
Matrix4723005 quad;
NI i;
NU32 tex;
nimfr("getClosestCursorPositionToPointInString", "font.nim")
nimln(309, "font.nim");
pt = TMP762;
nimln(310, "font.nim");
closestpoint = TMP762;
memset((void*)quad, 0, sizeof(quad));
nimln(312, "font.nim");
i = ((NI) 0);
tex = 0;
{
NI ch_750706;
NI i_750723;
NI result_750725;
ch_750706 = 0;
nimln(1250, "unicode.nim");
i_750723 = ((NI) 0);
result_750725 = 0;
{
nimln(1252, "unicode.nim");
while (1) {
NI TMP786;
if (!(i_750723 < (s ? s->Sup.len : 0))) goto LA3;
nimln(56, "unicode.nim");
{
NI TMP763;
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NU32)(((NI) (((NU8)(s->data[i_750723]))))) <= (NU32)(((NI) 127)))) goto LA6;
nimln(57, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = ((NI) (((NU8)(s->data[i_750723]))));
nimln(58, "unicode.nim");
TMP763 = addInt(i_750723, ((NI) 1));
i_750723 = (NI)(TMP763);
}
goto LA4;
LA6: ;
{
NI TMP764;
NI TMP765;
nimln(59, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750723]))))) >> (NU32)(((NI) 5))) == ((NI) 6))) goto LA9;
nimln(61, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
nimln(62, "unicode.nim");
TMP764 = addInt(i_750723, ((NI) 1));
if ((NU)((NI)(TMP764)) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = (NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750723])))) & ((NI) 31))))) << (NU32)(((NI) 6))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP764)])))) & ((NI) 63)))));
nimln(63, "unicode.nim");
TMP765 = addInt(i_750723, ((NI) 2));
i_750723 = (NI)(TMP765);
}
goto LA4;
LA9: ;
{
NI TMP766;
NI TMP767;
NI TMP768;
nimln(64, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750723]))))) >> (NU32)(((NI) 4))) == ((NI) 14))) goto LA12;
nimln(67, "unicode.nim");
nimln(68, "unicode.nim");
nimln(67, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
nimln(68, "unicode.nim");
TMP766 = addInt(i_750723, ((NI) 1));
if ((NU)((NI)(TMP766)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(69, "unicode.nim");
TMP767 = addInt(i_750723, ((NI) 2));
if ((NU)((NI)(TMP767)) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = (NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750723])))) & ((NI) 15))))) << (NU32)(((NI) 12))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP766)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP767)])))) & ((NI) 63)))));
nimln(70, "unicode.nim");
TMP768 = addInt(i_750723, ((NI) 3));
i_750723 = (NI)(TMP768);
}
goto LA4;
LA12: ;
{
NI TMP769;
NI TMP770;
NI TMP771;
NI TMP772;
nimln(71, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750723]))))) >> (NU32)(((NI) 3))) == ((NI) 30))) goto LA15;
nimln(75, "unicode.nim");
nimln(77, "unicode.nim");
nimln(76, "unicode.nim");
nimln(75, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
nimln(76, "unicode.nim");
TMP769 = addInt(i_750723, ((NI) 1));
if ((NU)((NI)(TMP769)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(77, "unicode.nim");
TMP770 = addInt(i_750723, ((NI) 2));
if ((NU)((NI)(TMP770)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(78, "unicode.nim");
TMP771 = addInt(i_750723, ((NI) 3));
if ((NU)((NI)(TMP771)) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = (NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750723])))) & ((NI) 7))))) << (NU32)(((NI) 18))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP769)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP770)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP771)])))) & ((NI) 63)))));
nimln(79, "unicode.nim");
TMP772 = addInt(i_750723, ((NI) 4));
i_750723 = (NI)(TMP772);
}
goto LA4;
LA15: ;
{
NI TMP773;
NI TMP774;
NI TMP775;
NI TMP776;
NI TMP777;
nimln(80, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750723]))))) >> (NU32)(((NI) 2))) == ((NI) 62))) goto LA18;
nimln(85, "unicode.nim");
nimln(88, "unicode.nim");
nimln(87, "unicode.nim");
nimln(86, "unicode.nim");
nimln(85, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
nimln(86, "unicode.nim");
TMP773 = addInt(i_750723, ((NI) 1));
if ((NU)((NI)(TMP773)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(87, "unicode.nim");
TMP774 = addInt(i_750723, ((NI) 2));
if ((NU)((NI)(TMP774)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(88, "unicode.nim");
TMP775 = addInt(i_750723, ((NI) 3));
if ((NU)((NI)(TMP775)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(89, "unicode.nim");
TMP776 = addInt(i_750723, ((NI) 4));
if ((NU)((NI)(TMP776)) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = (NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750723])))) & ((NI) 3))))) << (NU32)(((NI) 24))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP773)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP774)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP775)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP776)])))) & ((NI) 63)))));
nimln(90, "unicode.nim");
TMP777 = addInt(i_750723, ((NI) 5));
i_750723 = (NI)(TMP777);
}
goto LA4;
LA18: ;
{
NI TMP778;
NI TMP779;
NI TMP780;
NI TMP781;
NI TMP782;
NI TMP783;
nimln(91, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750723]))))) >> (NU32)(((NI) 1))) == ((NI) 126))) goto LA21;
nimln(97, "unicode.nim");
nimln(101, "unicode.nim");
nimln(100, "unicode.nim");
nimln(99, "unicode.nim");
nimln(98, "unicode.nim");
nimln(97, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
nimln(98, "unicode.nim");
TMP778 = addInt(i_750723, ((NI) 1));
if ((NU)((NI)(TMP778)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(99, "unicode.nim");
TMP779 = addInt(i_750723, ((NI) 2));
if ((NU)((NI)(TMP779)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(100, "unicode.nim");
TMP780 = addInt(i_750723, ((NI) 3));
if ((NU)((NI)(TMP780)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(101, "unicode.nim");
TMP781 = addInt(i_750723, ((NI) 4));
if ((NU)((NI)(TMP781)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(102, "unicode.nim");
TMP782 = addInt(i_750723, ((NI) 5));
if ((NU)((NI)(TMP782)) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = (NI)((NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750723])))) & ((NI) 1))))) << (NU32)(((NI) 30))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP778)])))) & ((NI) 63))))) << (NU32)(((NI) 24)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP779)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP780)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP781)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP782)])))) & ((NI) 63)))));
nimln(103, "unicode.nim");
TMP783 = addInt(i_750723, ((NI) 6));
i_750723 = (NI)(TMP783);
}
goto LA4;
LA21: ;
{
NI TMP784;
nimln(105, "unicode.nim");
if ((NU)(i_750723) > (NU)(s->Sup.len)) raiseIndexError();
result_750725 = ((NI) (((NU8)(s->data[i_750723]))));
nimln(106, "unicode.nim");
TMP784 = addInt(i_750723, ((NI) 1));
i_750723 = (NI)(TMP784);
}
LA4: ;
nimln(1251, "unicode.nim");
ch_750706 = result_750725;
nimln(315, "font.nim");
getquaddataforrune_750497(f, ch_750706, quad, (&tex), (&pt));
nimln(316, "font.nim");
{
NIM_BOOL LOC26;
NIM_BOOL LOC27;
NIM_BOOL LOC30;
NI TMP785;
LOC26 = 0;
LOC27 = 0;
LOC27 = (*f).ishorizontal;
if (!(LOC27)) goto LA28;
LOC27 = ((((NF) (((NF32)(p.Field0) - (NF32)(pt.Field0)))) > 0? (((NF) (((NF32)(p.Field0) - (NF32)(pt.Field0))))) : -(((NF) (((NF32)(p.Field0) - (NF32)(pt.Field0)))))) < (((NF) (((NF32)(p.Field0) - (NF32)(closestpoint.Field0)))) > 0? (((NF) (((NF32)(p.Field0) - (NF32)(closestpoint.Field0))))) : -(((NF) (((NF32)(p.Field0) - (NF32)(closestpoint.Field0)))))));
LA28: ;
LOC26 = LOC27;
if (LOC26) goto LA29;
nimln(317, "font.nim");
LOC30 = 0;
LOC30 = !((*f).ishorizontal);
if (!(LOC30)) goto LA31;
LOC30 = ((((NF) (((NF32)(p.Field1) - (NF32)(pt.Field1)))) > 0? (((NF) (((NF32)(p.Field1) - (NF32)(pt.Field1))))) : -(((NF) (((NF32)(p.Field1) - (NF32)(pt.Field1)))))) < (((NF) (((NF32)(p.Field1) - (NF32)(closestpoint.Field1)))) > 0? (((NF) (((NF32)(p.Field1) - (NF32)(closestpoint.Field1))))) : -(((NF) (((NF32)(p.Field1) - (NF32)(closestpoint.Field1)))))));
LA31: ;
LOC26 = LOC30;
LA29: ;
if (!LOC26) goto LA32;
nimln(318, "font.nim");
closestpoint = pt;
nimln(319, "font.nim");
TMP785 = addInt(i, ((NI) 1));
(*position) = (NI)(TMP785);
}
LA32: ;
nimln(320, "font.nim");
TMP786 = addInt(i, ((NI) 1));
i = (NI)(TMP786);
} LA3: ;
}
}
nimln(321, "font.nim");
{
if (!(*f).ishorizontal) goto LA36;
(*offset) = closestpoint.Field0;
}
goto LA34;
LA36: ;
{
(*offset) = closestpoint.Field1;
}
LA34: ;
popFrame();
}
N_NIMCALL(NF32, cursoroffsetforpositioninstring_750748)(FontHEX3Aobjecttype748072* f, NimStringDesc* s, NI position) {
NF32 result;
Point93017 pt;
Matrix4723005 quad;
NI i;
NU32 tex;
nimfr("cursorOffsetForPositionInString", "font.nim")
result = 0;
nimln(324, "font.nim");
pt = TMP762;
memset((void*)quad, 0, sizeof(quad));
nimln(326, "font.nim");
i = ((NI) 0);
tex = 0;
{
NI ch_750760;
NI i_750777;
NI result_750779;
ch_750760 = 0;
nimln(1250, "unicode.nim");
i_750777 = ((NI) 0);
result_750779 = 0;
{
nimln(1252, "unicode.nim");
while (1) {
NI TMP809;
if (!(i_750777 < (s ? s->Sup.len : 0))) goto LA3;
nimln(56, "unicode.nim");
{
NI TMP787;
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NU32)(((NI) (((NU8)(s->data[i_750777]))))) <= (NU32)(((NI) 127)))) goto LA6;
nimln(57, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = ((NI) (((NU8)(s->data[i_750777]))));
nimln(58, "unicode.nim");
TMP787 = addInt(i_750777, ((NI) 1));
i_750777 = (NI)(TMP787);
}
goto LA4;
LA6: ;
{
NI TMP788;
NI TMP789;
nimln(59, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750777]))))) >> (NU32)(((NI) 5))) == ((NI) 6))) goto LA9;
nimln(61, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
nimln(62, "unicode.nim");
TMP788 = addInt(i_750777, ((NI) 1));
if ((NU)((NI)(TMP788)) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = (NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750777])))) & ((NI) 31))))) << (NU32)(((NI) 6))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP788)])))) & ((NI) 63)))));
nimln(63, "unicode.nim");
TMP789 = addInt(i_750777, ((NI) 2));
i_750777 = (NI)(TMP789);
}
goto LA4;
LA9: ;
{
NI TMP790;
NI TMP791;
NI TMP792;
nimln(64, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750777]))))) >> (NU32)(((NI) 4))) == ((NI) 14))) goto LA12;
nimln(67, "unicode.nim");
nimln(68, "unicode.nim");
nimln(67, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
nimln(68, "unicode.nim");
TMP790 = addInt(i_750777, ((NI) 1));
if ((NU)((NI)(TMP790)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(69, "unicode.nim");
TMP791 = addInt(i_750777, ((NI) 2));
if ((NU)((NI)(TMP791)) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = (NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750777])))) & ((NI) 15))))) << (NU32)(((NI) 12))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP790)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP791)])))) & ((NI) 63)))));
nimln(70, "unicode.nim");
TMP792 = addInt(i_750777, ((NI) 3));
i_750777 = (NI)(TMP792);
}
goto LA4;
LA12: ;
{
NI TMP793;
NI TMP794;
NI TMP795;
NI TMP796;
nimln(71, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750777]))))) >> (NU32)(((NI) 3))) == ((NI) 30))) goto LA15;
nimln(75, "unicode.nim");
nimln(77, "unicode.nim");
nimln(76, "unicode.nim");
nimln(75, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
nimln(76, "unicode.nim");
TMP793 = addInt(i_750777, ((NI) 1));
if ((NU)((NI)(TMP793)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(77, "unicode.nim");
TMP794 = addInt(i_750777, ((NI) 2));
if ((NU)((NI)(TMP794)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(78, "unicode.nim");
TMP795 = addInt(i_750777, ((NI) 3));
if ((NU)((NI)(TMP795)) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = (NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750777])))) & ((NI) 7))))) << (NU32)(((NI) 18))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP793)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP794)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP795)])))) & ((NI) 63)))));
nimln(79, "unicode.nim");
TMP796 = addInt(i_750777, ((NI) 4));
i_750777 = (NI)(TMP796);
}
goto LA4;
LA15: ;
{
NI TMP797;
NI TMP798;
NI TMP799;
NI TMP800;
NI TMP801;
nimln(80, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750777]))))) >> (NU32)(((NI) 2))) == ((NI) 62))) goto LA18;
nimln(85, "unicode.nim");
nimln(88, "unicode.nim");
nimln(87, "unicode.nim");
nimln(86, "unicode.nim");
nimln(85, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
nimln(86, "unicode.nim");
TMP797 = addInt(i_750777, ((NI) 1));
if ((NU)((NI)(TMP797)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(87, "unicode.nim");
TMP798 = addInt(i_750777, ((NI) 2));
if ((NU)((NI)(TMP798)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(88, "unicode.nim");
TMP799 = addInt(i_750777, ((NI) 3));
if ((NU)((NI)(TMP799)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(89, "unicode.nim");
TMP800 = addInt(i_750777, ((NI) 4));
if ((NU)((NI)(TMP800)) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = (NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750777])))) & ((NI) 3))))) << (NU32)(((NI) 24))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP797)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP798)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP799)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP800)])))) & ((NI) 63)))));
nimln(90, "unicode.nim");
TMP801 = addInt(i_750777, ((NI) 5));
i_750777 = (NI)(TMP801);
}
goto LA4;
LA18: ;
{
NI TMP802;
NI TMP803;
NI TMP804;
NI TMP805;
NI TMP806;
NI TMP807;
nimln(91, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
if (!((NI)((NU32)(((NI) (((NU8)(s->data[i_750777]))))) >> (NU32)(((NI) 1))) == ((NI) 126))) goto LA21;
nimln(97, "unicode.nim");
nimln(101, "unicode.nim");
nimln(100, "unicode.nim");
nimln(99, "unicode.nim");
nimln(98, "unicode.nim");
nimln(97, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
nimln(98, "unicode.nim");
TMP802 = addInt(i_750777, ((NI) 1));
if ((NU)((NI)(TMP802)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(99, "unicode.nim");
TMP803 = addInt(i_750777, ((NI) 2));
if ((NU)((NI)(TMP803)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(100, "unicode.nim");
TMP804 = addInt(i_750777, ((NI) 3));
if ((NU)((NI)(TMP804)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(101, "unicode.nim");
TMP805 = addInt(i_750777, ((NI) 4));
if ((NU)((NI)(TMP805)) > (NU)(s->Sup.len)) raiseIndexError();
nimln(102, "unicode.nim");
TMP806 = addInt(i_750777, ((NI) 5));
if ((NU)((NI)(TMP806)) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = (NI)((NI)((NI)((NI)((NI)((NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[i_750777])))) & ((NI) 1))))) << (NU32)(((NI) 30))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP802)])))) & ((NI) 63))))) << (NU32)(((NI) 24)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP803)])))) & ((NI) 63))))) << (NU32)(((NI) 18)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP804)])))) & ((NI) 63))))) << (NU32)(((NI) 12)))) | (NI)((NU32)(((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP805)])))) & ((NI) 63))))) << (NU32)(((NI) 6)))) | ((NI) ((NI)(((NI) (((NU8)(s->data[(NI)(TMP806)])))) & ((NI) 63)))));
nimln(103, "unicode.nim");
TMP807 = addInt(i_750777, ((NI) 6));
i_750777 = (NI)(TMP807);
}
goto LA4;
LA21: ;
{
NI TMP808;
nimln(105, "unicode.nim");
if ((NU)(i_750777) > (NU)(s->Sup.len)) raiseIndexError();
result_750779 = ((NI) (((NU8)(s->data[i_750777]))));
nimln(106, "unicode.nim");
TMP808 = addInt(i_750777, ((NI) 1));
i_750777 = (NI)(TMP808);
}
LA4: ;
nimln(1251, "unicode.nim");
ch_750760 = result_750779;
nimln(330, "font.nim");
{
if (!(i == position)) goto LA26;
nimln(331, "font.nim");
goto LA1;
}
LA26: ;
nimln(332, "font.nim");
TMP809 = addInt(i, ((NI) 1));
i = (NI)(TMP809);
nimln(334, "font.nim");
getquaddataforrune_750497(f, ch_750760, quad, (&tex), (&pt));
} LA3: ;
}
} LA1: ;
nimln(335, "font.nim");
{
if (!(*f).ishorizontal) goto LA30;
result = pt.Field0;
}
goto LA28;
LA30: ;
{
result = pt.Field1;
}
LA28: ;
popFrame();
return result;
}
NIM_EXTERNC N_NOINLINE(void, nimx_fontInit)(void) {
nimfr("font", "font.nim")
popFrame();
}
NIM_EXTERNC N_NOINLINE(void, nimx_fontDatInit)(void) {
static TNimNode* TMP671[4];
static TNimNode* TMP707[4];
static TNimNode TMP524[10];
NTI748061.size = sizeof(CharinfoHEX3Aobjecttype748061);
NTI748061.kind = 18;
NTI748061.base = 0;
NTI748061.flags = 3;
TMP671[0] = &TMP524[1];
NTI748035.size = sizeof(Bakedcharinfo748035);
NTI748035.kind = 16;
NTI748035.base = (&NTI112);
NTI748035.flags = 3;
TMP524[1].kind = 1;
TMP524[1].offset = offsetof(CharinfoHEX3Aobjecttype748061, bakedchars);
TMP524[1].typ = (&NTI748035);
TMP524[1].name = "bakedChars";
TMP671[1] = &TMP524[2];
TMP524[2].kind = 1;
TMP524[2].offset = offsetof(CharinfoHEX3Aobjecttype748061, texture);
TMP524[2].typ = (&NTI141631);
TMP524[2].name = "texture";
TMP671[2] = &TMP524[3];
TMP524[3].kind = 1;
TMP524[3].offset = offsetof(CharinfoHEX3Aobjecttype748061, texwidth);
TMP524[3].typ = (&NTI122);
TMP524[3].name = "texWidth";
TMP671[3] = &TMP524[4];
TMP524[4].kind = 1;
TMP524[4].offset = offsetof(CharinfoHEX3Aobjecttype748061, texheight);
TMP524[4].typ = (&NTI122);
TMP524[4].name = "texHeight";
TMP524[0].len = 4; TMP524[0].kind = 2; TMP524[0].sons = &TMP671[0];
NTI748061.node = &TMP524[0];
NTI748060.size = sizeof(CharinfoHEX3Aobjecttype748061*);
NTI748060.kind = 22;
NTI748060.base = (&NTI748061);
NTI748060.flags = 2;
NTI748060.marker = TMP672;
NTI748072.size = sizeof(FontHEX3Aobjecttype748072);
NTI748072.kind = 18;
NTI748072.base = 0;
NTI748072.flags = 2;
TMP707[0] = &TMP524[6];
TMP524[6].kind = 1;
TMP524[6].offset = offsetof(FontHEX3Aobjecttype748072, chars);
TMP524[6].typ = (&NTI748078);
TMP524[6].name = "chars";
TMP707[1] = &TMP524[7];
TMP524[7].kind = 1;
TMP524[7].offset = offsetof(FontHEX3Aobjecttype748072, size);
TMP524[7].typ = (&NTI128);
TMP524[7].name = "size";
TMP707[2] = &TMP524[8];
TMP524[8].kind = 1;
TMP524[8].offset = offsetof(FontHEX3Aobjecttype748072, ishorizontal);
TMP524[8].typ = (&NTI138);
TMP524[8].name = "isHorizontal";
TMP707[3] = &TMP524[9];
TMP524[9].kind = 1;
TMP524[9].offset = offsetof(FontHEX3Aobjecttype748072, filepath);
TMP524[9].typ = (&NTI149);
TMP524[9].name = "filePath";
TMP524[5].len = 4; TMP524[5].kind = 2; TMP524[5].sons = &TMP707[0];
NTI748072.node = &TMP524[5];
NTI748071.size = sizeof(FontHEX3Aobjecttype748072*);
NTI748071.kind = 22;
NTI748071.base = (&NTI748072);
NTI748071.flags = 2;
NTI748071.marker = TMP709;
}
/* Generated by Nim Compiler v0.11.0 */
/* (c) 2015 Andreas Rumpf */
/* The generated code is subject to the original license. */
/* Compiled for: Windows, i386, vcc */
/* Command for C compiler:
cl.exe /c /nologo /IC:\nim\lib /Foc:\users\phowl_000\src\nimx\test\nimcache\ttf_ttf.obj c:\users\phowl_000\src\nimx\test\nimcache\ttf_ttf.c */
#define NIM_INTBITS 32
#include "nimbase.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct stbtt_fontinfo stbtt_fontinfo;
typedef struct stbtt_vertex stbtt_vertex;
typedef struct stbtt_active_edge stbtt_active_edge;
typedef struct stbtt_edge stbtt_edge;
typedef struct NimStringDesc NimStringDesc;
typedef struct TGenericSeq TGenericSeq;
typedef struct stbtt_point stbtt_point;
typedef struct TY744219 TY744219;
typedef struct TNimType TNimType;
typedef struct TNimNode TNimNode;
typedef struct stbtt_bakedchar stbtt_bakedchar;
typedef struct stbtt_aligned_quad stbtt_aligned_quad;
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
typedef NU8 fonttype743087[999999999];
struct stbtt_fontinfo {
void* userdata;
NU8* data;
int fontstart;
int numGlyphs;
int loca;
int head;
int glyf;
int hhea;
int hmtx;
int kern;
int index_map;
int indexToLocFormat;
};
struct stbtt_vertex {
NI16 x;
NI16 y;
NI16 cx;
NI16 cy;
NU8 type;
NU8 padding;
};
struct stbtt_active_edge {
int x;
int dx;
float ey;
stbtt_active_edge* next;
int valid;
};
struct stbtt_edge {
float x0;
float y0;
float x1;
float y1;
int invert;
};
struct TGenericSeq {
NI len;
NI reserved;
};
struct NimStringDesc {
TGenericSeq Sup;
NIM_CHAR data[SEQ_DECL_SIZE];
};
struct stbtt_point {
float x;
float y;
};
typedef N_NIMCALL_PTR(void, TY3289) (void* p, NI op);
typedef N_NIMCALL_PTR(void*, TY3294) (void* p);
struct TNimType {
NI size;
NU8 kind;
NU8 flags;
TNimType* base;
TNimNode* node;
void* finalizer;
TY3289 marker;
TY3294 deepcopy;
};
struct TNimNode {
NU8 kind;
NI offset;
TNimType* typ;
NCSTRING name;
NI len;
TNimNode** sons;
};
struct stbtt_bakedchar {
NU16 x0;
NU16 y0;
NU16 x1;
NU16 y1;
float xoff;
float yoff;
float xadvance;
};
struct stbtt_aligned_quad {
float x0;
float y0;
float s0;
float t0;
float x1;
float y1;
float s1;
float t1;
};
struct stbrp_node {
NU8 x;
};
struct stbrp_context {
int width;
int height;
int x;
int y;
int bottom_y;
};
struct stbrp_rect {
int x;
int y;
int id;
int w;
int h;
int was_packed;
};
struct TY744219 {
TGenericSeq Sup;
stbtt_point data[SEQ_DECL_SIZE];
};
#define STB_TRUETYPE_IMPLEMENTATION
// stb_truetype.h - v1.02 - 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
//
// Misc other:
// Ryan Gordon
//
// VERSION HISTORY
//
// 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.
//
// 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()
//
// 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
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
////
//// 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"
char ttf_buffer[1<<20];
unsigned char temp_bitmap[512*512];
stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
GLstbtt_uint ftex;
void my_stbtt_initfont(void)
{
fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
stbtt_BakeFontBitmap(data,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
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 <stdio.h>
#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!";
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.
#ifdef STB_TRUETYPE_IMPLEMENTATION
// #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;
typedef unsigned short stbtt_uint16;
typedef signed short stbtt_int16;
typedef unsigned int stbtt_uint32;
typedef signed int stbtt_int32;
#endif
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_sort() to override this to avoid qsort
#ifndef STBTT_sort
#include <stdlib.h>
#define STBTT_sort(data,num_items,item_size,compare_func) qsort(data,num_items,item_size,compare_func)
#endif
// #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
#ifndef STBTT_ifloor
#include <math.h>
#define STBTT_ifloor(x) ((int) floor(x))
#define STBTT_iceil(x) ((int) ceil(x))
#endif
#ifndef STBTT_sqrt
#include <math.h>
#define STBTT_sqrt(x) sqrt(x)
#endif
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc
#include <stdlib.h>
#define STBTT_malloc(x,u) ((void)(u),malloc(x))
#define STBTT_free(x,u) ((void)(u),free(x))
#endif
#ifndef STBTT_assert
#include <assert.h>
#define STBTT_assert(x) assert(x)
#endif
#ifndef STBTT_strlen
#include <string.h>
#define STBTT_strlen(x) strlen(x)
#endif
#ifndef STBTT_memcpy
#include <memory.h>
#define STBTT_memcpy memcpy
#define STBTT_memset memset
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
//// INTERFACE
////
////
#ifndef __STB_INCLUDE_STB_TRUETYPE_H__
#define __STB_INCLUDE_STB_TRUETYPE_H__
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
//
// 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
float xoff,yoff,xadvance;
float xoff2,yoff2;
} stbtt_packedchar;
typedef struct stbtt_pack_context stbtt_pack_context;
extern int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
// Initializes a packing context stored in the passed-in stbtt_pack_context.
// Future calls using this context will pack characters into the bitmap passed
// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
// the distance from one row to the next (or 0 to mean they are packed tightly
// together). "padding" is // the amount of padding to leave between each
// character (normally you want '1' for bitmaps you'll use as textures with
// bilinear filtering).
//
// Returns 0 on failure, 1 on success.
extern void stbtt_PackEnd (stbtt_pack_context *spc);
// Cleans up the packing context and frees all memory.
#define STBTT_POINT_SIZE(x) (-(x))
extern int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
// 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_pack_range;
extern int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
// Creates character bitmaps from multiple ranges of characters stored in
// ranges. This will usually create a better-packed bitmap than multiple
// calls to stbtt_PackFontRange.
extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
// Oversampling a font increases the quality by allowing higher-quality subpixel
// positioning, and is especially valuable at smaller text sizes.
//
// This function sets the amount of oversampling for all following calls to
// stbtt_PackFontRange(s). The default (no oversampling) is achieved by
// h_oversample=1, v_oversample=1. The total number of pixels required is
// h_oversample*v_oversample larger than the default; for example, 2x2
// oversampling requires 4x the storage of 1x1. For best results, render
// oversampled textures with bilinear filtering. Look at the readme in
// stb/tests/oversample for information about oversampled fonts
extern void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
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;
int height;
int stride_in_bytes;
int padding;
unsigned int h_oversample, v_oversample;
unsigned char *pixels;
void *nodes;
};
extern float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
// computes a scale factor to produce a font whose EM size is mapped to
// 'pixels' tall. This is probably what traditional APIs compute, but
// I'm not positive.
extern void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
// ascent is the coordinate above the baseline the font extends; descent
// is the coordinate below the baseline the font extends (i.e. it is typically negative)
// lineGap is the spacing between one row's descent and the next row's ascent...
// so you should advance the vertical position by "*ascent - *descent + *lineGap"
// these are expressed in unscaled coordinates, so you must multiply by
// the scale factor for a given size
extern void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
// leftSideBearing is the offset from the current horizontal position to the left edge of the character
// advanceWidth is the offset from the current horizontal position to the next horizontal position
// these are expressed in unscaled coordinates
extern int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
// an additional amount to add to the 'advance' value between ch1 and ch2
extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
// Gets the bounding box of the visible part of the glyph, in unscaled coordinates
extern int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
//////////////////////////////////////////////////////////////////////////////
//
// GLYPH SHAPES (you probably don't need these, but they have to go before
// the bitmaps for C declaration-order reasons)
//
enum
{
STBTT_vmove = 1,
STBTT_vline,
STBTT_vcurve
};
typedef short stbtt_vertex_type;
extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
// returns # of vertices and fills *vertices with the pointer to them
// these are expressed in "unscaled" coordinates
//
// The shape is a series of countours. Each one starts with
// a STBTT_moveto, then consists of a series of mixed
// STBTT_lineto and STBTT_curveto segments. A lineto
// draws a line from previous endpoint to its x,y; a curveto
// draws a quadratic bezier from previous endpoint to
// its x,y, using cx,cy as the bezier control point.
extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
// frees the data allocated above
//////////////////////////////////////////////////////////////////////////////
//
// BITMAP RENDERING
//
extern void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
// frees the bitmap allocated below
extern unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
// 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).
// *width & *height are filled out with the width & height of the bitmap,
// which is stored left-to-right, top-to-bottom.
//
// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
extern 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
extern 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.
extern 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
extern 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.)
extern 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)
extern unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
extern 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);
// @TODO: don't expose this structure
typedef struct
{
int w,h,stride;
unsigned char *pixels;
} stbtt__bitmap;
extern void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, 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
// of what font is what, and don't try to get it out of the .ttf file.
// That's because getting it out of the .ttf file is really hard, because
// the names in the file can appear in many possible encodings, in many
// possible languages, and e.g. if you need a case-insensitive comparison,
// the details of that depend on the encoding & language in a complex way
// (actually underspecified in truetype, but also gigantic).
//
// But you can use the provided functions in two possible ways:
// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
// unicode-encoded names to try to find the font you want;
// you can run this before calling stbtt_InitFont()
//
// stbtt_GetFontNameString() lets you get any of the various strings
// from the file yourself and do your own comparisons on them.
// You have to have called stbtt_InitFont() first.
extern int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
// returns the offset (not index) of the font that matches, or -1 if none
// if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
// if you use any other flag, use a font name like "Arial"; this checks
// the 'macStyle' header field; i don't know if fonts set this consistently
#define STBTT_MACSTYLE_DONTCARE 0
#define STBTT_MACSTYLE_BOLD 1
#define STBTT_MACSTYLE_ITALIC 2
#define STBTT_MACSTYLE_UNDERSCORE 4
#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
extern 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
extern 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.
//
// some of the values for the IDs are below; for more see the truetype spec:
// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
// http://www.microsoft.com/typography/otspec/name.htm
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,
STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
};
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,
STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
};
#ifdef __cplusplus
}
#endif
#endif // __STB_INCLUDE_STB_TRUETYPE_H__
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
//// IMPLEMENTATION
////
////
#ifdef STB_TRUETYPE_IMPLEMENTATION
#ifndef STBTT_MAX_OVERSAMPLE
#define STBTT_MAX_OVERSAMPLE 8
#endif
typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
//////////////////////////////////////////////////////////////////////////
//
// 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
N_NIMCALL(NU8, ttBYTE)(fonttype743087 p);
static N_INLINE(void, nimFrame)(TFrame* s);
N_NOINLINE(void, stackoverflow_20001)(void);
static N_INLINE(void, popFrame)(void);
N_NIMCALL(NI8, ttCHAR)(fonttype743087 p);
N_NIMCALL(NU16, ttUSHORT)(fonttype743087 p);
N_NIMCALL(NU16, ttushort_743348)(fonttype743087 p, NI idx);
N_NIMCALL(NI16, ttSHORT)(fonttype743087 p);
N_NIMCALL(NI16, ttshort_743393)(fonttype743087 p, NI idx);
N_NIMCALL(NU32, ttULONG)(fonttype743087 p);
N_NIMCALL(NU32, ttulong_743475)(fonttype743087 p, NI idx);
N_NIMCALL(NI32, ttlong_743544)(fonttype743087 p, NI idx);
N_NIMCALL(NIM_BOOL, stbtttag4_743562)(NU8* p, NI pLen0, NI idx, NIM_CHAR c0, NIM_CHAR c1, NIM_CHAR c2, NIM_CHAR c3);
N_NOINLINE(void, raiseIndexError)(void);
N_NIMCALL(NI, addInt)(NI a, NI b);
N_NIMCALL(NIM_BOOL, stbtttag_743582)(NU8* p, NI pLen0, NI idx, NCSTRING str);
N_NIMCALL(NIM_BOOL, stbtt_isfont)(fonttype743087 font);
N_NIMCALL(NU32, stbtt_find_table)(fonttype743087 data, NU32 fontstart, NCSTRING tag);
static N_INLINE(NI, chckRange)(NI i, NI a, NI b);
N_NOINLINE(void, raiseRangeError)(NI64 val);
N_NIMCALL(NI, mulInt)(NI a, NI b);
N_NIMCALL(int, stbtt_GetFontOffsetForIndex)(fonttype743087 fontcollection, int index);
N_NIMCALL(int, stbtt_InitFont)(stbtt_fontinfo* info, fonttype743087 data, int fontstart);
N_NIMCALL(NI, subInt)(NI a, NI b);
int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
{
stbtt_uint8 *data = info->data;
stbtt_uint32 index_map = info->index_map;
stbtt_uint16 format = ttUSHORT(data + index_map + 0);
if (format == 0) { // apple byte encoding
stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
if (unicode_codepoint < bytes-6)
return ttBYTE(data + index_map + 6 + unicode_codepoint);
return 0;
} else if (format == 6) {
stbtt_uint32 first = ttUSHORT(data + index_map + 6);
stbtt_uint32 count = ttUSHORT(data + index_map + 8);
if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
return 0;
} else if (format == 2) {
STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
return 0;
} else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
stbtt_uint16 item, offset, start, end;
// do a binary search of the segments
stbtt_uint32 endCount = index_map + 14;
stbtt_uint32 search = endCount;
if (unicode_codepoint > 0xffff)
return 0;
// they lie from endCount .. endCount + segCount
// but searchRange is the nearest power of two, so...
if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
search += rangeShift*2;
// now decrement to bias correctly to find smallest
search -= 2;
while (entrySelector) {
searchRange >>= 1;
start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2);
end = ttUSHORT(data + search + searchRange*2);
if (unicode_codepoint > end)
search += searchRange*2;
--entrySelector;
}
search += 2;
item = (stbtt_uint16) ((search - endCount) >> 1);
STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
end = ttUSHORT(data + index_map + 14 + 2 + 2*item);
if (unicode_codepoint < start)
return 0;
offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
if (offset == 0)
return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
} else if (format == 12 || format == 13) {
stbtt_uint32 ngroups = ttULONG(data+index_map+12);
stbtt_int32 low,high;
low = 0; high = (stbtt_int32)ngroups;
// Binary search the right group.
while (low < high) {
stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
if ((stbtt_uint32) unicode_codepoint < start_char)
high = mid;
else if ((stbtt_uint32) unicode_codepoint > end_char)
low = mid+1;
else {
stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
if (format == 12)
return start_glyph + unicode_codepoint-start_char;
else // format == 13
return start_glyph;
}
}
return 0; // not found
}
// @TODO
STBTT_assert(0);
return 0;
}
int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
{
return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
}
N_NIMCALL(void, stbtt_setvertex)(stbtt_vertex* v, NU8 t, NI32 x, NI32 y, NI32 cx, NI32 cy);
N_NIMCALL(int, stbtt_GetGlyfOffset)(stbtt_fontinfo* info, int glyphindex);
N_NIMCALL(int, stbtt_GetGlyphBox)(stbtt_fontinfo* info, int glyphindex, int* x0, int* y0, int* x1, int* y1);
N_NIMCALL(NIM_BOOL, stbttisglyphempty_743865)(stbtt_fontinfo* info, int glyphindex);
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);
}
static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off,
stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
{
if (start_off) {
if (was_off)
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
} else {
if (was_off)
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
else
stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
}
return num_vertices;
}
int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
{
stbtt_int16 numberOfContours;
stbtt_uint8 *endPtsOfContours;
stbtt_uint8 *data = info->data;
stbtt_vertex *vertices=0;
int num_vertices=0;
int g = stbtt_GetGlyfOffset(info, glyph_index);
*pvertices = NULL;
if (g < 0) return 0;
numberOfContours = ttSHORT(data + g);
if (numberOfContours > 0) {
stbtt_uint8 flags=0,flagcount;
stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
stbtt_uint8 *points;
endPtsOfContours = (data + g + 10);
ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
points = data + g + 10 + numberOfContours * 2 + 2 + ins;
n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
m = n + 2*numberOfContours; // a loose bound on how many vertices we might need
vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
if (vertices == 0)
return 0;
next_move = 0;
flagcount=0;
// in first pass, we load uninterpreted data into the allocated array
// above, shifted to the end of the array so we won't overwrite it when
// we create our final data starting from the front
off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
// first load flags
for (i=0; i < n; ++i) {
if (flagcount == 0) {
flags = *points++;
if (flags & 8)
flagcount = *points++;
} else
--flagcount;
vertices[off+i].type = flags;
}
// now load x coordinates
x=0;
for (i=0; i < n; ++i) {
flags = vertices[off+i].type;
if (flags & 2) {
stbtt_int16 dx = *points++;
x += (flags & 16) ? dx : -dx; // ???
} else {
if (!(flags & 16)) {
x = x + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
}
}
vertices[off+i].x = (stbtt_int16) x;
}
// now load y coordinates
y=0;
for (i=0; i < n; ++i) {
flags = vertices[off+i].type;
if (flags & 4) {
stbtt_int16 dy = *points++;
y += (flags & 32) ? dy : -dy; // ???
} else {
if (!(flags & 32)) {
y = y + (stbtt_int16) (points[0]*256 + points[1]);
points += 2;
}
}
vertices[off+i].y = (stbtt_int16) y;
}
// now convert them to our format
num_vertices=0;
sx = sy = cx = cy = scx = scy = 0;
for (i=0; i < n; ++i) {
flags = vertices[off+i].type;
x = (stbtt_int16) vertices[off+i].x;
y = (stbtt_int16) vertices[off+i].y;
if (next_move == i) {
if (i != 0)
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
// now start the new one
start_off = !(flags & 1);
if (start_off) {
// if we start off with an off-curve point, then when we need to find a point on the curve
// where we can start, and we need to save some state for when we wraparound.
scx = x;
scy = y;
if (!(vertices[off+i+1].type & 1)) {
// next point is also a curve point, so interpolate an on-point curve
sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
} else {
// otherwise just use the next point as our start point
sx = (stbtt_int32) vertices[off+i+1].x;
sy = (stbtt_int32) vertices[off+i+1].y;
++i; // we're using point i+1 as the starting point, so skip it
}
} else {
sx = x;
sy = y;
}
stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
was_off = 0;
next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
++j;
} else {
if (!(flags & 1)) { // if it's a curve
if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
cx = x;
cy = y;
was_off = 1;
} else {
if (was_off)
stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
else
stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
was_off = 0;
}
}
}
num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
} else if (numberOfContours == -1) {
// Compound shapes.
int more = 1;
stbtt_uint8 *comp = data + g + 10;
num_vertices = 0;
vertices = 0;
while (more) {
stbtt_uint16 flags, gidx;
int comp_num_verts = 0, i;
stbtt_vertex *comp_verts = 0, *tmp = 0;
float mtx[6] = {1,0,0,1,0,0}, m, n;
flags = ttSHORT(comp); comp+=2;
gidx = ttSHORT(comp); comp+=2;
if (flags & 2) { // XY values
if (flags & 1) { // shorts
mtx[4] = ttSHORT(comp); comp+=2;
mtx[5] = ttSHORT(comp); comp+=2;
} else {
mtx[4] = ttCHAR(comp); comp+=1;
mtx[5] = ttCHAR(comp); comp+=1;
}
}
else {
// @TODO handle matching point
STBTT_assert(0);
}
if (flags & (1<<3)) { // WE_HAVE_A_SCALE
mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
} else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = mtx[2] = 0;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
} else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
}
// Find transformation scales.
m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
// Get indexed glyph.
comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
if (comp_num_verts > 0) {
// Transform vertices.
for (i = 0; i < comp_num_verts; ++i) {
stbtt_vertex* v = &comp_verts[i];
stbtt_vertex_type x,y;
x=v->x; y=v->y;
v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
x=v->cx; y=v->cy;
v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
}
// Append vertices.
tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
if (!tmp) {
if (vertices) STBTT_free(vertices, info->userdata);
if (comp_verts) STBTT_free(comp_verts, info->userdata);
return 0;
}
if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
if (vertices) STBTT_free(vertices, info->userdata);
vertices = tmp;
STBTT_free(comp_verts, info->userdata);
num_vertices += comp_num_verts;
}
// More components ?
more = flags & (1<<5);
}
} else if (numberOfContours < 0) {
// @TODO other compound variations?
STBTT_assert(0);
} else {
// numberOfCounters == 0, do nothing
}
*pvertices = vertices;
return num_vertices;
}
N_NIMCALL(void, stbtt_GetGlyphHMetrics)(stbtt_fontinfo* info, int glyphindex, int* advancewidth, int* leftsidebearing);
int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
{
stbtt_uint8 *data = info->data + info->kern;
stbtt_uint32 needle, straw;
int l, r, m;
// we only look at the first table. it must be 'horizontal' and format 0.
if (!info->kern)
return 0;
if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
return 0;
if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
return 0;
l = 0;
r = ttUSHORT(data+10) - 1;
needle = glyph1 << 16 | glyph2;
while (l <= r) {
m = (l + r) >> 1;
straw = ttULONG(data+18+(m*6)); // note: unaligned read
if (needle < straw)
r = m - 1;
else if (needle > straw)
l = m + 1;
else
return ttSHORT(data+22+(m*6));
}
return 0;
}
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
return 0;
return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
}
void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
{
stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
}
N_NIMCALL(void, stbttgetfontvmetrics_743900)(stbtt_fontinfo* info, int* ascent, int* descent, int* linegap);
N_NIMCALL(void, stbttgetfontboundingbox_743913)(stbtt_fontinfo* info, NI* x0, NI* y0, NI* x1, NI* y1);
N_NIMCALL(float, stbtt_ScaleForPixelHeight)(stbtt_fontinfo* info, float height);
N_NOINLINE(void, raiseOverflow)(void);
float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
{
int unitsPerEm = ttUSHORT(info->data + info->head + 18);
return pixels / unitsPerEm;
}
void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
{
STBTT_free(v, info->userdata);
}
//////////////////////////////////////////////////////////////////////////////
//
// antialiasing software rasterizer
//
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 (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)?
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);
if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
}
}
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);
}
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);
}
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);
}
N_NIMCALL(stbtt_active_edge*, new_active)(stbtt_edge* e, int offx, float startpoint, void* userdata);
N_NIMCALL(void, failedassertimpl_88817)(NimStringDesc* msg);
#define FIXSHIFT 10
#define FIX (1 << FIXSHIFT)
#define FIXMASK (FIX-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
static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt_active_edge *e, int max_weight)
{
// non-zero winding fill
int x0=0, 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->valid;
} else {
int x1 = e->x; w += e->valid;
// if we went to zero, we need to draw
if (w == 0) {
int i = x0 >> FIXSHIFT;
int j = x1 >> FIXSHIFT;
if (i < len && j >= 0) {
if (i == j) {
// x0,x1 are the same pixel, so compute combined coverage
scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> FIXSHIFT);
} else {
if (i >= 0) // add antialiasing for x0
scanline[i] = scanline[i] + (stbtt_uint8) (((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT);
else
i = -1; // clip
if (j < len) // add antialiasing for x1
scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT);
else
j = len; // clip
for (++i; i < j; ++i) // fill pixels between x0 and x1
scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
}
}
}
}
e = e->next;
}
}
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt_edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{
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;
if (result->w > 512)
scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
else
scanline = scanline_data;
y = off_y * vsubsample;
e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
while (j < result->h) {
STBTT_memset(scanline, 0, result->w);
for (s=0; s < vsubsample; ++s) {
// find center of pixel for this scanline
float scan_y = y + 0.5f;
stbtt_active_edge **step = &active;
// update all active edges;
// remove all active edges that terminate before the center of this scanline
while (*step) {
stbtt_active_edge * z = *step;
if (z->ey <= scan_y) {
*step = z->next; // delete from list
STBTT_assert(z->valid);
z->valid = 0;
STBTT_free(z, userdata);
} else {
z->x += z->dx; // advance to position for current scanline
step = &((*step)->next); // advance through list
}
}
// resort the list if needed
for(;;) {
int changed=0;
step = &active;
while (*step && (*step)->next) {
if ((*step)->x > (*step)->next->x) {
stbtt_active_edge *t = *step;
stbtt_active_edge *q = t->next;
t->next = q->next;
q->next = t;
*step = q;
changed = 1;
}
step = &(*step)->next;
}
if (!changed) break;
}
// insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
while (e->y0 <= scan_y) {
if (e->y1 > scan_y) {
stbtt_active_edge *z = new_active(e, off_x, scan_y, userdata);
// find insertion point
if (active == NULL)
active = z;
else if (z->x < active->x) {
// insert at front
z->next = active;
active = z;
} else {
// find thing to insert AFTER
stbtt_active_edge *p = active;
while (p->next && p->next->x < z->x)
p = p->next;
// at this point, p->next->x is NOT < z->x
z->next = p->next;
p->next = z;
}
}
++e;
}
// now process all active edges in XOR fashion
if (active)
stbtt__fill_active_edges(scanline, result->w, active, max_weight);
++y;
}
STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
++j;
}
while (active) {
stbtt_active_edge *z = active;
active = active->next;
STBTT_free(z, userdata);
}
if (scanline != scanline_data)
STBTT_free(scanline, userdata);
}
static int stbtt__edge_compare(const void *p, const void *q)
{
stbtt_edge *a = (stbtt_edge *) p;
stbtt_edge *b = (stbtt_edge *) q;
if (a->y0 < b->y0) return -1;
if (a->y0 > b->y0) return 1;
return 0;
}
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;
int n,i,j,k,m;
int vsubsample = result->h < 8 ? 15 : 5;
// vsubsample should divide 255 evenly; otherwise we won't reach full opacity
// 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
if (e == 0) return;
n = 0;
m=0;
for (i=0; i < windings; ++i) {
stbtt_point *p = pts + m;
m += wcount[i];
j = wcount[i]-1;
for (k=0; k < wcount[i]; j=k++) {
int a=k,b=j;
// skip the edge if horizontal
if (p[j].y == p[k].y)
continue;
// 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;
a=j,b=k;
}
e[n].x0 = p[a].x * scale_x + shift_x;
e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
e[n].x1 = p[b].x * scale_x + shift_x;
e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
++n;
}
}
// 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, 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);
}
N_NIMCALL(void, stbttaddpoint_744034)(stbtt_point* points, NI pointsLen0, NI n, NF x, NF y);
N_NIMCALL(void, stbtttesselatecurve_744055)(stbtt_point* points, NI pointsLen0, int* numpoints, NF x0, NF y0, NF x1, NF y1, NF x2, NF y2, NF objspaceflatnesssquared, NI n);
N_NIMCALL(TY744219*, newseq_744214)(NI len);
N_NIMCALL(stbtt_point*, tocarray_744306)(TY744219* s);
N_NIMCALL(stbtt_point*, stbtt_FlattenCurves)(stbtt_vertex* vertices, NI verticesLen0, float objspaceflatness, int** contourlengths, int* numcontours, void* userdata);
N_NIMCALL(void*, newSeq)(TNimType* typ, NI len);
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) {
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);
}
}
void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
{
STBTT_free(bitmap, userdata);
}
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;
stbtt_vertex *vertices;
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;
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
gbm.w = (ix1 - ix0);
gbm.h = (iy1 - iy0);
gbm.pixels = NULL; // in case we error
if (width ) *width = gbm.w;
if (height) *height = gbm.h;
if (xoff ) *xoff = ix0;
if (yoff ) *yoff = iy0;
if (gbm.w && gbm.h) {
gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
if (gbm.pixels) {
gbm.stride = gbm.w;
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
}
}
STBTT_free(vertices, info->userdata);
return gbm.pixels;
}
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);
}
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;
int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
stbtt__bitmap gbm;
stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
gbm.pixels = output;
gbm.w = out_w;
gbm.h = out_h;
gbm.stride = out_stride;
if (gbm.w && gbm.h)
stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
STBTT_free(vertices, info->userdata);
}
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);
}
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);
}
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));
}
unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
{
return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
}
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);
}
//////////////////////////////////////////////////////////////////////////////
//
// bitmap baking
//
// This is SUPER-CRAPPY packing to keep source code small
extern 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
x=y=1;
bottom_y = 1;
scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
for (i=0; i < num_chars; ++i) {
int advance, lsb, x0,y0,x1,y1,gw,gh;
int g = stbtt_FindGlyphIndex(&f, first_char + i);
stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
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
return -i;
STBTT_assert(x+gw < pw);
STBTT_assert(y+gh < ph);
stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
chardata[i].x0 = (stbtt_int16) x;
chardata[i].y0 = (stbtt_int16) y;
chardata[i].x1 = (stbtt_int16) (x + gw);
chardata[i].y1 = (stbtt_int16) (y + gh);
chardata[i].xadvance = scale * advance;
chardata[i].xoff = (float) x0;
chardata[i].yoff = (float) y0;
x = x + gw + 1;
if (y+gh+1 > bottom_y)
bottom_y = y+gh+1;
}
return bottom_y;
}
N_NIMCALL(void, stbtt_GetBakedQuad)(stbtt_bakedchar* bakedchar, NI pw, NI ph, float* xpos, float* ypos, stbtt_aligned_quad* q, NIM_BOOL openglfillrule);
static N_INLINE(void, HEX2BHEX3D_93329)(NF32* x, NF32 y);
//////////////////////////////////////////////////////////////////////////////
//
// rectangle packing replacement routines if you don't have stb_rect_pack.h
//
#ifndef STB_RECT_PACK_VERSION
#ifdef _MSC_VER
#define STBTT__NOTUSED(v) (void)(v)
#else
#define STBTT__NOTUSED(v) (void)sizeof(v)
#endif
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" //
// //
////////////////////////////////////////////////////////////////////////////////////
N_NIMCALL(void, stbrp_init_target)(stbrp_context* con, int pw, int ph, stbrp_node* nodes, NI nodesLen0);
N_NIMCALL(void, stbrp_pack_rects)(stbrp_context* con, stbrp_rect* rects, NI rectsLen0);
#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.
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);
int num_nodes = pw - padding;
stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
if (context == NULL || nodes == NULL) {
if (context != NULL) STBTT_free(context, alloc_context);
if (nodes != NULL) STBTT_free(nodes , alloc_context);
return 0;
}
spc->user_allocator_context = alloc_context;
spc->width = pw;
spc->height = ph;
spc->pixels = pixels;
spc->pack_info = context;
spc->nodes = nodes;
spc->padding = padding;
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
spc->h_oversample = 1;
spc->v_oversample = 1;
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
return 1;
}
void stbtt_PackEnd (stbtt_pack_context *spc)
{
STBTT_free(spc->nodes , spc->user_allocator_context);
STBTT_free(spc->pack_info, spc->user_allocator_context);
}
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);
if (h_oversample <= STBTT_MAX_OVERSAMPLE)
spc->h_oversample = h_oversample;
if (v_oversample <= STBTT_MAX_OVERSAMPLE)
spc->v_oversample = v_oversample;
}
#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)
{
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width;
int j;
for (j=0; j < h; ++j) {
int i;
unsigned int total;
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) {
case 2:
for (i=0; i <= safe_w; ++i) {
total += pixels[i] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
pixels[i] = (unsigned char) (total / 2);
}
break;
case 3:
for (i=0; i <= safe_w; ++i) {
total += pixels[i] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
pixels[i] = (unsigned char) (total / 3);
}
break;
case 4:
for (i=0; i <= safe_w; ++i) {
total += pixels[i] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
pixels[i] = (unsigned char) (total / 4);
}
break;
default:
for (i=0; i <= safe_w; ++i) {
total += pixels[i] - buffer[i & STBTT__OVER_MASK];
buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
pixels[i] = (unsigned char) (total / kernel_width);
}
break;
}
for (; i < w; ++i) {
STBTT_assert(pixels[i] == 0);
total -= buffer[i & STBTT__OVER_MASK];
pixels[i] = (unsigned char) (total / kernel_width);
}
pixels += stride_in_bytes;
}
}
static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
{
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width;
int j;
for (j=0; j < w; ++j) {
int i;
unsigned int total;
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) {
case 2:
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) {
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) {
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) {
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);
}
break;
}
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);
}
pixels += 1;
}
}
N_NIMCALL(NF, stbtt_oversample_shift)(int oversample);
int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
{
stbtt_fontinfo info;
float recip_h = 1.0f / spc->h_oversample;
float recip_v = 1.0f / spc->v_oversample;
float sub_x = stbtt_oversample_shift(spc->h_oversample);
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
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 =
ranges[i].chardata_for_range[j].y0 =
ranges[i].chardata_for_range[j].x1 =
ranges[i].chardata_for_range[j].y1 = 0;
n = 0;
for (i=0; i < num_ranges; ++i)
n += ranges[i].num_chars_in_range;
rects = (stbrp_rect *) calloc(n, sizeof(*rects));
if (rects == NULL)
return 0;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
k=0;
for (i=0; i < num_ranges; ++i) {
float fh = ranges[i].font_size;
float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
for (j=0; j < ranges[i].num_chars_in_range; ++j) {
int x0,y0,x1,y1;
stbtt_GetCodepointBitmapBoxSubpixel(&info, ranges[i].first_unicode_char_in_range + j,
scale * spc->h_oversample,
scale * spc->v_oversample,
0,0,
&x0,&y0,&x1,&y1);
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
++k;
}
}
stbrp_pack_rects(context, rects, k);
k = 0;
for (i=0; i < num_ranges; ++i) {
float fh = ranges[i].font_size;
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) {
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
r->x += pad;
r->y += pad;
r->w -= pad;
r->h -= pad;
stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb);
stbtt_GetGlyphBitmapBox(&info, glyph,
scale * spc->h_oversample,
scale * spc->v_oversample,
&x0,&y0,&x1,&y1);
stbtt_MakeGlyphBitmapSubpixel(&info,
spc->pixels + r->x + r->y*spc->stride_in_bytes,
r->w - spc->h_oversample+1,
r->h - spc->v_oversample+1,
spc->stride_in_bytes,
scale * spc->h_oversample,
scale * spc->v_oversample,
0,0,
glyph);
if (spc->h_oversample > 1)
stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
r->w, r->h, spc->stride_in_bytes,
spc->h_oversample);
if (spc->v_oversample > 1)
stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
r->w, r->h, spc->stride_in_bytes,
spc->v_oversample);
bc->x0 = (stbtt_int16) r->x;
bc->y0 = (stbtt_int16) r->y;
bc->x1 = (stbtt_int16) (r->x + r->w);
bc->y1 = (stbtt_int16) (r->y + r->h);
bc->xadvance = scale * advance;
bc->xoff = (float) x0 * recip_h + sub_x;
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
}
++k;
}
}
return return_value;
}
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)
{
stbtt_pack_range range;
range.first_unicode_char_in_range = first_unicode_char_in_range;
range.num_chars_in_range = num_chars_in_range;
range.chardata_for_range = chardata_for_range;
range.font_size = font_size;
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
}
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;
if (align_to_integer) {
float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5);
float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5);
q->x0 = x;
q->y0 = y;
q->x1 = x + b->xoff2 - b->xoff;
q->y1 = y + b->yoff2 - b->yoff;
} else {
q->x0 = *xpos + b->xoff;
q->y0 = *ypos + b->yoff;
q->x1 = *xpos + b->xoff2;
q->y1 = *ypos + b->yoff2;
}
q->s0 = b->x0 * ipw;
q->t0 = b->y0 * iph;
q->s1 = b->x1 * ipw;
q->t1 = b->y1 * iph;
*xpos += b->xadvance;
}
//////////////////////////////////////////////////////////////////////////////
//
// 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
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
while (len2) {
stbtt_uint16 ch = s2[0]*256 + s2[1];
if (ch < 0x80) {
if (i >= len1) return -1;
if (s1[i++] != ch) return -1;
} else if (ch < 0x800) {
if (i+1 >= len1) return -1;
if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
} else if (ch >= 0xd800 && ch < 0xdc00) {
stbtt_uint32 c;
stbtt_uint16 ch2 = s2[2]*256 + s2[3];
if (i+3 >= len1) return -1;
c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
if (s1[i++] != 0xf0 + (c >> 18)) return -1;
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
len2 -= 2;
} else if (ch >= 0xdc00 && ch < 0xe000) {
return -1;
} else {
if (i+2 >= len1) return -1;
if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1;
}
s2 += 2;
len2 -= 2;
}
return i;
}
int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
{
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
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;
stbtt_uint32 offset = font->fontstart;
stbtt_uint32 nm = stbtt_find_table(fc, offset, "name");
if (!nm) return NULL;
count = ttUSHORT(fc+nm+2);
stringOffset = nm + ttUSHORT(fc+nm+4);
for (i=0; i < count; ++i) {
stbtt_uint32 loc = nm + 6 + 12 * i;
if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
&& languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
*length = ttUSHORT(fc+loc+8);
return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
}
}
return NULL;
}
static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
{
stbtt_int32 i;
stbtt_int32 count = ttUSHORT(fc+nm+2);
stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
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
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)) {
stbtt_int32 slen = ttUSHORT(fc+loc+8);
stbtt_int32 off = ttUSHORT(fc+loc+10);
// 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) {
slen = ttUSHORT(fc+loc+12+8);
off = ttUSHORT(fc+loc+12+10);
if (slen == 0) {
if (matchlen == nlen)
return 1;
} 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
if (matchlen == nlen)
return 1;
}
}
}
// @TODO handle other encodings
}
}
return 0;
}
static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
{
stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
stbtt_uint32 nm,hd;
if (!stbtt_isfont(fc+offset)) return 0;
// 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 (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 {
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;
}
return 0;
}
int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags)
{
stbtt_int32 i;
for (i=0;;++i) {
stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
if (off < 0) return off;
if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
return off;
}
}
#endif // STB_TRUETYPE_IMPLEMENTATION
STRING_LITERAL(TMP633, "e.y0 <= start_point ", 20);
extern TFrame* frameptr_17042;
TNimType NTI744025; /* stbtt_point */
extern TNimType NTI5817; /* cfloat */
extern TNimType NTI744219; /* seq[stbtt_point] */
static N_INLINE(void, nimFrame)(TFrame* s) {
NI LOC1;
LOC1 = 0;
{
if (!(frameptr_17042 == NIM_NIL)) goto LA4;
LOC1 = ((NI) 0);
}
goto LA2;
LA4: ;
{
LOC1 = ((NI) ((NI16)((*frameptr_17042).calldepth + ((NI16) 1))));
}
LA2: ;
(*s).calldepth = ((NI16) (LOC1));
(*s).prev = frameptr_17042;
frameptr_17042 = s;
{
if (!((*s).calldepth == ((NI16) 2000))) goto LA9;
stackoverflow_20001();
}
LA9: ;
}
static N_INLINE(void, popFrame)(void) {
frameptr_17042 = (*frameptr_17042).prev;
}
N_NIMCALL(NU8, ttBYTE)(fonttype743087 p) {
NU8 result;
nimfr("ttBYTE", "ttf.nim")
result = 0;
nimln(923, "ttf.nim");
result = p[(((NI) 0))- 0];
popFrame();
return result;
}
N_NIMCALL(NI8, ttCHAR)(fonttype743087 p) {
NI8 result;
nimfr("ttCHAR", "ttf.nim")
result = 0;
nimln(924, "ttf.nim");
result = ((NI8) (p[(((NI) 0))- 0]));
popFrame();
return result;
}
N_NIMCALL(NU16, ttUSHORT)(fonttype743087 p) {
NU16 result;
nimfr("ttUSHORT", "ttf.nim")
result = 0;
nimln(926, "ttf.nim");
result = (NU16)((NU16)((NU16)((NU32)(((NU16) (p[(((NI) 0))- 0]))) * (NU32)(((NI) 256)))) + (NU16)(((NU16) (p[(((NI) 1))- 0]))));
popFrame();
return result;
}
N_NIMCALL(NU16, ttushort_743348)(fonttype743087 p, NI idx) {
NU16 result;
nimfr("ttUSHORT", "ttf.nim")
result = 0;
nimln(927, "ttf.nim");
result = (NU16)((NU16)((NU16)((NU32)(((NU16) (p[(idx)- 0]))) * (NU32)(((NI) 256)))) + (NU16)(((NU16) (p[((NI)(idx + ((NI) 1)))- 0]))));
popFrame();
return result;
}
N_NIMCALL(NI16, ttSHORT)(fonttype743087 p) {
NI16 result;
nimfr("ttSHORT", "ttf.nim")
result = 0;
nimln(928, "ttf.nim");
result = (NI16)((NI16)(((NI16) (p[(((NI) 0))- 0])) * ((NI16) 256)) + ((NI16) (p[(((NI) 1))- 0])));
popFrame();
return result;
}
N_NIMCALL(NI16, ttshort_743393)(fonttype743087 p, NI idx) {
NI16 result;
nimfr("ttSHORT", "ttf.nim")
result = 0;
nimln(929, "ttf.nim");
result = (NI16)((NI16)(((NI16) (p[(idx)- 0])) * ((NI16) 256)) + ((NI16) (p[((NI)(idx + ((NI) 1)))- 0])));
popFrame();
return result;
}
N_NIMCALL(NU32, ttULONG)(fonttype743087 p) {
NU32 result;
nimfr("ttULONG", "ttf.nim")
result = 0;
nimln(931, "ttf.nim");
result = (NU32)((NU32)((NU32)((NU32)((NU32)((NU32)((NU32)((NU32)(((NU32) (p[(((NI) 0))- 0]))) << (NU32)(((NI) 24)))) + (NU32)((NU32)((NU32)(((NU32) (p[(((NI) 1))- 0]))) << (NU32)(((NI) 16)))))) + (NU32)((NU32)((NU32)(((NU32) (p[(((NI) 2))- 0]))) << (NU32)(((NI) 8)))))) + (NU32)(((NU32) (p[(((NI) 3))- 0]))));
popFrame();
return result;
}
N_NIMCALL(NU32, ttulong_743475)(fonttype743087 p, NI idx) {
NU32 result;
nimfr("ttULONG", "ttf.nim")
result = 0;
nimln(932, "ttf.nim");
result = (NU32)((NU32)((NU32)((NU32)((NU32)((NU32)((NU32)((NU32)(((NU32) (p[(idx)- 0]))) << (NU32)(((NI) 24)))) + (NU32)((NU32)((NU32)(((NU32) (p[((NI)(idx + ((NI) 1)))- 0]))) << (NU32)(((NI) 16)))))) + (NU32)((NU32)((NU32)(((NU32) (p[((NI)(idx + ((NI) 2)))- 0]))) << (NU32)(((NI) 8)))))) + (NU32)(((NU32) (p[((NI)(idx + ((NI) 3)))- 0]))));
popFrame();
return result;
}
N_NIMCALL(NI32, ttlong_743544)(fonttype743087 p, NI idx) {
NI32 result;
nimfr("ttLONG", "ttf.nim")
result = 0;
nimln(934, "ttf.nim");
result = (NI32)((NI32)((NI32)((NI32)((NU32)(((NI32) (p[(idx)- 0]))) << (NU32)(((NI32) 24))) + (NI32)((NU32)(((NI32) (p[((NI)(idx + ((NI) 1)))- 0]))) << (NU32)(((NI32) 16)))) + (NI32)((NU32)(((NI32) (p[((NI)(idx + ((NI) 2)))- 0]))) << (NU32)(((NI32) 8)))) + ((NI32) (p[((NI)(idx + ((NI) 3)))- 0])));
popFrame();
return result;
}
N_NIMCALL(NIM_BOOL, stbtttag4_743562)(NU8* p, NI pLen0, NI idx, NIM_CHAR c0, NIM_CHAR c1, NIM_CHAR c2, NIM_CHAR c3) {
NIM_BOOL result;
NIM_BOOL LOC1;
NIM_BOOL LOC2;
NIM_BOOL LOC3;
NI TMP566;
NI TMP567;
NI TMP568;
nimfr("stbtt_tag4", "ttf.nim")
result = 0;
nimln(940, "ttf.nim");
LOC1 = 0;
LOC2 = 0;
LOC3 = 0;
if ((NU)(idx) >= (NU)(pLen0)) raiseIndexError();
LOC3 = ((NU8)(((NIM_CHAR) (p[idx]))) == (NU8)(c0));
if (!(LOC3)) goto LA4;
TMP566 = addInt(idx, ((NI) 1));
if ((NU)((NI)(TMP566)) >= (NU)(pLen0)) raiseIndexError();
LOC3 = ((NU8)(((NIM_CHAR) (p[(NI)(TMP566)]))) == (NU8)(c1));
LA4: ;
LOC2 = LOC3;
if (!(LOC2)) goto LA5;
TMP567 = addInt(idx, ((NI) 2));
if ((NU)((NI)(TMP567)) >= (NU)(pLen0)) raiseIndexError();
LOC2 = ((NU8)(((NIM_CHAR) (p[(NI)(TMP567)]))) == (NU8)(c2));
LA5: ;
LOC1 = LOC2;
if (!(LOC1)) goto LA6;
TMP568 = addInt(idx, ((NI) 3));
if ((NU)((NI)(TMP568)) >= (NU)(pLen0)) raiseIndexError();
LOC1 = ((NU8)(((NIM_CHAR) (p[(NI)(TMP568)]))) == (NU8)(c3));
LA6: ;
result = LOC1;
popFrame();
return result;
}
N_NIMCALL(NIM_BOOL, stbtttag_743582)(NU8* p, NI pLen0, NI idx, NCSTRING str) {
NIM_BOOL result;
nimfr("stbtt_tag", "ttf.nim")
result = 0;
nimln(943, "ttf.nim");
result = stbtttag4_743562(p, pLen0, idx, str[((NI) 0)], str[((NI) 1)], str[((NI) 2)], str[((NI) 3)]);
popFrame();
return result;
}
N_NIMCALL(NIM_BOOL, stbtt_isfont)(fonttype743087 font) {
NIM_BOOL result;
NIM_BOOL LOC1;
NIM_BOOL LOC2;
NIM_BOOL LOC3;
nimfr("stbtt_isfont", "ttf.nim")
result = 0;
nimln(946, "ttf.nim");
nimln(947, "ttf.nim");
LOC1 = 0;
nimln(946, "ttf.nim");
LOC2 = 0;
LOC3 = 0;
LOC3 = stbtttag4_743562(font, 999999999, ((NI) 0), 49, 0, 0, 0);
if (LOC3) goto LA4;
LOC3 = stbtttag_743582(font, 999999999, ((NI) 0), "typ1");
LA4: ;
LOC2 = LOC3;
if (LOC2) goto LA5;
nimln(947, "ttf.nim");
LOC2 = stbtttag_743582(font, 999999999, ((NI) 0), "OTTO");
LA5: ;
LOC1 = LOC2;
if (LOC1) goto LA6;
LOC1 = stbtttag4_743562(font, 999999999, ((NI) 0), 0, 1, 0, 0);
LA6: ;
result = LOC1;
popFrame();
return result;
}
static N_INLINE(NI, chckRange)(NI i, NI a, NI b) {
NI result;
{ result = 0;
{
NIM_BOOL LOC3;
LOC3 = 0;
LOC3 = (a <= i);
if (!(LOC3)) goto LA4;
LOC3 = (i <= b);
LA4: ;
if (!LOC3) goto LA5;
result = i;
goto BeforeRet;
}
goto LA1;
LA5: ;
{
raiseRangeError(((NI64) (i)));
}
LA1: ;
}BeforeRet: ;
return result;
}
N_NIMCALL(NU32, stbtt_find_table)(fonttype743087 data, NU32 fontstart, NCSTRING tag) {
NU32 result;
NI numtables;
NI TMP569;
NU16 LOC1;
NU32 tabledir;
nimfr("stbtt_find_table", "ttf.nim")
{ result = 0;
nimln(951, "ttf.nim");
TMP569 = addInt(((NI)chckRange(fontstart, ((NI) (-2147483647 -1)), ((NI) 2147483647))), ((NI) 4));
LOC1 = 0;
LOC1 = ttushort_743348(data, (NI)(TMP569));
numtables = ((NI) (LOC1));
nimln(952, "ttf.nim");
tabledir = (NU32)((NU32)(fontstart) + (NU32)(((NI) 12)));
{
NI i_743632;
NI res_743638;
i_743632 = 0;
nimln(1598, "system.nim");
res_743638 = ((NI) 0);
{
nimln(1599, "system.nim");
while (1) {
NI loc;
NI TMP570;
NI TMP571;
NI TMP574;
if (!(res_743638 <= numtables)) goto LA4;
nimln(1600, "system.nim");
i_743632 = res_743638;
nimln(954, "ttf.nim");
TMP570 = mulInt(((NI) 16), i_743632);
TMP571 = addInt(((NI)chckRange(tabledir, ((NI) (-2147483647 -1)), ((NI) 2147483647))), (NI)(TMP570));
loc = (NI)(TMP571);
nimln(955, "ttf.nim");
{
NI TMP572;
NIM_BOOL LOC7;
NI TMP573;
TMP572 = addInt(loc, ((NI) 0));
LOC7 = 0;
LOC7 = stbtttag_743582(data, 999999999, (NI)(TMP572), tag);
if (!LOC7) goto LA8;
nimln(956, "ttf.nim");
TMP573 = addInt(loc, ((NI) 8));
result = ttulong_743475(data, (NI)(TMP573));
goto BeforeRet;
}
LA8: ;
nimln(1619, "system.nim");
TMP574 = addInt(res_743638, ((NI) 1));
res_743638 = (NI)(TMP574);
} LA4: ;
}
}
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(int, stbtt_GetFontOffsetForIndex)(fonttype743087 fontcollection, int index) {
int result;
nimfr("stbtt_GetFontOffsetForIndex", "ttf.nim")
{ result = 0;
nimln(960, "ttf.nim");
{
NIM_BOOL LOC3;
NI LOC6;
LOC3 = 0;
LOC3 = stbtt_isfont(fontcollection);
if (!LOC3) goto LA4;
nimln(961, "ttf.nim");
LOC6 = 0;
{
if (!(index == ((NI32) 0))) goto LA9;
LOC6 = ((NI) 0);
}
goto LA7;
LA9: ;
{
LOC6 = ((NI) -1);
}
LA7: ;
result = ((int) (LOC6));
goto BeforeRet;
}
LA4: ;
nimln(964, "ttf.nim");
{
NIM_BOOL LOC14;
LOC14 = 0;
LOC14 = stbtttag_743582(fontcollection, 999999999, ((NI) 0), "ttcf");
if (!LOC14) goto LA15;
nimln(966, "ttf.nim");
{
NIM_BOOL LOC19;
NU32 LOC20;
NU32 LOC22;
NI32 n;
NI32 TMP575;
NI32 TMP576;
NU32 LOC29;
LOC19 = 0;
LOC20 = 0;
LOC20 = ttulong_743475(fontcollection, ((NI) 4));
LOC19 = (LOC20 == ((NI) 65536));
if (LOC19) goto LA21;
LOC22 = 0;
LOC22 = ttulong_743475(fontcollection, ((NI) 4));
LOC19 = (LOC22 == ((NI) 131072));
LA21: ;
if (!LOC19) goto LA23;
nimln(967, "ttf.nim");
n = ttlong_743544(fontcollection, ((NI) 8));
nimln(968, "ttf.nim");
{
if (!(n <= index)) goto LA27;
nimln(969, "ttf.nim");
result = ((int) -1);
goto BeforeRet;
}
LA27: ;
nimln(970, "ttf.nim");
TMP575 = mulInt(index, ((NI32) 14));
TMP576 = addInt(((NI32) 12), (NI32)(TMP575));
LOC29 = 0;
LOC29 = ttulong_743475(fontcollection, ((NI) ((NI32)(TMP576))));
result = ((int)chckRange(LOC29, ((int) (-2147483647 -1)), ((int) 2147483647)));
goto BeforeRet;
}
LA23: ;
}
LA15: ;
nimln(971, "ttf.nim");
result = ((int) -1);
goto BeforeRet;
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(int, stbtt_InitFont)(stbtt_fontinfo* info, fonttype743087 data, int fontstart) {
int result;
NU32 cmap;
NU32 LOC1;
NU32 LOC2;
NU32 LOC3;
NU32 LOC4;
NU32 LOC5;
NU32 LOC6;
NU32 t;
NI numtables;
NI TMP578;
NU16 LOC27;
NI32 TMP588;
NU16 LOC44;
nimfr("stbtt_InitFont", "ttf.nim")
{ result = 0;
nimln(975, "ttf.nim");
(*info).fontstart = fontstart;
nimln(976, "ttf.nim");
cmap = stbtt_find_table(data, ((NU32) (fontstart)), "cmap");
nimln(977, "ttf.nim");
LOC1 = 0;
LOC1 = stbtt_find_table(data, ((NU32) (fontstart)), "loca");
(*info).loca = ((int)chckRange(LOC1, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(978, "ttf.nim");
LOC2 = 0;
LOC2 = stbtt_find_table(data, ((NU32) (fontstart)), "head");
(*info).head = ((int)chckRange(LOC2, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(979, "ttf.nim");
LOC3 = 0;
LOC3 = stbtt_find_table(data, ((NU32) (fontstart)), "glyf");
(*info).glyf = ((int)chckRange(LOC3, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(980, "ttf.nim");
LOC4 = 0;
LOC4 = stbtt_find_table(data, ((NU32) (fontstart)), "hhea");
(*info).hhea = ((int)chckRange(LOC4, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(981, "ttf.nim");
LOC5 = 0;
LOC5 = stbtt_find_table(data, ((NU32) (fontstart)), "hmtx");
(*info).hmtx = ((int)chckRange(LOC5, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(982, "ttf.nim");
LOC6 = 0;
LOC6 = stbtt_find_table(data, ((NU32) (fontstart)), "kern");
(*info).kern = ((int)chckRange(LOC6, ((int) (-2147483647 -1)), ((int) 2147483647)));
nimln(984, "ttf.nim");
info->data = data;
nimln(986, "ttf.nim");
{
NIM_BOOL LOC9;
NIM_BOOL LOC10;
NIM_BOOL LOC11;
NIM_BOOL LOC12;
NIM_BOOL LOC13;
LOC9 = 0;
LOC10 = 0;
LOC11 = 0;
LOC12 = 0;
LOC13 = 0;
LOC13 = (cmap == ((NI) 0));
if (LOC13) goto LA14;
LOC13 = ((*info).loca == ((NI32) 0));
LA14: ;
LOC12 = LOC13;
if (LOC12) goto LA15;
LOC12 = ((*info).head == ((NI32) 0));
LA15: ;
LOC11 = LOC12;
if (LOC11) goto LA16;
LOC11 = ((*info).glyf == ((NI32) 0));
LA16: ;
LOC10 = LOC11;
if (LOC10) goto LA17;
LOC10 = ((*info).hhea == ((NI32) 0));
LA17: ;
LOC9 = LOC10;
if (LOC9) goto LA18;
LOC9 = ((*info).hmtx == ((NI32) 0));
LA18: ;
if (!LOC9) goto LA19;
nimln(987, "ttf.nim");
result = ((int) 0);
goto BeforeRet;
}
LA19: ;
nimln(989, "ttf.nim");
t = stbtt_find_table(data, ((NU32) (fontstart)), "maxp");
nimln(990, "ttf.nim");
{
if (!(t == ((NI) 0))) goto LA23;
nimln(991, "ttf.nim");
(*info).numGlyphs = ((int) 65535);
}
goto LA21;
LA23: ;
{
NI TMP577;
NU16 LOC26;
nimln(993, "ttf.nim");
TMP577 = addInt(((NI)chckRange(t, ((NI) (-2147483647 -1)), ((NI) 2147483647))), ((NI) 4));
LOC26 = 0;
LOC26 = ttushort_743348(data, (NI)(TMP577));
(*info).numGlyphs = ((int) (LOC26));
}
LA21: ;
nimln(999, "ttf.nim");
TMP578 = addInt(((NI)chckRange(cmap, ((NI) (-2147483647 -1)), ((NI) 2147483647))), ((NI) 2));
LOC27 = 0;
LOC27 = ttushort_743348(data, (NI)(TMP578));
numtables = ((NI) (LOC27));
nimln(1000, "ttf.nim");
(*info).index_map = ((int) 0);
{
NI i_743736;
NI HEX3Atmp_743742;
NI res_743745;
i_743736 = 0;
HEX3Atmp_743742 = 0;
nimln(1002, "ttf.nim");
HEX3Atmp_743742 = subInt(numtables, 1);
nimln(1598, "system.nim");
res_743745 = ((NI) 0);
{
nimln(1599, "system.nim");
while (1) {
NI encodingrecord;
NI TMP579;
NI TMP580;
NI TMP581;
NU16 LOC31;
NI TMP587;
if (!(res_743745 <= HEX3Atmp_743742)) goto LA30;
nimln(1600, "system.nim");
i_743736 = res_743745;
nimln(1003, "ttf.nim");
TMP579 = addInt(((NI)chckRange(cmap, ((NI) (-2147483647 -1)), ((NI) 2147483647))), ((NI) 4));
TMP580 = mulInt(((NI) 8), i_743736);
TMP581 = addInt((NI)(TMP579), (NI)(TMP580));
encodingrecord = (NI)(TMP581);
nimln(1005, "ttf.nim");
LOC31 = 0;
LOC31 = ttushort_743348(data, encodingrecord);
switch (((NU8)chckRange(LOC31, ((NU8) 0), ((NU8) 3)))) {
case ((NU8) 3):
{
NI TMP582;
NU16 LOC33;
nimln(1007, "ttf.nim");
TMP582 = addInt(encodingrecord, ((NI) 2));
LOC33 = 0;
LOC33 = ttushort_743348(data, (NI)(TMP582));
switch (LOC33) {
case ((NI) 1):
case ((NI) 10):
{
NI TMP583;
NU32 LOC35;
NI32 TMP584;
nimln(1010, "ttf.nim");
TMP583 = addInt(encodingrecord, ((NI) 4));
LOC35 = 0;
LOC35 = ttulong_743475(data, (NI)(TMP583));
TMP584 = addInt(((int)chckRange(cmap, ((int) (-2147483647 -1)), ((int) 2147483647))), ((int)chckRange(LOC35, ((int) (-2147483647 -1)), ((int) 2147483647))));
(*info).index_map = (NI32)(TMP584);
}
break;
default:
{
}
break;
}
}
break;
case ((NU8) 0):
{
NI TMP585;
NU32 LOC38;
NI32 TMP586;
nimln(1015, "ttf.nim");
TMP585 = addInt(encodingrecord, ((NI) 4));
LOC38 = 0;
LOC38 = ttulong_743475(data, (NI)(TMP585));
TMP586 = addInt(((int)chckRange(cmap, ((int) (-2147483647 -1)), ((int) 2147483647))), ((int)chckRange(LOC38, ((int) (-2147483647 -1)), ((int) 2147483647))));
(*info).index_map = (NI32)(TMP586);
}
break;
default:
{
}
break;
}
nimln(1619, "system.nim");
TMP587 = addInt(res_743745, ((NI) 1));
res_743745 = (NI)(TMP587);
} LA30: ;
}
}
nimln(1017, "ttf.nim");
{
if (!((*info).index_map == ((NI32) 0))) goto LA42;
nimln(1018, "ttf.nim");
result = ((int) 0);
goto BeforeRet;
}
LA42: ;
nimln(1020, "ttf.nim");
TMP588 = addInt((*info).head, ((NI32) 50));
LOC44 = 0;
LOC44 = ttushort_743348(data, ((NI) ((NI32)(TMP588))));
(*info).indexToLocFormat = ((int) (LOC44));
nimln(1021, "ttf.nim");
result = ((int) 1);
goto BeforeRet;
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(void, stbtt_setvertex)(stbtt_vertex* v, NU8 t, NI32 x, NI32 y, NI32 cx, NI32 cy) {
nimfr("stbtt_setvertex", "ttf.nim")
nimln(1124, "ttf.nim");
(*v).type = t;
nimln(1125, "ttf.nim");
(*v).x = ((NI16)chckRange(x, ((NI16) -32768), ((NI16) 32767)));
nimln(1126, "ttf.nim");
(*v).y = ((NI16)chckRange(y, ((NI16) -32768), ((NI16) 32767)));
nimln(1127, "ttf.nim");
(*v).cx = ((NI16)chckRange(cx, ((NI16) -32768), ((NI16) 32767)));
nimln(1128, "ttf.nim");
(*v).cy = ((NI16)chckRange(cy, ((NI16) -32768), ((NI16) 32767)));
popFrame();
}
N_NIMCALL(int, stbtt_GetGlyfOffset)(stbtt_fontinfo* info, int glyphindex) {
int result;
int g1;
int g2;
NI LOC18;
nimfr("stbtt_GetGlyfOffset", "ttf.nim")
{ result = 0;
nimln(1131, "ttf.nim");
{
if (!((*info).numGlyphs <= glyphindex)) goto LA3;
result = ((int) -1);
goto BeforeRet;
}
LA3: ;
nimln(1132, "ttf.nim");
{
if (!(((NI32) 2) <= (*info).indexToLocFormat)) goto LA7;
result = ((int) -1);
goto BeforeRet;
}
LA7: ;
g1 = 0;
g2 = 0;
nimln(1135, "ttf.nim");
{
NI32 TMP589;
NI32 TMP590;
NU16 LOC13;
NI32 TMP591;
NI32 TMP592;
NI32 TMP593;
NI32 TMP594;
NI32 TMP595;
NU16 LOC14;
NI32 TMP596;
NI32 TMP597;
if (!((*info).indexToLocFormat == ((NI32) 0))) goto LA11;
nimln(1136, "ttf.nim");
TMP589 = mulInt(glyphindex, ((NI32) 2));
TMP590 = addInt((*info).loca, (NI32)(TMP589));
LOC13 = 0;
LOC13 = ttushort_743348((*info).data, ((NI) ((NI32)(TMP590))));
TMP591 = mulInt(((int) (LOC13)), ((NI32) 2));
TMP592 = addInt((*info).glyf, (NI32)(TMP591));
g1 = (NI32)(TMP592);
nimln(1137, "ttf.nim");
TMP593 = mulInt(glyphindex, ((NI32) 2));
TMP594 = addInt((*info).loca, (NI32)(TMP593));
TMP595 = addInt((NI32)(TMP594), ((NI32) 2));
LOC14 = 0;
LOC14 = ttushort_743348((*info).data, ((NI) ((NI32)(TMP595))));
TMP596 = mulInt(((int) (LOC14)), ((NI32) 2));
TMP597 = addInt((*info).glyf, (NI32)(TMP596));
g2 = (NI32)(TMP597);
}
goto LA9;
LA11: ;
{
NI32 TMP598;
NI32 TMP599;
NU32 LOC16;
NI32 TMP600;
NI32 TMP601;
NI32 TMP602;
NI32 TMP603;
NU32 LOC17;
NI32 TMP604;
nimln(1139, "ttf.nim");
TMP598 = mulInt(glyphindex, ((NI32) 4));
TMP599 = addInt((*info).loca, (NI32)(TMP598));
LOC16 = 0;
LOC16 = ttulong_743475((*info).data, ((NI) ((NI32)(TMP599))));
TMP600 = addInt((*info).glyf, ((int)chckRange(LOC16, ((int) (-2147483647 -1)), ((int) 2147483647))));
g1 = (NI32)(TMP600);
nimln(1140, "ttf.nim");
TMP601 = mulInt(glyphindex, ((NI32) 4));
TMP602 = addInt((*info).loca, (NI32)(TMP601));
TMP603 = addInt((NI32)(TMP602), ((NI32) 4));
LOC17 = 0;
LOC17 = ttulong_743475((*info).data, ((NI) ((NI32)(TMP603))));
TMP604 = addInt((*info).glyf, ((int)chckRange(LOC17, ((int) (-2147483647 -1)), ((int) 2147483647))));
g2 = (NI32)(TMP604);
}
LA9: ;
nimln(1142, "ttf.nim");
LOC18 = 0;
{
if (!(g1 == g2)) goto LA21;
LOC18 = ((NI) -1);
}
goto LA19;
LA21: ;
{
LOC18 = ((NI) (g1));
}
LA19: ;
result = ((int) (LOC18));
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(int, stbtt_GetGlyphBox)(stbtt_fontinfo* info, int glyphindex, int* x0, int* y0, int* x1, int* y1) {
int result;
int g;
nimfr("stbtt_GetGlyphBox", "ttf.nim")
{ result = 0;
nimln(1145, "ttf.nim");
g = stbtt_GetGlyfOffset(info, glyphindex);
nimln(1146, "ttf.nim");
{
if (!(g < ((NI32) 0))) goto LA3;
result = ((int) 0);
goto BeforeRet;
}
LA3: ;
nimln(1148, "ttf.nim");
{
NI32 TMP605;
NI16 LOC9;
if (!!((x0 == NIM_NIL))) goto LA7;
TMP605 = addInt(g, ((NI32) 2));
LOC9 = 0;
LOC9 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP605))));
(*x0) = ((int) (LOC9));
}
LA7: ;
nimln(1149, "ttf.nim");
{
NI32 TMP606;
NI16 LOC14;
if (!!((y0 == NIM_NIL))) goto LA12;
TMP606 = addInt(g, ((NI32) 4));
LOC14 = 0;
LOC14 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP606))));
(*y0) = ((int) (LOC14));
}
LA12: ;
nimln(1150, "ttf.nim");
{
NI32 TMP607;
NI16 LOC19;
if (!!((x1 == NIM_NIL))) goto LA17;
TMP607 = addInt(g, ((NI32) 6));
LOC19 = 0;
LOC19 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP607))));
(*x1) = ((int) (LOC19));
}
LA17: ;
nimln(1151, "ttf.nim");
{
NI32 TMP608;
NI16 LOC24;
if (!!((y1 == NIM_NIL))) goto LA22;
TMP608 = addInt(g, ((NI32) 8));
LOC24 = 0;
LOC24 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP608))));
(*y1) = ((int) (LOC24));
}
LA22: ;
nimln(1152, "ttf.nim");
result = ((int) 1);
goto BeforeRet;
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(NIM_BOOL, stbttisglyphempty_743865)(stbtt_fontinfo* info, int glyphindex) {
NIM_BOOL result;
int g;
NI16 numberofcontours;
nimfr("stbtt_IsGlyphEmpty", "ttf.nim")
{ result = 0;
nimln(1156, "ttf.nim");
g = stbtt_GetGlyfOffset(info, glyphindex);
nimln(1157, "ttf.nim");
{
if (!(g < ((NI32) 0))) goto LA3;
result = NIM_TRUE;
goto BeforeRet;
}
LA3: ;
nimln(1158, "ttf.nim");
numberofcontours = ttshort_743393((*info).data, ((NI) (g)));
nimln(1159, "ttf.nim");
result = (numberofcontours == ((NI16) 0));
goto BeforeRet;
}BeforeRet: ;
popFrame();
return result;
}
N_NIMCALL(void, stbtt_GetGlyphHMetrics)(stbtt_fontinfo* info, int glyphindex, int* advancewidth, int* leftsidebearing) {
NI numoflonghormetrics;
NI32 TMP609;
NU16 LOC1;
nimfr("stbtt_GetGlyphHMetrics", "ttf.nim")
nimln(1412, "ttf.nim");
TMP609 = addInt((*info).hhea, ((NI32) 34));
LOC1 = 0;
LOC1 = ttushort_743348((*info).data, ((NI) ((NI32)(TMP609))));
numoflonghormetrics = ((NI) (LOC1));
nimln(1413, "ttf.nim");
{
NI32 TMP610;
NI32 TMP611;
NI16 LOC6;
NI32 TMP612;
NI32 TMP613;
NI32 TMP614;
NI16 LOC7;
if (!(((NI) (glyphindex)) < numoflonghormetrics)) goto LA4;
nimln(1414, "ttf.nim");
TMP610 = mulInt(((NI32) 4), glyphindex);
TMP611 = addInt((*info).hmtx, (NI32)(TMP610));
LOC6 = 0;
LOC6 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP611))));
(*advancewidth) = ((int) (LOC6));
nimln(1415, "ttf.nim");
TMP612 = mulInt(((NI32) 4), glyphindex);
TMP613 = addInt((*info).hmtx, (NI32)(TMP612));
TMP614 = addInt((NI32)(TMP613), ((NI32) 2));
LOC7 = 0;
LOC7 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP614))));
(*leftsidebearing) = ((int) (LOC7));
}
goto LA2;
LA4: ;
{
NI TMP615;
NI TMP616;
NI TMP617;
NI16 LOC9;
NI TMP618;
NI TMP619;
NI TMP620;
NI TMP621;
NI TMP622;
NI16 LOC10;
nimln(1417, "ttf.nim");
TMP615 = subInt(numoflonghormetrics, ((NI) 1));
TMP616 = mulInt(((NI) 4), (NI)(TMP615));
TMP617 = addInt(((NI) ((*info).hmtx)), (NI)(TMP616));
LOC9 = 0;
LOC9 = ttshort_743393((*info).data, (NI)(TMP617));
(*advancewidth) = ((int) (LOC9));
nimln(1418, "ttf.nim");
TMP618 = mulInt(((NI) 4), numoflonghormetrics);
TMP619 = addInt(((NI) ((*info).hmtx)), (NI)(TMP618));
TMP620 = subInt(((NI) (glyphindex)), numoflonghormetrics);
TMP621 = mulInt(((NI) 2), (NI)(TMP620));
TMP622 = addInt((NI)(TMP619), (NI)(TMP621));
LOC10 = 0;
LOC10 = ttshort_743393((*info).data, (NI)(TMP622));
(*leftsidebearing) = ((int) (LOC10));
}
LA2: ;
popFrame();
}
N_NIMCALL(void, stbttgetfontvmetrics_743900)(stbtt_fontinfo* info, int* ascent, int* descent, int* linegap) {
NI32 TMP623;
NI16 LOC1;
NI32 TMP624;
NI16 LOC2;
NI32 TMP625;
NI16 LOC3;
nimfr("stbtt_GetFontVMetrics", "ttf.nim")
nimln(1466, "ttf.nim");
TMP623 = addInt((*info).hhea, ((NI32) 4));
LOC1 = 0;
LOC1 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP623))));
(*ascent) = ((int) (LOC1));
nimln(1467, "ttf.nim");
TMP624 = addInt((*info).hhea, ((NI32) 6));
LOC2 = 0;
LOC2 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP624))));
(*descent) = ((int) (LOC2));
nimln(1468, "ttf.nim");
TMP625 = addInt((*info).hhea, ((NI32) 8));
LOC3 = 0;
LOC3 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP625))));
(*linegap) = ((int) (LOC3));
popFrame();
}
N_NIMCALL(void, stbttgetfontboundingbox_743913)(stbtt_fontinfo* info, NI* x0, NI* y0, NI* x1, NI* y1) {
NI32 TMP626;
NI16 LOC1;
NI32 TMP627;
NI16 LOC2;
NI32 TMP628;
NI16 LOC3;
NI32 TMP629;
NI16 LOC4;
nimfr("stbtt_GetFontBoundingBox", "ttf.nim")
nimln(1472, "ttf.nim");
TMP626 = addInt((*info).head, ((NI32) 36));
LOC1 = 0;
LOC1 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP626))));
(*x0) = ((NI) (LOC1));
nimln(1473, "ttf.nim");
TMP627 = addInt((*info).head, ((NI32) 38));
LOC2 = 0;
LOC2 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP627))));
(*y0) = ((NI) (LOC2));
nimln(1474, "ttf.nim");
TMP628 = addInt((*info).head, ((NI32) 40));
LOC3 = 0;
LOC3 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP628))));
(*x1) = ((NI) (LOC3));
nimln(1475, "ttf.nim");
TMP629 = addInt((*info).head, ((NI32) 42));
LOC4 = 0;
LOC4 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP629))));
(*y1) = ((NI) (LOC4));
popFrame();
}
N_NIMCALL(float, stbtt_ScaleForPixelHeight)(stbtt_fontinfo* info, float height) {
float result;
NI16 fheight;
NI32 TMP630;
NI16 LOC1;
NI32 TMP631;
NI16 LOC2;
NI TMP632;
nimfr("stbtt_ScaleForPixelHeight", "ttf.nim")
result = 0;
nimln(1478, "ttf.nim");
TMP630 = addInt((*info).hhea, ((NI32) 4));
LOC1 = 0;
LOC1 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP630))));
TMP631 = addInt((*info).hhea, ((NI32) 6));
LOC2 = 0;
LOC2 = ttshort_743393((*info).data, ((NI) ((NI32)(TMP631))));
TMP632 = subInt(LOC1, LOC2);
if (TMP632 < -32768 || TMP632 > 32767) raiseOverflow();
fheight = (NI16)(TMP632);
nimln(1479, "ttf.nim");
result = ((NF32)(height) / (NF32)(((float) (fheight))));
popFrame();
return result;
}
N_NIMCALL(stbtt_active_edge*, new_active)(stbtt_edge* e, int offx, float startpoint, void* userdata) {
stbtt_active_edge* result;
void* LOC1;
NF32 dxdy;
NF LOC13;
NI32 TMP634;
int TMP635;
NI LOC14;
nimfr("new_active", "ttf.nim")
result = 0;
nimln(1548, "ttf.nim");
LOC1 = 0;
LOC1 = malloc(((NI)sizeof(stbtt_active_edge)));
result = ((stbtt_active_edge*) (LOC1));
nimln(1549, "ttf.nim");
dxdy = ((NF32)(((NF32)((*e).x1) - (NF32)((*e).x0))) / (NF32)(((NF32)((*e).y1) - (NF32)((*e).y0))));
nimln(1550, "ttf.nim");
{
if (!!(((*e).y0 <= startpoint))) goto LA4;
failedassertimpl_88817(((NimStringDesc*) &TMP633));
}
LA4: ;
nimln(1552, "ttf.nim");
{
NF LOC10;
if (!(dxdy < 0.0)) goto LA8;
nimln(1553, "ttf.nim");
LOC10 = 0;
LOC10 = floor(((NF) (((NF32)(1.0240000000000000e+003) * (NF32)(-(dxdy))))));
if (((int) (LOC10)) == (-2147483647 -1)) raiseOverflow();
(*result).dx = ((NI32)-(((int) (LOC10))));
}
goto LA6;
LA8: ;
{
NF LOC12;
nimln(1555, "ttf.nim");
LOC12 = 0;
LOC12 = floor(((NF) (((NF32)(1.0240000000000000e+003) * (NF32)(dxdy)))));
(*result).dx = ((int) (LOC12));
}
LA6: ;
nimln(1556, "ttf.nim");
LOC13 = 0;
LOC13 = floor(((NF) (((NF32)(1.0240000000000000e+003) * (NF32)(((NF32)((*e).x0) + (NF32)(((NF32)(dxdy) * (NF32)(((NF32)(startpoint) - (NF32)((*e).y0)))))))))));
(*result).x = ((int) (LOC13));
nimln(1557, "ttf.nim");
TMP634 = mulInt(offx, ((NI32) 1024));
TMP635 = subInt((*result).x, (NI32)(TMP634));
(*result).x = (int)(TMP635);
nimln(1558, "ttf.nim");
(*result).ey = (*e).y1;
nimln(1559, "ttf.nim");
(*result).next = NIM_NIL;
nimln(1560, "ttf.nim");
LOC14 = 0;
{
if (!!(((*e).invert == ((NI32) 0)))) goto LA17;
LOC14 = ((NI) 1);
}
goto LA15;
LA17: ;
{
LOC14 = ((NI) -1);
}
LA15: ;
(*result).valid = ((int) (LOC14));
popFrame();
return result;
}
N_NIMCALL(void, stbttaddpoint_744034)(stbtt_point* points, NI pointsLen0, NI n, NF x, NF y) {
nimfr("stbtt_add_point", "ttf.nim")
nimln(1785, "ttf.nim");
{
if (!(n < pointsLen0)) goto LA3;
nimln(1786, "ttf.nim");
if ((NU)(n) >= (NU)(pointsLen0)) raiseIndexError();
points[n].x = ((float) (x));
nimln(1787, "ttf.nim");
if ((NU)(n) >= (NU)(pointsLen0)) raiseIndexError();
points[n].y = ((float) (y));
}
LA3: ;
popFrame();
}
N_NIMCALL(void, stbtttesselatecurve_744055)(stbtt_point* points, NI pointsLen0, int* numpoints, NF x0, NF y0, NF x1, NF y1, NF x2, NF y2, NF objspaceflatnesssquared, NI n) {
NF mx;
NF my;
NF dx;
NF dy;
nimfr("stbtt_tesselate_curve", "ttf.nim")
{ nimln(1792, "ttf.nim");
mx = ((NF)(((NF)(((NF)(x0) + (NF)(((NF)(2.0000000000000000e+000) * (NF)(x1))))) + (NF)(x2))) / (NF)(4.0000000000000000e+000));
nimln(1793, "ttf.nim");
my = ((NF)(((NF)(((NF)(y0) + (NF)(((NF)(2.0000000000000000e+000) * (NF)(y1))))) + (NF)(y2))) / (NF)(4.0000000000000000e+000));
nimln(1795, "ttf.nim");
dx = ((NF)(((NF)(((NF)(x0) + (NF)(x2))) / (NF)(2.0000000000000000e+000))) - (NF)(mx));
nimln(1796, "ttf.nim");
dy = ((NF)(((NF)(((NF)(y0) + (NF)(y2))) / (NF)(2.0000000000000000e+000))) - (NF)(my));
nimln(1797, "ttf.nim");
{
if (!(((NI) 16) < n)) goto LA3;
nimln(1798, "ttf.nim");
goto BeforeRet;
}
LA3: ;
nimln(1799, "ttf.nim");
{
NI TMP636;
NI TMP637;
if (!(objspaceflatnesssquared < ((NF)(((NF)(dx) * (NF)(dx))) + (NF)(((NF)(dy) * (NF)(dy)))))) goto LA7;
nimln(1800, "ttf.nim");
TMP636 = addInt(n, ((NI) 1));
stbtttesselatecurve_744055(points, pointsLen0, numpoints, x0, y0, ((NF)(((NF)(x0) + (NF)(x1))) / (NF)(2.0000000000000000e+000)), ((NF)(((NF)(y0) + (NF)(y1))) / (NF)(2.0000000000000000e+000)), mx, my, objspaceflatnesssquared, (NI)(TMP636));
nimln(1801, "ttf.nim");
TMP637 = addInt(n, ((NI) 1));
stbtttesselatecurve_744055(points, pointsLen0, numpoints, mx, my, ((NF)(((NF)(x1) + (NF)(x2))) / (NF)(2.0000000000000000e+000)), ((NF)(((NF)(y1) + (NF)(y2))) / (NF)(2.0000000000000000e+000)), x2, y2, objspaceflatnesssquared, (NI)(TMP637));
}
goto LA5;
LA7: ;
{
int TMP638;
nimln(1803, "ttf.nim");
stbttaddpoint_744034(points, pointsLen0, ((NI) ((*numpoints))), x2, y2);
nimln(1804, "ttf.nim");
TMP638 = addInt((*numpoints), ((NI) 1));
(*numpoints) = (int)(TMP638);
}
LA5: ;
}BeforeRet: ;
popFrame();
}
N_NIMCALL(stbtt_point*, tocarray_744306)(TY744219* s) {
stbtt_point* result;
NI TMP641;
void* LOC1;
stbtt_point* p;
nimfr("toCArray", "ttf.nim")
result = 0;
nimln(1807, "ttf.nim");
TMP641 = mulInt((s ? s->Sup.len : 0), ((NI)sizeof(stbtt_point)));
LOC1 = 0;
LOC1 = malloc((NI)(TMP641));
result = ((stbtt_point*) (LOC1));
nimln(1808, "ttf.nim");
p = ((stbtt_point*) (result));
{
NI i_744372;
stbtt_point v_744373;
NI i_744380;
i_744372 = 0;
memset((void*)(&v_744373), 0, sizeof(v_744373));
nimln(1789, "system.nim");
i_744380 = ((NI) 0);
{
nimln(1790, "system.nim");
while (1) {
NI TMP642;
if (!(i_744380 < (s ? s->Sup.len : 0))) goto LA4;
nimln(1789, "system.nim");
i_744372 = i_744380;
nimln(1791, "system.nim");
if ((NU)(i_744380) >= (NU)(s->Sup.len)) raiseIndexError();
v_744373 = s->data[i_744380];
nimln(1810, "ttf.nim");
if ((NU)(i_744372) > (NU)(999998)) raiseIndexError();
p[(i_744372)- 0] = v_744373;
nimln(1792, "system.nim");
TMP642 = addInt(i_744380, ((NI) 1));
i_744380 = (NI)(TMP642);
} LA4: ;
}
}
popFrame();
return result;
}
N_NIMCALL(stbtt_point*, stbtt_FlattenCurves)(stbtt_vertex* vertices, NI verticesLen0, float objspaceflatness, int** contourlengths, int* numcontours, void* userdata) {
stbtt_point* result;
int numpoints;
NF32 objspaceflatnesssquared;
int n;
int start;
NI TMP645;
void* LOC12;
int* contourlengthsarr;
TY744219* windings;
nimfr("stbtt_FlattenCurves", "ttf.nim")
{ result = 0;
nimln(1814, "ttf.nim");
numpoints = ((int) 0);
nimln(1816, "ttf.nim");
objspaceflatnesssquared = ((NF32)(objspaceflatness) * (NF32)(objspaceflatness));
n = 0;
start = 0;
{
stbtt_vertex v_744176;
NI i_744399;
memset((void*)(&v_744176), 0, sizeof(v_744176));
nimln(1689, "system.nim");
i_744399 = ((NI) 0);
{
nimln(1690, "system.nim");
while (1) {
NI TMP644;
if (!(i_744399 < verticesLen0)) goto LA3;
nimln(1691, "system.nim");
if ((NU)(i_744399) >= (NU)(verticesLen0)) raiseIndexError();
v_744176 = vertices[i_744399];
nimln(1821, "ttf.nim");
{
int TMP643;
if (!(v_744176.type == ((NU8) 1))) goto LA6;
nimln(1822, "ttf.nim");
TMP643 = addInt(n, ((NI) 1));
n = (int)(TMP643);
}
LA6: ;
nimln(1692, "system.nim");
TMP644 = addInt(i_744399, ((NI) 1));
i_744399 = (NI)(TMP644);
} LA3: ;
}
}
nimln(1824, "ttf.nim");
(*numcontours) = n;
nimln(1825, "ttf.nim");
{
if (!(n == ((NI32) 0))) goto LA10;
goto BeforeRet;
}
LA10: ;
nimln(1826, "ttf.nim");
TMP645 = mulInt(((NI) ((*numcontours))), ((NI) 4));
LOC12 = 0;
LOC12 = malloc((NI)(TMP645));
(*contourlengths) = ((int*) (LOC12));
nimln(1828, "ttf.nim");
contourlengthsarr = ((int*) ((*contourlengths)));
nimln(1830, "ttf.nim");
windings = newseq_744214(((NI) 0));
{
NI pass_744255;
NI res_744422;
pass_744255 = 0;
nimln(1598, "system.nim");
res_744422 = ((NI) 0);
{
nimln(1599, "system.nim");
while (1) {
NF x;
NF y;
NI32 TMP651;
NI TMP652;
if (!(res_744422 <= ((NI) 1))) goto LA15;
nimln(1600, "system.nim");
pass_744255 = res_744422;
x = 0;
y = 0;
nimln(1835, "ttf.nim");
{
if (!(pass_744255 == ((NI) 1))) goto LA18;
nimln(1836, "ttf.nim");
windings = (TY744219*) newSeq((&NTI744219), ((NI)chckRange(numpoints, ((NI) 0), ((NI) 2147483647))));
}
LA18: ;
nimln(1838, "ttf.nim");
numpoints = ((int) 0);
nimln(1839, "ttf.nim");
n = ((int) -1);
{
stbtt_vertex v_744276;
NI i_744419;
memset((void*)(&v_744276), 0, sizeof(v_744276));
nimln(1689, "system.nim");
i_744419 = ((NI) 0);
{
nimln(1690, "system.nim");
while (1) {
NI TMP650;
if (!(i_744419 < verticesLen0)) goto LA22;
nimln(1691, "system.nim");
if ((NU)(i_744419) >= (NU)(verticesLen0)) raiseIndexError();
v_744276 = vertices[i_744419];
nimln(1841, "ttf.nim");
switch (v_744276.type) {
case ((NU8) 1):
{
int TMP647;
int TMP648;
nimln(1844, "ttf.nim");
{
NI32 TMP646;
if (!(((NI32) 0) <= n)) goto LA26;
nimln(1845, "ttf.nim");
if ((NU)(n) > (NU)(99998)) raiseIndexError();
TMP646 = subInt(numpoints, start);
contourlengthsarr[(n)- 0] = (NI32)(TMP646);
}
LA26: ;
nimln(1846, "ttf.nim");
TMP647 = addInt(n, ((NI) 1));
n = (int)(TMP647);
nimln(1847, "ttf.nim");
start = numpoints;
nimln(1849, "ttf.nim");
x = ((NF) (v_744276.x));
nimln(1850, "ttf.nim");
y = ((NF) (v_744276.y));
nimln(1851, "ttf.nim");
stbttaddpoint_744034(windings->data, windings->Sup.len, ((NI) (numpoints)), x, y);
nimln(1852, "ttf.nim");
TMP648 = addInt(numpoints, ((NI) 1));
numpoints = (int)(TMP648);
}
break;
case ((NU8) 2):
{
int TMP649;
nimln(1855, "ttf.nim");
x = ((NF) (v_744276.x));
nimln(1856, "ttf.nim");
y = ((NF) (v_744276.y));
nimln(1857, "ttf.nim");
stbttaddpoint_744034(windings->data, windings->Sup.len, ((NI) (numpoints)), x, y);
nimln(1858, "ttf.nim");
TMP649 = addInt(numpoints, ((NI) 1));
numpoints = (int)(TMP649);
}
break;
case ((NU8) 3):
{
nimln(1861, "ttf.nim");
stbtttesselatecurve_744055(windings->data, windings->Sup.len, (&numpoints), x, y, ((NF) (v_744276.cx)), ((NF) (v_744276.cy)), ((NF) (v_744276.x)), ((NF) (v_744276.y)), ((NF) (objspaceflatnesssquared)), ((NI) 0));
nimln(1865, "ttf.nim");
x = ((NF) (v_744276.x));
nimln(1866, "ttf.nim");
y = ((NF) (v_744276.y));
}
break;
default:
{
}
break;
}
nimln(1692, "system.nim");
TMP650 = addInt(i_744419, ((NI) 1));
i_744419 = (NI)(TMP650);
} LA22: ;
}
}
nimln(1870, "ttf.nim");
if ((NU)(n) > (NU)(99998)) raiseIndexError();
TMP651 = subInt(numpoints, start);
contourlengthsarr[(n)- 0] = (NI32)(TMP651);
nimln(1614, "system.nim");
TMP652 = addInt(res_744422, ((NI) 1));
res_744422 = (NI)(TMP652);
} LA15: ;
}
}
nimln(1872, "ttf.nim");
result = tocarray_744306(windings);
}BeforeRet: ;
popFrame();
return result;
}
static N_INLINE(void, HEX2BHEX3D_93329)(NF32* x, NF32 y) {
nimfr("+=", "system.nim")
nimln(2992, "system.nim");
(*x) = ((NF32)((*x)) + (NF32)(y));
popFrame();
}
N_NIMCALL(void, stbtt_GetBakedQuad)(stbtt_bakedchar* bakedchar, NI pw, NI ph, float* xpos, float* ypos, stbtt_aligned_quad* q, NIM_BOOL openglfillrule) {
NF d3dbias;
NF ipw;
NF iph;
NI roundx;
NF LOC6;
NI roundy;
NF LOC7;
nimfr("stbtt_GetBakedQuad", "ttf.nim")
nimln(2038, "ttf.nim");
{
if (!openglfillrule) goto LA3;
d3dbias = 0.0;
}
goto LA1;
LA3: ;
{
d3dbias = -5.0000000000000000e-001;
}
LA1: ;
nimln(2039, "ttf.nim");
ipw = ((NF)(1.0000000000000000e+000) / (NF)(((NF) (pw))));
nimln(2040, "ttf.nim");
iph = ((NF)(1.0000000000000000e+000) / (NF)(((NF) (ph))));
nimln(2041, "ttf.nim");
LOC6 = 0;
LOC6 = floor(((NF) (((NF32)(((NF32)((*xpos)) + (NF32)((*bakedchar).xoff))) + (NF32)(5.0000000000000000e-001)))));
roundx = ((NI) (LOC6));
nimln(2042, "ttf.nim");
LOC7 = 0;
LOC7 = floor(((NF) (((NF32)(((NF32)((*ypos)) + (NF32)((*bakedchar).yoff))) + (NF32)(5.0000000000000000e-001)))));
roundy = ((NI) (LOC7));
nimln(2044, "ttf.nim");
(*q).x0 = ((float) (((NF)(((NF) (roundx))) + (NF)(d3dbias))));
nimln(2045, "ttf.nim");
(*q).y0 = ((float) (((NF)(((NF) (roundy))) + (NF)(d3dbias))));
nimln(2046, "ttf.nim");
(*q).x1 = ((float) (((NF)(((NF)(((NF)(((NF) (roundx))) + (NF)(((NF) ((*bakedchar).x1))))) - (NF)(((NF) ((*bakedchar).x0))))) + (NF)(d3dbias))));
nimln(2047, "ttf.nim");
(*q).y1 = ((float) (((NF)(((NF)(((NF)(((NF) (roundy))) + (NF)(((NF) ((*bakedchar).y1))))) - (NF)(((NF) ((*bakedchar).y0))))) + (NF)(d3dbias))));
nimln(2049, "ttf.nim");
(*q).s0 = ((float) (((NF)(((NF) ((*bakedchar).x0))) * (NF)(ipw))));
nimln(2050, "ttf.nim");
(*q).t0 = ((float) (((NF)(((NF) ((*bakedchar).y0))) * (NF)(iph))));
nimln(2051, "ttf.nim");
(*q).s1 = ((float) (((NF)(((NF) ((*bakedchar).x1))) * (NF)(ipw))));
nimln(2052, "ttf.nim");
(*q).t1 = ((float) (((NF)(((NF) ((*bakedchar).y1))) * (NF)(iph))));
nimln(2054, "ttf.nim");
HEX2BHEX3D_93329(xpos, (*bakedchar).xadvance);
popFrame();
}
N_NIMCALL(void, stbrp_init_target)(stbrp_context* con, int pw, int ph, stbrp_node* nodes, NI nodesLen0) {
nimfr("stbrp_init_target", "ttf.nim")
nimln(2099, "ttf.nim");
(*con).width = pw;
nimln(2100, "ttf.nim");
(*con).height = ph;
nimln(2101, "ttf.nim");
(*con).x = ((int) 0);
nimln(2102, "ttf.nim");
(*con).y = ((int) 0);
nimln(2103, "ttf.nim");
(*con).bottom_y = ((int) 0);
popFrame();
}
N_NIMCALL(void, stbrp_pack_rects)(stbrp_context* con, stbrp_rect* rects, NI rectsLen0) {
nimfr("stbrp_pack_rects", "ttf.nim")
{
stbrp_rect* r_744610;
NI i_744623;
r_744610 = 0;
nimln(1696, "system.nim");
i_744623 = ((NI) 0);
{
nimln(1697, "system.nim");
while (1) {
int TMP655;
NI TMP658;
if (!(i_744623 < rectsLen0)) goto LA3;
nimln(1698, "system.nim");
if ((NU)(i_744623) >= (NU)(rectsLen0)) raiseIndexError();
r_744610 = (&rects[i_744623]);
nimln(2107, "ttf.nim");
{
NI32 TMP653;
TMP653 = addInt((*con).x, (*r_744610).w);
if (!((*con).width < (NI32)(TMP653))) goto LA6;
nimln(2108, "ttf.nim");
(*con).x = ((int) 0);
nimln(2109, "ttf.nim");
(*con).y = (*con).bottom_y;
}
LA6: ;
nimln(2111, "ttf.nim");
{
NI32 TMP654;
TMP654 = addInt((*con).y, (*r_744610).h);
if (!((*con).height < (NI32)(TMP654))) goto LA10;
nimln(2112, "ttf.nim");
goto LA1;
}
LA10: ;
nimln(2113, "ttf.nim");
(*r_744610).x = (*con).x;
nimln(2114, "ttf.nim");
(*r_744610).y = (*con).y;
nimln(2115, "ttf.nim");
(*r_744610).was_packed = ((int) 1);
nimln(2116, "ttf.nim");
TMP655 = addInt((*con).x, (*r_744610).w);
(*con).x = (int)(TMP655);
nimln(2117, "ttf.nim");
{
NI32 TMP656;
NI32 TMP657;
TMP656 = addInt((*con).y, (*r_744610).h);
if (!((*con).bottom_y < (NI32)(TMP656))) goto LA14;
nimln(2118, "ttf.nim");
TMP657 = addInt((*con).y, (*r_744610).h);
(*con).bottom_y = (NI32)(TMP657);
}
LA14: ;
nimln(1699, "system.nim");
TMP658 = addInt(i_744623, ((NI) 1));
i_744623 = (NI)(TMP658);
} LA3: ;
}
} LA1: ;
popFrame();
}
N_NIMCALL(NF, stbtt_oversample_shift)(int oversample) {
NF result;
nimfr("stbtt_oversample_shift", "ttf.nim")
result = 0;
nimln(2291, "ttf.nim");
{
NI32 TMP659;
if (!!((oversample == ((NI32) 0)))) goto LA3;
nimln(2296, "ttf.nim");
TMP659 = subInt(oversample, ((NI32) 1));
result = ((NF)(-(((NF) ((NI32)(TMP659))))) / (NF)(((NF)(2.0000000000000000e+000) * (NF)(((NF) (oversample))))));
}
LA3: ;
popFrame();
return result;
}
NIM_EXTERNC N_NOINLINE(void, ttf_ttfInit)(void) {
nimfr("ttf", "ttf.nim")
popFrame();
}
NIM_EXTERNC N_NOINLINE(void, ttf_ttfDatInit)(void) {
static TNimNode* TMP639[2];
static TNimNode TMP564[3];
NTI744025.size = sizeof(stbtt_point);
NTI744025.kind = 18;
NTI744025.base = 0;
NTI744025.flags = 3;
TMP639[0] = &TMP564[1];
TMP564[1].kind = 1;
TMP564[1].offset = offsetof(stbtt_point, x);
TMP564[1].typ = (&NTI5817);
TMP564[1].name = "x";
TMP639[1] = &TMP564[2];
TMP564[2].kind = 1;
TMP564[2].offset = offsetof(stbtt_point, y);
TMP564[2].typ = (&NTI5817);
TMP564[2].name = "y";
TMP564[0].len = 2; TMP564[0].kind = 2; TMP564[0].sons = &TMP639[0];
NTI744025.node = &TMP564[0];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment