diff --git a/src/util/real_point.hpp b/src/util/real_point.hpp index 7a2e30fe..2655c5b7 100644 --- a/src/util/real_point.hpp +++ b/src/util/real_point.hpp @@ -99,6 +99,14 @@ class RealRect { inline RealRect(double x, double y, double w, double h) : position(x,y), size(w,h) {} + + inline operator wxRect() const { + return wxRect(position.x, position.y, size.width, size.height); + } + /// Return a rectangle that is amount larger to all sides + inline RealRect grow(double amount) { + return RealRect(position.x - amount, position.y - amount, size.width + 2 * amount, size.height + 2 * amount); + } }; // ----------------------------------------------------------------------------- : Operators diff --git a/src/util/rotation.cpp b/src/util/rotation.cpp index 7547bbf5..425ba334 100644 --- a/src/util/rotation.cpp +++ b/src/util/rotation.cpp @@ -7,6 +7,7 @@ // ----------------------------------------------------------------------------- : Includes #include +#include // ----------------------------------------------------------------------------- : Rotation @@ -43,7 +44,21 @@ RealSize Rotation::trNoNeg(const RealSize& s) const { } } RealRect Rotation::trNoNeg(const RealRect& r) const { - throw "TODO"; + RealSize s = (sideways() ? RealSize(r.size.height, r.size.width) : r.size) * zoom; + return RealRect(tr(r.position) - RealSize(revX()?s.width:0, revY()?s.height:0), s); +} +RealRect Rotation::trNoNegNoZoom(const RealRect& r) const { + RealSize s = sideways() ? RealSize(r.size.height, r.size.width) : r.size; + return RealRect(tr(r.position) - RealSize(revX()?s.width:0, revY()?s.height:0), s); +} + + +RealSize Rotation::trInv(const RealSize& s) const { + if (sideways()) { + return RealSize(negY(s.height), negX(s.width)) / zoom; + } else { + return RealSize(negX(s.width), negY(s.height)) / zoom; + } } RealPoint Rotation::trInv(const RealPoint& p) const { @@ -53,4 +68,86 @@ RealPoint Rotation::trInv(const RealPoint& p) const { } else { return RealPoint(negX(p2.x), negY(p2.y)); } -} \ No newline at end of file +} + +// ----------------------------------------------------------------------------- : Rotater + + +// ----------------------------------------------------------------------------- : RotatedDC + +RotatedDC::RotatedDC(DC& dc, int angle, const RealRect& rect, double zoom, bool high_quality) + : Rotation(angle, rect, zoom) + , dc(dc), high_quality(high_quality) +{} + +RotatedDC::RotatedDC(DC& dc, const Rotation& rotation, bool high_quality = false) + : Rotation(rotation) + , dc(dc), high_quality(high_quality) +{} + +// ----------------------------------------------------------------------------- : RotatedDC : Drawing + +void RotatedDC::DrawText (const String& text, const RealPoint& pos) { + if (text.empty()) return; +// if (high_quality) { +/* RealRect r(p, getTextExtent(text)); + //dc.getTextExtent(text, &r.width, &r.height) + RealRect r_ext = trNoNeg(r); + drawResampledText( { + dc, r_ext.x, r_ext.y, r_ext.width, r_ext.height, + revX(), revY(), + angle, text); + } + } else { +*/ RealPoint p_ext = tr(pos); + dc.DrawRotatedText(text, p_ext.x, p_ext.y, angle); +// } +} + +void RotatedDC::DrawBitmap(const Bitmap& bitmap, const RealPoint& pos) { + if (angle == 0) { + RealPoint p_ext = tr(pos); + dc.DrawBitmap(bitmap, p_ext.x, p_ext.y, true); + } else { + DrawImage(bitmap.ConvertToImage(), pos); + } +} +void RotatedDC::DrawImage (const Image& image, const RealPoint& pos, ImageCombine combine) { + Image rotated = rotate_image(image, angle); + wxRect r = trNoNegNoZoom(RealRect(pos, RealSize(image.GetWidth(), image.GetHeight()))); + draw_combine_image(dc, r.x, r.y, rotated, combine); +} + +void RotatedDC::DrawLine (const RealPoint& p1, const RealPoint& p2) { + wxPoint p1_ext = tr(p1), p2_ext = tr(p2); + dc.DrawLine(p1_ext.x, p1_ext.y, p2_ext.x, p2_ext.y); +} + +void RotatedDC::DrawRectangle(const RealRect& r) { + wxRect r_ext = trNoNeg(r); + dc.DrawRectangle(r_ext.x, r_ext.y, r_ext.width, r_ext.height); +} + +void RotatedDC::DrawRoundedRectangle(const RealRect& r, double radius) { + wxRect r_ext = trNoNeg(r); + dc.DrawRoundedRectangle(r_ext.x, r_ext.y, r_ext.width, r_ext.height, trS(radius)); +} + +// ----------------------------------------------------------------------------- : Forwarded properties + +void RotatedDC::SetPen(const wxPen& pen) { dc.SetPen(pen); } +void RotatedDC::SetBrush(const wxBrush& brush) { dc.SetBrush(brush); } +void RotatedDC::SetTextForeground(const Color& color) { dc.SetTextForeground(color); } +void RotatedDC::SetLogicalFunction(int function) { dc.SetLogicalFunction(function); } + +void RotatedDC::SetFont(const wxFont& font) { SetFont(font, font.GetPointSize()); } +void RotatedDC::SetFont(wxFont font, double size) { + font.SetPointSize(trS(size)); + dc.SetFont(font); +} + +RealSize RotatedDC::GetTextExtent(const String& text) { + int w, h; + dc.GetTextExtent(text, &w, &h); + return RealSize(w,h) / zoom; +} diff --git a/src/util/rotation.hpp b/src/util/rotation.hpp index d0405b5b..0d564554 100644 --- a/src/util/rotation.hpp +++ b/src/util/rotation.hpp @@ -30,6 +30,10 @@ class Rotation { inline void setZoom(double z) { zoom = z; } /// Change the angle void setAngle(int a); + /// The internal size + inline RealSize getInternalSize() const { return trInv(size); } + /// The intarnal rectangle (origin at (0,0)) + inline RealRect getInternalRect() const { return RealRect(RealPoint(0,0), getInternalSize()); } /// Translate a size or length inline double trS(double s) const { return s * zoom; } @@ -45,14 +49,19 @@ class Rotation { RealSize trNoNeg(const RealSize& s) const; /// Translate a rectangle, the result will never have a negative size RealRect trNoNeg(const RealRect& r) const; + /// Translate a rectangle, the result will never have a negative size + /** The rectangle is also not zoomed */ + RealRect trNoNegNoZoom(const RealRect& r) const; /// Translate a size or length back to internal 'coordinates' inline double trInvS(double s) const { return s / zoom; } /// Translate a point back to internal coordinates RealPoint trInv(const RealPoint& p) const; + /// Translate a size back to internal coordinates + RealSize trInv(const RealSize& s) const; - private: + protected: int angle; ///< The angle of rotation in degrees (counterclockwise) RealSize size; ///< Size of the rectangle, in external coordinates RealPoint origin; ///< tr(0,0) @@ -96,27 +105,40 @@ class Rotater { */ class RotatedDC : public Rotation { public: - RotatedDC(int angle, const RealRect& rect, double zoom = 1.0); - RotatedDC(const Rotation& rotation); + RotatedDC(DC& dc, int angle, const RealRect& rect, double zoom, bool high_quality); + RotatedDC(DC& dc, const Rotation& rotation, bool high_quality); // ----------------------------- : Drawing void DrawText (const String& text, const RealPoint& pos); + /// Draw abitmap, it must already be zoomed! void DrawBitmap(const Bitmap& bitmap, const RealPoint& pos); + /// Draw an image using the given combining mode, the image must already be zoomed! void DrawImage (const Image& image, const RealPoint& pos, ImageCombine combine = COMBINE_NORMAL); void DrawLine (const RealPoint& p1, const RealPoint& p2); void DrawRectangle(const RealRect& r); void DrawRoundedRectangle(const RealRect& r, double radius); + // Fill the dc with the color of the current brush + void Fill(); + // ----------------------------- : Forwarded properties + /// Sets the pen for the dc, does not scale the line width void SetPen(const wxPen&); void SetBrush(const wxBrush&); void SetTextForeground(const Color&); void SetLogicalFunction(int function); + void SetFont(const wxFont& font); + /// Set the font, scales for zoom and high_quality + /** The font will get the given (internal) point size */ + void SetFont(wxFont font, double size); - RealSize getTextExtent(const String& string); + RealSize GetTextExtent(const String& text); + private: + wxDC& dc; ///< The actual dc + bool high_quality; ///< Drawing using our own anti aliassing? }; // ----------------------------------------------------------------------------- : EOF