Oolite 1.91.0.7645-241119-222d325
Loading...
Searching...
No Matches
OOPolygonSprite.m File Reference
+ Include dependency graph for OOPolygonSprite.m:

Go to the source code of this file.

Classes

category  OOPolygonSprite(Private)
 
struct  TessPolygonData
 

Macros

#define APIENTRY
 
#define kCosMitreLimit   0.866f
 

Typedefs

typedef GLvoid(* TessFuncPtr) ()
 

Functions

static NSArray * DataArrayToPoints (TessPolygonData *data, NSArray *dataArray)
 
static NSArray * BuildOutlineContour (NSArray *dataArray, GLfloat width, BOOL inner)
 
static void SubmitVertices (GLUtesselator *tesselator, TessPolygonData *polygonData, NSArray *contour)
 
static BOOL GrowTessPolygonData (TessPolygonData *data, size_t capacityHint)
 
static BOOL AppendVertex (TessPolygonData *data, NSPoint vertex)
 
static void SVGDumpBegin (TessPolygonData *data)
 
static void SVGDumpEnd (TessPolygonData *data)
 
static void SVGDumpBeginGroup (TessPolygonData *data, NSString *name)
 
static void SVGDumpEndGroup (TessPolygonData *data)
 
static void SVGDumpAppendBaseContour (TessPolygonData *data, NSArray *points)
 
static void SVGDumpBeginPrimitive (TessPolygonData *data)
 
static void SVGDumpEndPrimitive (TessPolygonData *data)
 
static void SVGDumpAppendTriangle (TessPolygonData *data, NSPoint v0, NSPoint v1, NSPoint v2)
 
static void APIENTRY TessBeginCallback (GLenum type, void *polygonData)
 
static void APIENTRY TessVertexCallback (void *vertexData, void *polygonData)
 
static void APIENTRY TessCombineCallback (GLdouble coords[3], void *vertexData[4], GLfloat weight[4], void **outData, void *polygonData)
 
static void APIENTRY TessEndCallback (void *polygonData)
 
static void APIENTRY ErrorCallback (GLenum error, void *polygonData)
 

Macro Definition Documentation

◆ APIENTRY

#define APIENTRY

Definition at line 51 of file OOPolygonSprite.m.

◆ kCosMitreLimit

#define kCosMitreLimit   0.866f

Definition at line 55 of file OOPolygonSprite.m.

Referenced by BuildOutlineContour().

Typedef Documentation

◆ TessFuncPtr

typedef GLvoid(* TessFuncPtr) ()

Definition at line 119 of file OOPolygonSprite.m.

Function Documentation

◆ AppendVertex()

static BOOL AppendVertex ( TessPolygonData * data,
NSPoint vertex )
static

Definition at line 647 of file OOPolygonSprite.m.

648{
649 NSCParameterAssert(data != NULL);
650
651 if (data->capacity == data->count && !GrowTessPolygonData(data, data->capacity * 2)) return NO;
652
653 data->data[data->count * 2] = vertex.x;
654 data->data[data->count * 2 + 1] = vertex.y;
655 data->count++;
656 return YES;
657}
static BOOL GrowTessPolygonData(TessPolygonData *data, size_t capacityHint)

References TessPolygonData::capacity, TessPolygonData::count, TessPolygonData::data, and GrowTessPolygonData().

Referenced by TessVertexCallback().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ BuildOutlineContour()

static NSArray * BuildOutlineContour ( NSArray * dataArray,
GLfloat width,
BOOL inner )
static

Definition at line 511 of file OOPolygonSprite.m.

512{
513 NSUInteger i, count = [dataArray count];
514 if (count < 2) return dataArray;
515
516 /*
517 Generate inner or outer boundary for a contour, offset by the specified
518 width inwards/outwards from the line. At anticlockwise (convex) corners
519 sharper than acos(kCosMitreLimit), the corner is mitred, i.e. an
520 additional line segment is generated so the outline doesn't protrude
521 arbitratrily far.
522
523 Overview of the maths:
524 For each vertex, we consider a normalized vector A from the previous
525 vertex and a normalized vector B to the next vertex. (These are always
526 defined since the polygons are closed.)
527
528 The dot product of A and B is the cosine of the angle, which we compare
529 to kCosMitreLimit to determine mitreing. If the dot product is exactly
530 1, the vectors are antiparallel and we have a cap; the mitreing case
531 handles this implicitly. (The non-mitreing case would result in a
532 divide-by-zero.)
533
534 Non-mitreing case:
535 To position the vertex, we need a vector N normal to the corner.
536 We observe that A + B is tangent to the corner, and a 90 degree
537 rotation in 2D is trivial. The offset along this line is
538 proportional to the secant of the angle between N and the 90 degree
539 rotation of A (or B; the angle is by definition the same), or
540 width / (N dot rA).
541 Since both N and rA are rotated by ninety degrees in the same
542 direction, we can cut out both rotations (i.e., using the tangent
543 and A) and get the same result.
544
545 Mitreing case:
546 The two new vertices are the original vertex offset by scale along
547 the ninety-degree rotation of A and B respectively.
548 */
549
550 NSPoint prev, current, next;
551 if (inner)
552 {
553 prev = [[dataArray objectAtIndex:0] pointValue];
554 current = [[dataArray objectAtIndex:count -1] pointValue];
555 next = [[dataArray objectAtIndex:count - 2] pointValue];
556 }
557 else
558 {
559 prev = [[dataArray objectAtIndex:count - 1] pointValue];
560 current = [[dataArray objectAtIndex:0] pointValue];
561 next = [[dataArray objectAtIndex:1] pointValue];
562 }
563
564 NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
565
566 for (i = 0; i < count; i++)
567 {
568 NSPoint a = PtNormal(PtSub(current, prev));
569 NSPoint b = PtNormal(PtSub(next, current));
570
571 CGFloat dot = PtDot(a, b);
572 BOOL clockwise = PtCross(a, b) < 0.0f;
573
574 if (-dot < kCosMitreLimit || !clockwise)
575 {
576 // Non-mitreing case.
577 NSPoint t = PtNormal(PtAdd(a, b));
578 NSPoint v = PtScale(PtRotACW(t), width / PtDot(t, a));
579
580 if (!isnan(v.x) && !isnan(v.y))
581 {
582 [result addObject:[NSValue valueWithPoint:PtAdd(v, current)]];
583 }
584 }
585 else
586 {
587 // Mitreing case.
588 NSPoint v1 = PtScale(PtAdd(PtRotACW(a), a), width);
589 NSPoint v2 = PtScale(PtSub(PtRotACW(b), b), width);
590
591 if (!isnan(v1.x) && !isnan(v1.y))
592 {
593 [result addObject:[NSValue valueWithPoint:PtAdd(v1, current)]];
594 }
595 if (!isnan(v2.x) && !isnan(v2.y))
596 {
597 [result addObject:[NSValue valueWithPoint:PtAdd(v2, current)]];
598 }
599 }
600
601 prev = current;
602 current = next;
603
604 if (inner)
605 {
606 next = [[dataArray objectAtIndex:(count * 2 - 3 - i) % count] pointValue];
607 }
608 else
609 {
610 next = [[dataArray objectAtIndex:(i + 2) % count] pointValue];
611 }
612 }
613
614 return result;
615}
unsigned count
OOINLINE CGFloat PtDot(NSPoint a, NSPoint b)
OOINLINE NSPoint PtScale(NSPoint p, CGFloat scale)
OOINLINE NSPoint PtSub(NSPoint a, NSPoint b)
OOINLINE NSPoint PtRotACW(NSPoint p)
OOINLINE NSPoint PtNormal(NSPoint p)
OOINLINE CGFloat PtCross(NSPoint a, NSPoint b)
OOINLINE NSPoint PtAdd(NSPoint a, NSPoint b)
Definition OOPointMaths.h:6
#define kCosMitreLimit

References count, kCosMitreLimit, PtAdd(), PtCross(), PtDot(), PtNormal(), PtRotACW(), PtScale(), and PtSub().

+ Here is the call graph for this function:

◆ DataArrayToPoints()

static NSArray * DataArrayToPoints ( TessPolygonData * data,
NSArray * dataArray )
static

Definition at line 442 of file OOPolygonSprite.m.

