freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] 2 commits: Formatting and ChangeLog add


From: Werner Lemberg (@wl)
Subject: [Git][freetype/freetype][master] 2 commits: Formatting and ChangeLog additions for previous commits.
Date: Fri, 16 Jul 2021 05:51:02 +0000

Werner Lemberg pushed to branch master at FreeType / FreeType

Commits:

3 changed files:

Changes:

  • ChangeLog
    1
    +2021-07-16  Werner Lemberg  <wl@gnu.org>
    
    2
    +
    
    3
    +	[smooth] Minor fixes.
    
    4
    +
    
    5
    +	* src/smooth/ftgrays.c (gray_render_conic): Move variable and
    
    6
    +	structure declarations to beginning of function.  Inspite of C99
    
    7
    +	compliance we still do this for the sake of backward compatibility.
    
    8
    +	This also avoids a shadowing declaration of `count`.
    
    9
    +	(gray_convert_glyph_inner): Fix typo.
    
    10
    +
    
    11
    +2021-07-15  Ben Wagner  <bungeman@chromium.org>
    
    12
    +
    
    13
    +	* src/smooth/ftgrays.c: Guard inclusion of `emmintrin.h`.
    
    14
    +
    
    15
    +	Guard inclusion of `emmintrin.h` with `#ifdef __SSE2__`.  The gcc
    
    16
    +	version of this header, `xmmintrin.h`, and `mmintrin.h` check that
    
    17
    +	the appropriate defines are set before defining anything (are
    
    18
    +	internally guarded).  However, the clang versions of these includes
    
    19
    +	are not internally guarded.  As a result of this, externally guard
    
    20
    +	the inclusion of these headers.
    
    21
    +
    
    1 22
     2021-07-15  David Turner  <david@freetype.org>
    
    2 23
     
    
    3
    -	[smooth] Implement Bezier quadratic arc flattenning with DDA
    
    24
    +	[smooth] Implement Bézier quadratic arc flattening with DDA.
    
    4 25
     
    
    5 26
     	Benchmarking shows that this provides a very slighty performance
    
    6
    -	boost when rendering fonts with lots of quadratic bezier arcs,
    
    27
    +	boost when rendering fonts with lots of quadratic zier arcs,
    
    7 28
     	compared to the recursive arc splitting, but only when SSE2 is
    
    8 29
     	available, or on 64-bit CPUs.
    
    9 30
     
    
    31
    +	On a 2017 Core i5-7300U CPU on Linux/x86_64:
    
    32
    +
    
    33
    +	  ftbench -p -s10 -t5 -cb DroidSansFallbackFull.ttf
    
    34
    +
    
    35
    +	  Before: 4.033 us/op  (best of 5 runs for all numbers)
    
    36
    +	  After:  3.876 us/op
    
    37
    +
    
    38
    +	  ftbench -p -s60 -t5 -cb DroidSansFallbackFull.ttf
    
    39
    +
    
    40
    +	  Before: 13.467 us/op
    
    41
    +	  After:  13.385 us/op
    
    42
    +
    
    10 43
     	* src/smooth/ftgrays.c (gray_render_conic): New implementation
    
    11 44
     	based on DDA and optionally SSE2.
    
    12 45
     
    
    13 46
     2021-07-15  David Turner  <david@freetype.org>
    
    14 47
     
    
    15
    -	[smooth] Minor speedup to smooth rasterizer
    
    48
    +	[smooth] Minor speedup to smooth rasterizer.
    
    16 49
     
    
    17
    -	This speeds up the smooth rasterizer by avoiding a conditional
    
    50
    +	This speeds up the smooth rasterizer by avoiding conditional
    
    18 51
     	branches in the hot path.
    
    19 52
     
    
    20
    -	* src/smooth/ftgrays.c: Define a null cell used to both as a
    
    21
    -	sentinel for all linked-lists, and to accumulate coverage and
    
    22
    -	area values for "out-of-bounds" cell positions without a
    
    23
    -	conditional check.
    
    53
    +	- Define a fixed 'null cell', which will be pointed to whenever the
    
    54
    +	  current cell is outside of the current target region.  This avoids
    
    55
    +	  a `ras.cell != NULL` check in the `FT_INTEGRATE` macro.
    
    56
    +
    
    57
    +	- Also use the null cell as a sentinel at the end of all `ycells`
    
    58
    +	  linked-lists, by setting its x coordinate to `INT_MAX`.  This
    
    59
    +	  avoids a `if (!cell)` check in `gray_set_cell` as well.
    
    60
    +
    
    61
    +	- Slightly change the worker struct fields to perform a little less
    
    62
    +	  operations during rendering.
    
    63
    +
    
    64
    +	Example results (on a 2013 Corei5-3337U CPU)
    
    65
    +
    
    66
    +	  out/ftbench -p -s10 -t5 -bc DroidSansFallbackFull.ttf
    
    67
    +
    
    68
    +	  Before: 5.472 us/op
    
    69
    +	  After:  5.275 us/op
    
    70
    +
    
    71
    +	  out/ftbench -p -s60 -t5 -bc DroidSansFallbackFull.ttf
    
    72
    +
    
    73
    +	  Before: 17.988 us/op
    
    74
    +	  After:  17.389 us/op
    
    75
    +
    
    76
    +	* src/smooth/ftgrays.c (grat_TWorker): Replace `num_cells` field with
    
    77
    +	`cell_free` and `cell_limit`.
    
    78
    +	(NULL_CELL_PTR, CELL_MAX_X_VALUE, CELL_IS_NULL): New macros.
    
    79
    +	(gray_dump_cells, gray_set_cell, gray_sweep, gray_sweep_direct,
    
    80
    +	gray_convert_glyph_inner, gray_convert_glyph): Updated.
    
    24 81
     
    
    25 82
     2021-07-15  David Turner  <david@freetype.org>
    
    26 83
     
    
    27
    -	Replaces download-test-fonts.sh with download-test-fonts.py which
    
    28
    -	does the same work, and also avoids downloading anything if the
    
    29
    -	files are already installed with the right content.
    
    84
    +	[tests] Rewrite download script in Python3.
    
    85
    +
    
    86
    +	This commit replaces the bash script with a Python script that does
    
    87
    +	the same work, plus avoiding to download anything if the files are
    
    88
    +	already installed with the right content.
    
    30 89
     
    
    31
    -	Now uses the first 8 byte of each file's sha256 hash for the digest.
    
    90
    +	We now use the first 8 bytes of each file's sha256 hash for the
    
    91
    +	digest.
    
    32 92
     
    
    33
    -	* tests/scripts/download-test-fonts.sh: Removed
    
    34
    -	* tests/scripts/download-test-fonts.py: New script
    
    35
    -	* tests/README.md: Updated
    
    93
    +	* tests/scripts/download-test-fonts.sh: Removed.
    
    94
    +	* tests/scripts/download-test-fonts.py: New script.
    
    95
    +	* tests/README.md: Updated.
    
    36 96
     
    
    37 97
     2021-07-15  Alex Richardson  <Alexander.Richardson@cl.cam.ac.uk>
    
    38 98
     
    

  • src/smooth/ftgrays.c
    ... ... @@ -487,8 +487,8 @@ typedef ptrdiff_t FT_PtrDist;
    487 487
         PCell       cell_free;   /* call allocation next free slot           */
    
    488 488
         PCell       cell_limit;  /* cell allocation limit                    */
    
    489 489
     
    
    490
    -    PCell*      ycells;      /* array of cell linked-lists, one per      */
    
    491
    -							 /* vertical coordinate in the current band. */
    
    490
    +    PCell*      ycells;      /* array of cell linked-lists; one per      */
    
    491
    +                             /* vertical coordinate in the current band  */
    
    492 492
     
    
    493 493
         PCell       cells;       /* cell storage area     */
    
    494 494
         FT_PtrDist  max_cells;   /* cell storage capacity */
    
    ... ... @@ -513,19 +513,21 @@ typedef ptrdiff_t FT_PtrDist;
    513 513
       static gray_TWorker  ras;
    
    514 514
     #endif
    
    515 515
     
    
    516
    -/* Return a pointer to the "null cell", used as a sentinel at the end   */
    
    517
    -/* of all ycells[] linked lists. Its x coordinate should be maximal     */
    
    518
    -/* to ensure no NULL checks are necessary when looking for an insertion */
    
    519
    -/* point in gray_set_cell(). Other loops should check the cell pointer  */
    
    520
    -/* with CELL_IS_NULL() to detect the end of the list.                   */
    
    521
    -#define NULL_CELL_PTR(ras)  (ras).cells
    
    516
    +  /*
    
    517
    +   * Return a pointer to the 'null cell', used as a sentinel at the end of
    
    518
    +   * all `ycells` linked lists.  Its x coordinate should be maximal to
    
    519
    +   * ensure no NULL checks are necessary when looking for an insertion point
    
    520
    +   * in `gray_set_cell`.  Other loops should check the cell pointer with
    
    521
    +   * CELL_IS_NULL() to detect the end of the list.
    
    522
    +   */
    
    523
    +#define NULL_CELL_PTR( ras )  (ras).cells
    
    522 524
     
    
    523
    -/* The |x| value of the null cell. Must be the largest possible */
    
    524
    -/* integer value stored in a TCell.x field.                     */
    
    525
    +  /* The |x| value of the null cell.  Must be the largest possible */
    
    526
    +  /* integer value stored in a `TCell.x` field.                    */
    
    525 527
     #define CELL_MAX_X_VALUE    INT_MAX
    
    526 528
     
    
    527
    -/* Return true iff |cell| points to the null cell. */
    
    528
    -#define CELL_IS_NULL(cell)  ((cell)->x == CELL_MAX_X_VALUE)
    
    529
    +  /* Return true iff |cell| points to the null cell. */
    
    530
    +#define CELL_IS_NULL( cell )  ( (cell)->x == CELL_MAX_X_VALUE )
    
    529 531
     
    
    530 532
     
    
    531 533
     #define FT_INTEGRATE( ras, a, b )                                     \
    
    ... ... @@ -556,7 +558,7 @@ typedef ptrdiff_t FT_PtrDist;
    556 558
     
    
    557 559
           printf( "%3d:", y );
    
    558 560
     
    
    559
    -      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    561
    +      for ( ; !CELL_IS_NULL( cell ); cell = cell->next )
    
    560 562
             printf( " (%3d, c:%4d, a:%6d)",
    
    561 563
                     cell->x, cell->cover, cell->area );
    
    562 564
           printf( "\n" );
    
    ... ... @@ -584,9 +586,11 @@ typedef ptrdiff_t FT_PtrDist;
    584 586
         /* Note that if a cell is to the left of the clipping region, it is    */
    
    585 587
         /* actually set to the (min_ex-1) horizontal position.                 */
    
    586 588
     
    
    587
    -    TCoord ey_index = ey - ras.min_ey;
    
    589
    +    TCoord  ey_index = ey - ras.min_ey;
    
    590
    +
    
    591
    +
    
    588 592
         if ( ey_index < 0 || ey_index >= ras.count_ey || ex >= ras.max_ex )
    
    589
    -      ras.cell = NULL_CELL_PTR(ras);
    
    593
    +      ras.cell = NULL_CELL_PTR( ras );
    
    590 594
         else
    
    591 595
         {
    
    592 596
           PCell*  pcell = ras.ycells + ey_index;
    
    ... ... @@ -610,7 +614,7 @@ typedef ptrdiff_t FT_PtrDist;
    610 614
     
    
    611 615
           /* insert new cell */
    
    612 616
           cell = ras.cell_free++;
    
    613
    -      if (cell >= ras.cell_limit)
    
    617
    +      if ( cell >= ras.cell_limit )
    
    614 618
             ft_longjmp( ras.jump_buffer, 1 );
    
    615 619
     
    
    616 620
           cell->x     = ex;
    
    ... ... @@ -978,6 +982,7 @@ typedef ptrdiff_t FT_PtrDist;
    978 982
             }
    
    979 983
     
    
    980 984
             gray_set_cell( RAS_VAR_ ex1, ey1 );
    
    985
    +
    
    981 986
           } while ( ex1 != ex2 || ey1 != ey2 );
    
    982 987
         }
    
    983 988
     
    
    ... ... @@ -987,30 +992,37 @@ typedef ptrdiff_t FT_PtrDist;
    987 992
         FT_INTEGRATE( ras, fy2 - fy1, fx1 + fx2 );
    
    988 993
     
    
    989 994
       End:
    
    990
    -    ras.x       = to_x;
    
    991
    -    ras.y       = to_y;
    
    995
    +    ras.x = to_x;
    
    996
    +    ras.y = to_y;
    
    992 997
       }
    
    993 998
     
    
    994 999
     #endif
    
    995 1000
     
    
    996
    -/* Benchmarking shows that using DDA to flatten the quadratic bezier
    
    997
    - * arcs is slightly faster in the following cases:
    
    998
    - *
    
    999
    - *   - When the host CPU is 64-bit.
    
    1000
    - *   - When SSE2 SIMD registers and instructions are available (even on x86).
    
    1001
    - *
    
    1002
    - * For other cases, using binary splits is actually slightly faster.
    
    1003
    - */
    
    1004
    -#if defined(__SSE2__) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_AMD64) || defined(_M_ARM64)
    
    1005
    -#define BEZIER_USE_DDA  1
    
    1001
    +  /*
    
    1002
    +   * Benchmarking shows that using DDA to flatten the quadratic Bézier arcs
    
    1003
    +   * is slightly faster in the following cases:
    
    1004
    +   *
    
    1005
    +   *   - When the host CPU is 64-bit.
    
    1006
    +   *   - When SSE2 SIMD registers and instructions are available (even on
    
    1007
    +   *     x86).
    
    1008
    +   *
    
    1009
    +   * For other cases, using binary splits is actually slightly faster.
    
    1010
    +   */
    
    1011
    +#if defined( __SSE2__ )    || \
    
    1012
    +    defined( __x86_64__ )  || \
    
    1013
    +    defined( __aarch64__ ) || \
    
    1014
    +    defined( _M_AMD64 )    || \
    
    1015
    +    defined( _M_ARM64 )
    
    1016
    +#  define BEZIER_USE_DDA  1
    
    1006 1017
     #else
    
    1007
    -#define BEZIER_USE_DDA  0
    
    1018
    +#  define BEZIER_USE_DDA  0
    
    1008 1019
     #endif
    
    1009 1020
     
    
    1021
    +
    
    1010 1022
     #if BEZIER_USE_DDA
    
    1011 1023
     
    
    1012 1024
     #ifdef __SSE2__
    
    1013
    -#include <emmintrin.h>
    
    1025
    +#  include <emmintrin.h>
    
    1014 1026
     #endif
    
    1015 1027
     
    
    1016 1028
       static void
    
    ... ... @@ -1018,6 +1030,16 @@ typedef ptrdiff_t FT_PtrDist;
    1018 1030
                                   const FT_Vector*  to )
    
    1019 1031
       {
    
    1020 1032
         FT_Vector  p0, p1, p2;
    
    1033
    +    TPos       dx, dy;
    
    1034
    +    int        shift;
    
    1035
    +
    
    1036
    +    FT_Int64  ax, ay, bx, by;
    
    1037
    +    FT_Int64  rx, ry;
    
    1038
    +    FT_Int64  qx, qy;
    
    1039
    +    FT_Int64  px, py;
    
    1040
    +
    
    1041
    +    FT_UInt  count;
    
    1042
    +
    
    1021 1043
     
    
    1022 1044
         p0.x = ras.x;
    
    1023 1045
         p0.y = ras.y;
    
    ... ... @@ -1039,8 +1061,8 @@ typedef ptrdiff_t FT_PtrDist;
    1039 1061
           return;
    
    1040 1062
         }
    
    1041 1063
     
    
    1042
    -    TPos dx = FT_ABS( p0.x + p2.x - 2 * p1.x );
    
    1043
    -    TPos dy = FT_ABS( p0.y + p2.y - 2 * p1.y );
    
    1064
    +    dx = FT_ABS( p0.x + p2.x - 2 * p1.x );
    
    1065
    +    dy = FT_ABS( p0.y + p2.y - 2 * p1.y );
    
    1044 1066
         if ( dx < dy )
    
    1045 1067
           dx = dy;
    
    1046 1068
     
    
    ... ... @@ -1053,13 +1075,13 @@ typedef ptrdiff_t FT_PtrDist;
    1053 1075
         /* We can calculate the number of necessary bisections because  */
    
    1054 1076
         /* each bisection predictably reduces deviation exactly 4-fold. */
    
    1055 1077
         /* Even 32-bit deviation would vanish after 16 bisections.      */
    
    1056
    -    int shift = 0;
    
    1078
    +    shift = 0;
    
    1057 1079
         do
    
    1058 1080
         {
    
    1059 1081
           dx   >>= 2;
    
    1060 1082
           shift += 1;
    
    1061
    -    }
    
    1062
    -    while (dx > ONE_PIXEL / 4);
    
    1083
    +
    
    1084
    +    } while ( dx > ONE_PIXEL / 4 );
    
    1063 1085
     
    
    1064 1086
         /*
    
    1065 1087
          * The (P0,P1,P2) arc equation, for t in [0,1] range:
    
    ... ... @@ -1102,78 +1124,96 @@ typedef ptrdiff_t FT_PtrDist;
    1102 1124
          *     Q << 32   = (2 * B << (32 - N)) + (A << (32 - N - N))
    
    1103 1125
          *               = (B << (33 - N)) + (A << (32 - N - N))
    
    1104 1126
          */
    
    1127
    +
    
    1105 1128
     #ifdef __SSE2__
    
    1106
    -    /* Experience shows that for small shift values, SSE2 is actually slower. */
    
    1107
    -    if (shift > 2) {
    
    1108
    -      union {
    
    1109
    -        struct { FT_Int64 ax, ay, bx, by; } i;
    
    1110
    -        struct { __m128i a, b; } vec;
    
    1129
    +    /* Experience shows that for small shift values, */
    
    1130
    +    /* SSE2 is actually slower.                      */
    
    1131
    +    if ( shift > 2 )
    
    1132
    +    {
    
    1133
    +      union
    
    1134
    +      {
    
    1135
    +        struct { FT_Int64  ax, ay, bx, by; }  i;
    
    1136
    +        struct { __m128i  a, b; }  vec;
    
    1137
    +
    
    1111 1138
           } u;
    
    1112 1139
     
    
    1140
    +      union
    
    1141
    +      {
    
    1142
    +        struct { FT_Int32  px_lo, px_hi, py_lo, py_hi; }  i;
    
    1143
    +        __m128i  vec;
    
    1144
    +
    
    1145
    +      } v;
    
    1146
    +
    
    1147
    +      __m128i  a, b;
    
    1148
    +      __m128i  r, q, q2;
    
    1149
    +      __m128i  p;
    
    1150
    +
    
    1151
    +
    
    1113 1152
           u.i.ax = p0.x + p2.x - 2 * p1.x;
    
    1114 1153
           u.i.ay = p0.y + p2.y - 2 * p1.y;
    
    1115 1154
           u.i.bx = p1.x - p0.x;
    
    1116 1155
           u.i.by = p1.y - p0.y;
    
    1117 1156
     
    
    1118
    -      __m128i a = _mm_load_si128(&u.vec.a);
    
    1119
    -      __m128i b = _mm_load_si128(&u.vec.b);
    
    1157
    +      a = _mm_load_si128( &u.vec.a );
    
    1158
    +      b = _mm_load_si128( &u.vec.b );
    
    1120 1159
     
    
    1121
    -      __m128i r = _mm_slli_epi64(a, 33 - 2 * shift);
    
    1122
    -      __m128i q = _mm_slli_epi64(b, 33 - shift);
    
    1123
    -      __m128i q2 = _mm_slli_epi64(a, 32 - 2 * shift);
    
    1124
    -      q = _mm_add_epi64(q2, q);
    
    1160
    +      r  = _mm_slli_epi64( a, 33 - 2 * shift );
    
    1161
    +      q  = _mm_slli_epi64( b, 33 - shift );
    
    1162
    +      q2 = _mm_slli_epi64( a, 32 - 2 * shift );
    
    1163
    +
    
    1164
    +      q = _mm_add_epi64( q2, q );
    
    1125 1165
     
    
    1126
    -      union {
    
    1127
    -        struct { FT_Int32  px_lo, px_hi, py_lo, py_hi; } i;
    
    1128
    -        __m128i vec;
    
    1129
    -      } v;
    
    1130 1166
           v.i.px_lo = 0;
    
    1131 1167
           v.i.px_hi = p0.x;
    
    1132 1168
           v.i.py_lo = 0;
    
    1133 1169
           v.i.py_hi = p0.y;
    
    1134 1170
     
    
    1135
    -      __m128i p = _mm_load_si128(&v.vec);
    
    1171
    +      p = _mm_load_si128( &v.vec );
    
    1136 1172
     
    
    1137
    -      for (unsigned count = (1u << shift); count > 0; count--) {
    
    1138
    -        p = _mm_add_epi64(p, q);
    
    1139
    -        q = _mm_add_epi64(q, r);
    
    1173
    +      for ( count = ( 1U << shift ); count > 0; count-- )
    
    1174
    +      {
    
    1175
    +        p = _mm_add_epi64( p, q );
    
    1176
    +        q = _mm_add_epi64( q, r );
    
    1140 1177
     
    
    1141
    -        _mm_store_si128(&v.vec, p);
    
    1178
    +        _mm_store_si128( &v.vec, p );
    
    1142 1179
     
    
    1143
    -        gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi);
    
    1180
    +        gray_render_line( RAS_VAR_ v.i.px_hi, v.i.py_hi );
    
    1144 1181
           }
    
    1182
    +
    
    1145 1183
           return;
    
    1146 1184
         }
    
    1147
    -#endif  /* !__SSE2__ */
    
    1148
    -    FT_Int64 ax = p0.x + p2.x - 2 * p1.x;
    
    1149
    -    FT_Int64 ay = p0.y + p2.y - 2 * p1.y;
    
    1150
    -    FT_Int64 bx = p1.x - p0.x;
    
    1151
    -    FT_Int64 by = p1.y - p0.y;
    
    1185
    +#endif  /* __SSE2__ */
    
    1152 1186
     
    
    1153
    -    FT_Int64 rx = ax << (33 - 2 * shift);
    
    1154
    -    FT_Int64 ry = ay << (33 - 2 * shift);
    
    1187
    +    ax = p0.x + p2.x - 2 * p1.x;
    
    1188
    +    ay = p0.y + p2.y - 2 * p1.y;
    
    1189
    +    bx = p1.x - p0.x;
    
    1190
    +    by = p1.y - p0.y;
    
    1155 1191
     
    
    1156
    -    FT_Int64 qx = (bx << (33 - shift)) + (ax << (32 - 2 * shift));
    
    1157
    -    FT_Int64 qy = (by << (33 - shift)) + (ay << (32 - 2 * shift));
    
    1192
    +    rx = ax << ( 33 - 2 * shift );
    
    1193
    +    ry = ay << ( 33 - 2 * shift );
    
    1158 1194
     
    
    1159
    -    FT_Int64 px = (FT_Int64)p0.x << 32;
    
    1160
    -    FT_Int64 py = (FT_Int64)p0.y << 32;
    
    1195
    +    qx = ( bx << ( 33 - shift ) ) + ( ax << ( 32 - 2 * shift ) );
    
    1196
    +    qy = ( by << ( 33 - shift ) ) + ( ay << ( 32 - 2 * shift ) );
    
    1161 1197
     
    
    1162
    -	FT_UInt count = 1u << shift;
    
    1198
    +    px = (FT_Int64)p0.x << 32;
    
    1199
    +    py = (FT_Int64)p0.y << 32;
    
    1163 1200
     
    
    1164
    -    for (; count > 0; count--) {
    
    1201
    +    for ( count = 1U << shift; count > 0; count-- )
    
    1202
    +    {
    
    1165 1203
           px += qx;
    
    1166 1204
           py += qy;
    
    1167 1205
           qx += rx;
    
    1168 1206
           qy += ry;
    
    1169 1207
     
    
    1170
    -      gray_render_line( RAS_VAR_ (FT_Pos)(px >> 32), (FT_Pos)(py >> 32));
    
    1208
    +      gray_render_line( RAS_VAR_ (FT_Pos)( px >> 32 ),
    
    1209
    +                                 (FT_Pos)( py >> 32 ) );
    
    1171 1210
         }
    
    1172 1211
       }
    
    1173 1212
     
    
    1174 1213
     #else  /* !BEZIER_USE_DDA */
    
    1175 1214
     
    
    1176
    -  /* Note that multiple attempts to speed up the function below
    
    1215
    +  /*
    
    1216
    +   * Note that multiple attempts to speed up the function below
    
    1177 1217
        * with SSE2 intrinsics, using various data layouts, have turned
    
    1178 1218
        * out to be slower than the non-SIMD code below.
    
    1179 1219
        */
    
    ... ... @@ -1264,12 +1304,14 @@ typedef ptrdiff_t FT_PtrDist;
    1264 1304
     
    
    1265 1305
     #endif  /* !BEZIER_USE_DDA */
    
    1266 1306
     
    
    1267
    -  /* For cubic bezier, binary splits are still faster than DDA
    
    1307
    +
    
    1308
    +  /*
    
    1309
    +   * For cubic Bézier, binary splits are still faster than DDA
    
    1268 1310
        * because the splits are adaptive to how quickly each sub-arc
    
    1269 1311
        * approaches their chord trisection points.
    
    1270 1312
        *
    
    1271 1313
        * It might be useful to experiment with SSE2 to speed up
    
    1272
    -   * gray_split_cubic() though.
    
    1314
    +   * `gray_split_cubic`, though.
    
    1273 1315
        */
    
    1274 1316
       static void
    
    1275 1317
       gray_split_cubic( FT_Vector*  base )
    
    ... ... @@ -1361,6 +1403,7 @@ typedef ptrdiff_t FT_PtrDist;
    1361 1403
         }
    
    1362 1404
       }
    
    1363 1405
     
    
    1406
    +
    
    1364 1407
       static int
    
    1365 1408
       gray_move_to( const FT_Vector*  to,
    
    1366 1409
                     gray_PWorker      worker )
    
    ... ... @@ -1428,7 +1471,7 @@ typedef ptrdiff_t FT_PtrDist;
    1428 1471
           unsigned char*  line = ras.target.origin - ras.target.pitch * y;
    
    1429 1472
     
    
    1430 1473
     
    
    1431
    -      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    1474
    +      for ( ; !CELL_IS_NULL( cell ); cell = cell->next )
    
    1432 1475
           {
    
    1433 1476
             if ( cover != 0 && cell->x > x )
    
    1434 1477
             {
    
    ... ... @@ -1476,7 +1519,7 @@ typedef ptrdiff_t FT_PtrDist;
    1476 1519
           TArea   area;
    
    1477 1520
     
    
    1478 1521
     
    
    1479
    -      for ( ; !CELL_IS_NULL(cell); cell = cell->next )
    
    1522
    +      for ( ; !CELL_IS_NULL( cell ); cell = cell->next )
    
    1480 1523
           {
    
    1481 1524
             if ( cover != 0 && cell->x > x )
    
    1482 1525
             {
    
    ... ... @@ -1856,7 +1899,7 @@ typedef ptrdiff_t FT_PtrDist;
    1856 1899
           FT_TRACE7(( "band [%d..%d]: %ld cell%s\n",
    
    1857 1900
                       ras.min_ey,
    
    1858 1901
                       ras.max_ey,
    
    1859
    -                  ras.cell_free - ras.cells.,
    
    1902
    +                  ras.cell_free - ras.cells,
    
    1860 1903
                       ras.cell_free - ras.cells == 1 ? "" : "s" ));
    
    1861 1904
         }
    
    1862 1905
         else
    
    ... ... @@ -1898,19 +1941,19 @@ typedef ptrdiff_t FT_PtrDist;
    1898 1941
         /* memory management */
    
    1899 1942
         n = ( height * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / sizeof ( TCell );
    
    1900 1943
     
    
    1901
    -    ras.cells     = buffer + n;
    
    1902
    -    ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - n );
    
    1944
    +    ras.cells      = buffer + n;
    
    1945
    +    ras.max_cells  = (FT_PtrDist)( FT_MAX_GRAY_POOL - n );
    
    1903 1946
         ras.cell_limit = ras.cells + ras.max_cells;
    
    1904
    -    ras.ycells    = (PCell*)buffer;
    
    1947
    +    ras.ycells     = (PCell*)buffer;
    
    1905 1948
     
    
    1906
    -	/* Initialize the null cell is at the start of the 'cells' array. */
    
    1907
    -	/* Note that this requires ras.cell_free initialization to skip   */
    
    1908
    -	/* over the first entry in the array.                             */
    
    1909
    -	PCell null_cell  = NULL_CELL_PTR(ras);
    
    1910
    -	null_cell->x     = CELL_MAX_X_VALUE;
    
    1911
    -	null_cell->area  = 0;
    
    1912
    -	null_cell->cover = 0;
    
    1913
    -	null_cell->next  = NULL;;
    
    1949
    +    /* Initialize the null cell at the start of the `cells` array.    */
    
    1950
    +    /* Note that this requires `ras.cell_free` initialization to skip */
    
    1951
    +    /* over the first entry in the array.                             */
    
    1952
    +    PCell null_cell  = NULL_CELL_PTR( ras );
    
    1953
    +    null_cell->x     = CELL_MAX_X_VALUE;
    
    1954
    +    null_cell->area  = 0;
    
    1955
    +    null_cell->cover = 0;
    
    1956
    +    null_cell->next  = NULL;;
    
    1914 1957
     
    
    1915 1958
         for ( y = yMin; y < yMax; )
    
    1916 1959
         {
    
    ... ... @@ -1928,7 +1971,8 @@ typedef ptrdiff_t FT_PtrDist;
    1928 1971
             TCoord  w;
    
    1929 1972
             int     error;
    
    1930 1973
     
    
    1931
    -        for (w = 0; w < width; ++w)
    
    1974
    +
    
    1975
    +        for ( w = 0; w < width; ++w )
    
    1932 1976
               ras.ycells[w] = null_cell;
    
    1933 1977
     
    
    1934 1978
             ras.cell_free = ras.cells + 1;  /* NOTE: Skip over the null cell. */
    

  • tests/scripts/download-test-fonts.py
    1 1
     #!/usr/bin/env python3
    
    2 2
     
    
    3
    -"""Download test fonts used by the FreeType regression test programs.
    
    4
    -These will be copied to $FREETYPE/tests/data/ by default.
    
    5
    -"""
    
    3
    +"""Download test fonts used by the FreeType regression test programs.  These
    
    4
    +will be copied to $FREETYPE/tests/data/ by default."""
    
    6 5
     
    
    7 6
     import argparse
    
    8 7
     import collections
    
    ... ... @@ -15,8 +14,8 @@ import zipfile
    15 14
     
    
    16 15
     from typing import Callable, List, Optional, Tuple
    
    17 16
     
    
    18
    -# The list of download items describing the font files to install.
    
    19
    -# Each download item is a dictionary with one of the following schemas:
    
    17
    +# The list of download items describing the font files to install.  Each
    
    18
    +# download item is a dictionary with one of the following schemas:
    
    20 19
     #
    
    21 20
     # - File item:
    
    22 21
     #
    
    ... ... @@ -28,8 +27,8 @@ from typing import Callable, List, Optional, Tuple
    28 27
     #      install_name
    
    29 28
     #        Type: file name string
    
    30 29
     #        Required: No
    
    31
    -#        Description: Installation name for the font file, only provided if it
    
    32
    -#          must be different from the original URL's basename.
    
    30
    +#        Description: Installation name for the font file, only provided if
    
    31
    +#          it must be different from the original URL's basename.
    
    33 32
     #
    
    34 33
     #      hex_digest
    
    35 34
     #        Type: hexadecimal string
    
    ... ... @@ -39,7 +38,7 @@ from typing import Callable, List, Optional, Tuple
    39 38
     # - Zip items:
    
    40 39
     #
    
    41 40
     #   These items correspond to one or more font files that are embedded in a
    
    42
    -#   remote zip archive. Each entry has the following fields:
    
    41
    +#   remote zip archive.  Each entry has the following fields:
    
    43 42
     #
    
    44 43
     #      zip_url
    
    45 44
     #        Type: URL string.
    
    ... ... @@ -52,23 +51,25 @@ from typing import Callable, List, Optional, Tuple
    52 51
     #        Description: A list of entries describing a single font file to be
    
    53 52
     #          extracted from the archive
    
    54 53
     #
    
    55
    -# Apart from that, some schemas are used for dictionaries used inside download
    
    56
    -# items:
    
    54
    +# Apart from that, some schemas are used for dictionaries used inside
    
    55
    +# download items:
    
    57 56
     #
    
    58 57
     # - File entries:
    
    59 58
     #
    
    60
    -#   These are dictionaries describing a single font file to extract from an archive.
    
    59
    +#   These are dictionaries describing a single font file to extract from an
    
    60
    +#   archive.
    
    61 61
     #
    
    62 62
     #      filename
    
    63 63
     #        Type: file path string
    
    64 64
     #        Required: Yes
    
    65
    -#        Description: Path of source file, relative to the archive's top-level directory.
    
    65
    +#        Description: Path of source file, relative to the archive's
    
    66
    +#          top-level directory.
    
    66 67
     #
    
    67 68
     #      install_name
    
    68 69
     #        Type: file name string
    
    69 70
     #        Required: No
    
    70
    -#        Description: Installation name for the font file, only provided if it must be
    
    71
    -#          different from the original filename value.
    
    71
    +#        Description: Installation name for the font file; only provided if
    
    72
    +#          it must be different from the original filename value.
    
    72 73
     #
    
    73 74
     #      hex_digest
    
    74 75
     #        Type: hexadecimal string
    
    ... ... @@ -90,7 +91,8 @@ _DOWNLOAD_ITEMS = [
    90 91
     
    
    91 92
     
    
    92 93
     def digest_data(data: bytes):
    
    93
    -    """Compute the digest of a given input byte string, which are the first 8 bytes of its sha256 hash."""
    
    94
    +    """Compute the digest of a given input byte string, which are the first
    
    95
    +    8 bytes of its sha256 hash."""
    
    94 96
         m = hashlib.sha256()
    
    95 97
         m.update(data)
    
    96 98
         return m.digest()[:8]
    
    ... ... @@ -155,14 +157,16 @@ def extract_file_from_zip_archive(
    155 157
     
    
    156 158
         Args:
    
    157 159
           archive: Input ZipFile objec.
    
    158
    -      archive_name: Archive name or URL, only used to generate a human-readable error
    
    159
    -        message.
    
    160
    +      archive_name: Archive name or URL, only used to generate a
    
    161
    +        human-readable error message.
    
    162
    +
    
    160 163
           filepath: Input filepath in archive.
    
    161 164
           expected_digest: Optional digest for the file.
    
    162 165
         Returns:
    
    163 166
           A new File instance corresponding to the extract file.
    
    164 167
         Raises:
    
    165
    -      ValueError if expected_digest is not None and does not match the extracted file.
    
    168
    +      ValueError if expected_digest is not None and does not match the
    
    169
    +      extracted file.
    
    166 170
         """
    
    167 171
         file = archive.open(filepath)
    
    168 172
         if expected_digest is not None:
    
    ... ... @@ -181,7 +185,8 @@ def _get_and_install_file(
    181 185
         force_download: bool,
    
    182 186
         get_content: Callable[[], bytes],
    
    183 187
     ) -> bool:
    
    184
    -    if not force_download and hex_digest is not None and os.path.exists(install_path):
    
    188
    +    if not force_download and hex_digest is not None \
    
    189
    +      and os.path.exists(install_path):
    
    185 190
             with open(install_path, "rb") as f:
    
    186 191
                 content: bytes = f.read()
    
    187 192
             if bytes.fromhex(hex_digest) == digest_data(content):
    
    ... ... @@ -200,14 +205,15 @@ def download_and_install_item(
    200 205
         Args:
    
    201 206
           item: Download item as a dictionary, see above for schema.
    
    202 207
           install_dir: Installation directory.
    
    203
    -      force_download: Set to True to force download and installation, even if
    
    204
    -        the font file is already installed with the right content.
    
    208
    +      force_download: Set to True to force download and installation, even
    
    209
    +        if the font file is already installed with the right content.
    
    205 210
     
    
    206 211
         Returns:
    
    207
    -      A list of (install_name, status) tuples, where 'install_name' is the file's
    
    208
    -      installation name under 'install_dir', and 'status' is a boolean that is True
    
    209
    -      to indicate that the file was downloaded and installed, or False to indicate that
    
    210
    -      the file is already installed with the right content.
    
    212
    +      A list of (install_name, status) tuples, where 'install_name' is the
    
    213
    +      file's installation name under 'install_dir', and 'status' is a
    
    214
    +      boolean that is True to indicate that the file was downloaded and
    
    215
    +      installed, or False to indicate that the file is already installed
    
    216
    +      with the right content.
    
    211 217
         """
    
    212 218
         if "file_url" in item:
    
    213 219
             file_url = item["file_url"]
    
    ... ... @@ -284,10 +290,13 @@ def main():
    284 290
             for install_name, status in download_and_install_item(
    
    285 291
                 item, args.install_dir, args.force
    
    286 292
             ):
    
    287
    -            print("%s %s" % (install_name, "INSTALLED" if status else "UP-TO-DATE"))
    
    293
    +            print("%s %s" % (install_name,
    
    294
    +                             "INSTALLED" if status else "UP-TO-DATE"))
    
    288 295
     
    
    289 296
         return 0
    
    290 297
     
    
    291 298
     
    
    292 299
     if __name__ == "__main__":
    
    293 300
         sys.exit(main())
    
    301
    +
    
    302
    +# EOF


  • reply via email to

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