ReactOS 0.4.16-dev-1172-g2041f3c
ftstroke.h File Reference
#include <ft2build.h>
Include dependency graph for ftstroke.h:

Go to the source code of this file.

Typedefs

typedef typedefFT_BEGIN_HEADER struct FT_StrokerRec_FT_Stroker
 
typedef enum FT_Stroker_LineJoin_ FT_Stroker_LineJoin
 
typedef enum FT_Stroker_LineCap_ FT_Stroker_LineCap
 
typedef enum FT_StrokerBorder_ FT_StrokerBorder
 

Enumerations

enum  FT_Stroker_LineJoin_ {
  FT_STROKER_LINEJOIN_ROUND = 0 , FT_STROKER_LINEJOIN_BEVEL = 1 , FT_STROKER_LINEJOIN_MITER_VARIABLE = 2 , FT_STROKER_LINEJOIN_MITER = FT_STROKER_LINEJOIN_MITER_VARIABLE ,
  FT_STROKER_LINEJOIN_MITER_FIXED = 3
}
 
enum  FT_Stroker_LineCap_ { FT_STROKER_LINECAP_BUTT = 0 , FT_STROKER_LINECAP_ROUND , FT_STROKER_LINECAP_SQUARE }
 
enum  FT_StrokerBorder_ { FT_STROKER_BORDER_LEFT = 0 , FT_STROKER_BORDER_RIGHT }
 

Functions

 FT_Outline_GetInsideBorder (FT_Outline *outline)
 
 FT_Outline_GetOutsideBorder (FT_Outline *outline)
 
 FT_Stroker_New (FT_Library library, FT_Stroker *astroker)
 
 FT_Stroker_Set (FT_Stroker stroker, FT_Fixed radius, FT_Stroker_LineCap line_cap, FT_Stroker_LineJoin line_join, FT_Fixed miter_limit)
 
 FT_Stroker_Rewind (FT_Stroker stroker)
 
 FT_Stroker_ParseOutline (FT_Stroker stroker, FT_Outline *outline, FT_Bool opened)
 
 FT_Stroker_BeginSubPath (FT_Stroker stroker, FT_Vector *to, FT_Bool open)
 
 FT_Stroker_EndSubPath (FT_Stroker stroker)
 
 FT_Stroker_LineTo (FT_Stroker stroker, FT_Vector *to)
 
 FT_Stroker_ConicTo (FT_Stroker stroker, FT_Vector *control, FT_Vector *to)
 
 FT_Stroker_CubicTo (FT_Stroker stroker, FT_Vector *control1, FT_Vector *control2, FT_Vector *to)
 
 FT_Stroker_GetBorderCounts (FT_Stroker stroker, FT_StrokerBorder border, FT_UInt *anum_points, FT_UInt *anum_contours)
 
 FT_Stroker_ExportBorder (FT_Stroker stroker, FT_StrokerBorder border, FT_Outline *outline)
 
 FT_Stroker_GetCounts (FT_Stroker stroker, FT_UInt *anum_points, FT_UInt *anum_contours)
 
 FT_Stroker_Export (FT_Stroker stroker, FT_Outline *outline)
 
 FT_Stroker_Done (FT_Stroker stroker)
 
 FT_Glyph_Stroke (FT_Glyph *pglyph, FT_Stroker stroker, FT_Bool destroy)
 
 FT_Glyph_StrokeBorder (FT_Glyph *pglyph, FT_Stroker stroker, FT_Bool inside, FT_Bool destroy)
 

Typedef Documentation

◆ FT_Stroker

typedef typedefFT_BEGIN_HEADER struct FT_StrokerRec_* FT_Stroker

Definition at line 92 of file ftstroke.h.

◆ FT_Stroker_LineCap

◆ FT_Stroker_LineJoin

◆ FT_StrokerBorder

Enumeration Type Documentation

◆ FT_Stroker_LineCap_

Enumerator
FT_STROKER_LINECAP_BUTT 
FT_STROKER_LINECAP_ROUND 
FT_STROKER_LINECAP_SQUARE 

Definition at line 169 of file ftstroke.h.