443{
444 /* This converts an icon definition in the form of an array of array of
445 numbers to internal data in the form of an array of arrays of NSValues
446 containing NSPoint data. In addition to repacking the data, it performs
447 the following data processing:
448 * Sequences of duplicate vertices are removed (including across the
449 beginning and end, in case of manually closed contours).
450 * Vertices containing nans or infinities are skipped, Just In Case.
451 * The signed area of each contour is calculated; if it is negative,
452 the contour is clockwise, and we need to flip it.
453 */
454
455 SVGDumpBeginGroup(data, @"Base contours");
456
457 NSUInteger polyIter, polyCount = [dataArray count];
458 NSArray *subArrays[polyCount];
459
460 for (polyIter = 0; polyIter < polyCount; polyIter++)
461 {
462 NSArray *polyDef = [dataArray objectAtIndex:polyIter];
463 NSUInteger vertIter, vertCount = [polyDef count] / 2;
464 NSMutableArray *newPolyDef = [NSMutableArray arrayWithCapacity:vertCount];
465 CGFloat area = 0;
466
467 CGFloat oldX = [polyDef oo_doubleAtIndex:(vertCount -1) * 2];
468 CGFloat oldY = [polyDef oo_doubleAtIndex:(vertCount -1) * 2 + 1];
469
470 for (vertIter = 0; vertIter < vertCount; vertIter++)
471 {
472 CGFloat x = [polyDef oo_doubleAtIndex:vertIter * 2];
473 CGFloat y = [polyDef oo_doubleAtIndex:vertIter * 2 + 1];
474
475 // Skip bad or duplicate vertices.
476 if (x == oldX && y == oldY) continue;
477 if (isnan(x) || isnan(y)) continue;
478 if (!isfinite(x) || !isfinite(y)) continue;
479
480 area += x * oldY - oldX * y;
481
482 oldX = x;
483 oldY = y;
484
485 [newPolyDef addObject:[NSValue valueWithPoint:NSMakePoint(x, y)]];
486 }
487
488 // Eliminate duplicates at ends - the initialization of oldX and oldY will catch one pair, but not extra-silly cases.
489 while ([newPolyDef count] > 1 && [[newPolyDef objectAtIndex:0] isEqual:[newPolyDef lastObject]])
490 {
491 [newPolyDef removeLastObject];
492 }
493
494 if (area >= 0)
495 {
496 subArrays[polyIter] = newPolyDef;
497 }
498 else
499 {
500 subArrays[polyIter] = [[newPolyDef reverseObjectEnumerator] allObjects];
501 }
502
503 SVGDumpAppendBaseContour(data, subArrays[polyIter]);
504 }
505
506 SVGDumpEndGroup(data);
507 return [NSArray arrayWithObjects:subArrays count:polyCount];
508}
static void SVGDumpBeginGroup(TessPolygonData *data, NSString *name)
static void SVGDumpAppendBaseContour(TessPolygonData *data, NSArray *points)
static void SVGDumpEndGroup(TessPolygonData *data)
float y
float x

References count, SVGDumpAppendBaseContour(), SVGDumpBeginGroup(), SVGDumpEndGroup(), x, and y.

+ Here is the call graph for this function:

◆ ErrorCallback()

static void APIENTRY ErrorCallback ( GLenum error,
void * polygonData )
static

Definition at line 780 of file OOPolygonSprite.m.

781{
782 TessPolygonData *data = polygonData;
783 NSCParameterAssert(data != NULL);
784
785 NSString *name = @"";
786#ifndef NDEBUG
787 name = [NSString stringWithFormat:@" \"%@\"", data->name];
788#endif
789
790 char *errStr = (char *)gluErrorString(error);
791
792 OOLog(@"polygonSprite.tesselate.error", @"Error %s (%u) while tesselating polygon%@.", errStr, error, name);
793 data->OK = NO;
794}
#define OOLog(class, format,...)
Definition OOLogging.h:88

References TessPolygonData::OK, and OOLog.

◆ GrowTessPolygonData()

static BOOL GrowTessPolygonData ( TessPolygonData * data,
size_t capacityHint )
static

Definition at line 618 of file OOPolygonSprite.m.

619{
620 NSCParameterAssert(data != NULL);
621
622 size_t minCapacity = data->capacity + 1;
623 size_t desiredCapacity = MAX(capacityHint, minCapacity);
624 size_t newCapacity = 0;
625 GLfloat *newData = realloc(data->data, desiredCapacity * sizeof (GLfloat) * 2);
626 if (newData != NULL)
627 {
628 newCapacity = desiredCapacity;
629 }
630 else
631 {
632 desiredCapacity = minCapacity;
633 newData = realloc(data->data, desiredCapacity * sizeof (GLfloat) * 2);
634 if (newData != NULL) newCapacity = desiredCapacity;
635 }
636
637 if (newData == NULL) return NO;
638
639 NSCAssert(newCapacity > data->capacity, @"Buffer regrow logic error");
640
641 data->data = newData;
642 data->capacity = newCapacity;
643 return YES;
644}
#define MAX(A, B)
Definition OOMaths.h:114

