1 /* 2 * tikz.cc -- ePiX::tikz output format 3 * 4 * This file is part of ePiX, a C++ library for creating high-quality 5 * figures in LaTeX 6 * 7 * Version 1.1.15 8 * Last Change: September 07, 2007 9 * 10 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 11 * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> 12 * Department of Mathematics and Computer Science 13 * College of the Holy Cross 14 * Worcester, MA, 01610-2395, USA 15 * 16 * 17 * ePiX is free software; you can redistribute it and/or modify it 18 * under the terms of the GNU General Public License as published by 19 * the Free Software Foundation; either version 2 of the License, or 20 * (at your option) any later version. 21 * 22 * ePiX is distributed in the hope that it will be useful, but WITHOUT 23 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 25 * License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with ePiX; if not, write to the Free Software Foundation, Inc., 29 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 30 */ 31 32 #include <list> 33 34 #include <string> 35 #include <sstream> 36 37 #include <set> 38 39 #include "constants.h" 40 41 #include "utils.h" 42 43 #include "pairs.h" 44 #include "edge_data.h" 45 46 #include "Color.h" 47 48 #include "path_style.h" 49 #include "pen_data.h" 50 51 // need to get units from the_picture 52 #include "picture_data.h" 53 #include "picture.h" 54 55 #include "format.h" 56 #include "tikz.h" 57 58 namespace ePiX { 59 tikz()60 tikz::tikz() 61 : m_fill(Neutral()), m_stroke(Black()), m_lwidth(PLAIN_WIDTH), 62 m_units(the_picture().the_unitlength.units()) { } 63 64 clone() const65 tikz* tikz::clone() const 66 { 67 return new tikz(*this); 68 } 69 70 // Filled region with specified Cartesian edges, offset, and color print_fill(const std::list<edge2d> & edges,const pair & offset,const Color & fc,const pen_data & line,const std::string & len) const71 std::string tikz::print_fill(const std::list<edge2d>& edges, 72 const pair& offset, 73 const Color& fc, 74 const pen_data& line, 75 const std::string& len) const 76 { 77 std::stringstream obuf; 78 obuf << set_fill_state(fc) << set_pen_state(line); 79 80 // compute attribute string 81 std::stringstream attribs; 82 83 if ( !(fc.is_unset()) ) 84 { 85 attribs << "[fill"; 86 87 if (fc.alpha() < 1) 88 attribs << ",opacity=" << fc.alpha(); 89 90 attribs << "]"; 91 } 92 93 obuf << print_paths(edges, offset, attribs.str(), len); 94 95 return obuf.str(); 96 } 97 98 // Unfilled region, specified Cartesian edges print_line(const std::list<edge2d> & edges,const pair & offset,const pen_data & line,const pen_data & base,const path_state & style,const std::string & len) const99 std::string tikz::print_line(const std::list<edge2d>& edges, 100 const pair& offset, 101 const pen_data& line, 102 const pen_data& base, 103 const path_state& style, 104 const std::string& len) const 105 { 106 std::string value; 107 108 // draw *solid* base first 109 if (line.width() < base.width() && !base.color().is_unset()) 110 { 111 std::stringstream battr; 112 battr << "[color=" << format::print(base.color()) << "," 113 << "line width=" << format::print(base.width()) << "]"; 114 115 value += format::print_line(edges, offset, base, path_state(), 116 battr.str(), len); 117 } 118 119 value += set_pen_state(line); 120 121 return value += format::print_line(edges, offset, line, style, "", len); 122 } 123 124 // Print color declaration strings: model, name, densities print_color(const std::string & model,const std::string & name,double d1,double d2,double d3) const125 std::string tikz::print_color(const std::string& model, 126 const std::string& name, 127 double d1, double d2, 128 double d3) const 129 { 130 return format::xdefinecolor(model, name, d1, d2, d3); 131 } 132 print_color(const std::string & model,const std::string & name,double d1,double d2,double d3,double d4) const133 std::string tikz::print_color(const std::string& model, 134 const std::string& name, 135 double d1, double d2, 136 double d3, double d4) const 137 { 138 return format::xdefinecolor(model, name, d1, d2, d3, d4); 139 } 140 141 142 // One-line comment print_comment(const std::string & msg) const143 std::string tikz::print_comment(const std::string& msg) const 144 { 145 std::stringstream obuf; 146 obuf << "%% " << msg << std::endl; 147 148 return obuf.str(); 149 } 150 151 // verbatim string, newline protected print_verbatim(const std::string & msg) const152 std::string tikz::print_verbatim(const std::string& msg) const 153 { 154 std::stringstream obuf; 155 obuf << msg << "%" << std::endl; 156 157 return obuf.str(); 158 } 159 160 161 // start/end a picture-like environment, set unit length start_picture(const pair & sz,const pair & offset) const162 std::string tikz::start_picture(const pair& sz, const pair& offset) const 163 { 164 std::stringstream obuf; 165 obuf << "\\begin{tikzpicture}" << std::endl 166 << "\\pgfsetlinewidth{" << format::print(PLAIN_WIDTH) << "}" 167 << std::endl 168 << "\\useasboundingbox " << print(offset) 169 << " rectangle " << print(sz + offset) << ";" 170 << std::endl; 171 172 return obuf.str(); 173 } 174 end_picture() const175 std::string tikz::end_picture() const 176 { 177 std::stringstream obuf; 178 obuf << "\\end{tikzpicture}" << std::endl; 179 180 return obuf.str(); 181 } 182 183 // Actual work done in start_picture set_unitlength(const std::string & len) const184 std::string tikz::set_unitlength(const std::string& len) const 185 { 186 return ""; 187 /* 188 std::stringstream obuf; 189 190 obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl; 191 192 return obuf.str(); 193 */ 194 } 195 196 reset_state() const197 void tikz::reset_state() const 198 { 199 m_fill = Neutral(); 200 m_stroke = Black(); 201 m_lwidth = PLAIN_WIDTH; 202 } 203 204 //// private member functions //// path_connector() const205 std::string tikz::path_connector() const 206 { 207 return "--"; 208 } 209 210 usepackages() const211 std::string tikz::usepackages() const 212 { 213 return "usepackages tikz"; 214 } 215 216 // string argument for passing attributes local to this path/loop start_open_path(const std::string & attribs) const217 std::string tikz::start_open_path(const std::string& attribs) const 218 { 219 return "\\draw " + attribs; 220 } 221 end_open_path(const std::string &) const222 std::string tikz::end_open_path(const std::string&) const 223 { 224 std::stringstream obuf; 225 obuf << ";" << std::endl; 226 227 return obuf.str(); 228 } 229 start_closed_path(const std::string & attribs) const230 std::string tikz::start_closed_path(const std::string& attribs) const 231 { 232 return "\\draw " + attribs; 233 } 234 end_closed_path(const std::string &) const235 std::string tikz::end_closed_path(const std::string&) const 236 { 237 std::stringstream obuf; 238 obuf << "--cycle;" << std::endl; 239 240 return obuf.str(); 241 } 242 243 // print declarations to set state of output format set_fill_state(const Color & col) const244 std::string tikz::set_fill_state(const Color& col) const 245 { 246 std::stringstream buf; 247 if (col != m_fill && !col.is_unset()) 248 buf << "\\pgfsetfillcolor{" << format::print(col) << "}" << std::endl; 249 250 m_fill = col; 251 return buf.str(); 252 } 253 set_pen_state(const pen_data & pen) const254 std::string tikz::set_pen_state(const pen_data& pen) const 255 { 256 std::stringstream buf; 257 if (pen.color() != m_stroke) 258 { 259 buf << "\\pgfsetstrokecolor{" << format::print(pen.color()) << "}" 260 << std::endl; 261 262 m_stroke = pen.color(); 263 } 264 265 if (pen.width() != m_lwidth) 266 { 267 buf << "\\pgfsetlinewidth{" << format::print(pen.width()) << "}" 268 << std::endl; 269 270 m_lwidth = pen.width(); 271 } 272 273 return buf.str(); 274 } 275 276 // place a LaTeX box of width zero (containing string) at location (pair) put_box(const pair & loc,const std::string & msg) const277 std::string tikz::put_box(const pair& loc, const std::string& msg) const 278 { 279 std::stringstream obuf; 280 281 obuf << "\\pgftext[at={\\pgfpoint{" 282 << truncate(loc.x1()) << m_units << "}{" 283 << truncate(loc.x2()) << m_units 284 << "}}] {" << msg << "}" << std::endl; 285 286 return obuf.str(); 287 } 288 print_circle_marker(const pair & here,double diam,bool fill,const Color & color,const std::string & len) const289 std::string tikz::print_circle_marker(const pair& here, double diam, 290 bool fill, const Color& color, 291 const std::string& len) const 292 { 293 std::stringstream obuf; 294 obuf << "\\"; 295 296 if (fill) 297 obuf << "fill"; 298 299 obuf << "draw[color=" << format::print(color) << "] " 300 << print(here) << " circle(" << 0.5*diam << len << ");" << std::endl; 301 302 return obuf.str(); 303 } 304 print(const pair & arg) const305 std::string tikz::print(const pair& arg) const 306 { 307 std::stringstream o; 308 o << "(" << truncate(arg.x1()) << m_units 309 << "," << truncate(arg.x2()) << m_units << ")"; 310 return o.str(); 311 } 312 } // end of namespace 313