1 // -*-c++-*-
2 
3 // fixg2sxd - a utility to convert fig to sxd format
4 
5 // Copyright (C) 2003-2010 Alexander Bürger, acfb@users.sourceforge.net
6 
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 #include "check.h"
22 #include "xfigobjects.h"
23 #include "misc.h"
24 #include "xmlwrite.h"
25 
26 #include <cmath>
27 
read(istream & figfile)28 istream& Arc::read( istream& figfile )
29 {
30     LineFillStyle lfstmp;
31     lfstmp.read( figfile, sub_type, depth );
32     figfile >> cap_style >> direction >> forward_arrow >> backward_arrow
33             >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
34 
35     keep_range( sub_type,  "arc sub_type",  1, 2 );
36     keep_range( cap_style, "arc cap_style", 0, 2 );
37     keep_range( direction, "arc direction", 0, 1 );
38     keep_range( forward_arrow,  "arc forward_arrow",  0, 1 );
39     keep_range( backward_arrow, "arc backward_arrow", 0, 1 );
40 
41     if( forward_arrow != 0 )
42         lfstmp.read_arrow( figfile, direction == 0 );
43     if( backward_arrow != 0 )
44         lfstmp.read_arrow( figfile, direction != 0 );
45     lfs = linefillstyles.insert( lfstmp ).first;
46     lfs->stylename();
47     lfs->stylename_line();
48     lfs->stylename_fill();
49 
50     return figfile;
51 }
52 
write(ostream & out)53 ostream& Arc::write( ostream& out )
54 {
55     float radius = sqrt( (center_x - x1)*(center_x - x1)
56                          + (center_y - y1)*(center_y - y1) );
57     // y increases to bottom => minus sign
58     float angle_start = -atan2( y1-center_y, x1-center_x ) * 180/M_PI;
59     float angle_end   = -atan2( y3-center_y, x3-center_x ) * 180/M_PI;
60     if( direction == 0 )
61         swap( angle_end, angle_start );
62     Node circle("draw:circle");
63     circle["draw:z-index"] << depth2z(depth);
64     circle["svg:x"] << tr(center_x-radius) << "cm";
65     circle["svg:y"] << tr(center_y-radius) << "cm";
66     //circle["svg:r"]  << tr(radius) << "cm";
67     circle["svg:width"]  << 2*tr(radius) << "cm";
68     circle["svg:height"]  << 2*tr(radius) << "cm";
69     circle["draw:start-angle"] << angle_start;
70     circle["draw:end-angle"]   << angle_end;
71     if( sub_type == 2 ) {
72         if( lfs->hasLine() || lfs->hasFill() ) {
73             circle["draw:style-name"] << lfs->stylename();
74             circle["draw:kind"] << "section";
75             out << circle;
76         }
77     } else {
78         if( lfs->hasFill() ) {
79             circle["draw:style-name"] << lfs->stylename_fill();
80             circle["draw:kind"] << "cut";
81             out << circle;
82         }
83         if( lfs->hasLine() ) {
84             circle["draw:style-name"] << lfs->stylename_line();
85             circle["draw:kind"] << "arc";
86             out << circle;
87         }
88     }
89     return out;
90 }
91