00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "a2dprec.h"
00012
00013 #ifdef __BORLANDC__
00014 #pragma hdrstop
00015 #endif
00016
00017 #ifndef WX_PRECOMP
00018 #include "wx/wx.h"
00019 #endif
00020
00021 #include "wx/canvas/vpath.h"
00022 #include "wx/canvas/candoc.h"
00023 #include "wx/canvas/drawer.h"
00024
00025 IMPLEMENT_DYNAMIC_CLASS(a2dVectorPath, a2dCanvasObject)
00026
00027
00028
00029
00030 a2dVectorPath::a2dVectorPath()
00031 : a2dCanvasObject()
00032 {
00033 m_contourwidth = 0;
00034 m_datatype = 0;
00035 m_pathtype = a2dPATH_END_SQAURE;
00036 m_segments = new a2dVpath();
00037 }
00038
00039 a2dVectorPath::a2dVectorPath( a2dVpath* path )
00040 : a2dCanvasObject()
00041 {
00042 m_contourwidth = 0;
00043 m_datatype = 0;
00044 m_pathtype = a2dPATH_END_SQAURE;
00045 m_segments = path;
00046 }
00047
00048 a2dVectorPath::~a2dVectorPath()
00049 {
00050 delete m_segments;
00051 }
00052
00053 a2dVectorPath::a2dVectorPath( const a2dVectorPath &other, CloneOptions options )
00054 :a2dCanvasObject( other, options )
00055 {
00056 m_segments = new a2dVpath();
00057 *m_segments = *other.m_segments;
00058 m_contourwidth = other.m_contourwidth;
00059 m_datatype = other.m_datatype;
00060 m_pathtype = other.m_pathtype;
00061 }
00062
00063 a2dObject* a2dVectorPath::Clone( CloneOptions options ) const
00064 {
00065 return new a2dVectorPath( *this, options );
00066 };
00067
00068 a2dCanvasObjectList* a2dVectorPath::GetAsCanvasVpaths( bool transform )
00069 {
00070 a2dAffineMatrix pworld;
00071 if ( transform )
00072 pworld = m_lworld;
00073
00074 a2dCanvasObjectList* canpathlist = new a2dCanvasObjectList();
00075 a2dVectorPath* copy = wxStaticCast( this->Clone( clone_deep ), a2dVectorPath );
00076 copy->m_segments->Transform( pworld );
00077
00078 canpathlist->push_back( copy );
00079
00080 return canpathlist;
00081 }
00082
00083 bool a2dVectorPath::RestrictToObject( a2dRestrictionEngine* engine, a2dSnapToWhatMask snapToWhat )
00084 {
00085 bool res = false;
00086 if ( m_segments && snapToWhat & a2dRestrictionEngine::snapToObjectVertexes )
00087 {
00088 unsigned int i;
00089 for (i = 0; i < m_segments->GetCount(); i++)
00090 {
00091 a2dVpathSegment& seg = m_segments->Item(i);
00092 switch ( seg.GetType() )
00093 {
00094 case a2dPATHSEG_MOVETO:
00095 case a2dPATHSEG_LINETO:
00096 case a2dPATHSEG_LINETO_NOSTROKE:
00097 case a2dPATHSEG_CBCURVETO_NOSTROKE:
00098 case a2dPATHSEG_CBCURVETO:
00099 case a2dPATHSEG_QBCURVETO_NOSTROKE:
00100 case a2dPATHSEG_QBCURVETO:
00101 case a2dPATHSEG_ARCTO_NOSTROKE:
00102 case a2dPATHSEG_ARCTO:
00103 {
00104
00105 res |= engine->SetPointSnapResultIfCloser( a2dPoint2D( seg.m_x1, seg.m_y1 ) );
00106 }
00107 break;
00108 }
00109 }
00110 }
00111 return res;
00112 }
00113
00114 a2dCanvasObjectList* a2dVectorPath::GetAsPolygons()
00115 {
00116 a2dCanvasObjectList* ret = new a2dCanvasObjectList();
00117
00118 double tstep = 1/ (double) SPLINE_STEP;
00119 unsigned int i;
00120 double x,y,xm,ym;
00121 bool move = false;
00122 int count = 0;
00123 bool nostrokeparts = false;
00124
00125 if ( m_lworld.IsTranslate() && m_segments->IsPolygon( true ) )
00126 {
00127 a2dVertexListPtr lpoints = new a2dVertexList();
00128
00129 for (i = 0; i < m_segments->GetCount(); i++)
00130 {
00131 a2dVpathSegment& seg = Item(i);
00132 switch ( seg.GetType() )
00133 {
00134 case a2dPATHSEG_MOVETO:
00135 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00136 lpoints->push_back( new a2dLineSegment( x, y ) );
00137 break;
00138 case a2dPATHSEG_LINETO:
00139 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00140 lpoints->push_back( new a2dLineSegment( x, y ) );
00141 break;
00142 case a2dPATHSEG_ARCTO:
00143 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00144 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00145 m_lworld.TransformPoint( cseg.m_x2, cseg.m_y2, xm, ym );
00146 lpoints->push_back( new a2dArcSegment( x, y, xm, ym ) );
00147 break;
00148 }
00149 if ( seg.GetClose() == a2dPATHSEG_END_CLOSED )
00150 {
00151 lpoints->push_back( new a2dLineSegment( Item(0).m_x1, Item(0).m_y1 ) );
00152 }
00153 }
00154
00155 a2dPolygonL* poly = new a2dPolygonL( lpoints );
00156 poly->SetContourWidth( m_contourwidth );
00157 ret->push_back( poly );
00158 return ret;
00159 }
00160
00161 if ( m_lworld.IsTranslate() && m_segments->IsPolyline( true ) )
00162 {
00163 a2dVertexListPtr lpoints = new a2dVertexList();
00164
00165 for (i = 0; i < m_segments->GetCount(); i++)
00166 {
00167 a2dVpathSegment& seg = Item(i);
00168 switch ( seg.GetType() )
00169 {
00170 case a2dPATHSEG_MOVETO:
00171 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00172 lpoints->push_back( new a2dLineSegment( x, y ) );
00173 break;
00174 case a2dPATHSEG_LINETO:
00175 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00176 lpoints->push_back( new a2dLineSegment( x, y ) );
00177 break;
00178 case a2dPATHSEG_ARCTO:
00179 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00180 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00181 m_lworld.TransformPoint( cseg.m_x2, cseg.m_y2, xm, ym );
00182 lpoints->push_back( new a2dArcSegment( x, y, xm, ym ) );
00183 break;
00184 }
00185 if ( seg.GetClose() == a2dPATHSEG_END_CLOSED )
00186 {
00187 lpoints->push_back( new a2dLineSegment( Item(0).m_x1, Item(0).m_y1 ) );
00188 }
00189 }
00190
00191 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00192 polyl->SetContourWidth( m_contourwidth );
00193 polyl->SetPathType( m_pathtype );
00194 ret->push_back( new a2dPolylineL( lpoints ) );
00195 return ret;
00196 }
00197
00198 a2dVertexListPtr lpoints = new a2dVertexList();
00199
00200 for (i = 0; i < m_segments->GetCount(); i++)
00201 {
00202 a2dVpathSegment& seg = m_segments->Item(i);
00203 switch ( seg.GetType() )
00204 {
00205 case a2dPATHSEG_MOVETO:
00206 if ( count == 0 )
00207 {
00208 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00209 lpoints->push_back( new a2dLineSegment( x, y ) );
00210 count++;
00211 }
00212 else
00213 {
00214 i--;
00215 move = true;
00216 }
00217 break;
00218
00219 case a2dPATHSEG_LINETO:
00220 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00221 lpoints->push_back( new a2dLineSegment( x, y ) );
00222 count++;
00223 break;
00224 case a2dPATHSEG_LINETO_NOSTROKE:
00225 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00226 lpoints->push_back( new a2dLineSegment( x, y ) );
00227 count++;
00228 nostrokeparts = true;
00229 break;
00230
00231 case a2dPATHSEG_CBCURVETO_NOSTROKE:
00232 nostrokeparts = true;
00233 case a2dPATHSEG_CBCURVETO:
00234 {
00235 double xw, yw;
00236
00237 double xwl = m_segments->Item(i? i-1: 0).m_x1;
00238 double ywl = m_segments->Item(i? i-1: 0).m_y1;
00239 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
00240
00241 int step;
00242 double t = 0;
00243 for ( step=0; step <= SPLINE_STEP; step++ )
00244 {
00245 xw = xwl*pow(1-t,3) + cseg.m_x2*pow(1-t,2)*t*3 + cseg.m_x3*(1-t)*t*t*3 + cseg.m_x1*pow(t,3);
00246 yw = ywl*pow(1-t,3) + cseg.m_y2*pow(1-t,2)*t*3 + cseg.m_y3*(1-t)*t*t*3 + cseg.m_y1*pow(t,3);
00247 m_lworld.TransformPoint( xw, yw, x, y );
00248 lpoints->push_back( new a2dLineSegment( x, y ) );
00249 count++;
00250 t= t + tstep;
00251 }
00252 }
00253 break;
00254
00255 case a2dPATHSEG_QBCURVETO_NOSTROKE:
00256 nostrokeparts = true;
00257 case a2dPATHSEG_QBCURVETO:
00258 {
00259 double xw, yw;
00260
00261 double xwl = m_segments->Item(i? i-1: 0).m_x1;
00262 double ywl = m_segments->Item(i? i-1: 0).m_y1;
00263 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
00264
00265 int step;
00266 double t = 0;
00267 for ( step=0; step <= SPLINE_STEP; step++ )
00268 {
00269 xw = xwl*pow(1-t,2) + cseg.m_x2*(1-t)*t*2 + cseg.m_x1*pow(t,2);
00270 yw = ywl*pow(1-t,2) + cseg.m_y2*(1-t)*t*2 + cseg.m_y1*pow(t,2);
00271 m_lworld.TransformPoint( xw, yw, x, y );
00272 lpoints->push_back( new a2dLineSegment( x, y ) );
00273 count++;
00274 t= t + tstep;
00275 }
00276 }
00277 break;
00278
00279 case a2dPATHSEG_ARCTO_NOSTROKE:
00280 nostrokeparts = true;
00281 case a2dPATHSEG_ARCTO:
00282 {
00283 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00284
00285 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
00286
00287 if ( cseg.CalcR( m_segments->Item(i? i-1: 0), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
00288 {
00289 double dphi;
00290 unsigned int segments;
00291 a2dGlobals->Aberration( phit, radius , dphi, segments );
00292
00293 double theta = beginrad;
00294 unsigned int step;
00295
00296 double x,y;
00297 for (step = 0; step < segments+1; step++)
00298 {
00299 m_lworld.TransformPoint( center_x + radius * cos (theta), center_y + radius * sin (theta), x, y );
00300 lpoints->push_back( new a2dLineSegment( x, y ) );
00301 count++;
00302 theta = theta + dphi;
00303 }
00304 }
00305 else
00306 {
00307 double x,y;
00308 m_lworld.TransformPoint( cseg.m_x1, cseg.m_y1, x, y );
00309 lpoints->push_back( new a2dLineSegment( x, y ) );
00310 count++;
00311 }
00312 }
00313 break;
00314 }
00315
00316 if ( move )
00317 {
00318 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00319 polyl->SetContourWidth( m_contourwidth );
00320 polyl->SetPathType( m_pathtype );
00321 ret->push_back( polyl );
00322 move = false;
00323 lpoints = new a2dVertexList;
00324 count = 0;
00325 }
00326 else if ( seg.GetClose() != a2dPATHSEG_END_OPEN )
00327 {
00328 if (nostrokeparts || seg.GetClose() == a2dPATHSEG_END_CLOSED_NOSTROKE )
00329 {
00330 a2dPolygonL* poly = new a2dPolygonL( lpoints );
00331 poly->SetContourWidth( m_contourwidth );
00332 ret->push_back( poly );
00333 nostrokeparts = true;
00334 }
00335 else
00336 {
00337 a2dPolygonL* poly = new a2dPolygonL( lpoints );
00338 poly->SetContourWidth( m_contourwidth );
00339 ret->push_back( poly );
00340 }
00341
00342 move = false;
00343 lpoints = new a2dVertexList;
00344 count = 0;
00345 }
00346 else if ( i == m_segments->GetCount()-1 )
00347 {
00348 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00349 polyl->SetContourWidth( m_contourwidth );
00350 polyl->SetPathType( m_pathtype );
00351 ret->push_back( polyl );
00352 }
00353 }
00354
00355 if (nostrokeparts)
00356 {
00357 move = false;
00358 count = 0;
00359 a2dVertexList* lpoints = new a2dVertexList();
00360
00361 nostrokeparts = false;
00362
00363 double lastmovex = 0;
00364 double lastmovey = 0;
00365
00366 for (i = 0; i < m_segments->GetCount(); i++)
00367 {
00368 a2dVpathSegment& seg = m_segments->Item(i);
00369 switch ( seg.GetType() )
00370 {
00371 case a2dPATHSEG_MOVETO:
00372 if ( count == 0 )
00373 {
00374 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00375 lpoints->push_back( new a2dLineSegment( x, y ) );
00376 lastmovex = x;
00377 lastmovey = y;
00378 count++;
00379 }
00380 else
00381 {
00382 i--;
00383 move = true;
00384 }
00385 break;
00386
00387 case a2dPATHSEG_LINETO:
00388 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00389 lpoints->push_back( new a2dLineSegment( x, y ) );
00390 count++;
00391 break;
00392
00393 case a2dPATHSEG_LINETO_NOSTROKE:
00394 case a2dPATHSEG_CBCURVETO_NOSTROKE:
00395 case a2dPATHSEG_QBCURVETO_NOSTROKE:
00396 case a2dPATHSEG_ARCTO_NOSTROKE:
00397 if ( count == 0 )
00398 {
00399 m_lworld.TransformPoint( seg.m_x1, seg.m_y1, x, y );
00400 lpoints->push_back( new a2dLineSegment( x, y ) );
00401 count++;
00402 }
00403 else
00404 {
00405 i--;
00406 nostrokeparts = true;
00407 }
00408 break;
00409
00410 case a2dPATHSEG_CBCURVETO:
00411 {
00412 double xw, yw;
00413
00414 double xwl = m_segments->Item(i? i-1: 0).m_x1;
00415 double ywl = m_segments->Item(i? i-1: 0).m_y1;
00416 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
00417
00418 int step;
00419 double t = 0;
00420 for ( step=0; step <= SPLINE_STEP; step++ )
00421 {
00422 xw = xwl*pow(1-t,3) + cseg.m_x2*pow(1-t,2)*t*3 + cseg.m_x3*(1-t)*t*t*3 + cseg.m_x1*pow(t,3);
00423 yw = ywl*pow(1-t,3) + cseg.m_y2*pow(1-t,2)*t*3 + cseg.m_y3*(1-t)*t*t*3 + cseg.m_y1*pow(t,3);
00424 m_lworld.TransformPoint( xw, yw, x, y );
00425 lpoints->push_back( new a2dLineSegment( x, y ) );
00426 count++;
00427 t= t + tstep;
00428 }
00429 }
00430 break;
00431
00432 case a2dPATHSEG_QBCURVETO:
00433 {
00434 double xw, yw;
00435
00436 double xwl = m_segments->Item(i? i-1: 0).m_x1;
00437 double ywl = m_segments->Item(i? i-1: 0).m_y1;
00438 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
00439
00440 int step;
00441 double t = 0;
00442 for ( step=0; step <= SPLINE_STEP; step++ )
00443 {
00444 xw = xwl*pow(1-t,2) + cseg.m_x2*(1-t)*t*2 + cseg.m_x1*pow(t,2);
00445 yw = ywl*pow(1-t,2) + cseg.m_y2*(1-t)*t*2 + cseg.m_y1*pow(t,2);
00446 m_lworld.TransformPoint( xw, yw, x, y );
00447 lpoints->push_back( new a2dLineSegment( x, y ) );
00448 count++;
00449 t= t + tstep;
00450 }
00451 }
00452 break;
00453
00454 case a2dPATHSEG_ARCTO:
00455 {
00456 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00457
00458 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
00459
00460 if ( cseg.CalcR( m_segments->Item(i? i-1: 0), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
00461 {
00462 double dphi;
00463 unsigned int segments;
00464 a2dGlobals->Aberration( phit, radius , dphi, segments );
00465
00466 double theta = beginrad;
00467 unsigned int step;
00468
00469 double x,y;
00470 for (step = 0; step < segments+1; step++)
00471 {
00472 m_lworld.TransformPoint( center_x + radius * cos (theta), center_y + radius * sin (theta), x, y );
00473 lpoints->push_back( new a2dLineSegment( x, y ) );
00474 count++;
00475 theta = theta + dphi;
00476 }
00477 }
00478 else
00479 {
00480 double x,y;
00481 m_lworld.TransformPoint( cseg.m_x1, cseg.m_y1, x, y );
00482 lpoints->push_back( new a2dLineSegment( x, y ) );
00483 count++;
00484 }
00485 }
00486 break;
00487 }
00488
00489 if ( move || nostrokeparts )
00490 {
00491 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00492 polyl->SetContourWidth( m_contourwidth );
00493 polyl->SetPathType( m_pathtype );
00494 ret->push_back( polyl );
00495 move = false;
00496 nostrokeparts = false;
00497 lpoints = new a2dVertexList();
00498 count = 0;
00499 }
00500 else if ( seg.GetClose() != a2dPATHSEG_END_OPEN )
00501 {
00502 if ( seg.GetClose() == a2dPATHSEG_END_CLOSED )
00503 {
00504 lpoints->push_back( new a2dLineSegment( lastmovex, lastmovey ) );
00505 count++;
00506 }
00507 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00508 polyl->SetContourWidth( m_contourwidth );
00509 polyl->SetPathType( m_pathtype );
00510 ret->push_back( polyl );
00511 nostrokeparts = false;
00512 move = false;
00513 lpoints = new a2dVertexList;
00514 count = 0;
00515 }
00516 else if ( i == m_segments->GetCount() )
00517 {
00518 a2dPolylineL* polyl = new a2dPolylineL( lpoints );
00519 polyl->SetContourWidth( m_contourwidth );
00520 polyl->SetPathType( m_pathtype );
00521 ret->push_back( polyl );
00522 }
00523 }
00524 }
00525 return ret;
00526 }
00527
00528 void a2dVectorPath::ConvertToLines()
00529 {
00530 m_segments->ConvertToLines();
00531 }
00532
00533 bool a2dVectorPath::EliminateMatrix()
00534 {
00535 if (!m_lworld.IsIdentity())
00536 {
00537 m_segments->ConvertToLines();
00538 unsigned int i;
00539 for (i=0; i < m_segments->GetCount() ;i++)
00540 {
00541 m_lworld.TransformPoint(m_segments->Item(i).m_x1, m_segments->Item(i).m_y1,
00542 m_segments->Item(i).m_x1, m_segments->Item(i).m_y1 );
00543 }
00544
00545 }
00546 return a2dCanvasObject::EliminateMatrix();
00547 }
00548
00549 a2dBoundingBox a2dVectorPath::DoGetUnTransformedBbox( a2dBboxFlags WXUNUSED(flags) ) const
00550 {
00551 a2dBoundingBox bbox;
00552 unsigned int i;
00553 for (i=0; i < m_segments->GetCount();i++)
00554 {
00555 a2dVpathSegment& seg = m_segments->Item(i);
00556 switch ( seg.GetType() )
00557 {
00558 case a2dPATHSEG_CBCURVETO:
00559 case a2dPATHSEG_CBCURVETO_NOSTROKE:
00560 {
00561 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
00562 bbox.Expand( cseg.m_x2, cseg.m_y2);
00563 bbox.Expand( cseg.m_x3, cseg.m_y3);
00564 }
00565 break;
00566
00567 case a2dPATHSEG_QBCURVETO:
00568 case a2dPATHSEG_QBCURVETO_NOSTROKE:
00569 {
00570 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
00571 bbox.Expand( cseg.m_x2, cseg.m_y2);
00572 }
00573 break;
00574
00575 case a2dPATHSEG_ARCTO:
00576 case a2dPATHSEG_ARCTO_NOSTROKE:
00577 {
00578 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00579
00580 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
00581
00582
00583 if ( cseg.CalcR( m_segments->Item(i? i-1: 0), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
00584 {
00585 bbox.Expand( center_x + radius , center_y + radius );
00586 bbox.Expand( center_x + radius , center_y - radius );
00587 bbox.Expand( center_x - radius , center_y + radius );
00588 bbox.Expand( center_x - radius , center_y - radius );
00589 }
00590
00591 bbox.Expand( cseg.m_x1, cseg.m_y1);
00592 bbox.Expand( cseg.m_x2, cseg.m_y2);
00593 }
00594 break;
00595 default:
00596 break;
00597 }
00598 bbox.Expand( m_segments->Item(i).m_x1,m_segments->Item(i).m_y1);
00599 }
00600 bbox.Enlarge( m_contourwidth );
00601 return bbox;
00602 }
00603
00604 bool a2dVectorPath::DoUpdate( UpdateMode mode, const a2dBoundingBox& childbox, const a2dBoundingBox& clipbox, const a2dBoundingBox& propbox )
00605 {
00606
00607 if ( !m_bbox.GetValid() )
00608 {
00609 m_bbox=DoGetUnTransformedBbox();
00610 m_bbox.MapBbox(m_lworld);
00611 return true;
00612 }
00613 return false;
00614
00615 }
00616
00617 void a2dVectorPath::DoRender( a2dIterC& ic, OVERLAP WXUNUSED(clipparent) )
00618 {
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 if ( m_contourwidth )
00631 {
00632 a2dVpath* segments = new a2dVpath();
00633 *segments = *m_segments;
00634 segments->Contour( m_contourwidth/2, m_pathtype );
00635 ic.GetDrawer2D()->DrawVpath( segments );
00636 delete segments;
00637 }
00638 else
00639 ic.GetDrawer2D()->DrawVpath( m_segments );
00640 }
00641
00642 #if wxART2D_USE_CVGIO
00643
00644 void a2dVectorPath::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
00645 {
00646 a2dCanvasObject::DoSave( parent, out, xmlparts, towrite );
00647 if ( xmlparts == a2dXmlSer_attrib )
00648 {
00649 out.WriteAttribute( wxT("segments"), m_segments->GetCount() );
00650 }
00651 else
00652 {
00653
00654 unsigned int i;
00655 for (i=0; i < m_segments->GetCount();i++)
00656 {
00657 if (i%2==0)
00658 out.WriteNewLine();
00659 a2dVpathSegment& seg = m_segments->Item(i);
00660
00661 out.WriteStartElementAttributes( wxT("seg") );
00662 switch ( seg.m_type )
00663 {
00664 case a2dPATHSEG_MOVETO:
00665 {
00666 out.WriteAttribute( wxT("type"), wxT("moveto") );
00667 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00668 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00669 break;
00670 }
00671 case a2dPATHSEG_LINETO:
00672 {
00673 out.WriteAttribute( wxT("type"), wxT("lineto") );
00674 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00675 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00676 break;
00677 }
00678 case a2dPATHSEG_LINETO_NOSTROKE:
00679 {
00680 out.WriteAttribute( wxT("type"), wxT("lineto_nostroke") );
00681 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00682 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00683 break;
00684 }
00685
00686 case a2dPATHSEG_CBCURVETO:
00687 {
00688 out.WriteAttribute( wxT("type"), wxT("cb_curveto") );
00689 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00690 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00691 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
00692 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00693 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00694 out.WriteAttribute( wxT("x3"), cseg.m_x3 );
00695 out.WriteAttribute( wxT("y3"), cseg.m_y3 );
00696 break;
00697 }
00698 case a2dPATHSEG_CBCURVETO_NOSTROKE:
00699 {
00700 out.WriteAttribute( wxT("type"), wxT("cb_curveto_nostroke") );
00701 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00702 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00703 a2dVpathCBCurveSegment& cseg = (a2dVpathCBCurveSegment&) seg;
00704 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00705 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00706 out.WriteAttribute( wxT("x3"), cseg.m_x3 );
00707 out.WriteAttribute( wxT("y3"), cseg.m_y3 );
00708 break;
00709 }
00710
00711 case a2dPATHSEG_QBCURVETO:
00712 {
00713 out.WriteAttribute( wxT("type"), wxT("qb_curveto") );
00714 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00715 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00716 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
00717 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00718 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00719 break;
00720 }
00721 case a2dPATHSEG_QBCURVETO_NOSTROKE:
00722 {
00723 out.WriteAttribute( wxT("type"), wxT("qb_curveto_nostroke") );
00724 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00725 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00726 a2dVpathQBCurveSegment& cseg = (a2dVpathQBCurveSegment&) seg;
00727 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00728 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00729 break;
00730 }
00731
00732 case a2dPATHSEG_ARCTO:
00733 {
00734 out.WriteAttribute( wxT("type"), wxT("arcto") );
00735 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00736 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00737 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00738 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00739 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00740 break;
00741 }
00742 case a2dPATHSEG_ARCTO_NOSTROKE:
00743 {
00744 out.WriteAttribute( wxT("type"), wxT("arcto_nostroke") );
00745 out.WriteAttribute( wxT("x1"), seg.m_x1 );
00746 out.WriteAttribute( wxT("y1"), seg.m_y1 );
00747 a2dVpathArcSegment& cseg = (a2dVpathArcSegment&) seg;
00748 out.WriteAttribute( wxT("x2"), cseg.m_x2 );
00749 out.WriteAttribute( wxT("y2"), cseg.m_y2 );
00750 break;
00751 }
00752 default:
00753 break;
00754 }
00755
00756 switch ( seg.m_close )
00757 {
00758 case a2dPATHSEG_END_OPEN:
00759 {
00760 out.WriteAttribute( wxT("end"), wxT("open") );
00761 break;
00762 }
00763 case a2dPATHSEG_END_CLOSED:
00764 {
00765 out.WriteAttribute( wxT("end"), wxT("closed") );
00766 break;
00767 }
00768 case a2dPATHSEG_END_CLOSED_NOSTROKE:
00769 {
00770 out.WriteAttribute( wxT("end"), wxT("closed_nostroke") );
00771 break;
00772 }
00773 }
00774 out.WriteEndAttributes( true );
00775 }
00776 }
00777 }
00778
00779 void a2dVectorPath::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
00780 {
00781 a2dCanvasObject::DoLoad( parent, parser, xmlparts );
00782 if ( xmlparts == a2dXmlSer_attrib )
00783 {
00784 }
00785 else
00786 {
00787 while( parser.GetTagName() == wxT("seg") )
00788 {
00789
00790 a2dVpathSegment* seg = NULL;
00791
00792 wxString s1,s2;
00793 double x1 = parser.GetAttributeValueDouble( wxT("x1") );
00794 double y1 = parser.GetAttributeValueDouble( wxT("y1") );
00795 double x2 = parser.GetAttributeValueDouble( wxT("x2") );
00796 double y2 = parser.GetAttributeValueDouble( wxT("y2") );
00797 double x3 = parser.GetAttributeValueDouble( wxT("x3") );
00798 double y3 = parser.GetAttributeValueDouble( wxT("y3") );
00799
00800 a2dPATHSEG_END end = a2dPATHSEG_END_OPEN;
00801 wxString send = parser.GetAttributeValue( wxT("end") );
00802 if ( send == wxT("open") )
00803 end = a2dPATHSEG_END_OPEN;
00804 else if ( send == wxT("closed") )
00805 end = a2dPATHSEG_END_CLOSED;
00806 else if ( send == wxT("closed_nostroke") )
00807 end = a2dPATHSEG_END_CLOSED_NOSTROKE;
00808
00809 wxString type = parser.GetAttributeValue( wxT("type") );
00810
00811 if ( type == wxT("moveto") )
00812 {
00813 seg = new a2dVpathSegment( x1, y1 , a2dPATHSEG_MOVETO, end );
00814 }
00815 else if ( type == wxT("lineto") )
00816 {
00817 seg = new a2dVpathSegment( x1, y1 , a2dPATHSEG_LINETO, end );
00818 }
00819 else if ( type == wxT("lineto_nostroke") )
00820 {
00821 seg = new a2dVpathSegment( x1, y1 , a2dPATHSEG_LINETO_NOSTROKE, end );
00822 }
00823
00824 else if ( type == wxT("cb_curveto") )
00825 {
00826 seg = new a2dVpathCBCurveSegment( x1, y1 , x2, y2, x3, y3, a2dPATHSEG_CBCURVETO, end );
00827 }
00828 else if ( type == wxT("cb_curveto_nostroke") )
00829 {
00830 seg = new a2dVpathCBCurveSegment( x1, y1 , x2, y2, x3, y3, a2dPATHSEG_CBCURVETO_NOSTROKE, end );
00831 }
00832
00833 else if ( type == wxT("qb_curveto") )
00834 {
00835 seg = new a2dVpathQBCurveSegment( x1, y1 , x2, y2, a2dPATHSEG_QBCURVETO, end );
00836 }
00837 else if ( type == wxT("qb_curveto_nostroke") )
00838 {
00839 seg = new a2dVpathQBCurveSegment( x1, y1 , x2, y2, a2dPATHSEG_QBCURVETO_NOSTROKE, end );
00840 }
00841
00842 else if ( type == wxT("arcto") )
00843 {
00844 seg = new a2dVpathArcSegment( x1, y1 , x2, y2, a2dPATHSEG_ARCTO, end );
00845 }
00846 else if ( type == wxT("arcto_nostroke") )
00847 {
00848 seg = new a2dVpathArcSegment( x1, y1 , x2, y2, a2dPATHSEG_ARCTO_NOSTROKE, end );
00849 }
00850
00851 m_segments->push_back( seg );
00852
00853 parser.Next();
00854 parser.Require( END_TAG, wxT("seg") );
00855 parser.Next();
00856 }
00857 }
00858 }
00859 #endif //wxART2D_USE_CVGIO
00860
00861
00862 bool a2dVectorPath::DoIsHitWorld( a2dIterC& ic, a2dHitEvent& hitEvent )
00863 {
00864 a2dPoint2D P=a2dPoint2D(hitEvent.m_relx, hitEvent.m_rely);
00865
00866
00867
00868
00869
00870 hitEvent.m_how = a2dHit::stock_fill;
00871 return hitEvent.m_how.IsHit();
00872 }
00873
00874
00875