References TessPolygonData::capacity, TessPolygonData::data, and MAX.

Referenced by AppendVertex().

+ Here is the caller graph for this function:

◆ SubmitVertices()

static void SubmitVertices ( GLUtesselator * tesselator,
TessPolygonData * polygonData,
NSArray * contour )
static

Definition at line 421 of file OOPolygonSprite.m.

422{
423 NSUInteger vertexCount = [contour count], vertexIndex;
424 if (vertexCount > 2)
425 {
426 gluTessBeginContour(tesselator);
427
428 for (vertexIndex = 0; vertexIndex < vertexCount && polygonData->OK; vertexIndex++)
429 {
430 NSValue *pointValue = [contour objectAtIndex:vertexIndex];
431 NSPoint p = [pointValue pointValue];
432 GLdouble vert[3] = { p.x, p.y, 0.0 };
433
434 gluTessVertex(tesselator, vert, pointValue);
435 }
436
437 gluTessEndContour(tesselator);
438 }
439}

References TessPolygonData::OK.

◆ SVGDumpAppendBaseContour()

static void SVGDumpAppendBaseContour ( TessPolygonData * data,
NSArray * points )
static

Definition at line 838 of file OOPolygonSprite.m.

839{
840 if (data->debugSVG == nil) return;
841
842 NSString *groupName = [NSString stringWithFormat:@"contour %u", data->svgID++];
843 [data->debugSVG appendFormat:@"\t\t<g id=\"%@\" stroke=\"#BBB\" fill=\"none\">\n\t\t<path stroke-width=\"0.05\" d=\"", groupName];
844
845 NSUInteger i, count = [points count];
846 for (i = 0; i < count; i++)
847 {
848 NSPoint p = [[points objectAtIndex:i] pointValue];
849 [data->debugSVG appendFormat:@"%c %f %f ", (i == 0) ? 'M' : 'L', p.x, -p.y];
850 }
851
852 // Close and add a circle at the first vertex. (SVG has support for end markers, but this isn’t reliable across implementations.)
853 NSPoint p = [[points objectAtIndex:0] pointValue];
854 [data->debugSVG appendFormat:@"z\"/>\n\t\t\t<circle cx=\"%f\" cy=\"%f\" r=\"0.1\" fill=\"#BBB\" stroke=\"none\"/>\n\t\t</g>\n", p.x, -p.y];
855}
return nil
NSMutableString * debugSVG

References count, TessPolygonData::debugSVG, and nil.

Referenced by DataArrayToPoints().

+ Here is the caller graph for this function:

◆ SVGDumpAppendTriangle()

static void SVGDumpAppendTriangle ( TessPolygonData * data,
NSPoint v0,
NSPoint v1,
NSPoint v2 )
static

Definition at line 901 of file OOPolygonSprite.m.

902{
903 if (data->debugSVG == nil) return;
904 [data->debugSVG appendFormat:@"\t\t\t<path d=\"M %f %f L %f %f L %f %f z\"/>\n", v0.x, -v0.y, v1.x, -v1.y, v2.x, -v2.y];
905}

References TessPolygonData::debugSVG, and nil.

Referenced by TessVertexCallback().

+ Here is the caller graph for this function:

◆ SVGDumpBegin()

static void SVGDumpBegin ( TessPolygonData * data)
static

Definition at line 800 of file OOPolygonSprite.m.

801{
802 DESTROY(data->debugSVG);
803 data->debugSVG = [[NSMutableString alloc] initWithString:
804 @"<?xml version=\"1.0\" standalone=\"no\"?>\n"
805 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
806 "<svg viewBox=\"-5 -5 10 10\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n"
807 "\t<desc>Oolite polygon sprite debug dump.</desc>\n"
808 "\t\n"
809 ];
810}
#define DESTROY(x)
Definition OOCocoa.h:77

References TessPolygonData::debugSVG, and DESTROY.

◆ SVGDumpBeginGroup()