170 {
174
@ FT_STROKER_LINECAP_ROUND
Definition: ftstroke.h:172
@ FT_STROKER_LINECAP_BUTT
Definition: ftstroke.h:171
@ FT_STROKER_LINECAP_SQUARE
Definition: ftstroke.h:173
enum FT_Stroker_LineCap_ FT_Stroker_LineCap

◆ FT_Stroker_LineJoin_

Enumerator
FT_STROKER_LINEJOIN_ROUND 
FT_STROKER_LINEJOIN_BEVEL 
FT_STROKER_LINEJOIN_MITER_VARIABLE 
FT_STROKER_LINEJOIN_MITER 
FT_STROKER_LINEJOIN_MITER_FIXED 

Definition at line 138 of file ftstroke.h.

139 {
145
@ FT_STROKER_LINEJOIN_MITER
Definition: ftstroke.h:143
@ FT_STROKER_LINEJOIN_MITER_FIXED
Definition: ftstroke.h:144
@ FT_STROKER_LINEJOIN_BEVEL
Definition: ftstroke.h:141
@ FT_STROKER_LINEJOIN_MITER_VARIABLE
Definition: ftstroke.h:142
@ FT_STROKER_LINEJOIN_ROUND
Definition: ftstroke.h:140
enum FT_Stroker_LineJoin_ FT_Stroker_LineJoin

◆ FT_StrokerBorder_

Enumerator
FT_STROKER_BORDER_LEFT 
FT_STROKER_BORDER_RIGHT 

Definition at line 203 of file ftstroke.h.

204 {
207
@ FT_STROKER_BORDER_RIGHT
Definition: ftstroke.h:206
@ FT_STROKER_BORDER_LEFT
Definition: ftstroke.h:205
enum FT_StrokerBorder_ FT_StrokerBorder

Function Documentation

◆ FT_Glyph_Stroke()

FT_Glyph_Stroke ( FT_Glyph pglyph,
FT_Stroker  stroker,
FT_Bool  destroy 
)

Definition at line 2298 of file ftstroke.c.

2301 {
2302 FT_Error error = FT_ERR( Invalid_Argument );
2303 FT_Glyph glyph = NULL;
2304
2305
2306 if ( !pglyph )
2307 goto Exit;
2308
2309 glyph = *pglyph;
2310 if ( !glyph || glyph->clazz != &ft_outline_glyph_class )
2311 goto Exit;
2312
2313 {
2314 FT_Glyph copy;
2315
2316
2317 error = FT_Glyph_Copy( glyph, &copy );
2318 if ( error )
2319 goto Exit;
2320
2321 glyph = copy;
2322 }
2323
2324 {
2325 FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph;
2326 FT_Outline* outline = &oglyph->outline;
2327 FT_UInt num_points, num_contours;
2328
2329
2331 if ( error )
2332 goto Fail;
2333
2334 FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
2335
2336 FT_Outline_Done( glyph->library, outline );
2337
2338 error = FT_Outline_New( glyph->library,
2339 num_points,
2340 (FT_Int)num_contours,
2341 outline );
2342 if ( error )
2343 goto Fail;
2344
2345 outline->n_points = 0;
2346 outline->n_contours = 0;
2347
2348 FT_Stroker_Export( stroker, outline );
2349 }
2350
2351 if ( destroy )
2352 FT_Done_Glyph( *pglyph );
2353
2354 *pglyph = glyph;
2355 goto Exit;
2356
2357 Fail:
2358 FT_Done_Glyph( glyph );
2359 glyph = NULL;
2360
2361 if ( !destroy )
2362 *pglyph = NULL;
2363
2364 Exit:
2365 return error;
2366 }
void destroy(_Tp *__pointer)
Definition: _construct.h:278
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
int Fail
Definition: ehthrow.cxx:24
FT_Done_Glyph(FT_Glyph glyph)
Definition: ftglyph.c:640
FT_Glyph_Copy(FT_Glyph source, FT_Glyph *target)
Definition: ftglyph.c:315
struct FT_OutlineGlyphRec_ * FT_OutlineGlyph
Definition: ftglyph.h:187
FT_Outline_New(FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:295
FT_Outline_Done(FT_Library library, FT_Outline *outline)
Definition: ftoutln.c:427
FT_Stroker_Export(FT_Stroker stroker, FT_Outline *outline)
Definition: ftstroke.c:2075
FT_Stroker_GetCounts(FT_Stroker stroker, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:2011
FT_CALLBACK_TABLE const FT_Glyph_Class ft_outline_glyph_class
Definition: ftstroke.c:30
FT_Stroker_ParseOutline(FT_Stroker stroker, FT_Outline *outline, FT_Bool opened)
Definition: ftstroke.c:2090
int FT_Error
Definition: fttypes.h:299
#define FT_ERR(e)
Definition: fttypes.h:599
unsigned int FT_UInt
Definition: fttypes.h:231
signed int FT_Int
Definition: fttypes.h:220
#define error(str)
Definition: mkdosfs.c:1605
static void Exit(void)
Definition: sock.c:1330
FT_Library library
Definition: ftglyph.h:115
const FT_Glyph_Class * clazz
Definition: ftglyph.h:116
FT_Outline outline
Definition: ftglyph.h:221
Definition: mesh.c:5330

◆ FT_Glyph_StrokeBorder()

FT_Glyph_StrokeBorder ( FT_Glyph pglyph,
FT_Stroker  stroker,
FT_Bool  inside,
FT_Bool  destroy 
)

Definition at line 2372 of file ftstroke.c.

2376 {
2377 FT_Error error = FT_ERR( Invalid_Argument );
2378 FT_Glyph glyph = NULL;
2379
2380
2381 if ( !pglyph )
2382 goto Exit;
2383
2384 glyph = *pglyph;
2385 if ( !glyph || glyph->clazz != &ft_outline_glyph_class )
2386 goto Exit;
2387
2388 {
2389 FT_Glyph copy;
2390
2391
2392 error = FT_Glyph_Copy( glyph, &copy );
2393 if ( error )
2394 goto Exit;
2395
2396 glyph = copy;
2397 }
2398
2399 {
2400 FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph;
2402 FT_Outline* outline = &oglyph->outline;
2403 FT_UInt num_points, num_contours;
2404
2405
2407 if ( inside )
2408 {
2411 else
2413 }
2414
2416 if ( error )
2417 goto Fail;
2418
2420 &num_points, &num_contours );
2421
2422 FT_Outline_Done( glyph->library, outline );
2423
2424 error = FT_Outline_New( glyph->library,
2425 num_points,
2426 (FT_Int)num_contours,
2427 outline );
2428 if ( error )
2429 goto Fail;
2430
2431 outline->n_points = 0;
2432 outline->n_contours = 0;
2433
2435 }
2436
2437 if ( destroy )
2438 FT_Done_Glyph( *pglyph );
2439
2440 *pglyph = glyph;
2441 goto Exit;
2442
2443 Fail:
2444 FT_Done_Glyph( glyph );
2445 glyph = NULL;
2446
2447 if ( !destroy )
2448 *pglyph = NULL;
2449
2450 Exit:
2451 return error;
2452 }
FT_Stroker_GetBorderCounts(FT_Stroker stroker, FT_StrokerBorder border, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:1980
FT_Outline_GetOutsideBorder(FT_Outline *outline)
Definition: ftstroke.c:49
FT_Stroker_ExportBorder(FT_Stroker stroker, FT_StrokerBorder border, FT_Outline *outline)
Definition: ftstroke.c:2053
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546

◆ FT_Outline_GetInsideBorder()

FT_Outline_GetInsideBorder ( FT_Outline outline)

Definition at line 36 of file ftstroke.c.

37 {
39
40
43 }
@ FT_ORIENTATION_TRUETYPE
Definition: ftoutln.h:543
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1031
enum FT_Orientation_ FT_Orientation

◆ FT_Outline_GetOutsideBorder()

FT_Outline_GetOutsideBorder ( FT_Outline outline)

Definition at line 49 of file ftstroke.c.

Referenced by FT_Glyph_StrokeBorder().

◆ FT_Stroker_BeginSubPath()

FT_Stroker_BeginSubPath ( FT_Stroker  stroker,
FT_Vector to,
FT_Bool  open 
)

Definition at line 1785 of file ftstroke.c.

1788 {
1789 if ( !stroker || !to )
1790 return FT_THROW( Invalid_Argument );
1791
1792 /* We cannot process the first point, because there is not enough */
1793 /* information regarding its corner/cap. The latter will be processed */
1794 /* in the `FT_Stroker_EndSubPath' routine. */
1795 /* */
1796 stroker->first_point = TRUE;
1797 stroker->center = *to;
1798 stroker->subpath_open = open;
1799
1800 /* Determine if we need to check whether the border radius is greater */
1801 /* than the radius of curvature of a curve, to handle this case */
1802 /* specially. This is only required if bevel joins or butt caps may */
1803 /* be created, because round & miter joins and round & square caps */
1804 /* cover the negative sector created with wide strokes. */
1805 stroker->handle_wide_strokes =
1806 FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_ROUND ||
1807 ( stroker->subpath_open &&
1808 stroker->line_cap == FT_STROKER_LINECAP_BUTT ) );
1809
1810 /* record the subpath start point for each border */
1811 stroker->subpath_start = *to;
1812
1813 stroker->angle_in = 0;
1814
1815 return FT_Err_Ok;
1816 }
#define open
Definition: acwin.h:95
#define TRUE
Definition: types.h:120
return FT_Err_Ok
Definition: ftbbox.c:527
#define FT_THROW(e)
Definition: ftdebug.h:241
#define FT_BOOL(x)
Definition: fttypes.h:591

Referenced by FT_Stroker_ParseOutline().

◆ FT_Stroker_ConicTo()

FT_Stroker_ConicTo ( FT_Stroker  stroker,
FT_Vector control,
FT_Vector to 
)

Definition at line 1368 of file ftstroke.c.

1371 {
1373 FT_Vector bez_stack[34];
1374 FT_Vector* arc;
1375 FT_Vector* limit = bez_stack + 30;
1376 FT_Bool first_arc = TRUE;
1377
1378
1379 if ( !stroker || !control || !to )
1380 {
1381 error = FT_THROW( Invalid_Argument );
1382 goto Exit;
1383 }
1384
1385 /* if all control points are coincident, this is a no-op; */
1386 /* avoid creating a spurious corner */
1387 if ( FT_IS_SMALL( stroker->center.x - control->x ) &&
1388 FT_IS_SMALL( stroker->center.y - control->y ) &&
1389 FT_IS_SMALL( control->x - to->x ) &&
1390 FT_IS_SMALL( control->y - to->y ) )
1391 {
1392 stroker->center = *to;
1393 goto Exit;
1394 }
1395
1396 arc = bez_stack;
1397 arc[0] = *to;
1398 arc[1] = *control;
1399 arc[2] = stroker->center;
1400
1401 while ( arc >= bez_stack )
1402 {
1403 FT_Angle angle_in, angle_out;
1404
1405
1406 /* initialize with current direction */
1407 angle_in = angle_out = stroker->angle_in;
1408
1409 if ( arc < limit &&
1410 !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) )
1411 {
1412 if ( stroker->first_point )
1413 stroker->angle_in = angle_in;
1414
1415 ft_conic_split( arc );
1416 arc += 2;
1417 continue;
1418 }
1419
1420 if ( first_arc )
1421 {
1422 first_arc = FALSE;
1423
1424 /* process corner if necessary */
1425 if ( stroker->first_point )
1426 error = ft_stroker_subpath_start( stroker, angle_in, 0 );
1427 else
1428 {
1429 stroker->angle_out = angle_in;
1430 error = ft_stroker_process_corner( stroker, 0 );
1431 }
1432 }
1433 else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) >
1435 {
1436 /* if the deviation from one arc to the next is too great, */
1437 /* add a round corner */
1438 stroker->center = arc[2];
1439 stroker->angle_out = angle_in;
1440 stroker->line_join = FT_STROKER_LINEJOIN_ROUND;
1441
1442 error = ft_stroker_process_corner( stroker, 0 );
1443
1444 /* reinstate line join style */
1445 stroker->line_join = stroker->line_join_saved;
1446 }
1447
1448 if ( error )
1449 goto Exit;
1450
1451 /* the arc's angle is small enough; we can add it directly to each */
1452 /* border */
1453 {
1455 FT_Angle theta, phi, rotate, alpha0 = 0;
1458 FT_Int side;
1459
1460
1461 theta = FT_Angle_Diff( angle_in, angle_out ) / 2;
1462 phi = angle_in + theta;
1463 length = FT_DivFix( stroker->radius, FT_Cos( theta ) );
1464
1465 /* compute direction of original arc */
1466 if ( stroker->handle_wide_strokes )
1467 alpha0 = FT_Atan2( arc[0].x - arc[2].x, arc[0].y - arc[2].y );
1468
1469 for ( border = stroker->borders, side = 0;
1470 side <= 1;
1471 side++, border++ )
1472 {
1473 rotate = FT_SIDE_TO_ROTATE( side );
1474
1475 /* compute control point */
1477 ctrl.x += arc[1].x;
1478 ctrl.y += arc[1].y;
1479
1480 /* compute end point */
1481 FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate );
1482 end.x += arc[0].x;
1483 end.y += arc[0].y;
1484
1485 if ( stroker->handle_wide_strokes )
1486 {
1488 FT_Angle alpha1;
1489
1490
1491 /* determine whether the border radius is greater than the */
1492 /* radius of curvature of the original arc */
1493 start = border->points[border->num_points - 1];
1494
1495 alpha1 = FT_Atan2( end.x - start.x, end.y - start.y );
1496
1497 /* is the direction of the border arc opposite to */
1498 /* that of the original arc? */
1499 if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) >
1500 FT_ANGLE_PI / 2 )
1501 {
1502 FT_Angle beta, gamma;
1503 FT_Vector bvec, delta;
1504 FT_Fixed blen, sinA, sinB, alen;
1505
1506
1507 /* use the sine rule to find the intersection point */
1508 beta = FT_Atan2( arc[2].x - start.x, arc[2].y - start.y );
1509 gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y );
1510
1511 bvec.x = end.x - start.x;
1512 bvec.y = end.y - start.y;
1513
1514 blen = FT_Vector_Length( &bvec );
1515
1516 sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) );
1517 sinB = ft_pos_abs( FT_Sin( beta - gamma ) );
1518
1519 alen = FT_MulDiv( blen, sinA, sinB );
1520
1521 FT_Vector_From_Polar( &delta, alen, beta );
1522 delta.x += start.x;
1523 delta.y += start.y;
1524
1525 /* circumnavigate the negative sector backwards */
1526 border->movable = FALSE;
1528 if ( error )
1529 goto Exit;
1531 if ( error )
1532 goto Exit;
1534 if ( error )
1535 goto Exit;
1536 /* and then move to the endpoint */
1538 if ( error )
1539 goto Exit;
1540
1541 continue;
1542 }
1543
1544 /* else fall through */
1545 }
1546
1547 /* simply add an arc */
1549 if ( error )
1550 goto Exit;
1551 }
1552 }
1553
1554 arc -= 2;
1555
1556 stroker->angle_in = angle_out;
1557 }
1558
1559 stroker->center = *to;
1560
1561 Exit:
1562 return error;
1563 }
_STLP_MOVE_TO_STD_NAMESPACE void rotate(_ForwardIter __first, _ForwardIter __middle, _ForwardIter __last)
Definition: _algo.c:519
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
static void ft_conic_split(FT_Vector *base)
Definition: ftstroke.c:83
#define FT_SIDE_TO_ROTATE(s)
Definition: ftstroke.c:766
static FT_Bool ft_conic_is_small_enough(FT_Vector *base, FT_Angle *angle_in, FT_Angle *angle_out)
Definition: ftstroke.c:103
static FT_Error ft_stroke_border_conicto(FT_StrokeBorder border, FT_Vector *control, FT_Vector *to)
Definition: ftstroke.c:461
static FT_Error ft_stroker_process_corner(FT_Stroker stroker, FT_Fixed line_length)
Definition: ftstroke.c:1217
#define FT_IS_SMALL(x)
Definition: ftstroke.c:72
#define FT_SMALL_CONIC_THRESHOLD
Definition: ftstroke.c:67
static FT_Error ft_stroke_border_lineto(FT_StrokeBorder border, FT_Vector *to, FT_Bool movable)
Definition: ftstroke.c:419
static FT_Error ft_stroker_subpath_start(FT_Stroker stroker, FT_Angle start_angle, FT_Fixed line_length)
Definition: ftstroke.c:1251
static FT_Pos ft_pos_abs(FT_Pos x)
Definition: ftstroke.c:76
FT_Vector_From_Polar(FT_Vector *vec, FT_Fixed length, FT_Angle angle)
Definition: fttrigon.c:485
FT_BEGIN_HEADER typedef FT_Fixed FT_Angle
Definition: fttrigon.h:52
#define FT_ANGLE_PI
Definition: fttrigon.h:64
FT_Atan2(FT_Fixed x, FT_Fixed y)
Definition: fttrigon.c:340
FT_Vector_Length(FT_Vector *vec)
Definition: fttrigon.c:418
FT_Angle_Diff(FT_Angle angle1, FT_Angle angle2)
Definition: fttrigon.c:502
FT_Sin(FT_Angle angle)
Definition: fttrigon.c:312
FT_Cos(FT_Angle angle)
Definition: fttrigon.c:298
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_Fixed
Definition: fttypes.h:287
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint limit
Definition: glext.h:10326
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
#define ctrl
Definition: input.c:1756
FT_Pos x
Definition: ftimage.h:78
FT_Pos y
Definition: ftimage.h:79
Definition: dialog.c:52

