freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Git][freetype/freetype][hdmx-advances] [truetype] Binary search through


From: Alexei Podtelezhnikov (@apodtele)
Subject: [Git][freetype/freetype][hdmx-advances] [truetype] Binary search through `hdmx` records.
Date: Wed, 01 Dec 2021 19:03:07 +0000

Alexei Podtelezhnikov pushed to branch hdmx-advances at FreeType / FreeType

Commits:

2 changed files:

Changes:

  • include/freetype/internal/tttypes.h
    ... ... @@ -1390,8 +1390,8 @@ FT_BEGIN_HEADER
    1390 1390
        *   hdmx_record_size ::
    
    1391 1391
        *     The size of a single hdmx record.
    
    1392 1392
        *
    
    1393
    -   *   hdmx_record_sizes ::
    
    1394
    -   *     An array holding the ppem sizes available in the 'hdmx' table.
    
    1393
    +   *   hdmx_records ::
    
    1394
    +   *     A array of pointers to the 'hdmx' table records sorted by ppem.
    
    1395 1395
        *
    
    1396 1396
        *   sbit_table ::
    
    1397 1397
        *     A pointer to the font's embedded bitmap location table.
    
    ... ... @@ -1605,7 +1605,7 @@ FT_BEGIN_HEADER
    1605 1605
         FT_ULong              hdmx_table_size;
    
    1606 1606
         FT_UInt               hdmx_record_count;
    
    1607 1607
         FT_ULong              hdmx_record_size;
    
    1608
    -    FT_Byte*              hdmx_record_sizes;
    
    1608
    +    FT_Byte**             hdmx_records;
    
    1609 1609
     
    
    1610 1610
         FT_Byte*              sbit_table;
    
    1611 1611
         FT_ULong              sbit_table_size;
    

  • src/truetype/ttpload.c
    ... ... @@ -498,6 +498,14 @@
    498 498
       }
    
    499 499
     
    
    500 500
     
    
    501
    +  FT_COMPARE_DEF( int )
    
    502
    +  compare_ppem( const void*  a,
    
    503
    +                const void*  b )
    
    504
    +  {
    
    505
    +    return **(FT_Byte**)a - **(FT_Byte**)b;
    
    506
    +  }
    
    507
    +
    
    508
    +
    
    501 509
       /**************************************************************************
    
    502 510
        *
    
    503 511
        * @Function:
    
    ... ... @@ -574,20 +582,21 @@
    574 582
           goto Fail;
    
    575 583
         }
    
    576 584
     
    
    577
    -    if ( FT_QNEW_ARRAY( face->hdmx_record_sizes, num_records ) )
    
    585
    +    if ( FT_QNEW_ARRAY( face->hdmx_records, num_records ) )
    
    578 586
           goto Fail;
    
    579 587
     
    
    580
    -    /* XXX: We do not check if the records are sorted by ppem */
    
    581
    -    /* and cannot use binary search later.                    */
    
    582 588
         for ( nn = 0; nn < num_records; nn++ )
    
    583 589
         {
    
    584 590
           if ( p + record_size > limit )
    
    585 591
             break;
    
    586
    -
    
    587
    -      face->hdmx_record_sizes[nn] = p[0];
    
    588
    -      p                          += record_size;
    
    592
    +      face->hdmx_records[nn] = p;
    
    593
    +      p                     += record_size;
    
    589 594
         }
    
    590 595
     
    
    596
    +    /* The records must be already sorted by ppem but it does not */
    
    597
    +    /* hurt to make sure so that the binary search works later.   */
    
    598
    +    ft_qsort( face->hdmx_records, nn, sizeof ( FT_Byte* ), compare_ppem );
    
    599
    +
    
    591 600
         face->hdmx_record_count = nn;
    
    592 601
         face->hdmx_table_size   = table_size;
    
    593 602
         face->hdmx_record_size  = record_size;
    
    ... ... @@ -611,7 +620,7 @@
    611 620
         FT_Memory  memory = stream->memory;
    
    612 621
     
    
    613 622
     
    
    614
    -    FT_FREE( face->hdmx_record_sizes );
    
    623
    +    FT_FREE( face->hdmx_records );
    
    615 624
         FT_FRAME_RELEASE( face->hdmx_table );
    
    616 625
       }
    
    617 626
     
    
    ... ... @@ -619,27 +628,34 @@
    619 628
       /**************************************************************************
    
    620 629
        *
    
    621 630
        * Return the advance width table for a given pixel size if it is found
    
    622
    -   * in the font's `hdmx' table (if any).
    
    631
    +   * in the font's `hdmx' table (if any).  The records must be sorted for
    
    632
    +   * the binary search to work properly.
    
    623 633
        */
    
    624 634
       FT_LOCAL_DEF( FT_Byte* )
    
    625 635
       tt_face_get_device_metrics( TT_Face  face,
    
    626 636
                                   FT_UInt  ppem,
    
    627 637
                                   FT_UInt  gindex )
    
    628 638
       {
    
    629
    -    FT_UInt   nn;
    
    639
    +    FT_UInt   min         = 0;
    
    640
    +    FT_UInt   max         = face->hdmx_record_count;
    
    641
    +    FT_UInt   mid;
    
    630 642
         FT_Byte*  result      = NULL;
    
    631
    -    FT_ULong  record_size = face->hdmx_record_size;
    
    632
    -    FT_Byte*  record      = FT_OFFSET( face->hdmx_table, 8 );
    
    633 643
     
    
    634 644
     
    
    635
    -    for ( nn = 0; nn < face->hdmx_record_count; nn++ )
    
    636
    -      if ( face->hdmx_record_sizes[nn] == ppem )
    
    645
    +    while ( min < max )
    
    646
    +    {
    
    647
    +      mid = ( min + max ) >> 1;
    
    648
    +
    
    649
    +      if ( face->hdmx_records[mid][0] > ppem )
    
    650
    +        max = mid;
    
    651
    +      else if ( face->hdmx_records[mid][0] < ppem )
    
    652
    +        min = mid + 1;
    
    653
    +      else
    
    637 654
           {
    
    638
    -        gindex += 2;
    
    639
    -        if ( gindex < record_size )
    
    640
    -          result = record + nn * record_size + gindex;
    
    655
    +        result = face->hdmx_records[mid] + gindex + 2;
    
    641 656
             break;
    
    642 657
           }
    
    658
    +    }
    
    643 659
     
    
    644 660
         return result;
    
    645 661
       }
    


  • reply via email to

    [Prev in Thread] Current Thread [Next in Thread]