static void SVGDumpBeginGroup ( TessPolygonData * data,
NSString * name )
static

Definition at line 823 of file OOPolygonSprite.m.

824{
825 if (data->debugSVG == nil) return;
826
827 [data->debugSVG appendFormat:@"\t<g id=\"%@ %u\">\n", name, data->svgID++];
828}

References TessPolygonData::debugSVG, and nil.

Referenced by DataArrayToPoints().

+ Here is the caller graph for this function:

◆ SVGDumpBeginPrimitive()

static void SVGDumpBeginPrimitive ( TessPolygonData * data)
static

Definition at line 858 of file OOPolygonSprite.m.

859{
860 if (data->debugSVG == nil) return;
861
862 NSString *groupName = @"Unknown primitive";
863 switch (data->mode)
864 {
865 case GL_TRIANGLES:
866 groupName = @"Triangle soup";
867 break;
868
869 case GL_TRIANGLE_FAN:
870 groupName = @"Triangle fan";
871 break;
872
873 case GL_TRIANGLE_STRIP:
874 groupName = @"Triangle strip";
875 break;
876 }
877 groupName = [groupName stringByAppendingFormat:@" %u", data->svgID++];
878
879 // Pick random colour for the primitive.
880 uint8_t red = (Ranrot() & 0x3F) + 0x20;
881 uint8_t green = (Ranrot() & 0x3F) + 0x20;
882 uint8_t blue = (Ranrot() & 0x3F) + 0x20;
883 if (!data->generatingOutline)
884 {
885 red += 0x80;
886 green += 0x80;
887 blue += 0x80;
888 }
889
890 [data->debugSVG appendFormat:@"\t\t<g id=\"%@\" fill=\"#%2X%2X%2X\" fill-opacity=\"0.3\" stroke=\"%@\" stroke-width=\"0.01\">\n", groupName, red, green, blue, data->generatingOutline ? @"#060" : @"#008"];
891}
unsigned Ranrot(void)

References TessPolygonData::debugSVG, TessPolygonData::generatingOutline, TessPolygonData::mode, nil, and Ranrot().

Referenced by TessBeginCallback().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SVGDumpEnd()

static void SVGDumpEnd ( TessPolygonData * data)
static

Definition at line 813 of file OOPolygonSprite.m.

814{
815 if (data->debugSVG == nil) return;
816
817 [data->debugSVG appendString:@"</svg>\n"];
818 [ResourceManager writeDiagnosticString:data->debugSVG toFileNamed:[NSString stringWithFormat:@"Polygon Sprites/%@.svg", data->name]];
819 DESTROY(data->debugSVG);
820}

References TessPolygonData::debugSVG, DESTROY, nil, and ResourceManager::writeDiagnosticString:toFileNamed:.

+ Here is the call graph for this function:

◆ SVGDumpEndGroup()

static void SVGDumpEndGroup ( TessPolygonData * data)
static

Definition at line 831 of file OOPolygonSprite.m.

832{
833 if (data->debugSVG == nil) return;
834 [data->debugSVG appendString:@"\t</g>\n"];
835}

References TessPolygonData::debugSVG, and nil.

Referenced by DataArrayToPoints().

+ Here is the caller graph for this function:

◆ SVGDumpEndPrimitive()

static void SVGDumpEndPrimitive ( TessPolygonData * data)
static

Definition at line 894 of file OOPolygonSprite.m.

895{
896 if (data->debugSVG == nil) return;
897 [data->debugSVG appendString:@"\t\t</g>\n"];
898}

References TessPolygonData::debugSVG, and nil.

Referenced by TessEndCallback().

+ Here is the caller graph for this function:

◆ TessBeginCallback()

static void APIENTRY TessBeginCallback ( GLenum type,
void * polygonData )
static

Definition at line 660 of file OOPolygonSprite.m.

661{
662 TessPolygonData *data = polygonData;
663 NSCParameterAssert(data != NULL);
664
665 data->mode = type;
666 data->vCount = 0;
667
669}
static void SVGDumpBeginPrimitive(TessPolygonData *data)

References TessPolygonData::mode, SVGDumpBeginPrimitive(), and TessPolygonData::vCount.

+ Here is the call graph for this function:

◆ TessCombineCallback()

static void APIENTRY TessCombineCallback ( GLdouble coords[3],
void * vertexData[4],
GLfloat weight[4],
void ** outData,
void * polygonData )
static

