Subversion Repositories Kolibri OS

Rev

Rev 3002 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3002 Rev 5517
Line 1... Line 1...
1
// stb_truetype.h - v0.6c - public domain
1
// stb_truetype.h - v1.02 - public domain
2
// authored from 2009-2012 by Sean Barrett / RAD Game Tools
2
// authored from 2009-2014 by Sean Barrett / RAD Game Tools
3
//
3
//
4
//   This library processes TrueType files:
4
//   This library processes TrueType files:
5
//        parse files
5
//        parse files
6
//        extract glyph metrics
6
//        extract glyph metrics
7
//        extract glyph shapes
7
//        extract glyph shapes
Line 19... Line 19...
19
// ADDITIONAL CONTRIBUTORS
19
// ADDITIONAL CONTRIBUTORS
20
//
20
//
21
//   Mikko Mononen: compound shape support, more cmap formats
21
//   Mikko Mononen: compound shape support, more cmap formats
22
//   Tor Andersson: kerning, subpixel rendering
22
//   Tor Andersson: kerning, subpixel rendering
23
//
23
//
24
//   Bug/warning reports:
24
//   Bug/warning reports/fixes:
25
//       "Zer" on mollyrocket (with fix)
25
//       "Zer" on mollyrocket (with fix)
26
//       Cass Everitt
26
//       Cass Everitt
27
//       stoiko (Haemimont Games)
27
//       stoiko (Haemimont Games)
28
//       Brian Hook 
28
//       Brian Hook 
29
//       Walter van Niftrik
29
//       Walter van Niftrik
-
 
30
//       David Gow
-
 
31
//       David Given
-
 
32
//       Ivan-Assen Ivanov
-
 
33
//       Anthony Pesch
-
 
34
//       Johan Duparc
-
 
35
//       Hou Qiming
-
 
36
//       Fabian "ryg" Giesen
-
 
37
//
-
 
38
//   Misc other:
-
 
39
//       Ryan Gordon
30
//
40
//
31
// VERSION HISTORY
41
// VERSION HISTORY
32
//
42
//
-
 
43
//   1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++
-
 
44
//   1.01 (2014-12-08) fix subpixel position when oversampling to exactly match
-
 
45
//                        non-oversampled; STBTT_POINT_SIZE for packed case only
-
 
46
//   1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling
-
 
47
//   0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg)
-
 
48
//   0.9  (2014-08-07) support certain mac/iOS fonts without an MS platformID
-
 
49
//   0.8b (2014-07-07) fix a warning
-
 
50
//   0.8  (2014-05-25) fix a few more warnings
-
 
51
//   0.7  (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back
33
//   0.6c (2012-07-24) improve documentation
52
//   0.6c (2012-07-24) improve documentation
34
//   0.6b (2012-07-20) fix a few more warnings
53
//   0.6b (2012-07-20) fix a few more warnings
35
//   0.6  (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
54
//   0.6  (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels,
36
//                        stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
55
//                        stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty
37
//   0.5 (2011-12-09) bugfixes:
56
//   0.5  (2011-12-09) bugfixes:
Line 44... Line 63...
44
//                        codepoint-to-glyph conversion using table fmt=4
63
//                        codepoint-to-glyph conversion using table fmt=4
45
//                        stbtt_GetBakedQuad with non-square texture (Zer)
64
//                        stbtt_GetBakedQuad with non-square texture (Zer)
46
//                    updated Hello World! sample to use kerning and subpixel
65
//                    updated Hello World! sample to use kerning and subpixel
47
//                    fixed some warnings
66
//                    fixed some warnings
48
//   0.3 (2009-06-24) cmap fmt=12, compound shapes (MM)
67
//   0.3  (2009-06-24) cmap fmt=12, compound shapes (MM)
49
//                    userdata, malloc-from-userdata, non-zero fill (STB)
68
//                    userdata, malloc-from-userdata, non-zero fill (stb)
50
//   0.2 (2009-03-11) Fix unsigned/signed char warnings
69
//   0.2  (2009-03-11) Fix unsigned/signed char warnings
51
//   0.1 (2009-03-09) First public release
70
//   0.1  (2009-03-09) First public release
52
//
71
//
53
// LICENSE
72
// LICENSE
54
//
73
//
Line 62... Line 81...
62
//   file, write:
81
//   file, write:
63
//      #define STB_TRUETYPE_IMPLEMENTATION
82
//      #define STB_TRUETYPE_IMPLEMENTATION
64
//   before the #include of this file. This expands out the actual
83
//   before the #include of this file. This expands out the actual
65
//   implementation into that C/C++ file.
84
//   implementation into that C/C++ file.
66
//
85
//
67
//   Look at the header-file sections below for the API, but here's a quick skim:
-
 
68
//
-
 
69
//   Simple 3D API (don't ship this, but it's fine for tools and quick start,
86
//   Simple 3D API (don't ship this, but it's fine for tools and quick start)
70
//                  and you can cut and paste from it to move to more advanced)
-
 
71
//           stbtt_BakeFontBitmap()               -- bake a font to a bitmap for use as texture
87
//           stbtt_BakeFontBitmap()               -- bake a font to a bitmap for use as texture
72
//           stbtt_GetBakedQuad()                 -- compute quad to draw for a given char
88
//           stbtt_GetBakedQuad()                 -- compute quad to draw for a given char
73
//
89
//
-
 
90
//   Improved 3D API (more shippable):
-
 
91
//           #include "stb_rect_pack.h"           -- optional, but you really want it
-
 
92
//           stbtt_PackBegin()
-
 
93
//           stbtt_PackSetOversample()            -- for improved quality on small fonts
-
 
94
//           stbtt_PackFontRanges()
-
 
95
//           stbtt_PackEnd()
-
 
96
//           stbtt_GetPackedQuad()
-
 
97
//
74
//   "Load" a font file from a memory buffer (you have to keep the buffer loaded)
98
//   "Load" a font file from a memory buffer (you have to keep the buffer loaded)
75
//           stbtt_InitFont()
99
//           stbtt_InitFont()
76
//           stbtt_GetFontOffsetForIndex()        -- use for TTC font collections
100
//           stbtt_GetFontOffsetForIndex()        -- use for TTC font collections
77
//
101
//
78
//   Render a unicode codepoint to a bitmap
102
//   Render a unicode codepoint to a bitmap
Line 222... Line 246...
222
   glBindTexture(GL_TEXTURE_2D, ftex);
246
   glBindTexture(GL_TEXTURE_2D, ftex);
223
   glBegin(GL_QUADS);
247
   glBegin(GL_QUADS);
224
   while (*text) {
248
   while (*text) {
225
      if (*text >= 32 && *text < 128) {
249
      if (*text >= 32 && *text < 128) {
226
         stbtt_aligned_quad q;
250
         stbtt_aligned_quad q;
227
         stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl,0=old d3d
251
         stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9
228
         glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
252
         glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0);
229
         glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
253
         glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0);
230
         glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
254
         glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1);
231
         glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
255
         glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1);
232
      }
256
      }
Line 291... Line 315...
291
 
315
 
