... |
... |
@@ -738,6 +738,18 @@ |
738
|
738
|
|
739
|
739
|
contour = shape->contours;
|
740
|
740
|
|
|
741
|
+ /* If the control point coincide with any of the end point */
|
|
742
|
+ /* then it's a line and should be treated as one to avoid */
|
|
743
|
+ /* unnecessary complexity later in the algorithm. */
|
|
744
|
+ if ( ( contour->last_pos.x == control_1->x &&
|
|
745
|
+ contour->last_pos.y == control_1->y ) ||
|
|
746
|
+ ( control_1->x == to->x &&
|
|
747
|
+ control_1->y == to->y ) )
|
|
748
|
+ {
|
|
749
|
+ sdf_line_to( to, user );
|
|
750
|
+ goto Exit;
|
|
751
|
+ }
|
|
752
|
+
|
741
|
753
|
FT_CALL( sdf_edge_new( memory, &edge ) );
|
742
|
754
|
|
743
|
755
|
edge->edge_type = SDF_EDGE_CONIC;
|
... |
... |
@@ -1160,9 +1172,9 @@ |
1160
|
1172
|
/* we check the deviation of the bezier and stop if it is */
|
1161
|
1173
|
/* lower than a pre-defined `threhold` value. */
|
1162
|
1174
|
if ( FT_ABS( 2 * cpos[0].x - 3 * cpos[1].x + cpos[3].x ) < threshold &&
|
1163
|
|
- FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
|
|
1175
|
+ FT_ABS( 2 * cpos[0].y - 3 * cpos[1].y + cpos[3].y ) < threshold &&
|
1164
|
1176
|
FT_ABS( cpos[0].x - 3 * cpos[2].x + 2 * cpos[3].x ) < threshold &&
|
1165
|
|
- FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
|
|
1177
|
+ FT_ABS( cpos[0].y - 3 * cpos[2].y + 2 * cpos[3].y ) < threshold )
|
1166
|
1178
|
{
|
1167
|
1179
|
split_cubic( cpos );
|
1168
|
1180
|
goto Append;
|
... |
... |
@@ -1264,29 +1276,29 @@ |
1264
|
1276
|
/* Subdivide the curve and add it to the list. */
|
1265
|
1277
|
{
|
1266
|
1278
|
FT_26D6_Vec ctrls[3];
|
1267
|
|
- FT_26D6 dx, dy;
|
1268
|
|
- FT_UInt num_splits;
|
|
1279
|
+ FT_26D6 dx, dy;
|
|
1280
|
+ FT_UInt num_splits;
|
1269
|
1281
|
|
1270
|
1282
|
|
1271
|
1283
|
ctrls[0] = edge->start_pos;
|
1272
|
1284
|
ctrls[1] = edge->control_a;
|
1273
|
1285
|
ctrls[2] = edge->end_pos;
|
1274
|
1286
|
|
1275
|
|
- dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
|
1276
|
|
- dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
|
|
1287
|
+ dx = FT_ABS( ctrls[2].x + ctrls[0].x - 2 * ctrls[1].x );
|
|
1288
|
+ dy = FT_ABS( ctrls[2].y + ctrls[0].y - 2 * ctrls[1].y );
|
1277
|
1289
|
if ( dx < dy )
|
1278
|
|
- dx = dy;
|
1279
|
|
-
|
1280
|
|
- /* Here we calculate the number of necessary bisections. Each */
|
1281
|
|
- /* bisection reduces the deviation by exactly 4-fold, hence */
|
1282
|
|
- /* we bisect the bezier until the deviation becomes less than */
|
1283
|
|
- /* 1/8th of a pixel. For more details check `ftgrays.c`. */
|
1284
|
|
- num_splits = 1;
|
1285
|
|
- while ( dx > ONE_PIXEL / 8 )
|
1286
|
|
- {
|
1287
|
|
- dx >>= 2;
|
1288
|
|
- num_splits <<= 1;
|
1289
|
|
- }
|
|
1290
|
+ dx = dy;
|
|
1291
|
+
|
|
1292
|
+ /* Here we calculate the number of necessary bisections. Each */
|
|
1293
|
+ /* bisection reduces the deviation by exactly 4-fold, hence */
|
|
1294
|
+ /* we bisect the bezier until the deviation becomes less than */
|
|
1295
|
+ /* 1/8th of a pixel. For more details check `ftgrays.c`. */
|
|
1296
|
+ num_splits = 1;
|
|
1297
|
+ while ( dx > ONE_PIXEL / 8 )
|
|
1298
|
+ {
|
|
1299
|
+ dx >>= 2;
|
|
1300
|
+ num_splits <<= 1;
|
|
1301
|
+ }
|
1290
|
1302
|
|
1291
|
1303
|
error = split_sdf_conic( memory, ctrls, num_splits, &new_edges );
|
1292
|
1304
|
}
|
... |
... |
@@ -3316,6 +3328,7 @@ |
3316
|
3328
|
FT_26D6_Vec grid_point = zero_vector;
|
3317
|
3329
|
SDF_Signed_Distance dist = max_sdf;
|
3318
|
3330
|
FT_UInt index = 0;
|
|
3331
|
+ FT_16D16 diff = 0;
|
3319
|
3332
|
|
3320
|
3333
|
|
3321
|
3334
|
if ( x < 0 || x >= width )
|
... |
... |
@@ -3343,7 +3356,7 @@ |
3343
|
3356
|
if ( dist.distance > sp_sq )
|
3344
|
3357
|
continue;
|
3345
|
3358
|
|
3346
|
|
- /* square_root the values and fit in a 6.10 fixed-point */
|
|
3359
|
+ /* square_root the values if required */
|
3347
|
3360
|
if ( USE_SQUARED_DISTANCES )
|
3348
|
3361
|
dist.distance = square_root( dist.distance );
|
3349
|
3362
|
|
... |
... |
@@ -3355,11 +3368,15 @@ |
3355
|
3368
|
/* check whether the pixel is set or not */
|
3356
|
3369
|
if ( dists[index].sign == 0 )
|
3357
|
3370
|
dists[index] = dist;
|
3358
|
|
- else if ( dists[index].distance > dist.distance )
|
3359
|
|
- dists[index] = dist;
|
3360
|
|
- else if ( FT_ABS( dists[index].distance - dist.distance )
|
3361
|
|
- < CORNER_CHECK_EPSILON )
|
3362
|
|
- dists[index] = resolve_corner( dists[index], dist );
|
|
3371
|
+ else
|
|
3372
|
+ {
|
|
3373
|
+ diff = FT_ABS( dists[index].distance - dist.distance );
|
|
3374
|
+
|
|
3375
|
+ if ( diff <= CORNER_CHECK_EPSILON )
|
|
3376
|
+ dists[index] = resolve_corner( dists[index], dist );
|
|
3377
|
+ else if ( dists[index].distance > dist.distance )
|
|
3378
|
+ dists[index] = dist;
|
|
3379
|
+ }
|
3363
|
3380
|
}
|
3364
|
3381
|
}
|
3365
|
3382
|
|