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

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