292
int main(int arg, char **argv)
316
int main(int arg, char **argv)
293
{
317
{
294
   stbtt_fontinfo font;
318
   stbtt_fontinfo font;
295
   int i,j,ascent,baseline,ch=0;
319
   int i,j,ascent,baseline,ch=0;
296
   float scale, xpos=0;
320
   float scale, xpos=2; // leave a little padding in case the character extends left
Line 297... Line 321...
297
   char *text = "Heljo World!";
321
   char *text = "Heljo World!";
298
 
322
 
Line 337... Line 361...
337
////
361
////
338
////   The following sections allow you to supply alternate definitions
362
////   The following sections allow you to supply alternate definitions
339
////   of C library functions used by stb_truetype.
363
////   of C library functions used by stb_truetype.
Line 340... Line 364...
340
 
364
 
341
#ifdef STB_TRUETYPE_IMPLEMENTATION
-
 
342
 
-
 
343
#define NULL 0
-
 
344
typedef unsigned int size_t;
365
#ifdef STB_TRUETYPE_IMPLEMENTATION
345
   // #define your own (u)stbtt_int8/16/32 before including to override this
366
   // #define your own (u)stbtt_int8/16/32 before including to override this
346
   #ifndef stbtt_uint8
367
   #ifndef stbtt_uint8
347
   typedef unsigned char   stbtt_uint8;
368
   typedef unsigned char   stbtt_uint8;
348
   typedef signed   char   stbtt_int8;
369
   typedef signed   char   stbtt_int8;
Line 353... Line 374...
353
   #endif
374
   #endif
Line 354... Line 375...
354
 
375
 
355
   typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
376
   typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
Line 356... Line -...
356
   typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
-
 
357
 
-
 
358
 
-
 
359
 
-
 
360
#define		THRESH		4		/* threshold for insertion */
-
 
361
#define		MTHRESH		6		/* threshold for median */
-
 
362
 
-
 
363
static  int		(*qcmp)(const void *, const void *);		/* the comparison routine */
-
 
364
static  int		qsz;			/* size of each record */
-
 
365
static  int		thresh;			/* THRESHold in chars */
-
 
366
static  int		mthresh;		/* MTHRESHold in chars */
-
 
367
 
-
 
368
/*
-
 
369
 * qst:
-
 
370
 * Do a quicksort
-
 
371
 * First, find the median element, and put that one in the first place as the
-
 
372
 * discriminator.  (This "median" is just the median of the first, last and
-
 
373
 * middle elements).  (Using this median instead of the first element is a big
-
 
374
 * win).  Then, the usual partitioning/swapping, followed by moving the
-
 
375
 * discriminator into the right place.  Then, figure out the sizes of the two
-
 
376
 * partions, do the smaller one recursively and the larger one via a repeat of
-
 
377
 * this code.  Stopping when there are less than THRESH elements in a partition
-
 
378
 * and cleaning up with an insertion sort (in our caller) is a huge win.
-
 
379
 * All data swaps are done in-line, which is space-losing but time-saving.
-
 
380
 * (And there are only three places where this is done).
-
 
381
 */
-
 
382
 
-
 
383
static void
-
 
384
qst(char *base, char *max)
-
 
385
{
-
 
386
  char c, *i, *j, *jj;
-
 
387
  int ii;
-
 
388
  char *mid, *tmp;
-
 
389
  int lo, hi;
-
 
390
 
-
 
391
  /*
-
 
392
   * At the top here, lo is the number of characters of elements in the
-
 
393
   * current partition.  (Which should be max - base).
-
 
394
   * Find the median of the first, last, and middle element and make
-
 
395
   * that the middle element.  Set j to largest of first and middle.
-
 
396
   * If max is larger than that guy, then it's that guy, else compare
-
 
397
   * max with loser of first and take larger.  Things are set up to
-
 
398
   * prefer the middle, then the first in case of ties.
-
 
399
   */
-
 
400
  lo = max - base;		/* number of elements as chars */
-
 
401
  do	{
-
 
402
    mid = i = base + qsz * ((lo / qsz) >> 1);
-
 
403
    if (lo >= mthresh)
-
 
404
    {
-
 
405
      j = (qcmp((jj = base), i) > 0 ? jj : i);
-
 
406
      if (qcmp(j, (tmp = max - qsz)) > 0)
-
 
407
      {
-
 
408
	/* switch to first loser */
-
 
409
	j = (j == jj ? i : jj);
-
 
410
	if (qcmp(j, tmp) < 0)
-
 
411
	  j = tmp;
-
 
412
      }
-
 
413
      if (j != i)
-
 
414
      {
-
 
415
	ii = qsz;
-
 
416
	do	{
-
 
417
	  c = *i;
-
 
418
	  *i++ = *j;
-
 
419
	  *j++ = c;
-
 
420
	} while (--ii);
-
 
421
      }
-
 
422
    }
-
 
423
    /*
-
 
424
     * Semi-standard quicksort partitioning/swapping
-
 
425
     */
-
 
426
    for (i = base, j = max - qsz; ; )
-
 
427
    {
-
 
428
      while (i < mid && qcmp(i, mid) <= 0)
-
 
429
	i += qsz;
-
 
430
      while (j > mid)
-
 
431
      {
-
 
432
	if (qcmp(mid, j) <= 0)
-
 
433
	{
-
 
434
	  j -= qsz;
-
 
435
	  continue;
-
 
436
	}
-
 
437
	tmp = i + qsz;		/* value of i after swap */
-
 
438
	if (i == mid)
-
 
439
	{
-
 
440
	  /* j <-> mid, new mid is j */
-
 
441
	  mid = jj = j;
-
 
442
	}
-
 
443
	else
-
 
444
	{
-
 
445
	  /* i <-> j */
-
 
446
	  jj = j;
-
 
447
	  j -= qsz;
-
 
448
	}
-
 
449
	goto swap;
-
 
450
      }
-
 
451
      if (i == mid)
-
 
452
      {
-
 
453
	break;
-
 
454
      }
-
 
455
      else
-
 
456
      {
-
 
457
	/* i <-> mid, new mid is i */
-
 
458
	jj = mid;
-
 
459
	tmp = mid = i;		/* value of i after swap */
-
 
460
	j -= qsz;
-
 
461
      }
-
 
462
    swap:
-
 
463
      ii = qsz;
-
 
464
      do	{
-
 
465
	c = *i;
-
 
466
	*i++ = *jj;
-
 
467
	*jj++ = c;
-
 
468
      } while (--ii);
-
 
469
      i = tmp;
-
 
470
    }
-
 
471
    /*
-
 
472
     * Look at sizes of the two partitions, do the smaller
-
 
473
     * one first by recursion, then do the larger one by
-
 
474
     * making sure lo is its size, base and max are update
-
 
475
     * correctly, and branching back.  But only repeat
-
 
476
     * (recursively or by branching) if the partition is
-
 
477
     * of at least size THRESH.
-
 
478
     */
-
 
479
    i = (j = mid) + qsz;
-
 
480
    if ((lo = j - base) <= (hi = max - i))
-
 
481
    {
-
 
482
      if (lo >= thresh)
-
 
483
	qst(base, j);
-
 
484
      base = i;
-
 
485
      lo = hi;
-
 
486
    }
-
 
487
    else
-
 
488
    {
-
 
489
      if (hi >= thresh)
-
 
490
	qst(i, max);
-
 
491
      max = j;
-
 
492
    }
-
 
493
  } while (lo >= thresh);
-
 
494
}
-
 
495
 
-
 
496
/*
-
 
497
 * qsort:
-
 
498
 * First, set up some global parameters for qst to share.  Then, quicksort
-
 
499
 * with qst(), and then a cleanup insertion sort ourselves.  Sound simple?
-
 
500
 * It's not...
-
 
501
 */
-
 
502
 
-
 
503
void
-
 
504
qsort_g(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *))
-
 
505
{
-
 
506
  char *base = (char *)base0;
-
 
507
  char c, *i, *j, *lo, *hi;
-
 
508
  char *min, *max;
-
 
509
 
-
 
510
  if (n <= 1)
-
 
511
    return;
-
 
512
  qsz = size;
-
 
513
  qcmp = compar;
-
 
514
  thresh = qsz * THRESH;
-
 
515
  mthresh = qsz * MTHRESH;
-
 
516
  max = base + n * qsz;
-
 
517
  if (n >= THRESH)
-
 
518
  {
-
 
519
    qst(base, max);
-
 
520
    hi = base + thresh;
-
 
521
  }
-
 
522
  else
-
 
523
  {
-
 
524
    hi = max;
-
 
525
  }
-
 
526
  /*
-
 
527
   * First put smallest element, which must be in the first THRESH, in
-
 
528
   * the first position as a sentinel.  This is done just by searching
-
 
529
   * the first THRESH elements (or the first n if n < THRESH), finding
-
 
530
   * the min, and swapping it into the first position.
-
 
531
   */
-
 
532
  for (j = lo = base; (lo += qsz) < hi; )
-
 
533
    if (qcmp(j, lo) > 0)
-
 
534
      j = lo;
-
 
535
  if (j != base)
-
 
536
  {
-
 
537
    /* swap j into place */
-
 
538
    for (i = base, hi = base + qsz; i < hi; )
-
 
539
    {
-
 
540
      c = *j;
-
 
541
      *j++ = *i;
-
 
542
      *i++ = c;
-
 
543
    }
-
 
544
  }
-
 
545
  /*
-
 
546
   * With our sentinel in place, we now run the following hyper-fast
-
 
547
   * insertion sort.  For each remaining element, min, from [1] to [n-1],
-
 
548
   * set hi to the index of the element AFTER which this one goes.
-
 
549
   * Then, do the standard insertion sort shift on a character at a time
-
 
550
   * basis for each element in the frob.
-
 
551
   */
-
 
552
  for (min = base; (hi = min += qsz) < max; )
-
 
553
  {
-
 
554
    while (qcmp(hi -= qsz, min) > 0)
-
 
555
      /* void */;
-
 
556
    if ((hi += qsz) != min) {
-
 
557
      for (lo = min + qsz; --lo >= min; )
-
 
558
      {
-
 
559
	c = *lo;
-
 
560
	for (i = j = lo; (j -= qsz) >= hi; i = j)
-
 
561
	  *i = *j;
-
 
562
	*i = c;
-
 
563
      }
-
 
564
    }
-
 
565
  }
-
 
566
}
-
 
567
 
377
   typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
568
 
378
 
569
   // #define your own STBTT_sort() to override this to avoid qsort
379
   // #define your own STBTT_sort() to override this to avoid qsort
570
   #ifndef STBTT_sort
380
   #ifndef STBTT_sort
571
   //#include 
381
   #include 
Line 572... Line -...
572
   #define STBTT_sort(data,num_items,item_size,compare_func)   qsort_g(data,num_items,item_size,compare_func)
-
 
573
   #endif
-
 
574
 
-
 
575
asm ("_floor: \n\t"
-
 
576
	"pushl	%ebp\n\t"
-
 
577
	"movl	%esp,%ebp\n\t"
-
 
578
	"subl	$8,%esp\n\t"      
-
 
579
	"fstcw	-4(%ebp)\n\t"
-
 
580
	"fwait\n\t"
-
 
581
	"movw	-4(%ebp),%ax\n\t"
-
 
582
	"andw	$0xf3ff,%ax\n\t"
-
 
583
	"orw	$0x0400,%ax\n\t"
-
 
584
	"movw	%ax,-2(%ebp)\n\t"
-
 
585
	"fldcw	-2(%ebp)\n\t"
-
 
586
	"fldl	8(%ebp)\n\t"
-
 
587
	"frndint\n\t"
-
 
588
	"fldcw	-4(%ebp)\n\t"
-
 
589
	"movl	%ebp,%esp\n\t"
-
 
590
	"popl	%ebp\n\t"
-
 
591
	"ret");
-
 
592
 
-
 
593
 
-
 
594
int i_floor (float x) {
-
 
595
	int z;
-
 
596
	z=x;
-
 
597
	if (z+1>x) {return z;} else {return (z+1);}
-
 
598
	
-
 
599
}
-
 
600
 
-
 
601
int i_ceil (float x) {
-
 
602
	int z;
-
 
603
	z=x;
-
 
604
	if (z>x) {return z;} else {return (z+1);}
-
 
605
	
-
 
606
}
-
 
607
	
-
 
608
	
-
 
609
double
-
 
610
sqrt (double x)
-
 
611
{
-
 
612
  if (x < 0.0F )
-
 
613
    {
-
 
614
      return -1;
-
 
615
    }
-
 
616
  else
-
 
617
    {
-
 
618
      double res;
-
 
619
      asm ("fsqrt" : "=t" (res) : "0" (x));
-
 
620
      return res;
-
 
621
    }
382
   #define STBTT_sort(data,num_items,item_size,compare_func)   qsort(data,num_items,item_size,compare_func)
622
}
383
   #endif
623
 
384
 
624
   // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
385
   // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
625
   #ifndef STBTT_ifloor
386
   #ifndef STBTT_ifloor
626
  // #include 
387
   #include 
Line 627... Line -...
627
   #define STBTT_ifloor(x)   ((int) i_floor(x))
-
 
628
   #define STBTT_iceil(x)    ((int) i_ceil(x))
-
 
629
   #endif
388
   #define STBTT_ifloor(x)   ((int) floor(x))
630
 
-
 
631
static inline void *zmalloc(size_t size) { 
-
 
632
	void *val; __asm__ __volatile__( "int $0x40" :"=a"(val) :"a"(68),"b"(12),"c"(size));
389
   #define STBTT_iceil(x)    ((int) ceil(x))
633
	 return val; }
-
 
634
 
390
   #endif
635
 
391
 
Line 636... Line 392...
636
void zfree(void *p)
392
   #ifndef STBTT_sqrt
637
{
393
   #include 
638
asm ("int $0x40"::"a"(68), "b"(13), "c"(p) );
394
   #define STBTT_sqrt(x)      sqrt(x)
639
}
395
   #endif
640
 
396
 
641
   // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
397
   // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
Line 642... Line -...
642
   #ifndef STBTT_malloc
-
 
643
  //#include 
-
 
644
   #define STBTT_malloc(x,u)  zmalloc(x)
398
   #ifndef STBTT_malloc
645
   #define STBTT_free(x,u)    zfree(x)
399
   #include 
646
   #endif
400
   #define STBTT_malloc(x,u)  ((void)(u),malloc(x))
647
 
401
   #define STBTT_free(x,u)    ((void)(u),free(x))
Line 648... Line -...
648
#define assert_g(ignore)((void) 0)
-
 
649
 
-
 
650
   #ifndef STBTT_assert
-
 
651
   //#include 
-
 
652
   #define STBTT_assert(x)    assert_g(x)
-
 
653
   #endif
-
 
654
 
-
 
655
 
-
 
656
int strlen_g(const char* string)
-
 
657
{
-
 
658
	int i;
402
   #endif
659
	i=0;
403
 
660
	while (*string++) i++;
404
   #ifndef STBTT_assert
661
	return i;
405
   #include 
Line 662... Line -...
662
}
-
 
663
 
-
 
664
 
-
 
665
   #ifndef STBTT_strlen
-
 
666
   //#include 
-
 
667
   #define STBTT_strlen(x)    strlen_g(x)
-
 
668
   #endif
-
 
669
 
-
 
670
void*  zmemset(void *mem, int c, unsigned size)
-
 
671
{
-
 
672
unsigned i;
-
 
673
 
-
 
674
for ( i = 0; i < size; i++ )
-
 
675
	 *((char *)mem+i) = (char) c;
-
 
676
 
-
 
677
return 0;	
-
 
678
}
-
 
679
 
-
 
680
 
-
 
681
void* zmemcpy(void *dst, const void *src, unsigned size)
-
 
682
{
-
 
683
 
-
 
684
unsigned i;
406
   #define STBTT_assert(x)    assert(x)
685
 
407
   #endif
686
for ( i = 0; i < size; i++)
408
 
687
	*(char *)(dst+i) = *(char *)(src+i);
409
   #ifndef STBTT_strlen
688
 
410
   #include 
689
return 0;
411
   #define STBTT_strlen(x)    strlen(x)
Line 690... Line 412...
690
}
412
   #endif
691
 
413
 
Line 753... Line 475...
753
// see discussion of "BASELINE" above.
475
// see discussion of "BASELINE" above.
754
//
476
//
755
// It's inefficient; you might want to c&p it and optimize it.
477
// It's inefficient; you might want to c&p it and optimize it.
Line -... Line 478...
-
 
478
 
-
 
479
 
-
 
480
 
-
 
481
//////////////////////////////////////////////////////////////////////////////
-
 
482
//
-
 
483
// NEW TEXTURE BAKING API
-
 
484
//
-
 
485
// This provides options for packing multiple fonts into one atlas, not
-
 
486
// perfectly but better than nothing.
-
 
487
 
-
 
488
typedef struct
-
 
489
{
-
 
490
   unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
-
 
491
   float xoff,yoff,xadvance;
-
 
492
   float xoff2,yoff2;
-
 
493
} stbtt_packedchar;
-
 
494
 
-
 
495
typedef struct stbtt_pack_context stbtt_pack_context;
-
 
496
 
-
 
497
extern int  stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context);
-
 