Definition at line 761 of file OOPolygonSprite.m.

762{
763 NSPoint point = { coords[0], coords[1] };
764 *outData = [NSValue valueWithPoint:point];
765}

◆ TessEndCallback()

static void APIENTRY TessEndCallback ( void * polygonData)
static

Definition at line 768 of file OOPolygonSprite.m.

769{
770 TessPolygonData *data = polygonData;
771 NSCParameterAssert(data != NULL);
772
773 data->mode = 0;
774 data->vCount = 0;
775
777}
static void SVGDumpEndPrimitive(TessPolygonData *data)

References TessPolygonData::mode, SVGDumpEndPrimitive(), and TessPolygonData::vCount.

+ Here is the call graph for this function:

◆ TessVertexCallback()

static void APIENTRY TessVertexCallback ( void * vertexData,
void * polygonData )
static

Definition at line 672 of file OOPolygonSprite.m.

673{
674 TessPolygonData *data = polygonData;
675 NSValue *vertValue = vertexData;
676 NSCParameterAssert(vertValue != NULL && data != NULL);
677 if (!data->OK) return;
678
679 NSPoint p = [vertValue pointValue];
680 NSPoint vertex = { p.x, p.y };
681 size_t vCount = data->vCount++;
682
683 switch (data->mode)
684 {
685 case GL_TRIANGLES:
686 data->OK = AppendVertex(data, vertex);
687#ifndef NDEBUG
688 switch (vCount % 3)
689 {
690 case 0:
691 data->pending0 = vertex;
692 break;
693
694 case 1:
695 data->pending1 = vertex;
696 break;
697
698 case 2:
699 SVGDumpAppendTriangle(data, data->pending0, data->pending1, vertex);
700 }
701#endif
702 break;
703
704 case GL_TRIANGLE_FAN:
705 if (vCount == 0) data->pending0 = vertex;
706 else if (vCount == 1) data->pending1 = vertex;
707 else
708 {
709 data->OK = AppendVertex(data, data->pending0) &&
710 AppendVertex(data, data->pending1) &&
711 AppendVertex(data, vertex);
712 SVGDumpAppendTriangle(data, data->pending0, data->pending1, vertex);
713 data->pending1 = vertex;
714 }
715 break;
716
717 case GL_TRIANGLE_STRIP:
718 if (vCount == 0) data->pending0 = vertex;
719 else if (vCount == 1) data->pending1 = vertex;
720 else
721 {
722 /* In order to produce consistent winding, the vertex->triangle
723 order for GL_TRIANGLE_STRIP is:
724 0, 1, 2
725 2, 1, 3
726 2, 3, 4
727 4, 3, 5
728 4, 5, 6
729 6, 5, 7
730 6, 7, 8
731
732 Vertices 0 and 1 are special-cased above, and the first
733 time we get here it's time for the first triangle, which
734 is pending0, pending1, v. v (i.e., vertex 2) then goes into
735 pending0.
736 For the second triangle, the triangle is again pending0,
737 pending1, v, and we then put v (i.e., vertex 3) into
738 pending1.
739 The third triangle follows the same pattern as the first,
740 and the fourthe the same as the second.
741 In other words, after storing each triangle, v goes into
742 pending0 for even vertex indicies, and pending1 for odd
743 vertex indices.
744 */
745 data->OK = AppendVertex(data, data->pending0) &&
746 AppendVertex(data, data->pending1) &&
747 AppendVertex(data, vertex);
748 SVGDumpAppendTriangle(data, data->pending0, data->pending1, vertex);
749 if ((vCount % 2) == 0) data->pending0 = vertex;
750 else data->pending1 = vertex;
751 }
752 break;
753
754 default:
755 OOLog(@"polygonSprite.tesselate.error", @"Unexpected tesselator primitive mode %u.", data->mode);
756 data->OK = NO;
757 }
758}
static BOOL AppendVertex(TessPolygonData *data, NSPoint vertex)
static void SVGDumpAppendTriangle(TessPolygonData *data, NSPoint v0, NSPoint v1, NSPoint v2)

References AppendVertex(), TessPolygonData::mode, TessPolygonData::OK, OOLog, TessPolygonData::pending0, TessPolygonData::pending1, SVGDumpAppendTriangle(), and TessPolygonData::vCount.

+ Here is the call graph for this function: