From b623f5953691b2a0614e6f1f4def86bdbb9a4113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sat, 8 Aug 2020 11:53:00 +0200 Subject: New upstream version 5.2.0Beta2.1 --- app/bin/trkseg.c | 558 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 329 insertions(+), 229 deletions(-) (limited to 'app/bin/trkseg.c') 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; inxu.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; inxu.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; inxu.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; inxu.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; inxu.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; inxu.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;linu.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; inxu.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; iu.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 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; icolor; @@ -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;jbezSegs.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;ju.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; ju.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;ju.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; icnt;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; icnt;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;itype == 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; +} -- cgit v1.2.3