498
// Initializes a packing context stored in the passed-in stbtt_pack_context.
-
 
499
// Future calls using this context will pack characters into the bitmap passed
-
 
500
// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is
-
 
501
// the distance from one row to the next (or 0 to mean they are packed tightly
-
 
502
// together). "padding" is // the amount of padding to leave between each
-
 
503
// character (normally you want '1' for bitmaps you'll use as textures with
-
 
504
// bilinear filtering).
-
 
505
//
-
 
506
// Returns 0 on failure, 1 on success.
-
 
507
 
-
 
508
extern void stbtt_PackEnd  (stbtt_pack_context *spc);
-
 
509
// Cleans up the packing context and frees all memory.
-
 
510
 
-
 
511
#define STBTT_POINT_SIZE(x)   (-(x))
-
 
512
 
-
 
513
extern int  stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
-
 
514
                                int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range);
-
 
515
// Creates character bitmaps from the font_index'th font found in fontdata (use
-
 
516
// font_index=0 if you don't know what that is). It creates num_chars_in_range
-
 
517
// bitmaps for characters with unicode values starting at first_unicode_char_in_range
-
 
518
// and increasing. Data for how to render them is stored in chardata_for_range;
-
 
519
// pass these to stbtt_GetPackedQuad to get back renderable quads.
-
 
