ReactOS 0.4.16-dev-2332-g4cba65d
ftstroke.h File Reference
#include <freetype/ftoutln.h>
#include <freetype/ftglyph.h>
Include dependency graph for ftstroke.h:
This graph shows which files directly or indirectly include this file:

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 91 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 165 of file ftstroke.h.

166 {
170
@ FT_STROKER_LINECAP_ROUND
Definition: ftstroke.h:168
@ FT_STROKER_LINECAP_BUTT
Definition: ftstroke.h:167
@ FT_STROKER_LINECAP_SQUARE
Definition: ftstroke.h:169
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 134 of file ftstroke.h.

135 {
141
@ FT_STROKER_LINEJOIN_MITER
Definition: ftstroke.h:139
@ FT_STROKER_LINEJOIN_MITER_FIXED
Definition: ftstroke.h:140
@ FT_STROKER_LINEJOIN_BEVEL
Definition: ftstroke.h:137
@ FT_STROKER_LINEJOIN_MITER_VARIABLE
Definition: ftstroke.h:138
@ FT_STROKER_LINEJOIN_ROUND
Definition: ftstroke.h:136
enum FT_Stroker_LineJoin_ FT_Stroker_LineJoin

◆ FT_StrokerBorder_

Enumerator
FT_STROKER_BORDER_LEFT 
FT_STROKER_BORDER_RIGHT 

Definition at line 199 of file ftstroke.h.

200 {
203
@ FT_STROKER_BORDER_RIGHT
Definition: ftstroke.h:202
@ FT_STROKER_BORDER_LEFT
Definition: ftstroke.h:201
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 2270 of file ftstroke.c.

2273 {
2274 FT_Error error = FT_ERR( Invalid_Argument );
2275 FT_Glyph glyph = NULL;
2276
2277
2278 if ( !pglyph )
2279 goto Exit;
2280
2281 glyph = *pglyph;
2282 if ( !glyph || glyph->clazz != &ft_outline_glyph_class )
2283 goto Exit;
2284
2285 {
2286 FT_Glyph copy;
2287
2288
2289 error = FT_Glyph_Copy( glyph, &copy );
2290 if ( error )
2291 goto Exit;
2292
2293 glyph = copy;
2294 }
2295
2296 {
2297 FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph;
2298 FT_Outline* outline = &oglyph->outline;
2299 FT_UInt num_points, num_contours;
2300
2301
2303 if ( error )
2304 goto Fail;
2305
2306 FT_Stroker_GetCounts( stroker, &num_points, &num_contours );
2307
2308 FT_Outline_Done( glyph->library, outline );
2309
2310 error = FT_Outline_New( glyph->library,
2311 num_points,
2312 (FT_Int)num_contours,
2313 outline );
2314 if ( error )
2315 goto Fail;
2316
2317 outline->n_points = 0;
2318 outline->n_contours = 0;
2319
2320 FT_Stroker_Export( stroker, outline );
2321 }
2322
2323 if ( destroy )
2324 FT_Done_Glyph( *pglyph );
2325
2326 *pglyph = glyph;
2327 goto Exit;
2328
2329 Fail:
2330 FT_Done_Glyph( glyph );
2331 glyph = NULL;
2332
2333 if ( !destroy )
2334 *pglyph = NULL;
2335
2336 Exit:
2337 return error;
2338 }
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:641
FT_Glyph_Copy(FT_Glyph source, FT_Glyph *target)
Definition: ftglyph.c:316
struct FT_OutlineGlyphRec_ * FT_OutlineGlyph
Definition: ftglyph.h:186
FT_Outline_New(FT_Library library, FT_UInt numPoints, FT_Int numContours, FT_Outline *anoutline)
Definition: ftoutln.c:293
FT_Outline_Done(FT_Library library, FT_Outline *outline)
Definition: ftoutln.c:425
FT_Stroker_Export(FT_Stroker stroker, FT_Outline *outline)
Definition: ftstroke.c:2047
FT_Stroker_GetCounts(FT_Stroker stroker, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:1983
FT_CALLBACK_TABLE const FT_Glyph_Class ft_outline_glyph_class
Definition: ftstroke.c:29
FT_Stroker_ParseOutline(FT_Stroker stroker, FT_Outline *outline, FT_Bool opened)
Definition: ftstroke.c:2062
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:114
const FT_Glyph_Class * clazz
Definition: ftglyph.h:115
FT_Outline outline
Definition: ftglyph.h:220
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 2344 of file ftstroke.c.

2348 {
2349 FT_Error error = FT_ERR( Invalid_Argument );
2350 FT_Glyph glyph = NULL;
2351
2352
2353 if ( !pglyph )
2354 goto Exit;
2355
2356 glyph = *pglyph;
2357 if ( !glyph || glyph->clazz != &ft_outline_glyph_class )
2358 goto Exit;
2359
2360 {
2361 FT_Glyph copy;
2362
2363
2364 error = FT_Glyph_Copy( glyph, &copy );
2365 if ( error )
2366 goto Exit;
2367
2368 glyph = copy;
2369 }
2370
2371 {
2372 FT_OutlineGlyph oglyph = (FT_OutlineGlyph)glyph;
2374 FT_Outline* outline = &oglyph->outline;
2375 FT_UInt num_points, num_contours;
2376
2377
2379 if ( inside )
2380 {
2383 else
2385 }
2386
2388 if ( error )
2389 goto Fail;
2390
2392 &num_points, &num_contours );
2393
2394 FT_Outline_Done( glyph->library, outline );
2395
2396 error = FT_Outline_New( glyph->library,
2397 num_points,
2398 (FT_Int)num_contours,
2399 outline );
2400 if ( error )
2401 goto Fail;
2402
2403 outline->n_points = 0;
2404 outline->n_contours = 0;
2405
2407 }
2408
2409 if ( destroy )
2410 FT_Done_Glyph( *pglyph );
2411
2412 *pglyph = glyph;
2413 goto Exit;
2414
2415 Fail:
2416 FT_Done_Glyph( glyph );
2417 glyph = NULL;
2418
2419 if ( !destroy )
2420 *pglyph = NULL;
2421
2422 Exit:
2423 return error;
2424 }
FT_Stroker_GetBorderCounts(FT_Stroker stroker, FT_StrokerBorder border, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:1952
FT_Outline_GetOutsideBorder(FT_Outline *outline)
Definition: ftstroke.c:48
FT_Stroker_ExportBorder(FT_Stroker stroker, FT_StrokerBorder border, FT_Outline *outline)
Definition: ftstroke.c:2025
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546

◆ FT_Outline_GetInsideBorder()

FT_Outline_GetInsideBorder ( FT_Outline outline)

Definition at line 35 of file ftstroke.c.

36 {
38
39
42 }
@ FT_ORIENTATION_TRUETYPE
Definition: ftoutln.h:536
FT_Outline_Get_Orientation(FT_Outline *outline)
Definition: ftoutln.c:1039
enum FT_Orientation_ FT_Orientation

◆ FT_Outline_GetOutsideBorder()

FT_Outline_GetOutsideBorder ( FT_Outline outline)

Definition at line 48 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 1757 of file ftstroke.c.

1760 {
1761 if ( !stroker || !to )
1762 return FT_THROW( Invalid_Argument );
1763
1764 /* We cannot process the first point, because there is not enough */
1765 /* information regarding its corner/cap. The latter will be processed */
1766 /* in the `FT_Stroker_EndSubPath' routine. */
1767 /* */
1768 stroker->first_point = TRUE;
1769 stroker->center = *to;
1770 stroker->subpath_open = open;
1771
1772 /* Determine if we need to check whether the border radius is greater */
1773 /* than the radius of curvature of a curve, to handle this case */
1774 /* specially. This is only required if bevel joins or butt caps may */
1775 /* be created, because round & miter joins and round & square caps */
1776 /* cover the negative sector created with wide strokes. */
1777 stroker->handle_wide_strokes =
1778 FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_ROUND ||
1779 ( stroker->subpath_open &&
1780 stroker->line_cap == FT_STROKER_LINECAP_BUTT ) );
1781
1782 /* record the subpath start point for each border */
1783 stroker->subpath_start = *to;
1784
1785 stroker->angle_in = 0;
1786
1787 return FT_Err_Ok;
1788 }
#define TRUE
Definition: types.h:120
#define open
Definition: io.h:44
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_THROW(e)
Definition: ftdebug.h:243
#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 1340 of file ftstroke.c.

1343 {
1345 FT_Vector bez_stack[34];
1346 FT_Vector* arc;
1347 FT_Vector* limit = bez_stack + 30;
1348 FT_Bool first_arc = TRUE;
1349
1350
1351 if ( !stroker || !control || !to )
1352 {
1353 error = FT_THROW( Invalid_Argument );
1354 goto Exit;
1355 }
1356
1357 /* if all control points are coincident, this is a no-op; */
1358 /* avoid creating a spurious corner */
1359 if ( FT_IS_SMALL( stroker->center.x - control->x ) &&
1360 FT_IS_SMALL( stroker->center.y - control->y ) &&
1361 FT_IS_SMALL( control->x - to->x ) &&
1362 FT_IS_SMALL( control->y - to->y ) )
1363 {
1364 stroker->center = *to;
1365 goto Exit;
1366 }
1367
1368 arc = bez_stack;
1369 arc[0] = *to;
1370 arc[1] = *control;
1371 arc[2] = stroker->center;
1372
1373 while ( arc >= bez_stack )
1374 {
1375 FT_Angle angle_in, angle_out;
1376
1377
1378 /* initialize with current direction */
1379 angle_in = angle_out = stroker->angle_in;
1380
1381 if ( arc < limit &&
1382 !ft_conic_is_small_enough( arc, &angle_in, &angle_out ) )
1383 {
1384 if ( stroker->first_point )
1385 stroker->angle_in = angle_in;
1386
1387 ft_conic_split( arc );
1388 arc += 2;
1389 continue;
1390 }
1391
1392 if ( first_arc )
1393 {
1394 first_arc = FALSE;
1395
1396 /* process corner if necessary */
1397 if ( stroker->first_point )
1398 error = ft_stroker_subpath_start( stroker, angle_in, 0 );
1399 else
1400 {
1401 stroker->angle_out = angle_in;
1402 error = ft_stroker_process_corner( stroker, 0 );
1403 }
1404 }
1405 else if ( ft_pos_abs( FT_Angle_Diff( stroker->angle_in, angle_in ) ) >
1407 {
1408 /* if the deviation from one arc to the next is too great, */
1409 /* add a round corner */
1410 stroker->center = arc[2];
1411 stroker->angle_out = angle_in;
1412 stroker->line_join = FT_STROKER_LINEJOIN_ROUND;
1413
1414 error = ft_stroker_process_corner( stroker, 0 );
1415
1416 /* reinstate line join style */
1417 stroker->line_join = stroker->line_join_saved;
1418 }
1419
1420 if ( error )
1421 goto Exit;
1422
1423 /* the arc's angle is small enough; we can add it directly to each */
1424 /* border */
1425 {
1427 FT_Angle theta, phi, rotate, alpha0 = 0;
1430 FT_Int side;
1431
1432
1433 theta = FT_Angle_Diff( angle_in, angle_out ) / 2;
1434 phi = angle_in + theta;
1435 length = FT_DivFix( stroker->radius, FT_Cos( theta ) );
1436
1437 /* compute direction of original arc */
1438 if ( stroker->handle_wide_strokes )
1439 alpha0 = FT_Atan2( arc[0].x - arc[2].x, arc[0].y - arc[2].y );
1440
1441 for ( border = stroker->borders, side = 0;
1442 side <= 1;
1443 side++, border++ )
1444 {
1445 rotate = FT_SIDE_TO_ROTATE( side );
1446
1447 /* compute control point */
1449 ctrl.x += arc[1].x;
1450 ctrl.y += arc[1].y;
1451
1452 /* compute end point */
1453 FT_Vector_From_Polar( &end, stroker->radius, angle_out + rotate );
1454 end.x += arc[0].x;
1455 end.y += arc[0].y;
1456
1457 if ( stroker->handle_wide_strokes )
1458 {
1460 FT_Angle alpha1;
1461
1462
1463 /* determine whether the border radius is greater than the */
1464 /* radius of curvature of the original arc */
1465 start = border->points[border->num_points - 1];
1466
1467 alpha1 = FT_Atan2( end.x - start.x, end.y - start.y );
1468
1469 /* is the direction of the border arc opposite to */
1470 /* that of the original arc? */
1471 if ( ft_pos_abs( FT_Angle_Diff( alpha0, alpha1 ) ) >
1472 FT_ANGLE_PI / 2 )
1473 {
1474 FT_Angle beta, gamma;
1475 FT_Vector bvec, delta;
1476 FT_Fixed blen, sinA, sinB, alen;
1477
1478
1479 /* use the sine rule to find the intersection point */
1480 beta = FT_Atan2( arc[2].x - start.x, arc[2].y - start.y );
1481 gamma = FT_Atan2( arc[0].x - end.x, arc[0].y - end.y );
1482
1483 bvec.x = end.x - start.x;
1484 bvec.y = end.y - start.y;
1485
1486 blen = FT_Vector_Length( &bvec );
1487
1488 sinA = ft_pos_abs( FT_Sin( alpha1 - gamma ) );
1489 sinB = ft_pos_abs( FT_Sin( beta - gamma ) );
1490
1491 alen = FT_MulDiv( blen, sinA, sinB );
1492
1493 FT_Vector_From_Polar( &delta, alen, beta );
1494 delta.x += start.x;
1495 delta.y += start.y;
1496
1497 /* circumnavigate the negative sector backwards */
1498 border->movable = FALSE;
1500 if ( error )
1501 goto Exit;
1503 if ( error )
1504 goto Exit;
1506 if ( error )
1507 goto Exit;
1508 /* and then move to the endpoint */
1510 if ( error )
1511 goto Exit;
1512
1513 continue;
1514 }
1515
1516 /* else fall through */
1517 }
1518
1519 /* simply add an arc */
1521 if ( error )
1522 goto Exit;
1523 }
1524 }
1525
1526 arc -= 2;
1527
1528 stroker->angle_in = angle_out;
1529 }
1530
1531 stroker->center = *to;
1532
1533 Exit:
1534 return error;
1535 }
_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:607
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:415
static void ft_conic_split(FT_Vector *base)
Definition: ftstroke.c:82
#define FT_SIDE_TO_ROTATE(s)
Definition: ftstroke.c:760
static FT_Bool ft_conic_is_small_enough(FT_Vector *base, FT_Angle *angle_in, FT_Angle *angle_out)
Definition: ftstroke.c:104
static FT_Error ft_stroke_border_conicto(FT_StrokeBorder border, FT_Vector *control, FT_Vector *to)
Definition: ftstroke.c:466
static FT_Error ft_stroker_process_corner(FT_Stroker stroker, FT_Fixed line_length)
Definition: ftstroke.c:1189
#define FT_IS_SMALL(x)
Definition: ftstroke.c:71
#define FT_SMALL_CONIC_THRESHOLD
Definition: ftstroke.c:66
static FT_Error ft_stroke_border_lineto(FT_StrokeBorder border, FT_Vector *to, FT_Bool movable)
Definition: ftstroke.c:424
static FT_Error ft_stroker_subpath_start(FT_Stroker stroker, FT_Angle start_angle, FT_Fixed line_length)
Definition: ftstroke.c:1223
static FT_Pos ft_pos_abs(FT_Pos x)
Definition: ftstroke.c:75
FT_Vector_From_Polar(FT_Vector *vec, FT_Fixed length, FT_Angle angle)
Definition: fttrigon.c:484
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:339
FT_Vector_Length(FT_Vector *vec)
Definition: fttrigon.c:417
FT_Angle_Diff(FT_Angle angle1, FT_Angle angle2)
Definition: fttrigon.c:501
FT_Sin(FT_Angle angle)
Definition: fttrigon.c:311
FT_Cos(FT_Angle angle)
Definition: fttrigon.c:297
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:77
FT_Pos y
Definition: ftimage.h:78
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 1541 of file ftstroke.c.

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

Referenced by FT_Stroker_ParseOutline().

◆ FT_Stroker_Done()

FT_Stroker_Done ( FT_Stroker  stroker)

Definition at line 865 of file ftstroke.c.

866 {
867 if ( stroker )
868 {
869 FT_Memory memory = stroker->library->memory;
870
871
872 ft_stroke_border_done( &stroker->borders[0] );
873 ft_stroke_border_done( &stroker->borders[1] );
874
875 stroker->library = NULL;
876 FT_FREE( stroker );
877 }
878 }
#define FT_FREE(ptr)
Definition: ftmemory.h:337
static void ft_stroke_border_done(FT_StrokeBorder border)
Definition: ftstroke.c:634
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
static char memory[1024 *256]
Definition: process.c:122

◆ FT_Stroker_EndSubPath()

FT_Stroker_EndSubPath ( FT_Stroker  stroker)

Definition at line 1859 of file ftstroke.c.

1860 {
1862
1863
1864 if ( !stroker )
1865 {
1866 error = FT_THROW( Invalid_Argument );
1867 goto Exit;
1868 }
1869
1870 if ( stroker->subpath_open )
1871 {
1872 FT_StrokeBorder right = stroker->borders;
1873
1874
1875 /* All right, this is an opened path, we need to add a cap between */
1876 /* right & left, add the reverse of left, then add a final cap */
1877 /* between left & right. */
1878 error = ft_stroker_cap( stroker, stroker->angle_in, 0 );
1879 if ( error )
1880 goto Exit;
1881
1882 /* add reversed points from `left' to `right' */
1884 if ( error )
1885 goto Exit;
1886
1887 /* now add the final cap */
1888 stroker->center = stroker->subpath_start;
1889 error = ft_stroker_cap( stroker,
1890 stroker->subpath_angle + FT_ANGLE_PI, 0 );
1891 if ( error )
1892 goto Exit;
1893
1894 /* Now end the right subpath accordingly. The left one is */
1895 /* rewind and doesn't need further processing. */
1897 }
1898 else
1899 {
1900 FT_Angle turn;
1901 FT_Int inside_side;
1902
1903
1904 /* close the path if needed */
1905 if ( stroker->center.x != stroker->subpath_start.x ||
1906 stroker->center.y != stroker->subpath_start.y )
1907 {
1908 error = FT_Stroker_LineTo( stroker, &stroker->subpath_start );
1909 if ( error )
1910 goto Exit;
1911 }
1912
1913 /* process the corner */
1914 stroker->angle_out = stroker->subpath_angle;
1915 turn = FT_Angle_Diff( stroker->angle_in,
1916 stroker->angle_out );
1917
1918 /* no specific corner processing is required if the turn is 0 */
1919 if ( turn != 0 )
1920 {
1921 /* when we turn to the right, the inside side is 0 */
1922 /* otherwise, the inside side is 1 */
1923 inside_side = ( turn < 0 );
1924
1925 error = ft_stroker_inside( stroker,
1926 inside_side,
1927 stroker->subpath_line_length );
1928 if ( error )
1929 goto Exit;
1930
1931 /* process the outside side */
1932 error = ft_stroker_outside( stroker,
1933 !inside_side,
1934 stroker->subpath_line_length );
1935 if ( error )
1936 goto Exit;
1937 }
1938
1939 /* then end our two subpaths */
1940 ft_stroke_border_close( stroker->borders + 0, FALSE );
1941 ft_stroke_border_close( stroker->borders + 1, TRUE );
1942 }
1943
1944 Exit:
1945 return error;
1946 }
FT_Stroker_LineTo(FT_Stroker stroker, FT_Vector *to)
Definition: ftstroke.c:1264
static FT_Error ft_stroker_inside(FT_Stroker stroker, FT_Int side, FT_Fixed line_length)
Definition: ftstroke.c:970
static FT_Error ft_stroker_cap(FT_Stroker stroker, FT_Angle angle, FT_Int side)
Definition: ftstroke.c:910
static FT_Error ft_stroker_outside(FT_Stroker stroker, FT_Int side, FT_Fixed line_length)
Definition: ftstroke.c:1036
static void ft_stroke_border_close(FT_StrokeBorder border, FT_Bool reverse)
Definition: ftstroke.c:357
static FT_Error ft_stroker_add_reverse_left(FT_Stroker stroker, FT_Bool open)
Definition: ftstroke.c:1792
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 2047 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 2025 of file ftstroke.c.

2028 {
2029 if ( !stroker || !outline )
2030 return;
2031
2034 {
2035 FT_StrokeBorder sborder = & stroker->borders[border];
2036
2037
2038 if ( sborder->valid )
2039 ft_stroke_border_export( sborder, outline );
2040 }
2041 }
static void ft_stroke_border_export(FT_StrokeBorder border, FT_Outline *outline)
Definition: ftstroke.c:701

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 1952 of file ftstroke.c.

1956 {
1957 FT_UInt num_points = 0, num_contours = 0;
1959
1960
1961 if ( !stroker || border > 1 )
1962 {
1963 error = FT_THROW( Invalid_Argument );
1964 goto Exit;
1965 }
1966
1967 error = ft_stroke_border_get_counts( stroker->borders + border,
1968 &num_points, &num_contours );
1969 Exit:
1970 if ( anum_points )
1971 *anum_points = num_points;
1972
1973 if ( anum_contours )
1974 *anum_contours = num_contours;
1975
1976 return error;
1977 }
static FT_Error ft_stroke_border_get_counts(FT_StrokeBorder border, FT_UInt *anum_points, FT_UInt *anum_contours)
Definition: ftstroke.c:650

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 1983 of file ftstroke.c.

1986 {
1987 FT_UInt count1, count2, num_points = 0;
1988 FT_UInt count3, count4, num_contours = 0;
1990
1991
1992 if ( !stroker )
1993 {
1994 error = FT_THROW( Invalid_Argument );
1995 goto Exit;
1996 }
1997
1998 error = ft_stroke_border_get_counts( stroker->borders + 0,
1999 &count1, &count2 );
2000 if ( error )
2001 goto Exit;
2002
2003 error = ft_stroke_border_get_counts( stroker->borders + 1,
2004 &count3, &count4 );
2005 if ( error )
2006 goto Exit;
2007
2008 num_points = count1 + count3;
2009 num_contours = count2 + count4;
2010
2011 Exit:
2012 if ( anum_points )
2013 *anum_points = num_points;
2014
2015 if ( anum_contours )
2016 *anum_contours = num_contours;
2017
2018 return error;
2019 }

Referenced by FT_Glyph_Stroke().

◆ FT_Stroker_LineTo()

FT_Stroker_LineTo ( FT_Stroker  stroker,
FT_Vector to 
)

Definition at line 1264 of file ftstroke.c.

1266 {
1269 FT_Vector delta;
1271 FT_Int side;
1272 FT_Fixed line_length;
1273
1274
1275 if ( !stroker || !to )
1276 return FT_THROW( Invalid_Argument );
1277
1278 delta.x = to->x - stroker->center.x;
1279 delta.y = to->y - stroker->center.y;
1280
1281 /* a zero-length lineto is a no-op; avoid creating a spurious corner */
1282 if ( delta.x == 0 && delta.y == 0 )
1283 goto Exit;
1284
1285 /* compute length of line */
1286 line_length = FT_Vector_Length( &delta );
1287
1288 angle = FT_Atan2( delta.x, delta.y );
1289 FT_Vector_From_Polar( &delta, stroker->radius, angle + FT_ANGLE_PI2 );
1290
1291 /* process corner if necessary */
1292 if ( stroker->first_point )
1293 {
1294 /* This is the first segment of a subpath. We need to */
1295 /* add a point to each border at their respective starting */
1296 /* point locations. */
1297 error = ft_stroker_subpath_start( stroker, angle, line_length );
1298 if ( error )
1299 goto Exit;
1300 }
1301 else
1302 {
1303 /* process the current corner */
1304 stroker->angle_out = angle;
1305 error = ft_stroker_process_corner( stroker, line_length );
1306 if ( error )
1307 goto Exit;
1308 }
1309
1310 /* now add a line segment to both the `inside' and `outside' paths */
1311 for ( border = stroker->borders, side = 1; side >= 0; side--, border++ )
1312 {
1314
1315
1316 point.x = to->x + delta.x;
1317 point.y = to->y + delta.y;
1318
1319 /* the ends of lineto borders are movable */
1321 if ( error )
1322 goto Exit;
1323
1324 delta.x = -delta.x;
1325 delta.y = -delta.y;
1326 }
1327
1328 stroker->angle_in = angle;
1329 stroker->center = *to;
1330 stroker->line_length = line_length;
1331
1332 Exit:
1333 return error;
1334 }
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:130
LONG x
Definition: windef.h:129

Referenced by FT_Stroker_EndSubPath(), and FT_Stroker_ParseOutline().

◆ FT_Stroker_New()

FT_Stroker_New ( FT_Library  library,
FT_Stroker astroker 
)

Definition at line 790 of file ftstroke.c.

792 {
793 FT_Error error; /* assigned in FT_NEW */
795 FT_Stroker stroker = NULL;
796
797
798 if ( !library )
799 return FT_THROW( Invalid_Library_Handle );
800
801 if ( !astroker )
802 return FT_THROW( Invalid_Argument );
803
805
806 if ( !FT_NEW( stroker ) )
807 {
808 stroker->library = library;
809
810 ft_stroke_border_init( &stroker->borders[0], memory );
811 ft_stroke_border_init( &stroker->borders[1], memory );
812 }
813
814 *astroker = stroker;
815
816 return error;
817 }
FT_Library library
Definition: cffdrivr.c:660
#define FT_NEW(ptr)
Definition: ftmemory.h:339
static void ft_stroke_border_init(FT_StrokeBorder border, FT_Memory memory)
Definition: ftstroke.c:610
typedefFT_BEGIN_HEADER struct FT_StrokerRec_ * FT_Stroker
Definition: ftstroke.h:91
FT_Memory memory
Definition: ftobjs.h:895

◆ FT_Stroker_ParseOutline()

FT_Stroker_ParseOutline ( FT_Stroker  stroker,
FT_Outline outline,
FT_Bool  opened 
)

Definition at line 2062 of file ftstroke.c.

2065 {
2066 FT_Vector v_last;
2067 FT_Vector v_control;
2068 FT_Vector v_start;
2069
2072 char* tags;
2073
2075
2076 FT_Int n; /* index of contour in outline */
2077 FT_UInt first; /* index of first point in contour */
2078 FT_Int tag; /* current point's state */
2079
2080
2081 if ( !outline )
2082 return FT_THROW( Invalid_Outline );
2083
2084 if ( !stroker )
2085 return FT_THROW( Invalid_Argument );
2086
2087 FT_Stroker_Rewind( stroker );
2088
2089 first = 0;
2090
2091 for ( n = 0; n < outline->n_contours; n++ )
2092 {
2093 FT_UInt last; /* index of last point in contour */
2094
2095
2096 last = (FT_UInt)outline->contours[n];
2097 limit = outline->points + last;
2098
2099 /* skip empty points; we don't stroke these */
2100 if ( last <= first )
2101 {
2102 first = last + 1;
2103 continue;
2104 }
2105
2106 v_start = outline->points[first];
2107 v_last = outline->points[last];
2108
2109 v_control = v_start;
2110
2111 point = outline->points + first;
2112 tags = outline->tags + first;
2113 tag = FT_CURVE_TAG( tags[0] );
2114
2115 /* A contour cannot start with a cubic control point! */
2116 if ( tag == FT_CURVE_TAG_CUBIC )
2117 goto Invalid_Outline;
2118
2119 /* check first point to determine origin */
2120 if ( tag == FT_CURVE_TAG_CONIC )
2121 {
2122 /* First point is conic control. Yes, this happens. */
2123 if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
2124 {
2125 /* start at last point if it is on the curve */
2126 v_start = v_last;
2127 limit--;
2128 }
2129 else
2130 {
2131 /* if both first and last points are conic, */
2132 /* start at their middle */
2133 v_start.x = ( v_start.x + v_last.x ) / 2;
2134 v_start.y = ( v_start.y + v_last.y ) / 2;
2135 }
2136 point--;
2137 tags--;
2138 }
2139
2140 error = FT_Stroker_BeginSubPath( stroker, &v_start, opened );
2141 if ( error )
2142 goto Exit;
2143
2144 while ( point < limit )
2145 {
2146 point++;
2147 tags++;
2148
2149 tag = FT_CURVE_TAG( tags[0] );
2150 switch ( tag )
2151 {
2152 case FT_CURVE_TAG_ON: /* emit a single line_to */
2153 {
2154 FT_Vector vec;
2155
2156
2157 vec.x = point->x;
2158 vec.y = point->y;
2159
2160 error = FT_Stroker_LineTo( stroker, &vec );
2161 if ( error )
2162 goto Exit;
2163 continue;
2164 }
2165
2166 case FT_CURVE_TAG_CONIC: /* consume conic arcs */
2167 v_control.x = point->x;
2168 v_control.y = point->y;
2169
2170 Do_Conic:
2171 if ( point < limit )
2172 {
2173 FT_Vector vec;
2174 FT_Vector v_middle;
2175
2176
2177 point++;
2178 tags++;
2179 tag = FT_CURVE_TAG( tags[0] );
2180
2181 vec = point[0];
2182
2183 if ( tag == FT_CURVE_TAG_ON )
2184 {
2185 error = FT_Stroker_ConicTo( stroker, &v_control, &vec );
2186 if ( error )
2187 goto Exit;
2188 continue;
2189 }
2190
2191 if ( tag != FT_CURVE_TAG_CONIC )
2192 goto Invalid_Outline;
2193
2194 v_middle.x = ( v_control.x + vec.x ) / 2;
2195 v_middle.y = ( v_control.y + vec.y ) / 2;
2196
2197 error = FT_Stroker_ConicTo( stroker, &v_control, &v_middle );
2198 if ( error )
2199 goto Exit;
2200
2201 v_control = vec;
2202 goto Do_Conic;
2203 }
2204
2205 error = FT_Stroker_ConicTo( stroker, &v_control, &v_start );
2206 goto Close;
2207
2208 default: /* FT_CURVE_TAG_CUBIC */
2209 {
2210 FT_Vector vec1, vec2;
2211
2212
2213 if ( point + 1 > limit ||
2215 goto Invalid_Outline;
2216
2217 point += 2;
2218 tags += 2;
2219
2220 vec1 = point[-2];
2221 vec2 = point[-1];
2222
2223 if ( point <= limit )
2224 {
2225 FT_Vector vec;
2226
2227
2228 vec = point[0];
2229
2230 error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &vec );
2231 if ( error )
2232 goto Exit;
2233 continue;
2234 }
2235
2236 error = FT_Stroker_CubicTo( stroker, &vec1, &vec2, &v_start );
2237 goto Close;
2238 }
2239 }
2240 }
2241
2242 Close:
2243 if ( error )
2244 goto Exit;
2245
2246 /* don't try to end the path if no segments have been generated */
2247 if ( !stroker->first_point )
2248 {
2249 error = FT_Stroker_EndSubPath( stroker );
2250 if ( error )
2251 goto Exit;
2252 }
2253
2254 first = last + 1;
2255 }
2256
2257 return FT_Err_Ok;
2258
2259 Exit:
2260 return error;
2261
2262 Invalid_Outline:
2263 return FT_THROW( Invalid_Outline );
2264 }
FT_Vector * vec
Definition: ftbbox.c:469
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:464
#define FT_CURVE_TAG_CONIC
Definition: ftimage.h:463
#define FT_CURVE_TAG(flag)
Definition: ftimage.h:459
#define FT_CURVE_TAG_ON
Definition: ftimage.h:462
FT_Stroker_Rewind(FT_Stroker stroker)
Definition: ftstroke.c:852
FT_Stroker_CubicTo(FT_Stroker stroker, FT_Vector *control1, FT_Vector *control2, FT_Vector *to)
Definition: ftstroke.c:1541
FT_Stroker_BeginSubPath(FT_Stroker stroker, FT_Vector *to, FT_Bool open)
Definition: ftstroke.c:1757
FT_Stroker_ConicTo(FT_Stroker stroker, FT_Vector *control, FT_Vector *to)
Definition: ftstroke.c:1340
FT_Stroker_EndSubPath(FT_Stroker stroker)
Definition: ftstroke.c:1859
GLdouble n
Definition: glext.h:7729
const GLint * first
Definition: glext.h:5794
if(dx< 0)
Definition: linetemp.h:194
const char * tags[99]
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 852 of file ftstroke.c.

853 {
854 if ( stroker )
855 {
856 ft_stroke_border_reset( &stroker->borders[0] );
857 ft_stroke_border_reset( &stroker->borders[1] );
858 }
859 }
static void ft_stroke_border_reset(FT_StrokeBorder border)
Definition: ftstroke.c:625

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 823 of file ftstroke.c.

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