Referenced by FT_Stroker_ParseOutline().

◆ FT_Stroker_CubicTo()

FT_Stroker_CubicTo ( FT_Stroker  stroker,
FT_Vector control1,
FT_Vector control2,
FT_Vector to 
)

Definition at line 1569 of file ftstroke.c.

1573 {
1575 FT_Vector bez_stack[37];
1576 FT_Vector* arc;
1577 FT_Vector* limit = bez_stack + 32;
1578 FT_Bool first_arc = TRUE;
1579
1580
1581 if ( !stroker || !control1 || !control2 || !to )
1582 {
1583 error = FT_THROW( Invalid_Argument );
1584 goto Exit;
1585 }
1586
1587 /* if all control points are coincident, this is a no-op; */
1588 /* avoid creating a spurious corner */
1589 if ( FT_IS_SMALL( stroker->center.x - control1->x ) &&
1590 FT_IS_SMALL( stroker->center.y - control1->y ) &&
1591 FT_IS_SMALL( control1->x - control2->x ) &&
1592 FT_IS_SMALL( control1->y - control2->y ) &&
1593 FT_IS_SMALL( control2->x - to->x ) &&
1594 FT_IS_SMALL( control2->y - to->y ) )
1595 {
1596 stroker->center = *to;
1597 goto Exit;
1598 }
1599
1600 arc = bez_stack;
1601 arc[0] = *to;
1602 arc[1] = *control2;
1603 arc[2] = *control1;
1604 arc[3] = stroker->center;
1605
1606 while ( arc >= bez_stack )
1607 {
1608 FT_Angle angle_in, angle_mid, angle_out;
1609
1610
1611 /* initialize with current direction */
1612 angle_in = angle_out = angle_mid = stroker->angle_in;
1613
1614 if ( arc < limit &&
1615 !ft_cubic_is_small_enough( arc, &angle_in,
1616 &angle_mid, &angle_out ) )
1617 {
1618 if ( stroker->first_point )
1619 stroker->angle_in = angle_in;
1620
1621 ft_cubic_split( arc );
1622 arc += 3;
1623 continue;
1624 }
1625
1626 if ( first_arc )
1627 {
1628 first_arc = FALSE;
1629
1630 /* process corner if necessary */
1631 if ( stroker->first_point )
1632 error = ft_stroker_subpath_start( stroker, angle_in, 0 );
1633 else
1634 {
1635 stroker->angle_out = angle_in;
1636 error = ft_stroker_process_corner( stroker, 0 );
1637 }
1638 }
1639 else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) >
1641 {
1642 /* if the deviation from one arc to the next is too great, */
1643 /* add a round corner */
1644 stroker->center = arc[3];
1645 stroker->angle_out = angle_in;
1646 stroker->line_join = FT_STROKER_LINEJOIN_ROUND;
1647
1648 error = ft_stroker_process_corner( stroker, 0 );
1649
1650 /* reinstate line join style */
1651 stroker->line_join = stroker->line_join_saved;
1652 }
1653
1654 if ( error )
1655 goto Exit;
1656
1657 /* the arc's angle is small enough; we can add it directly to each */
1658 /* border */
1659 {
1660 FT_Vector ctrl1, ctrl2, end;
1661 FT_Angle theta1, phi1, theta2, phi2, rotate, alpha0 = 0;
1662 FT_Fixed length1, length2;
1664 FT_Int side;
1665
1666
1667 theta1 = FT_Angle_Diff( angle_in, angle_mid ) / 2;
1668 theta2 = FT_Angle_Diff( angle_mid, angle_out ) / 2;
1669 phi1 = ft_angle_mean( angle_in, angle_mid );
1670 phi2 = ft_angle_mean( angle_mid, angle_out );
1671 length1 = FT_DivFix( stroker->radius, FT_Cos( theta1 ) );
1672 length2 = FT_DivFix( stroker->radius, FT_Cos( theta2 ) );
1673
1674 /* compute direction of original arc */
1675 if ( stroker->handle_wide_strokes )
1676 alpha0 = FT_Atan2( arc[0].x - arc[3].x, arc[0].y - arc[3].y );
1677
1678 for ( border = stroker->borders, side = 0;
1679 side <= 1;
1680 side++, border++ )
1681 {
1682 rotate = FT_SIDE_TO_ROTATE( side );
1683
1684 /* compute control points */
1685 FT_Vector_From_Polar( &ctrl1, length1, phi1 + rotate );
1686 ctrl1.x += arc[2].x;
1687 ctrl1.y += arc[2].y;
1688
1689 FT_Vector_From_Polar( &ctrl2, length2, phi2 + rotate );
1690 ctrl2.x += arc[1].x;
1691 ctrl2.y += arc[1].y;
1692
1693 /* compute end point */
1694 FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate );
1695 end.x += arc[0].x;
1696 end.y += arc[0].y;
1697
1698 if ( stroker->handle_wide_strokes )
1699 {
1701 FT_Angle alpha1;
1702
1703
1704 /* determine whether the border radius is greater than the */
1705 /* radius of curvature of the original arc */
1706 start = border->points[border->num_points - 1];
1707
1708 alpha1 = FT_Atan2( end.x - start.x, end.y - start.y );
1709
1710 /* is the direction of the border arc opposite to */
1711 /* that of the original arc? */
1712 if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) >
1713 FT_ANGLE_PI / 2 )
1714 {
1715 FT_Angle beta, gamma;
1716 FT_Vector bvec, delta;
1717 FT_Fixed blen, sinA, sinB, alen;
1718
1719
1720 /* use the sine rule to find the intersection point */
1721 beta = FT_Atan2( arc[3].x - start.x, arc[3].y - start.y );
1722 gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y );
1723
1724 bvec.x = end.x - start.x;
1725 bvec.y = end.y - start.y;
1726
1727 blen = FT_Vector_Length( &bvec );
1728
1729 sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) );
1730 sinB = ft_pos_abs( FT_Sin( beta - gamma ) );
1731
1732 alen = FT_MulDiv( blen, sinA, sinB );
1733
1734 FT_Vector_From_Polar( &delta, alen, beta );
1735 delta.x += start.x;
1736 delta.y += start.y;
1737
1738 /* circumnavigate the negative sector backwards */
1739 border->movable = FALSE;
1741 if ( error )
1742 goto Exit;
1744 if ( error )
1745 goto Exit;
1747 &ctrl2,
1748 &ctrl1,
1749 &start );
1750 if ( error )
1751 goto Exit;
1752 /* and then move to the endpoint */
1754 if ( error )
1755 goto Exit;
1756
1757 continue;
1758 }
1759
1760 /* else fall through */
1761 }
1762
1763 /* simply add an arc */
1764 error = ft_stroke_border_cubicto( border, &ctrl1, &ctrl2, &end );
1765 if ( error )
1766 goto Exit;
1767 }
1768 }
1769
1770 arc -= 3;
1771
1772 stroker->angle_in = angle_out;
1773 }
1774
1775 stroker->center = *to;
1776
1777 Exit:
1778 return error;
1779 }
static FT_Error ft_stroke_border_cubicto(FT_StrokeBorder border, FT_Vector *control1, FT_Vector *control2, FT_Vector *to)
Definition: ftstroke.c:493
static FT_Bool ft_cubic_is_small_enough(FT_Vector *base, FT_Angle *angle_in, FT_Angle *angle_mid, FT_Angle *angle_out)
Definition: ftstroke.c:193
static void ft_cubic_split(FT_Vector *base)
Definition: ftstroke.c:154
static FT_Angle ft_angle_mean(FT_Angle angle1, FT_Angle angle2)
Definition: ftstroke.c:185
#define FT_SMALL_CUBIC_THRESHOLD
Definition: ftstroke.c:68

