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 100KB

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