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

stb_truetype.h 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. //