22 #include "a2dprivate.h"
26 #pragma warning(disable: 4786)
29 #include "wx/wfstream.h"
32 #include "wx/strconv.h"
33 #include <wx/tokenzr.h>
47 a2dIOHandlerSVGIn::a2dIOHandlerSVGIn()
51 m_docClassInfo = &a2dCanvasDocument::ms_classInfo;
54 a2dIOHandlerSVGIn::~a2dIOHandlerSVGIn()
63 if ( docClassInfo && m_docClassInfo && !docClassInfo->IsKindOf( m_docClassInfo ) )
71 int last_read = Read( buf, 1000 );
73 if( last_read > 1000 )
77 header = wxString( buf, wxConvUTF8, last_read );
81 return ( header.Contains( _T(
"<?xml" ) ) && header.Contains( _T(
"<!DOCTYPE" ) ) && header.Contains( _T(
"<svg" ) )
83 header.Contains( _T(
"<svg" ) )
98 oke = LoadSvg( m_doc );
115 #include <wx/hashmap.h>
117 #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS
118 #define new new(__TFILE__,__LINE__)
122 static StringStringHashMap m_shapeclass;
123 static wxString m_defaultclass;
124 static double m_defaultfontsize;
131 m_defaultclass = GetAttributeValue( _T(
"class" ) );
134 if ( GetTagName() == _T(
"title" ) )
138 Require(
END_TAG, _T(
"title" ) );
141 if ( GetTagName() == _T(
"desc" ) )
145 Require(
END_TAG, _T(
"desc" ) );
151 m_doc->GetDrawing()->GetRootObject()->SetFill( fill );
152 m_doc->GetDrawing()->GetRootObject()->SetStroke( stroke );
154 if ( GetEventType() ==
START_TAG && GetTagName() == _T(
"g" ) )
158 LoadSvgGroup( m_doc->GetDrawing()->GetRootObject() );
159 m_fill = m_doc->GetDrawing()->GetRootObject()->GetFill();
160 m_stroke = m_doc->GetDrawing()->GetRootObject()->GetStroke();
162 while( GetTagName() != _T(
"svg" ) );
168 LoadSvgGroupElement( m_doc->GetDrawing()->GetRootObject() );
170 while( GetTagName() != _T(
"svg" ) );
180 wxString elementname = GetTagName();
182 elementname != _T(
"g" ) &&
183 elementname != _T(
"a" ) &&
184 elementname != _T(
"rect" ) &&
185 elementname != _T(
"text" ) &&
186 elementname != _T(
"circle" ) &&
187 elementname != _T(
"ellipse" ) &&
188 elementname != _T(
"polygon" ) &&
189 elementname != _T(
"polyline" ) &&
190 elementname != _T(
"line" ) &&
191 elementname != _T(
"path" ) &&
192 elementname != _T(
"image" )
195 if( elementname == _T(
"style" ) && g == m_doc->GetDrawing()->GetRootObject() )
197 wxString style = GetContent();
200 wxStringTokenizer tkz( style, _T(
"{}" ) );
201 while ( tkz.HasMoreTokens() )
203 wxString shapeclass = tkz.GetNextToken().Trim(
false ).Trim();
204 wxString shapestyle = tkz.GetNextToken().Trim(
false ).Trim();
205 if ( shapeclass.Length() > 1 && shapestyle.IsEmpty () ==
false && shapeclass[( size_t )0] == _T(
'.' ) )
207 shapeclass = shapeclass.Right( shapeclass.Length() - 1 );
208 m_shapeclass[shapeclass] = shapestyle ;
212 if( m_defaultclass != _T(
"" ) )
214 wxString defaultstyle = m_shapeclass[m_defaultclass];
215 if( defaultstyle.Find( _T(
"font-size:" ) ) >= 0 )
217 defaultstyle = defaultstyle.Right( defaultstyle.Length() - defaultstyle.Find( _T(
"font-size:" ) ) - wxString( _T(
"font-size:" ) ).Length() );
218 defaultstyle.ToDouble( &m_defaultfontsize );
223 Require(
END_TAG, elementname );
230 wxString parseerror = _T(
"not implemented or unknown element " ) + GetTagName();
233 Require(
END_TAG, elementname );
239 if ( LoadSvgGroup( g ) ||
240 LoadSvgAnchor( g ) ||
243 LoadSvgCircle( g ) ||
244 LoadSvgEllipse( g ) ||
245 LoadSvgPolygon( g ) ||
246 LoadSvgPolyline( g ) ||
256 wxString parseerror = _T(
"not implemented or unknown element " ) + GetTagName();
266 if ( GetTagName() != _T(
"g" ) )
271 parent->
Append( m_currentobject );
273 ParseSvgTransForm( m_currentobject );
274 ParseSvgStyle( m_currentobject );
280 if ( !LoadSvgGroupElement( g ) )
289 m_fill = g->GetFill();
290 m_stroke = g->GetStroke();
295 m_fill = g->GetFill();
296 m_stroke = g->GetStroke();
302 if ( GetTagName() != _T(
"a" ) )
307 parent->
Append( m_currentobject );
309 ParseSvgTransForm( m_currentobject );
310 ParseSvgStyle( m_currentobject );
311 ParseSvgLink( m_currentobject );
317 if ( !LoadSvgGroupElement( g ) )
326 m_fill = g->GetFill();
327 m_stroke = g->GetStroke();
332 m_fill = g->GetFill();
333 m_stroke = g->GetStroke();
340 wxString str = GetAttributeValue( _T(
"transform" ) );
342 if ( str == _T(
"" ) )
346 double matrixcoef[12];
357 for ( i = 0; i < str.Len(); i++ )
360 while ( wxIsspace( str[i] ) ) i++;
365 while ( i < str.Len() && wxIsalpha ( str[i] ) )
367 keywstr += str.GetChar( i );
372 while ( wxIsspace( str[i] ) ) i++;
374 if ( str[i] != _T(
'(' ) )
381 while ( wxIsspace( str[i] ) ) i++;
383 size_t len = str.Len();
384 while ( i < len && str[i] != _T(
')' ) )
387 while ( i < len && ( wxIsdigit( str[i] ) || str[i] == _T(
'+' ) || str[i] == _T(
'-' ) || str[i] == _T(
'.' ) || str[i] == _T(
'E' ) ) )
393 numstr.ToDouble( &val );
394 matrixcoef[nr_matrixcoef] = val;
396 while ( i < len && ( wxIsspace( str[i] ) || str[i] == _T(
',' ) ) ) i++;
399 if ( str[i] != _T(
')' ) )
406 if ( keywstr == _T(
"matrix" ) )
408 if ( nr_matrixcoef != 6 )
410 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
412 GetCurrentLineNumber() );
415 matrix.
SetValue( 0, 0, matrixcoef[0] );
416 matrix.
SetValue( 0, 1, matrixcoef[1] );
417 matrix.
SetValue( 1, 0, matrixcoef[2] );
418 matrix.
SetValue( 1, 1, matrixcoef[3] );
419 matrix.
SetValue( 2, 0, matrixcoef[4] );
420 matrix.
SetValue( 2, 1, matrixcoef[5] );
422 matrixtotal = matrixtotal * matrix;
424 else if ( keywstr == _T(
"translate" ) )
426 if ( nr_matrixcoef == 1 )
428 else if ( nr_matrixcoef != 2 )
430 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
432 GetCurrentLineNumber() );
437 matrix.
Translate( matrixcoef[0] , matrixcoef[1] );
439 matrixtotal = matrixtotal * matrix;
441 else if ( keywstr == _T(
"scale" ) )
443 if ( nr_matrixcoef == 1 )
444 matrixcoef[1] = matrixcoef[0];
445 else if ( nr_matrixcoef != 2 )
447 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
449 GetCurrentLineNumber() );
454 matrix.
Scale( matrixcoef[0] , matrixcoef[1], 0, 0 );
457 matrixtotal = matrixtotal * matrix;
459 else if ( keywstr == _T(
"rotate" ) )
461 if ( nr_matrixcoef != 1 )
463 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
465 GetCurrentLineNumber() );
472 matrixtotal = matrixtotal * matrix;
474 else if ( keywstr == _T(
"skewX" ) )
476 if ( nr_matrixcoef != 1 )
478 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
480 GetCurrentLineNumber() );
485 matrix.
SkewX( matrixcoef[0] );
486 matrixtotal = matrixtotal * matrix;
488 else if ( keywstr == _T(
"skewY" ) )
490 if ( nr_matrixcoef != 1 )
492 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
494 GetCurrentLineNumber() );
499 matrix.
SkewY( matrixcoef[0] );
500 matrixtotal = matrixtotal * matrix;
502 else if ( keywstr == _T(
"flipX" ) )
504 if ( nr_matrixcoef != 0 )
506 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
508 GetCurrentLineNumber() );
513 matrix.
Mirror(
true,
false );
514 matrixtotal = matrixtotal * matrix;
516 else if ( keywstr == _T(
"flipY" ) )
518 if ( nr_matrixcoef != 0 )
520 wxLogWarning( _(
"SVG : wrong number of arguments %s at line %d" ),
522 GetCurrentLineNumber() );
527 matrix.
Mirror(
false,
true );
528 matrixtotal = matrixtotal * matrix;
532 wxLogWarning( _(
"SVG : invalid transform %s at line %d" ),
534 GetCurrentLineNumber() );
555 wxString styleattrib = GetAttributeValue( _T(
"style" ) ).Trim(
false ).Trim();
558 if ( styleattrib == _T(
"" ) )
560 wxString classname = GetAttributeValue( _T(
"class" ) );
561 if ( classname != _T(
"" ) )
564 wxStringTokenizer tkz( classname, _T(
" " ) );
565 while ( tkz.HasMoreTokens() )
567 wxString oneitem = tkz.GetNextToken();
569 if( !m_shapeclass[oneitem].IsEmpty() )
571 if ( styleattrib.IsEmpty() )
572 styleattrib = m_shapeclass[oneitem] ;
574 styleattrib = styleattrib + wxT(
";" ) + m_shapeclass[oneitem] ;
579 if ( styleattrib == _T(
"" ) )
586 wxStringTokenizer tkz( styleattrib, _T(
";" ) );
587 while ( tkz.HasMoreTokens() )
589 wxStringTokenizer stylepart( tkz.GetNextToken(), _T(
":" ) );
590 wxString substyle = stylepart.GetNextToken().Trim(
false ).Trim();
591 wxString value = stylepart.GetNextToken().Trim(
false ).Trim();
594 value.ToDouble( &adouble );
595 value.ToLong( &aint );
596 if ( substyle == _T(
"fill" ) )
598 if ( value != _T(
"none" ) )
600 m_fill =
a2dFill( ParseSvgColour( value ) );
607 else if ( substyle == _T(
"fill-rule" ) )
613 if ( value == _T(
"evenodd" ) )
615 else if ( value == _T(
"nonzero" ) )
618 wxLogWarning( _(
"SVG unknown style fill-rule: %s at line %d" ),
620 GetCurrentLineNumber() );
623 else if ( substyle == _T(
"stroke" ) )
625 if ( value != _T(
"none" ) )
634 else if ( substyle == _T(
"opacity" ) )
636 m_fill.SetAlpha( aint );
637 m_stroke.SetAlpha( aint );
639 else if ( substyle == _T(
"fill-opacity" ) )
641 m_fill.SetAlpha( aint );
643 else if ( substyle == _T(
"stroke-opacity" ) )
645 m_stroke.SetAlpha( aint );
647 else if ( substyle == _T(
"stroke-width" ) )
649 m_stroke.SetWidth( adouble );
651 else if ( substyle == _T(
"stroke-linecap" ) )
653 if ( value == _T(
"butt" ) )
654 m_stroke.SetCap( wxCAP_BUTT );
655 else if ( value == _T(
"round" ) )
656 m_stroke.SetCap( wxCAP_ROUND );
657 else if ( value == _T(
"square" ) )
658 m_stroke.SetCap( wxCAP_PROJECTING );
660 wxLogWarning( _(
"SVG unknown line cap style: %s at line %d" ),
662 GetCurrentLineNumber() );
664 else if ( substyle == _T(
"stroke-linejoin" ) )
666 if ( value == _T(
"miter" ) )
667 m_stroke.SetJoin( wxJOIN_MITER );
668 else if ( value == _T(
"round" ) )
669 m_stroke.SetJoin( wxJOIN_ROUND );
670 else if ( value == _T(
"bevel" ) )
671 m_stroke.SetJoin( wxJOIN_BEVEL );
673 wxLogWarning( _(
"SVG unknown line join style: %s at line %d" ),
675 GetCurrentLineNumber() );
677 else if ( substyle == _T(
"font-size" ) )
686 if( value.Right( 2 ) == _T(
"em" ) )
688 if( m_defaultfontsize < 0.1 )
697 else if ( substyle == _T(
"font-family" ) )
704 else if ( substyle == _T(
"stroke-miterlimit" ) )
712 wxLogWarning( _(
"SVG unknown style: %s: %s at line %d" ),
713 substyle.c_str(), value.c_str(),
714 GetCurrentLineNumber() );
728 wxString linkattrib = GetAttributeValue( _T(
"xlink:href" ) ).Trim(
false ).Trim();
729 wxStringTokenizer tkz( linkattrib, _T(
";" ) );
730 while ( tkz.HasMoreTokens() )
732 wxString url = tkz.GetNextToken();
733 object->SetURI( url );
741 if ( GetTagName() != _T(
"rect" ) )
745 m_currentobject = rect;
746 parent->
Append( m_currentobject );
748 ParseSvgTransForm( m_currentobject );
749 ParseSvgStyle( m_currentobject );
754 matrix.
Translate( GetAttributeValueDouble( _T(
"x" ) ) , GetAttributeValueDouble( _T(
"y" ) ) );
755 matrixtotal = matrixtotal * matrix;
758 rect->
SetWidth( GetAttributeValueDouble( _T(
"width" ) ) );
759 rect->
SetHeight( GetAttributeValueDouble( _T(
"height" ) ) );
762 Require(
END_TAG, _T(
"rect" ) );
770 if ( GetTagName() != _T(
"circle" ) )
774 m_currentobject = circle;
775 parent->
Append( m_currentobject );
777 ParseSvgTransForm( m_currentobject );
778 ParseSvgStyle( m_currentobject );
783 matrix.
Translate( GetAttributeValueDouble( _T(
"cx" ) ) , GetAttributeValueDouble( _T(
"cy" ) ) );
784 matrixtotal = matrixtotal * matrix;
787 circle->
SetRadius( GetAttributeValueDouble( _T(
"r" ) ) );
790 Require(
END_TAG, _T(
"circle" ) );
798 if ( GetTagName() != _T(
"ellipse" ) )
802 m_currentobject = Ellipse;
803 parent->
Append( m_currentobject );
805 ParseSvgTransForm( m_currentobject );
806 ParseSvgStyle( m_currentobject );
811 matrix.
Translate( GetAttributeValueDouble( _T(
"cx" ) ) , GetAttributeValueDouble( _T(
"cy" ) ) );
812 matrixtotal = matrixtotal * matrix;
815 Ellipse->
SetWidth( GetAttributeValueDouble( _T(
"rx" ) ) * 2 );
816 Ellipse->
SetHeight( GetAttributeValueDouble( _T(
"ry" ) ) * 2 );
819 Require(
END_TAG, _T(
"ellipse" ) );
827 if ( GetTagName() != _T(
"text" ) )
831 m_currentobject = text;
832 parent->
Append( m_currentobject );
834 ParseSvgTransForm( m_currentobject );
835 ParseSvgStyle( m_currentobject );
842 matrix.
Translate( GetAttributeValueDouble( _T(
"x" ) ) , GetAttributeValueDouble( _T(
"y" ) ) );
843 matrixtotal = matrixtotal * matrix;
848 if( GetEventType() ==
END_TAG )
850 Require(
END_TAG, _T(
"text" ) );
855 wxString s = _T(
"" );
856 while( GetEventType() !=
END_TAG || GetTagName() != _T(
"text" ) )
858 if( !GetContent().IsEmpty() )
860 s = s + GetContent();
874 wxString pstr = GetAttributeValue( _T(
"points" ) );
876 if ( pstr == _T(
"" ) )
882 double x = 0.0, y = 0.0;
885 for ( i = 0; i < pstr.Len(); i++ )
887 if ( pstr[i] != _T(
' ' ) && pstr[i] != _T(
',' ) )
892 while ( i < pstr.Len() && pstr[i] != _T(
' ' ) && pstr[i] != _T(
',' ) )
894 numstr += pstr.GetChar( i );
897 numstr.ToDouble( &x );
903 while ( i < pstr.Len() && pstr[i] != _T(
' ' ) && pstr[i] != _T(
',' ) )
905 numstr += pstr.GetChar( i );
908 numstr.ToDouble( &y );
919 if ( GetTagName() != _T(
"polygon" ) )
924 if ( !ParsePoints( points ) )
927 wxString parseerror = _T(
"points missing in polygon" );
933 m_currentobject = poly;
934 parent->
Append( m_currentobject );
936 ParseSvgTransForm( m_currentobject );
937 ParseSvgStyle( m_currentobject );
940 Require(
END_TAG, _T(
"polygon" ) );
948 if ( GetTagName() != _T(
"polyline" ) )
953 if ( !ParsePoints( points ) )
956 wxString parseerror = _T(
"points missing in polyline" );
959 GetCurrentLineNumber() );
964 m_currentobject = poly;
965 parent->
Append( m_currentobject );
967 ParseSvgTransForm( m_currentobject );
968 ParseSvgStyle( m_currentobject );
971 Require(
END_TAG, _T(
"polyline" ) );
979 if ( GetTagName() != _T(
"line" ) )
982 double x1 = GetAttributeValueDouble( _T(
"x1" ) );
983 double y1 = GetAttributeValueDouble( _T(
"y1" ) );
984 double x2 = GetAttributeValueDouble( _T(
"x2" ) );
985 double y2 = GetAttributeValueDouble( _T(
"y2" ) );
989 m_currentobject = line;
990 parent->
Append( m_currentobject );
992 ParseSvgTransForm( m_currentobject );
993 ParseSvgStyle( m_currentobject );
996 Require(
END_TAG, _T(
"line" ) );
1004 #define M_PI (3.1415926535897932384626433832795028841972)
1033 rsvg_path_arc (
double startx,
double starty,
1034 double rx,
double ry,
double x_axis_rotation,
1035 int large_arc_flag,
int sweep_flag,
1037 double* pcx,
double* pcy,
1040 double sin_th, cos_th;
1041 double a00, a01, a10, a11;
1042 double x0, y0, x1, y1, xc, yc;
1043 double d, sfactor, sfactor_sq;
1044 double th0, th1, th_arc;
1047 sin_th = sin ( x_axis_rotation * ( M_PI / 180.0 ) );
1048 cos_th = cos ( x_axis_rotation * ( M_PI / 180.0 ) );
1053 x0 = a00 * startx + a01 * starty;
1054 y0 = a10 * startx + a11 * starty;
1055 x1 = a00 * x + a01 * y;
1056 y1 = a10 * x + a11 * y;
1062 d = ( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 );
1063 sfactor_sq = 1.0 / d - 0.25;
1064 if ( sfactor_sq < 0 ) sfactor_sq = 0;
1065 sfactor = sqrt ( sfactor_sq );
1066 if ( sweep_flag == large_arc_flag ) sfactor = -sfactor;
1067 xc = 0.5 * ( x0 + x1 ) - sfactor * ( y1 - y0 );
1068 yc = 0.5 * ( y0 + y1 ) + sfactor * ( x1 - x0 );
1071 th0 = atan2 ( y0 - yc, x0 - xc );
1072 th1 = atan2 ( y1 - yc, x1 - xc );
1075 if ( th_arc < 0 && sweep_flag )
1077 else if ( th_arc > 0 && !sweep_flag )
1080 n_segs = ( int ) ceil ( fabs ( th_arc / ( M_PI * 0.5 + 0.001 ) ) );
1083 sin_th = sin ( x_axis_rotation * ( M_PI / 180.0 ) );
1084 cos_th = cos ( x_axis_rotation * ( M_PI / 180.0 ) );
1091 double th_half = 0.5 * ( th1 - th0 );
1092 double t = ( 8.0 / 3.0 ) * sin ( th_half * 0.5 ) * sin ( th_half * 0.5 ) / sin ( th_half );
1093 x1 = xc + cos ( th0 ) - t * sin ( th0 );
1094 y1 = yc + sin ( th0 ) + t * cos ( th0 );
1099 *pcx = a00 * xc + a01 * yc;
1100 *pcy = a10 * xc + a11 * yc;
1107 wxString buffer = GetAttributeValue( _T(
"d" ) );
1109 if ( buffer == _T(
"" ) )
1112 unsigned int position = 0;
1114 double lastmovex = 0;
1115 double lastmovey = 0;
1125 SkipSpaces( buffer, position );
1127 while ( position < buffer.Len() )
1129 current = buffer[ position ];
1130 char command = current;
1132 SkipSpaces( buffer, position );
1144 points->push_back( seg );
1150 if ( command == _T(
'm' ) )
1151 lastx += ParseDouble( buffer, position );
1153 lastx = ParseDouble( buffer, position );
1155 SkipCommaSpaces( buffer, position );
1157 if ( command == _T(
'm' ) )
1158 lasty += ParseDouble( buffer, position );
1160 lasty = ParseDouble( buffer, position );
1162 SkipCommaSpaces( buffer, position );
1166 points->push_back( seg );
1172 current = buffer[ position ];
1173 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1175 if ( command == _T(
'm' ) )
1176 lastx += ParseDouble( buffer, position );
1178 lastx = ParseDouble( buffer, position );
1180 SkipCommaSpaces( buffer, position );
1182 if ( command == _T(
'm' ) )
1183 lasty += ParseDouble( buffer, position );
1185 lasty = ParseDouble( buffer, position );
1189 points->push_back( seg );
1193 SkipCommaSpaces( buffer, position );
1202 current = buffer[ position ];
1203 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1205 if ( command == _T(
'l' ) )
1206 lastx += ParseDouble( buffer, position );
1208 lastx = ParseDouble( buffer, position );
1210 SkipCommaSpaces( buffer, position );
1212 if ( command == _T(
'l' ) )
1213 lasty += ParseDouble( buffer, position );
1215 lasty = ParseDouble( buffer, position );
1219 points->push_back( seg );
1223 SkipCommaSpaces( buffer, position );
1232 current = buffer[ position ];
1233 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1235 if ( command == _T(
'h' ) )
1236 lastx += ParseDouble( buffer, position );
1238 lastx = ParseDouble( buffer, position );
1242 points->push_back( seg );
1246 SkipCommaSpaces( buffer, position );
1255 current = buffer[ position ];
1256 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1258 if ( command == _T(
'v' ) )
1259 lasty += ParseDouble( buffer, position );
1261 lasty = ParseDouble( buffer, position );
1265 points->push_back( seg );
1269 SkipCommaSpaces( buffer, position );
1278 double x1 = 0.0, y1 = 0.0, x2, y2, x, y;
1281 current = buffer[ position ];
1282 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1284 if ( command == _T(
'C' ) || command == _T(
'c' ) )
1286 x1 = ParseDouble( buffer, position );
1287 SkipCommaSpaces( buffer, position );
1288 y1 = ParseDouble( buffer, position );
1289 SkipCommaSpaces( buffer, position );
1291 x2 = ParseDouble( buffer, position );
1292 SkipCommaSpaces( buffer, position );
1293 y2 = ParseDouble( buffer, position );
1294 SkipCommaSpaces( buffer, position );
1295 x = ParseDouble( buffer, position );
1296 SkipCommaSpaces( buffer, position );
1297 y = ParseDouble( buffer, position );
1298 SkipCommaSpaces( buffer, position );
1300 if ( command == _T(
'c' ) || command == _T(
's' ) )
1311 if ( command == _T(
'C' ) || command == _T(
'c' ) )
1316 points->push_back( seg );
1322 SkipCommaSpaces( buffer, position );
1331 double x1 = 0.0, y1 = 0.0, x, y;
1334 current = buffer[ position ];
1335 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1338 if ( command == _T(
'Q' ) || command == _T(
'q' ) )
1340 x1 = ParseDouble( buffer, position );
1341 SkipCommaSpaces( buffer, position );
1342 y1 = ParseDouble( buffer, position );
1343 SkipCommaSpaces( buffer, position );
1345 x = ParseDouble( buffer, position );
1346 SkipCommaSpaces( buffer, position );
1347 y = ParseDouble( buffer, position );
1348 SkipCommaSpaces( buffer, position );
1350 if ( command == _T(
'q' ) || command == _T(
't' ) )
1359 if ( command == _T(
'Q' ) || command == _T(
'q' ) )
1363 points->push_back( seg );
1369 SkipCommaSpaces( buffer, position );
1376 double rx, ry, ax, x, y;
1379 current = buffer[ position ];
1380 if ( current == wxT(
'+' ) || current == wxT(
'-' ) || wxIsdigit( current ) )
1382 rx = ParseDouble( buffer, position );
1383 SkipCommaSpaces( buffer, position );
1384 ry = ParseDouble( buffer, position );
1385 SkipCommaSpaces( buffer, position );
1386 ax = ParseDouble( buffer, position );
1387 SkipCommaSpaces( buffer, position );
1389 current = buffer[ position ];
1402 SkipCommaSpaces( buffer, position );
1403 current = buffer[ position ];
1417 SkipCommaSpaces( buffer, position );
1418 x = ParseDouble( buffer, position );
1419 SkipCommaSpaces( buffer, position );
1420 y = ParseDouble( buffer, position );
1421 SkipCommaSpaces( buffer, position );
1423 if ( command == _T(
'a' ) )
1433 rsvg_path_arc( lastx, lasty, rx, ry, ax, laf, sf, x, y, &xc, &yc, &angle );
1437 points->push_back( seg );
1443 SkipCommaSpaces( buffer, position );
1465 if ( GetTagName() != _T(
"path" ) )
1470 if ( !ParsePathPoints( points ) )
1473 wxString parseerror = _T(
"points missing in polygon" );
1476 GetCurrentLineNumber() );
1481 m_currentobject = path;
1482 parent->
Append( m_currentobject );
1484 ParseSvgTransForm( m_currentobject );
1485 ParseSvgStyle( m_currentobject );
1488 Require(
END_TAG, _T(
"path" ) );
1496 if ( GetTagName() != _T(
"image" ) )
1500 m_currentobject = Image;
1501 parent->
Append( m_currentobject );
1503 ParseSvgTransForm( m_currentobject );
1504 ParseSvgStyle( m_currentobject );
1506 Image->
Translate( GetAttributeValueDouble( _T(
"x" ) ) , GetAttributeValueDouble( _T(
"y" ) ) );
1508 Image->
SetWidth( GetAttributeValueDouble( _T(
"width" ) ) );
1509 Image->
SetHeight( GetAttributeValueDouble( _T(
"height" ) ) );
1510 Image->
SetFilename( GetAttributeValue( _T(
"xlink:href" ) ), wxBITMAP_TYPE_PNG );
1514 Require(
END_TAG, _T(
"image" ) );
1524 a2dIOHandlerSVGOut::a2dIOHandlerSVGOut()
1528 m_showObject = NULL;
1532 a2dIOHandlerSVGOut::~a2dIOHandlerSVGOut()
1548 if ( !m_showObject )
1549 m_showObject = m_doc->GetDrawing()->GetRootObject();
1556 ic =
a2dIterC( drawer->GetDrawingPart() );
1561 wxASSERT_MSG( m_ic, wxT(
"No iteration context set while writing SVG output" ) );
1562 wxASSERT_MSG( m_ic->GetDrawer2D(), wxT(
"a2dIOHandlerSVGOut no a2dDrawer2D while writing SVG output" ) );
1566 double Width = 1000;
1567 double Height = 1000;
1568 wxString unit = _T(
"um" );
1570 bool yaxis = m_ic->GetDrawer2D()->GetYaxis();
1578 m_streamo = &stream;
1580 WriteStartDocument( _T(
"1.0" ), _T(
"UTF-8" ) ,
false );
1581 EndlWriteString ( _T(
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " ) );
1583 EndlWriteString ( _T(
"\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> " ) );
1585 WriteStartElementAttributes( _T(
"svg" ) );
1587 WriteAttribute( _T(
"xmlns" ), _T(
"http://www.w3.org/2000/svg" ) );
1588 WriteAttribute( _T(
"xmlns:xlink" ), _T(
"http://www.w3.org/1999/xlink" ) );
1591 s.Printf ( _T(
" width=\"%.2f%s\" height=\"%.2f%s\" viewBox=\"%f %f %f %f \" " ),
1592 Width, unit.c_str(), Height, unit.c_str(),
1593 m_ic->GetDrawer2D()->GetVisibleMinX(),
1594 m_ic->GetDrawer2D()->GetVisibleMinY(),
1595 m_ic->GetDrawer2D()->GetVisibleWidth(),
1596 m_ic->GetDrawer2D()->GetVisibleHeight() );
1601 WriteEndAttributes();
1603 WriteElement( _T(
"title" ), m_doc->GetPrintableName() );
1604 WriteElement( _T(
"desc" ), m_doc->GetDescription() );
1606 WriteStartElementAttributes( _T(
"g" ) );
1607 WriteAttribute( _T(
"style" ), _T(
"fill:black; stroke:black; stroke-width:1" ) );
1608 WriteEndAttributes();
1612 WriteStartElementAttributes( _T(
"g" ) );
1613 WriteAttribute( _T(
"transform" ), _T(
"scale( 1,-1)" ) );
1614 WriteEndAttributes();
1619 Save( root, wxLAYER_ALL );
1635 wxString a2dIOHandlerSVGOut::UniqueName ( wxString baseName )
1637 if ( m_nameMap.find( baseName ) == m_nameMap.end() )
1639 m_nameMap[baseName] = 0;
1643 ++m_nameMap[baseName];
1645 baseName.Printf( _T(
"obj_%s_%d" ), baseName.c_str(), m_nameMap[baseName] );
1652 int objectlayer =
object->GetLayer();
1654 if ( layer != objectlayer && layer != wxLAYER_ALL )
1666 SaveGradient( object->GetFill(), object );
1673 SaveGradient( shadow->
GetFill(), object );
1677 wxString url =
object->GetURI().BuildURI();
1679 if ( !url.IsEmpty() )
1681 WriteStartElementAttributes( _T(
"a" ) );
1682 WriteAttribute( _T(
"xlink:href" ), url );
1683 WriteAttribute( _T(
"id" ), UniqueName( object->
GetName() ) );
1687 WriteStartElementAttributes( _T(
"g" ) );
1688 WriteAttribute( _T(
"id" ), UniqueName( object->
GetName() ) );
1694 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
1699 WriteAttribute( _T(
"transform" ), s );
1703 SetSVGStyle( object->GetFill(),
object->GetStroke(), object, layer );
1705 WriteEndAttributes();
1709 double dx = cos( shadow->GetExtrudeAngle() ) * shadow->GetExtrudeDepth();
1710 double dy = sin( shadow->GetExtrudeAngle() ) * shadow->GetExtrudeDepth();
1712 WriteStartElementAttributes( _T(
"g" ) );
1713 s.Printf ( _T(
" %f %f " ), dx, dy );
1714 WriteAttribute( _T(
"translate" ), s );
1718 WriteEndAttributes();
1720 DoSave(
object, layer );
1725 DoSave(
object, layer );
1727 a2dNamedPropertyList::const_iterator iter;
1728 for( iter = object->
GetPropertyList().begin(); iter !=
object->GetPropertyList().end(); ++iter )
1731 DoSaveProperty(
object, prop, wxLAYER_ALL );
1738 a2dCanvasObjectList::const_iterator iter = childobjects->begin();
1740 if ( iter != childobjects->end() )
1747 if ( ( layer == wxLAYER_ALL ||
object == m_ic->GetDrawingPart()->GetShowObject() )
1749 m_doc->GetLayerSetup()
1753 for ( j = 0; j < wxMAXLAYER; j++ )
1756 if ( m_ic->GetDrawingPart()->GetReverseOrder() )
1763 if ( objlayer == wxNullLayerInfo )
1776 for( a2dCanvasObjectList::const_iterator iter2 = childobjects->begin(); iter2 != childobjects->end(); ++iter2 )
1782 if ( olayer == objlayer->
GetLayer() )
1792 for( a2dCanvasObjectList::const_iterator iter2 = childobjects->begin(); iter2 != childobjects->end(); ++iter2 )
1797 if ( olayer == layer )
1817 double x2 = fill.
GetStop().m_x;
1818 double y2 = fill.
GetStop().m_y;
1820 if ( x1 == x2 && y1 == y2 )
1829 WriteStartElementAttributes( _T(
"linearGradient" ) );
1830 WriteAttribute( _T(
"id" ), fill.
GetStamp() );
1831 WriteAttribute( _T(
"gradientUnits" ), _T(
"userSpaceOnUse" ) );
1832 WriteAttribute( _T(
"x1" ), x1 );
1833 WriteAttribute( _T(
"y1" ), y1 );
1834 WriteAttribute( _T(
"x2" ), x2 );
1835 WriteAttribute( _T(
"y2" ), y2 );
1836 WriteEndAttributes();
1840 WriteStartElementAttributes( _T(
"stop" ) );
1841 WriteAttribute( _T(
"offset" ), 0 );
1843 WriteAttribute( _T(
"style" ), s );
1844 WriteEndAttributes();
1847 WriteStartElementAttributes( _T(
"stop" ) );
1848 WriteAttribute( _T(
"offset" ), 1 );
1850 WriteAttribute( _T(
"style" ), s );
1851 WriteEndAttributes();
1866 WriteStartElementAttributes( _T(
"radialGradient" ) );
1867 WriteAttribute( _T(
"id" ), fill.
GetStamp() );
1868 WriteAttribute( _T(
"gradientUnits" ), _T(
"userSpaceOnUse" ) );
1870 WriteAttribute( _T(
"cx" ), fill.
GetCenter().m_x );
1871 WriteAttribute( _T(
"cy" ), fill.
GetCenter().m_y );
1872 WriteAttribute( _T(
"r" ), radius );
1873 WriteAttribute( _T(
"xfc" ), fill.
GetFocal().m_x );
1874 WriteAttribute( _T(
"yfc" ), fill.
GetFocal().m_y );
1875 WriteEndAttributes();
1879 WriteStartElementAttributes( _T(
"stop" ) );
1880 WriteAttribute( _T(
"offset" ), 0 );
1882 WriteAttribute( _T(
"style" ), s );
1883 WriteEndAttributes();
1886 WriteStartElementAttributes( _T(
"stop" ) );
1887 WriteAttribute( _T(
"offset" ), 1 );
1889 WriteAttribute( _T(
"style" ), s );
1890 WriteEndAttributes();
1899 int objectlayer =
object->GetLayer();
1901 a2dLayers* layers = m_doc->GetLayerSetup();
1910 fillw = layers->GetFill( objectlayer );
1918 strokew = layers->GetStroke( objectlayer );
1934 double worldwidth = m_ic->GetDrawer2D()->DeviceToWorldXRel( stroke.
GetWidth() );
1935 s3.Printf ( _T(
"stroke-width:%f; " ), worldwidth );
1939 s3.Printf ( _T(
"stroke-width:%f; " ), strokew.
GetWidth() );
1942 if ( strokew.GetAlpha() < 255 )
1944 wxString strokeAlpha;
1947 _T(
"stroke-opacity:%f; " ),
1948 (
double )( strokew.GetAlpha() / 255.0 )
1950 s3 = s3 + strokeAlpha;
1954 wxString strokeDash;
1955 switch ( strokew.GetStyle() )
1958 strokeDash = _T(
"stroke-dasharray: 0.3 0.3;" );
1961 strokeDash = _T(
"stroke-dasharray: 1.5 0.5;" );
1964 strokeDash = _T(
"stroke-dasharray: 1 0.5;" );
1967 strokeDash = _T(
"stroke-dasharray: 0.5 1 1.5 1;" );
1988 if ( strokeDash.Length() > 0 )
1990 s3 = s3 + strokeDash;
1996 s2 = _T(
" stroke:none; " ) ;
2012 wxString s1( _T(
"" ) );
2021 s1 = _T(
" fill:none; " ) ;
2026 wxString gradientstamp;
2027 gradientstamp.Printf( _T(
"%d" ), fillw.
GetStamp() );
2031 s1 = _T(
" fill-rule:nonzero; fill:url(#" ) + gradientstamp + _T(
"); " );
2035 s1 = _T(
" fill:none; " ) ;
2041 wxString gradientstamp;
2042 gradientstamp.Printf( _T(
"%d" ), fillw.
GetStamp() );
2046 s1 = _T(
" fill-rule:nonzero; fill:url(#" ) + gradientstamp + _T(
"); " );
2051 s1 = _T(
" fill:none; " ) ;
2054 if ( fillw.GetAlpha() < 255 )
2059 _T(
"fill-opacity:%f; " ),
2060 (
double )( fillw.GetAlpha() / 255.0 )
2062 s1 = s1 + fillAlpha;
2069 a2dNamedPropertyList::const_iterator iter;
2070 for( iter = object->
GetPropertyList().begin(); iter !=
object->GetPropertyList().end(); ++iter )
2083 *
this << _T(
" style = \" " ) << s << _T(
" \" " );
2091 const wxString& style
2099 WriteStartElementAttributes( _T(
"path" ) );
2103 if ( style.Length() > 0 )
2105 WriteAttribute( _T(
"style" ), style );
2109 WriteAttribute( _T(
"style" ), _T(
"fill-rule:nonzero; " ) );
2114 WriteAttribute( _T(
"style" ), _T(
"fill:none;" ) );
2116 EndlWriteString( _T(
"d=\"" ) );
2119 a2dVertexList::const_iterator iter = vertexList->begin();
2124 double x = point->
m_x;
2125 double y = point->
m_y;
2135 double xFirstMidpoint = xOld + 0.5 * ( x - xOld );
2136 double yFirstMidpoint = yOld + 0.5 * ( y - yOld );
2141 s.Printf( _T(
"M %f,%f" ), xFirstMidpoint, yFirstMidpoint );
2142 EndlWriteString( s );
2150 s.Printf( _T(
"M %f,%f" ), xOld, yOld );
2151 EndlWriteString( s );
2153 s.Printf( _T(
"L %f,%f" ), xFirstMidpoint, yFirstMidpoint );
2154 EndlWriteString( s );
2167 iter != vertexList->end();
2181 _T(
"Q %f,%f,%f,%f" ),
2184 xOld + 0.5 * ( x - xOld ),
2185 yOld + 0.5 * ( y - yOld )
2187 EndlWriteString ( s );
2195 point = vertexList->front();
2200 _T(
"Q %f,%f,%f,%f" ),
2203 xOld + 0.5 * ( x - xOld ),
2204 yOld + 0.5 * ( y - yOld )
2206 EndlWriteString( s );
2210 _T(
"Q %f,%f,%f,%f" ),
2216 EndlWriteString( s );
2222 s.Printf ( _T(
"L %f,%f" ), x, y );
2223 EndlWriteString( s );
2226 EndlWriteString( _T(
"\"" ) ) ;
2227 WriteEndAttributes();
2234 const wxString& style
2239 for ( i = 0; i < vertexArray->size(); i++ )
2241 h.push_back( vertexArray->Item( i )->
Clone() );
2244 CreateSVGSpline( &h, asPolygon, style );
2263 for ( i = 0 ; i < obj->GetRows(); i++ )
2265 for ( j = 0 ; j < obj->GetColumns(); j++ )
2268 tworld *= originalRef;
2273 offsetXY.
Translate( obj->GetHorzSpace(), 0 );
2276 currentWorld *= offsetXY;
2279 offsetXY.
Translate( -obj->GetHorzSpace()*obj->GetColumns(), obj->GetVertSpace() );
2281 currentWorld *= offsetXY;
2295 double w = ( int ) m_ic->GetDrawer2D()->DeviceToWorldXRel( obj->
GetWidth() );
2296 double h = ( int ) m_ic->GetDrawer2D()->DeviceToWorldYRel( obj->
GetHeight() );
2298 s.Printf ( _T(
"M%f %f L %f %f" ), -w, 0.0, w, 0.0 );
2299 WriteStartElementAttributes( _T(
"path" ) );
2300 WriteAttribute( _T(
"d" ), s );
2301 WriteEndAttributes();
2303 s.Printf ( _T(
"M %f %f L %f %f" ), 0.0, -h, 0.0, h );
2304 WriteStartElementAttributes( _T(
"path" ) );
2305 WriteAttribute( _T(
"d" ), s );
2306 WriteEndAttributes();
2361 cpoints[0].m_x = 0 ; cpoints[0].m_y = 0;
2362 cpoints[1].m_x = obj->
GetL1(); cpoints[1].m_y = obj->
GetBase() / 2;
2363 cpoints[2].m_x = obj->
GetL2(); cpoints[2].m_y = 0;
2364 cpoints[3].m_x = obj->
GetL1(); cpoints[3].m_y = -obj->
GetBase() / 2;
2366 WriteStartElementAttributes( _T(
"polygon" ) );
2368 wxPolygonFillMode fillStyle = wxWINDING_RULE;
2369 if ( fillStyle == wxODDEVEN_RULE )
2370 s = _T(
"fill-rule:evenodd; " );
2372 s = _T(
"fill-rule:nonzero; " );
2374 WriteAttribute( _T(
"style" ), s );
2375 EndlWriteString( _T(
" points=\"" ) );
2377 for (
int i = 0; i < 5; i++ )
2379 s.Printf ( _T(
"%f,%f " ), cpoints [i].m_x, cpoints[i].m_y );
2383 EndlWriteString( _T(
"\"" ) ) ;
2384 WriteEndAttributes(
true );
2397 WriteStartElementAttributes( _T(
"rect" ) );
2398 WriteAttribute( _T(
"x" ), x );
2399 WriteAttribute( _T(
"y" ), y );
2400 WriteAttribute( _T(
"width" ), obj->
GetWidth() );
2401 WriteAttribute( _T(
"height" ), obj->
GetHeight() );
2404 WriteAttribute( _T(
"rx" ), obj->
GetRadius() );
2406 WriteEndAttributes(
true );
2417 WriteStartElementAttributes( _T(
"rect" ) );
2418 WriteAttribute( _T(
"x" ), x );
2421 WriteAttribute( _T(
"y" ), obj->
GetHeight() );
2422 WriteAttribute( _T(
"width" ), obj->
GetWidth() );
2423 WriteAttribute( _T(
"height" ), -obj->
GetHeight() );
2427 WriteAttribute( _T(
"y" ), y );
2428 WriteAttribute( _T(
"width" ), obj->
GetWidth() );
2429 WriteAttribute( _T(
"height" ), obj->
GetHeight() );
2433 WriteAttribute( _T(
"rx" ), obj->
GetRadius() );
2435 WriteEndAttributes(
true );
2442 WriteStartElementAttributes( _T(
"circle" ) );
2443 WriteAttribute( _T(
"cx" ), 0 );
2444 WriteAttribute( _T(
"cy" ), 0 );
2445 WriteAttribute( _T(
"r" ), obj->
GetRadius() );
2447 WriteEndAttributes(
true );
2458 WriteStartElementAttributes( _T(
"ellipse" ) );
2459 WriteAttribute( _T(
"cx" ), 0 );
2460 WriteAttribute( _T(
"cy" ), 0 );
2461 WriteAttribute( _T(
"rx" ), rw );
2462 WriteAttribute( _T(
"ry" ), rh );
2464 WriteEndAttributes(
true );
2482 wxString s, s1, s2, s3 ;
2484 a2dFill fill =
object->GetFill();
2492 double xs, ys, xe, ye ;
2500 double theta1 = atan2( yc - ys, xs - xc );
2501 if ( theta1 < 0 ) theta1 = theta1 +
wxPI * 2;
2502 double theta2 = atan2( yc - ye, xe - xc );
2503 if ( theta2 < 0 ) theta2 = theta2 + wxPI * 2;
2504 if ( theta2 < theta1 ) theta2 = theta2 + wxPI * 2 ;
2507 if ( fabs( ( theta2 - theta1 ) ) > wxPI ) fArc =
true;
else fArc =
false;
2509 bool fSweep =
false;
2513 WriteStartElementAttributes( _T(
"path" ) );
2516 s.Printf ( _T(
"M%f %f A%f %f 0.0 %s %s %f %f L%f %f Z" ),
2517 xs, ys, rx, ry, fArc ? _T(
"1" ) : _T(
"0" ) , fSweep ? _T(
"1" ) : _T(
"0" ), xe, ye, xc, yc );
2518 WriteAttribute( _T(
"d" ), s );
2519 WriteAttribute( _T(
"style" ), _T(
"stroke:none; " ) );
2520 WriteEndAttributes();
2527 WriteStartElementAttributes( _T(
"path" ) );
2530 s.Printf ( _T(
"M%f %f A%f %f 0.0 %s %s %f %f L%f %f Z" ),
2531 xs, ys, rx, ry, fArc ? _T(
"1" ) : _T(
"0" ) , fSweep ? _T(
"1" ) : _T(
"0" ), xe, ye, xc, yc );
2536 WriteAttribute( _T(
"d" ), s );
2537 WriteAttribute( _T(
"style" ), _T(
"fill:none; " ) );
2538 WriteEndAttributes();
2554 wxString s, s1, s2, s3 ;
2556 a2dFill fill =
object->GetFill();
2561 double dx = obj->
GetX1();
2562 double dy = obj->
GetY1();
2563 double radius = sqrt( dx * dx + dy * dy );
2565 double start =
wxRadToDeg( atan2( dy, dx ) );
2574 double xs, ys, xe, ye ;
2575 if ( m_ic->GetDrawer2D()->GetYaxis() )
2592 double theta1 = atan2( yc - ys, xs - xc );
2593 if ( theta1 < 0 ) theta1 = theta1 +
wxPI * 2;
2594 double theta2 = atan2( yc - ye, xe - xc );
2595 if ( theta2 < 0 ) theta2 = theta2 + wxPI * 2;
2596 if ( theta2 < theta1 ) theta2 = theta2 + wxPI * 2 ;
2599 if ( fabs( ( theta2 - theta1 ) ) > wxPI ) fArc =
true;
else fArc =
false;
2601 bool fSweep =
false;
2605 WriteStartElementAttributes( _T(
"path" ) );
2608 s.Printf ( _T(
"M%f %f A%f %f 0.0 %s %s %f %f L%f %f Z" ),
2609 xs, ys, rx, ry, fArc ? _T(
"1" ) : _T(
"0" ) , fSweep ? _T(
"1" ) : _T(
"0" ), xe, ye, xc, yc );
2610 WriteAttribute( _T(
"d" ), s );
2611 WriteAttribute( _T(
"style" ), _T(
"stroke:none; " ) );
2612 WriteEndAttributes();
2619 WriteStartElementAttributes( _T(
"path" ) );
2622 s.Printf ( _T(
"M%f %f A%f %f 0.0 %s %s %f %f L%f %f Z" ),
2623 xs, ys, rx, ry, fArc ? _T(
"1" ) : _T(
"0" ) , fSweep ? _T(
"1" ) : _T(
"0" ), xe, ye, xc, yc );
2628 WriteAttribute( _T(
"d" ), s );
2629 WriteAttribute( _T(
"style" ), _T(
"fill:none; " ) );
2630 WriteEndAttributes();
2639 double x1 = obj->
GetPosX1(
false );
2640 double y1 = obj->
GetPosY1(
false );
2641 double x2 = obj->
GetPosX2(
false );
2642 double y2 = obj->
GetPosY2(
false );
2643 double xscale = obj->GetEndScaleX();
2644 double yscale = obj->GetEndScaleY();
2646 WriteStartElementAttributes( _T(
"path" ) );
2647 s.Printf ( _T(
"M%f %f L%f %f" ), x1, y1, x2, y2 );
2648 WriteAttribute( _T(
"d" ), s );
2649 WriteEndAttributes();
2665 lworld.
Scale( xscale, yscale, 0, 0 );
2669 WriteStartElementAttributes( _T(
"g" ) );
2670 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
2675 WriteAttribute( _T(
"transform" ), s );
2676 WriteEndAttributes();
2696 lworld.
Scale( xscale, yscale, 0, 0 );
2700 WriteStartElementAttributes( _T(
"g" ) );
2701 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
2706 WriteAttribute( _T(
"transform" ), s );
2707 WriteEndAttributes();
2709 Save( obj->
GetEnd(), layer );
2719 WriteStartElementAttributes( _T(
"path" ) );
2721 WriteAttribute( _T(
"d" ), s );
2722 WriteEndAttributes();
2734 double x = -width / 2;
2735 double y = -height / 2;
2737 WriteStartElementAttributes( _T(
"image" ) );
2738 WriteAttribute( _T(
"x" ), x );
2739 WriteAttribute( _T(
"y" ), y );
2740 WriteAttribute( _T(
"width" ), width );
2741 WriteAttribute( _T(
"height" ), height );
2742 WriteAttribute( _T(
"xlink:href" ), obj->
GetFilename() );
2743 WriteEndAttributes();
2755 wxString fontFamily =
2756 ( font.
GetName().Length() > 0 )
2758 : _T(
"Verdana, LiberationSans, sans-serif" );
2760 wxString fontStyleBold =
2761 ( font.
GetStyle().Lower().Find( _T(
"bold" ) ) != -1 )
2762 ? _T(
"font-weight:bold; " )
2763 : ( font.
GetStyle().Lower().Find( _T(
"light" ) ) != -1 )
2764 ? _T(
"font-weight:lighter; " )
2767 wxString fontStyleItalic =
2768 ( font.
GetStyle().Lower().Find( _T(
"italic" ) ) != -1 )
2769 ? _T(
"font-style:italic; " )
2770 : ( font.
GetStyle().Lower().Find( _T(
"slant" ) ) != -1 )
2771 ? _T(
"font-style:oblique; " )
2775 wxString alignmentH =
2782 wxString alignmentV =
2793 _T(
"font-family:%s; " )
2794 _T(
"font-size:%fpt; " )
2796 _T(
"stroke:#%s; " )
2797 _T(
"text-anchor:%s; " )
2798 _T(
"baseline-shift:%s; " )
2802 #if wxCHECK_VERSION(2, 9, 0)
2803 color.GetData().AsChar(),
2804 color.GetData().AsChar(),
2805 alignmentH.GetData().AsChar(),
2806 alignmentV.GetData().AsChar(),
2807 fontStyleBold.GetData().AsChar(),
2808 fontStyleItalic.GetData().AsChar()
2814 fontStyleBold.c_str(),
2815 fontStyleItalic.c_str()
2819 WriteStartElementAttributes( _T(
"text" ) );
2820 WriteAttribute( _T(
"x" ), 0 );
2821 WriteAttribute( _T(
"y" ), 0 );
2822 WriteAttribute( _T(
"style" ), s );
2823 WriteEndAttributes();
2828 WriteContent( obj->
GetText() );
2838 if ( obj->
GetSpline() && ( points->size() > 2 ) )
2840 CreateSVGSpline ( points );
2846 WriteStartElementAttributes( _T(
"polyline" ) );
2848 WriteAttribute( _T(
"style" ), _T(
"fill:none;" ) );
2849 EndlWriteString( _T(
" points=\"" ) );
2854 a2dVertexList::iterator iter = points->begin();
2855 iter != points->end();
2860 s.Printf ( _T(
"%f,%f " ), point->
m_x, point->
m_y );
2867 EndlWriteString( _T(
"\"" ) ) ;
2868 WriteEndAttributes();
2878 if ( obj->GetBegin() )
2880 a2dVertexList::iterator iter = points->begin();
2886 dx = point2->
m_x - point1->
m_x;
2887 dy = point2->
m_y - point1->
m_y;
2897 lworld.
Scale( xscale, yscale, 0, 0 );
2901 WriteStartElementAttributes( _T(
"g" ) );
2902 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
2907 WriteAttribute( _T(
"transform" ), s );
2908 WriteEndAttributes();
2910 Save( obj->GetBegin(), layer );
2915 if ( obj->GetEnd() )
2917 a2dVertexList::reverse_iterator iter = points->rbegin();
2923 dx = point2->
m_x - point1->
m_x;
2924 dy = point2->
m_y - point1->
m_y;
2933 lworld.
Scale( xscale, yscale, 0, 0 );
2937 WriteStartElementAttributes( _T(
"g" ) );
2938 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
2943 WriteAttribute( _T(
"transform" ), s );
2944 WriteEndAttributes();
2946 Save( obj->GetEnd(), layer );
2958 wxPolygonFillMode fillStyle = wxWINDING_RULE;
2959 if ( fillStyle == wxODDEVEN_RULE )
2960 s = _T(
"fill-rule:evenodd; " );
2962 s = _T(
"fill-rule:nonzero; " );
2964 if ( obj->
GetSpline() && ( points->size() > 2 ) )
2966 CreateSVGSpline( points,
true, s );
2970 WriteStartElementAttributes( _T(
"polygon" ) );
2972 WriteAttribute( _T(
"style" ), s );
2974 EndlWriteString( _T(
" points=\"" ) );
2979 a2dVertexList::iterator iter = points->begin();
2980 iter != points->end();
2987 s.Printf ( _T(
"%f,%f " ), seg->
m_x, seg->
m_y );
2991 WriteString( _T(
"\"" ) ) ;
2993 WriteEndAttributes();
3002 WriteStartElementAttributes( _T(
"path" ) );
3003 WriteString( _T(
" d=\"" ) );
3006 for ( i = 0; i < obj->
GetCount(); i++ )
3014 s.Printf ( _T(
"M %f %f " ), seg->
m_x1, seg->
m_y1 );
3019 s.Printf ( _T(
"L %f %f " ), seg->
m_x1, seg->
m_y1 );
3025 s.Printf ( _T(
"L %f %f " ), seg->
m_x1, seg->
m_y1 );
3045 s.Printf ( _T(
"T %f %f %f %f " ), cseg->
m_x2, cseg->
m_y2, cseg->
m_x1, cseg->
m_y1 );
3051 s.Printf ( _T(
"T %f %f %f %f " ), cseg->
m_x2, cseg->
m_y2, cseg->
m_x1, cseg->
m_y1 );
3059 s.Printf ( _T(
"T %f %f %f %f " ), cseg->
m_x2, cseg->
m_y2, cseg->
m_x1, cseg->
m_y1 );
3066 s.Printf ( _T(
"T %f %f %f %f " ), cseg->
m_x2, cseg->
m_y2, cseg->
m_x1, cseg->
m_y1 );
3079 WriteString( _T(
" Z" ) );
3085 WriteString( _T(
" Z" ) );
3096 WriteString( _T(
"\"" ) ) ;
3097 WriteEndAttributes();
3113 WriteStartElement( _T(
"defs" ) );
3114 WriteStartElementAttributes( _T(
"clipPath" ) );
3122 if ( !lworld.IsIdentity() )
3124 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
3125 lworld.GetValue( 0, 0 ), lworld.GetValue( 0, 1 ),
3126 lworld.GetValue( 1, 0 ), lworld.GetValue( 1, 1 ),
3127 lworld.GetValue( 2, 0 ), lworld.GetValue( 2, 1 )
3129 WriteAttribute( _T(
"transform" ), s );
3133 WriteEndAttributes();
3145 DoSave( ( *iter ), layer );
3152 if ( prop->GetVisible() )
3160 property->GetCanRender() &&
property->GetVisible() )
a2dCanvasObject * GetCanvasObject()
set check on a2dObject flag false or true
a2dCircle at x,y, and with radius
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
a2dAffineMatrix & Mirror(bool y=true, bool x=false)
mirror a matrix in x, y
For exceptions thrown while parsing XML files.
(In) Visible property that can be added to Docview Objects.
double GetEndScaleY()
scale begin and end object with this factor in X
double GetWidth() const
get width of image
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Base class for all types of strokes, understood by a2dDrawer2D classes.
double GetPosX2(bool transform=true) const
Get (transformed) position of X2.
a2dCanvasObjectReference is a reference to any a2dCanvasObject derived class.
const wxString & GetName() const
Get name of font, e.g. Arial.
virtual bool IsTemporary_DontSave() const
Check if this is a temporary object, which should not be saved.
virtual wxString GetName() const
Returns the name of this object, if no name is given the internal id will be returned.
double GetWidth() const
return width
Font info class, used as a single element for enumerating fonts.
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
void SetDescription(const wxString &desc)
Sets a description of the document.
a2dPoint2D GetStop() const
Get stop for gradient fill colour change.
const a2dFill * a2dINHERIT_FILL
global a2dFill stock object for INHERTED from parent object filling
Creates a shadow behind a a2dCanvasObject when added as property.
wxColour GetColour2() const
return colour 2
View on a a2dCanvasDocument.
void SetRadius(double radius)
set radius
double GetRadius() const
return radius
polygon defined with list of points.
size_t GetCount()
Return the number of segments.
void SetTransformMatrix(const a2dAffineMatrix &mat=a2dIDENTITY_MATRIX)
Returns the matrix used to position the object.
bool Rotate(double angle)
Rotate clockwise by the given number of degrees:
double GetRadius() const
return radius
double wxDegToRad(double deg)
conversion from degrees to radians
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
double GetY2() const
Get Y2 of arc being end point of arc.
double m_y3
control point 2
double GetBase()
return how broad the basis of the arrow is.
bool IsIdentity(void) const
Is the matrix the identity matrix?
double m_x3
control point 2
double GetRadius() const
Get stop for gradient fill colour change.
bool GetPixelStroke() const
if the width is pixels or not.
wxString A2DGENERALDLLEXP ColourToHex(const wxColour &colour)
RGB to 3-digit hex.
double GetValue(int col, int row) const
get the value in the matrix at col,row
wxUint32 GetStamp() const
time stamp gradient fill
a2dRectC is a centered rectangle
void SetFilename(const wxString filename, wxBitmapType type, bool doread=true)
set filename and type of image for saving.
bool SkewX(double degrees)
Skew Xaxis:
double GetWidth() const
return width
a2dCanvasObject * GetEnd()
dummies to be compatible with a2dEndsLine
vertex array of line and arc segments.
a2dCanvasObject is the base class for Canvas Objects.
void SetFillRule(wxPolygonFillMode val)
Set Polygon filling mode wxODDEVEN_RULE or wxWINDING_RULE.
wxColour GetColour() const
return colour 1
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
double m_y2
control point 1
property to hold a a2dObjectPtr smart pointer type variable to be associated with a a2dObject ...
Docview framework its controlling class.
a2dCanvasObjectArrayReference is an array of a reference to any a2dCanvasObject derived class...
a2dPATHSEG_END GetClose() const
is this segment the closing a part since the last move
virtual a2dObject * GetRefObject() const
when a2dProperty, return its value else assert
void SetWidth(double w)
set width of rectangle
a2dPATHSEG m_type
easy way to test type of segment
a2dCanvasObjectList * GetChildObjectList()
get the list where the child objects are stored in.
vertex list of line and arc segments.
bool ParseSvgStyle(a2dCanvasObject *parent)
bool GetVisible()
is the layer visible
double GetStart()
return start angle
a2dFont GetFont() const
get font for text
virtual a2dObject * GetRefObject() const
when a2dProperty, return its value else assert
void SetHeight(double h)
set height of rectangle
a2dText is an abstract base class.
a2dCanvasObjectList * wxNullCanvasObjectList
define a NON a2dCanvasObjectList
double GetWidth()
return width
double m_y2
second control point
a2dOrigin stays at World Coordinate Zero (0,0) not matter what.
#define forEachIn(listtype, list)
easy iteration for a2dlist
a2dEllipse centered at x,y.
polyline defined with list of points.
double GetL2()
return Distance from top to the inside of the arrow.
const a2dError a2dError_XMLparse
a2dPoint2D GetStart() const
Get start for gradient fill colour change.
Normal straight line segment in a2dVpath.
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
a2dPoint2D GetCenter() const
Get start for gradient fill colour change.
a2dVertexListPtr GetSegments()
Get the list of points ( this is not a copy! )
a2dImage (will scale/rotate image when needed)
double wxRadToDeg(double rad)
conversion from radians to degrees
Normal straight line segment in a2dVertexList and a2dVertexArray.
virtual a2dPolygonL * GetClipObject() const
return a2dPolygonL that is used for clipping
double GetL1()
Returns the arrow length.
bool ParsePathPoints(a2dVpath *points)
void CreateSVGSpline(const a2dVertexList *vertexList, bool asPolygon=false, const wxString &style=_T(""))
Generates a quadratic spline path in SVG from a set of points representing the control polygon...
void SetTextHeight(double height)
set text height in world coordinates
void Translate(double x, double y)
relative translate the object to position x,y in world coordinates
void DoSave(const a2dCanvasObject *object, int layer)
Generates SVG XML code for different types of canvas objects.
bool SkewY(double degrees)
Skew Yaxis:
wxUint16 GetLayer() const
Returns the layer index where this object is drawn upon.
const a2dFill & GetFill() const
contains the layer properties for one layer,
const a2dStroke * a2dINHERIT_STROKE
global a2dStroke stock object for INHERTED from parent object stroking
double GetTextHeight() const
get text height in world coordinates
bool CanSave(const wxObject *obj=NULL)
Should return true if the handler can write this document to a stream.
a2dPoint2D GetFocal() const
Get start for gradient fill colour change.
const a2dFill * a2dNullFILL
global a2dFill stock object for defining NO filling
WX_DECLARE_STRING_HASH_MAP(a2dPropertyId *, a2dPropertyIdHashMap)
Declaration of the hash map type to convert prop names to prop id objects.
double GetPosY2(bool transform=true) const
Get (transformed) position of Y2.
bool GetSpline()
Get the polygon spline setting.
bool Identity(void)
Make into identity matrix.
a2dArrow is used for having line begin and ends on specific objects.
void SetWidth(double width)
set width
double GetX1() const
Get X1 of arc being begin point of arc.
double m_x2
control point 1
A 2x3 affine matrix class for 2D transformations.
a2dView * GetCurrentView() const
return the one that is active right now (e.g. has focus in case of a wxWindow), or NULL ...
const a2dStroke * a2dNullSTROKE
global a2dStroke stock object for NO stroking
wxString & GetFilename()
get filename
double GetPosX1(bool transform=true) const
Get (transformed) position of X1.
virtual a2dLineSegment * Clone()
create exact copy
while iterating a a2dCanvasDocument, this holds the context.
wxInputStream a2dDocumentInputStream
input stream based wxStreams
double m_x
x endpoint of line
virtual bool CanLoad(a2dDocumentInputStream &stream, const wxObject *obj=NULL, wxClassInfo *docClassInfo=NULL)
Should return true if the handler can read from the stream.
double m_y
y endpoint of line
a2dDocviewGlobal * a2dDocviewGlobals
a global pointer to get to global instance of important classes.
void SetStroke(const wxColour &strokecolor, double width=0, a2dStrokeStyle style=a2dSTROKE_SOLID)
Set a stroke for the object which will be used instead of the layer stroke.
double GetHeight() const
get height of image
std::vector< a2dLayerInfoPtr > & GetReverseOrderIndex()
return array index on ReverseOrder
void SetHeight(double height)
set height
Clipping Path property that can be added to a2dCanvasObject's.
void SetText(const wxString &text)
set the text for the object ' ' in string means new line
Each a2dCanvasView needs to have a a2dCanvasDocument set in order to render data. ...
virtual bool Load(a2dDocumentInputStream &stream, wxObject *doc)
override to read the stream and store (part of) the contents in to a specific a2dDocument or othere o...
double m_y1
y endpoint of line
a2dEndsLine with begin and/or end object.
a2dCanvasObject * GetBegin()
dummies to be compatible with a2dEndsLine
const wxString & GetStyle() const
Get style of font, e.g. Bold.
return to contain children bbox
wxColour GetColour() const
return colour
bool Scale(double scale)
Scale by scale (isotropic scaling i.e. the same in x and y):
bool Translate(double x, double y)
Translate by dx, dy:
const a2dStroke & GetStroke() const
virtual void ReportErrorF(const a2dError &error, const wxChar *Format,...)
concatenate to the the error report the given error.
const a2dStroke * a2dTRANSPARENT_STROKE
global a2dStroke stock object for TRANSPARENT stroking
double GetRadius() const
return radius
a2dDocumentCommandProcessor * GetDocviewCommandProcessor() const
Gets a2dDocumentCommandProcessor pointer.
double GetEndScaleX()
scale begin and end object with this factor in X
const a2dNamedPropertyList & GetPropertyList() const
Get the Property List.
std::vector< a2dLayerInfoPtr > & GetOrderIndex()
return array index on Order
void SetTitle(const wxString &title, bool notifyViews=false)
Sets the title for this document.
double GetX2() const
Get X2 of arc being end point of arc.
double GetEnd()
return end angle
void SetValue(int col, int row, double value)
set the value in the matrix at col,row
double m_x1
x endpoint of line
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *doc)
Override to write to the stream and store (part of) of the document contents in the stream...
a2dVpath * GetSegments()
modify point at index to x,y
all headers of the canvas module
double GetY1() const
Get Y1 of arc being begin point of arc.
a2dCanvasObject for a Vector Path
int GetAlignment() const
Get the position of the anchor point w.r.t the text.
double GetPosY1(bool transform=true) const
Get (transformed) position of Y1.
const a2dFontInfo & GetFontInfo() const
Get fontinfo of the font.
void SetRotation(double rotation)
set rotation
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
double GetHeight() const
return height
wxString GetText() const
get the text of the object ' ' in string means new line
bool Start(a2dObject *object)
start removing properties from the object given, and down.
double GetHeight() const
return height
double m_x2
second control point
const double wxPI
defines PI
wxInt64 GetUniqueSerializationId() const
return a unique id for this object
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
a2dEllipticArc centered at x,y
double GetHeight()
return height
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling