Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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