Referenced by FT_Stroker_ParseOutline().

◆ FT_Stroker_Done()

FT_Stroker_Done ( FT_Stroker  stroker)

Definition at line 871 of file ftstroke.c.

872 {
873 if ( stroker )
874 {
875 FT_Memory memory = stroker->library->memory;
876
877
878 ft_stroke_border_done( &stroker->borders[0] );
879 ft_stroke_border_done( &stroker->borders[1] );
880
881 stroker->library = NULL;
882 FT_FREE( stroker );
883 }
884 }
#define FT_FREE(ptr)
Definition: ftmemory.h:328
static void ft_stroke_border_done(FT_StrokeBorder border)
Definition: ftstroke.c:640
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:65
static char memory[1024 *256]
Definition: process.c:116

◆ FT_Stroker_EndSubPath()

FT_Stroker_EndSubPath ( FT_Stroker  stroker)

Definition at line 1887 of file ftstroke.c.

1888 {
1890
1891
1892 if ( !stroker )
1893 {
1894 error = FT_THROW( Invalid_Argument );
1895 goto Exit;
1896 }
1897
1898 if ( stroker->subpath_open )
1899 {
1900 FT_StrokeBorder right = stroker->borders;
1901
1902
1903 /* All right, this is an opened path, we need to add a cap between */
1904 /* right & left, add the reverse of left, then add a final cap */
1905 /* between left & right. */
1906 error = ft_stroker_cap( stroker, stroker->angle_in, 0 );
1907 if ( error )
1908 goto Exit;
1909
1910 /* add reversed points from `left' to `right' */
1912 if ( error )
1913 goto Exit;
1914
1915 /* now add the final cap */
1916 stroker->center = stroker->subpath_start;
1917 error = ft_stroker_cap( stroker,
1918 stroker->subpath_angle + FT_ANGLE_PI, 0 );
1919 if ( error )
1920 goto Exit;
1921
1922 /* Now end the right subpath accordingly. The left one is */
1923 /* rewind and doesn't need further processing. */
1925 }
1926 else
1927 {
1928 FT_Angle turn;
1929 FT_Int inside_side;
1930
1931
1932 /* close the path if needed */
1933 if ( stroker->center.x != stroker->subpath_start.x ||
1934 stroker->center.y != stroker->subpath_start.y )
1935 {
1936 error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );
1937 if ( error )
1938 goto Exit;
1939 }
1940
1941 /* process the corner */
1942 stroker->angle_out = stroker->subpath_angle;
1943 turn = FT_Angle_Diff( stroker->angle_in,
1944 stroker->angle_out );
1945
1946 /* no specific corner processing is required if the turn is 0 */
1947 if ( turn != 0 )
1948 {
1949 /* when we turn to the right, the inside side is 0 */
1950 /* otherwise, the inside side is 1 */
1951 inside_side = ( turn < 0 );
1952
1953 error = ft_stroker_inside( stroker,
1954 inside_side,
1955 stroker->subpath_line_length );
1956 if ( error )
1957 goto Exit;
1958
1959 /* process the outside side */
1960 error = ft_stroker_outside( stroker,
1961 !inside_side,
1962 stroker->subpath_line_length );
1963 if ( error )
1964 goto Exit;
1965 }
1966
1967 /* then end our two subpaths */
1968 ft_stroke_border_close( stroker->borders + 0, FALSE );
1969 ft_stroke_border_close( stroker->borders + 1, TRUE );
1970 }
1971
1972 Exit:
1973 return error;
1974 }
FT_Stroker_LineTo(FT_Stroker stroker, FT_Vector *to)
Definition: ftstroke.c:1292
static FT_Error ft_stroker_inside(FT_Stroker stroker, FT_Int side, FT_Fixed line_length)
Definition: ftstroke.c:991
static FT_Error ft_stroker_cap(FT_Stroker stroker, FT_Angle angle, FT_Int side)
Definition: ftstroke.c:916
static FT_Error ft_stroker_outside(FT_Stroker stroker, FT_Int side, FT_Fixed line_length)
Definition: ftstroke.c:1056
static void ft_stroke_border_close(FT_StrokeBorder border, FT_Bool reverse)
Definition: ftstroke.c:352
static FT_Error ft_stroker_add_reverse_left(FT_Stroker stroker, FT_Bool open)
Definition: ftstroke.c:1820
GLdouble GLdouble right
Definition: glext.h:10859