520
//
-
 
521
// font_size is the full height of the character from ascender to descender,
-
 
522
// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed
-
 
523
// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE()
-
 
524
// and pass that result as 'font_size':
-
 
525
//       ...,                  20 , ... // font max minus min y is 20 pixels tall
-
 
526
//       ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall
-
 
527
 
-
 
528
typedef struct
-
 
529
{
-
 
530
   float font_size;
-
 
531
   int first_unicode_char_in_range;
-
 
532
   int num_chars_in_range;
-
 
533
   stbtt_packedchar *chardata_for_range; // output
-
 
534
} stbtt_pack_range;
-
 
535
 
-
 
536
extern int  stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges);
-
 
537
// Creates character bitmaps from multiple ranges of characters stored in
-
 
538
// ranges. This will usually create a better-packed bitmap than multiple
-
 
539
// calls to stbtt_PackFontRange.
-
 
540
 
-
 
541
 
-
 
542
extern void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample);
-
 
543
// Oversampling a font increases the quality by allowing higher-quality subpixel
-
 
544
// positioning, and is especially valuable at smaller text sizes.
-
 
545
//
-
 
546
// This function sets the amount of oversampling for all following calls to
-
 
547
// stbtt_PackFontRange(s). The default (no oversampling) is achieved by
-
 
548
// h_oversample=1, v_oversample=1. The total number of pixels required is
-
 
549
// h_oversample*v_oversample larger than the default; for example, 2x2
-
 
550
// oversampling requires 4x the storage of 1x1. For best results, render
-
 
551
// oversampled textures with bilinear filtering. Look at the readme in
-
 
552
// stb/tests/oversample for information about oversampled fonts
-
 
553
 
-
 
554
extern void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph,  // same data as above
-
 
555
                               int char_index,             // character to display
-
 
556
                               float *xpos, float *ypos,   // pointers to current position in screen pixel space
-
 
557
                               stbtt_aligned_quad *q,      // output: quad to draw
-
 
558
                               int align_to_integer);
-
 
559
 
-
 
560
// this is an opaque structure that you shouldn't mess with which holds
-
 
561
// all the context needed from PackBegin to PackEnd.
-
 
562
struct stbtt_pack_context {
-
 
563
   void *user_allocator_context;
-
 
564
   void *pack_info;
-
 
565
   int   width;
-
 
566
   int   height;
-
 
567
   int   stride_in_bytes;
-
 
568
   int   padding;
-
 
569
   unsigned int   h_oversample, v_oversample;
-
 
570
   unsigned char *pixels;
-
 
571
   void  *nodes;
756
 
572
};
757
 
573
 
758
//////////////////////////////////////////////////////////////////////////////
574
//////////////////////////////////////////////////////////////////////////////
759
//
575
//
760
// FONT LOADING
576
// FONT LOADING
Line 838... Line 654...
838
// advanceWidth is the offset from the current horizontal position to the next horizontal position
654
// advanceWidth is the offset from the current horizontal position to the next horizontal position
839
//   these are expressed in unscaled coordinates
655
//   these are expressed in unscaled coordinates
Line 840... Line 656...
840
 
656
 
841
extern int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
657
extern int  stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2);
842
// an additional amount to add to the 'advance' value between ch1 and ch2
-
 
Line 843... Line 658...
843
// @TODO; for now always returns 0!
658
// an additional amount to add to the 'advance' value between ch1 and ch2
844
 
659
 
Line 845... Line 660...
845
extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
660
extern int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1);
Line 880... Line 695...
880
 
695
 
881
extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
696
extern int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices);
882
extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
697
extern int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices);
883
// returns # of vertices and fills *vertices with the pointer to them
698
// returns # of vertices and fills *vertices with the pointer to them
-
 
699
//   these are expressed in "unscaled" coordinates
-
 
700
//
-
 
701
// The shape is a series of countours. Each one starts with
-
 
702
// a STBTT_moveto, then consists of a series of mixed
-
 
703
// STBTT_lineto and STBTT_curveto segments. A lineto
-
 
704
// draws a line from previous endpoint to its x,y; a curveto
-
 
705
// draws a quadratic bezier from previous endpoint to
Line 884... Line 706...
884
//   these are expressed in "unscaled" coordinates
706
// its x,y, using cx,cy as the bezier control point.
885
 
707
 
Line 886... Line 708...
886
extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
708
extern void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices);
Line 1054... Line 876...
1054
////
876
////
1055
////
877
////
Line 1056... Line 878...
1056
 
878
 
Line -... Line 879...
-
 
879
#ifdef STB_TRUETYPE_IMPLEMENTATION
-
 
880
 
-
 
881
#ifndef STBTT_MAX_OVERSAMPLE
-
 
882
#define STBTT_MAX_OVERSAMPLE   8
-
 
883
#endif
-
 
884
 
1057
#ifdef STB_TRUETYPE_IMPLEMENTATION
885
typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1];
1058
 
886
 
1059
//////////////////////////////////////////////////////////////////////////
887
//////////////////////////////////////////////////////////////////////////
1060
//
888
//
Line 1066... Line 894...
1066
 
894
 
1067
#define ttBYTE(p)     (* (stbtt_uint8 *) (p))
895
#define ttBYTE(p)     (* (stbtt_uint8 *) (p))
1068
#define ttCHAR(p)     (* (stbtt_int8 *) (p))
896
#define ttCHAR(p)     (* (stbtt_int8 *) (p))
Line -... Line 897...
-
 
897
#define ttFixed(p)    ttLONG(p)
Line 1069... Line -...
1069
#define ttFixed(p)    ttLONG(p)
-
 
1070
 
