diff options
Diffstat (limited to 'dviware/dvi2bitmap/DviFilePosition.cc')
-rw-r--r-- | dviware/dvi2bitmap/DviFilePosition.cc | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/dviware/dvi2bitmap/DviFilePosition.cc b/dviware/dvi2bitmap/DviFilePosition.cc new file mode 100644 index 0000000000..9c4c3e19d4 --- /dev/null +++ b/dviware/dvi2bitmap/DviFilePosition.cc @@ -0,0 +1,161 @@ +/* This file is part of dvi2bitmap; see README for copyrights and licence */ + + +#include <config.h> +#include <iostream> +using STD::cerr; +using STD::endl; + +#include "DviFilePosition.h" + +// Static variables +verbosities DviFilePosition::verbosity_ = normal; + + +/** + * Create a new marked position in a DVI file. + * @param f the DVI file of interest + * @param x the x-coordinate of the position + * @param y the y-coordinate of the position + * @param u the units of the (x,y) position + */ +DviFilePosition::DviFilePosition(DviFile* f, + double x, double y, + DviFile::DviUnits u) +{ + // Hrumph. Initialise the y coordinate as one less than the one + // passed in. I don't have a good explanation of why I'm doing + // this, except that if I don't, then the last test in t8.pl + // doesn't work, because the reported mark positions are 0.0001 + // pixels `too large', which ends up with them being rounded to 31 + // rather than 30. This is doubtless some variant of the question + // of whether pixel centres are at integer or half-integer + // coordinates, and may be related, in some weird way which spans + // 4 orders of magnitude!) to the dithering in Bitmap.cc about the + // offset of +1 added to the reported mark position. [there's a + // reference to this text in t8.pl.in comments, so change both together] + + dvif = f; + this->x = DviFile::convertToScaledPoints(x, u, dvif); + this->y = DviFile::convertToScaledPoints(y, u, dvif) - 1; + if (verbosity_ > normal) + cerr << "New mark at (" + << DviFile::convertFromScaledPoints(this->x, + DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(this->y, + DviFile::unit_pixels, dvif) + << ")px" << endl; +} +/** + * Create a new marked position in a DVI file. + * @param dvifp use the DVI file referred to by this class + * @param x the x-coordinate of the position + * @param y the y-coordinate of the position + * @param u the units of the (x,y) position + */ +DviFilePosition::DviFilePosition(DviFilePosition* dvifp, + double x, double y, + DviFile::DviUnits u) +{ + dvif = dvifp->dvif; + this->x = DviFile::convertToScaledPoints(x, u, dvif); + this->y = DviFile::convertToScaledPoints(y, u, dvif) - 1; +} +/** + * Retrieve the x-coordinate of this position. + * @param u express the answer in these units + * @return the x-coordinate in the required units + */ +double DviFilePosition::getX(DviFile::DviUnits u) +{ + return DviFile::convertFromScaledPoints(x, u, dvif); +} +/** + * Retrieve the y-coordinate of this position. + * @param u express the answer in these units + * @return the y-coordinate in the required units + */ +double DviFilePosition::getY(DviFile::DviUnits u) +{ + return DviFile::convertFromScaledPoints(y, u, dvif); +} +/** + * Shift the mark position by the given amount + * @param dx the amount to shift in the x direction + * @param dy the amount to shift in the y direction + * @param u the units in which dx and dy are expressed + */ +void DviFilePosition::shift(double dx, double dy, DviFile::DviUnits u) +{ + if (verbosity_ > normal) + cerr << "shift(" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif); + x += DviFile::convertToScaledPoints(dx, u, dvif); + y += DviFile::convertToScaledPoints(dy, u, dvif); + if (verbosity_ > normal) + cerr << ")px -> (" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif) + << ")px" << endl; +} + +/** + * Scale the position by the given factor. The scaling is done in + * such a way that the coordinate <em>(0,0)</em> remains `fixed'. + * @param factor a scaling factor, by which all distances are multiplied + */ +void DviFilePosition::scale(double factor) +{ + if (verbosity_ > normal) + cerr << "scale(" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif); + x = static_cast<int>(x * factor + 0.5); + y = static_cast<int>(y * factor + 0.5); + if (verbosity_ > normal) + cerr << ")px -> (" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif) + << ")px" << endl; +} +#if 0 +// redundant method, but still potentially useful (and apparently correct) +/** + * Scale the position by the given factor. The scaling is done in + * such a way that it is the distance between the marked position and + * the fixed point that is scaled + * @param scale a scaling factor, by which all distances are multiplied + * @param fixed_point the fixed point in the scaling operation + */ +void DviFilePosition::scale(double factor, DviFilePosition& fixed_point) +{ + if (verbosity_ > normal) + cerr << "scale(" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif); + x = static_cast<int>(fixed_point.x + (x - fixed_point.x)*factor + 0.5); + y = static_cast<int>(fixed_point.y + (y - fixed_point.y)*factor + 0.5); + if (verbosity_ > normal) + cerr << ")px -> (" + << DviFile::convertFromScaledPoints(x, DviFile::unit_pixels, dvif) + << ',' + << DviFile::convertFromScaledPoints(y, DviFile::unit_pixels, dvif) + << ")px" << endl; +} +#endif + +/** + * Return a copy of the object + */ +DviFilePosition* DviFilePosition::copy() +{ + return new DviFilePosition(dvif, x, y, DviFile::unit_sp); +} + |