Referenced by FT_Stroker_ParseOutline().

◆ FT_Stroker_Export()

FT_Stroker_Export ( FT_Stroker  stroker,
FT_Outline outline 
)

Definition at line 2075 of file ftstroke.c.

Referenced by FT_Glyph_Stroke().

◆ FT_Stroker_ExportBorder()

FT_Stroker_ExportBorder ( FT_Stroker  stroker,
FT_StrokerBorder  border,
FT_Outline outline 
)

Definition at line 2053 of file ftstroke.c.

2056 {
2057 if ( !stroker || !outline )
2058 return;
2059
2062 {
2063 FT_StrokeBorder sborder = & stroker->borders[border];
2064
2065
2066 if ( sborder->valid )
2067 ft_stroke_border_export( sborder, outline );
2068 }
2069 }
static void ft_stroke_border_export(FT_StrokeBorder border, FT_Outline *outline)
Definition: ftstroke.c:707

Referenced by FT_Glyph_StrokeBorder(), and FT_Stroker_Export().

◆ FT_Stroker_GetBorderCounts()

FT_Stroker_GetBorderCounts ( FT_Stroker  stroker,
FT_StrokerBorder  border,
FT_UInt anum_points,
FT_UInt anum_contours 
)

Definition at line 1980 of file ftstroke.c.

1984 {
1985 FT_UInt num_points = 0, num_contours = 0;
1987
1988
1989 if ( !stroker || border > 1 )
1990 {
1991 error = FT_THROW( Invalid_Argument );
1992 goto Exit;
1993 }
1994
1995 error = ft_stroke_border_get_counts( stroker->borders + border,
1996 &num_points, &num_contours );
1997 Exit:
1998 if ( anum_points )
1999 *anum_points = num_points;
2000
2001 if ( anum_contours )
2002 *anum_contours = num_contours;
2003
2004 return error;
2005 }
static FT_Error ft_stroke_border_get_counts(FT_StrokeBorder border, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:656

Referenced by FT_Glyph_StrokeBorder().

◆ FT_Stroker_GetCounts()

FT_Stroker_GetCounts ( FT_Stroker  stroker,
FT_UInt anum_points,
FT_UInt anum_contours 
)

Definition at line 2011 of file ftstroke.c.

2014 {
2015 FT_UInt count1, count2, num_points = 0;
2016 FT_UInt count3, count4, num_contours = 0;
2018
2019
2020 if ( !stroker )
2021 {
2022 error = FT_THROW( Invalid_Argument );
2023 goto Exit;
2024 }
2025
2026 error = ft_stroke_border_get_counts( stroker->borders + 0,
2027 &count1, &count2 );
2028 if ( error )
2029 goto Exit;
2030
2031 error = ft_stroke_border_get_counts( stroker->borders + 1,
2032 &count3, &count4 );
2033 if ( error )
2034 goto Exit;
2035
2036 num_points = count1 + count3;
2037 num_contours = count2 + count4;
2038
2039 Exit:
2040 if ( anum_points )
2041 *anum_points = num_points;
2042
2043 if ( anum_contours )
2044 *anum_contours = num_contours;
2045
2046 return error;
2047 }

Referenced by FT_Glyph_Stroke().

◆ FT_Stroker_LineTo()

FT_Stroker_LineTo ( FT_Stroker  stroker,
FT_Vector to 
)

Definition at line 1292 of file ftstroke.c.

1294 {
1297 FT_Vector delta;
1299 FT_Int side;
1300 FT_Fixed line_length;
1301
1302
1303 if ( !stroker || !to )
1304 return FT_THROW( Invalid_Argument );
1305
1306 delta.x = to->x - stroker->center.x;
1307 delta.y = to->y - stroker->center.y;
1308
1309 /* a zero-length lineto is a no-op; avoid creating a spurious corner */
1310 if ( delta.x == 0 && delta.y == 0 )
1311 goto Exit;
1312
1313 /* compute length of line */
1314 line_length = FT_Vector_Length( &delta );
1315
1316 angle = FT_Atan2( delta.x, delta.y );
1317 FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 );
1318
1319 /* process corner if necessary */
1320 if ( stroker->first_point )
1321 {
1322 /* This is the first segment of a subpath. We need to */
1323 /* add a point to each border at their respective starting */
1324 /* point locations. */
1325 error = ft_stroker_subpath_start( stroker, angle, line_length );
1326 if ( error )
1327 goto Exit;
1328 }
1329 else
1330 {
1331 /* process the current corner */
1332 stroker->angle_out = angle;
1333 error = ft_stroker_process_corner( stroker, line_length );
1334 if ( error )
1335 goto Exit;
1336 }
1337
1338 /* now add a line segment to both the `inside' and `outside' paths */
1339 for ( border = stroker->borders, side = 1; side >= 0; side--, border++ )
1340 {
1342
1343
1344 point.x = to->x + delta.x;
1345 point.y = to->y + delta.y;
1346
1347 /* the ends of lineto borders are movable */
1349 if ( error )
1350 goto Exit;
1351
1352 delta.x = -delta.x;
1353 delta.y = -delta.y;
1354 }
1355
1356 stroker->angle_in = angle;
1357 stroker->center = *to;
1358 stroker->line_length = line_length;
1359
1360 Exit:
1361 return error;
1362 }
POINTL point
Definition: edittest.c:50
#define FT_ANGLE_PI2
Definition: fttrigon.h:88
GLfloat angle
Definition: glext.h:10853
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329

