diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2016-12-28 16:52:56 +0100 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2016-12-28 16:52:56 +0100 |
commit | 7b358424ebad9349421acd533c2fa1cbf6cf3e3e (patch) | |
tree | 686678532eefed525c242fd214d0cfb2914726c5 /app/bin/cdraw.c |
Initial import of xtrkcad version 1:4.0.2-2
Diffstat (limited to 'app/bin/cdraw.c')
-rw-r--r-- | app/bin/cdraw.c | 1245 |
1 files changed, 1245 insertions, 0 deletions
diff --git a/app/bin/cdraw.c b/app/bin/cdraw.c new file mode 100644 index 0000000..59e45b8 --- /dev/null +++ b/app/bin/cdraw.c @@ -0,0 +1,1245 @@ +/** \file cdraw.c + * Drawing of geometric elements + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "track.h" +#include "ccurve.h" +#include "drawgeom.h" +#include "i18n.h" + +#include <stdint.h> + +extern void wSetSelectedFontSize(int size); + +static long fontSizeList[] = { + 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, + 40, 48, 56, 64, 72, 80, 90, 100, 120, 140, 160, 180, + 200, 250, 300, 350, 400, 450, 500 }; + +EXPORT void LoadFontSizeList( + wList_p list, + long curFontSize ) +{ + wIndex_t curInx=0, inx1; + int inx; + wListClear( list ); + for ( inx=0; inx<sizeof fontSizeList/sizeof fontSizeList[0]; inx++ ) { + if ( ( inx==0 || curFontSize > fontSizeList[inx-1] ) && + ( curFontSize < fontSizeList[inx] ) ) { + sprintf( message, "%ld", curFontSize ); + curInx = wListAddValue( list, message, NULL, (void*)curFontSize ); + } + sprintf( message, "%ld", fontSizeList[inx] ); + inx1 = wListAddValue( list, message, NULL, (void*)fontSizeList[inx] ); + if ( curFontSize == fontSizeList[inx] ) + curInx = inx1; + } + if ( curFontSize > fontSizeList[(sizeof fontSizeList/sizeof fontSizeList[0])-1] ) { + sprintf( message, "%ld", curFontSize ); + curInx = wListAddValue( list, message, NULL, (void*)curFontSize ); + } + wListSetIndex( list, curInx ); + wFlush(); +} + + +EXPORT void UpdateFontSizeList( + long * fontSizeR, + wList_p list, + wIndex_t listInx ) +{ + long fontSize; + + if ( listInx >= 0 ) { + *fontSizeR = (long)wListGetItemContext( list, listInx ); + } else { + wListGetValues( list, message, sizeof message, NULL, NULL ); + if ( message[0] != '\0' ) { + fontSize = atol( message ); + if ( fontSize <= 0 ) { + NoticeMessage( _("Font Size must be > 0"), _("Ok"), NULL ); + sprintf( message, "%ld", *fontSizeR ); + wListSetValue( list, message ); + } else { + if ( fontSize <= 500 || NoticeMessage( MSG_LARGE_FONT, _("Yes"), _("No") ) > 0 ) { + + *fontSizeR = fontSize; + /* inform gtkfont dialog from change */ + wSetSelectedFontSize((int)fontSize); + /*LoadFontSizeList( list, *fontSizeR );*/ + } else { + sprintf( message, "%ld", *fontSizeR ); + wListSetValue( list, message ); + } + } + } + } +} + +/******************************************************************************* + * + * DRAW + * + */ + +struct extraData { + coOrd orig; + ANGLE_T angle; + wIndex_t segCnt; + trkSeg_t segs[1]; + }; + +static TRKTYP_T T_DRAW = -1; +static track_p ignoredTableEdge; +static track_p ignoredDraw; + + +static void ComputeDrawBoundingBox( track_p t ) +{ + struct extraData * xx = GetTrkExtraData(t); + coOrd lo, hi; + + GetSegBounds( xx->orig, xx->angle, xx->segCnt, xx->segs, &lo, &hi ); + hi.x += lo.x; + hi.y += lo.y; + SetBoundingBox( t, hi, lo ); +} + + +static track_p MakeDrawFromSeg1( + wIndex_t index, + coOrd pos, + ANGLE_T angle, + trkSeg_p sp ) +{ + struct extraData * xx; + track_p trk; + if ( sp->type == ' ' ) + return NULL; + trk = NewTrack( index, T_DRAW, 0, sizeof *xx ); + xx = GetTrkExtraData( trk ); + xx->orig = pos; + xx->angle = angle; + xx->segCnt = 1; + memcpy( xx->segs, sp, sizeof *(trkSeg_p)0 ); + ComputeDrawBoundingBox( trk ); + return trk; +} + +EXPORT track_p MakeDrawFromSeg( + coOrd pos, + ANGLE_T angle, + trkSeg_p sp ) +{ + return MakeDrawFromSeg1( 0, pos, angle, sp ); +} + + + + +static DIST_T DistanceDraw( track_p t, coOrd * p ) +{ + struct extraData * xx = GetTrkExtraData(t); + if ( ignoredTableEdge == t && xx->segs[0].type == SEG_TBLEDGE ) + return 100000.0; + if ( ignoredDraw == t ) + return 100000.0; + return DistanceSegs( xx->orig, xx->angle, xx->segCnt, xx->segs, p, NULL ); +} + + +static struct { + coOrd endPt[2]; + FLOAT_T length; + coOrd center; + DIST_T radius; + ANGLE_T angle0; + ANGLE_T angle1; + ANGLE_T angle; + long pointCount; + long lineWidth; + wDrawColor color; + wIndex_t benchChoice; + wIndex_t benchOrient; + wIndex_t dimenSize; + descPivot_t pivot; + wIndex_t fontSizeInx; + char text[STR_SIZE]; + LAYER_T layer; + } drawData; +typedef enum { E0, E1, CE, RA, LN, AL, A1, A2, VC, LW, CO, BE, OR, DS, TP, TA, TS, TX, PV, LY } drawDesc_e; +static descData_t drawDesc[] = { +/*E0*/ { DESC_POS, N_("End Pt 1: X"), &drawData.endPt[0] }, +/*E1*/ { DESC_POS, N_("End Pt 2: X"), &drawData.endPt[1] }, +/*CE*/ { DESC_POS, N_("Center: X"), &drawData.center }, +/*RA*/ { DESC_DIM, N_("Radius"), &drawData.radius }, +/*LN*/ { DESC_DIM, N_("Length"), &drawData.length }, +/*AL*/ { DESC_FLOAT, N_("Angle"), &drawData.angle }, +/*A1*/ { DESC_ANGLE, N_("CCW Angle"), &drawData.angle0 }, +/*A2*/ { DESC_ANGLE, N_("CW Angle"), &drawData.angle1 }, +/*VC*/ { DESC_LONG, N_("Point Count"), &drawData.pointCount }, +/*LW*/ { DESC_LONG, N_("Line Width"), &drawData.lineWidth }, +/*CO*/ { DESC_COLOR, N_("Color"), &drawData.color }, +/*BE*/ { DESC_LIST, N_("Lumber"), &drawData.benchChoice }, +/*OR*/ { DESC_LIST, N_("Orientation"), &drawData.benchOrient }, +/*DS*/ { DESC_LIST, N_("Size"), &drawData.dimenSize }, +/*TP*/ { DESC_POS, N_("Origin: X"), &drawData.endPt[0] }, +/*TA*/ { DESC_FLOAT, N_("Angle"), &drawData.angle }, +/*TS*/ { DESC_EDITABLELIST, N_("Font Size"), &drawData.fontSizeInx }, +/*TX*/ { DESC_STRING, N_("Text"), &drawData.text }, +/*PV*/ { DESC_PIVOT, N_("Pivot"), &drawData.pivot }, +/*LY*/ { DESC_LAYER, N_("Layer"), &drawData.layer }, + { DESC_NULL } }; +int drawSegInx; + +#define UNREORIGIN( Q, P, A, O ) { \ + (Q) = (P); \ + (Q).x -= (O).x; \ + (Q).y -= (O).y; \ + if ( (A) != 0.0 ) \ + Rotate( &(Q), zero, -(A) ); \ + } + +static void UpdateDraw( track_p trk, int inx, descData_p descUpd, BOOL_T final ) +{ + struct extraData *xx = GetTrkExtraData(trk); + trkSeg_p segPtr; + coOrd mid; + const char * text; + long fontSize; + + if ( drawSegInx==-1 ) + return; + if ( inx == -1 ) + return; + segPtr = &xx->segs[drawSegInx]; + MainRedraw(); + //UndrawNewTrack( trk ); + switch ( inx ) { + case LW: + segPtr->width = drawData.lineWidth/mainD.dpi; + break; + case CO: + segPtr->color = drawData.color; + break; + case E0: + case E1: + if ( inx == E0 ) { + UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); + } else { + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + } + drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); + drawData.angle = FindAngle( drawData.endPt[0], drawData.endPt[1] ); + drawDesc[LN].mode |= DESC_CHANGE; + drawDesc[AL].mode |= DESC_CHANGE; + break; + case LN: + case AL: + if ( segPtr->type == SEG_CRVLIN && inx == AL ) { + if ( drawData.angle <= 0.0 || drawData.angle >= 360.0 ) { + ErrorMessage( MSG_CURVE_OUT_OF_RANGE ); + drawData.angle = segPtr->u.c.a1; + drawDesc[AL].mode |= DESC_CHANGE; + break; + } + } else { + if ( drawData.length <= minLength ) { + ErrorMessage( MSG_OBJECT_TOO_SHORT ); + if ( segPtr->type != SEG_CRVLIN ) { + drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); + } else { + drawData.length = segPtr->u.c.radius*2*M_PI*segPtr->u.c.a1/360.0; + } + drawDesc[LN].mode |= DESC_CHANGE; + break; + } + } + if ( segPtr->type != SEG_CRVLIN ) { + switch ( drawData.pivot ) { + case DESC_PIVOT_FIRST: + Translate( &drawData.endPt[1], drawData.endPt[0], drawData.angle, drawData.length ); + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + drawDesc[E1].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_SECOND: + Translate( &drawData.endPt[0], drawData.endPt[1], drawData.angle+180.0, drawData.length ); + UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); + drawDesc[E0].mode |= DESC_CHANGE; + break; + case DESC_PIVOT_MID: + mid.x = (drawData.endPt[0].x+drawData.endPt[1].x)/2.0; + mid.y = (drawData.endPt[0].y+drawData.endPt[1].y)/2.0; + Translate( &drawData.endPt[0], mid, drawData.angle+180.0, drawData.length/2.0 ); + Translate( &drawData.endPt[1], mid, drawData.angle, drawData.length/2.0 ); + UNREORIGIN( segPtr->u.l.pos[0], drawData.endPt[0], xx->angle, xx->orig ); + UNREORIGIN( segPtr->u.l.pos[1], drawData.endPt[1], xx->angle, xx->orig ); + drawDesc[E0].mode |= DESC_CHANGE; + drawDesc[E1].mode |= DESC_CHANGE; + break; + default: + break; + } + } else { + if ( drawData.angle < 0.0 || drawData.angle >= 360.0 ) { + ErrorMessage( MSG_CURVE_OUT_OF_RANGE ); + drawData.angle = segPtr->u.c.a1; + drawDesc[AL].mode |= DESC_CHANGE; + } else { + segPtr->u.c.a0 = NormalizeAngle( segPtr->u.c.a0+segPtr->u.c.a1/2.0-drawData.angle/2.0); + segPtr->u.c.a1 = drawData.angle; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+segPtr->u.c.a1 ); + drawDesc[A1].mode |= DESC_CHANGE; + drawDesc[A2].mode |= DESC_CHANGE; + } + } + break; + case CE: + UNREORIGIN( segPtr->u.c.center, drawData.center, xx->angle, xx->orig ); + break; + case RA: + segPtr->u.c.radius = drawData.radius; + break; + case A1: + segPtr->u.c.a0 = NormalizeAngle( drawData.angle0-xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+drawData.angle ); + drawDesc[A2].mode |= DESC_CHANGE; + break; + case A2: + segPtr->u.c.a0 = NormalizeAngle( drawData.angle1-segPtr->u.c.a1-xx->angle ); + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawDesc[A1].mode |= DESC_CHANGE; + break; + case BE: + BenchUpdateOrientationList( (long)wListGetItemContext((wList_p)drawDesc[BE].control0, drawData.benchChoice ), (wList_p)drawDesc[OR].control0 ); + if ( drawData.benchOrient < wListGetCount( (wList_p)drawDesc[OR].control0 ) ) + wListSetIndex( (wList_p)drawDesc[OR].control0, drawData.benchOrient ); + else + drawData.benchOrient = 0; + segPtr->u.l.option = GetBenchData( (long)wListGetItemContext((wList_p)drawDesc[BE].control0, drawData.benchChoice ), drawData.benchOrient ); + break; + case OR: + segPtr->u.l.option = GetBenchData( (long)wListGetItemContext((wList_p)drawDesc[BE].control0, drawData.benchChoice ), drawData.benchOrient ); + break; + case DS: + segPtr->u.l.option = drawData.dimenSize; + break; + case TP: + UNREORIGIN( segPtr->u.t.pos, drawData.endPt[0], xx->angle, xx->orig ); + break; + case TA: + //segPtr->u.t.angle = NormalizeAngle( drawData.angle ); + xx->angle = NormalizeAngle( drawData.angle ); + break; + case TS: + fontSize = (long)segPtr->u.t.fontSize; + UpdateFontSizeList( &fontSize, (wList_p)drawDesc[TS].control0, drawData.fontSizeInx ); + segPtr->u.t.fontSize = fontSize; + break; + case TX: + text = wStringGetValue( (wString_p)drawDesc[TX].control0 ); + if ( text && text[0] && strcmp( segPtr->u.t.string, text ) != 0 ) { + MyFree( segPtr->u.t.string ); + segPtr->u.t.string = MyStrdup( text ); + /*(char*)drawDesc[TX].valueP = segPtr->u.t.string;*/ + } + break; + case LY: + SetTrkLayer( trk, drawData.layer); + break; + default: + AbortProg( "bad op" ); + } + ComputeDrawBoundingBox( trk ); + DrawNewTrack( trk ); +} + +static void DescribeDraw( track_p trk, char * str, CSIZE_T len ) +{ + struct extraData *xx = GetTrkExtraData(trk); + coOrd pos = oldMarker; + trkSeg_p segPtr; + int inx; + char * title = NULL; + + + DistanceSegs( xx->orig, xx->angle, xx->segCnt, xx->segs, &pos, &drawSegInx ); + if ( drawSegInx==-1 ) + return; + segPtr = &xx->segs[drawSegInx]; + for ( inx=0; inx<sizeof drawDesc/sizeof drawDesc[0]; inx++ ) { + drawDesc[inx].mode = DESC_IGNORE; + drawDesc[inx].control0 = NULL; + } + drawData.color = segPtr->color; + drawDesc[CO].mode = 0; + drawData.lineWidth = (long)floor(segPtr->width*mainD.dpi+0.5); + drawDesc[LW].mode = 0; + drawDesc[LY].mode = DESC_NOREDRAW; + drawDesc[BE].mode = + drawDesc[OR].mode = + drawDesc[DS].mode = DESC_IGNORE; + drawData.pivot = DESC_PIVOT_MID; + switch ( segPtr->type ) { + case SEG_STRLIN: + case SEG_DIMLIN: + case SEG_BENCH: + case SEG_TBLEDGE: + REORIGIN( drawData.endPt[0], segPtr->u.l.pos[0], xx->angle, xx->orig ); + REORIGIN( drawData.endPt[1], segPtr->u.l.pos[1], xx->angle, xx->orig ); + drawData.length = FindDistance( drawData.endPt[0], drawData.endPt[1] ); + drawData.angle = FindAngle( drawData.endPt[0], drawData.endPt[1] ); + drawDesc[LN].mode = + drawDesc[AL].mode = + drawDesc[PV].mode = 0; + drawDesc[E0].mode = + drawDesc[E1].mode = 0; + switch (segPtr->type) { + case SEG_STRLIN: + title = _("Straight Line"); + break; + case SEG_DIMLIN: + title = _("Dimension Line"); + drawDesc[CO].mode = DESC_IGNORE; + drawDesc[LW].mode = DESC_IGNORE; + drawData.dimenSize = (wIndex_t)segPtr->u.l.option; + drawDesc[DS].mode = 0; + break; + case SEG_BENCH: + title = _("Lumber"); + drawDesc[LW].mode = DESC_IGNORE; + drawDesc[BE].mode = + drawDesc[OR].mode = 0; + drawData.benchChoice = GetBenchListIndex( segPtr->u.l.option ); + drawData.benchOrient = (wIndex_t)(segPtr->u.l.option&0xFF); + break; + case SEG_TBLEDGE: + title = _("Table Edge"); + drawDesc[CO].mode = DESC_IGNORE; + drawDesc[LW].mode = DESC_IGNORE; + break; + } + break; + case SEG_CRVLIN: + REORIGIN( drawData.center, segPtr->u.c.center, xx->angle, xx->orig ); + drawData.radius = segPtr->u.c.radius; + drawDesc[CE].mode = + drawDesc[RA].mode = 0; + if ( segPtr->u.c.a1 >= 360.0 ) { + title = _("Circle"); + } else { + drawData.angle = segPtr->u.c.a1; + drawData.angle0 = NormalizeAngle( segPtr->u.c.a0+xx->angle ); + drawData.angle1 = NormalizeAngle( drawData.angle0+drawData.angle ); + drawDesc[AL].mode = + drawDesc[A1].mode = + drawDesc[A2].mode = 0; + title = _("Curved Line"); + } + break; + case SEG_FILCRCL: + REORIGIN( drawData.center, segPtr->u.c.center, xx->angle, xx->orig ); + drawData.radius = segPtr->u.c.radius; + drawDesc[CE].mode = + drawDesc[RA].mode = 0; + drawDesc[LW].mode = DESC_IGNORE; + title = _("Filled Circle"); + break; + case SEG_POLY: + drawData.pointCount = segPtr->u.p.cnt; + drawDesc[VC].mode = DESC_RO; + title = _("Poly Line"); + break; + case SEG_FILPOLY: + drawData.pointCount = segPtr->u.p.cnt; + drawDesc[VC].mode = DESC_RO; + drawDesc[LW].mode = DESC_IGNORE; + title = _("Polygon"); + break; + case SEG_TEXT: + REORIGIN( drawData.endPt[0], segPtr->u.t.pos, xx->angle, xx->orig ); + //drawData.angle = NormalizeAngle( segPtr->u.t.angle ); + drawData.angle = NormalizeAngle( xx->angle ); + strncpy( drawData.text, segPtr->u.t.string, sizeof drawData.text ); + /*drawData.fontSize = segPtr->u.t.fontSize;*/ + /*(char*)drawDesc[TX].valueP = segPtr->u.t.string;*/ + drawDesc[TP].mode = + drawDesc[TS].mode = + drawDesc[TX].mode = + drawDesc[TA].mode = + drawDesc[CO].mode = 0; /*Allow Text color setting*/ + drawDesc[LW].mode = DESC_IGNORE; + title = _("Text"); + break; + default: + AbortProg( "bad seg type" ); + } + + sprintf( str, _("%s: Layer=%d"), title, GetTrkLayer(trk)+1 ); + + DoDescribe( title, trk, drawDesc, UpdateDraw ); + if ( segPtr->type==SEG_BENCH && drawDesc[BE].control0!=NULL && drawDesc[OR].control0!=NULL) { + BenchLoadLists( (wList_p)drawDesc[BE].control0, (wList_p)drawDesc[OR].control0 ); + wListSetIndex( (wList_p)drawDesc[BE].control0, drawData.benchChoice ); + BenchUpdateOrientationList( (long)wListGetItemContext((wList_p)drawDesc[BE].control0, drawData.benchChoice ), (wList_p)drawDesc[OR].control0 ); + wListSetIndex( (wList_p)drawDesc[OR].control0, drawData.benchOrient ); + } + if ( segPtr->type==SEG_DIMLIN && drawDesc[DS].control0!=NULL ) { + wListClear( (wList_p)drawDesc[DS].control0 ); + wListAddValue( (wList_p)drawDesc[DS].control0, _("Tiny"), NULL, (void*)0 ); + wListAddValue( (wList_p)drawDesc[DS].control0, _("Small"), NULL, (void*)1 ); + wListAddValue( (wList_p)drawDesc[DS].control0, _("Medium"), NULL, (void*)2 ); + wListAddValue( (wList_p)drawDesc[DS].control0, _("Large"), NULL, (void*)3 ); + wListSetIndex( (wList_p)drawDesc[DS].control0, drawData.dimenSize ); + } + if ( segPtr->type==SEG_TEXT && drawDesc[TS].control0!=NULL ) { + LoadFontSizeList( (wList_p)drawDesc[TS].control0, (long)segPtr->u.t.fontSize ); + } +} + + +static void DrawDraw( track_p t, drawCmd_p d, wDrawColor color ) +{ + struct extraData * xx = GetTrkExtraData(t); + if ( (d->options&DC_QUICK) == 0 ) + DrawSegs( d, xx->orig, xx->angle, xx->segs, xx->segCnt, 0.0, color ); +} + + +static void DeleteDraw( track_p t ) +{ +} + + +static BOOL_T WriteDraw( track_p t, FILE * f ) +{ + struct extraData * xx = GetTrkExtraData(t); + BOOL_T rc = TRUE; + rc &= fprintf(f, "DRAW %d %d 0 0 0 %0.6f %0.6f 0 %0.6f\n", GetTrkIndex(t), GetTrkLayer(t), + xx->orig.x, xx->orig.y, xx->angle )>0; + rc &= WriteSegs( f, xx->segCnt, xx->segs ); + return rc; +} + + +static void ReadDraw( char * header ) +{ + track_p trk; + wIndex_t index; + coOrd orig; + DIST_T elev; + ANGLE_T angle; + wIndex_t layer; + struct extraData * xx; + + if ( !GetArgs( header+5, paramVersion<3?"dXpYf":paramVersion<9?"dL000pYf":"dL000pff", + &index, &layer, &orig, &elev, &angle ) ) + return; + ReadSegs(); + if (tempSegs_da.cnt == 1) { + trk = MakeDrawFromSeg1( index, orig, angle, &tempSegs(0) ); + SetTrkLayer( trk, layer ); + } else { + trk = NewTrack( index, T_DRAW, 0, sizeof *xx + (tempSegs_da.cnt-1) * sizeof *(trkSeg_p)0 ); + SetTrkLayer( trk, layer ); + xx = GetTrkExtraData(trk); + xx->orig = orig; + xx->angle = angle; + xx->segCnt = tempSegs_da.cnt; + memcpy( xx->segs, tempSegs_da.ptr, tempSegs_da.cnt * sizeof *(trkSeg_p)0 ); + ComputeDrawBoundingBox( trk ); + } +} + + +static void MoveDraw( track_p trk, coOrd orig ) +{ + struct extraData * xx = GetTrkExtraData(trk); + xx->orig.x += orig.x; + xx->orig.y += orig.y; + ComputeDrawBoundingBox( trk ); +} + + +static void RotateDraw( track_p trk, coOrd orig, ANGLE_T angle ) +{ + struct extraData * xx = GetTrkExtraData(trk); + Rotate( &xx->orig, orig, angle ); + xx->angle = NormalizeAngle( xx->angle + angle ); + ComputeDrawBoundingBox( trk ); +} + + +static void RescaleDraw( track_p trk, FLOAT_T ratio ) +{ + struct extraData * xx = GetTrkExtraData(trk); + xx->orig.x *= ratio; + xx->orig.y *= ratio; + RescaleSegs( xx->segCnt, xx->segs, ratio, ratio, ratio ); +} + + +static STATUS_T ModifyDraw( track_p trk, wAction_t action, coOrd pos ) +{ + struct extraData * xx = GetTrkExtraData(trk); + STATUS_T rc; + + if (action == C_DOWN) { + //UndrawNewTrack( trk ); + } + if ( action == C_MOVE ) + ignoredDraw = trk; + rc = DrawGeomModify( xx->orig, xx->angle, xx->segCnt, xx->segs, action, pos, GetTrkSelected(trk) ); + ignoredDraw = NULL; + if (action == C_UP) { + ComputeDrawBoundingBox( trk ); + DrawNewTrack( trk ); + } + return rc; +} + + +static void UngroupDraw( track_p trk ) +{ + struct extraData * xx = GetTrkExtraData(trk); + int inx; + if ( xx->segCnt <= 1 ) + return; + DeleteTrack( trk, FALSE ); + for ( inx=0; inx<xx->segCnt; inx++ ) { + trk = MakeDrawFromSeg( xx->orig, xx->angle, &xx->segs[inx] ); + if ( trk ) { + SetTrkBits( trk, TB_SELECTED ); + DrawNewTrack( trk ); + } + } +} + + +static ANGLE_T GetAngleDraw( + track_p trk, + coOrd pos, + EPINX_T * ep0, + EPINX_T * ep1 ) +{ + struct extraData * xx = GetTrkExtraData(trk); + ANGLE_T angle; + + pos.x -= xx->orig.x; + pos.y -= xx->orig.y; + Rotate( &pos, zero, -xx->angle ); + angle = GetAngleSegs( xx->segCnt, xx->segs, pos, NULL ); + if ( ep0 ) *ep0 = -1; + if ( ep1 ) *ep1 = -1; + return NormalizeAngle( angle + xx->angle ); +} + + + +static BOOL_T EnumerateDraw( + track_p trk ) +{ + struct extraData * xx; + int inx; + trkSeg_p segPtr; + + if ( trk ) { + xx = GetTrkExtraData(trk); + if ( xx->segCnt < 1 ) + return TRUE; + for ( inx=0; inx<xx->segCnt; inx++ ) { + segPtr = &xx->segs[inx]; + if ( segPtr->type == SEG_BENCH ) { + CountBench( segPtr->u.l.option, FindDistance( segPtr->u.l.pos[0], segPtr->u.l.pos[1] ) ); + } + } + } else { + TotalBench(); + } + return TRUE; +} + + +static void FlipDraw( + track_p trk, + coOrd orig, + ANGLE_T angle ) +{ + struct extraData * xx = GetTrkExtraData(trk); + FlipPoint( &xx->orig, orig, angle ); + xx->angle = NormalizeAngle( 2*angle - xx->angle + 180.0 ); + FlipSegs( xx->segCnt, xx->segs, zero, angle ); + ComputeDrawBoundingBox( trk ); +} + + +static trackCmd_t drawCmds = { + "DRAW", + DrawDraw, + DistanceDraw, + DescribeDraw, + DeleteDraw, + WriteDraw, + ReadDraw, + MoveDraw, + RotateDraw, + RescaleDraw, + NULL, + GetAngleDraw, /* getAngle */ + NULL, /* split */ + NULL, /* traverse */ + EnumerateDraw, + NULL, /* redraw */ + NULL, /* trim */ + NULL, /* merge */ + ModifyDraw, + NULL, /* getLength */ + NULL, /* getTrackParams */ + NULL, /* moveEndPt */ + NULL, /* query */ + UngroupDraw, + FlipDraw }; + +EXPORT BOOL_T OnTableEdgeEndPt( track_p trk, coOrd * pos ) +{ + track_p trk1; + struct extraData *xx; + coOrd pos1 = *pos; + + ignoredTableEdge = trk; + if ((trk1 = OnTrack( &pos1, FALSE, FALSE )) != NULL && + GetTrkType(trk1) == T_DRAW) { + ignoredTableEdge = NULL; + xx = GetTrkExtraData(trk1); + if (xx->segCnt < 1) + return FALSE; + if (xx->segs[0].type == SEG_TBLEDGE) { + if ( IsClose( FindDistance( *pos, xx->segs[0].u.l.pos[0] ) ) ) { + *pos = xx->segs[0].u.l.pos[0]; + return TRUE; + } else if ( IsClose( FindDistance( *pos, xx->segs[0].u.l.pos[1] ) ) ) { + *pos = xx->segs[0].u.l.pos[1]; + return TRUE; + } + } + } + ignoredTableEdge = NULL; + return FALSE; +} + + + + +static void DrawRedraw(void); +static drawContext_t drawCmdContext = { + InfoMessage, + DrawRedraw, + &mainD, + OP_LINE }; + +static void DrawRedraw( void ) +{ + MainRedraw(); +} + + +#ifdef LATER +static void DrawOk( void * context ) +{ + track_p t; + struct extraData * xx; + trkSeg_p sp; + wIndex_t cnt; + + for ( cnt=0,sp=&DrawLineSegs(0); sp < &DrawLineSegs(drawCmdContext.Segs_da.cnt); sp++ ) + if (sp->type != ' ') + cnt++; + if (cnt == 0) + return; + UndoStart( _("Create Lines"), "newDraw" ); + for ( sp=&DrawLineSegs(0); sp < &DrawLineSegs(drawCmdContext.Segs_da.cnt); sp++ ) { + if (sp->type != ' ') { + t = NewTrack( 0, T_DRAW, 0, sizeof *xx + sizeof *(trkSeg_p)0 ); + xx = GetTrkExtraData( t ); + xx->orig = zero; + xx->angle = 0.0; + xx->segCnt = 1; + memcpy( xx->segs, sp, sizeof *(trkSeg_p)0 ); + ComputeDrawBoundingBox( t ); + DrawNewTrack(t); + } + } + UndoEnd(); + DYNARR_RESET( trkSeg_t, drawCmdContext.Segs_da ); + Reset(); +} +#endif + + + +static wIndex_t benchChoice; +static wIndex_t benchOrient; +static wIndex_t dimArrowSize; +static wDrawColor lineColor; +static wDrawColor benchColor; +#ifdef LATER +static wIndex_t benchInx; +#endif + +static paramIntegerRange_t i0_100 = { 0, 100, 25 }; +static paramData_t drawPLs[] = { +#define drawWidthPD (drawPLs[0]) + { PD_LONG, &drawCmdContext.Width, "linewidth", PDO_NORECORD, &i0_100, N_("Line Width") }, +#define drawColorPD (drawPLs[1]) + { PD_COLORLIST, &lineColor, "linecolor", PDO_NORECORD, NULL, N_("Color") }, +#define drawBenchColorPD (drawPLs[2]) + { PD_COLORLIST, &benchColor, "benchcolor", PDO_NORECORD, NULL, N_("Color") }, +#define drawBenchChoicePD (drawPLs[3]) + { PD_DROPLIST, &benchChoice, "benchlist", PDO_NOPREF|PDO_NORECORD|PDO_LISTINDEX, (void*)80, N_("Lumber Type") }, +#define drawBenchOrientPD (drawPLs[4]) +#ifdef WINDOWS + { PD_DROPLIST, &benchOrient, "benchorient", PDO_NOPREF|PDO_NORECORD|PDO_LISTINDEX, (void*)45, "", 0 }, +#else + { PD_DROPLIST, &benchOrient, "benchorient", PDO_NOPREF|PDO_NORECORD|PDO_LISTINDEX, (void*)105, "", 0 }, +#endif +#define drawDimArrowSizePD (drawPLs[5]) + { PD_DROPLIST, &dimArrowSize, "arrowsize", PDO_NORECORD|PDO_LISTINDEX, (void*)80, N_("Size") } }; +static paramGroup_t drawPG = { "draw", 0, drawPLs, sizeof drawPLs/sizeof drawPLs[0] }; + +static char * objectName[] = { + N_("Straight"), + N_("Dimension"), + N_("Lumber"), + N_("Table Edge"), + N_("Curved"), + N_("Curved"), + N_("Curved"), + N_("Curved"), + N_("Circle"), + N_("Circle"), + N_("Circle"), + N_("Box"), + N_("Polyline"), + N_("Filled Circle"), + N_("Filled Circle"), + N_("Filled Circle"), + N_("Filled Box"), + N_("Polygon"), + NULL}; + +static STATUS_T CmdDraw( wAction_t action, coOrd pos ) + +{ + static BOOL_T infoSubst = FALSE; + wControl_p controls[4]; + char * labels[3]; + static char labelName[40]; + + switch (action&0xFF) { + + case C_START: + ParamLoadControls( &drawPG ); + /*drawContext = &drawCmdContext;*/ + drawWidthPD.option |= PDO_NORECORD; + drawColorPD.option |= PDO_NORECORD; + drawBenchColorPD.option |= PDO_NORECORD; + drawBenchChoicePD.option |= PDO_NORECORD; + drawBenchOrientPD.option |= PDO_NORECORD; + drawDimArrowSizePD.option |= PDO_NORECORD; + drawCmdContext.Op = (wIndex_t)(long)commandContext; + if ( drawCmdContext.Op < 0 || drawCmdContext.Op > OP_LAST ) { + NoticeMessage( "cmdDraw: Op %d", _("Ok"), NULL, drawCmdContext.Op ); + drawCmdContext.Op = OP_LINE; + } + /*DrawGeomOp( (void*)(drawCmdContext.Op>=0?drawCmdContext.Op:OP_LINE) );*/ + infoSubst = TRUE; + switch( drawCmdContext.Op ) { + case OP_LINE: + case OP_CURVE1: + case OP_CURVE2: + case OP_CURVE3: + case OP_CURVE4: + case OP_CIRCLE2: + case OP_CIRCLE3: + case OP_BOX: + case OP_POLY: + controls[0] = drawWidthPD.control; + controls[1] = drawColorPD.control; + controls[2] = NULL; + sprintf( labelName, _("%s Line Width"), _(objectName[drawCmdContext.Op]) ); + labels[0] = labelName; + labels[1] = N_("Color"); + InfoSubstituteControls( controls, labels ); + drawWidthPD.option &= ~PDO_NORECORD; + drawColorPD.option &= ~PDO_NORECORD; + break; + case OP_FILLCIRCLE2: + case OP_FILLCIRCLE3: + case OP_FILLBOX: + case OP_FILLPOLY: + controls[0] = drawColorPD.control; + controls[1] = NULL; + sprintf( labelName, _("%s Color"), _(objectName[drawCmdContext.Op]) ); + labels[0] = labelName; + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawColorPD.option &= ~PDO_NORECORD; + break; + case OP_BENCH: + controls[0] = drawBenchChoicePD.control; + controls[1] = drawBenchOrientPD.control; + controls[2] = drawBenchColorPD.control; + controls[3] = NULL; + labels[0] = N_("Lumber Type"); + labels[1] = ""; + labels[2] = N_("Color"); + if ( wListGetCount( (wList_p)drawBenchChoicePD.control ) == 0 ) + BenchLoadLists( (wList_p)drawBenchChoicePD.control, (wList_p)drawBenchOrientPD.control ); +#ifdef LATER + if ( benchInx >= 0 && benchInx < wListGetCount( (wList_p)drawBenchChoicePD.control ) ) + wListSetIndex( (wList_p)drawBenchChoicePD.control, benchInx ); +#endif + ParamLoadControls( &drawPG ); + BenchUpdateOrientationList( (long)wListGetItemContext( (wList_p)drawBenchChoicePD.control, benchChoice ), (wList_p)drawBenchOrientPD.control ); + wListSetIndex( (wList_p)drawBenchOrientPD.control, benchOrient ); + InfoSubstituteControls( controls, labels ); + drawBenchColorPD.option &= ~PDO_NORECORD; + drawBenchChoicePD.option &= ~PDO_NORECORD; + drawBenchOrientPD.option &= ~PDO_NORECORD; + break; + case OP_DIMLINE: + controls[0] = drawDimArrowSizePD.control; + controls[1] = NULL; + labels[0] = N_("Dimension Line Size"); + if ( wListGetCount( (wList_p)drawDimArrowSizePD.control ) == 0 ) { + wListAddValue( (wList_p)drawDimArrowSizePD.control, _("Tiny"), NULL, NULL ); + wListAddValue( (wList_p)drawDimArrowSizePD.control, _("Small"), NULL, NULL ); + wListAddValue( (wList_p)drawDimArrowSizePD.control, _("Medium"), NULL, NULL ); + wListAddValue( (wList_p)drawDimArrowSizePD.control, _("Large"), NULL, NULL ); + } + ParamLoadControls( &drawPG ); + InfoSubstituteControls( controls, labels ); + drawDimArrowSizePD.option &= ~PDO_NORECORD; + break; + case OP_TBLEDGE: + InfoSubstituteControls( NULL, NULL ); + InfoMessage( _("Drag to create Table Edge") ); + drawColorPD.option &= ~PDO_NORECORD; + break; + default: + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + ParamGroupRecord( &drawPG ); + DrawGeomMouse( C_START, pos, &drawCmdContext ); + + return C_CONTINUE; + + case wActionLDown: + ParamLoadData( &drawPG ); + if ( drawCmdContext.Op == OP_BENCH ) { + drawCmdContext.benchOption = GetBenchData( (long)wListGetItemContext((wList_p)drawBenchChoicePD.control, benchChoice ), benchOrient ); + drawCmdContext.Color = benchColor; +#ifdef LATER + benchInx = wListGetIndex( (wList_p)drawBenchChoicePD.control ); +#endif + } else if ( drawCmdContext.Op == OP_DIMLINE ) { + drawCmdContext.benchOption = dimArrowSize; + } else { + drawCmdContext.Color = lineColor; + } + if ( infoSubst ) { + InfoSubstituteControls( NULL, NULL ); + infoSubst = FALSE; + } + case wActionLDrag: + ParamLoadData( &drawPG ); + case wActionMove: + case wActionLUp: + case wActionRDown: + case wActionRDrag: + case wActionRUp: + case wActionText: + case C_CMDMENU: + SnapPos( &pos ); + return DrawGeomMouse( action, pos, &drawCmdContext ); + + case C_CANCEL: + InfoSubstituteControls( NULL, NULL ); + return DrawGeomMouse( action, pos, &drawCmdContext ); + + case C_OK: + return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext ); + /*DrawOk( NULL );*/ + + case C_FINISH: + return DrawGeomMouse( (0x0D<<8|wActionText), pos, &drawCmdContext ); + /*DrawOk( NULL );*/ + + case C_REDRAW: + return DrawGeomMouse( action, pos, &drawCmdContext ); + + default: + return C_CONTINUE; + } +} + +#include "bitmaps/dline.xpm" +#include "bitmaps/ddimlin.xpm" +#include "bitmaps/dbench.xpm" +#include "bitmaps/dtbledge.xpm" +#include "bitmaps/dcurve1.xpm" +#include "bitmaps/dcurve2.xpm" +#include "bitmaps/dcurve3.xpm" +#include "bitmaps/dcurve4.xpm" +/*#include "bitmaps/dcircle1.xpm"*/ +#include "bitmaps/dcircle2.xpm" +#include "bitmaps/dcircle3.xpm" +/*#include "bitmaps/dflcrcl1.xpm"*/ +#include "bitmaps/dflcrcl2.xpm" +#include "bitmaps/dflcrcl3.xpm" +#include "bitmaps/dbox.xpm" +#include "bitmaps/dfilbox.xpm" +#include "bitmaps/dpoly.xpm" +#include "bitmaps/dfilpoly.xpm" + +typedef struct { + char **xpm; + int OP; + char * shortName; + char * cmdName; + char * helpKey; + long acclKey; + } drawData_t; + +static drawData_t dlineCmds[] = { + { dline_xpm, OP_LINE, N_("Line"), N_("Draw Line"), "cmdDrawLine", ACCL_DRAWLINE }, + { ddimlin_xpm, OP_DIMLINE, N_("Dimension Line"), N_("Draw Dimension Line"), "cmdDrawDimLine", ACCL_DRAWDIMLINE }, + { dbench_xpm, OP_BENCH, N_("Benchwork"), N_("Draw Benchwork"), "cmdDrawBench", ACCL_DRAWBENCH }, + { dtbledge_xpm, OP_TBLEDGE, N_("Table Edge"), N_("Draw Table Edge"), "cmdDrawTableEdge", ACCL_DRAWTBLEDGE } }; +static drawData_t dcurveCmds[] = { + { dcurve1_xpm, OP_CURVE1, N_("Curve End"), N_("Draw Curve from End"), "cmdDrawCurveEndPt", ACCL_DRAWCURVE1 }, + { dcurve2_xpm, OP_CURVE2, N_("Curve Tangent"), N_("Draw Curve from Tangent"), "cmdDrawCurveTangent", ACCL_DRAWCURVE2 }, + { dcurve3_xpm, OP_CURVE3, N_("Curve Center"), N_("Draw Curve from Center"), "cmdDrawCurveCenter", ACCL_DRAWCURVE3 }, + { dcurve4_xpm, OP_CURVE4, N_("Curve Chord"), N_("Draw Curve from Chord"), "cmdDrawCurveChord", ACCL_DRAWCURVE4 } }; +static drawData_t dcircleCmds[] = { + /*{ dcircle1_xpm, OP_CIRCLE1, "Circle Fixed Radius", "Draw Fixed Radius Circle", "cmdDrawCircleFixedRadius", ACCL_DRAWCIRCLE1 },*/ + { dcircle2_xpm, OP_CIRCLE3, N_("Circle Tangent"), N_("Draw Circle from Tangent"), "cmdDrawCircleTangent", ACCL_DRAWCIRCLE2 }, + { dcircle3_xpm, OP_CIRCLE2, N_("Circle Center"), N_("Draw Circle from Center"), "cmdDrawCircleCenter", ACCL_DRAWCIRCLE3 }, + /*{ dflcrcl1_xpm, OP_FILLCIRCLE1, "Circle Filled Fixed Radius", "Draw Fixed Radius Filled Circle", "cmdDrawFilledCircleFixedRadius", ACCL_DRAWFILLCIRCLE1 },*/ + { dflcrcl2_xpm, OP_FILLCIRCLE3, N_("Circle Filled Tangent"), N_("Draw Filled Circle from Tangent"), "cmdDrawFilledCircleTangent", ACCL_DRAWFILLCIRCLE2 }, + { dflcrcl3_xpm, OP_FILLCIRCLE2, N_("Circle Filled Center"), N_("Draw Filled Circle from Center"), "cmdDrawFilledCircleCenter", ACCL_DRAWFILLCIRCLE3 } }; +static drawData_t dshapeCmds[] = { + { dbox_xpm, OP_BOX, N_("Box"), N_("Draw Box"), "cmdDrawBox", ACCL_DRAWBOX }, + { dfilbox_xpm, OP_FILLBOX, N_("Filled Box"), N_("Draw Filled Box"), "cmdDrawFilledBox", ACCL_DRAWFILLBOX }, + { dpoly_xpm, OP_POLY, N_("Poly Line"), N_("Draw Polyline"), "cmdDrawPolyline", ACCL_DRAWPOLYLINE }, + { dfilpoly_xpm, OP_FILLPOLY, N_("Polygon"), N_("Draw Polygon"), "cmdDrawPolygon", ACCL_DRAWPOLYGON } }; + +typedef struct { + char * helpKey; + char * menuTitle; + char * stickyLabel; + int cnt; + drawData_t * data; + long acclKey; + wIndex_t cmdInx; + int curr; + } drawStuff_t; +static drawStuff_t drawStuff[4]; + + +static drawStuff_t drawStuff[4] = { + { "cmdDrawLineSetCmd", N_("Straight Objects"), N_("Draw Straight Objects"), 4, dlineCmds }, + { "cmdDrawCurveSetCmd", N_("Curved Lines"), N_("Draw Curved Lines"), 4, dcurveCmds }, + { "cmdDrawCircleSetCmd", N_("Circle Lines"), N_("Draw Circles"), 4, dcircleCmds }, + { "cmdDrawShapeSetCmd", N_("Shapes"), N_("Draw Shapes"), 4, dshapeCmds} }; + + +#ifdef LATER +static void SetDrawMode( char * modeName ) +{ + wButton_p bb; + int inx1, inx2; + drawData_t * dp; + + for ( inx1=0; inx1<4; inx1++ ) { + for ( inx2=0; inx2<drawStuff[inx1].cnt; inx2++ ) { + dp = &drawStuff[inx1].data[inx2]; + if (strncmp( modeName, dp->modeS, strlen(dp->modeS) ) == 0 ) { + bb = GetCommandButton(drawStuff[inx1].cmdInx); + wButtonSetLabel( bb, (char*)(dp->icon) ); + wControlSetHelp( (wControl_p)bb, dp->help ); + drawStuff[inx1].curr = inx2; + DoCommandB( (void*)(drawStuff[inx1].cmdInx) ); + return; + } + } + } +} +#endif + + +static void ChangeDraw( long changes ) +{ + wIndex_t choice, orient; + if ( changes & CHANGE_UNITS ) { + if ( drawBenchChoicePD.control && drawBenchOrientPD.control ) { + choice = wListGetIndex( (wList_p)drawBenchChoicePD.control ); + orient = wListGetIndex( (wList_p)drawBenchOrientPD.control ); + BenchLoadLists( (wList_p)drawBenchChoicePD.control, (wList_p)drawBenchOrientPD.control ); + wListSetIndex( (wList_p)drawBenchChoicePD.control, choice ); + wListSetIndex( (wList_p)drawBenchOrientPD.control, orient ); + } + } +} + + + +static void DrawDlgUpdate( + paramGroup_p pg, + int inx, + void * valueP ) +{ + if ( inx >= 0 && pg->paramPtr[inx].valueP == &benchChoice ) + BenchUpdateOrientationList( (long)wListGetItemContext( (wList_p)drawBenchChoicePD.control, (wIndex_t)*(long*)valueP ), (wList_p)drawBenchOrientPD.control ); +} + +EXPORT void InitCmdDraw( wMenu_p menu ) +{ + int inx1, inx2; + drawStuff_t * dsp; + drawData_t * ddp; + wIcon_p icon; + + drawCmdContext.Color = wDrawColorBlack; + lineColor = wDrawColorBlack; + benchColor = wDrawFindColor( wRGB(255,192,0) ); + ParamCreateControls( &drawPG, DrawDlgUpdate ); + + for ( inx1=0; inx1<4; inx1++ ) { + dsp = &drawStuff[inx1]; + ButtonGroupBegin( _(dsp->menuTitle), dsp->helpKey, _(dsp->stickyLabel) ); + for ( inx2=0; inx2<dsp->cnt; inx2++ ) { + ddp = &dsp->data[inx2]; + icon = wIconCreatePixMap( ddp->xpm ); + AddMenuButton( menu, CmdDraw, ddp->helpKey, _(ddp->cmdName), icon, LEVEL0_50, IC_STICKY|IC_POPUP2, ddp->acclKey, (void *)(intptr_t)ddp->OP ); + } + ButtonGroupEnd(); + } + + ParamRegister( &drawPG ); + RegisterChangeNotification( ChangeDraw ); +#ifdef LATER + InitCommand( cmdDraw, N_("Draw"), draw_bits, LEVEL0_50, IC_POPUP|IC_CMDMENU, ACCL_DRAW ); +#endif +} + + +BOOL_T ReadTableEdge( char * line ) +{ + track_p trk; + TRKINX_T index; + DIST_T elev0, elev1; + trkSeg_t seg; + wIndex_t layer; + + if ( !GetArgs( line, paramVersion<3?"dXpYpY":paramVersion<9?"dL000pYpY":"dL000pfpf", + &index, &layer, &seg.u.l.pos[0], &elev0, &seg.u.l.pos[1], &elev1 ) ) + return FALSE; + seg.type = SEG_TBLEDGE; + seg.color = wDrawColorBlack; + seg.width = 0; + trk = MakeDrawFromSeg1( index, zero, 0.0, &seg ); + SetTrkLayer(trk, layer); + return TRUE; +} + +/** + * Create a new segment for text. The data are stored in a trk structure. + * Storage for the string is dynamically allocated. + * + * \param index IN of new element + * \param pos IN coordinates of element + * \param angle IN orientation + * \param text IN text itself + * \param textSize IN font size in pts + * \param color IN text color + * \return the newly allocated trk structure + */ + +EXPORT track_p NewText( + wIndex_t index, + coOrd pos, + ANGLE_T angle, + char * text, + CSIZE_T textSize, + wDrawColor color ) +{ + trkSeg_t tempSeg; + track_p trk; + tempSeg.type = SEG_TEXT; + tempSeg.color = color; + tempSeg.width = 0; + tempSeg.u.t.pos = zero; + tempSeg.u.t.angle = angle; + tempSeg.u.t.fontP = NULL; + tempSeg.u.t.fontSize = textSize; + tempSeg.u.t.string = MyStrdup( text ); + trk = MakeDrawFromSeg1( index, pos, angle, &tempSeg ); + return trk; +} + + +EXPORT BOOL_T ReadText( char * line ) +{ + coOrd pos; + CSIZE_T textSize; + char * text; + wIndex_t index; + wIndex_t layer; + track_p trk; + ANGLE_T angle; + wDrawColor color = wDrawColorBlack; + if ( paramVersion<3 ) { + if (!GetArgs( line, "XXpYql", &index, &layer, &pos, &angle, &text, &textSize )) + return FALSE; + } else if (paramVersion<9 ) { + if (!GetArgs(line, "dL000pYql", &index, &layer, &pos, &angle, &text, &textSize)) + return FALSE; + } else { + if (!GetArgs(line, "dLl00pfql", &index, &layer, &color, &pos, &angle, &text, &textSize )) + return FALSE; + } + + trk = NewText( index, pos, angle, text, textSize, color ); + SetTrkLayer( trk, layer ); + MyFree(text); + return TRUE; +} + + +EXPORT void InitTrkDraw( void ) +{ + T_DRAW = InitObject( &drawCmds ); + AddParam( "TABLEEDGE", ReadTableEdge ); + AddParam( "TEXT", ReadText ); +} |