diff options
Diffstat (limited to 'graphics/epix/eepic.cc')
-rw-r--r-- | graphics/epix/eepic.cc | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/graphics/epix/eepic.cc b/graphics/epix/eepic.cc new file mode 100644 index 0000000000..eaed35a653 --- /dev/null +++ b/graphics/epix/eepic.cc @@ -0,0 +1,297 @@ +/* + * eepic.cc -- ePiX's eepic output format + * + * This file is part of ePiX, a C++ library for creating high-quality + * figures in LaTeX + * + * Version 1.2.0-2 + * Last Change: September 26, 2007 + */ + +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Andrew D. Hwang <rot 13 nujnat at zngupf dot ubylpebff dot rqh> + * Department of Mathematics and Computer Science + * College of the Holy Cross + * Worcester, MA, 01610-2395, USA + */ + +/* + * ePiX 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. + * + * ePiX 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 ePiX; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <cmath> +#include <list> + +#include <string> +#include <sstream> + +#include <set> // for pallet + +#include "constants.h" + +#include "functions.h" + +#include "pairs.h" +#include "edge_data.h" + +#include "Color.h" + +#include "path_style.h" +#include "pen_data.h" + +#include "hatching.h" + +#include "format.h" +#include "eepic.h" + +namespace ePiX { + + // rotate successive hatches this much to avoid parallelity + const double d_hatch_theta(111.24612); // ~90*(sqrt(5)-1) + + eepic::eepic() + : m_ink(Black()), m_nib(PLAIN_WIDTH), m_hatch(0) { } + + eepic* eepic::clone() const + { + return new eepic(*this); + } + + // Filled region with specified Cartesian edges, offset, and color + std::string eepic::print_fill(const std::list<edge2d>& edges, + const pair& offset, + const Color& fc, + const pen_data& line, + const std::string& len) const + { + std::stringstream obuf; + + // set angle + const double hatch_angle(m_hatch); + m_hatch += d_hatch_theta; + + // draw hatch lines separated by pen.width(), actual line width + // scaled by density + double dens(fc.alpha()); // transparency + if (dens < EPIX_EPSILON) + return ""; + + // else + length hatch_width(length(PLAIN_WIDTH).to(len)); + + path_state style; // solid + + if (EPIX_EPSILON < dens*hatch_width.magnitude()) + { + // Use fill color, draw thin lines to simulate transparency. + // Area covered by double-hatching is (supposed to be) dens. + pen_data fill_pen(fc, (1-sqrt(1-dens))*hatch_width); + + // draw hatch-filled edges + hatch_data bd1(hatch_angle, hatch_width.magnitude(), edges); + for (unsigned int i=0; i < bd1.data().size(); ++i) + obuf << format::print_line(bd1.data().at(i), offset, + fill_pen, style, std::string(""), len); + + // re-draw hatch lines at right angles... + hatch_data bd2(hatch_angle+90, hatch_width.magnitude(), edges); + for (unsigned int i=0; i < bd2.data().size(); ++i) + obuf << format::print_line(bd2.data().at(i), offset, + fill_pen, style, "", len); + } + + obuf << set_pen_state(line); + obuf << print_paths(edges, offset, "", len); + + return obuf.str(); + } // end of eepic::print_fill() + + + // may assume line is visible + std::string eepic::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) const + { + std::string value; + + // draw *solid* base first if necessary + if (line.width() < base.width() && !base.color().is_unset()) + value += format::print_line(edges, offset, base, path_state(), "", len); + + return value += format::print_line(edges, offset, line, style, "", len); + } + + + std::string eepic::print_color(const std::string& model, + const std::string& name, + double d1, double d2, double d3) const + { + return format::xdefinecolor(model, name, d1, d2, d3); + } + + std::string eepic::print_color(const std::string& model, + const std::string& name, + double d1, double d2, + double d3, double d4) const + { + return format::xdefinecolor(model, name, d1, d2, d3, d4); + } + + // one-line comment + std::string eepic::print_comment(const std::string& msg) const + { + std::stringstream obuf; + obuf << "%% " << msg << std::endl; + + return obuf.str(); + } + + // verbatim string, newline protected + std::string eepic::print_verbatim(const std::string& msg) const + { + std::stringstream obuf; + obuf << msg << "%" << std::endl; + + return obuf.str(); + } + + void eepic::reset_state() const + { + m_ink = Neutral(); + m_nib = length(0); + } + + + //// private member functions //// + std::string eepic::start_picture(const pair& sz, const pair& offset) const + { + std::stringstream obuf; + obuf << "\\begin{picture}" + << format::print(sz) << format::print(-offset) << "%" << std::endl; + + return obuf.str(); + } + + std::string eepic::end_picture() const + { + std::stringstream obuf; + obuf << "\\end{picture}%" << std::endl; + return obuf.str(); + } + + std::string eepic::set_unitlength(const std::string& len) const + { + std::stringstream obuf; + + obuf << "\\setlength{\\unitlength}{1" << len << "}%" << std::endl; + + return obuf.str(); + } + + + std::string eepic::usepackages() const + { + return "usepackages epic,eepic,xcolor"; + } + + // string argument for passing attributes local to this path/loop + std::string eepic::start_open_path(const std::string& attribs) const + { + return "\\path"; + } + + std::string eepic::end_open_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string eepic::start_closed_path(const std::string& attribs) const + { + return "\\path"; + } + + std::string eepic::end_closed_path(const std::string& attribs) const + { + std::stringstream obuf; + obuf << std::endl; + return obuf.str(); + } + + std::string eepic::set_fill_state(const Color& col) const // unused + { + std::stringstream obuf; + + if (m_ink != col) + { + m_ink = col; + obuf << "\\color{" << m_ink.name() << "}%" << std::endl; + } + + return obuf.str(); + } + + std::string eepic::set_pen_state(const pen_data& pen) const + { + std::stringstream obuf; + + if (m_nib != pen.width()) + { + m_nib = pen.width(); + obuf << "\\allinethickness{" << m_nib.name() << "}%" << std::endl; + } + + if (m_ink != pen.color()) + { + m_ink = pen.color(); + obuf << "\\color{" << m_ink.name() << "}%" << std::endl; + } + + return obuf.str(); + } + + // place a LaTeX box of width zero (containing string) at location (pair) + std::string eepic::put_box(const pair& loc, const std::string& msg) const + { + std::stringstream obuf; + obuf << "\\put" << print(loc) << "{" << msg << "}" << std::endl; + + return obuf.str(); + } + + std::string eepic::print_circle_marker(const pair& here, double diam, + bool fill, const Color& color, + const std::string& len) const + { + std::stringstream obuf; + obuf << "\\put" << print(here) + << "{\\color{" << print(color) << "}$"; + + if (fill) + obuf << "\\allinethickness{" << 0.5*diam << len << "}" + << "\\circle{" << 0.5*diam << "}"; + + else + obuf << "\\circle{" << diam << "}"; + + obuf << "$}%" << std::endl; + + return obuf.str(); + } +} // end of namespace |