summaryrefslogtreecommitdiff
path: root/app/bin/trkseg.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/trkseg.c')
-rw-r--r--app/bin/trkseg.c558
1 files changed, 329 insertions, 229 deletions
diff --git a/app/bin/trkseg.c b/app/bin/trkseg.c
index ab4b5a8..3e38933 100644
--- a/app/bin/trkseg.c
+++ b/app/bin/trkseg.c
@@ -142,8 +142,14 @@ EXPORT coOrd GetSegEndPt(
break;
case SEG_BEZTRK:
case SEG_BEZLIN:
- if (ep ==1) pos = segPtr->u.b.pos[3]; //For Bezier, use the End Points of the overall curve
- else pos = segPtr->u.b.pos[0];
+ if (ep ==1) {
+ pos = segPtr->u.b.pos[3]; //For Bezier, use the End Points of the overall curve
+ angle = FindAngle(segPtr->u.b.pos[2],segPtr->u.b.pos[3]);
+ } else {
+ pos = segPtr->u.b.pos[0];
+ angle = FindAngle(segPtr->u.b.pos[1],segPtr->u.b.pos[0]);
+ }
+
break;
default:
AbortProg("GetSegCntPt(%c)", segPtr->type );
@@ -172,8 +178,8 @@ EXPORT void GetTextBounds(
coOrd * hiR )
{
- coOrd size;
- POS_T descent = 0.0;
+ coOrd size, size2;
+ POS_T descent = 0.0, ascent = 0.0;
coOrd lo, hi;
coOrd p[4];
coOrd lastL;
@@ -183,9 +189,9 @@ EXPORT void GetTextBounds(
// set up the corners of the rectangle
p[0].x = p[3].x = 0.0;
p[1].x = p[2].x = size.x;
- DrawTextSize2(&mainD, "A", NULL, fs, FALSE, &size, &descent);
+ DrawTextSize2(&mainD, "A", NULL, fs, FALSE, &size2, &descent, &ascent);
p[0].y = p[1].y = lastL.y - descent;
- p[2].y = p[3].y = size.y;
+ p[2].y = p[3].y = size2.y;
lo = hi = zero;
@@ -239,24 +245,10 @@ static void Get1SegBounds( trkSeg_p segPtr, coOrd xlat, ANGLE_T angle, coOrd *lo
case SEG_TBLEDGE:
case SEG_CRVLIN:
case SEG_JNTTRK:
- REORIGIN( p0, GetSegEndPt( segPtr, 0, FALSE, NULL ), angle, xlat )
- REORIGIN( p1, GetSegEndPt( segPtr, 1, FALSE, NULL ), angle, xlat )
- if (p0.x < p1.x) {
- lo->x = p0.x;
- hi->x = p1.x;
- } else {
- lo->x = p1.x;
- hi->x = p0.x;
- }
- if (p0.y < p1.y) {
- lo->y = p0.y;
- hi->y = p1.y;
- } else {
- lo->y = p1.y;
- hi->y = p0.y;
- }
- if ( segPtr->type == SEG_CRVTRK ||
- segPtr->type == SEG_CRVLIN ) {
+ if ( (segPtr->type == SEG_CRVTRK) ||
+ (segPtr->type == SEG_CRVLIN) ) {
+ /* TODO: be more precise about curved line width */
+ width.x = width.y = segPtr->width/2.0;
REORIGIN( pc, segPtr->u.c.center, angle, xlat );
a0 = NormalizeAngle( segPtr->u.c.a0 + angle );
a1 = segPtr->u.c.a1;
@@ -266,7 +258,7 @@ static void Get1SegBounds( trkSeg_p segPtr, coOrd xlat, ANGLE_T angle, coOrd *lo
lo->y = pc.y - radius;
hi->x = pc.x + radius;
hi->y = pc.y + radius;
- return;
+ break;
}
if ( a0 + a1 >= 360.0 )
hi->y = pc.y + radius;
@@ -277,12 +269,25 @@ static void Get1SegBounds( trkSeg_p segPtr, coOrd xlat, ANGLE_T angle, coOrd *lo
if ( a0 < 270.0 && a0+a1 >= 270.0 )
lo->x = pc.x - radius;
}
+ REORIGIN( p0, GetSegEndPt( segPtr, 0, FALSE, NULL ), angle, xlat )
+ REORIGIN( p1, GetSegEndPt( segPtr, 1, FALSE, NULL ), angle, xlat )
+ if (p0.x < p1.x) {
+ lo->x = p0.x;
+ hi->x = p1.x;
+ } else {
+ lo->x = p1.x;
+ hi->x = p0.x;
+ }
+ if (p0.y < p1.y) {
+ lo->y = p0.y;
+ hi->y = p1.y;
+ } else {
+ lo->y = p1.y;
+ hi->y = p0.y;
+ }
if ( segPtr->type == SEG_STRLIN ) {
width.x = segPtr->width * fabs(cos( D2R( FindAngle(p0, p1) ) ) ) / 2.0;
width.y = segPtr->width * fabs(sin( D2R( FindAngle(p0, p1) ) ) ) / 2.0;
- } else if ( segPtr->type == SEG_CRVLIN ) {
- /* TODO: be more precise about curved line width */
- width.x = width.y = segPtr->width/2.0;
} else if ( segPtr->type == SEG_BENCH ) {
width.x = BenchGetWidth( segPtr->u.l.option ) * fabs(cos( D2R( FindAngle(p0, p1) ) ) ) / 2.0;
width.y = BenchGetWidth( segPtr->u.l.option ) * fabs(sin( D2R( FindAngle(p0, p1) ) ) ) / 2.0;
@@ -293,7 +298,7 @@ static void Get1SegBounds( trkSeg_p segPtr, coOrd xlat, ANGLE_T angle, coOrd *lo
width.x = width.y = segPtr->width/2.0;
case SEG_FILPOLY:
for (inx=0; inx<segPtr->u.p.cnt; inx++ ) {
- REORIGIN( p0, segPtr->u.p.pts[inx], angle, xlat )
+ REORIGIN( p0, segPtr->u.p.pts[inx].pt, angle, xlat )
if (inx==0) {
*lo = *hi = p0;
} else {
@@ -431,8 +436,8 @@ EXPORT void MoveSegs(
case SEG_POLY:
case SEG_FILPOLY:
for (inx=0; inx<s->u.p.cnt; inx++) {
- s->u.p.pts[inx].x += orig.x;
- s->u.p.pts[inx].y += orig.y;
+ s->u.p.pts[inx].pt.x += orig.x;
+ s->u.p.pts[inx].pt.y += orig.y;
}
break;
case SEG_JNTTRK:
@@ -484,7 +489,7 @@ EXPORT void RotateSegs(
case SEG_POLY:
case SEG_FILPOLY:
for (inx=0; inx<s->u.p.cnt; inx++) {
- Rotate( &s->u.p.pts[inx], orig, angle );
+ Rotate( &s->u.p.pts[inx].pt, orig, angle );
}
break;
case SEG_JNTTRK:
@@ -511,7 +516,7 @@ EXPORT void FlipSegs(
{
trkSeg_p s;
int inx;
- coOrd * pts;
+ pts_t * pts;
for (s=segs; s<&segs[segCnt]; s++) {
switch (s->type) {
@@ -537,11 +542,11 @@ EXPORT void FlipSegs(
break;
case SEG_POLY:
case SEG_FILPOLY:
- pts = (coOrd*)MyMalloc( s->u.p.cnt * sizeof (coOrd) );
- memcpy( pts, s->u.p.pts, s->u.p.cnt * sizeof (coOrd) );
+ pts = (pts_t*)MyMalloc( s->u.p.cnt * sizeof (pts_t) );
+ memcpy( pts, s->u.p.pts, s->u.p.cnt * sizeof (pts_t) );
s->u.p.pts = pts;
for (inx=0; inx<s->u.p.cnt; inx++) {
- s->u.p.pts[inx].y = -s->u.p.pts[inx].y;
+ s->u.p.pts[inx].pt.y = -s->u.p.pts[inx].pt.y;
}
/* Don't Free - we only just got! ALso can't free other copy as that may be a template */
//MyFree(pts);
@@ -602,8 +607,8 @@ EXPORT void RescaleSegs(
case SEG_POLY:
case SEG_FILPOLY:
for (inx=0; inx<s->u.p.cnt; inx++) {
- s->u.p.pts[inx].x *= scale_x;
- s->u.p.pts[inx].y *= scale_y;
+ s->u.p.pts[inx].pt.x *= scale_x;
+ s->u.p.pts[inx].pt.y *= scale_y;
}
break;
case SEG_JNTTRK:
@@ -638,7 +643,7 @@ EXPORT void CloneFilledDraw(
trkSeg_p segs,
BOOL_T reorigin )
{
- coOrd * newPts;
+ pts_t * newPts;
trkSeg_p sp;
wIndex_t inx;
@@ -646,21 +651,20 @@ EXPORT void CloneFilledDraw(
switch (sp->type) {
case SEG_POLY:
case SEG_FILPOLY:
- newPts = (coOrd*)MyMalloc( sp->u.p.cnt * sizeof (coOrd) );
+ newPts = (pts_t*)MyMalloc( sp->u.p.cnt * sizeof (pts_t) );
+ memcpy( newPts, sp->u.p.pts, sp->u.p.cnt * sizeof (pts_t) );
if ( reorigin ) {
for ( inx = 0; inx<sp->u.p.cnt; inx++ )
- REORIGIN( newPts[inx], sp->u.p.pts[inx], sp->u.p.angle, sp->u.p.orig );
+ REORIGIN( newPts[inx].pt, sp->u.p.pts[inx].pt, sp->u.p.angle, sp->u.p.orig );
sp->u.p.angle = 0;
sp->u.p.orig = zero;
- } else {
- memcpy( newPts, sp->u.p.pts, sp->u.p.cnt * sizeof (coOrd) );
}
//if (sp->u.p.pts) Can't do this a pts could be pointing at static
// free(sp->u.p.pts);
sp->u.p.pts = newPts;
break;
case SEG_TEXT:
- sp->u.t.string = strdup( sp->u.t.string);
+ sp->u.t.string = MyStrdup( sp->u.t.string);
break;
case SEG_BEZTRK:
case SEG_BEZLIN:
@@ -753,9 +757,9 @@ EXPORT DIST_T DistanceSegs(
for (lin=0;lin<segPtr->u.p.cnt;lin++) {
pt = p0;
if (lin < segPtr->u.p.cnt-1 )
- ddd = LineDistance( &pt, segPtr->u.p.pts[lin], segPtr->u.p.pts[lin+1] );
+ ddd = LineDistance( &pt, segPtr->u.p.pts[lin].pt, segPtr->u.p.pts[lin+1].pt );
else
- ddd = LineDistance( &pt, segPtr->u.p.pts[lin], segPtr->u.p.pts[0] );
+ ddd = LineDistance( &pt, segPtr->u.p.pts[lin].pt, segPtr->u.p.pts[0].pt );
if ( ddd < dd ) {
dd = ddd;
p1 = pt;
@@ -846,7 +850,7 @@ EXPORT ANGLE_T GetAngleSegs(
{
wIndex_t inx;
ANGLE_T angle = 0.0;
- coOrd p0;
+ coOrd p0,p1;
DIST_T d, dd;
segProcData_t segProcData;
coOrd pos2 = * pos1;
@@ -889,15 +893,17 @@ EXPORT ANGLE_T GetAngleSegs(
break;
case SEG_POLY:
case SEG_FILPOLY:
- p0 = pos2;
- dd = LineDistance( &p0, segPtr->u.p.pts[segPtr->u.p.cnt-1], segPtr->u.p.pts[0] );
- angle = FindAngle( segPtr->u.p.pts[segPtr->u.p.cnt-1], segPtr->u.p.pts[0] );
+ p0 = p1 = pos2;
+ dd = LineDistance( &p0, segPtr->u.p.pts[segPtr->u.p.cnt-1].pt, segPtr->u.p.pts[0].pt );
+ angle = FindAngle( segPtr->u.p.pts[segPtr->u.p.cnt-1].pt, segPtr->u.p.pts[0].pt );
for ( inx=0; inx<segPtr->u.p.cnt-1; inx++ ) {
- p0 = pos2;
- d = LineDistance( &p0, segPtr->u.p.pts[inx], segPtr->u.p.pts[inx+1] );
+ p0 = p1;
+ d = LineDistance( &p0, segPtr->u.p.pts[inx].pt, segPtr->u.p.pts[inx+1].pt );
if ( d < dd ) {
dd = d;
- angle = FindAngle( segPtr->u.p.pts[inx], segPtr->u.p.pts[inx+1] );
+ angle = FindAngle( segPtr->u.p.pts[inx].pt, segPtr->u.p.pts[inx+1].pt );
+ if (subSegInxR) *subSegInxR = inx;
+ pos2 = p0;
}
}
break;
@@ -1125,14 +1131,14 @@ static void AppendPath( signed char c )
EXPORT BOOL_T ReadSegs( void )
{
char *cp, *cpp;
- BOOL_T rc=FALSE;
+ BOOL_T rc=TRUE;
trkSeg_p s;
trkEndPt_p e;
long rgb;
int i;
DIST_T elev0, elev1;
BOOL_T hasElev;
- BOOL_T isPolyV2, noVersion;
+ BOOL_T isPolyV1, isPolyV2;
BOOL_T improvedEnds;
FLOAT_T ignoreFloat;
char type;
@@ -1146,14 +1152,13 @@ EXPORT BOOL_T ReadSegs( void )
DYNARR_RESET( trkSeg_t, tempSegs_da );
DYNARR_RESET( trkEndPt_t, tempEndPts_da );
pathCnt = 0;
- while ( (cp = GetNextLine()) != NULL ) {
+ AppendPath(0); // End of all paths
+ while ( rc && ((cp = GetNextLine()) != NULL) ) {
while (isspace(*cp)) cp++;
hasElev = FALSE;
improvedEnds = FALSE;
- if ( strncmp( cp, "END", 3 ) == 0 ) {
- rc = TRUE;
- subsegs = FALSE;
- break;
+ if ( IsEND( END_SEGS ) ) {
+ return TRUE;
}
if ( strncmp(cp, "SUBSEGS", 7) == 0) {
subsegs = TRUE;
@@ -1163,24 +1168,22 @@ EXPORT BOOL_T ReadSegs( void )
subsegs = FALSE;
continue;
}
- if ( *cp == '\n' || *cp == '#' ) {
+ if ( *cp == '\0' || *cp == '\n' || *cp == '#' ) {
continue;
}
+ if (subsegs) continue;
type = *cp++;
- hasElev = FALSE;
- noVersion = TRUE;
- if ( *cp != ' ')
- noVersion = FALSE;
- if ( *cp == '3' ) {
- cp++;
- hasElev = TRUE;
- }
- isPolyV2 = FALSE;
- if (*cp == '4') {
- cp++;
- hasElev = TRUE;
- isPolyV2 = TRUE;
- improvedEnds = TRUE;
+ improvedEnds = isPolyV2 = hasElev = isPolyV1 = FALSE;
+ if ( isdigit( *cp ) ) {
+ long iVersion = strtol( cp, &cp, 10 );
+ if ( iVersion >= 3 )
+ hasElev = isPolyV1 = TRUE;
+ if ( iVersion >= 4 )
+ improvedEnds = isPolyV2 = TRUE;
+ if ( iVersion > 4 ) {
+ InputError( "Invalid segment version number, maximum is %d", TRUE, 4 );
+ break;
+ }
}
switch (type) {
case SEG_STRLIN:
@@ -1341,34 +1344,28 @@ EXPORT BOOL_T ReadSegs( void )
s = &tempSegs(tempSegs_da.cnt-1);
s->type = type;
s->u.p.polyType = FREEFORM;
- if (isPolyV2) {
- if ( !GetArgs( cp, "lwdd",
- &rgb, &s->width,
- &s->u.p.cnt, &s->u.p.polyType) ) {
- rc = FALSE;
- /*??*/break;
- }
- } else {
- if ( !GetArgs( cp, "lwd",
- &rgb, &s->width,
- &s->u.p.cnt) ) {
- rc = FALSE;
- /*??*/break;
- }
+ if ( !GetArgs( cp,
+ isPolyV2?"lwdd":"lwdX",
+ &rgb,
+ &s->width,
+ &s->u.p.cnt,
+ &s->u.p.polyType) ) {
+ rc = FALSE;
+ /*??*/break;
}
s->color = wDrawFindColor( rgb );
- s->u.p.pts = (coOrd*)MyMalloc( s->u.p.cnt * sizeof (coOrd) );
+ s->u.p.pts = (pts_t*)MyMalloc( s->u.p.cnt * sizeof (pts_t) );
for ( i=0; i<s->u.p.cnt; i++ ) {
cp = GetNextLine();
- if (cp == NULL || !GetArgs( cp, "p", &s->u.p.pts[i])) {
+ if (cp == NULL ||
+ !GetArgs( cp,
+// TODO: does elev belong here instead of the seg header?
+ isPolyV2?"pdY":isPolyV1?"pXf":"pXY",
+ &s->u.p.pts[i].pt,
+ &s->u.p.pts[i].pt_type,
+ &elev0 )) {
rc = FALSE;
}
- if (!noVersion) {
- if (cp == NULL || !GetArgs( cp, hasElev?"f":"Y", &elev0 ) ) {
- rc = FALSE;
- /*??*/break;
- }
- }
}
s->u.p.angle = 0.0;
s->u.p.orig = zero;
@@ -1378,14 +1375,11 @@ EXPORT BOOL_T ReadSegs( void )
s = &tempSegs(tempSegs_da.cnt-1);
s->type = type;
s->u.t.fontP = NULL;
- char * expandedText;
- if ( !GetArgs( cp, "lpf0fq", &rgb, &s->u.t.pos, &s->u.t.angle, &s->u.t.fontSize, &expandedText ) ) {
+ if ( !GetArgs( cp, "lpfdfq", &rgb, &s->u.t.pos, &s->u.t.angle, &s->u.t.boxed, &s->u.t.fontSize, &plain_text ) ) {
rc = FALSE;
/*??*/break;
}
- plain_text = ConvertFromEscapedText(expandedText);
- s->u.t.string = plain_text;
- MyFree(expandedText);
+ s->u.t.string = MyStrdup(plain_text);
s->color = wDrawFindColor( rgb );
break;
case SEG_UNCEP:
@@ -1455,18 +1449,20 @@ EXPORT BOOL_T ReadSegs( void )
case SEG_PATH:
while (isspace(*cp)) cp++;
if (*cp == '\"') cp++;
- while ( *cp != '\"') AppendPath((signed char)*cp++);
- AppendPath(0);
+ pathCnt--; // Overwrite previous terminator
+ while ( *cp != '\"') AppendPath((signed char)*cp++); // Name of path
+ AppendPath(0); // End of name
cp++;
while (1) {
i = (int)strtol(cp, &cpp, 10);
if (cp == cpp)
/*??*/break;
cp = cpp;
- AppendPath( (signed char)i );
+ AppendPath( (signed char)i ); // Segment # of path component
}
- AppendPath( 0 );
- AppendPath( 0 );
+ AppendPath( 0 ); // End of last path components
+ AppendPath( 0 ); // End of path
+ AppendPath( 0 ); // End of all paths
break;
case SEG_SPEC:
strncpy( tempSpecial, cp+1, sizeof tempSpecial - 1 );
@@ -1481,11 +1477,18 @@ EXPORT BOOL_T ReadSegs( void )
}
break;
default:
+ InputError( "Unknown segment type: %c", TRUE, type );
+ rc = FALSE;
break;
}
}
- AppendPath( 0 );
- return rc;
+// We've hit an InputError.
+// The user may have chosen to not continue (paramFile == NULL)
+// Otherwise we have to flush until we see END$SEGS
+
+ while ( GetNextLine() && !IsEND( END_SEGS ) ); // Chomp, Chomp
+
+ return FALSE;
}
EXPORT BOOL_T WriteSegs(
@@ -1559,7 +1562,8 @@ EXPORT BOOL_T WriteSegsEnd(
case SEG_BEZTRK:
case SEG_BEZLIN:
rc &= fprintf( f, "\t%c3 %ld %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f %0.6f\n",
- segs[i].type, wDrawGetRGB(segs[i].color), segs[i].width,
+ segs[i].type, wDrawGetRGB(segs[i].color),
+ segs[i].width,
segs[i].u.l.pos[0].x, segs[i].u.l.pos[0].y,
segs[i].u.l.pos[1].x, segs[i].u.l.pos[1].y,
segs[i].u.l.pos[2].x, segs[i].u.l.pos[2].y,
@@ -1584,24 +1588,26 @@ EXPORT BOOL_T WriteSegsEnd(
break;
case SEG_POLY:
case SEG_FILPOLY:
+// TODO: to be consistent, we should add a dummy 0 for elev. See ReadSegs/SEG_POLY
rc &= fprintf( f, "\t%c4 %ld %0.6f %d %d \n",
segs[i].type, wDrawGetRGB(segs[i].color), segs[i].width,
segs[i].u.p.cnt, segs[i].u.p.polyType ) > 0;
for ( j=0; j<segs[i].u.p.cnt; j++ )
- rc &= fprintf( f, "\t\t%0.6f %0.6f 0\n",
- segs[i].u.p.pts[j].x, segs[i].u.p.pts[j].y ) > 0;
+ rc &= fprintf( f, "\t\t%0.6f %0.6f %d\n",
+ segs[i].u.p.pts[j].pt.x, segs[i].u.p.pts[j].pt.y, segs[i].u.p.pts[j].pt_type ) > 0;
break;
case SEG_TEXT: /* 0pf0fq */
escaped_text = ConvertToEscapedText(segs[i].u.t.string);
- rc &= fprintf( f, "\t%c %ld %0.6f %0.6f %0.6f 0 %0.6f \"%s\"\n",
+ rc &= fprintf( f, "\t%c %ld %0.6f %0.6f %0.6f %d %0.6f \"%s\"\n",
segs[i].type, wDrawGetRGB(segs[i].color),
segs[i].u.t.pos.x, segs[i].u.t.pos.y, segs[i].u.t.angle,
+ segs[i].u.t.boxed,
segs[i].u.t.fontSize, escaped_text ) > 0;
MyFree(escaped_text);
break;
}
}
- if (writeEnd) rc &= fprintf( f, "\tEND\n" )>0;
+ if (writeEnd) rc &= fprintf( f, "\t%s\n", END_SEGS )>0;
return rc;
}
@@ -1664,15 +1670,15 @@ EXPORT void DrawDimLine(
if ( ( option & 0x10 ) == 0 ) {
Translate( &p, p0, a0-45, dist );
- DrawLine( d, p0, p, 0, color );
+ DrawLine( d, p0, p, width, color );
Translate( &p, p0, a0+45, dist );
- DrawLine( d, p0, p, 0, color );
+ DrawLine( d, p0, p, width, color );
}
if ( ( option & 0x20 ) == 0 ) {
Translate( &p, p1, a0-135, dist );
- DrawLine( d, p1, p, 0, color );
+ DrawLine( d, p1, p, width, color );
Translate( &p, p1, a0+135, dist );
- DrawLine( d, p1, p, 0, color );
+ DrawLine( d, p1, p, width, color );
}
if ( fs < 2*d->scale ) {
@@ -1686,7 +1692,7 @@ EXPORT void DrawDimLine(
size.y = textsize.y/2.0;
dist1 = FindDistance( zero, size );
if ( dist <= dist1*2 ) {
- DrawLine( d, p0, p1, 0, color );
+ DrawLine( d, p0, p1, width, color );
return;
}
a1 = FindAngle( zero, size );
@@ -1715,11 +1721,11 @@ EXPORT void DrawDimLine(
p = pc;
p.x -= fx*x;
p.y -= fy*y;
- DrawLine( d, p0, p, 0, color );
+ DrawLine( d, p0, p, width, color );
p = pc;
p.x += fx*x;
p.y += fy*y;
- DrawLine( d, p, p1, 0, color );
+ DrawLine( d, p, p1, width, color );
}
/*
@@ -1747,6 +1753,8 @@ EXPORT void DrawSegsO(
long option;
wFontSize_t fs;
+ wBool_t bFill;
+
for (i=0; i<segCnt; i++,segPtr++ ) {
if (color == wDrawColorBlack) {
color1 = segPtr->color;
@@ -1754,60 +1762,10 @@ EXPORT void DrawSegsO(
} else {
color1 = color2 = color;
}
- if ( (options&DTS_TIES)!=0 ) {
- if ( segPtr->color == wDrawColorWhite )
- continue;
- switch (segPtr->type) {
- case SEG_STRTRK:
- REORIGIN( p0, segPtr->u.l.pos[0], angle, orig )
- REORIGIN( p1, segPtr->u.l.pos[1], angle, orig )
- DrawStraightTies( d, trk, p0, p1, color );
- break;
- case SEG_CRVTRK:
- a0 = NormalizeAngle(segPtr->u.c.a0 + angle);
- REORIGIN( c, segPtr->u.c.center, angle, orig );
- DrawCurvedTies( d, trk, c, fabs(segPtr->u.c.radius), a0, segPtr->u.c.a1, color );
- break;
- case SEG_JNTTRK:
- REORIGIN( p0, segPtr->u.j.pos, angle, orig );
- DrawJointTrack( d, p0, NormalizeAngle(segPtr->u.j.angle+angle), segPtr->u.j.l0, segPtr->u.j.l1, segPtr->u.j.R, segPtr->u.j.L, segPtr->u.j.negate, segPtr->u.j.flip, segPtr->u.j.Scurve, trk, -1, -1, trackGauge, color1, options );
- break;
- case SEG_BEZTRK:
- REORIGIN(p0, segPtr->u.b.pos[0], angle, orig);
- REORIGIN(p1, segPtr->u.b.pos[1], angle, orig);
- REORIGIN(p2, segPtr->u.b.pos[2], angle, orig);
- REORIGIN(p3, segPtr->u.b.pos[3], angle, orig);
- tempPtr = segPtr->bezSegs.ptr;
- for(int j=0;j<segPtr->bezSegs.cnt;j++,tempPtr++) { //Loop through sub parts (only Trks supported)
- if (tempPtr->type == SEG_CRVTRK) {
- a0 = NormalizeAngle(tempPtr->u.c.a0 + angle);
- REORIGIN( c, tempPtr->u.c.center, angle, orig );
- DrawCurvedTies( d, trk, c, fabs(tempPtr->u.c.radius), a0, tempPtr->u.c.a1, color );
- }
- if (tempPtr->type == SEG_STRTRK) {
- REORIGIN( p0, tempPtr->u.l.pos[0], angle, orig )
- REORIGIN( p1, tempPtr->u.l.pos[1], angle, orig )
- DrawStraightTies( d, trk, p0, p1, color );
- }
- }
- break;
- }
- continue;
- }
- switch (segPtr->type) {
- case SEG_STRTRK:
- case SEG_CRVTRK:
- case SEG_JNTTRK:
- case SEG_BEZTRK:
- case SEG_TEXT:
- break;
- default:
- if (d->options&DC_QUICK)
- return;
- if ((d->options&DC_SIMPLE) != 0 &&
- trackGauge != 0.0)
- return;
- }
+ wDrawWidth thick = 3;
+#ifdef WINDOWS
+ thick *= (wDrawWidth)(d->dpi/mainD.dpi);
+#endif
switch (segPtr->type) {
case SEG_STRLIN:
case SEG_DIMLIN:
@@ -1824,17 +1782,16 @@ EXPORT void DrawSegsO(
break;
DrawStraightTrack( d,
p0, p1,
- FindAngle(p0, p1 ),
- NULL, trackGauge, color1, options );
+ FindAngle(p1, p0 ),
+ trk, color1, options );
break;
case SEG_STRLIN:
- DrawLine( d, p0, p1, (wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
+ DrawLine( d, p0, p1, (d->options&DC_THICK)?thick:(wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
break;
case SEG_DIMLIN:
case SEG_BENCH:
case SEG_TBLEDGE:
- if ( (d->options&DC_GROUP) ||
- (segPtr->type == SEG_DIMLIN && d->funcs == &tempSegDrawFuncs) ) {
+ if ( (d->options&DC_SEGTRACK) ) {
DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 );
tempPtr = &tempSegs(tempSegs_da.cnt-1);
memcpy( tempPtr, segPtr, sizeof segPtr[0] );
@@ -1848,7 +1805,7 @@ EXPORT void DrawSegsO(
fs /= (option==0?8:option==1?4:option==2?2:1);
if ( fs < 2 )
fs = 2;
- DrawDimLine( d, p0, p1, FormatDistance(FindDistance(p0,p1)), fs, 0.5, 0, color, option & 0x00 );
+ DrawDimLine( d, p0, p1, FormatDistance(FindDistance(p0,p1)), fs, 0.5, (d->options&DC_THICK)?thick:0, color, option & 0x00 );
break;
case SEG_BENCH:
DrawBench( d, p0, p1, color1, color2, options, segPtr->u.l.option );
@@ -1876,10 +1833,10 @@ EXPORT void DrawSegsO(
fabs(segPtr->u.c.radius),
a0, segPtr->u.c.a1,
p0, p1,
- NULL, trackGauge, color1, options );
+ trk, color1, options );
} else {
DrawArc( d, c, fabs(segPtr->u.c.radius), a0, segPtr->u.c.a1,
- FALSE, (wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
+ FALSE, (d->options&DC_THICK)?thick:(wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
}
break;
case SEG_BEZTRK:
@@ -1889,7 +1846,7 @@ EXPORT void DrawSegsO(
color1 = normalColor;
if ( segPtr->color == wDrawColorWhite )
break;
- }
+ } else
REORIGIN(p0, segPtr->u.b.pos[0], angle, orig);
REORIGIN(p1, segPtr->u.b.pos[1], angle, orig);
REORIGIN(p2, segPtr->u.b.pos[2], angle, orig);
@@ -1911,10 +1868,10 @@ EXPORT void DrawSegsO(
fabs(tempPtr->u.c.radius),
a0, tempPtr->u.c.a1,
p0, p1,
- NULL, trackGauge, color1, options );
+ trk, color1, options );
} else if (tempPtr->type == SEG_CRVLIN) {
DrawArc( d, c, fabs(tempPtr->u.c.radius), a0, tempPtr->u.c.a1,
- FALSE, (wDrawWidth)floor(tempPtr->width*factor+0.5), color1 );
+ FALSE, (d->options&DC_THICK)?thick:(wDrawWidth)floor(tempPtr->width*factor+0.5), color1 );
}
break;
case SEG_STRTRK:
@@ -1922,15 +1879,14 @@ EXPORT void DrawSegsO(
if ( tempPtr->color == wDrawColorWhite ) break;
REORIGIN(p0,tempPtr->u.l.pos[0], angle, orig);
REORIGIN(p1,tempPtr->u.l.pos[1], angle, orig);
- DrawStraightTrack( d,
- p0, p1,
- FindAngle(p0, p1 ),
- NULL, trackGauge, color1, options );
+ DrawStraightTrack( d, p0, p1,
+ FindAngle(p1, p0 ),
+ trk, color1, options );
break;
case SEG_STRLIN:
REORIGIN(p0,tempPtr->u.l.pos[0], angle, orig);
REORIGIN(p1,tempPtr->u.l.pos[1], angle, orig);
- DrawLine( d, p0, p1, (wDrawWidth)floor(tempPtr->width*factor+0.5), color1 );
+ DrawLine( d, p0, p1, (d->options&DC_THICK)?thick:(wDrawWidth)floor(tempPtr->width*factor+0.5), color1 );
break;
}
}
@@ -1941,48 +1897,37 @@ EXPORT void DrawSegsO(
break;
case SEG_TEXT:
REORIGIN( p0, segPtr->u.t.pos, angle, orig )
- DrawMultiString( d, p0, segPtr->u.t.string, segPtr->u.t.fontP, segPtr->u.t.fontSize, color1, NormalizeAngle(angle + segPtr->u.t.angle), NULL, NULL );
+ DrawMultiString( d, p0, segPtr->u.t.string, segPtr->u.t.fontP, segPtr->u.t.fontSize, color1, NormalizeAngle(angle + segPtr->u.t.angle), NULL, NULL, segPtr->u.t.boxed );
break;
case SEG_FILPOLY:
- if ( (d->options&DC_GROUP) == 0 &&
- d->funcs != &tempSegDrawFuncs ) {
- /* Note: if we call tempSegDrawFillPoly we get a nasty bug
- /+ because we don't make a private copy of p.pts */
- coOrd *tempPts = malloc(sizeof(coOrd)*segPtr->u.p.cnt);
-// coOrd tempPts[segPtr->u.p.cnt];
- for (j=0;j<segPtr->u.p.cnt;j++) {
- REORIGIN( tempPts[j], segPtr->u.p.pts[j], angle, orig );
- }
- DrawFillPoly( d, segPtr->u.p.cnt, tempPts, color1 );
- free(tempPts);
- break;
- } /* else fall thru */
case SEG_POLY:
- if ( (d->options&DC_GROUP) ) {
- DYNARR_APPEND( trkSeg_t, tempSegs_da, 10 );
- tempPtr = &tempSegs(tempSegs_da.cnt-1);
- memcpy( tempPtr, segPtr, sizeof segPtr[0] );
- tempPtr->u.p.orig = orig;
- tempPtr->u.p.angle = angle;
- break;
- }
- REORIGIN( p0, segPtr->u.p.pts[0], angle, orig )
- c = p0;
- for (j=1; j<segPtr->u.p.cnt; j++) {
- REORIGIN( p1, segPtr->u.p.pts[j], angle, orig );
- DrawLine( d, p0, p1, (wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
- p0 = p1;
+ ;
+ /* Note: if we call tempSegDrawFillPoly we get a nasty bug
+ /+ because we don't make a private copy of p.pts */
+ coOrd *tempPts = malloc(sizeof(coOrd)*segPtr->u.p.cnt);
+ int *tempTypes = malloc(sizeof(int)*segPtr->u.p.cnt);
+// coOrd tempPts[segPtr->u.p.cnt];
+ for (j=0;j<segPtr->u.p.cnt;j++) {
+ REORIGIN( tempPts[j], segPtr->u.p.pts[j].pt, angle, orig );
+ tempTypes[j] = segPtr->u.p.pts[j].pt_type;
}
- DrawLine( d, p0, c, (wDrawWidth)floor(segPtr->width*factor+0.5), color1 );
+ bFill = (segPtr->type == SEG_FILPOLY);
+ if ( (d->options&DC_SIMPLE) && programMode != MODE_TRAIN )
+ bFill = FALSE;
+ DrawPoly( d, segPtr->u.p.cnt, tempPts, tempTypes, color1, (d->options&DC_THICK)?thick:(wDrawWidth)floor(segPtr->width*factor+0.5), bFill?1:0, segPtr->u.p.polyType==POLYLINE?1:0);
+ free(tempPts);
+ free(tempTypes);
break;
case SEG_FILCRCL:
REORIGIN( c, segPtr->u.c.center, angle, orig )
- if ( (d->options&DC_GROUP) != 0 ||
- d->funcs != &tempSegDrawFuncs ) {
+ bFill = TRUE;
+ if ( (d->options&DC_SIMPLE) && programMode != MODE_TRAIN )
+ bFill = FALSE;
+ if ( bFill ) {
DrawFillCircle( d, c, fabs(segPtr->u.c.radius), color1 );
} else {
DrawArc( d, c, fabs(segPtr->u.c.radius), 0, 360,
- FALSE, (wDrawWidth)0, color1 );
+ FALSE, (d->options&DC_THICK)?thick:(wDrawWidth)0, color1 );
}
break;
}
@@ -2003,7 +1948,8 @@ EXPORT void DrawSegs(
DIST_T trackGauge,
wDrawColor color )
{
- DrawSegsO( d, NULL, orig, angle, segPtr, segCnt, trackGauge, color, 0 );
+
+ DrawSegsO( d, NULL, orig, angle, segPtr, segCnt, trackGauge, color, DTS_LEFT|DTS_RIGHT );
}
/*
@@ -2031,16 +1977,170 @@ EXPORT void CleanSegs(dynArr_t * seg_p) {
seg_p->max = 0;
}
+/*
+ * Copy Segs from one array to another
+ */
+EXPORT void AppendSegsToArray(dynArr_t * seg_to, dynArr_t * seg_from) {
+ if (seg_from->cnt ==0) return;
+ int j = 0;
+ DYNARR_APPEND(trkSeg_t, * seg_to, seg_from->cnt);
+ for (int i=0; i<seg_from->cnt;i++,j++) {
+ trkSeg_p from_p = &DYNARR_N(trkSeg_t, * seg_from,j);
+ trkSeg_p to_p = &DYNARR_N(trkSeg_t, * seg_to,i);
+ memcpy((void *)to_p,(void *)from_p,sizeof( trkSeg_t));
+ if (from_p->type == SEG_BEZLIN || from_p->type == SEG_BEZTRK) {
+ if (from_p->bezSegs.ptr) {
+ to_p->bezSegs.ptr = memdup(from_p->bezSegs.ptr,from_p->bezSegs.cnt*sizeof(trkSeg_t));
+ }
+ }
+ if (from_p->type == SEG_POLY || from_p->type == SEG_FILPOLY) {
+ if (from_p->u.p.pts) {
+ to_p->u.p.pts = memdup(from_p->u.p.pts,from_p->u.p.cnt*sizeof(pts_t));
+ }
+ }
+ }
+}
+
+EXPORT void AppendTransformedSegs(dynArr_t * seg_to, dynArr_t * seg_from, coOrd orig, coOrd rotateOrig, ANGLE_T angle) {
+ if (seg_from->cnt ==0) return;
+ int j = 0;
+ DYNARR_APPEND(trkSeg_t, * seg_to, seg_from->cnt);
+ for (int i=0; i<seg_from->cnt;i++,j++) {
+ trkSeg_p from_p = &DYNARR_N(trkSeg_t, * seg_from,j);
+ trkSeg_p to_p = &DYNARR_N(trkSeg_t, * seg_to,i);
+ memcpy((void *)to_p,(void *)from_p,sizeof( trkSeg_t));
+ if (from_p->type == SEG_BEZLIN || from_p->type == SEG_BEZTRK) {
+ if (from_p->bezSegs.ptr) {
+ to_p->bezSegs.ptr = memdup(from_p->bezSegs.ptr,from_p->bezSegs.cnt*sizeof(trkSeg_t));
+ }
+ }
+ if (from_p->type == SEG_POLY || from_p->type == SEG_FILPOLY) {
+ if (from_p->u.p.pts) {
+ to_p->u.p.pts = memdup(from_p->u.p.pts,from_p->u.p.cnt*sizeof(pts_t));
+ }
+ }
+ RotateSegs(1,to_p,rotateOrig,angle);
+ coOrd move;
+ move.x = orig.x - rotateOrig.x;
+ move.y = orig.y - rotateOrig.y;
+ MoveSegs(1,to_p,move);
+ }
+}
+
EXPORT void CopyPoly(trkSeg_p p, wIndex_t segCnt) {
- coOrd * newPts;
+ pts_t * newPts;
for (int i=0;i<segCnt;i++,p++) {
- if (p->type == SEG_POLY || p->type == SEG_FILPOLY) {
- newPts = memdup( p->u.p.pts, p->u.p.cnt*sizeof (coOrd) );
+ if ((p->type == SEG_POLY) || (p->type == SEG_FILPOLY)) {
+ newPts = memdup( p->u.p.pts, p->u.p.cnt*sizeof (pts_t) );
p->u.p.pts = newPts;
}
+ if ( p->type == SEG_TEXT ) {
+ p->u.t.string = MyStrdup( p->u.t.string );
+ }
}
}
-
-
+EXPORT wBool_t CompareSegs(
+ trkSeg_p segPtr1,
+ int segCnt1,
+ trkSeg_p segPtr2,
+ int segCnt2 )
+{
+ char * cp = message+strlen(message);
+ if ( segCnt1 != segCnt2 ) {
+ sprintf( cp, "SegCnt %d %d\n", segCnt1, segCnt2 );
+ return FALSE;
+ }
+ char * cq = cp-2;;
+ for ( int segInx = 0; segInx < segCnt1; segInx++ ) {
+ cp = cq;
+ sprintf( cp, "SEG:%d - ", segInx );
+ cp += strlen( cp );
+ trkSeg_p segP1 = &segPtr1[segInx];
+ trkSeg_p segP2 = &segPtr2[segInx];
+ REGRESS_CHECK_INT( "Type", segP1, segP2, type );
+ REGRESS_CHECK_COLOR( "Color", segP1, segP2, color );
+ switch( segP1->type ) {
+ case SEG_DIMLIN:
+ case SEG_TBLEDGE:
+ case SEG_BENCH:
+ // These don't have widths
+ break;
+ default:
+ REGRESS_CHECK_WIDTH( "Width", segP1, segP2, width );
+ }
+ switch( segP1->type ) {
+ case SEG_DIMLIN:
+ case SEG_TBLEDGE:
+ // These don't have color
+ break;
+ default:
+ REGRESS_CHECK_COLOR( "Color", segP1, segP2, color );
+ }
+ switch( segP1->type ) {
+ case SEG_STRTRK:
+ case SEG_STRLIN:
+ case SEG_DIMLIN:
+ case SEG_BENCH:
+ case SEG_TBLEDGE:
+ REGRESS_CHECK_POS( "Pos[0]", segP1, segP2, u.l.pos[0] )
+ REGRESS_CHECK_POS( "Pos[1]", segP1, segP2, u.l.pos[1] )
+// REGRESS_CHECK_POS( "Pos[2]", segP1, segP2, u.l.pos[2] )
+// REGRESS_CHECK_POS( "Pos[3]", segP1, segP2, u.l.pos[3] )
+ REGRESS_CHECK_ANGLE( "Angle", segP1, segP2, u.l.angle )
+ REGRESS_CHECK_INT( "Option", segP1, segP2, u.l.option )
+ break;
+ case SEG_BEZTRK:
+ case SEG_BEZLIN:
+ break; // u.b
+ case SEG_CRVLIN:
+ case SEG_CRVTRK:
+ case SEG_FILCRCL:
+ REGRESS_CHECK_POS( "Center", segP1, segP2, u.c.center )
+ REGRESS_CHECK_ANGLE( "A0", segP1, segP2, u.c.a0 )
+ REGRESS_CHECK_ANGLE( "A1", segP1, segP2, u.c.a1 )
+ REGRESS_CHECK_DIST( "Radius", segP1, segP2, u.c.radius )
+ break; // u.c
+ case SEG_JNTTRK:
+ REGRESS_CHECK_POS( "Pos", segP1, segP2, u.j.pos )
+ REGRESS_CHECK_ANGLE( "Angle", segP1, segP2, u.j.angle )
+ REGRESS_CHECK_DIST( "R", segP1, segP2, u.j.R )
+ REGRESS_CHECK_DIST( "L", segP1, segP2, u.j.L )
+ REGRESS_CHECK_DIST( "L0", segP1, segP2, u.j.l0 )
+ REGRESS_CHECK_DIST( "L1", segP1, segP2, u.j.l1 );
+ REGRESS_CHECK_INT( "Flip", segP1, segP2, u.j.flip )
+ REGRESS_CHECK_INT( "Negate", segP1, segP2, u.j.negate )
+ REGRESS_CHECK_INT( "Scurve", segP1, segP2, u.j.Scurve )
+ break; // u.j
+ case SEG_TEXT:
+ REGRESS_CHECK_POS( "Pos", segP1, segP2, u.t.pos )
+ REGRESS_CHECK_ANGLE( "Angle", segP1, segP2, u.t.angle )
+ // CHECK fontP
+ REGRESS_CHECK_DIST( "Fontsize", segP1, segP2, u.t.fontSize )
+ REGRESS_CHECK_INT( "Boxed", segP1, segP2, u.t.boxed )
+ // CHECK string
+ break; // u.t
+ case SEG_POLY:
+ case SEG_FILPOLY:
+ REGRESS_CHECK_INT( "Cnt", segP1, segP2, u.p.cnt )
+ // CHECK pts
+ REGRESS_CHECK_POS( "Orig", segP1, segP2, u.p.orig )
+ REGRESS_CHECK_ANGLE( "Angle", segP1, segP2, u.p.angle )
+ break; // u.p
+ // EndPts
+ case SEG_UNCEP:
+ case SEG_CONEP:
+ break;
+ // Turnout/Struct
+ case SEG_PATH:
+ case SEG_SPEC:
+ case SEG_CUST:
+ case SEG_DOFF:
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}