-
 
1071
 
-
 
1072
 
898
 
1073
//#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
899
#if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE)
1074
/*
900
 
1075
   #define ttUSHORT(p)   (* (stbtt_uint16 *) (p))
901
   #define ttUSHORT(p)   (* (stbtt_uint16 *) (p))
1076
   #define ttSHORT(p)    (* (stbtt_int16 *) (p))
902
   #define ttSHORT(p)    (* (stbtt_int16 *) (p))
1077
   #define ttULONG(p)    (* (stbtt_uint32 *) (p))
903
   #define ttULONG(p)    (* (stbtt_uint32 *) (p))
Line 1078... Line 904...
1078
   #define ttLONG(p)     (* (stbtt_int32 *) (p))
904
   #define ttLONG(p)     (* (stbtt_int32 *) (p))
1079
*/
905
 
1080
//#else 
906
#else
1081
 
907
 
Line 1082... Line 908...
1082
   stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
908
   stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; }
Line 1083... Line 909...
1083
   stbtt_int16 ttSHORT(const stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
909
   stbtt_int16 ttSHORT(const stbtt_uint8 *p)   { return p[0]*256 + p[1]; }
1084
   stbtt_uint32 ttULONG(const stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
910
   stbtt_uint32 ttULONG(const stbtt_uint8 *p)  { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
Line 1085... Line 911...
1085
   stbtt_int32 ttLONG(const stbtt_uint8 *p)    { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
911
   stbtt_int32 ttLONG(const stbtt_uint8 *p)    { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; }
Line 1173... Line 999...
1173
                  // MS/Unicode
999
                  // MS/Unicode
1174
                  info->index_map = cmap + ttULONG(data+encoding_record+4);
1000
                  info->index_map = cmap + ttULONG(data+encoding_record+4);
1175
                  break;
1001
                  break;
1176
            }
1002
            }
1177
            break;
1003
            break;
-
 
1004
        case STBTT_PLATFORM_ID_UNICODE:
-
 
1005
            // Mac/iOS has these
-
 
1006
            // all the encodingIDs are unicode, so we don't bother to check it
-
 
1007
            info->index_map = cmap + ttULONG(data+encoding_record+4);
-
 
1008
            break;
1178
      }
1009
      }
1179
   }
1010
   }
1180
   if (info->index_map == 0)
1011
   if (info->index_map == 0)
1181
      return 0;
1012
      return 0;
Line 1224... Line 1055...
1224
         search += rangeShift*2;
1055
         search += rangeShift*2;
Line 1225... Line 1056...
1225
 
1056
 
1226
      // now decrement to bias correctly to find smallest
1057
      // now decrement to bias correctly to find smallest
1227
      search -= 2;
1058
      search -= 2;
1228
      while (entrySelector) {
-
 
1229
         stbtt_uint16 start, end;
1059
      while (entrySelector) {
1230
         searchRange >>= 1;
-
 
1231
         start = ttUSHORT(data + search + 2 + segcount*2 + 2);
-
 
1232
         end = ttUSHORT(data + search + 2);
1060
         searchRange >>= 1;
1233
         start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2);
1061
         start = ttUSHORT(data + search + searchRange*2 + segcount*2 + 2);
1234
         end = ttUSHORT(data + search + searchRange*2);
1062
         end = ttUSHORT(data + search + searchRange*2);
1235
         if (unicode_codepoint > end)
1063
         if (unicode_codepoint > end)
1236
            search += searchRange*2;
1064
            search += searchRange*2;
Line 1252... Line 1080...
1252
 
1080
 
1253
      return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1081
      return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item);
1254
   } else if (format == 12 || format == 13) {
1082
   } else if (format == 12 || format == 13) {
1255
      stbtt_uint32 ngroups = ttULONG(data+index_map+12);
1083
      stbtt_uint32 ngroups = ttULONG(data+index_map+12);
1256
      stbtt_int32 low,high;
-
 
1257
      //stbtt_uint16 g = 0;
1084
      stbtt_int32 low,high;
1258
      low = 0; high = (stbtt_int32)ngroups;
1085
      low = 0; high = (stbtt_int32)ngroups;
1259
      // Binary search the right group.
1086
      // Binary search the right group.
1260
      while (low < high) {
1087
      while (low < high) {
1261
         stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
1088
         stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high
Line 1533... Line 1360...
1533
            mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
1360
            mtx[2] = ttSHORT(comp)/16384.0f; comp+=2;
1534
            mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1361
            mtx[3] = ttSHORT(comp)/16384.0f; comp+=2;
1535
         }
1362
         }
Line 1536... Line 1363...
1536
         
1363
         
1537
         // Find transformation scales.
1364
         // Find transformation scales.
1538
         m = (float) sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
1365
         m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]);
Line 1539... Line 1366...
1539
         n = (float) sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1366
         n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]);
1540
 
1367
 
1541
         // Get indexed glyph.
1368
         // Get indexed glyph.
1542
         comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
1369
         comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts);
Line 1557... Line 1384...
1557
            if (!tmp) {
1384
            if (!tmp) {
1558
               if (vertices) STBTT_free(vertices, info->userdata);
1385
               if (vertices) STBTT_free(vertices, info->userdata);
1559
               if (comp_verts) STBTT_free(comp_verts, info->userdata);
1386
               if (comp_verts) STBTT_free(comp_verts, info->userdata);
1560
               return 0;
1387
               return 0;
1561
            }
1388
            }
1562
            //if (num_vertices > 0) STBTT_memset(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
-
 
1563
            if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));//lev
1389
            if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
1564
            STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
1390
            STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
1565
            if (vertices) STBTT_free(vertices, info->userdata);
1391
            if (vertices) STBTT_free(vertices, info->userdata);
1566
            vertices = tmp;
1392
            vertices = tmp;
1567
            STBTT_free(comp_verts, info->userdata);
1393
            STBTT_free(comp_verts, info->userdata);
1568
            num_vertices += comp_num_verts;
1394
            num_vertices += comp_num_verts;
Line 1673... Line 1499...
1673
//
1499
//
Line 1674... Line 1500...
1674
 
1500
 
1675
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)
1501
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)
1676
{
1502
{
1677
   int x0,y0,x1,y1;
1503
   int x0,y0,x1,y1;
1678
   if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1))
1504
   if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
-
 
1505
      // e.g. space character
-
 
1506
      if (ix0) *ix0 = 0;
-
 
1507
      if (iy0) *iy0 = 0;
-
 
1508
      if (ix1) *ix1 = 0;
-
 
1509
      if (iy1) *iy1 = 0;
1679
      x0=y0=x1=y1=0; // e.g. space character
1510
   } else {
1680
   // now move to integral bboxes (treating pixels as little squares, what pixels get touched)?
1511
      // move to integral bboxes (treating pixels as little squares, what pixels get touched)?
1681
   if (ix0) *ix0 =  STBTT_ifloor(x0 * scale_x + shift_x);
1512
      if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x);
1682
   if (iy0) *iy0 = -STBTT_iceil (y1 * scale_y + shift_y);
1513
      if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y);
1683
   if (ix1) *ix1 =  STBTT_iceil (x1 * scale_x + shift_x);
1514
      if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x);
-
 
1515
      if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y);
1684
   if (iy1) *iy1 = -STBTT_ifloor(y0 * scale_y + shift_y);
1516
   }
-
 
1517
}
1685
}
1518
 
1686
void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
1519
void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1)
1687
{
1520
{
1688
   stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
1521
   stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1);
Line 1927... Line 1760...
1927
         if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
1760
         if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) {
1928
            e[n].invert = 1;
1761
            e[n].invert = 1;
1929
            a=j,b=k;
1762
            a=j,b=k;
1930
         }
1763
         }
1931
         e[n].x0 = p[a].x * scale_x + shift_x;
1764
         e[n].x0 = p[a].x * scale_x + shift_x;
1932
         e[n].y0 = p[a].y * y_scale_inv * vsubsample + shift_y;
1765
         e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
1933
         e[n].x1 = p[b].x * scale_x + shift_x;
1766
         e[n].x1 = p[b].x * scale_x + shift_x;
1934
         e[n].y1 = p[b].y * y_scale_inv * vsubsample + shift_y;
1767
         e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
1935
         ++n;
1768
         ++n;
1936
      }
1769
      }
1937
   }
1770
   }
Line 1938... Line 1771...
1938
 
1771
 
Line 2071... Line 1904...
2071
   if (scale_y == 0) {
1904
   if (scale_y == 0) {
2072
      if (scale_x == 0) return NULL;
1905
      if (scale_x == 0) return NULL;
2073
      scale_y = scale_x;
1906
      scale_y = scale_x;
2074
   }
1907
   }
Line 2075... Line 1908...
2075
 
1908
 
Line 2076... Line 1909...
2076
   stbtt_GetGlyphBitmapBox(info, glyph, scale_x, scale_y, &ix0,&iy0,&ix1,&iy1);
1909
   stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1);
2077
 
1910
 
2078
   // now we get the size
1911
   // now we get the size
2079
   gbm.w = (ix1 - ix0);
1912
   gbm.w = (ix1 - ix0);
Line 2159... Line 1992...
2159
                                stbtt_bakedchar *chardata)
1992
                                stbtt_bakedchar *chardata)
2160
{
1993
{
2161
   float scale;
1994
   float scale;
2162
   int x,y,bottom_y, i;
1995
   int x,y,bottom_y, i;
2163
   stbtt_fontinfo f;
1996
   stbtt_fontinfo f;
2164
   stbtt_InitFont(&f, data, offset);
1997
   if (!stbtt_InitFont(&f, data, offset))
-
 
1998
      return -1;
2165
   STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
1999
   STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
2166
   x=y=1;
2000
   x=y=1;
2167
   bottom_y = 1;
2001
   bottom_y = 1;
Line 2168... Line 2002...
2168
 
2002
 
Line 2187... Line 2021...
2187
      chardata[i].x1 = (stbtt_int16) (x + gw);
2021
      chardata[i].x1 = (stbtt_int16) (x + gw);
2188
      chardata[i].y1 = (stbtt_int16) (y + gh);
2022
      chardata[i].y1 = (stbtt_int16) (y + gh);
2189
      chardata[i].xadvance = scale * advance;
2023
      chardata[i].xadvance = scale * advance;
2190
      chardata[i].xoff     = (float) x0;
2024
      chardata[i].xoff     = (float) x0;
2191
      chardata[i].yoff     = (float) y0;
2025
      chardata[i].yoff     = (float) y0;
2192
      x = x + gw + 2;
2026
      x = x + gw + 1;
2193
      if (y+gh+2 > bottom_y)
2027
      if (y+gh+1 > bottom_y)
2194
         bottom_y = y+gh+2;
2028
         bottom_y = y+gh+1;
2195
   }
2029
   }
2196
   return bottom_y;
2030
   return bottom_y;
2197
}
2031
}
Line 2198... Line 2032...
2198
 
2032
 
Line 2217... Line 2051...
2217
   *xpos += b->xadvance;
2051
   *xpos += b->xadvance;
2218
}
2052
}
Line 2219... Line 2053...
2219
 
2053
 
2220
//////////////////////////////////////////////////////////////////////////////
2054
//////////////////////////////////////////////////////////////////////////////
-
 
2055
//
-
 
2056
// rectangle packing replacement routines if you don't have stb_rect_pack.h
-
 
2057
//
-
 
2058
 
-
 
2059
#ifndef STB_RECT_PACK_VERSION
-
 
2060
#ifdef _MSC_VER
-
 
2061
#define STBTT__NOTUSED(v)  (void)(v)
-
 
2062
#else
-
 
2063
#define STBTT__NOTUSED(v)  (void)sizeof(v)
-
 
2064
#endif
-
 
2065
 
-
 
2066
typedef int stbrp_coord;
-
 
2067
 
-
 
2068
////////////////////////////////////////////////////////////////////////////////////
-
 
2069
//                                                                                //
-
 
2070
//                                                                                //
-
 
2071
// COMPILER WARNING ?!?!?                                                         //
-
 
2072
//                                                                                //
-
 
2073
//                                                                                //
-
 
2074
// if you get a compile warning due to these symbols being defined more than      //
-
 
2075
// once, move #include "stb_rect_pack.h" before #include "stb_truetype.h"         //
-
 
2076
//                                                                                //
-
 
2077
////////////////////////////////////////////////////////////////////////////////////
-
 
2078
 
-
 
2079
typedef struct
-
 
2080
{
-
 
2081
   int width,height;
-
 
2082
   int x,y,bottom_y;
-
 
2083
} stbrp_context;
-
 
2084
 
-
 
2085
typedef struct
-
 
2086
{
-
 
2087
   unsigned char x;
-
 
2088
} stbrp_node;
-
 
2089
 
-
 
2090
typedef struct
-
 
2091
{
-
 
2092
   stbrp_coord x,y;
-
 
2093
   int id,w,h,was_packed;
-
 
2094
} stbrp_rect;
-
 
2095
 
-
 
2096
static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes)
-
 
2097
{
-
 
2098
   con->width  = pw;
-
 
2099
   con->height = ph;
-
 
2100
   con->x = 0;
-
 
2101
   con->y = 0;
-
 
2102
   con->bottom_y = 0;
-
 
2103
   STBTT__NOTUSED(nodes);
-
 
2104
   STBTT__NOTUSED(num_nodes);   
-
 
2105
}
-
 
2106
 
-
 
2107
static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects)
-
 
2108
{
-
 
2109
   int i;
-
 
2110
   for (i=0; i < num_rects; ++i) {
-
 
2111
      if (con->x + rects[i].w > con->width) {
-
 
2112
         con->x = 0;
-
 
2113
         con->y = con->bottom_y;
-
 
2114
      }
-
 
2115
      if (con->y + rects[i].h > con->height)
-
 
2116
         break;
-
 
2117
      rects[i].x = con->x;
-
 
2118
      rects[i].y = con->y;
-
 
2119
      rects[i].was_packed = 1;
-
 
2120
      con->x += rects[i].w;
-
 
2121
      if (con->y + rects[i].h > con->bottom_y)
-
 
2122
         con->bottom_y = con->y + rects[i].h;
-
 
2123
   }
-
 
2124
   for (   ; i < num_rects; ++i)
-
 
2125
      rects[i].was_packed = 0;
-
 
2126
}
-
 
2127
#endif
-
 
2128
 
-
 
2129
//////////////////////////////////////////////////////////////////////////////
-
 
2130
//
-
 
2131
// bitmap baking
-
 
2132
//
-
 
2133
// This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If
-
 
2134
// stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy.
-
 
2135
 
-
 
2136
int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context)
-
 
2137
{
-
 
2138
   stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context)            ,alloc_context);
-
 
2139
   int            num_nodes = pw - padding;
-
 
2140
   stbrp_node    *nodes   = (stbrp_node    *) STBTT_malloc(sizeof(*nodes  ) * num_nodes,alloc_context);
-
 
2141
 
-
 
2142
   if (context == NULL || nodes == NULL) {
-
 
2143
      if (context != NULL) STBTT_free(context, alloc_context);
-
 
2144
      if (nodes   != NULL) STBTT_free(nodes  , alloc_context);
-
 
2145
      return 0;
-
 
2146
   }
-
 
2147
 
-
 
2148
   spc->user_allocator_context = alloc_context;
-
 
2149
   spc->width = pw;
-
 
2150
   spc->height = ph;
-
 
2151
   spc->pixels = pixels;
-
 
2152
   spc->pack_info = context;
-
 
2153
   spc->nodes = nodes;
-
 
2154
   spc->padding = padding;