Referenced by FT_Stroker_EndSubPath(), and FT_Stroker_ParseOutline().

◆ FT_Stroker_New()

FT_Stroker_New ( FT_Library  library,
FT_Stroker astroker 
)

Definition at line 796 of file ftstroke.c.

798 {
799 FT_Error error; /* assigned in FT_NEW */
801 FT_Stroker stroker = NULL;
802
803
804 if ( !library )
805 return FT_THROW( Invalid_Library_Handle );
806
807 if ( !astroker )
808 return FT_THROW( Invalid_Argument );
809
811
812 if ( !FT_NEW( stroker ) )
813 {
814 stroker->library = library;
815
816 ft_stroke_border_init( &stroker->borders[0], memory );
817 ft_stroke_border_init( &stroker->borders[1], memory );
818 }
819
820 *astroker = stroker;
821
822 return error;
823 }
FT_Library library
Definition: cffdrivr.c:661
#define FT_NEW(ptr)
Definition: ftmemory.h:330
static void ft_stroke_border_init(FT_StrokeBorder border, FT_Memory memory)
Definition: ftstroke.c:616
typedefFT_BEGIN_HEADER struct FT_StrokerRec_ * FT_Stroker
Definition: ftstroke.h:92
FT_Memory memory
Definition: ftobjs.h:897

◆ FT_Stroker_ParseOutline()

FT_Stroker_ParseOutline ( FT_Stroker  stroker,
FT_Outline outline,
FT_Bool  opened 
)

Definition at line 2090 of file ftstroke.c.

