freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] [raster] Fix linked profiles in contour


From: Alexei Podtelezhnikov (@apodtele)
Subject: [Git][freetype/freetype][master] [raster] Fix linked profiles in contour loops.
Date: Wed, 18 Oct 2023 04:16:54 +0000

Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType

Commits:

  • 3fa5c845
    by Alexei Podtelezhnikov (Алексей Подтележников) at 2023-10-17T23:56:23-04:00
    [raster] Fix linked profiles in contour loops.
    
    This fixes a subtle bug when the last profile in a contour was not
    properly short-circuited if it was still empty at `End_Profile`.
    We finalize all linking in `Finalize_Profile_List` now and do nothing
    else there.  The turns are added in `End_Profile`.
    
    * src/raster/ftraster.c (Insert_Y_Turn): Moved up unchanged.
    (End_Profile): Take care of turns but set only preliminary linking.
    (Finalize_Profile_Table): Take care of linking and null-termination.
    (Convert_Glyph): Adjusted accordingly.
    

1 changed file:

Changes:

  • src/raster/ftraster.c
    ... ... @@ -591,6 +591,62 @@
    591 591
       }
    
    592 592
     
    
    593 593
     
    
    594
    +  /**************************************************************************
    
    595
    +   *
    
    596
    +   * @Function:
    
    597
    +   *   Insert_Y_Turn
    
    598
    +   *
    
    599
    +   * @Description:
    
    600
    +   *   Insert a salient into the sorted list placed on top of the render
    
    601
    +   *   pool.
    
    602
    +   *
    
    603
    +   * @Input:
    
    604
    +   *   New y scanline position.
    
    605
    +   *
    
    606
    +   * @Return:
    
    607
    +   *   SUCCESS on success.  FAILURE in case of overflow.
    
    608
    +   */
    
    609
    +  static Bool
    
    610
    +  Insert_Y_Turn( RAS_ARGS Int  y )
    
    611
    +  {
    
    612
    +    PLong  y_turns;
    
    613
    +    Int    n;
    
    614
    +
    
    615
    +
    
    616
    +    n       = ras.numTurns - 1;
    
    617
    +    y_turns = ras.sizeBuff - ras.numTurns;
    
    618
    +
    
    619
    +    /* look for first y value that is <= */
    
    620
    +    while ( n >= 0 && y < y_turns[n] )
    
    621
    +      n--;
    
    622
    +
    
    623
    +    /* if it is <, simply insert it, ignore if == */
    
    624
    +    if ( n >= 0 && y > y_turns[n] )
    
    625
    +      do
    
    626
    +      {
    
    627
    +        Int  y2 = (Int)y_turns[n];
    
    628
    +
    
    629
    +
    
    630
    +        y_turns[n] = y;
    
    631
    +        y = y2;
    
    632
    +      } while ( --n >= 0 );
    
    633
    +
    
    634
    +    if ( n < 0 )
    
    635
    +    {
    
    636
    +      ras.maxBuff--;
    
    637
    +      if ( ras.maxBuff <= ras.top )
    
    638
    +      {
    
    639
    +        ras.error = FT_THROW( Raster_Overflow );
    
    640
    +        return FAILURE;
    
    641
    +      }
    
    642
    +      ras.numTurns++;
    
    643
    +      ras.sizeBuff[-ras.numTurns] = y;
    
    644
    +    }
    
    645
    +
    
    646
    +    return SUCCESS;
    
    647
    +  }
    
    648
    +
    
    649
    +
    
    594 650
       /**************************************************************************
    
    595 651
        *
    
    596 652
        * @Function:
    
    ... ... @@ -687,10 +743,10 @@
    687 743
       static Bool
    
    688 744
       End_Profile( RAS_ARGS Bool  overshoot )
    
    689 745
       {
    
    690
    -    Long  h;
    
    691
    -
    
    746
    +    PProfile  p = ras.cProfile;
    
    747
    +    Long      h = (Long)( ras.top - p->offset );
    
    748
    +    Int       bottom, top;
    
    692 749
     
    
    693
    -    h = (Long)( ras.top - ras.cProfile->offset );
    
    694 750
     
    
    695 751
         if ( h < 0 )
    
    696 752
         {
    
    ... ... @@ -701,82 +757,45 @@
    701 757
     
    
    702 758
         if ( h > 0 )
    
    703 759
         {
    
    704
    -      FT_TRACE7(( "  ending profile %p, start = %ld, height = %ld\n",
    
    705
    -                  (void *)ras.cProfile, ras.cProfile->start, h ));
    
    760
    +      FT_TRACE7(( "  ending profile %p, start = %2ld, height = %+3ld\n",
    
    761
    +                  (void *)p, p->start, p->flags & Flow_Up ? h : -h ));
    
    706 762
     
    
    707
    -      ras.cProfile->height = h;
    
    708 763
           if ( overshoot )
    
    709 764
           {
    
    710
    -        if ( ras.cProfile->flags & Flow_Up )
    
    711
    -          ras.cProfile->flags |= Overshoot_Top;
    
    765
    +        if ( p->flags & Flow_Up )
    
    766
    +          p->flags |= Overshoot_Top;
    
    712 767
             else
    
    713
    -          ras.cProfile->flags |= Overshoot_Bottom;
    
    768
    +          p->flags |= Overshoot_Bottom;
    
    714 769
           }
    
    715 770
     
    
    716
    -      /* premature, the last profile in the contour must loop */
    
    717
    -      ras.cProfile->next = (PProfile)ras.top;
    
    718
    -
    
    719
    -      ras.num_Profs++;
    
    720
    -    }
    
    721
    -
    
    722
    -    ras.joint = FALSE;
    
    723
    -
    
    724
    -    return SUCCESS;
    
    725
    -  }
    
    726
    -
    
    771
    +      p->height = h;
    
    727 772
     
    
    728
    -  /**************************************************************************
    
    729
    -   *
    
    730
    -   * @Function:
    
    731
    -   *   Insert_Y_Turn
    
    732
    -   *
    
    733
    -   * @Description:
    
    734
    -   *   Insert a salient into the sorted list placed on top of the render
    
    735
    -   *   pool.
    
    736
    -   *
    
    737
    -   * @Input:
    
    738
    -   *   New y scanline position.
    
    739
    -   *
    
    740
    -   * @Return:
    
    741
    -   *   SUCCESS on success.  FAILURE in case of overflow.
    
    742
    -   */
    
    743
    -  static Bool
    
    744
    -  Insert_Y_Turn( RAS_ARGS Int  y )
    
    745
    -  {
    
    746
    -    PLong  y_turns;
    
    747
    -    Int    n;
    
    748
    -
    
    749
    -
    
    750
    -    n       = ras.numTurns - 1;
    
    751
    -    y_turns = ras.sizeBuff - ras.numTurns;
    
    752
    -
    
    753
    -    /* look for first y value that is <= */
    
    754
    -    while ( n >= 0 && y < y_turns[n] )
    
    755
    -      n--;
    
    756
    -
    
    757
    -    /* if it is <, simply insert it, ignore if == */
    
    758
    -    if ( n >= 0 && y > y_turns[n] )
    
    759
    -      do
    
    773
    +      if ( p->flags & Flow_Up )
    
    760 774
           {
    
    761
    -        Int  y2 = (Int)y_turns[n];
    
    775
    +        bottom = (Int)p->start;
    
    776
    +        top    = (Int)( p->start + h - 1 );
    
    777
    +      }
    
    778
    +      else
    
    779
    +      {
    
    780
    +        bottom     = (Int)( p->start - h + 1 );
    
    781
    +        top        = (Int)p->start;
    
    782
    +        p->start   = bottom;
    
    783
    +        p->offset += h - 1;
    
    784
    +      }
    
    762 785
     
    
    786
    +      if ( Insert_Y_Turn( RAS_VARS bottom )  ||
    
    787
    +           Insert_Y_Turn( RAS_VARS top + 1 ) )
    
    788
    +        return FAILURE;
    
    763 789
     
    
    764
    -        y_turns[n] = y;
    
    765
    -        y = y2;
    
    766
    -      } while ( --n >= 0 );
    
    790
    +      /* preliminary values to be finalized */
    
    791
    +      p->link = (PProfile)ras.top;
    
    792
    +      p->next = ras.gProfile;
    
    767 793
     
    
    768
    -    if ( n < 0 )
    
    769
    -    {
    
    770
    -      ras.maxBuff--;
    
    771
    -      if ( ras.maxBuff <= ras.top )
    
    772
    -      {
    
    773
    -        ras.error = FT_THROW( Raster_Overflow );
    
    774
    -        return FAILURE;
    
    775
    -      }
    
    776
    -      ras.numTurns++;
    
    777
    -      ras.sizeBuff[-ras.numTurns] = y;
    
    794
    +      ras.num_Profs++;
    
    778 795
         }
    
    779 796
     
    
    797
    +    ras.joint = FALSE;
    
    798
    +
    
    780 799
         return SUCCESS;
    
    781 800
       }
    
    782 801
     
    
    ... ... @@ -788,56 +807,28 @@
    788 807
        *
    
    789 808
        * @Description:
    
    790 809
        *   Adjust all links in the profiles list.
    
    791
    -   *
    
    792
    -   * @Return:
    
    793
    -   *   SUCCESS on success.  FAILURE in case of overflow.
    
    794 810
        */
    
    795
    -  static Bool
    
    811
    +  static void
    
    796 812
       Finalize_Profile_Table( RAS_ARG )
    
    797 813
       {
    
    798
    -    UShort    n;
    
    799
    -    PProfile  p;
    
    800
    -
    
    814
    +    UShort    n = ras.num_Profs;
    
    815
    +    PProfile  p = ras.fProfile;
    
    816
    +    PProfile  q;
    
    801 817
     
    
    802
    -    n = ras.num_Profs;
    
    803
    -    p = ras.fProfile;
    
    804 818
     
    
    805
    -    if ( n > 1 && p )
    
    819
    +    while ( --n )
    
    806 820
         {
    
    807
    -      do
    
    808
    -      {
    
    809
    -        Int  bottom, top;
    
    810
    -
    
    811
    -
    
    812
    -        if ( n > 1 )
    
    813
    -          p->link = (PProfile)( p->offset + p->height );
    
    814
    -        else
    
    815
    -          p->link = NULL;
    
    816
    -
    
    817
    -        if ( p->flags & Flow_Up )
    
    818
    -        {
    
    819
    -          bottom = (Int)p->start;
    
    820
    -          top    = (Int)( p->start + p->height - 1 );
    
    821
    -        }
    
    822
    -        else
    
    823
    -        {
    
    824
    -          bottom     = (Int)( p->start - p->height + 1 );
    
    825
    -          top        = (Int)p->start;
    
    826
    -          p->start   = bottom;
    
    827
    -          p->offset += p->height - 1;
    
    828
    -        }
    
    821
    +      q = p->link;
    
    829 822
     
    
    830
    -        if ( Insert_Y_Turn( RAS_VARS bottom )  ||
    
    831
    -             Insert_Y_Turn( RAS_VARS top + 1 ) )
    
    832
    -          return FAILURE;
    
    823
    +      /* fix the contour loop */
    
    824
    +      if ( q->next == p->next )
    
    825
    +        p->next = q;
    
    833 826
     
    
    834
    -        p = p->link;
    
    835
    -      } while ( --n );
    
    827
    +      p = q;
    
    836 828
         }
    
    837
    -    else
    
    838
    -      ras.fProfile = NULL;
    
    839 829
     
    
    840
    -    return SUCCESS;
    
    830
    +    /* null-terminate */
    
    831
    +    p->link = NULL;
    
    841 832
       }
    
    842 833
     
    
    843 834
     
    
    ... ... @@ -2001,17 +1992,14 @@
    2001 1992
           if ( End_Profile( RAS_VARS o ) )
    
    2002 1993
             return FAILURE;
    
    2003 1994
     
    
    2004
    -      /* loop the last profile in the contour */
    
    2005
    -      ras.cProfile->next = ras.gProfile;
    
    2006
    -
    
    2007
    -      if ( !ras.fProfile )
    
    1995
    +      if ( !ras.fProfile && ras.num_Profs )
    
    2008 1996
             ras.fProfile = ras.gProfile;
    
    2009 1997
         }
    
    2010 1998
     
    
    2011
    -    if ( Finalize_Profile_Table( RAS_VAR ) )
    
    2012
    -      return FAILURE;
    
    1999
    +    if ( ras.num_Profs )
    
    2000
    +      Finalize_Profile_Table( RAS_VAR );
    
    2013 2001
     
    
    2014
    -    return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE );
    
    2002
    +    return SUCCESS;
    
    2015 2003
       }
    
    2016 2004
     
    
    2017 2005
     
    


  • reply via email to

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