-
 
2155
   spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
-
 
2156
   spc->h_oversample = 1;
-
 
2157
   spc->v_oversample = 1;
-
 
2158
 
-
 
2159
   stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
-
 
2160
 
-
 
2161
   STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
-
 
2162
 
-
 
2163
   return 1;
-
 
2164
}
-
 
2165
 
-
 
2166
void stbtt_PackEnd  (stbtt_pack_context *spc)
-
 
2167
{
-
 
2168
   STBTT_free(spc->nodes    , spc->user_allocator_context);
-
 
2169
   STBTT_free(spc->pack_info, spc->user_allocator_context);
-
 
2170
}
-
 
2171
 
-
 
2172
void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample)
-
 
2173
{
-
 
2174
   STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE);
-
 
2175
   STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE);
-
 
2176
   if (h_oversample <= STBTT_MAX_OVERSAMPLE)
-
 
2177
      spc->h_oversample = h_oversample;
-
 
2178
   if (v_oversample <= STBTT_MAX_OVERSAMPLE)
-
 
2179
      spc->v_oversample = v_oversample;
-
 
2180
}
-
 
2181
 
-
 
2182
#define STBTT__OVER_MASK  (STBTT_MAX_OVERSAMPLE-1)
-
 
2183
 
-
 
2184
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
-
 
2185
{
-
 
2186
   unsigned char buffer[STBTT_MAX_OVERSAMPLE];
-
 
2187
   int safe_w = w - kernel_width;
-
 
2188
   int j;
-
 
2189
   for (j=0; j < h; ++j) {
-
 
2190
      int i;
-
 
2191
      unsigned int total;
-
 
2192
      STBTT_memset(buffer, 0, kernel_width);
-
 
2193
 
-
 
2194
      total = 0;
-
 
2195
 
-
 
2196
      // make kernel_width a constant in common cases so compiler can optimize out the divide
-
 
2197
      switch (kernel_width) {
-
 
2198
         case 2:
-
 
2199
            for (i=0; i <= safe_w; ++i) {
-
 
2200
               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-
 
2201
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-
 
2202
               pixels[i] = (unsigned char) (total / 2);
-
 
2203
            }
-
 
2204
            break;
-
 
2205
         case 3:
-
 
2206
            for (i=0; i <= safe_w; ++i) {
-
 
2207
               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-
 
2208
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-
 
2209
               pixels[i] = (unsigned char) (total / 3);
-
 
2210
            }
-
 
2211
            break;
-
 
2212
         case 4:
-
 
2213
            for (i=0; i <= safe_w; ++i) {
-
 
2214
               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-
 
2215
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-
 
2216
               pixels[i] = (unsigned char) (total / 4);
-
 
2217
            }
-
 
2218
            break;
-
 
2219
         default:
-
 
2220
            for (i=0; i <= safe_w; ++i) {
-
 
2221
               total += pixels[i] - buffer[i & STBTT__OVER_MASK];
-
 
2222
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i];
-
 
2223
               pixels[i] = (unsigned char) (total / kernel_width);
-
 
2224
            }
-
 
2225
            break;
-
 
2226
      }
-
 
2227
 
-
 
2228
      for (; i < w; ++i) {
-
 
2229
         STBTT_assert(pixels[i] == 0);
-
 
2230
         total -= buffer[i & STBTT__OVER_MASK];
-
 
2231
         pixels[i] = (unsigned char) (total / kernel_width);
-
 
2232
      }
-
 
2233
 
-
 
2234
      pixels += stride_in_bytes;
-
 
2235
   }
-
 
2236
}
-
 
2237
 
-
 
2238
static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
-
 
2239
{
-
 
2240
   unsigned char buffer[STBTT_MAX_OVERSAMPLE];
-
 
2241
   int safe_h = h - kernel_width;
-
 
2242
   int j;
-
 
2243
   for (j=0; j < w; ++j) {
-
 
2244
      int i;
-
 
2245
      unsigned int total;
-
 
2246
      STBTT_memset(buffer, 0, kernel_width);
-
 
2247
 
-
 
2248
      total = 0;
-
 
2249
 
-
 
2250
      // make kernel_width a constant in common cases so compiler can optimize out the divide
-
 
2251
      switch (kernel_width) {
-
 
2252
         case 2:
-
 
2253
            for (i=0; i <= safe_h; ++i) {
-
 
2254
               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-
 
2255
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-
 
2256
               pixels[i*stride_in_bytes] = (unsigned char) (total / 2);
-
 
2257
            }
-
 
2258
            break;
-
 
2259
         case 3:
-
 
2260
            for (i=0; i <= safe_h; ++i) {
-
 
2261
               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-
 
2262
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-
 
2263
               pixels[i*stride_in_bytes] = (unsigned char) (total / 3);
-
 
2264
            }
-
 
2265
            break;
-
 
2266
         case 4:
-
 
2267
            for (i=0; i <= safe_h; ++i) {
-
 
2268
               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-
 
2269
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-
 
2270
               pixels[i*stride_in_bytes] = (unsigned char) (total / 4);
-
 
2271
            }
-
 
2272
            break;
-
 
2273
         default:
-
 
2274
            for (i=0; i <= safe_h; ++i) {
-
 
2275
               total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK];
-
 
2276
               buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes];
-
 
2277
               pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
-
 
2278
            }
-
 
2279
            break;
-
 
2280
      }
-
 
2281
 
-
 
2282
      for (; i < h; ++i) {
-
 
2283
         STBTT_assert(pixels[i*stride_in_bytes] == 0);
-
 
2284
         total -= buffer[i & STBTT__OVER_MASK];
-
 
2285
         pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width);
-
 
2286
      }
-
 
2287
 
-
 
2288
      pixels += 1;
-
 
2289
   }
-
 
2290
}
-
 
2291
 
-
 
2292
static float stbtt__oversample_shift(int oversample)
-
 
2293
{
-
 
2294
   if (!oversample)
-
 
2295
      return 0.0f;
-
 
2296
 
-
 
2297
   // The prefilter is a box filter of width "oversample",
-
 
2298
   // which shifts phase by (oversample - 1)/2 pixels in
-
 
2299
   // oversampled space. We want to shift in the opposite
-
 
2300
   // direction to counter this.
-
 
2301
   return (float)-(oversample - 1) / (2.0f * (float)oversample);
-
 
2302
}
-
 
2303
 
-
 
2304
int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
-
 
2305
{
-
 
2306
   stbtt_fontinfo info;
-
 
2307
   float recip_h = 1.0f / spc->h_oversample;
-
 
2308
   float recip_v = 1.0f / spc->v_oversample;
-
 
2309
   float sub_x = stbtt__oversample_shift(spc->h_oversample);
-
 
2310
   float sub_y = stbtt__oversample_shift(spc->v_oversample);
-
 
2311
   int i,j,k,n, return_value = 1;
-
 
2312
   stbrp_context *context = (stbrp_context *) spc->pack_info;
-
 
2313
   stbrp_rect    *rects;
-
 
2314
 
-
 
2315
   // flag all characters as NOT packed
-
 
2316
   for (i=0; i < num_ranges; ++i)
-
 
2317
      for (j=0; j < ranges[i].num_chars_in_range; ++j)
-
 
2318
         ranges[i].chardata_for_range[j].x0 =
-
 
2319
         ranges[i].chardata_for_range[j].y0 =
-
 
2320
         ranges[i].chardata_for_range[j].x1 =
-
 
2321
         ranges[i].chardata_for_range[j].y1 = 0;
-
 
2322
 
-
 
2323
   n = 0;
-
 
2324
   for (i=0; i < num_ranges; ++i)
-
 
2325
      n += ranges[i].num_chars_in_range;
-
 
2326
         
-
 
2327
   rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context);
-
 
2328
   if (rects == NULL)
-
 
2329
      return 0;
-
 
2330
 
-
 