2093 {
2094 FT_Vector v_last;
2095 FT_Vector v_control;
2096 FT_Vector v_start;
2097
2100 char* tags;
2101
2103
2104 FT_Int n; /* index of contour in outline */
2105 FT_UInt first; /* index of first point in contour */
2106 FT_Int tag; /* current point's state */
2107
2108
2109 if ( !outline )
2110 return FT_THROW( Invalid_Outline );
2111
2112 if ( !stroker )
2113 return FT_THROW( Invalid_Argument );
2114
2115 FT_Stroker_Rewind( stroker );
2116
2117 first = 0;
2118
2119 for ( n = 0; n < outline->n_contours; n++ )
2120 {
2121 FT_UInt last; /* index of last point in contour */
2122
2123
2124 last = (FT_UInt)outline->contours[n];
2125 limit = outline->points + last;
2126
2127 /* skip empty points; we don't stroke these */
2128 if ( last <= first )
2129 {
2130 first = last + 1;
2131 continue;
2132 }
2133
2134 v_start = outline->points[first];
2135 v_last = outline->points[last];
2136
2137 v_control = v_start;
2138
2139 point = outline->points + first;
2140 tags = outline->tags + first;
2141 tag = FT_CURVE_TAG( tags[0] );
2142
2143 /* A contour cannot start with a cubic control point! */
2144 if ( tag == FT_CURVE_TAG_CUBIC )
2145 goto Invalid_Outline;
2146
2147 /* check first point to determine origin */
2148 if ( tag == FT_CURVE_TAG_CONIC )
2149 {
2150 /* First point is conic control. Yes, this happens. */
2151 if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
2152 {
2153 /* start at last point if it is on the curve */
2154 v_start = v_last;
2155 limit--;
2156 }
2157 else
2158 {
2159 /* if both first and last points are conic, */
2160 /* start at their middle */
2161 v_start.x = ( v_start.x + v_last.x ) / 2;
2162 v_start.y = ( v_start.y + v_last.y ) / 2;
2163 }
2164 point--;
2165 tags--;
2166 }
2167
2168 error = FT_Stroker_BeginSubPath( stroker, &v_start, opened );
2169 if ( error )
2170 goto Exit;
2171
2172 while ( point < limit )
2173 {
2174 point++;
2175 tags++;
2176
2177 tag = FT_CURVE_TAG( tags[0] );
2178 switch ( tag )
2179 {
2180 case FT_CURVE_TAG_ON: /* emit a single line_to */
2181 {
2182 FT_Vector vec;
2183
2184
2185 vec.x = point->x;
2186 vec.y = point->y;
2187
2188 error = FT_Stroker_LineTo( stroker, &vec );
2189 if ( error )
2190 goto Exit;
2191 continue;
2192 }
2193
2194 case FT_CURVE_TAG_CONIC: /* consume conic arcs */
2195 v_control.x = point->x;
2196 v_control.y = point->y;
2197
2198 Do_Conic:
2199 if ( point < limit )
2200 {
2201 FT_Vector vec;
2202 FT_Vector v_middle;
2203
2204
2205 point++;
2206 tags++;
2207 tag = FT_CURVE_TAG( tags[0] );
2208
2209 vec = point[0];
2210
2211 if ( tag == FT_CURVE_TAG_ON )
2212 {
2213 error = FT_Stroker_ConicTo( stroker, &v_control, &vec );
2214 if ( error )
2215 goto Exit;
2216 continue;
2217 }
2218
2219 if ( tag != FT_CURVE_TAG_CONIC )
2220 goto Invalid_Outline;
2221
2222 v_middle.x = ( v_control.x + vec.x ) / 2;
2223 v_middle.y = ( v_control.y + vec.y ) / 2;
2224
2225 error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle );
2226 if ( error )
2227 goto Exit;
2228
2229 v_control = vec;
2230 goto Do_Conic;
2231 }
2232
2233 error = FT_Stroker_ConicTo( stroker, &v_control, &v_start );
2234 goto Close;
2235
2236 default: /* FT_CURVE_TAG_CUBIC */
2237 {
2238 FT_Vector vec1, vec2;
2239
2240
2241 if ( point + 1 > limit ||
2243 goto Invalid_Outline;
2244
2245 point += 2;
2246 tags += 2;
2247
2248 vec1 = point[-2];
2249 vec2 = point[-1];
2250
2251 if ( point <= limit )
2252 {
2253 FT_Vector vec;
2254
2255
2256 vec = point[0];
2257
2258 error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec );
2259 if ( error )
2260 goto Exit;
2261 continue;
2262 }
2263
2264 error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start );
2265 goto Close;
2266 }
2267 }
2268 }
2269
2270 Close:
2271 if ( error )
2272 goto Exit;
2273
2274 /* don't try to end the path if no segments have been generated */
2275 if ( !stroker->first_point )
2276 {
2277 error = FT_Stroker_EndSubPath( stroker );
2278 if ( error )
2279 goto Exit;
2280 }
2281
2282 first = last + 1;
2283 }
2284
2285 return FT_Err_Ok;
2286
2287 Exit:
2288 return error;
2289
2290 Invalid_Outline:
2291 return FT_THROW( Invalid_Outline );
2292 }
FT_Vector * vec
Definition: ftbbox.c:470
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:457
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:456
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:452
#define FT_CURVE_TAG_ON
Definition: ftimage.h:455
FT_Stroker_Rewind(FT_Stroker stroker)
Definition: ftstroke.c:858
FT_Stroker_CubicTo(FT_Stroker stroker, FT_Vector *control1, FT_Vector *control2, FT_Vector *to)
Definition: ftstroke.c:1569
FT_Stroker_BeginSubPath(FT_Stroker stroker, FT_Vector *to, FT_Bool open)
Definition: ftstroke.c:1785
FT_Stroker_ConicTo(FT_Stroker stroker, FT_Vector *control, FT_Vector *to)
Definition: ftstroke.c:1368
FT_Stroker_EndSubPath(FT_Stroker stroker)
Definition: ftstroke.c:1887
GLdouble n
Definition: glext.h:7729
const GLint * first
Definition: glext.h:5794
if(dx< 0)
Definition: linetemp.h:194
const char * tags[7 *8]
Definition: apphelp.c:216
static UINT UINT last
Definition: font.c:45
@ Close
Definition: sacdrv.h:268
Definition: ecma_167.h:138

Referenced by FT_Glyph_Stroke(), and FT_Glyph_StrokeBorder().

◆ FT_Stroker_Rewind()

FT_Stroker_Rewind ( FT_Stroker  stroker)

Definition at line 858 of file ftstroke.c.

859 {
860 if ( stroker )
861 {
862 ft_stroke_border_reset( &stroker->borders[0] );
863 ft_stroke_border_reset( &stroker->borders[1] );
864 }
865 }
static void ft_stroke_border_reset(FT_StrokeBorder border)
Definition: ftstroke.c:631

Referenced by FT_Stroker_ParseOutline(), and FT_Stroker_Set().

◆ FT_Stroker_Set()

FT_Stroker_Set ( FT_Stroker  stroker,
FT_Fixed  radius,
FT_Stroker_LineCap  line_cap,
FT_Stroker_LineJoin  line_join,
FT_Fixed  miter_limit 
)

Definition at line 829 of file ftstroke.c.

834 {
835 if ( !stroker )
836 return;
837
838 stroker->radius = radius;
839 stroker->line_cap = line_cap;
840 stroker->line_join = line_join;
841 stroker->miter_limit = miter_limit;
842
843 /* ensure miter limit has sensible value */
844 if ( stroker->miter_limit < 0x10000L )
845 stroker->miter_limit = 0x10000L;
846
847 /* save line join style: */
848 /* line join style can be temporarily changed when stroking curves */
849 stroker->line_join_saved = line_join;
850
851 FT_Stroker_Rewind( stroker );
852 }