Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

stb_truetype.h 102KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658
  1. // [ImGui] this is a slightly modified version of stb_truetype.h 1.02
  2. // [ImGui] we added stbtt_PackFontRangesGatherRects() and stbtt_PackFontRangesRenderIntoRects() and modified stbtt_PackBegin()
  3. // stb_truetype.h - v1.02 - public domain
  4. // authored from 2009-2014 by Sean Barrett / RAD Game Tools
  5. //
  6. // This library processes TrueType files:
  7. // parse files
  8. // extract glyph metrics
  9. // extract glyph shapes
  10. // render glyphs to one-channel bitmaps with antialiasing (box filter)
  11. //
  12. // Todo:
  13. // non-MS cmaps
  14. // crashproof on bad data
  15. // hinting? (no longer patented)
  16. // cleartype-style AA?
  17. // optimize: use simple memory allocator for intermediates
  18. // optimize: build edge-list directly from curves
  19. // optimize: rasterize directly from curves?
  20. //
  21. // ADDITIONAL CONTRIBUTORS
  22. //
  23. // Mikko Mononen: compound shape support, more cmap formats
  24. // Tor Andersson: kerning, subpixel rendering
  25. //
  26. // Bug/warning reports/fixes:
  27. // "Zer" on mollyrocket (with fix)
  28. // Cass Everitt
  29. // stoiko (Haemimont Games)
  30. // Brian Hook
  31. // Walter van Niftrik
  32. // David Gow
  33. // David Given
  34. // Ivan-Assen Ivanov
  35. // Anthony Pesch
  36. // Johan Duparc
  37. // Hou Qiming
  38. // Fabian "ryg" Giesen
  39. //
  40. // Misc other:
  41. // Ryan Gordon
  42. //
  43. // VERSION HISTORY
  44. //
  45. // 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
  46. // 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
  47. // non-oversampled; STBTT_POINT_SIZE for packed case only
  48. // 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
  49. // 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
  50. // 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID
  51. // 0.8b (2014-07-07) fix a warning
  52. // 0.8 (2014-05-25) fix a few more warnings
  53. // 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
  54. // 0.6c (2012-07-24) improve documentation
  55. // 0.6b (2012-07-20) fix a few more warnings
  56. // 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
  57. // stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
  58. // 0.5 (2011-12-09) bugfixes:
  59. // subpixel glyph renderer computed wrong bounding box
  60. // first vertex of shape can be off-curve (FreeSans)
  61. // 0.4b (2011-12-03) fixed an error in the font baking example
  62. // 0.4 (2011-12-01) kerning, subpixel rendering (tor)
  63. // bugfixes for:
  64. // codepoint-to-glyph conversion using table fmt=12
  65. // codepoint-to-glyph conversion using table fmt=4
  66. // stbtt_GetBakedQuad with non-square texture (Zer)
  67. // updated Hello World! sample to use kerning and subpixel
  68. // fixed some warnings
  69. // 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
  70. // userdata, malloc-from-userdata, non-zero fill (stb)
  71. // 0.2 (2009-03-11) Fix unsigned/signed char warnings
  72. // 0.1 (2009-03-09) First public release
  73. //
  74. // LICENSE
  75. //
  76. // This software is in the public domain. Where that dedication is not
  77. // recognized, you are granted a perpetual, irrevokable license to copy
  78. // and modify this file as you see fit.
  79. //
  80. // USAGE
  81. //
  82. // Include this file in whatever places neeed to refer to it. In ONE C/C++
  83. // file, write:
  84. // #define STB_TRUETYPE_IMPLEMENTATION
  85. // before the #include of this file. This expands out the actual
  86. // implementation into that C/C++ file.
  87. //
  88. // Simple 3D API (don't ship this, but it's fine for tools and quick start)
  89. // stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture
  90. // stbtt_GetBakedQuad() -- compute quad to draw for a given char
  91. //
  92. // Improved 3D API (more shippable):
  93. // #include "stb_rect_pack.h" -- optional, but you really want it
  94. // stbtt_PackBegin()
  95. // stbtt_PackSetOversample() -- for improved quality on small fonts
  96. // stbtt_PackFontRanges() -- pack and renders
  97. // stbtt_PackEnd()
  98. // stbtt_GetPackedQuad()
  99. //
  100. // "Load" a font file from a memory buffer (you have to keep the buffer loaded)
  101. // stbtt_InitFont()
  102. // stbtt_GetFontOffsetForIndex() -- use for TTC font collections
  103. //
  104. // Render a unicode codepoint to a bitmap
  105. // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
  106. // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
  107. // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
  108. //
  109. // Character advance/positioning
  110. // stbtt_GetCodepointHMetrics()
  111. // stbtt_GetFontVMetrics()
  112. // stbtt_GetCodepointKernAdvance()
  113. //
  114. // ADDITIONAL DOCUMENTATION
  115. //
  116. // Immediately after this block comment are a series of sample programs.
  117. //
  118. // After the sample programs is the "header file" section. This section
  119. // includes documentation for each API function.
  120. //
  121. // Some important concepts to understand to use this library:
  122. //
  123. // Codepoint
  124. // Characters are defined by unicode codepoints, e.g. 65 is
  125. // uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is
  126. // the hiragana for "ma".
  127. //
  128. // Glyph
  129. // A visual character shape (every codepoint is rendered as
  130. // some glyph)
  131. //
  132. // Glyph index
  133. // A font-specific integer ID representing a glyph
  134. //
  135. // Baseline
  136. // Glyph shapes are defined relative to a baseline, which is the
  137. // bottom of uppercase characters. Characters extend both above
  138. // and below the baseline.
  139. //
  140. // Current Point
  141. // As you draw text to the screen, you keep track of a "current point"
  142. // which is the origin of each character. The current point's vertical
  143. // position is the baseline. Even "baked fonts" use this model.
  144. //
  145. // Vertical Font Metrics
  146. // The vertical qualities of the font, used to vertically position
  147. // and space the characters. See docs for stbtt_GetFontVMetrics.
  148. //
  149. // Font Size in Pixels or Points
  150. // The preferred interface for specifying font sizes in stb_truetype
  151. // is to specify how tall the font's vertical extent should be in pixels.
  152. // If that sounds good enough, skip the next paragraph.
  153. //
  154. // Most font APIs instead use "points", which are a common typographic
  155. // measurement for describing font size, defined as 72 points per inch.
  156. // stb_truetype provides a point API for compatibility. However, true
  157. // "per inch" conventions don't make much sense on computer displays
  158. // since they different monitors have different number of pixels per
  159. // inch. For example, Windows traditionally uses a convention that
  160. // there are 96 pixels per inch, thus making 'inch' measurements have
  161. // nothing to do with inches, and thus effectively defining a point to
  162. // be 1.333 pixels. Additionally, the TrueType font data provides
  163. // an explicit scale factor to scale a given font's glyphs to points,
  164. // but the author has observed that this scale factor is often wrong
  165. // for non-commercial fonts, thus making fonts scaled in points
  166. // according to the TrueType spec incoherently sized in practice.
  167. //
  168. // ADVANCED USAGE
  169. //
  170. // Quality:
  171. //
  172. // - Use the functions with Subpixel at the end to allow your characters
  173. // to have subpixel positioning. Since the font is anti-aliased, not
  174. // hinted, this is very import for quality. (This is not possible with
  175. // baked fonts.)
  176. //
  177. // - Kerning is now supported, and if you're supporting subpixel rendering
  178. // then kerning is worth using to give your text a polished look.
  179. //
  180. // Performance:
  181. //
  182. // - Convert Unicode codepoints to glyph indexes and operate on the glyphs;
  183. // if you don't do this, stb_truetype is forced to do the conversion on
  184. // every call.
  185. //
  186. // - There are a lot of memory allocations. We should modify it to take
  187. // a temp buffer and allocate from the temp buffer (without freeing),
  188. // should help performance a lot.
  189. //
  190. // NOTES
  191. //
  192. // The system uses the raw data found in the .ttf file without changing it
  193. // and without building auxiliary data structures. This is a bit inefficient
  194. // on little-endian systems (the data is big-endian), but assuming you're
  195. // caching the bitmaps or glyph shapes this shouldn't be a big deal.
  196. //
  197. // It appears to be very hard to programmatically determine what font a
  198. // given file is in a general way. I provide an API for this, but I don't
  199. // recommend it.
  200. //
  201. //
  202. // SOURCE STATISTICS (based on v0.6c, 2050 LOC)
  203. //
  204. // Documentation & header file 520 LOC \___ 660 LOC documentation
  205. // Sample code 140 LOC /
  206. // Truetype parsing 620 LOC ---- 620 LOC TrueType
  207. // Software rasterization 240 LOC \ .
  208. // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
  209. // Bitmap management 100 LOC /
  210. // Baked bitmap interface 70 LOC /
  211. // Font name matching & access 150 LOC ---- 150
  212. // C runtime library abstraction 60 LOC ---- 60
  213. //////////////////////////////////////////////////////////////////////////////
  214. //////////////////////////////////////////////////////////////////////////////
  215. ////
  216. //// SAMPLE PROGRAMS
  217. ////
  218. //
  219. // Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless
  220. //
  221. #if 0
  222. #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
  223. #include "stb_truetype.h"
  224. char ttf_buffer[1<<20];
  225. unsigned char temp_bitmap[512*512];
  226. stbtt_bakedchar cdata[96]; // ASCII 32..126 is 95 glyphs
  227. GLstbtt_uint ftex;
  228. void my_stbtt_initfont(void)
  229. {
  230. fread(ttf_buffer, 1, 1<<20, fopen("c:/windows/fonts/times.ttf", "rb"));
  231. stbtt_BakeFontBitmap(data,0, 32.0, temp_bitmap,512,512, 32,96, cdata); // no guarantee this fits!
  232. // can free ttf_buffer at this point
  233. glGenTextures(1, &ftex);
  234. glBindTexture(GL_TEXTURE_2D, ftex);
  235. glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 512,512, 0, GL_ALPHA, GL_UNSIGNED_BYTE, temp_bitmap);
  236. // can free temp_bitmap at this point
  237. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  238. }
  239. void my_stbtt_print(float x, float y, char *text)
  240. {
  241. // assume orthographic projection with units = screen pixels, origin at top left
  242. glBindTexture(GL_TEXTURE_2D, ftex);
  243. glBegin(GL_QUADS);
  244. while (*text) {
  245. if (*text >= 32 && *text < 128) {
  246. stbtt_aligned_quad q;
  247. stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
  248. glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
  249. glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
  250. glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
  251. glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
  252. }
  253. ++text;
  254. }
  255. glEnd();
  256. }
  257. #endif
  258. //
  259. //
  260. //////////////////////////////////////////////////////////////////////////////
  261. //
  262. // Complete program (this compiles): get a single bitmap, print as ASCII art
  263. //
  264. #if 0
  265. #include <stdio.h>
  266. #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation
  267. #include "stb_truetype.h"
  268. char ttf_buffer[1<<25];
  269. int main(int argc, char **argv)
  270. {
  271. stbtt_fontinfo font;
  272. unsigned char *bitmap;
  273. int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20);
  274. fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb"));
  275. stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
  276. bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0);
  277. for (j=0; j < h; ++j) {
  278. for (i=0; i < w; ++i)
  279. putchar(" .:ioVM@"[bitmap[j*w+i]>>5]);
  280. putchar('\n');
  281. }
  282. return 0;
  283. }
  284. #endif
  285. //
  286. // Output:
  287. //
  288. // .ii.
  289. // @@@@@@.
  290. // V@Mio@@o
  291. // :i. V@V
  292. // :oM@@M
  293. // :@@@MM@M
  294. // @@o o@M
  295. // :@@. M@M
  296. // @@@o@@@@
  297. // :M@@V:@@.
  298. //
  299. //////////////////////////////////////////////////////////////////////////////
  300. //
  301. // Complete program: print "Hello World!" banner, with bugs
  302. //
  303. #if 0
  304. char buffer[24<<20];
  305. unsigned char screen[20][79];
  306. int main(int arg, char **argv)
  307. {
  308. stbtt_fontinfo font;
  309. int i,j,ascent,baseline,ch=0;
  310. float scale, xpos=2; // leave a little padding in case the character extends left
  311. char *text = "Heljo World!";
  312. fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb"));
  313. stbtt_InitFont(&font, buffer, 0);
  314. scale = stbtt_ScaleForPixelHeight(&font, 15);
  315. stbtt_GetFontVMetrics(&font, &ascent,0,0);
  316. baseline = (int) (ascent*scale);
  317. while (text[ch]) {
  318. int advance,lsb,x0,y0,x1,y1;
  319. float x_shift = xpos - (float) floor(xpos);
  320. stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb);
  321. stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1);
  322. stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]);
  323. // note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong
  324. // because this API is really for baking character bitmaps into textures. if you want to render
  325. // a sequence of characters, you really need to render each bitmap to a temp buffer, then
  326. // "alpha blend" that into the working buffer
  327. xpos += (advance * scale);
  328. if (text[ch+1])
  329. xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]);
  330. ++ch;
  331. }
  332. for (j=0; j < 20; ++j) {
  333. for (i=0; i < 78; ++i)
  334. putchar(" .:ioVM@"[screen[j][i]>>5]);
  335. putchar('\n');
  336. }
  337. return 0;
  338. }
  339. #endif
  340. //////////////////////////////////////////////////////////////////////////////
  341. //////////////////////////////////////////////////////////////////////////////
  342. ////
  343. //// INTEGRATION WITH YOUR CODEBASE
  344. ////
  345. //// The following sections allow you to supply alternate definitions
  346. //// of C library functions used by stb_truetype.
  347. #ifdef STB_TRUETYPE_IMPLEMENTATION
  348. // #define your own (u)stbtt_int8/16/32 before including to override this
  349. #ifndef stbtt_uint8
  350. typedef unsigned char stbtt_uint8;
  351. typedef signed char stbtt_int8;
  352. typedef unsigned short stbtt_uint16;
  353. typedef signed short stbtt_int16;
  354. typedef unsigned int stbtt_uint32;
  355. typedef signed int stbtt_int32;
  356. #endif
  357. typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
  358. typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
  359. #ifdef STBTT_STATIC
  360. #define STBTT_DEF static
  361. #else
  362. #define STBTT_DEF extern
  363. #endif
  364. // #define your own STBTT_sort() to override this to avoid qsort
  365. #ifndef STBTT_sort
  366. #include <stdlib.h>
  367. #define STBTT_sort(data,num_items,item_size,compare_func) qsort(data,num_items,item_size,compare_func)
  368. #endif
  369. // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
  370. #ifndef STBTT_ifloor
  371. #include <math.h>
  372. #define STBTT_ifloor(x) ((int) floor(x))
  373. #define STBTT_iceil(x) ((int) ceil(x))
  374. #endif
  375. #ifndef STBTT_sqrt
  376. #include <math.h>
  377. #define STBTT_sqrt(x) sqrt(x)
  378. #endif
  379. // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
  380. #ifndef STBTT_malloc
  381. #include <stdlib.h>
  382. #define STBTT_malloc(x,u) ((void)(u),malloc(x))
  383. #define STBTT_free(x,u) ((void)(u),free(x))
  384. #endif
  385. #ifndef STBTT_assert
  386. #include <assert.h>
  387. #define STBTT_assert(x) assert(x)
  388. #endif
  389. #ifndef STBTT_strlen
  390. #include <string.h>
  391. #define STBTT_strlen(x) strlen(x)
  392. #endif
  393. #ifndef STBTT_memcpy
  394. #include <memory.h>
  395. #define STBTT_memcpy memcpy
  396. #define STBTT_memset memset
  397. #endif
  398. #endif
  399. ///////////////////////////////////////////////////////////////////////////////
  400. ///////////////////////////////////////////////////////////////////////////////
  401. ////
  402. //// INTERFACE
  403. ////
  404. ////
  405. #ifndef __STB_INCLUDE_STB_TRUETYPE_H__
  406. #define __STB_INCLUDE_STB_TRUETYPE_H__
  407. #ifdef __cplusplus
  408. extern "C" {
  409. #endif
  410. //////////////////////////////////////////////////////////////////////////////
  411. //
  412. // TEXTURE BAKING API
  413. //
  414. // If you use this API, you only have to call two functions ever.
  415. //
  416. typedef struct
  417. {
  418. unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
  419. float xoff,yoff,xadvance;
  420. } stbtt_bakedchar;
  421. STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
  422. float pixel_height, // height of font in pixels
  423. unsigned char *pixels, int pw, int ph, // bitmap to be filled in
  424. int first_char, int num_chars, // characters to bake
  425. stbtt_bakedchar *chardata); // you allocate this, it's num_chars long
  426. // if return is positive, the first unused row of the bitmap
  427. // if return is negative, returns the negative of the number of characters that fit
  428. // if return is 0, no characters fit and no rows were used
  429. // This uses a very crappy packing.
  430. typedef struct
  431. {
  432. float x0,y0,s0,t0; // top-left
  433. float x1,y1,s1,t1; // bottom-right
  434. } stbtt_aligned_quad;
  435. STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
  436. int char_index, // character to display
  437. float *xpos, float *ypos, // pointers to current position in screen pixel space
  438. stbtt_aligned_quad *q, // output: quad to draw
  439. int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier
  440. // Call GetBakedQuad with char_index = 'character - first_char', and it
  441. // creates the quad you need to draw and advances the current position.
  442. //
  443. // The coordinate system used assumes y increases downwards.
  444. //
  445. // Characters will extend both above and below the current position;
  446. // see discussion of "BASELINE" above.
  447. //
  448. // It's inefficient; you might want to c&p it and optimize it.
  449. //////////////////////////////////////////////////////////////////////////////
  450. //
  451. // NEW TEXTURE BAKING API
  452. //
  453. // This provides options for packing multiple fonts into one atlas, not
  454. // perfectly but better than nothing.
  455. typedef struct
  456. {
  457. unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
  458. float xoff,yoff,xadvance;
  459. float xoff2,yoff2;
  460. } stbtt_packedchar;
  461. typedef struct stbtt_pack_context stbtt_pack_context;
  462. typedef struct stbtt_fontinfo stbtt_fontinfo;
  463. #ifndef STB_RECT_PACK_VERSION
  464. typedef struct stbrp_rect stbrp_rect;
  465. #endif
  466. STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
  467. // Initializes a packing context stored in the passed-in stbtt_pack_context.
  468. // Future calls using this context will pack characters into the bitmap passed
  469. // in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
  470. // the distance from one row to the next (or 0 to mean they are packed tightly
  471. // together). "padding" is // the amount of padding to leave between each
  472. // character (normally you want '1' for bitmaps you'll use as textures with
  473. // bilinear filtering).
  474. //
  475. // Returns 0 on failure, 1 on success.
  476. STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc);
  477. // Cleans up the packing context and frees all memory.
  478. #define STBTT_POINT_SIZE(x) (-(x))
  479. STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
  480. int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
  481. // Creates character bitmaps from the font_index'th font found in fontdata (use
  482. // font_index=0 if you don't know what that is). It creates num_chars_in_range
  483. // bitmaps for characters with unicode values starting at first_unicode_char_in_range
  484. // and increasing. Data for how to render them is stored in chardata_for_range;
  485. // pass these to stbtt_GetPackedQuad to get back renderable quads.
  486. //
  487. // font_size is the full height of the character from ascender to descender,
  488. // as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
  489. // by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
  490. // and pass that result as 'font_size':
  491. // ..., 20 , ... // font max minus min y is 20 pixels tall
  492. // ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
  493. typedef struct
  494. {
  495. float font_size;
  496. int first_unicode_char_in_range;
  497. int num_chars_in_range;
  498. stbtt_packedchar *chardata_for_range; // output
  499. } stbtt_pack_range;
  500. STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
  501. // Creates character bitmaps from multiple ranges of characters stored in
  502. // ranges. This will usually create a better-packed bitmap than multiple
  503. // calls to stbtt_PackFontRange.
  504. STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
  505. STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects);
  506. // Those functions are called by stbtt_PackFontRanges(). If you want to
  507. // pack multiple fonts or custom data into a same texture, you may copy
  508. // the contents of stbtt_PackFontRanges() and create a custom version
  509. // using those functions.
  510. STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
  511. // Oversampling a font increases the quality by allowing higher-quality subpixel
  512. // positioning, and is especially valuable at smaller text sizes.
  513. //
  514. // This function sets the amount of oversampling for all following calls to
  515. // stbtt_PackFontRange(s). The default (no oversampling) is achieved by
  516. // h_oversample=1, v_oversample=1. The total number of pixels required is
  517. // h_oversample*v_oversample larger than the default; for example, 2x2
  518. // oversampling requires 4x the storage of 1x1. For best results, render
  519. // oversampled textures with bilinear filtering. Look at the readme in
  520. // stb/tests/oversample for information about oversampled fonts
  521. STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
  522. int char_index, // character to display
  523. float *xpos, float *ypos, // pointers to current position in screen pixel space
  524. stbtt_aligned_quad *q, // output: quad to draw
  525. int align_to_integer);
  526. // this is an opaque structure that you shouldn't mess with which holds
  527. // all the context needed from PackBegin to PackEnd.
  528. struct stbtt_pack_context {
  529. void *user_allocator_context;
  530. void *pack_info;
  531. int width;
  532. int height;
  533. int stride_in_bytes;
  534. int padding;
  535. unsigned int h_oversample, v_oversample;
  536. unsigned char *pixels;
  537. void *nodes;
  538. };
  539. //////////////////////////////////////////////////////////////////////////////
  540. //
  541. // FONT LOADING
  542. //
  543. //
  544. STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
  545. // Each .ttf/.ttc file may have more than one font. Each font has a sequential
  546. // index number starting from 0. Call this function to get the font offset for
  547. // a given index; it returns -1 if the index is out of range. A regular .ttf
  548. // file will only define one font and it always be at offset 0, so it will
  549. // return '0' for index 0, and -1 for all other indices. You can just skip
  550. // this step if you know it's that kind of font.
  551. // The following structure is defined publically so you can declare one on
  552. // the stack or as a global or etc, but you should treat it as opaque.
  553. typedef struct stbtt_fontinfo
  554. {
  555. void * userdata;
  556. unsigned char * data; // pointer to .ttf file
  557. int fontstart; // offset of start of font
  558. int numGlyphs; // number of glyphs, needed for range checking
  559. int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
  560. int index_map; // a cmap mapping for our chosen character encoding
  561. int indexToLocFormat; // format needed to map from glyph index to glyph
  562. } stbtt_fontinfo;
  563. STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
  564. // Given an offset into the file that defines a font, this function builds
  565. // the necessary cached info for the rest of the system. You must allocate
  566. // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't
  567. // need to do anything special to free it, because the contents are pure
  568. // value data with no additional data structures. Returns 0 on failure.
  569. //////////////////////////////////////////////////////////////////////////////
  570. //
  571. // CHARACTER TO GLYPH-INDEX CONVERSIOn
  572. STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint);
  573. // If you're going to perform multiple operations on the same character
  574. // and you want a speed-up, call this function with the character you're
  575. // going to process, then use glyph-based functions instead of the
  576. // codepoint-based functions.
  577. //////////////////////////////////////////////////////////////////////////////
  578. //
  579. // CHARACTER PROPERTIES
  580. //
  581. STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels);
  582. // computes a scale factor to produce a font whose "height" is 'pixels' tall.
  583. // Height is measured as the distance from the highest ascender to the lowest
  584. // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics
  585. // and computing:
  586. // scale = pixels / (ascent - descent)
  587. // so if you prefer to measure height by the ascent only, use a similar calculation.
  588. STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels);
  589. // computes a scale factor to produce a font whose EM size is mapped to
  590. // 'pixels' tall. This is probably what traditional APIs compute, but
  591. // I'm not positive.
  592. STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap);
  593. // ascent is the coordinate above the baseline the font extends; descent
  594. // is the coordinate below the baseline the font extends (i.e. it is typically negative)
  595. // lineGap is the spacing between one row's descent and the next row's ascent...
  596. // so you should advance the vertical position by "*ascent - *descent + *lineGap"
  597. // these are expressed in unscaled coordinates, so you must multiply by
  598. // the scale factor for a given size
  599. STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1);
  600. // the bounding box around all possible characters
  601. STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing);
  602. // leftSideBearing is the offset from the current horizontal position to the left edge of the character
  603. // advanceWidth is the offset from the current horizontal position to the next horizontal position
  604. // these are expressed in unscaled coordinates
  605. STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
  606. // an additional amount to add to the 'advance' value between ch1 and ch2
  607. STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
  608. // Gets the bounding box of the visible part of the glyph, in unscaled coordinates
  609. STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing);
  610. STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2);
  611. STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1);
  612. // as above, but takes one or more glyph indices for greater efficiency
  613. //////////////////////////////////////////////////////////////////////////////
  614. //
  615. // GLYPH SHAPES (you probably don't need these, but they have to go before
  616. // the bitmaps for C declaration-order reasons)
  617. //
  618. #ifndef STBTT_vmove // you can predefine these to use different values (but why?)
  619. enum {
  620. STBTT_vmove=1,
  621. STBTT_vline,
  622. STBTT_vcurve
  623. };
  624. #endif
  625. #ifndef stbtt_vertex // you can predefine this to use different values
  626. // (we share this with other code at RAD)
  627. #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file
  628. typedef struct
  629. {
  630. stbtt_vertex_type x,y,cx,cy;
  631. unsigned char type,padding;
  632. } stbtt_vertex;
  633. #endif
  634. STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index);
  635. // returns non-zero if nothing is drawn for this glyph
  636. STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
  637. STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
  638. // returns # of vertices and fills *vertices with the pointer to them
  639. // these are expressed in "unscaled" coordinates
  640. //
  641. // The shape is a series of countours. Each one starts with
  642. // a STBTT_moveto, then consists of a series of mixed
  643. // STBTT_lineto and STBTT_curveto segments. A lineto
  644. // draws a line from previous endpoint to its x,y; a curveto
  645. // draws a quadratic bezier from previous endpoint to
  646. // its x,y, using cx,cy as the bezier control point.
  647. STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
  648. // frees the data allocated above
  649. //////////////////////////////////////////////////////////////////////////////
  650. //
  651. // BITMAP RENDERING
  652. //
  653. STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata);
  654. // frees the bitmap allocated below
  655. STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
  656. // allocates a large-enough single-channel 8bpp bitmap and renders the
  657. // specified character/glyph at the specified scale into it, with
  658. // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque).
  659. // *width & *height are filled out with the width & height of the bitmap,
  660. // which is stored left-to-right, top-to-bottom.
  661. //
  662. // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap
  663. STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff);
  664. // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel
  665. // shift for the character
  666. STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint);
  667. // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap
  668. // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap
  669. // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the
  670. // width and height and positioning info for it first.
  671. STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint);
  672. // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel
  673. // shift for the character
  674. STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
  675. // get the bbox of the bitmap centered around the glyph origin; so the
  676. // bitmap width is ix1-ix0, height is iy1-iy0, and location to place
  677. // the bitmap top left is (leftSideBearing*scale,iy0).
  678. // (Note that the bitmap uses y-increases-down, but the shape uses
  679. // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.)
  680. STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
  681. // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel
  682. // shift for the character
  683. // the following functions are equivalent to the above functions, but operate
  684. // on glyph indices instead of Unicode codepoints (for efficiency)
  685. STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff);
  686. STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff);
  687. STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph);
  688. STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph);
  689. STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1);
  690. STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1);
  691. // @TODO: don't expose this structure
  692. typedef struct
  693. {
  694. int w,h,stride;
  695. unsigned char *pixels;
  696. } stbtt__bitmap;
  697. STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata);
  698. //////////////////////////////////////////////////////////////////////////////
  699. //
  700. // Finding the right font...
  701. //
  702. // You should really just solve this offline, keep your own tables
  703. // of what font is what, and don't try to get it out of the .ttf file.
  704. // That's because getting it out of the .ttf file is really hard, because
  705. // the names in the file can appear in many possible encodings, in many
  706. // possible languages, and e.g. if you need a case-insensitive comparison,
  707. // the details of that depend on the encoding & language in a complex way
  708. // (actually underspecified in truetype, but also gigantic).
  709. //
  710. // But you can use the provided functions in two possible ways:
  711. // stbtt_FindMatchingFont() will use *case-sensitive* comparisons on
  712. // unicode-encoded names to try to find the font you want;
  713. // you can run this before calling stbtt_InitFont()
  714. //
  715. // stbtt_GetFontNameString() lets you get any of the various strings
  716. // from the file yourself and do your own comparisons on them.
  717. // You have to have called stbtt_InitFont() first.
  718. STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags);
  719. // returns the offset (not index) of the font that matches, or -1 if none
  720. // if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold".
  721. // if you use any other flag, use a font name like "Arial"; this checks
  722. // the 'macStyle' header field; i don't know if fonts set this consistently
  723. #define STBTT_MACSTYLE_DONTCARE 0
  724. #define STBTT_MACSTYLE_BOLD 1
  725. #define STBTT_MACSTYLE_ITALIC 2
  726. #define STBTT_MACSTYLE_UNDERSCORE 4
  727. #define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0
  728. STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2);
  729. // returns 1/0 whether the first string interpreted as utf8 is identical to
  730. // the second string interpreted as big-endian utf16... useful for strings from next func
  731. STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID);
  732. // returns the string (which may be big-endian double byte, e.g. for unicode)
  733. // and puts the length in bytes in *length.
  734. //
  735. // some of the values for the IDs are below; for more see the truetype spec:
  736. // http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html
  737. // http://www.microsoft.com/typography/otspec/name.htm
  738. enum { // platformID
  739. STBTT_PLATFORM_ID_UNICODE =0,
  740. STBTT_PLATFORM_ID_MAC =1,
  741. STBTT_PLATFORM_ID_ISO =2,
  742. STBTT_PLATFORM_ID_MICROSOFT =3
  743. };
  744. enum { // encodingID for STBTT_PLATFORM_ID_UNICODE
  745. STBTT_UNICODE_EID_UNICODE_1_0 =0,
  746. STBTT_UNICODE_EID_UNICODE_1_1 =1,
  747. STBTT_UNICODE_EID_ISO_10646 =2,
  748. STBTT_UNICODE_EID_UNICODE_2_0_BMP=3,
  749. STBTT_UNICODE_EID_UNICODE_2_0_FULL=4
  750. };
  751. enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT
  752. STBTT_MS_EID_SYMBOL =0,
  753. STBTT_MS_EID_UNICODE_BMP =1,
  754. STBTT_MS_EID_SHIFTJIS =2,
  755. STBTT_MS_EID_UNICODE_FULL =10
  756. };
  757. enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes
  758. STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4,
  759. STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5,
  760. STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6,
  761. STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7
  762. };
  763. enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID...
  764. // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs
  765. STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410,
  766. STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411,
  767. STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412,
  768. STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419,
  769. STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409,
  770. STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D
  771. };
  772. enum { // languageID for STBTT_PLATFORM_ID_MAC
  773. STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11,
  774. STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23,
  775. STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32,
  776. STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 ,
  777. STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 ,
  778. STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33,
  779. STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19
  780. };
  781. #ifdef __cplusplus
  782. }
  783. #endif
  784. #endif // __STB_INCLUDE_STB_TRUETYPE_H__
  785. ///////////////////////////////////////////////////////////////////////////////
  786. ///////////////////////////////////////////////////////////////////////////////
  787. ////
  788. //// IMPLEMENTATION
  789. ////
  790. ////
  791. #ifdef STB_TRUETYPE_IMPLEMENTATION
  792. #ifndef STBTT_MAX_OVERSAMPLE
  793. #define STBTT_MAX_OVERSAMPLE 8
  794. #endif
  795. typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
  796. //////////////////////////////////////////////////////////////////////////
  797. //
  798. // accessors to parse data from file
  799. //
  800. // on platforms that don't allow misaligned reads, if we want to allow
  801. // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE
  802. #define ttBYTE(p) (* (stbtt_uint8 *) (p))
  803. #define ttCHAR(p) (* (stbtt_int8 *) (p))
  804. #define ttFixed(p) ttLONG(p)
  805. #if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
  806. #define ttUSHORT(p) (* (stbtt_uint16 *) (p))
  807. #define ttSHORT(p) (* (stbtt_int16 *) (p))
  808. #define ttULONG(p) (* (stbtt_uint32 *) (p))
  809. #define ttLONG(p) (* (stbtt_int32 *) (p))
  810. #else
  811. static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
  812. static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
  813. static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
  814. static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
  815. #endif
  816. #define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3))
  817. #define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3])
  818. static int stbtt__isfont(const stbtt_uint8 *font)
  819. {
  820. // check the version number
  821. if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1
  822. if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this!
  823. if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF
  824. if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0
  825. return 0;
  826. }
  827. // @OPTIMIZE: binary search
  828. static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag)
  829. {
  830. stbtt_int32 num_tables = ttUSHORT(data+fontstart+4);
  831. stbtt_uint32 tabledir = fontstart + 12;
  832. stbtt_int32 i;
  833. for (i=0; i < num_tables; ++i) {
  834. stbtt_uint32 loc = tabledir + 16*i;
  835. if (stbtt_tag(data+loc+0, tag))
  836. return ttULONG(data+loc+8);
  837. }
  838. return 0;
  839. }
  840. STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index)
  841. {
  842. // if it's just a font, there's only one valid index
  843. if (stbtt__isfont(font_collection))
  844. return index == 0 ? 0 : -1;
  845. // check if it's a TTC
  846. if (stbtt_tag(font_collection, "ttcf")) {
  847. // version 1?
  848. if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) {
  849. stbtt_int32 n = ttLONG(font_collection+8);
  850. if (index >= n)
  851. return -1;
  852. return ttULONG(font_collection+12+index*14);
  853. }
  854. }
  855. return -1;
  856. }
  857. STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart)
  858. {
  859. stbtt_uint8 *data = (stbtt_uint8 *) data2;
  860. stbtt_uint32 cmap, t;
  861. stbtt_int32 i,numTables;
  862. info->data = data;
  863. info->fontstart = fontstart;
  864. cmap = stbtt__find_table(data, fontstart, "cmap"); // required
  865. info->loca = stbtt__find_table(data, fontstart, "loca"); // required
  866. info->head = stbtt__find_table(data, fontstart, "head"); // required
  867. info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required
  868. info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
  869. info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
  870. info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
  871. if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx)
  872. return 0;
  873. t = stbtt__find_table(data, fontstart, "maxp");
  874. if (t)
  875. info->numGlyphs = ttUSHORT(data+t+4);
  876. else
  877. info->numGlyphs = 0xffff;
  878. // find a cmap encoding table we understand *now* to avoid searching
  879. // later. (todo: could make this installable)
  880. // the same regardless of glyph.
  881. numTables = ttUSHORT(data + cmap + 2);
  882. info->index_map = 0;
  883. for (i=0; i < numTables; ++i) {
  884. stbtt_uint32 encoding_record = cmap + 4 + 8 * i;
  885. // find an encoding we understand:
  886. switch(ttUSHORT(data+encoding_record)) {
  887. case STBTT_PLATFORM_ID_MICROSOFT:
  888. switch (ttUSHORT(data+encoding_record+2)) {
  889. case STBTT_MS_EID_UNICODE_BMP:
  890. case STBTT_MS_EID_UNICODE_FULL:
  891. // MS/Unicode
  892. info->index_map = cmap + ttULONG(data+encoding_record+4);
  893. break;
  894. }
  895. break;
  896. case STBTT_PLATFORM_ID_UNICODE:
  897. // Mac/iOS has these
  898. // all the encodingIDs are unicode, so we don't bother to check it
  899. info->index_map = cmap + ttULONG(data+encoding_record+4);
  900. break;
  901. }
  902. }
  903. if (info->index_map == 0)
  904. return 0;
  905. info->indexToLocFormat = ttUSHORT(data+info->head + 50);
  906. return 1;
  907. }
  908. STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint)
  909. {
  910. stbtt_uint8 *data = info->data;
  911. stbtt_uint32 index_map = info->index_map;
  912. stbtt_uint16 format = ttUSHORT(data + index_map + 0);
  913. if (format == 0) { // apple byte encoding
  914. stbtt_int32 bytes = ttUSHORT(data + index_map + 2);
  915. if (unicode_codepoint < bytes-6)
  916. return ttBYTE(data + index_map + 6 + unicode_codepoint);
  917. return 0;
  918. } else if (format == 6) {
  919. stbtt_uint32 first = ttUSHORT(data + index_map + 6);
  920. stbtt_uint32 count = ttUSHORT(data + index_map + 8);
  921. if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count)
  922. return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2);
  923. return 0;
  924. } else if (format == 2) {
  925. STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean
  926. return 0;
  927. } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges
  928. stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1;
  929. stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1;
  930. stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10);
  931. stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1;
  932. stbtt_uint16 item, offset, start, end;
  933. // do a binary search of the segments
  934. stbtt_uint32 endCount = index_map + 14;
  935. stbtt_uint32 search = endCount;
  936. if (unicode_codepoint > 0xffff)
  937. return 0;
  938. // they lie from endCount .. endCount + segCount
  939. // but searchRange is the nearest power of two, so...
  940. if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2))
  941. search += rangeShift*2;
  942. // now decrement to bias correctly to find smallest
  943. search -= 2;
  944. while (entrySelector) {
  945. searchRange >>= 1;
  946. start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2);
  947. end = ttUSHORT(data + search + searchRange*2);
  948. if (unicode_codepoint > end)
  949. search += searchRange*2;
  950. --entrySelector;
  951. }
  952. search += 2;
  953. item = (stbtt_uint16) ((search - endCount) >> 1);
  954. STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item));
  955. start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item);
  956. end = ttUSHORT(data + index_map + 14 + 2 + 2*item);
  957. if (unicode_codepoint < start)
  958. return 0;
  959. offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item);
  960. if (offset == 0)
  961. return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item));
  962. return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
  963. } else if (format == 12 || format == 13) {
  964. stbtt_uint32 ngroups = ttULONG(data+index_map+12);
  965. stbtt_int32 low,high;
  966. low = 0; high = (stbtt_int32)ngroups;
  967. // Binary search the right group.
  968. while (low < high) {
  969. stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
  970. stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12);
  971. stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4);
  972. if ((stbtt_uint32) unicode_codepoint < start_char)
  973. high = mid;
  974. else if ((stbtt_uint32) unicode_codepoint > end_char)
  975. low = mid+1;
  976. else {
  977. stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8);
  978. if (format == 12)
  979. return start_glyph + unicode_codepoint-start_char;
  980. else // format == 13
  981. return start_glyph;
  982. }
  983. }
  984. return 0; // not found
  985. }
  986. // @TODO
  987. STBTT_assert(0);
  988. return 0;
  989. }
  990. STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices)
  991. {
  992. return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices);
  993. }
  994. static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy)
  995. {
  996. v->type = type;
  997. v->x = (stbtt_int16) x;
  998. v->y = (stbtt_int16) y;
  999. v->cx = (stbtt_int16) cx;
  1000. v->cy = (stbtt_int16) cy;
  1001. }
  1002. static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index)
  1003. {
  1004. int g1,g2;
  1005. if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range
  1006. if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format
  1007. if (info->indexToLocFormat == 0) {
  1008. g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2;
  1009. g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2;
  1010. } else {
  1011. g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4);
  1012. g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4);
  1013. }
  1014. return g1==g2 ? -1 : g1; // if length is 0, return -1
  1015. }
  1016. STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1)
  1017. {
  1018. int g = stbtt__GetGlyfOffset(info, glyph_index);
  1019. if (g < 0) return 0;
  1020. if (x0) *x0 = ttSHORT(info->data + g + 2);
  1021. if (y0) *y0 = ttSHORT(info->data + g + 4);
  1022. if (x1) *x1 = ttSHORT(info->data + g + 6);
  1023. if (y1) *y1 = ttSHORT(info->data + g + 8);
  1024. return 1;
  1025. }
  1026. STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1)
  1027. {
  1028. return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1);
  1029. }
  1030. STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index)
  1031. {
  1032. stbtt_int16 numberOfContours;
  1033. int g = stbtt__GetGlyfOffset(info, glyph_index);
  1034. if (g < 0) return 1;
  1035. numberOfContours = ttSHORT(info->data + g);
  1036. return numberOfContours == 0;
  1037. }
  1038. static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off,
  1039. stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy)
  1040. {
  1041. if (start_off) {
  1042. if (was_off)
  1043. stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy);
  1044. stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy);
  1045. } else {
  1046. if (was_off)
  1047. stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy);
  1048. else
  1049. stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0);
  1050. }
  1051. return num_vertices;
  1052. }
  1053. STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices)
  1054. {
  1055. stbtt_int16 numberOfContours;
  1056. stbtt_uint8 *endPtsOfContours;
  1057. stbtt_uint8 *data = info->data;
  1058. stbtt_vertex *vertices=0;
  1059. int num_vertices=0;
  1060. int g = stbtt__GetGlyfOffset(info, glyph_index);
  1061. *pvertices = NULL;
  1062. if (g < 0) return 0;
  1063. numberOfContours = ttSHORT(data + g);
  1064. if (numberOfContours > 0) {
  1065. stbtt_uint8 flags=0,flagcount;
  1066. stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0;
  1067. stbtt_int32 x,y,cx,cy,sx,sy, scx,scy;
  1068. stbtt_uint8 *points;
  1069. endPtsOfContours = (data + g + 10);
  1070. ins = ttUSHORT(data + g + 10 + numberOfContours * 2);
  1071. points = data + g + 10 + numberOfContours * 2 + 2 + ins;
  1072. n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2);
  1073. m = n + 2*numberOfContours; // a loose bound on how many vertices we might need
  1074. vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata);
  1075. if (vertices == 0)
  1076. return 0;
  1077. next_move = 0;
  1078. flagcount=0;
  1079. // in first pass, we load uninterpreted data into the allocated array
  1080. // above, shifted to the end of the array so we won't overwrite it when
  1081. // we create our final data starting from the front
  1082. off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated
  1083. // first load flags
  1084. for (i=0; i < n; ++i) {
  1085. if (flagcount == 0) {
  1086. flags = *points++;
  1087. if (flags & 8)
  1088. flagcount = *points++;
  1089. } else
  1090. --flagcount;
  1091. vertices[off+i].type = flags;
  1092. }
  1093. // now load x coordinates
  1094. x=0;
  1095. for (i=0; i < n; ++i) {
  1096. flags = vertices[off+i].type;
  1097. if (flags & 2) {
  1098. stbtt_int16 dx = *points++;
  1099. x += (flags & 16) ? dx : -dx; // ???
  1100. } else {
  1101. if (!(flags & 16)) {
  1102. x = x + (stbtt_int16) (points[0]*256 + points[1]);
  1103. points += 2;
  1104. }
  1105. }
  1106. vertices[off+i].x = (stbtt_int16) x;
  1107. }
  1108. // now load y coordinates
  1109. y=0;
  1110. for (i=0; i < n; ++i) {
  1111. flags = vertices[off+i].type;
  1112. if (flags & 4) {
  1113. stbtt_int16 dy = *points++;
  1114. y += (flags & 32) ? dy : -dy; // ???
  1115. } else {
  1116. if (!(flags & 32)) {
  1117. y = y + (stbtt_int16) (points[0]*256 + points[1]);
  1118. points += 2;
  1119. }
  1120. }
  1121. vertices[off+i].y = (stbtt_int16) y;
  1122. }
  1123. // now convert them to our format
  1124. num_vertices=0;
  1125. sx = sy = cx = cy = scx = scy = 0;
  1126. for (i=0; i < n; ++i) {
  1127. flags = vertices[off+i].type;
  1128. x = (stbtt_int16) vertices[off+i].x;
  1129. y = (stbtt_int16) vertices[off+i].y;
  1130. if (next_move == i) {
  1131. if (i != 0)
  1132. num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
  1133. // now start the new one
  1134. start_off = !(flags & 1);
  1135. if (start_off) {
  1136. // if we start off with an off-curve point, then when we need to find a point on the curve
  1137. // where we can start, and we need to save some state for when we wraparound.
  1138. scx = x;
  1139. scy = y;
  1140. if (!(vertices[off+i+1].type & 1)) {
  1141. // next point is also a curve point, so interpolate an on-point curve
  1142. sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1;
  1143. sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1;
  1144. } else {
  1145. // otherwise just use the next point as our start point
  1146. sx = (stbtt_int32) vertices[off+i+1].x;
  1147. sy = (stbtt_int32) vertices[off+i+1].y;
  1148. ++i; // we're using point i+1 as the starting point, so skip it
  1149. }
  1150. } else {
  1151. sx = x;
  1152. sy = y;
  1153. }
  1154. stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0);
  1155. was_off = 0;
  1156. next_move = 1 + ttUSHORT(endPtsOfContours+j*2);
  1157. ++j;
  1158. } else {
  1159. if (!(flags & 1)) { // if it's a curve
  1160. if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint
  1161. stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy);
  1162. cx = x;
  1163. cy = y;
  1164. was_off = 1;
  1165. } else {
  1166. if (was_off)
  1167. stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy);
  1168. else
  1169. stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0);
  1170. was_off = 0;
  1171. }
  1172. }
  1173. }
  1174. num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy);
  1175. } else if (numberOfContours == -1) {
  1176. // Compound shapes.
  1177. int more = 1;
  1178. stbtt_uint8 *comp = data + g + 10;
  1179. num_vertices = 0;
  1180. vertices = 0;
  1181. while (more) {
  1182. stbtt_uint16 flags, gidx;
  1183. int comp_num_verts = 0, i;
  1184. stbtt_vertex *comp_verts = 0, *tmp = 0;
  1185. float mtx[6] = {1,0,0,1,0,0}, m, n;
  1186. flags = ttSHORT(comp); comp+=2;
  1187. gidx = ttSHORT(comp); comp+=2;
  1188. if (flags & 2) { // XY values
  1189. if (flags & 1) { // shorts
  1190. mtx[4] = ttSHORT(comp); comp+=2;
  1191. mtx[5] = ttSHORT(comp); comp+=2;
  1192. } else {
  1193. mtx[4] = ttCHAR(comp); comp+=1;
  1194. mtx[5] = ttCHAR(comp); comp+=1;
  1195. }
  1196. }
  1197. else {
  1198. // @TODO handle matching point
  1199. STBTT_assert(0);
  1200. }
  1201. if (flags & (1<<3)) { // WE_HAVE_A_SCALE
  1202. mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
  1203. mtx[1] = mtx[2] = 0;
  1204. } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE
  1205. mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
  1206. mtx[1] = mtx[2] = 0;
  1207. mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
  1208. } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO
  1209. mtx[0] = ttSHORT(comp)/16384.0f; comp+=2;
  1210. mtx[1] = ttSHORT(comp)/16384.0f; comp+=2;
  1211. mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
  1212. mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
  1213. }
  1214. // Find transformation scales.
  1215. m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
  1216. n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
  1217. // Get indexed glyph.
  1218. comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
  1219. if (comp_num_verts > 0) {
  1220. // Transform vertices.
  1221. for (i = 0; i < comp_num_verts; ++i) {
  1222. stbtt_vertex* v = &comp_verts[i];
  1223. stbtt_vertex_type x,y;
  1224. x=v->x; y=v->y;
  1225. v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
  1226. v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
  1227. x=v->cx; y=v->cy;
  1228. v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4]));
  1229. v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5]));
  1230. }
  1231. // Append vertices.
  1232. tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata);
  1233. if (!tmp) {
  1234. if (vertices) STBTT_free(vertices, info->userdata);
  1235. if (comp_verts) STBTT_free(comp_verts, info->userdata);
  1236. return 0;
  1237. }
  1238. if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
  1239. STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
  1240. if (vertices) STBTT_free(vertices, info->userdata);
  1241. vertices = tmp;
  1242. STBTT_free(comp_verts, info->userdata);
  1243. num_vertices += comp_num_verts;
  1244. }
  1245. // More components ?
  1246. more = flags & (1<<5);
  1247. }
  1248. } else if (numberOfContours < 0) {
  1249. // @TODO other compound variations?
  1250. STBTT_assert(0);
  1251. } else {
  1252. // numberOfCounters == 0, do nothing
  1253. }
  1254. *pvertices = vertices;
  1255. return num_vertices;
  1256. }
  1257. STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing)
  1258. {
  1259. stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34);
  1260. if (glyph_index < numOfLongHorMetrics) {
  1261. if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index);
  1262. if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2);
  1263. } else {
  1264. if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1));
  1265. if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics));
  1266. }
  1267. }
  1268. STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
  1269. {
  1270. stbtt_uint8 *data = info->data + info->kern;
  1271. stbtt_uint32 needle, straw;
  1272. int l, r, m;
  1273. // we only look at the first table. it must be 'horizontal' and format 0.
  1274. if (!info->kern)
  1275. return 0;
  1276. if (ttUSHORT(data+2) < 1) // number of tables, need at least 1
  1277. return 0;
  1278. if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format
  1279. return 0;
  1280. l = 0;
  1281. r = ttUSHORT(data+10) - 1;
  1282. needle = glyph1 << 16 | glyph2;
  1283. while (l <= r) {
  1284. m = (l + r) >> 1;
  1285. straw = ttULONG(data+18+(m*6)); // note: unaligned read
  1286. if (needle < straw)
  1287. r = m - 1;
  1288. else if (needle > straw)
  1289. l = m + 1;
  1290. else
  1291. return ttSHORT(data+22+(m*6));
  1292. }
  1293. return 0;
  1294. }
  1295. STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
  1296. {
  1297. if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
  1298. return 0;
  1299. return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
  1300. }
  1301. STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing)
  1302. {
  1303. stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing);
  1304. }
  1305. STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap)
  1306. {
  1307. if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4);
  1308. if (descent) *descent = ttSHORT(info->data+info->hhea + 6);
  1309. if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8);
  1310. }
  1311. STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1)
  1312. {
  1313. *x0 = ttSHORT(info->data + info->head + 36);
  1314. *y0 = ttSHORT(info->data + info->head + 38);
  1315. *x1 = ttSHORT(info->data + info->head + 40);
  1316. *y1 = ttSHORT(info->data + info->head + 42);
  1317. }
  1318. STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height)
  1319. {
  1320. int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6);
  1321. return (float) height / fheight;
  1322. }
  1323. STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels)
  1324. {
  1325. int unitsPerEm = ttUSHORT(info->data + info->head + 18);
  1326. return pixels / unitsPerEm;
  1327. }
  1328. STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
  1329. {
  1330. STBTT_free(v, info->userdata);
  1331. }
  1332. //////////////////////////////////////////////////////////////////////////////
  1333. //
  1334. // antialiasing software rasterizer
  1335. //
  1336. STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
  1337. {
  1338. int x0,y0,x1,y1;
  1339. if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
  1340. // e.g. space character
  1341. if (ix0) *ix0 = 0;
  1342. if (iy0) *iy0 = 0;
  1343. if (ix1) *ix1 = 0;
  1344. if (iy1) *iy1 = 0;
  1345. } else {
  1346. // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
  1347. if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
  1348. if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
  1349. if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
  1350. if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
  1351. }
  1352. }
  1353. STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
  1354. {
  1355. stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
  1356. }
  1357. STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
  1358. {
  1359. stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1);
  1360. }
  1361. STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
  1362. {
  1363. stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1);
  1364. }
  1365. typedef struct stbtt__edge {
  1366. float x0,y0, x1,y1;
  1367. int invert;
  1368. } stbtt__edge;
  1369. typedef struct stbtt__active_edge
  1370. {
  1371. int x,dx;
  1372. float ey;
  1373. struct stbtt__active_edge *next;
  1374. int valid;
  1375. } stbtt__active_edge;
  1376. #define FIXSHIFT 10
  1377. #define FIX (1 << FIXSHIFT)
  1378. #define FIXMASK (FIX-1)
  1379. static stbtt__active_edge *new_active(stbtt__edge *e, int off_x, float start_point, void *userdata)
  1380. {
  1381. stbtt__active_edge *z = (stbtt__active_edge *) STBTT_malloc(sizeof(*z), userdata); // @TODO: make a pool of these!!!
  1382. float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
  1383. STBTT_assert(e->y0 <= start_point);
  1384. if (!z) return z;
  1385. // round dx down to avoid going too far
  1386. if (dxdy < 0)
  1387. z->dx = -STBTT_ifloor(FIX * -dxdy);
  1388. else
  1389. z->dx = STBTT_ifloor(FIX * dxdy);
  1390. z->x = STBTT_ifloor(FIX * (e->x0 + dxdy * (start_point - e->y0)));
  1391. z->x -= off_x * FIX;
  1392. z->ey = e->y1;
  1393. z->next = 0;
  1394. z->valid = e->invert ? 1 : -1;
  1395. return z;
  1396. }
  1397. // note: this routine clips fills that extend off the edges... ideally this
  1398. // wouldn't happen, but it could happen if the truetype glyph bounding boxes
  1399. // are wrong, or if the user supplies a too-small bitmap
  1400. static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight)
  1401. {
  1402. // non-zero winding fill
  1403. int x0=0, w=0;
  1404. while (e) {
  1405. if (w == 0) {
  1406. // if we're currently at zero, we need to record the edge start point
  1407. x0 = e->x; w += e->valid;
  1408. } else {
  1409. int x1 = e->x; w += e->valid;
  1410. // if we went to zero, we need to draw
  1411. if (w == 0) {
  1412. int i = x0 >> FIXSHIFT;
  1413. int j = x1 >> FIXSHIFT;
  1414. if (i < len && j >= 0) {
  1415. if (i == j) {
  1416. // x0,x1 are the same pixel, so compute combined coverage
  1417. scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> FIXSHIFT);
  1418. } else {
  1419. if (i >= 0) // add antialiasing for x0
  1420. scanline[i] = scanline[i] + (stbtt_uint8) (((FIX - (x0 & FIXMASK)) * max_weight) >> FIXSHIFT);
  1421. else
  1422. i = -1; // clip
  1423. if (j < len) // add antialiasing for x1
  1424. scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & FIXMASK) * max_weight) >> FIXSHIFT);
  1425. else
  1426. j = len; // clip
  1427. for (++i; i < j; ++i) // fill pixels between x0 and x1
  1428. scanline[i] = scanline[i] + (stbtt_uint8) max_weight;
  1429. }
  1430. }
  1431. }
  1432. }
  1433. e = e->next;
  1434. }
  1435. }
  1436. static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
  1437. {
  1438. stbtt__active_edge *active = NULL;
  1439. int y,j=0;
  1440. int max_weight = (255 / vsubsample); // weight per vertical scanline
  1441. int s; // vertical subsample index
  1442. unsigned char scanline_data[512], *scanline;
  1443. if (result->w > 512)
  1444. scanline = (unsigned char *) STBTT_malloc(result->w, userdata);
  1445. else
  1446. scanline = scanline_data;
  1447. y = off_y * vsubsample;
  1448. e[n].y0 = (off_y + result->h) * (float) vsubsample + 1;
  1449. while (j < result->h) {
  1450. STBTT_memset(scanline, 0, result->w);
  1451. for (s=0; s < vsubsample; ++s) {
  1452. // find center of pixel for this scanline
  1453. float scan_y = y + 0.5f;
  1454. stbtt__active_edge **step = &active;
  1455. // update all active edges;
  1456. // remove all active edges that terminate before the center of this scanline
  1457. while (*step) {
  1458. stbtt__active_edge * z = *step;
  1459. if (z->ey <= scan_y) {
  1460. *step = z->next; // delete from list
  1461. STBTT_assert(z->valid);
  1462. z->valid = 0;
  1463. STBTT_free(z, userdata);
  1464. } else {
  1465. z->x += z->dx; // advance to position for current scanline
  1466. step = &((*step)->next); // advance through list
  1467. }
  1468. }
  1469. // resort the list if needed
  1470. for(;;) {
  1471. int changed=0;
  1472. step = &active;
  1473. while (*step && (*step)->next) {
  1474. if ((*step)->x > (*step)->next->x) {
  1475. stbtt__active_edge *t = *step;
  1476. stbtt__active_edge *q = t->next;
  1477. t->next = q->next;
  1478. q->next = t;
  1479. *step = q;
  1480. changed = 1;
  1481. }
  1482. step = &(*step)->next;
  1483. }
  1484. if (!changed) break;
  1485. }
  1486. // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
  1487. while (e->y0 <= scan_y) {
  1488. if (e->y1 > scan_y) {
  1489. stbtt__active_edge *z = new_active(e, off_x, scan_y, userdata);
  1490. // find insertion point
  1491. if (active == NULL)
  1492. active = z;
  1493. else if (z->x < active->x) {
  1494. // insert at front
  1495. z->next = active;
  1496. active = z;
  1497. } else {
  1498. // find thing to insert AFTER
  1499. stbtt__active_edge *p = active;
  1500. while (p->next && p->next->x < z->x)
  1501. p = p->next;
  1502. // at this point, p->next->x is NOT < z->x
  1503. z->next = p->next;
  1504. p->next = z;
  1505. }
  1506. }
  1507. ++e;
  1508. }
  1509. // now process all active edges in XOR fashion
  1510. if (active)
  1511. stbtt__fill_active_edges(scanline, result->w, active, max_weight);
  1512. ++y;
  1513. }
  1514. STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w);
  1515. ++j;
  1516. }
  1517. while (active) {
  1518. stbtt__active_edge *z = active;
  1519. active = active->next;
  1520. STBTT_free(z, userdata);
  1521. }
  1522. if (scanline != scanline_data)
  1523. STBTT_free(scanline, userdata);
  1524. }
  1525. static int stbtt__edge_compare(const void *p, const void *q)
  1526. {
  1527. stbtt__edge *a = (stbtt__edge *) p;
  1528. stbtt__edge *b = (stbtt__edge *) q;
  1529. if (a->y0 < b->y0) return -1;
  1530. if (a->y0 > b->y0) return 1;
  1531. return 0;
  1532. }
  1533. typedef struct
  1534. {
  1535. float x,y;
  1536. } stbtt__point;
  1537. 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)
  1538. {
  1539. float y_scale_inv = invert ? -scale_y : scale_y;
  1540. stbtt__edge *e;
  1541. int n,i,j,k,m;
  1542. int vsubsample = result->h < 8 ? 15 : 5;
  1543. // vsubsample should divide 255 evenly; otherwise we won't reach full opacity
  1544. // now we have to blow out the windings into explicit edge lists
  1545. n = 0;
  1546. for (i=0; i < windings; ++i)
  1547. n += wcount[i];
  1548. e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel
  1549. if (e == 0) return;
  1550. n = 0;
  1551. m=0;
  1552. for (i=0; i < windings; ++i) {
  1553. stbtt__point *p = pts + m;
  1554. m += wcount[i];
  1555. j = wcount[i]-1;
  1556. for (k=0; k < wcount[i]; j=k++) {
  1557. int a=k,b=j;
  1558. // skip the edge if horizontal
  1559. if (p[j].y == p[k].y)
  1560. continue;
  1561. // add edge from j to k to the list
  1562. e[n].invert = 0;
  1563. if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
  1564. e[n].invert = 1;
  1565. a=j,b=k;
  1566. }
  1567. e[n].x0 = p[a].x * scale_x + shift_x;
  1568. e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
  1569. e[n].x1 = p[b].x * scale_x + shift_x;
  1570. e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
  1571. ++n;
  1572. }
  1573. }
  1574. // now sort the edges by their highest point (should snap to integer, and then by x)
  1575. STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare);
  1576. // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule
  1577. stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
  1578. STBTT_free(e, userdata);
  1579. }
  1580. static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
  1581. {
  1582. if (!points) return; // during first pass, it's unallocated
  1583. points[n].x = x;
  1584. points[n].y = y;
  1585. }
  1586. // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
  1587. static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
  1588. {
  1589. // midpoint
  1590. float mx = (x0 + 2*x1 + x2)/4;
  1591. float my = (y0 + 2*y1 + y2)/4;
  1592. // versus directly drawn line
  1593. float dx = (x0+x2)/2 - mx;
  1594. float dy = (y0+y2)/2 - my;
  1595. if (n > 16) // 65536 segments on one curve better be enough!
  1596. return 1;
  1597. if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA
  1598. stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1);
  1599. stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1);
  1600. } else {
  1601. stbtt__add_point(points, *num_points,x2,y2);
  1602. *num_points = *num_points+1;
  1603. }
  1604. return 1;
  1605. }
  1606. // returns number of contours
  1607. static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata)
  1608. {
  1609. stbtt__point *points=0;
  1610. int num_points=0;
  1611. float objspace_flatness_squared = objspace_flatness * objspace_flatness;
  1612. int i,n=0,start=0, pass;
  1613. // count how many "moves" there are to get the contour count
  1614. for (i=0; i < num_verts; ++i)
  1615. if (vertices[i].type == STBTT_vmove)
  1616. ++n;
  1617. *num_contours = n;
  1618. if (n == 0) return 0;
  1619. *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata);
  1620. if (*contour_lengths == 0) {
  1621. *num_contours = 0;
  1622. return 0;
  1623. }
  1624. // make two passes through the points so we don't need to realloc
  1625. for (pass=0; pass < 2; ++pass) {
  1626. float x=0,y=0;
  1627. if (pass == 1) {
  1628. points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata);
  1629. if (points == NULL) goto error;
  1630. }
  1631. num_points = 0;
  1632. n= -1;
  1633. for (i=0; i < num_verts; ++i) {
  1634. switch (vertices[i].type) {
  1635. case STBTT_vmove:
  1636. // start the next contour
  1637. if (n >= 0)
  1638. (*contour_lengths)[n] = num_points - start;
  1639. ++n;
  1640. start = num_points;
  1641. x = vertices[i].x, y = vertices[i].y;
  1642. stbtt__add_point(points, num_points++, x,y);
  1643. break;
  1644. case STBTT_vline:
  1645. x = vertices[i].x, y = vertices[i].y;
  1646. stbtt__add_point(points, num_points++, x, y);
  1647. break;
  1648. case STBTT_vcurve:
  1649. stbtt__tesselate_curve(points, &num_points, x,y,
  1650. vertices[i].cx, vertices[i].cy,
  1651. vertices[i].x, vertices[i].y,
  1652. objspace_flatness_squared, 0);
  1653. x = vertices[i].x, y = vertices[i].y;
  1654. break;
  1655. }
  1656. }
  1657. (*contour_lengths)[n] = num_points - start;
  1658. }
  1659. return points;
  1660. error:
  1661. STBTT_free(points, userdata);
  1662. STBTT_free(*contour_lengths, userdata);
  1663. *contour_lengths = 0;
  1664. *num_contours = 0;
  1665. return NULL;
  1666. }
  1667. STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata)
  1668. {
  1669. float scale = scale_x > scale_y ? scale_y : scale_x;
  1670. int winding_count, *winding_lengths;
  1671. stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata);
  1672. if (windings) {
  1673. stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata);
  1674. STBTT_free(winding_lengths, userdata);
  1675. STBTT_free(windings, userdata);
  1676. }
  1677. }
  1678. STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata)
  1679. {
  1680. STBTT_free(bitmap, userdata);
  1681. }
  1682. STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff)
  1683. {
  1684. int ix0,iy0,ix1,iy1;
  1685. stbtt__bitmap gbm;
  1686. stbtt_vertex *vertices;
  1687. int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
  1688. if (scale_x == 0) scale_x = scale_y;
  1689. if (scale_y == 0) {
  1690. if (scale_x == 0) return NULL;
  1691. scale_y = scale_x;
  1692. }
  1693. stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
  1694. // now we get the size
  1695. gbm.w = (ix1 - ix0);
  1696. gbm.h = (iy1 - iy0);
  1697. gbm.pixels = NULL; // in case we error
  1698. if (width ) *width = gbm.w;
  1699. if (height) *height = gbm.h;
  1700. if (xoff ) *xoff = ix0;
  1701. if (yoff ) *yoff = iy0;
  1702. if (gbm.w && gbm.h) {
  1703. gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata);
  1704. if (gbm.pixels) {
  1705. gbm.stride = gbm.w;
  1706. stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata);
  1707. }
  1708. }
  1709. STBTT_free(vertices, info->userdata);
  1710. return gbm.pixels;
  1711. }
  1712. STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff)
  1713. {
  1714. return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff);
  1715. }
  1716. STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph)
  1717. {
  1718. int ix0,iy0;
  1719. stbtt_vertex *vertices;
  1720. int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices);
  1721. stbtt__bitmap gbm;
  1722. stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0);
  1723. gbm.pixels = output;
  1724. gbm.w = out_w;
  1725. gbm.h = out_h;
  1726. gbm.stride = out_stride;
  1727. if (gbm.w && gbm.h)
  1728. stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata);
  1729. STBTT_free(vertices, info->userdata);
  1730. }
  1731. STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph)
  1732. {
  1733. stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph);
  1734. }
  1735. STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
  1736. {
  1737. return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff);
  1738. }
  1739. STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint)
  1740. {
  1741. stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint));
  1742. }
  1743. STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff)
  1744. {
  1745. return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff);
  1746. }
  1747. STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint)
  1748. {
  1749. stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint);
  1750. }
  1751. //////////////////////////////////////////////////////////////////////////////
  1752. //
  1753. // bitmap baking
  1754. //
  1755. // This is SUPER-CRAPPY packing to keep source code small
  1756. STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf)
  1757. float pixel_height, // height of font in pixels
  1758. unsigned char *pixels, int pw, int ph, // bitmap to be filled in
  1759. int first_char, int num_chars, // characters to bake
  1760. stbtt_bakedchar *chardata)
  1761. {
  1762. float scale;
  1763. int x,y,bottom_y, i;
  1764. stbtt_fontinfo f;
  1765. if (!stbtt_InitFont(&f, data, offset))
  1766. return -1;
  1767. STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
  1768. x=y=1;
  1769. bottom_y = 1;
  1770. scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
  1771. for (i=0; i < num_chars; ++i) {
  1772. int advance, lsb, x0,y0,x1,y1,gw,gh;
  1773. int g = stbtt_FindGlyphIndex(&f, first_char + i);
  1774. stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
  1775. stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
  1776. gw = x1-x0;
  1777. gh = y1-y0;
  1778. if (x + gw + 1 >= pw)
  1779. y = bottom_y, x = 1; // advance to next row
  1780. if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
  1781. return -i;
  1782. STBTT_assert(x+gw < pw);
  1783. STBTT_assert(y+gh < ph);
  1784. stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
  1785. chardata[i].x0 = (stbtt_int16) x;
  1786. chardata[i].y0 = (stbtt_int16) y;
  1787. chardata[i].x1 = (stbtt_int16) (x + gw);
  1788. chardata[i].y1 = (stbtt_int16) (y + gh);
  1789. chardata[i].xadvance = scale * advance;
  1790. chardata[i].xoff = (float) x0;
  1791. chardata[i].yoff = (float) y0;
  1792. x = x + gw + 1;
  1793. if (y+gh+1 > bottom_y)
  1794. bottom_y = y+gh+1;
  1795. }
  1796. return bottom_y;
  1797. }
  1798. STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
  1799. {
  1800. float d3d_bias = opengl_fillrule ? 0 : -0.5f;
  1801. float ipw = 1.0f / pw, iph = 1.0f / ph;
  1802. stbtt_bakedchar *b = chardata + char_index;
  1803. int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5);
  1804. int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5);
  1805. q->x0 = round_x + d3d_bias;
  1806. q->y0 = round_y + d3d_bias;
  1807. q->x1 = round_x + b->x1 - b->x0 + d3d_bias;
  1808. q->y1 = round_y + b->y1 - b->y0 + d3d_bias;
  1809. q->s0 = b->x0 * ipw;
  1810. q->t0 = b->y0 * iph;
  1811. q->s1 = b->x1 * ipw;
  1812. q->t1 = b->y1 * iph;
  1813. *xpos += b->xadvance;
  1814. }
  1815. //////////////////////////////////////////////////////////////////////////////
  1816. //
  1817. // rectangle packing replacement routines if you don't have stb_rect_pack.h
  1818. //
  1819. #ifndef STB_RECT_PACK_VERSION
  1820. #ifdef _MSC_VER
  1821. #define STBTT__NOTUSED(v) (void)(v)
  1822. #else
  1823. #define STBTT__NOTUSED(v) (void)sizeof(v)
  1824. #endif
  1825. typedef int stbrp_coord;
  1826. ////////////////////////////////////////////////////////////////////////////////////
  1827. // //
  1828. // //
  1829. // COMPILER WARNING ?!?!? //
  1830. // //
  1831. // //
  1832. // if you get a compile warning due to these symbols being defined more than //
  1833. // once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" //
  1834. // //
  1835. ////////////////////////////////////////////////////////////////////////////////////
  1836. typedef struct
  1837. {
  1838. int width,height;
  1839. int x,y,bottom_y;
  1840. } stbrp_context;
  1841. typedef struct
  1842. {
  1843. unsigned char x;
  1844. } stbrp_node;
  1845. struct stbrp_rect
  1846. {
  1847. stbrp_coord x,y;
  1848. int id,w,h,was_packed;
  1849. };
  1850. static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
  1851. {
  1852. con->width = pw;
  1853. con->height = ph;
  1854. con->x = 0;
  1855. con->y = 0;
  1856. con->bottom_y = 0;
  1857. STBTT__NOTUSED(nodes);
  1858. STBTT__NOTUSED(num_nodes);
  1859. }
  1860. static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
  1861. {
  1862. int i;
  1863. for (i=0; i < num_rects; ++i) {
  1864. if (con->x + rects[i].w > con->width) {
  1865. con->x = 0;
  1866. con->y = con->bottom_y;
  1867. }
  1868. if (con->y + rects[i].h > con->height)
  1869. break;
  1870. rects[i].x = con->x;
  1871. rects[i].y = con->y;
  1872. rects[i].was_packed = 1;
  1873. con->x += rects[i].w;
  1874. if (con->y + rects[i].h > con->bottom_y)
  1875. con->bottom_y = con->y + rects[i].h;
  1876. }
  1877. for ( ; i < num_rects; ++i)
  1878. rects[i].was_packed = 0;
  1879. }
  1880. #endif
  1881. //////////////////////////////////////////////////////////////////////////////
  1882. //
  1883. // bitmap baking
  1884. //
  1885. // This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
  1886. // stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
  1887. STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
  1888. {
  1889. stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context);
  1890. int num_nodes = pw - padding;
  1891. stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context);
  1892. if (context == NULL || nodes == NULL) {
  1893. if (context != NULL) STBTT_free(context, alloc_context);
  1894. if (nodes != NULL) STBTT_free(nodes , alloc_context);
  1895. return 0;
  1896. }
  1897. spc->user_allocator_context = alloc_context;
  1898. spc->width = pw;
  1899. spc->height = ph;
  1900. spc->pixels = pixels;
  1901. spc->pack_info = context;
  1902. spc->nodes = nodes;
  1903. spc->padding = padding;
  1904. spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
  1905. spc->h_oversample = 1;
  1906. spc->v_oversample = 1;
  1907. stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
  1908. if (pixels)
  1909. STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
  1910. return 1;
  1911. }
  1912. STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc)
  1913. {
  1914. STBTT_free(spc->nodes , spc->user_allocator_context);
  1915. STBTT_free(spc->pack_info, spc->user_allocator_context);
  1916. }
  1917. STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
  1918. {
  1919. STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
  1920. STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
  1921. if (h_oversample <= STBTT_MAX_OVERSAMPLE)
  1922. spc->h_oversample = h_oversample;
  1923. if (v_oversample <= STBTT_MAX_OVERSAMPLE)
  1924. spc->v_oversample = v_oversample;
  1925. }
  1926. #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
  1927. static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
  1928. {
  1929. unsigned char buffer[STBTT_MAX_OVERSAMPLE];
  1930. int safe_w = w - kernel_width;
  1931. int j;
  1932. for (j=0; j < h; ++j) {
  1933. int i;
  1934. unsigned int total;
  1935. memset(buffer, 0, kernel_width);
  1936. total = 0;
  1937. // make kernel_width a constant in common cases so compiler can optimize out the divide
  1938. switch (kernel_width) {
  1939. case 2:
  1940. for (i=0; i <= safe_w; ++i) {
  1941. total += pixels[i] - buffer[i & STBTT__OVER_MASK];
  1942. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
  1943. pixels[i] = (unsigned char) (total / 2);
  1944. }
  1945. break;
  1946. case 3:
  1947. for (i=0; i <= safe_w; ++i) {
  1948. total += pixels[i] - buffer[i & STBTT__OVER_MASK];
  1949. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
  1950. pixels[i] = (unsigned char) (total / 3);
  1951. }
  1952. break;
  1953. case 4:
  1954. for (i=0; i <= safe_w; ++i) {
  1955. total += pixels[i] - buffer[i & STBTT__OVER_MASK];
  1956. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
  1957. pixels[i] = (unsigned char) (total / 4);
  1958. }
  1959. break;
  1960. default:
  1961. for (i=0; i <= safe_w; ++i) {
  1962. total += pixels[i] - buffer[i & STBTT__OVER_MASK];
  1963. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
  1964. pixels[i] = (unsigned char) (total / kernel_width);
  1965. }
  1966. break;
  1967. }
  1968. for (; i < w; ++i) {
  1969. STBTT_assert(pixels[i] == 0);
  1970. total -= buffer[i & STBTT__OVER_MASK];
  1971. pixels[i] = (unsigned char) (total / kernel_width);
  1972. }
  1973. pixels += stride_in_bytes;
  1974. }
  1975. }
  1976. static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
  1977. {
  1978. unsigned char buffer[STBTT_MAX_OVERSAMPLE];
  1979. int safe_h = h - kernel_width;
  1980. int j;
  1981. for (j=0; j < w; ++j) {
  1982. int i;
  1983. unsigned int total;
  1984. memset(buffer, 0, kernel_width);
  1985. total = 0;
  1986. // make kernel_width a constant in common cases so compiler can optimize out the divide
  1987. switch (kernel_width) {
  1988. case 2:
  1989. for (i=0; i <= safe_h; ++i) {
  1990. total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
  1991. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
  1992. pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
  1993. }
  1994. break;
  1995. case 3:
  1996. for (i=0; i <= safe_h; ++i) {
  1997. total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
  1998. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
  1999. pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
  2000. }
  2001. break;
  2002. case 4:
  2003. for (i=0; i <= safe_h; ++i) {
  2004. total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
  2005. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
  2006. pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
  2007. }
  2008. break;
  2009. default:
  2010. for (i=0; i <= safe_h; ++i) {
  2011. total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
  2012. buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
  2013. pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
  2014. }
  2015. break;
  2016. }
  2017. for (; i < h; ++i) {
  2018. STBTT_assert(pixels[i*stride_in_bytes] == 0);
  2019. total -= buffer[i & STBTT__OVER_MASK];
  2020. pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
  2021. }
  2022. pixels += 1;
  2023. }
  2024. }
  2025. static float stbtt__oversample_shift(int oversample)
  2026. {
  2027. if (!oversample)
  2028. return 0.0f;
  2029. // The prefilter is a box filter of width "oversample",
  2030. // which shifts phase by (oversample - 1)/2 pixels in
  2031. // oversampled space. We want to shift in the opposite
  2032. // direction to counter this.
  2033. return (float)-(oversample - 1) / (2.0f * (float)oversample);
  2034. }
  2035. // rects array must be big enough to accommodate all characters in the given ranges
  2036. STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
  2037. {
  2038. int i,j,k;
  2039. k=0;
  2040. for (i=0; i < num_ranges; ++i) {
  2041. float fh = ranges[i].font_size;
  2042. float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
  2043. for (j=0; j < ranges[i].num_chars_in_range; ++j) {
  2044. int x0,y0,x1,y1;
  2045. int glyph = stbtt_FindGlyphIndex(info,ranges[i].first_unicode_char_in_range + j);
  2046. if (glyph) {
  2047. stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
  2048. scale * spc->h_oversample,
  2049. scale * spc->v_oversample,
  2050. 0,0,
  2051. &x0,&y0,&x1,&y1);
  2052. rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
  2053. rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
  2054. } else {
  2055. rects[k].w = rects[k].h = 1;
  2056. }
  2057. ++k;
  2058. }
  2059. }
  2060. return k;
  2061. }
  2062. // rects array must be big enough to accommodate all characters in the given ranges
  2063. STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
  2064. {
  2065. float recip_h = 1.0f / spc->h_oversample;
  2066. float recip_v = 1.0f / spc->v_oversample;
  2067. float sub_x = stbtt__oversample_shift(spc->h_oversample);
  2068. float sub_y = stbtt__oversample_shift(spc->v_oversample);
  2069. int i,j,k, return_value = 1;
  2070. k = 0;
  2071. for (i=0; i < num_ranges; ++i) {
  2072. float fh = ranges[i].font_size;
  2073. float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh);
  2074. for (j=0; j < ranges[i].num_chars_in_range; ++j) {
  2075. stbrp_rect *r = &rects[k];
  2076. if (r->was_packed) {
  2077. stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
  2078. int advance, lsb, x0,y0,x1,y1;
  2079. int glyph = stbtt_FindGlyphIndex(info, ranges[i].first_unicode_char_in_range + j);
  2080. stbrp_coord pad = (stbrp_coord) spc->padding;
  2081. // pad on left and top
  2082. r->x += pad;
  2083. r->y += pad;
  2084. r->w -= pad;
  2085. r->h -= pad;
  2086. stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb);
  2087. stbtt_GetGlyphBitmapBox(info, glyph,
  2088. scale * spc->h_oversample,
  2089. scale * spc->v_oversample,
  2090. &x0,&y0,&x1,&y1);
  2091. stbtt_MakeGlyphBitmapSubpixel(info,
  2092. spc->pixels + r->x + r->y*spc->stride_in_bytes,
  2093. r->w - spc->h_oversample+1,
  2094. r->h - spc->v_oversample+1,
  2095. spc->stride_in_bytes,
  2096. scale * spc->h_oversample,
  2097. scale * spc->v_oversample,
  2098. 0,0,
  2099. glyph);
  2100. if (spc->h_oversample > 1)
  2101. stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
  2102. r->w, r->h, spc->stride_in_bytes,
  2103. spc->h_oversample);
  2104. if (spc->v_oversample > 1)
  2105. stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
  2106. r->w, r->h, spc->stride_in_bytes,
  2107. spc->v_oversample);
  2108. bc->x0 = (stbtt_int16) r->x;
  2109. bc->y0 = (stbtt_int16) r->y;
  2110. bc->x1 = (stbtt_int16) (r->x + r->w);
  2111. bc->y1 = (stbtt_int16) (r->y + r->h);
  2112. bc->xadvance = scale * advance;
  2113. bc->xoff = (float) x0 * recip_h + sub_x;
  2114. bc->yoff = (float) y0 * recip_v + sub_y;
  2115. bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
  2116. bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
  2117. } else {
  2118. return_value = 0; // if any fail, report failure
  2119. }
  2120. ++k;
  2121. }
  2122. }
  2123. return return_value;
  2124. }
  2125. STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
  2126. {
  2127. stbtt_fontinfo info;
  2128. int i,j,n, return_value = 1;
  2129. stbrp_context *context = (stbrp_context *) spc->pack_info;
  2130. stbrp_rect *rects;
  2131. // flag all characters as NOT packed
  2132. for (i=0; i < num_ranges; ++i)
  2133. for (j=0; j < ranges[i].num_chars_in_range; ++j)
  2134. ranges[i].chardata_for_range[j].x0 =
  2135. ranges[i].chardata_for_range[j].y0 =
  2136. ranges[i].chardata_for_range[j].x1 =
  2137. ranges[i].chardata_for_range[j].y1 = 0;
  2138. n = 0;
  2139. for (i=0; i < num_ranges; ++i)
  2140. n += ranges[i].num_chars_in_range;
  2141. rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
  2142. if (rects == NULL)
  2143. return 0;
  2144. stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
  2145. n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
  2146. stbrp_pack_rects(context, rects, n);
  2147. return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects);
  2148. return return_value;
  2149. }
  2150. STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
  2151. int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
  2152. {
  2153. stbtt_pack_range range;
  2154. range.first_unicode_char_in_range = first_unicode_char_in_range;
  2155. range.num_chars_in_range = num_chars_in_range;
  2156. range.chardata_for_range = chardata_for_range;
  2157. range.font_size = font_size;
  2158. return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
  2159. }
  2160. STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
  2161. {
  2162. float ipw = 1.0f / pw, iph = 1.0f / ph;
  2163. stbtt_packedchar *b = chardata + char_index;
  2164. if (align_to_integer) {
  2165. float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5);
  2166. float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5);
  2167. q->x0 = x;
  2168. q->y0 = y;
  2169. q->x1 = x + b->xoff2 - b->xoff;
  2170. q->y1 = y + b->yoff2 - b->yoff;
  2171. } else {
  2172. q->x0 = *xpos + b->xoff;
  2173. q->y0 = *ypos + b->yoff;
  2174. q->x1 = *xpos + b->xoff2;
  2175. q->y1 = *ypos + b->yoff2;
  2176. }
  2177. q->s0 = b->x0 * ipw;
  2178. q->t0 = b->y0 * iph;
  2179. q->s1 = b->x1 * ipw;
  2180. q->t1 = b->y1 * iph;
  2181. *xpos += b->xadvance;
  2182. }
  2183. //////////////////////////////////////////////////////////////////////////////
  2184. //
  2185. // font name matching -- recommended not to use this
  2186. //
  2187. // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string
  2188. static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2)
  2189. {
  2190. stbtt_int32 i=0;
  2191. // convert utf16 to utf8 and compare the results while converting
  2192. while (len2) {
  2193. stbtt_uint16 ch = s2[0]*256 + s2[1];
  2194. if (ch < 0x80) {
  2195. if (i >= len1) return -1;
  2196. if (s1[i++] != ch) return -1;
  2197. } else if (ch < 0x800) {
  2198. if (i+1 >= len1) return -1;
  2199. if (s1[i++] != 0xc0 + (ch >> 6)) return -1;
  2200. if (s1[i++] != 0x80 + (ch & 0x3f)) return -1;
  2201. } else if (ch >= 0xd800 && ch < 0xdc00) {
  2202. stbtt_uint32 c;
  2203. stbtt_uint16 ch2 = s2[2]*256 + s2[3];
  2204. if (i+3 >= len1) return -1;
  2205. c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000;
  2206. if (s1[i++] != 0xf0 + (c >> 18)) return -1;
  2207. if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1;
  2208. if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1;
  2209. if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1;
  2210. s2 += 2; // plus another 2 below
  2211. len2 -= 2;
  2212. } else if (ch >= 0xdc00 && ch < 0xe000) {
  2213. return -1;
  2214. } else {
  2215. if (i+2 >= len1) return -1;
  2216. if (s1[i++] != 0xe0 + (ch >> 12)) return -1;
  2217. if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1;
  2218. if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1;
  2219. }
  2220. s2 += 2;
  2221. len2 -= 2;
  2222. }
  2223. return i;
  2224. }
  2225. STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2)
  2226. {
  2227. return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2);
  2228. }
  2229. // returns results in whatever encoding you request... but note that 2-byte encodings
  2230. // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare
  2231. STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID)
  2232. {
  2233. stbtt_int32 i,count,stringOffset;
  2234. stbtt_uint8 *fc = font->data;
  2235. stbtt_uint32 offset = font->fontstart;
  2236. stbtt_uint32 nm = stbtt__find_table(fc, offset, "name");
  2237. if (!nm) return NULL;
  2238. count = ttUSHORT(fc+nm+2);
  2239. stringOffset = nm + ttUSHORT(fc+nm+4);
  2240. for (i=0; i < count; ++i) {
  2241. stbtt_uint32 loc = nm + 6 + 12 * i;
  2242. if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2)
  2243. && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) {
  2244. *length = ttUSHORT(fc+loc+8);
  2245. return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10));
  2246. }
  2247. }
  2248. return NULL;
  2249. }
  2250. static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id)
  2251. {
  2252. stbtt_int32 i;
  2253. stbtt_int32 count = ttUSHORT(fc+nm+2);
  2254. stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4);
  2255. for (i=0; i < count; ++i) {
  2256. stbtt_uint32 loc = nm + 6 + 12 * i;
  2257. stbtt_int32 id = ttUSHORT(fc+loc+6);
  2258. if (id == target_id) {
  2259. // find the encoding
  2260. stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
  2261. // is this a Unicode encoding?
  2262. if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
  2263. stbtt_int32 slen = ttUSHORT(fc+loc+8);
  2264. stbtt_int32 off = ttUSHORT(fc+loc+10);
  2265. // check if there's a prefix match
  2266. stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
  2267. if (matchlen >= 0) {
  2268. // check for target_id+1 immediately following, with same encoding & language
  2269. 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) {
  2270. slen = ttUSHORT(fc+loc+12+8);
  2271. off = ttUSHORT(fc+loc+12+10);
  2272. if (slen == 0) {
  2273. if (matchlen == nlen)
  2274. return 1;
  2275. } else if (matchlen < nlen && name[matchlen] == ' ') {
  2276. ++matchlen;
  2277. if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen))
  2278. return 1;
  2279. }
  2280. } else {
  2281. // if nothing immediately following
  2282. if (matchlen == nlen)
  2283. return 1;
  2284. }
  2285. }
  2286. }
  2287. // @TODO handle other encodings
  2288. }
  2289. }
  2290. return 0;
  2291. }
  2292. static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags)
  2293. {
  2294. stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name);
  2295. stbtt_uint32 nm,hd;
  2296. if (!stbtt__isfont(fc+offset)) return 0;
  2297. // check italics/bold/underline flags in macStyle...
  2298. if (flags) {
  2299. hd = stbtt__find_table(fc, offset, "head");
  2300. if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0;
  2301. }
  2302. nm = stbtt__find_table(fc, offset, "name");
  2303. if (!nm) return 0;
  2304. if (flags) {
  2305. // if we checked the macStyle flags, then just check the family and ignore the subfamily
  2306. if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1;
  2307. if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1;
  2308. if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
  2309. } else {
  2310. if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1;
  2311. if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1;
  2312. if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1;
  2313. }
  2314. return 0;
  2315. }
  2316. STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags)
  2317. {
  2318. stbtt_int32 i;
  2319. for (i=0;;++i) {
  2320. stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i);
  2321. if (off < 0) return off;
  2322. if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags))
  2323. return off;
  2324. }
  2325. }
  2326. #endif // STB_TRUETYPE_IMPLEMENTATION