2331
   stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
-
 
2332
   k=0;
-
 
2333
   for (i=0; i < num_ranges; ++i) {
-
 
2334
      float fh = ranges[i].font_size;
-
 
2335
      float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
-
 
2336
      for (j=0; j < ranges[i].num_chars_in_range; ++j) {
-
 
2337
         int x0,y0,x1,y1;
-
 
2338
         stbtt_GetCodepointBitmapBoxSubpixel(&info, ranges[i].first_unicode_char_in_range + j,
-
 
2339
                                              scale * spc->h_oversample,
-
 
2340
                                              scale * spc->v_oversample,
-
 
2341
                                              0,0,
-
 
2342
                                              &x0,&y0,&x1,&y1);
-
 
2343
         rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
-
 
2344
         rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
-
 
2345
         ++k;
-
 
2346
      }
-
 
2347
   }
-
 
2348
 
-
 
2349
   stbrp_pack_rects(context, rects, k);
-
 
2350
 
-
 
2351
   k = 0;
-
 
2352
   for (i=0; i < num_ranges; ++i) {
-
 
2353
      float fh = ranges[i].font_size;
-
 
2354
      float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh);
-
 
2355
      for (j=0; j < ranges[i].num_chars_in_range; ++j) {
-
 
2356
         stbrp_rect *r = &rects[k];
-
 
2357
         if (r->was_packed) {
-
 
2358
            stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
-
 
2359
            int advance, lsb, x0,y0,x1,y1;
-
 
2360
            int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j);
-
 
2361
            stbrp_coord pad = (stbrp_coord) spc->padding;
-
 
2362
 
-
 
2363
            // pad on left and top
-
 
2364
            r->x += pad;
-
 
2365
            r->y += pad;
-
 
2366
            r->w -= pad;
-
 
2367
            r->h -= pad;
-
 
2368
            stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb);
-
 
2369
            stbtt_GetGlyphBitmapBox(&info, glyph,
-
 
2370
                                    scale * spc->h_oversample,
-
 
2371
                                    scale * spc->v_oversample,
-
 
2372
                                    &x0,&y0,&x1,&y1);
-
 
2373
            stbtt_MakeGlyphBitmapSubpixel(&info,
-
 
2374
                                          spc->pixels + r->x + r->y*spc->stride_in_bytes,
-
 
2375
                                          r->w - spc->h_oversample+1,
-
 
2376
                                          r->h - spc->v_oversample+1,
-
 
2377
                                          spc->stride_in_bytes,
-
 
2378
                                          scale * spc->h_oversample,
-
 
2379
                                          scale * spc->v_oversample,
-
 
2380
                                          0,0,
-
 
2381
                                          glyph);
-
 
2382
 
-
 
2383
            if (spc->h_oversample > 1)
-
 
2384
               stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
-
 
2385
                                  r->w, r->h, spc->stride_in_bytes,
-
 
2386
                                  spc->h_oversample);
-
 
2387
 
-
 
2388
            if (spc->v_oversample > 1)
-
 
2389
               stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes,
-
 
2390
                                  r->w, r->h, spc->stride_in_bytes,
-
 
2391
                                  spc->v_oversample);
-
 
2392
 
-
 
2393
            bc->x0       = (stbtt_int16)  r->x;
-
 
2394
            bc->y0       = (stbtt_int16)  r->y;
-
 
2395
            bc->x1       = (stbtt_int16) (r->x + r->w);
-
 
2396
            bc->y1       = (stbtt_int16) (r->y + r->h);
-
 
2397
            bc->xadvance =                scale * advance;
-
 
2398
            bc->xoff     =       (float)  x0 * recip_h + sub_x;
-
 
2399
            bc->yoff     =       (float)  y0 * recip_v + sub_y;
-
 
2400
            bc->xoff2    =                (x0 + r->w) * recip_h + sub_x;
-
 
2401
            bc->yoff2    =                (y0 + r->h) * recip_v + sub_y;
-
 
2402
         } else {
-
 
2403
            return_value = 0; // if any fail, report failure
-
 
2404
         }
-
 
2405
 
-
 
2406
         ++k;
-
 
2407
      }
-
 
2408
   }
-
 
2409
   
-
 
2410
   zfree(rects);		///////////////////////////////
-
 
2411
 
-
 
2412
   return return_value;
-
 
2413
}
-
 
2414
 
-
 
2415
int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size,
-
 
2416
            int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range)
-
 
2417
{
-
 
2418
   stbtt_pack_range range;
-
 
2419
   range.first_unicode_char_in_range = first_unicode_char_in_range;
-
 
2420
   range.num_chars_in_range          = num_chars_in_range;
-
 
2421
   range.chardata_for_range          = chardata_for_range;
-
 
2422
   range.font_size                   = font_size;
-
 
2423
   return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
-
 
2424
}
-
 
2425
 
-
 
2426
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)
-
 
2427
{
-
 
2428
   float ipw = 1.0f / pw, iph = 1.0f / ph;
-
 
2429
   stbtt_packedchar *b = chardata + char_index;
-
 
2430
 
-
 
2431
   if (align_to_integer) {
-
 
2432
      float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5);
-
 
2433
      float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5);
-
 
2434
      q->x0 = x;
-
 
2435
      q->y0 = y;
-
 
2436
      q->x1 = x + b->xoff2 - b->xoff;
-
 
2437
      q->y1 = y + b->yoff2 - b->yoff;
-
 
2438
   } else {
-
 
2439
      q->x0 = *xpos + b->xoff;
-
 
2440
      q->y0 = *ypos + b->yoff;
-
 
2441
      q->x1 = *xpos + b->xoff2;
-
 
2442
      q->y1 = *ypos + b->yoff2;
-
 
2443
   }
-
 
2444
 
-
 
2445
   q->s0 = b->x0 * ipw;
-
 
2446
   q->t0 = b->y0 * iph;
-
 
2447
   q->s1 = b->x1 * ipw;
-
 
2448
   q->t1 = b->y1 * iph;
-
 
2449
 
-
 
2450
   *xpos += b->xadvance;
-
 
2451
}
-
 
2452
 
-
 
2453
 
-
 
2454
//////////////////////////////////////////////////////////////////////////////
2221
//
2455
//
2222
// font name matching -- recommended not to use this
2456
// font name matching -- recommended not to use this
Line 2223... Line 2457...
2223
//
2457
//
2224
 
2458
 
Line 2303... Line 2537...
2303
         // find the encoding
2537
         // find the encoding
2304
         stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
2538
         stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4);
Line 2305... Line 2539...
2305
 
2539
 
2306
         // is this a Unicode encoding?
2540
         // is this a Unicode encoding?
-
 
2541
         if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
2307
         if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) {
2542
            stbtt_int32 slen = ttUSHORT(fc+loc+8);
Line 2308... Line 2543...
2308
            stbtt_int32 slen = ttUSHORT(fc+loc+8), off = ttUSHORT(fc+loc+10);
2543
            stbtt_int32 off = ttUSHORT(fc+loc+10);
2309
 
2544
 
2310
            // check if there's a prefix match
2545
            // check if there's a prefix match
2311
            stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
2546
            stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen);
2312
            if (matchlen >= 0) {
2547
            if (matchlen >= 0) {
-
 
2548
               // check for target_id+1 immediately following, with same encoding & language
2313
               // check for target_id+1 immediately following, with same encoding & language
2549
               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) {
2314
               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) {
2550
                  slen = ttUSHORT(fc+loc+12+8);
2315
                  stbtt_int32 slen = ttUSHORT(fc+loc+12+8), off = ttUSHORT(fc+loc+12+10);
2551
                  off = ttUSHORT(fc+loc+12+10);
2316
                  if (slen == 0) {
2552
                  if (slen == 0) {
2317
                     if (matchlen == nlen)
2553
                     if (matchlen == nlen)
2318
                        return 1;
2554
                        return 1;