// $Id$ /* mkhexgrid -- generates hex grids * Copyright (C) 2006 Joel Uckelman * * This program 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. * * This program 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 this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include using namespace std; #include "grid.h" ofstream out; void Grid::draw_svg() { if (outfile.empty() || outfile == "-") out.ostream::rdbuf(cout.rdbuf()); else { filebuf *buf = new filebuf; buf->open(outfile.c_str(), ios::out | ios::binary); out.ostream::rdbuf(buf); if (!out) throw runtime_error("cannot write to " + outfile); } // write header out << "\n" "\n" "\n"; // write definitions for repeated elements out << "\n"; // center definition if (center_style != Centerless) { switch (center_style) { case Cross: out << "\n"; out << "\n"; for (int c = 0; c < cols; ++c) { out << "\n"; } out << "\n"; break; case Dot: out << "\n"; for (int c = 0; c < cols; ++c) { out << "\n"; } out << "\n"; break; default: break; } } // grid definition if (lowfirstcol == true) { out << "\n"; out << "\n"; out << "\n"; } else { out << "\n"; out << "\n"; out << "\n"; } out << "\n"; // draw background if (!bg_color.empty()) { out << "\n"; } out << "\n"; } else { out << mleft+grid_thickness/2 << ',' << mtop+grid_thickness/2 << ")\">\n"; } // draw grid out << "\n"; if (lowfirstcol == true) { double x = 0.25*hw, y = 0.5*hh; out << "\n"; for (int r = 0; r < rows - 1; ++r) { x = 0.75*hw; out << "\n"; x = 0.25*hw; y += hh; out << "\n"; } x = 0.75*hw; out << "\n"; } else { double x = 0, y = 0.5*hh; out << "\n"; y = hh; for (int r = 0; r < rows - 1; ++r) { x = 0.75*hw; out << "\n"; x = 0.25*hw; out << "\n"; y += hh; } x = 0.75*hw; out << "\n"; } out << "\n"; // draw centers if (center_style != Centerless) { out << "\n"; for (int r = 0; r < rows; ++r) out << "\n"; out << "\n"; } if (coord_display) { // draw coordinates out << "\n"; // NB: CSS requires that font-size have some unit double bcos = cos(coord_bearing*rad), bsin = sin(coord_bearing*rad); for (int r = 0; r < rows; ++r) { if ((r+coord_rstart) % coord_rskip) continue; for (int c = 0; c < cols; ++c) { if ((c+coord_cstart) % coord_cskip) continue; int cc = 0, cr = 0; switch (coord_origin) { case UpperLeft: cc = c+coord_cstart; cr = r+coord_rstart; break; case UpperRight: cc = cols-c-1+coord_cstart; cr = r+coord_rstart; break; case LowerLeft: cc = c+coord_cstart; cr = rows-r-1+coord_rstart; break; case LowerRight: cc = cols-c-1+coord_cstart; cr = rows-r-1+coord_rstart; break; } int a = cc, b = cr; if (coord_order == RowsFirst) swap(a, b); ostringstream s; s << coord_fmt_pre; switch (coord_first_style) { case NoCoord: break; case Number: if (coord_first_width) s << setw(coord_first_width); if (coord_first_fill) s << setfill('0'); s << a; break; case Alpha: s << alpha(a); break; case AlphaTally: s << alpha_tally(a); break; } s << coord_fmt_inter; switch (coord_second_style) { case NoCoord: break; case Number: if (coord_second_width) s << setw(coord_second_width); if (coord_second_fill) s << setfill('0'); s << b; break; case Alpha: s << alpha(b); break; case AlphaTally: s << alpha_tally(b); break; } double x = (c*0.75 + 0.5)*hw+coord_dist*bcos; double y = (r + 0.5*(1 + (c+lowfirstcol)%2))*hh+coord_dist*bsin; out << "' << s.str() << "\n"; } } out << "\n"; } out << "\n"; out << "" << endl; if (!outfile.empty()) out.close(); } void Grid::side_path_svg(int n) { switch (n % 4) { case 0: out << ' ' << 0.25*hw << ' ' << 0.5*hh; break; case 2: out << ' ' << 0.25*hw << ' ' << -0.5*hh; break; case 1: case 3: out << ' ' << 0.5*hw << " 0"; break; } } void Grid::side_path_reverse_svg(int n) { switch (n % 4) { case 0: out << ' ' << -0.25*hw << ' ' << 0.5*hh; break; break; case 2: out << ' ' << -0.25*hw << ' ' << -0.5*hh; break; case 1: case 3: out << ' ' << -0.5*hw << " 0"; break; } } void Grid::side_skip_path_svg(int n) { switch (n % 4) { case 0: out << " l " << 0.25*hw << ' ' << 0.5*hh; break; case 2: out << " l " << 0.25*hw << ' ' << -0.5*hh; break; case 1: case 3: out << " m " << 0.5*hw << " 0"; break; } } void Grid::edge_path_svg(int n) { out << ' ' << (n % 2 ? 0.25 : -0.25)*hw << ' ' << 0.5*hh; } void Grid::edge_path_reverse_svg(int n) { out << ' ' << (n % 2 ? 0.25 : -0.25)*hw << ' ' << -0.5*hh; }