diff --git a/core/base/inc/TAttBBox2D.h b/core/base/inc/TAttBBox2D.h index f4f36e26be86c..4ca16c776b618 100644 --- a/core/base/inc/TAttBBox2D.h +++ b/core/base/inc/TAttBBox2D.h @@ -20,8 +20,8 @@ class TAttBBox2D { protected: - Double_t GetXCoord(const Int_t x, Bool_t is_ndc = kFALSE); - Double_t GetYCoord(const Int_t y, Bool_t is_ndc = kFALSE); + Double_t GetXCoord(const Int_t x, Bool_t is_ndc = kFALSE, Bool_t is_absolute = kFALSE); + Double_t GetYCoord(const Int_t y, Bool_t is_ndc = kFALSE, Bool_t is_absolute = kFALSE); public: virtual ~TAttBBox2D(); diff --git a/core/base/src/TAttBBox2D.cxx b/core/base/src/TAttBBox2D.cxx index 95b95f02e074f..874eb290f06df 100644 --- a/core/base/src/TAttBBox2D.cxx +++ b/core/base/src/TAttBBox2D.cxx @@ -54,34 +54,48 @@ void TAttBBox2D::SetBBoxCenter(const TPoint &p) } //////////////////////////////////////////////////////////////////////////////// -// Return user X coordinate for pixel X value -// Used in derived classes to implement SetBBox... methods +/// Return user X coordinate for pixel X value +/// Can return ndc or normal values +/// Also one can specify to use absolute coordinates for input parameter x +/// Used in derived classes to implement SetBBox... methods -Double_t TAttBBox2D::GetXCoord(const Int_t x, Bool_t is_ndc) +Double_t TAttBBox2D::GetXCoord(const Int_t x, Bool_t is_ndc, Bool_t is_absolute) { if (!gPad) return 0.; if (!is_ndc) - return gPad->PadtoX(gPad->PixeltoX(x)); + return gPad->PadtoX(is_absolute ? gPad->AbsPixeltoX(x) : gPad->PixeltoX(x)); + if (is_absolute) { + Double_t ww = gPad->GetWw(); + Double_t wndc = gPad->GetAbsWNDC(); + return ww > 0 && wndc > 0 ? (x / ww - gPad->GetAbsXlowNDC()) / wndc : 0.; + } Int_t pw = gPad->GetPadWidth(); return pw > 0 ? 1. * x / pw : 0.; } //////////////////////////////////////////////////////////////////////////////// // Return user Y coordinate for pixel Y value +/// Can return ndc or normal values +/// Also one can specify to use absolute coordinates for input parameter x // Used in derived classes to implement SetBBox... methods -Double_t TAttBBox2D::GetYCoord(const Int_t y, Bool_t is_ndc) +Double_t TAttBBox2D::GetYCoord(const Int_t y, Bool_t is_ndc, Bool_t is_absolute) { if (!gPad) return 0.; if (!is_ndc) - return gPad->PadtoY(gPad->PixeltoY(y - gPad->VtoPixel(0))); + return gPad->PadtoY(is_absolute ? gPad->AbsPixeltoY(y) : gPad->PixeltoY(y - gPad->VtoPixel(0))); - Int_t ph = gPad->GetPadHeight(); + if (is_absolute) { + Double_t wh = gPad->GetWh(); + Double_t hndc = gPad->GetAbsHNDC(); + return wh > 0 && hndc > 0 ? ((1. - y / wh) - gPad->GetAbsYlowNDC()) / hndc : 0.; + } + Int_t ph = gPad->GetPadHeight(); return ph > 0 ? 1. - 1. * y / ph : 0.; } diff --git a/graf2d/cocoa/inc/QuartzWindow.h b/graf2d/cocoa/inc/QuartzWindow.h index 79c5c3c0d999e..aab99954186fd 100644 --- a/graf2d/cocoa/inc/QuartzWindow.h +++ b/graf2d/cocoa/inc/QuartzWindow.h @@ -19,6 +19,9 @@ #include "X11Events.h" #include "GuiTypes.h" +class TAttMarker; +class TAttLine; + namespace ROOT { namespace MacOSX { namespace X11 { @@ -134,6 +137,8 @@ class Command; - (void) removeXorWindow; - (void) addXorLine : (QuartzView *) view : (Int_t) x1 : (Int_t) y1 : (Int_t) x2 : (Int_t) y2; - (void) addXorBox : (QuartzView *) view : (Int_t) x1 : (Int_t) y1 : (Int_t) x2 : (Int_t) y2; +- (void) addXorPolyLine : (QuartzView *) view : (Int_t) n : (TPoint *) pnts : (const TAttLine &) att; +- (void) addXorMarker : (QuartzView *) view : (Int_t) n : (TPoint *) pnts : (const TAttMarker &) att; - (void) setDrawMode : (TVirtualX::EDrawMode) newMode; - (TVirtualX::EDrawMode) getDrawMode; diff --git a/graf2d/cocoa/inc/TGQuartz.h b/graf2d/cocoa/inc/TGQuartz.h index e64fe08adcdb3..325046ab70ec1 100644 --- a/graf2d/cocoa/inc/TGQuartz.h +++ b/graf2d/cocoa/inc/TGQuartz.h @@ -95,10 +95,6 @@ class TGQuartz : public TGCocoa { private: - //Unfortunately, I have to convert from - //top-left to bottom-left corner system. - std::vector fConvertedPoints; - //Lines with AA can be quite different //from what we always had with X11. //Now this is a switch in our configuration file (system.rootrc), diff --git a/graf2d/cocoa/inc/X11Buffer.h b/graf2d/cocoa/inc/X11Buffer.h index 75c52cc3b7bde..be7792274b9e7 100644 --- a/graf2d/cocoa/inc/X11Buffer.h +++ b/graf2d/cocoa/inc/X11Buffer.h @@ -19,6 +19,9 @@ #include "CocoaGuiTypes.h" #include "GuiTypes.h" +#include "TAttMarker.h" +#include "TAttLine.h" +#include "TPoint.h" ////////////////////////////////////////////////////////////////////////////////// // // @@ -54,11 +57,11 @@ class Command { Command(Drawable_t wid, const GCValues_t &gc); virtual ~Command(); - virtual bool HasOperand(Drawable_t drawable)const; - virtual bool IsGraphicsCommand()const;//By-default - false. + virtual bool HasOperand(Drawable_t drawable) const; + virtual bool IsGraphicsCommand() const;//By-default - false. - virtual void Execute()const = 0; - virtual void Execute(CGContextRef /*ctx*/)const; + virtual void Execute() const = 0; + virtual void Execute(CGContextRef /*ctx*/) const; void setView(NSView *v) { @@ -76,8 +79,8 @@ class DrawLine : public Command { public: DrawLine(Drawable_t wid, const GCValues_t &gc, const Point &p1, const Point &p2); - void Execute()const; - bool IsGraphicsCommand()const + void Execute() const override; + bool IsGraphicsCommand() const override { return true; } @@ -89,8 +92,8 @@ class DrawSegments : public Command { public: DrawSegments(Drawable_t wid, const GCValues_t &gc, const Segment_t *segments, Int_t nSegments); - void Execute()const; - bool IsGraphicsCommand()const + void Execute() const override; + bool IsGraphicsCommand() const override { return true; } @@ -102,8 +105,8 @@ class ClearArea : public Command { public: ClearArea(Window_t wid, const Rectangle_t &area); - void Execute()const; - bool IsGraphicsCommand()const + void Execute() const override; + bool IsGraphicsCommand() const override { return true; } @@ -118,13 +121,13 @@ class CopyArea : public Command { public: CopyArea(Drawable_t src, Drawable_t dst, const GCValues_t &gc, const Rectangle_t &area, const Point &dstPoint); - bool HasOperand(Drawable_t drawable)const; - bool IsGraphicsCommand()const + bool HasOperand(Drawable_t drawable) const override; + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; @@ -136,12 +139,12 @@ class DrawString : public Command { public: DrawString(Drawable_t wid, const GCValues_t &gc, const Point &point, const std::string &text); - bool IsGraphicsCommand()const + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; class FillRectangle : public Command { @@ -151,12 +154,12 @@ class FillRectangle : public Command { public: FillRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle); - bool IsGraphicsCommand()const + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; class FillPolygon : public Command { @@ -166,12 +169,12 @@ class FillPolygon : public Command { public: FillPolygon(Drawable_t wid, const GCValues_t &gc, const Point_t *points, Int_t nPoints); - bool IsGraphicsCommand()const + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; class DrawRectangle : public Command { @@ -181,12 +184,12 @@ class DrawRectangle : public Command { public: DrawRectangle(Drawable_t wid, const GCValues_t &gc, const Rectangle_t &rectangle); - bool IsGraphicsCommand()const + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; class UpdateWindow : public Command { @@ -196,18 +199,18 @@ class UpdateWindow : public Command { public: UpdateWindow(QuartzView *view); - bool IsGraphicsCommand()const + bool IsGraphicsCommand() const override { return true; } - void Execute()const; + void Execute() const override; }; class DeletePixmap : public Command { public: DeletePixmap(Pixmap_t pixmap); - void Execute()const; + void Execute() const override; }; //Set of 'xor' operations, required by TCanvas and ExecuteEvent's machinery. @@ -219,8 +222,8 @@ class DrawBoxXor : public Command { public: DrawBoxXor(Window_t windowID, const Point &p1, const Point &p2); - void Execute()const; - void Execute(CGContextRef ctx)const; + void Execute() const override {} + void Execute(CGContextRef ctx) const override; }; class DrawLineXor : public Command { @@ -231,13 +234,45 @@ class DrawLineXor : public Command { public: DrawLineXor(Window_t windowID, const Point &p1, const Point &p2); - void Execute()const; - void Execute(CGContextRef ctx)const; + void Execute() const override {} + void Execute(CGContextRef ctx) const override; - Point start() const {return fP1;} - Point end() const {return fP2;} + Point start() const { return fP1; } + Point end() const { return fP2; } }; +class DrawPolyLineXor : public Command { +private: + std::vector fPnts; + TAttLine fAtt; + float fScaleFactor = 1.; + +public: + DrawPolyLineXor(Window_t windowID, const TAttLine &att) : + Command(windowID, GCValues_t()), fAtt(att) {} + void setPoints(Int_t n, TPoint *xy); + + void Execute() const override {} + void Execute(CGContextRef ctx) const override; +}; + + +class DrawMarkerXor : public Command { +private: + std::vector fPnts; + TAttMarker fAtt; + float fScaleFactor = 1.; + +public: + DrawMarkerXor(Window_t windowID, const TAttMarker &att) : + Command(windowID, GCValues_t()), fAtt(att) {} + void setPoints(Int_t n, TPoint *xy); + + void Execute() const override {} + void Execute(CGContextRef ctx) const override; +}; + + class CommandBuffer { private: CommandBuffer(const CommandBuffer &rhs); diff --git a/graf2d/cocoa/src/QuartzWindow.mm b/graf2d/cocoa/src/QuartzWindow.mm index 46a260a6fde8e..e4d8b0a8d0d51 100644 --- a/graf2d/cocoa/src/QuartzWindow.mm +++ b/graf2d/cocoa/src/QuartzWindow.mm @@ -1559,7 +1559,7 @@ - (void) addXorLine : (QuartzView *) view : (Int_t) x1 : (Int_t) y1 : (Int_t) x2 auto xorWindow = [self addXorWindow]; try { - std::unique_ptr cmd(new ROOT::MacOSX::X11::DrawLineXor(-1, ROOT::MacOSX::X11::Point(x1, y1), ROOT::MacOSX::X11::Point(x2, y2))); + auto cmd = std::make_unique(-1, ROOT::MacOSX::X11::Point(x1, y1), ROOT::MacOSX::X11::Point(x2, y2)); cmd->setView(view); auto cv = (XorDrawingView *)xorWindow.contentView; @@ -1578,7 +1578,7 @@ - (void) addXorBox : (QuartzView *) view : (Int_t) x1 : (Int_t) y1 : (Int_t) x2 auto xorWindow = [self addXorWindow]; try { - std::unique_ptr cmd(new ROOT::MacOSX::X11::DrawBoxXor(-1, ROOT::MacOSX::X11::Point(x1, y1), ROOT::MacOSX::X11::Point(x2, y2))); + auto cmd = std::make_unique(-1, ROOT::MacOSX::X11::Point(x1, y1), ROOT::MacOSX::X11::Point(x2, y2)); cmd->setView(view); auto cv = (XorDrawingView *)xorWindow.contentView; @@ -1590,6 +1590,45 @@ - (void) addXorBox : (QuartzView *) view : (Int_t) x1 : (Int_t) y1 : (Int_t) x2 } } +//______________________________________________________________________________ +- (void) addXorPolyLine : (QuartzView *) view : (Int_t) n : (TPoint *) pnts : (const TAttLine &) att +{ + auto xorWindow = [self addXorWindow]; + + try { + auto cmd = std::make_unique(-1, att); + cmd->setView(view); + cmd->setPoints(n, pnts); + + auto cv = (XorDrawingView *)xorWindow.contentView; + [cv addXorCommand : cmd.get()]; + cmd.release(); + [cv setNeedsDisplay : YES]; + + } catch (const std::exception &) { + throw; + } +} + +//______________________________________________________________________________ +- (void) addXorMarker : (QuartzView *) view : (Int_t) n : (TPoint *) pnts : (const TAttMarker &) att +{ + auto xorWindow = [self addXorWindow]; + + try { + auto cmd = std::make_unique(-1, att); + cmd->setView(view); + cmd->setPoints(n, pnts); + + auto cv = (XorDrawingView *)xorWindow.contentView; + [cv addXorCommand : cmd.get()]; + cmd.release(); + [cv setNeedsDisplay : YES]; + + } catch (const std::exception &) { + throw; + } +} //______________________________________________________________________________ - (void) setDrawMode : (TVirtualX::EDrawMode) newMode diff --git a/graf2d/cocoa/src/TGQuartz.mm b/graf2d/cocoa/src/TGQuartz.mm index c85d39c7a9f95..7ee0508a2c785 100644 --- a/graf2d/cocoa/src/TGQuartz.mm +++ b/graf2d/cocoa/src/TGQuartz.mm @@ -203,8 +203,10 @@ void ConvertPointsROOTToCocoa(Int_t nPoints, const TPoint *xy, std::vector pnts; + //Convert points to bottom-left system: - ConvertPointsROOTToCocoa(n, xy, fConvertedPoints, drawable); + ConvertPointsROOTToCocoa(n, xy, pnts, drawable); const Quartz::CGStateGuard ctxGuard(ctx); //AA flag is not a part of a state. @@ -223,7 +225,7 @@ void ConvertPointsROOTToCocoa(Int_t nPoints, const TPoint *xy, std::vector(fillColor)) { Quartz::DrawPolygonWithGradientFill(ctx, gradient, CGSizeMake(drawable.fWidth, drawable.fHeight), - n, &fConvertedPoints[0], kFALSE);//kFALSE == don't draw a shadow. + pnts.size(), pnts.data(), kFALSE);//kFALSE == don't draw a shadow. } else { unsigned patternIndex = 0; if (!Quartz::SetFillAreaParameters(ctx, &patternIndex, attfill)) { @@ -233,7 +235,7 @@ void ConvertPointsROOTToCocoa(Int_t nPoints, const TPoint *xy, std::vectorGetWindow(drawable0.fID).fContentView; + if (!view) { + ::Warning("DrawPolyLineW", "Invalid view/window for XOR-mode"); + return; + } - auto &attline = GetAttLine(wctxt); + [view.fQuartzWindow addXorPolyLine: view : n : xy : attline ]; + } + + return; + } auto drawable = (NSObject * const) GetPixmapDrawable(drawable0, "DrawPolyLineW"); if (!drawable) @@ -339,13 +352,15 @@ void ConvertPointsROOTToCocoa(Int_t nPoints, const TPoint *xy, std::vector pnts; + //Convert to bottom-left-corner system. - ConvertPointsROOTToCocoa(n, xy, fConvertedPoints, drawable); + ConvertPointsROOTToCocoa(n, xy, pnts, drawable); if (drawable.fScaleFactor > 1.) CGContextScaleCTM(ctx, 1. / drawable.fScaleFactor, 1. / drawable.fScaleFactor); - Quartz::DrawPolyLine(ctx, n, &fConvertedPoints[0]); + Quartz::DrawPolyLine(ctx, pnts.size(), pnts.data()); // CTM (current transformation matrix) is restored by 'ctxGuard's dtor. } @@ -372,57 +387,41 @@ void ConvertPointsROOTToCocoa(Int_t nPoints, const TPoint *xy, std::vector * const) wctxt; if (!drawable0) return; - //Do some checks first. - if ([drawable0 isDirectDraw]) - return; - auto &attmark = GetAttMarker(wctxt); + if ([drawable0 isDirectDraw]) { + if (!drawable0.fIsPixmap) { + QuartzView * const view = (QuartzView *)fPimpl->GetWindow(drawable0.fID).fContentView; + if (!view) { + ::Warning("DrawPolyMarkerW", "Invalid view/window for XOR-mode"); + return; + } + + [view.fQuartzWindow addXorMarker: view : n : xy : attmark ]; + } + + return; + } auto drawable = (NSObject * const) GetPixmapDrawable(drawable0, "DrawPolyMarkerW"); if (!drawable) return; + std::vector pnts; + + ConvertPointsROOTToCocoa(n, xy, pnts, drawable); + CGContextRef ctx = drawable.fContext; const Quartz::CGStateGuard ctxGuard(ctx); //AA flag is not a part of a state. const Quartz::CGAAStateGuard aaCtxGuard(ctx, fUseAA); - if (!Quartz::SetFillColor(ctx, attmark.GetMarkerColor())) { - Error("DrawPolyMarker", "Could not find TColor for index %d", attmark.GetMarkerColor()); - return; - } - - Quartz::SetLineColor(ctx, attmark.GetMarkerColor());//Can not fail (for coverity). - Quartz::SetLineStyle(ctx, 1); - Quartz::SetLineWidth(ctx, TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(attmark.GetMarkerStyle())))); - - ConvertPointsROOTToCocoa(n, xy, fConvertedPoints, drawable); - - if (drawable.fScaleFactor > 1.) - CGContextScaleCTM(ctx, 1. / drawable.fScaleFactor, 1. / drawable.fScaleFactor); - - Style_t markerstyle = TAttMarker::GetMarkerStyleBase(attmark.GetMarkerStyle()); - - // The fast pixel markers need to be treated separately - if (markerstyle == 1 || markerstyle == 6 || markerstyle == 7) { - CGContextSetLineJoin(ctx, kCGLineJoinMiter); - CGContextSetLineCap(ctx, kCGLineCapButt); - } else { - CGContextSetLineJoin(ctx, kCGLineJoinRound); - CGContextSetLineCap(ctx, kCGLineCapRound); - } - - Float_t MarkerSizeReduced = GetMarkerSize() - TMath::Floor(TAttMarker::GetMarkerLineWidth(attmark.GetMarkerStyle())/2.)/4.; - Quartz::DrawPolyMarker(ctx, n, &fConvertedPoints[0], MarkerSizeReduced * drawable.fScaleFactor, markerstyle); - - CGContextSetLineJoin(ctx, kCGLineJoinMiter); - CGContextSetLineCap(ctx, kCGLineCapButt); + Quartz::DrawPolyMarker(ctx, pnts.size(), pnts.data(), attmark, drawable.fScaleFactor); } //______________________________________________________________________________ diff --git a/graf2d/cocoa/src/X11Buffer.mm b/graf2d/cocoa/src/X11Buffer.mm index 76cc0ed250f1e..77ad33109e51f 100644 --- a/graf2d/cocoa/src/X11Buffer.mm +++ b/graf2d/cocoa/src/X11Buffer.mm @@ -22,9 +22,11 @@ #include "ROOTOpenGLView.h" #include "CocoaPrivate.h" #include "QuartzWindow.h" +#include "QuartzMarker.h" #include "QuartzPixmap.h" #include "QuartzUtils.h" #include "X11Drawable.h" +#include "QuartzLine.h" #include "X11Buffer.h" #include "TGWindow.h" #include "TGClient.h" @@ -274,10 +276,6 @@ } //______________________________________________________________________________ -void DrawBoxXor::Execute()const -{ - //Noop. -} const auto rootToNs = [](Point rp) { return NSPoint{CGFloat(rp.fX), CGFloat(rp.fY)}; @@ -303,13 +301,7 @@ } //______________________________________________________________________________ -void DrawLineXor::Execute()const -{ - //Noop. -} - -//______________________________________________________________________________ -void DrawLineXor::Execute(CGContextRef ctx)const +void DrawLineXor::Execute(CGContextRef ctx) const { assert(ctx && "Execute, invalid (nullptr) parameter 'ctx'"); @@ -326,6 +318,59 @@ CGContextStrokePath(ctx); } +//______________________________________________________________________________ +void DrawPolyLineXor::setPoints(Int_t n, TPoint *xy) +{ + fPnts.resize(n); + for (Int_t i = 0; i < n; ++i) { + auto point = NSPoint{CGFloat(xy[i].fX), CGFloat(xy[i].fY)}; + point = [view convertPoint : point toView : nil]; + fPnts[i].fX = (SCoord_t) point.x; + fPnts[i].fY = (SCoord_t) point.y; + } +} + +//______________________________________________________________________________ +void DrawPolyLineXor::Execute(CGContextRef ctx) const +{ + assert(ctx && "Execute, invalid (nullptr) parameter 'ctx'"); + + const Quartz::CGStateGuard ctxGuard(ctx); + + if (!Quartz::SetLineColor(ctx, fAtt.GetLineColor())) + return; + + Quartz::SetLineStyle(ctx, fAtt.GetLineStyle()); + Quartz::SetLineWidth(ctx, fAtt.GetLineWidth()); + + if (fScaleFactor > 1.) + CGContextScaleCTM(ctx, 1. / fScaleFactor, 1. / fScaleFactor); + + Quartz::DrawPolyLine(ctx, fPnts.size(), fPnts.data()); +} + +//______________________________________________________________________________ +void DrawMarkerXor::setPoints(Int_t n, TPoint *xy) +{ + fPnts.resize(n); + for (Int_t i = 0; i < n; ++i) { + auto point = NSPoint{CGFloat(xy[i].fX), CGFloat(xy[i].fY)}; + point = [view convertPoint : point toView : nil]; + fPnts[i].fX = (SCoord_t) point.x; + fPnts[i].fY = (SCoord_t) point.y; + } +} + +//______________________________________________________________________________ +void DrawMarkerXor::Execute(CGContextRef ctx) const +{ + assert(ctx && "Execute, invalid (nullptr) parameter 'ctx'"); + + const Quartz::CGStateGuard ctxGuard(ctx); + + Quartz::DrawPolyMarker(ctx, fPnts.size(), fPnts.data(), fAtt, fScaleFactor); +} + //______________________________________________________________________________ CommandBuffer::CommandBuffer() { diff --git a/graf2d/gpad/src/TPadPainter.cxx b/graf2d/gpad/src/TPadPainter.cxx index f39bcb95fe2b3..827104b5a74e6 100644 --- a/graf2d/gpad/src/TPadPainter.cxx +++ b/graf2d/gpad/src/TPadPainter.cxx @@ -31,7 +31,7 @@ using size_type = std::vector::size_type; template void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys, - std::vector &dst); + std::vector &dst, Bool_t absCoord = kFALSE); inline void MergePointsX(std::vector &points, unsigned nMerged, SCoord_t yMin, SCoord_t yMax, SCoord_t yLast); @@ -50,7 +50,7 @@ template void DrawFillAreaAux(TVirtualPad *pad, WinContext_t cont, Int_t nPoints, const T *xs, const T *ys, Bool_t add_first_point); template -void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys); +void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, Bool_t absCoord, unsigned nPoints, const T *xs, const T *ys); template void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, Bool_t double_buffer, unsigned nPoints, const T *xs, const T *ys); @@ -365,7 +365,7 @@ void TPadPainter::DrawPolyLine(Int_t n, const Double_t *xs, const Double_t *ys) return; } - DrawPolyLineAux(gPad, fWinContext, n, xs, ys); + DrawPolyLineAux(gPad, fWinContext, !fDoubleBuffer, n, xs, ys); } @@ -382,7 +382,7 @@ void TPadPainter::DrawPolyLine(Int_t n, const Float_t *xs, const Float_t *ys) return; } - DrawPolyLineAux(gPad, fWinContext, n, xs, ys); + DrawPolyLineAux(gPad, fWinContext, !fDoubleBuffer, n, xs, ys); } @@ -628,16 +628,23 @@ namespace { template void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y, - std::vector &dst) + std::vector &dst, Bool_t absCoord) { if (!nPoints) return; dst.resize(nPoints); - for (unsigned i = 0; i < nPoints; ++i) { - dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]); - dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]); + if (absCoord) { + for (unsigned i = 0; i < nPoints; ++i) { + dst[i].fX = (SCoord_t) pad->XtoAbsPixel(x[i]); + dst[i].fY = (SCoord_t) pad->YtoAbsPixel(y[i]); + } + } else { + for (unsigned i = 0; i < nPoints; ++i) { + dst[i].fX = (SCoord_t) pad->XtoPixel(x[i]); + dst[i].fY = (SCoord_t) pad->YtoPixel(y[i]); + } } } @@ -846,27 +853,25 @@ void DrawFillAreaAux(TVirtualPad *pad, WinContext_t cont, Int_t nPoints, const T //////////////////////////////////////////////////////////////////////////////// -template -void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys) +template +void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, Bool_t absCoord, unsigned nPoints, const T *xs, const T *ys) { std::vector xy; - const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(), - pad->GetWh() * pad->GetAbsHNDC())) * 2; + const UInt_t threshold = TMath::Min(pad->GetPadWidth(), pad->GetPadHeight()) * 2; - if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened. + if (threshold == 0) {//Ooops, pad is invisible or something really bad and stupid happened. ::Error("DrawPolyLineAux", "invalid pad's geometry"); return; } - if (nPoints < (unsigned)threshold) - ConvertPoints(pad, nPoints, xs, ys, xy); + if (absCoord || (nPoints < threshold)) + ConvertPoints(pad, nPoints, xs, ys, xy, absCoord); else ConvertPointsAndMerge(pad, threshold, nPoints, xs, ys, xy); if (xy.size() > 1) gVirtualX->DrawPolyLineW(cont, xy.size(), &xy[0]); - } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/graf/inc/TEllipse.h b/graf2d/graf/inc/TEllipse.h index f54f54336b3cf..9de88ee3f9f19 100644 --- a/graf2d/graf/inc/TEllipse.h +++ b/graf2d/graf/inc/TEllipse.h @@ -17,6 +17,7 @@ #include "TAttLine.h" #include "TAttFill.h" #include "TAttBBox2D.h" +#include class TPoint; @@ -31,6 +32,9 @@ class TEllipse : public TObject, public TAttLine, public TAttFill, public TAttBB Double_t fPhimax; ///< Maximum angle (degrees) Double_t fTheta; ///< Rotation angle (degrees) + Bool_t FillPoints(TVirtualPad &pad, std::vector &x, std::vector &y, + Double_t x1, Double_t y1, Double_t r1, Double_t r2, Double_t phimin, Double_t phimax, Double_t theta); + public: // TEllipse status bits enum { @@ -69,7 +73,6 @@ class TEllipse : public TObject, public TAttLine, public TAttFill, public TAttBB virtual void SetY1(Double_t y1) {fY1=y1;} // *MENU* Rectangle_t GetBBox() override; TPoint GetBBoxCenter() override; - void SetBBoxCenter(const TPoint &p) override; void SetBBoxCenterX(const Int_t x) override; void SetBBoxCenterY(const Int_t y) override; void SetBBoxX1(const Int_t x) override; diff --git a/graf2d/graf/inc/TText.h b/graf2d/graf/inc/TText.h index e4dcc853aefba..78a5ce4c861ce 100644 --- a/graf2d/graf/inc/TText.h +++ b/graf2d/graf/inc/TText.h @@ -78,13 +78,12 @@ class TText : public TNamed, public TAttText, public TAttBBox2D { Rectangle_t GetBBox() override; TPoint GetBBoxCenter() override; - void SetBBoxCenter(const TPoint &p) override; void SetBBoxCenterX(const Int_t x) override; void SetBBoxCenterY(const Int_t y) override; - void SetBBoxX1(const Int_t) override; //Not Implemented - void SetBBoxX2(const Int_t) override; //Not Implemented - void SetBBoxY1(const Int_t) override; //Not Implemented - void SetBBoxY2(const Int_t) override; //Not Implemented + void SetBBoxX1(const Int_t) override {} //Not Implemented + void SetBBoxX2(const Int_t) override {} //Not Implemented + void SetBBoxY1(const Int_t) override {} //Not Implemented + void SetBBoxY2(const Int_t) override {} //Not Implemented ClassDefOverride(TText,3) //Text }; diff --git a/graf2d/graf/src/TEllipse.cxx b/graf2d/graf/src/TEllipse.cxx index 2002b0f5b3025..6a11bd03622e7 100644 --- a/graf2d/graf/src/TEllipse.cxx +++ b/graf2d/graf/src/TEllipse.cxx @@ -16,6 +16,7 @@ #include "TBuffer.h" #include "TEllipse.h" #include "TVirtualPad.h" +#include "TVirtualPadPainter.h" #include "TMath.h" #include "TPoint.h" #include "TVirtualX.h" @@ -199,311 +200,156 @@ TEllipse *TEllipse::DrawEllipse(Double_t x1, Double_t y1,Double_t r1,Double_t r2 void TEllipse::ExecuteEvent(Int_t event, Int_t px, Int_t py) { - if (!gPad) return; + if (!gPad || !gPad->IsEditable()) return; - Int_t kMaxDiff = 10; + auto &parent = *gPad; - Int_t i, dpx, dpy; - Double_t angle,dx,dy,dphi,ct,st,fTy,fBy,fLx,fRx; - static Int_t px1,py1,npe,r1,r2,sav1,sav2; - const Int_t kMinSize = 25; - const Int_t np = 40; - static Bool_t pTop, pL, pR, pBot, pINSIDE; - static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy; - static Int_t x[np+2], y[np+2]; - static Int_t pxold, pyold; - static Int_t sig,impair; - static Double_t sdx, sdy; - static Double_t oldX1, oldY1, oldR1, oldR2; + auto pp = parent.GetPainter(); - Bool_t opaque = gPad->OpaqueMoving(); + Int_t kMaxDiff = 10; - if (!gPad->IsEditable()) return; + static enum { pNone, pTop, pL, pR, pBot, pINSIDE } mode = pNone; + static Int_t sdx = 0, sdy = 0; + static Double_t oldX1, oldY1, oldR1, oldR2; + static Bool_t first_move = kTRUE; + + auto paint_hollow = [this,&parent,pp]() { + pp->SetAttLine(*this); + std::vector x, y; + FillPoints(parent, x, y, GetX1(), GetY1(), GetR1(), GetR2(), GetPhimin(), GetPhimax(), GetTheta()); + pp->DrawPolyLine(x.size(), x.data(), y.data()); + pp->SetAttMarker({GetLineColor(), 25, 2}); + Double_t xm[4] = { GetX1(), GetX1(), GetX1() - GetR1(), GetX1() + GetR1() }; + Double_t ym[4] = { GetY1() + GetR2(), GetY1() - GetR2(), GetY1(), GetY1() }; + for (Int_t i = 0; i < 4; ++i) { + xm[i] = parent.XtoPad(xm[i]); + ym[i] = parent.YtoPad(ym[i]); + } + pp->DrawPolyMarker(4, xm, ym); + }; + + auto changeX = [this](Int_t px1, Int_t px2) { + auto x1 = GetXCoord(px1, kFALSE, kTRUE); + auto x2 = GetXCoord(px2, kFALSE, kTRUE); + SetX1((x1 + x2) * 0.5); + SetR1(TMath::Abs((x2 - x1) * 0.5)); + if (x2 < x1) + mode = (mode == pL) ? pR : pL; + }; + + auto changeY = [this](Int_t py1, Int_t py2) { + auto y1 = GetYCoord(py1, kFALSE, kTRUE); + auto y2 = GetYCoord(py2, kFALSE, kTRUE); + SetY1((y1 + y2) * 0.5); + SetR2(TMath::Abs((y1 - y2) * 0.5)); + if (y1 < y2) + mode = (mode == pTop) ? pBot : pTop; + }; + + Bool_t opaque = parent.OpaqueMoving(); switch (event) { case kArrowKeyPress: case kButton1Down: - oldX1 = fX1; - oldY1 = fY1; - oldR1 = fR1; - oldR2 = fR2; - dphi = (fPhimax-fPhimin)*kPI/(180*np); - ct = TMath::Cos(kPI*fTheta/180); - st = TMath::Sin(kPI*fTheta/180); - for (i=0;iXtoAbsPixel(fX1 + dx*ct - dy*st); - y[i] = gPad->YtoAbsPixel(fY1 + dx*st + dy*ct); - } - if (fPhimax-fPhimin >= 360 ) { - x[np] = x[0]; - y[np] = y[0]; - npe = np; - } else { - x[np] = gPad->XtoAbsPixel(fX1); - y[np] = gPad->YtoAbsPixel(fY1); - x[np+1] = x[0]; - y[np+1] = y[0]; - npe = np + 1; - } - impair = 0; - px1 = gPad->XtoAbsPixel(fX1); - py1 = gPad->YtoAbsPixel(fY1); - pTx = pBx = px1; - pLy = pRy = py1; - pTy = gPad->YtoAbsPixel(fR2+fY1); - pBy = gPad->YtoAbsPixel(-fR2+fY1); - pLx = gPad->XtoAbsPixel(-fR1+fX1); - pRx = gPad->XtoAbsPixel(fR1+fX1); - r2 = (pBy-pTy)/2; - r1 = (pRx-pLx)/2; - if (!opaque) { - gVirtualX->SetLineColor(-1); - TAttLine::Modify(); - gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4); - gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4); - gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4); - gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4); - gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4); - gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4); - gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4); - gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4); - gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4); - gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4); - gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4); - gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4); - gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4); - gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4); - gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4); - gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4); - } - else { - sdx = this->GetX1()-gPad->AbsPixeltoX(px); - sdy = this->GetY1()-gPad->AbsPixeltoY(py); - } + oldX1 = GetX1(); + oldY1 = GetY1(); + oldR1 = GetR1(); + oldR2 = GetR2(); + + sdx = parent.XtoAbsPixel(parent.XtoPad(GetX1())) - px; + sdy = parent.YtoAbsPixel(parent.YtoPad(GetY1())) - py; + // No break !!! - case kMouseMotion: - px1 = gPad->XtoAbsPixel(fX1); - py1 = gPad->YtoAbsPixel(fY1); - pTx = pBx = px1; - pLy = pRy = py1; - pTy = gPad->YtoAbsPixel(fR2+fY1); - pBy = gPad->YtoAbsPixel(-fR2+fY1); - pLx = gPad->XtoAbsPixel(-fR1+fX1); - pRx = gPad->XtoAbsPixel(fR1+fX1); - pTop = pL = pR = pBot = pINSIDE = kFALSE; - if ((TMath::Abs(px - pTx) < kMaxDiff) && - (TMath::Abs(py - pTy) < kMaxDiff)) { // top edge - pTop = kTRUE; - gPad->SetCursor(kTopSide); - } - else - if ((TMath::Abs(px - pBx) < kMaxDiff) && - (TMath::Abs(py - pBy) < kMaxDiff)) { // bottom edge - pBot = kTRUE; - gPad->SetCursor(kBottomSide); - } - else - if ((TMath::Abs(py - pLy) < kMaxDiff) && - (TMath::Abs(px - pLx) < kMaxDiff)) { // left edge - pL = kTRUE; - gPad->SetCursor(kLeftSide); - } - else - if ((TMath::Abs(py - pRy) < kMaxDiff) && - (TMath::Abs(px - pRx) < kMaxDiff)) { // right edge - pR = kTRUE; - gPad->SetCursor(kRightSide); + case kMouseMotion: { + Int_t px1 = parent.XtoAbsPixel(parent.XtoPad(GetX1())); + Int_t py1 = parent.YtoAbsPixel(parent.YtoPad(GetY1())); + Int_t pLx = parent.XtoAbsPixel(parent.XtoPad(GetX1() - GetR1())); + Int_t pRx = parent.XtoAbsPixel(parent.XtoPad(GetX1() + GetR1())); + Int_t pBy = parent.YtoAbsPixel(parent.YtoPad(GetY1() - GetR2())); + Int_t pTy = parent.YtoAbsPixel(parent.YtoPad(GetY1() + GetR2())); + mode = pNone; + if ((TMath::Abs(px - px1) < kMaxDiff) && (TMath::Abs(py - pTy) < kMaxDiff)) { + mode = pTop; // top edge + parent.SetCursor(kTopSide); + } else if ((TMath::Abs(px - px1) < kMaxDiff) && (TMath::Abs(py - pBy) < kMaxDiff)) { + mode = pBot; // bottom edge + parent.SetCursor(kBottomSide); + } else if ((TMath::Abs(py - py1) < kMaxDiff) && (TMath::Abs(px - pLx) < kMaxDiff)) { + mode = pL; // left edge + parent.SetCursor(kLeftSide); + } else if ((TMath::Abs(py - py1) < kMaxDiff) && (TMath::Abs(px - pRx) < kMaxDiff)) { + mode = pR; // right edge + parent.SetCursor(kRightSide); + } else { + mode = pINSIDE; + parent.SetCursor(kMove); } - else {pINSIDE= kTRUE; gPad->SetCursor(kMove); } - pxold = px; pyold = py; - + first_move = kTRUE; break; + } case kArrowKeyRelease: - case kButton1Motion: - if (!opaque) - { - gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4); - gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4); - gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4); - gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4); - gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4); - gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4); - gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4); - gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4); - gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4); - gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4); - gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4); - gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4); - gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4); - gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4); - gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4); - gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4); - for (i=0;iDrawLine(x[i], y[i], x[i+1], y[i+1]); - } - if (pTop) { - sav1 = py1; - sav2 = r2; - py1 += (py - pyold)/2; - r2 -= (py - pyold)/2; - if (TMath::Abs(pyold-py)%2==1) impair++; - if (py-pyold>0) sig=+1; - else sig=-1; - if (impair==2) { impair = 0; py1 += sig; r2 -= sig;} - if (py1 > pBy-kMinSize) {py1 = sav1; r2 = sav2; py = pyold;} - } - if (pBot) { - sav1 = py1; - sav2 = r2; - py1 += (py - pyold)/2; - r2 += (py - pyold)/2; - if (TMath::Abs(pyold-py)%2==1) impair++; - if (py-pyold>0) sig=+1; - else sig=-1; - if (impair==2) { impair = 0; py1 += sig; r2 += sig;} - if (py1 < pTy+kMinSize) {py1 = sav1; r2 = sav2; py = pyold;} - } - if (pL) { - sav1 = px1; - sav2 = r1; - px1 += (px - pxold)/2; - r1 -= (px - pxold)/2; - if (TMath::Abs(pxold-px)%2==1) impair++; - if (px-pxold>0) sig=+1; - else sig=-1; - if (impair==2) { impair = 0; px1 += sig; r1 -= sig;} - if (px1 > pRx-kMinSize) {px1 = sav1; r1 = sav2; px = pxold;} - } - if (pR) { - sav1 = px1; - sav2 = r1; - px1 += (px - pxold)/2; - r1 += (px - pxold)/2; - if (TMath::Abs(pxold-px)%2==1) impair++; - if (px-pxold>0) sig=+1; - else sig=-1; - if (impair==2) { impair = 0; px1 += sig; r1 += sig;} - if (px1 < pLx+kMinSize) {px1 = sav1; r1 = sav2; px = pxold;} - } - if (pTop || pBot || pL || pR) { - if (!opaque) { - dphi = (fPhimax-fPhimin)*kPI/(180*np); - ct = TMath::Cos(kPI*fTheta/180); - st = TMath::Sin(kPI*fTheta/180); - for (i=0;i= 360 ) { - x[np] = x[0]; - y[np] = y[0]; - npe = np; - } else { - x[np] = px1; - y[np] = py1; - x[np+1] = x[0]; - y[np+1] = y[0]; - npe = np + 1; - } - gVirtualX->SetLineColor(-1); - TAttLine::Modify(); - for (i=0;iDrawLine(x[i], y[i], x[i+1], y[i+1]); - } - else - { - this->SetX1(gPad->AbsPixeltoX(px1)); - this->SetY1(gPad->AbsPixeltoY(py1)); - this->SetR1(TMath::Abs(gPad->AbsPixeltoX(px1-r1)-gPad->AbsPixeltoX(px1+r1))/2); - this->SetR2(TMath::Abs(gPad->AbsPixeltoY(py1-r2)-gPad->AbsPixeltoY(py1+r2))/2); - if (pTop) gPad->ShowGuidelines(this, event, 't', true); - if (pBot) gPad->ShowGuidelines(this, event, 'b', true); - if (pL) gPad->ShowGuidelines(this, event, 'l', true); - if (pR) gPad->ShowGuidelines(this, event, 'r', true); - gPad->Modified(kTRUE); - gPad->Update(); - } - } - if (pINSIDE) { - if (!opaque){ - dpx = px-pxold; dpy = py-pyold; - px1 += dpx; py1 += dpy; - for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;} - for (i=0;iDrawLine(x[i], y[i], x[i+1], y[i+1]); - } - else { - this->SetX1(gPad->AbsPixeltoX(px)+sdx); - this->SetY1(gPad->AbsPixeltoY(py)+sdy); - gPad->ShowGuidelines(this, event, 'i', true); - gPad->Modified(kTRUE); - gPad->Update(); - } - } - if (!opaque){ - pTx = pBx = px1; - pRx = px1+r1; - pLx = px1-r1; - pRy = pLy = py1; - pTy = py1-r2; - pBy = py1+r2; - gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4); - gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4); - gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4); - gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4); - gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4); - gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4); - gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4); - gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4); - gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4); - gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4); - gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4); - gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4); - gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4); - gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4); - gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4); - gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4); + case kButton1Motion: { + if (mode == pNone) + break; + if (!opaque && !first_move) + paint_hollow(); + char guide = 'i'; + switch (mode) { + case pNone: + break; + case pL: + changeX(px, parent.XtoAbsPixel(parent.XtoPad(GetX1() + GetR1()))); + guide = 'l'; + break; + case pR: + changeX(parent.XtoAbsPixel(parent.XtoPad(GetX1() - GetR1())), px); + guide = 'r'; + break; + case pTop: + changeY(py, parent.YtoAbsPixel(parent.YtoPad(GetY1() - GetR2()))); + guide = 't'; + break; + case pBot: + changeY(parent.YtoAbsPixel(parent.YtoPad(GetY1() + GetR2())), py); + guide = 'b'; + break; + case pINSIDE: + SetX1(GetXCoord(px + sdx, kFALSE, kTRUE)); + SetY1(GetYCoord(py + sdy, kFALSE, kTRUE)); + guide = 'i'; + break; } - pxold = px; - pyold = py; + first_move = kFALSE; + if (opaque) { + parent.ShowGuidelines(this, event, guide, true); + parent.ModifiedUpdate(); + } else + paint_hollow(); break; + } case kButton1Up: if (gROOT->IsEscaped()) { gROOT->SetEscape(kFALSE); if (opaque) { - gPad->ShowGuidelines(this, event); - this->SetX1(oldX1); - this->SetY1(oldY1); - this->SetR1(oldR1); - this->SetR2(oldR2); - gPad->Modified(kTRUE); - gPad->Update(); + parent.ShowGuidelines(this, event); + SetX1(oldX1); + SetY1(oldY1); + SetR1(oldR1); + SetR2(oldR2); + parent.ModifiedUpdate(); } break; } - if (opaque) { - gPad->ShowGuidelines(this, event); - } else { - fX1 = gPad->AbsPixeltoX(px1); - fY1 = gPad->AbsPixeltoY(py1); - fBy = gPad->AbsPixeltoY(py1+r2); - fTy = gPad->AbsPixeltoY(py1-r2); - fLx = gPad->AbsPixeltoX(px1+r1); - fRx = gPad->AbsPixeltoX(px1-r1); - fR1 = TMath::Abs(fRx-fLx)/2; - fR2 = TMath::Abs(fTy-fBy)/2; - gPad->Modified(kTRUE); - gVirtualX->SetLineColor(-1); - } + if (opaque) + parent.ShowGuidelines(this, event); + else + parent.Modified(kTRUE); + mode = pNone; } } @@ -553,56 +399,74 @@ void TEllipse::ls(Option_t *) const void TEllipse::Paint(Option_t *option) { - PaintEllipse(fX1,fY1,fR1,fR2,fPhimin,fPhimax,fTheta,option); + PaintEllipse(fX1, fY1, fR1, fR2, fPhimin, fPhimax, fTheta, option); } //////////////////////////////////////////////////////////////////////////////// -/// Draw this ellipse with new coordinates. +/// Fill points which can be used for the painting +/// Return true if full 360 ellipse is created -void TEllipse::PaintEllipse(Double_t x1, Double_t y1, Double_t r1, Double_t r2, - Double_t phimin, Double_t phimax, Double_t theta, - Option_t *option) +Bool_t TEllipse::FillPoints(TVirtualPad &pad, std::vector &x, std::vector &y, + Double_t x1, Double_t y1, Double_t r1, Double_t r2, Double_t phimin, Double_t phimax, Double_t theta) { - if (!gPad) return; const Int_t np = 200; - static Double_t x[np+3], y[np+3]; - TAttLine::Modify(); //Change line attributes only if necessary - TAttFill::Modify(); //Change fill attributes only if necessary - Double_t phi1 = TMath::Min(phimin,phimax); - Double_t phi2 = TMath::Max(phimin,phimax); + Double_t phi1 = TMath::Min(phimin, phimax); + Double_t phi2 = TMath::Max(phimin, phimax); //set number of points approximatively proportional to the ellipse circumference Double_t circ = kPI*(r1+r2)*(phi2-phi1)/360; - Int_t n = (Int_t)(np*circ/((gPad->GetX2()-gPad->GetX1())+(gPad->GetY2()-gPad->GetY1()))); - if (n < 8) n= 8; - if (n > np) n = np; - Double_t angle,dx,dy; + Int_t n = (Int_t)(np*circ/((pad.GetX2() - pad.GetX1())+(pad.GetY2()-pad.GetY1()))); + Bool_t full_circle = phi2-phi1 >= 360; + n = TMath::Min(np, TMath::Max(n, (Int_t) (full_circle ? 36 : 8))); + + x.resize(n + (full_circle ? 1 : 3)); + y.resize(n + (full_circle ? 1 : 3)); + Double_t dphi = (phi2-phi1)*kPI/(180*n); Double_t ct = TMath::Cos(kPI*theta/180); Double_t st = TMath::Sin(kPI*theta/180); - for (Int_t i=0;i<=n;i++) { - angle = phi1*kPI/180 + Double_t(i)*dphi; - dx = r1*TMath::Cos(angle); - dy = r2*TMath::Sin(angle); - x[i] = gPad->XtoPad(x1 + dx*ct - dy*st); - y[i] = gPad->YtoPad(y1 + dx*st + dy*ct); + for (Int_t i = 0; i <= n; i++) { + Double_t angle = phi1*kPI/180 + i*dphi; + Double_t dx = r1*TMath::Cos(angle); + Double_t dy = r2*TMath::Sin(angle); + x[i] = pad.XtoPad(x1 + dx*ct - dy*st); + y[i] = pad.YtoPad(y1 + dx*st + dy*ct); } - TString opt = option; - opt.ToLower(); - if (phi2-phi1 >= 360 ) { - if (GetFillStyle()) gPad->PaintFillArea(n,x,y); - if (GetLineStyle()) gPad->PaintPolyLine(n+1,x,y); - } else { - x[n+1] = gPad->XtoPad(x1); - y[n+1] = gPad->YtoPad(y1); + if (!full_circle) { + x[n+1] = pad.XtoPad(x1); + y[n+1] = pad.YtoPad(y1); x[n+2] = x[0]; y[n+2] = y[0]; - if (GetFillStyle()) gPad->PaintFillArea(n+2,x,y); - if (GetLineStyle()) { - if (TestBit(kNoEdges) || opt.Contains("only")) gPad->PaintPolyLine(n+1,x,y); - else gPad->PaintPolyLine(n+3,x,y); - } + } + + return full_circle; +} + + +//////////////////////////////////////////////////////////////////////////////// +/// Draw this ellipse with new coordinates. + +void TEllipse::PaintEllipse(Double_t x1, Double_t y1, Double_t r1, Double_t r2, + Double_t phimin, Double_t phimax, Double_t theta, + Option_t *option) +{ + if (!gPad) return; + + std::vector x, y; + Bool_t full_circle = FillPoints(*gPad, x, y, x1, y1, r1, r2, phimin, phimax, theta); + + TAttFill::ModifyOn(*gPad); //Change fill attributes only if necessary + TAttLine::ModifyOn(*gPad); //Change line attributes only if necessary + + if (GetFillStyle() > 0) + gPad->PaintFillArea(x.size() - 1, x.data(), y.data()); + + if (GetLineStyle() > 0) { + TString opt = option; + opt.ToLower(); + Bool_t less_points = !full_circle && (TestBit(kNoEdges) || opt.Contains("only")); + gPad->PaintPolyLine(x.size() - (less_points ? 2 : 0), x.data(), y.data()); } } @@ -716,23 +580,12 @@ TPoint TEllipse::GetBBoxCenter() return p; } -//////////////////////////////////////////////////////////////////////////////// -/// Set center of the Ellipse - -void TEllipse::SetBBoxCenter(const TPoint &p) -{ - if (!gPad) return; - fX1 = gPad->PixeltoX(p.GetX()); - fY1 = gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0)); -} - //////////////////////////////////////////////////////////////////////////////// /// Set X coordinate of the center of the Ellipse void TEllipse::SetBBoxCenterX(const Int_t x) { - if (!gPad) return; - fX1 = gPad->PixeltoX(x); + SetX1(GetXCoord(x)); } //////////////////////////////////////////////////////////////////////////////// @@ -740,8 +593,7 @@ void TEllipse::SetBBoxCenterX(const Int_t x) void TEllipse::SetBBoxCenterY(const Int_t y) { - if (!gPad) return; - fY1 = gPad->PixeltoY(y-gPad->VtoPixel(0)); + SetY1(GetYCoord(y)); } //////////////////////////////////////////////////////////////////////////////// @@ -750,12 +602,11 @@ void TEllipse::SetBBoxCenterY(const Int_t y) void TEllipse::SetBBoxX1(const Int_t x) { - if (!gPad) return; - Double_t x1 = gPad->PixeltoX(x); - if (x1>fX1+fR1) return; + Double_t x1 = GetXCoord(x); + if (x1 > fX1+fR1) return; - fR1 = (fX1+fR1-x1)*0.5; - fX1 = x1 + fR1; + SetR1((fX1+fR1-x1)*0.5); + SetX1(x1 + fR1); } //////////////////////////////////////////////////////////////////////////////// @@ -764,12 +615,11 @@ void TEllipse::SetBBoxX1(const Int_t x) void TEllipse::SetBBoxX2(const Int_t x) { - if (!gPad) return; - Double_t x2 = gPad->PixeltoX(x); - if (x2PixeltoY(y-gPad->VtoPixel(0)); - if (y1PixeltoY(y-gPad->VtoPixel(0)); - - if (y2>fY1+fR2) return; + Double_t y2 = GetYCoord(y); + if (y2 > fY1+fR2) return; - fR2 = (fY1+fR2-y2)*0.5; - fY1 = y2+fR2; + SetR2((fY1+fR2-y2)*0.5); + SetY1(y2 + fR2); } diff --git a/graf2d/graf/src/TLine.cxx b/graf2d/graf/src/TLine.cxx index b0401e31abe3e..ade905fd26d50 100644 --- a/graf2d/graf/src/TLine.cxx +++ b/graf2d/graf/src/TLine.cxx @@ -143,35 +143,22 @@ void TLine::ExecuteEvent(Int_t event, Int_t px, Int_t py) Bool_t opaque = parent.OpaqueMoving(); auto action = [this, &parent](Int_t code, Int_t _x1, Int_t _y1, Int_t _x2 = 0, Int_t _y2 = 0) { - Double_t x1, y1, x2, y2; Bool_t isndc = TestBit(kLineNDC); - if (isndc) { - x1 = (1. * _x1 / parent.GetWw() - parent.GetAbsXlowNDC()) / parent.GetAbsWNDC(); - y1 = ((1 - 1. * _y1 / parent.GetWh()) - parent.GetAbsYlowNDC()) / parent.GetAbsHNDC(); - x2 = (1. * _x2 / parent.GetWw() - parent.GetAbsXlowNDC()) / parent.GetAbsWNDC(); - y2 = ((1 - 1. * _y2 / parent.GetWh()) - parent.GetAbsYlowNDC()) / parent.GetAbsHNDC(); - } else { - x1 = parent.AbsPixeltoX(_x1); - y1 = parent.AbsPixeltoY(_y1); - x2 = parent.AbsPixeltoX(_x2); - y2 = parent.AbsPixeltoY(_y2); - } + Double_t x1 = GetXCoord(_x1, isndc, kTRUE); + Double_t y1 = GetYCoord(_y1, isndc, kTRUE); + Double_t x2 = GetXCoord(_x2, isndc, kTRUE); + Double_t y2 = GetYCoord(_y2, isndc, kTRUE); + if (code == 0) { auto pp = parent.GetPainter(); pp->SetAttLine(*this); if (isndc) pp->DrawLineNDC(x1, y1, x2, y2); else - pp->DrawLine(x1, y1, x2, y2); + pp->DrawLine(parent.XtoPad(x1), parent.YtoPad(y1), parent.XtoPad(x2), parent.YtoPad(y2)); } else { - if (!isndc) { - x1 = parent.PadtoX(x1); - x2 = parent.PadtoX(x2); - y1 = parent.PadtoY(y1); - y2 = parent.PadtoY(y2); - } if (code & 1) { SetX1(x1); diff --git a/graf2d/graf/src/TText.cxx b/graf2d/graf/src/TText.cxx index ad0410d198e5f..b736c94e91af8 100644 --- a/graf2d/graf/src/TText.cxx +++ b/graf2d/graf/src/TText.cxx @@ -15,8 +15,9 @@ #include "TBuffer.h" #include "TVirtualPad.h" #include "TVirtualPadPainter.h" -#include "TVirtualX.h" +#include "TCanvasImp.h" #include "TMath.h" +#include "TAttMarker.h" #include "TPoint.h" #include @@ -142,11 +143,9 @@ Int_t TText::DistancetoPrimitive(Int_t px, Int_t py) if (!gPad) return 9999; Int_t ptx, pty; - TAttText::Modify(); // change text attributes only if necessary - if (TestBit(kTextNDC)) { - ptx = gPad->UtoPixel(fX); - pty = gPad->VtoPixel(fY); + ptx = gPad->UtoAbsPixel(fX); + pty = gPad->VtoAbsPixel(fY); } else { ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX)); pty = gPad->YtoAbsPixel(gPad->YtoPad(fY)); @@ -220,91 +219,91 @@ TText *TText::DrawTextNDC(Double_t x, Double_t y, const wchar_t *text) void TText::ExecuteEvent(Int_t event, Int_t px, Int_t py) { - if (!gPad) return; + if (!gPad || !gPad->IsEditable()) + return; + + auto &parent = *gPad; static Int_t px1, py1, pxold, pyold, Size, height, width; static Bool_t resize,turn; Int_t dx, dy; const char *text = GetTitle(); Int_t len = strlen(text); - Double_t sizetowin = gPad->GetAbsHNDC()*Double_t(gPad->GetWh()); + Double_t sizetowin = parent.GetAbsHNDC()*Double_t(parent.GetWh()); Double_t fh = (fTextSize*sizetowin); Int_t h = Int_t(fh/2); Int_t w = h*len; Short_t halign = fTextAlign/10; Short_t valign = fTextAlign - 10*halign; Double_t co, si, dtheta, norm; - static Bool_t right, ndcsav; + static Bool_t right; static Double_t theta; - Int_t ax, ay, bx, by, cx, cy; - ax = ay = 0; + Int_t ax = 0, ay = 0, bx, by, cx, cy; Double_t lambda, x2,y2; - Double_t dpx,dpy,xp1,yp1; Int_t cBoxX[4], cBoxY[4], part; Double_t div = 0; - Bool_t opaque = gPad->OpaqueMoving(); + Bool_t opaque = parent.OpaqueMoving(); - if (!gPad->IsEditable()) return; switch (event) { case kArrowKeyPress: case kButton1Down: - ndcsav = TestBit(kTextNDC); - // No break !!! - case kMouseMotion: if (TestBit(kTextNDC)) { - px1 = gPad->UtoPixel(fX); - py1 = gPad->VtoPixel(fY); + px1 = parent.UtoAbsPixel(fX); + py1 = parent.VtoAbsPixel(fY); } else { - px1 = gPad->XtoAbsPixel(gPad->XtoPad(fX)); - py1 = gPad->YtoAbsPixel(gPad->YtoPad(fY)); + px1 = parent.XtoAbsPixel(parent.XtoPad(fX)); + py1 = parent.YtoAbsPixel(parent.YtoPad(fY)); } - theta = fTextAngle; + theta = GetTextAngle(); Size = 0; pxold = px; pyold = py; - co = TMath::Cos(fTextAngle*0.017453293); - si = TMath::Sin(fTextAngle*0.017453293); + co = TMath::Cos(theta*0.017453293); + si = TMath::Sin(theta*0.017453293); resize = kFALSE; turn = kFALSE; GetControlBox(px1, py1, -theta, cBoxX, cBoxY); div = ((cBoxX[3]-cBoxX[0])*co-(cBoxY[3]-cBoxY[0])*si); - if (TMath::Abs(div) > 1e-8) part = (Int_t)(3*((px-cBoxX[0])*co-(py-cBoxY[0])*si)/ div); - else part = 0; + if (TMath::Abs(div) > 1e-8) + part = (Int_t)(3*((px-cBoxX[0])*co-(py-cBoxY[0])*si)/ div); + else + part = 0; switch (part) { case 0: if (halign == 3) { turn = kTRUE; right = kTRUE; - gPad->SetCursor(kRotate); + parent.SetCursor(kRotate); } else { resize = kTRUE; height = valign; width = halign; - gPad->SetCursor(kArrowVer); + parent.SetCursor(kArrowVer); } break; case 1: - gPad->SetCursor(kMove); + parent.SetCursor(kMove); break; case 2: if (halign == 3) { resize = kTRUE; height = valign; width = halign; - gPad->SetCursor(kArrowVer); + parent.SetCursor(kArrowVer); } else { turn = kTRUE; right = kFALSE; - gPad->SetCursor(kRotate); + parent.SetCursor(kRotate); } } break; case kArrowKeyRelease: case kButton1Motion: - if (!opaque) PaintControlBox(px1, py1, -theta); + if (!opaque) + PaintControlBox(px1, py1, -theta); if (turn) { norm = TMath::Sqrt(Double_t((py-py1)*(py-py1)+(px-px1)*(px-px1))); if (norm>0) { @@ -316,7 +315,6 @@ void TText::ExecuteEvent(Int_t event, Int_t px, Int_t py) if (right) {theta = theta+180; if (theta>=360) theta -= 360;} } } else if (resize) { - co = TMath::Cos(fTextAngle*0.017453293); si = TMath::Sin(fTextAngle*0.017453293); if (width == 1) { @@ -340,8 +338,13 @@ void TText::ExecuteEvent(Int_t event, Int_t px, Int_t py) case 3 : ax = px1-Int_t(co*w+si*h*3/2); ay = py1+Int_t(si*w+co*h*3/2); break; } } - if (height == 3) {bx = ax-Int_t(si*h); by = ay-Int_t(co*h);} - else {bx = ax; by = ay;} + if (height == 3) { + bx = ax-Int_t(si*h); + by = ay-Int_t(co*h); + } else { + bx = ax; + by = ay; + } cx = bx+Int_t(co*w); cy = by-Int_t(si*w); lambda = Double_t(((px-bx)*(cx-bx)+(py-by)*(cy-by)))/Double_t(((cx-bx)*(cx-bx)+(cy-by)*(cy-by))); x2 = Double_t(px) - lambda*Double_t(cx-bx)-Double_t(bx); @@ -350,49 +353,35 @@ void TText::ExecuteEvent(Int_t event, Int_t px, Int_t py) if (Size<4) Size = 4; SetTextSize(Size/sizetowin); - TAttText::Modify(); } else { dx = px - pxold; px1 += dx; dy = py - pyold; py1 += dy; } if (opaque) { - if (ndcsav) this->SetNDC(kFALSE); - this->SetX(gPad->PadtoX(gPad->AbsPixeltoX(px1))); - this->SetY(gPad->PadtoY(gPad->AbsPixeltoY(py1))); - if (resize) gPad->ShowGuidelines(this, event, 't', false); - if ((!resize)&&(!turn)) gPad->ShowGuidelines(this, event, 'i', true); - gPad->ShowGuidelines(this, event, !resize&!turn); - this->SetTextAngle(theta); - gPad->Modified(kTRUE); - gPad->Update(); + SetX(GetXCoord(px1, TestBit(kTextNDC), kTRUE)); + SetY(GetYCoord(py1, TestBit(kTextNDC), kTRUE)); + if (resize) + parent.ShowGuidelines(this, event, 't', false); + if (!resize && !turn) + parent.ShowGuidelines(this, event, 'i', true); + parent.ShowGuidelines(this, event, !resize && !turn); + SetTextAngle(theta); + parent.ModifiedUpdate(); } - if (!opaque) PaintControlBox(px1, py1, -theta); + if (!opaque) + PaintControlBox(px1, py1, -theta); pxold = px; pyold = py; break; case kButton1Up: if (opaque) { - if (ndcsav && !this->TestBit(kTextNDC)) { - this->SetX((fX - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1())); - this->SetY((fY - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1())); - this->SetNDC(); - } - gPad->ShowGuidelines(this, event, !resize&!turn); + parent.ShowGuidelines(this, event, !resize && !turn); } else { - if (TestBit(kTextNDC)) { - dpx = gPad->GetX2() - gPad->GetX1(); - dpy = gPad->GetY2() - gPad->GetY1(); - xp1 = gPad->GetX1(); - yp1 = gPad->GetY1(); - fX = (gPad->AbsPixeltoX(px1)-xp1)/dpx; - fY = (gPad->AbsPixeltoY(py1)-yp1)/dpy; - } else { - fX = gPad->PadtoX(gPad->AbsPixeltoX(px1)); - fY = gPad->PadtoY(gPad->AbsPixeltoY(py1)); - } - fTextAngle = theta; + SetX(GetXCoord(px1, TestBit(kTextNDC), kTRUE)); + SetY(GetYCoord(py1, TestBit(kTextNDC), kTRUE)); + SetTextAngle(theta); } - gPad->Modified(kTRUE); + parent.Modified(kTRUE); break; case kButton1Locate: @@ -400,7 +389,7 @@ void TText::ExecuteEvent(Int_t event, Int_t px, Int_t py) while (1) { px = py = 0; - event = gVirtualX->RequestLocator(1, 1, px, py); + event = parent.GetCanvasImp()->RequestLocator(px, py); ExecuteEvent(kButton1Motion, px, py); @@ -422,10 +411,15 @@ void TText::GetControlBox(Int_t x, Int_t y, Double_t theta, { Short_t halign = fTextAlign/10; // horizontal alignment Short_t valign = fTextAlign - 10*halign; // vertical alignment - UInt_t cBoxW, cBoxH; // control box width and heigh + UInt_t cBoxW = 0, cBoxH = 0; // control box width and heigh UInt_t Dx = 0, Dy = 0; // delta along x and y to align the box - GetBoundingBox(cBoxW, cBoxH); + if (gPad) { + Double_t tsize = GetTextSizePixels(*gPad); + auto pp = gPad->GetPainter(); + if (pp) + pp->GetTextExtent(GetTextFont(), tsize, cBoxW, cBoxH, GetTitle()); + } // compute the translations (Dx, Dy) required by the alignments switch (halign) { @@ -481,8 +475,8 @@ void TText::GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle) Int_t cBoxX[4], cBoxY[4]; Int_t ptx, pty; if (TestBit(kTextNDC)) { - ptx = gPad->UtoPixel(fX); - pty = gPad->VtoPixel(fY); + ptx = gPad->UtoAbsPixel(fX); + pty = gPad->VtoAbsPixel(fY); } else { ptx = gPad->XtoAbsPixel(gPad->XtoPad(fX)); pty = gPad->YtoAbsPixel(gPad->YtoPad(fY)); @@ -498,8 +492,8 @@ void TText::GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle) if (cBoxY[i] < y1) y1 = cBoxY[i]; if (cBoxY[i] > y2) y2 = cBoxY[i]; } - w = x2-x1; - h = y2-y1; + w = x2 - x1; + h = y2 - y1; } else { Double_t tsize = GetTextSizePixels(*gPad); auto pp = gPad->GetPainter(); @@ -625,14 +619,20 @@ void TText::PaintControlBox(Int_t x, Int_t y, Double_t theta) Short_t valign = fTextAlign - 10*halign; // vertical alignment GetControlBox(x, y, theta, cBoxX, cBoxY); + + auto pp = gPad->GetPainter(); + if (!pp) + return; + // Draw the text control box outline - gVirtualX->SetLineStyle((Style_t)1); - gVirtualX->SetLineWidth(1); - gVirtualX->SetLineColor(1); - gVirtualX->DrawLine(cBoxX[0], cBoxY[0], cBoxX[1], cBoxY[1]); - gVirtualX->DrawLine(cBoxX[1], cBoxY[1], cBoxX[2], cBoxY[2]); - gVirtualX->DrawLine(cBoxX[2], cBoxY[2], cBoxX[3], cBoxY[3]); - gVirtualX->DrawLine(cBoxX[3], cBoxY[3], cBoxX[0], cBoxY[0]); + pp->SetAttLine({(Style_t)1, 1, 1}); + for (int p1 = 0; p1 < 4; ++p1) { + int p2 = (p1 + 1) % 4; + pp->DrawLine(gPad->AbsPixeltoX(cBoxX[p1]), + gPad->AbsPixeltoY(cBoxY[p1]), + gPad->AbsPixeltoX(cBoxX[p2]), + gPad->AbsPixeltoY(cBoxY[p2])); + } // Draw a symbol at the text starting point TPoint p; @@ -660,12 +660,10 @@ void TText::PaintControlBox(Int_t x, Int_t y, Double_t theta) } break; } - p.fX = (cBoxX[ix]+cBoxX[iy])/2; - p.fY = (cBoxY[ix]+cBoxY[iy])/2; - gVirtualX->SetMarkerColor(1); - gVirtualX->SetMarkerStyle(24); - gVirtualX->SetMarkerSize(0.7); - gVirtualX->DrawPolyMarker(1, &p); + Double_t mX = gPad->AbsPixeltoX((cBoxX[ix]+cBoxX[iy])/2); + Double_t mY = gPad->AbsPixeltoY((cBoxY[ix]+cBoxY[iy])/2); + pp->SetAttMarker({(Color_t)1, 24, 0.7}); + pp->DrawPolyMarker(1, &mX, &mY); } //////////////////////////////////////////////////////////////////////////////// @@ -787,7 +785,7 @@ void TText::Streamer(TBuffer &R__b) Rectangle_t TText::GetBBox() { - Rectangle_t BBox{0, 0, 0, 0}; + Rectangle_t bbox{0, 0, 0, 0}; if (gPad) { UInt_t w, h; Int_t Dx = 0, Dy = 0; @@ -807,13 +805,17 @@ Rectangle_t TText::GetBBox() case 2: Dy = h / 2; break; case 3: Dy = 0; break; } - - BBox.fX = gPad->XtoPixel(fX) - Dx; - BBox.fY = gPad->YtoPixel(fY) - Dy; - BBox.fWidth = w; - BBox.fHeight = h; + if (TestBit(kTextNDC)) { + bbox.fX = gPad->UtoPixel(GetX()) - Dx; + bbox.fY = gPad->VtoPixel(GetY()) - Dy; + } else { + bbox.fX = gPad->XtoPixel(gPad->XtoPad(GetX())) - Dx; + bbox.fY = gPad->YtoPixel(gPad->YtoPad(GetY())) - Dy; + } + bbox.fWidth = w; + bbox.fHeight = h; } - return BBox; + return bbox; } //////////////////////////////////////////////////////////////////////////////// @@ -823,29 +825,23 @@ TPoint TText::GetBBoxCenter() { TPoint p(0, 0); if (gPad) { - p.SetX(gPad->XtoPixel(fX)); - p.SetY(gPad->YtoPixel(fY)); + if (TestBit(kTextNDC)) { + p.SetX(gPad->UtoPixel(GetX())); + p.SetY(gPad->VtoPixel(GetY())); + } else { + p.SetX(gPad->XtoPixel(gPad->XtoPad(GetX()))); + p.SetY(gPad->YtoPixel(gPad->YtoPad(GetY()))); + } } return p; } -//////////////////////////////////////////////////////////////////////////////// -/// Set the point given by Alignment as 'center' - -void TText::SetBBoxCenter(const TPoint &p) -{ - if (!gPad) return; - this->SetX(gPad->PixeltoX(p.GetX())); - this->SetY(gPad->PixeltoY(p.GetY()-gPad->VtoPixel(0))); -} - //////////////////////////////////////////////////////////////////////////////// /// Set X coordinate of the point given by Alignment as 'center' void TText::SetBBoxCenterX(const Int_t x) { - if (!gPad) return; - this->SetX(gPad->PixeltoX(x)); + SetX(GetXCoord(x, TestBit(kTextNDC))); } //////////////////////////////////////////////////////////////////////////////// @@ -853,41 +849,5 @@ void TText::SetBBoxCenterX(const Int_t x) void TText::SetBBoxCenterY(const Int_t y) { - if (!gPad) return; - this->SetY(gPad->PixeltoY(y - gPad->VtoPixel(0))); -} - -//////////////////////////////////////////////////////////////////////////////// -/// Set left hand side of BoundingBox to a value -/// (resize in x direction on left) - -void TText::SetBBoxX1(const Int_t /*x*/) -{ - //NOT IMPLEMENTED -} - -//////////////////////////////////////////////////////////////////////////////// -/// Set right hand side of BoundingBox to a value -/// (resize in x direction on right) - -void TText::SetBBoxX2(const Int_t /*x*/) -{ - //NOT IMPLEMENTED -} - -//////////////////////////////////////////////////////////////////////////////// -/// Set top of BoundingBox to a value (resize in y direction on top) - -void TText::SetBBoxY1(const Int_t /*y*/) -{ - //NOT IMPLEMENTED -} - -//////////////////////////////////////////////////////////////////////////////// -/// Set bottom of BoundingBox to a value -/// (resize in y direction on bottom) - -void TText::SetBBoxY2(const Int_t /*y*/) -{ - //NOT IMPLEMENTED + SetY(GetYCoord(y, TestBit(kTextNDC))); } diff --git a/graf2d/quartz/inc/QuartzLine.h b/graf2d/quartz/inc/QuartzLine.h index cff6c96459af6..762f82f669c1e 100644 --- a/graf2d/quartz/inc/QuartzLine.h +++ b/graf2d/quartz/inc/QuartzLine.h @@ -34,7 +34,7 @@ void SetLineStyle(CGContextRef ctx, Int_t lstyle); void SetLineWidth(CGContextRef ctx, Int_t width); void DrawLine(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2); -void DrawPolyLine(CGContextRef ctx, Int_t n, TPoint * xy); +void DrawPolyLine(CGContextRef ctx, Int_t n, const TPoint *xy); } } diff --git a/graf2d/quartz/inc/QuartzMarker.h b/graf2d/quartz/inc/QuartzMarker.h index 9191799fcc4d6..533a85d9e1594 100644 --- a/graf2d/quartz/inc/QuartzMarker.h +++ b/graf2d/quartz/inc/QuartzMarker.h @@ -27,14 +27,13 @@ #include "Rtypes.h" #include "TPoint.h" +#include "TAttMarker.h" namespace ROOT { namespace Quartz { -void DrawPolyMarker(CGContextRef ctx, const std::vector &marker, - Size_t markerSize, Style_t markerStyle); void DrawPolyMarker(CGContextRef ctx, unsigned nPoints, const TPoint *marker, - Size_t markerSize, Style_t markerStyle); + const TAttMarker &attmark, float scaleFactor); } } diff --git a/graf2d/quartz/src/QuartzLine.mm b/graf2d/quartz/src/QuartzLine.mm index 36e33e7c133d7..9568073919a5d 100644 --- a/graf2d/quartz/src/QuartzLine.mm +++ b/graf2d/quartz/src/QuartzLine.mm @@ -133,7 +133,7 @@ void DrawLine(CGContextRef ctx, Int_t x1, Int_t y1, Int_t x2, Int_t y2) //______________________________________________________________________________ -void DrawPolyLine(CGContextRef ctx, Int_t n, TPoint * xy) +void DrawPolyLine(CGContextRef ctx, Int_t n, const TPoint *xy) { // Draw a line through all points. // n : number of points diff --git a/graf2d/quartz/src/QuartzMarker.mm b/graf2d/quartz/src/QuartzMarker.mm index 87af296b0cb6a..ee2cd6771c785 100644 --- a/graf2d/quartz/src/QuartzMarker.mm +++ b/graf2d/quartz/src/QuartzMarker.mm @@ -12,6 +12,9 @@ #include "TAttMarker.h" #include "QuartzMarker.h" +#include "QuartzLine.h" +#include "QuartzFillArea.h" +#include "TMath.h" namespace ROOT { namespace Quartz { @@ -906,8 +909,32 @@ void DrawMarkerFourSquaresPlus(CGContextRef ctx, unsigned n, const TPoint *xy, //______________________________________________________________________________ void DrawPolyMarker(CGContextRef ctx, unsigned nPoints, const TPoint *xy, - Size_t markerSize, Style_t markerStyle) + const TAttMarker &attmark, float scaleFactor) { + if (!Quartz::SetFillColor(ctx, attmark.GetMarkerColor())) + return; + + Quartz::SetLineColor(ctx, attmark.GetMarkerColor());//Can not fail (for coverity). + Quartz::SetLineStyle(ctx, 1); + Quartz::SetLineWidth(ctx, TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(attmark.GetMarkerStyle())))); + + if (scaleFactor > 1.) + CGContextScaleCTM(ctx, 1. / scaleFactor, 1. / scaleFactor); + + Style_t markerStyle = TAttMarker::GetMarkerStyleBase(attmark.GetMarkerStyle()); + + // The fast pixel markers need to be treated separately + if (markerStyle == 1 || markerStyle == 6 || markerStyle == 7) { + CGContextSetLineJoin(ctx, kCGLineJoinMiter); + CGContextSetLineCap(ctx, kCGLineCapButt); + } else { + CGContextSetLineJoin(ctx, kCGLineJoinRound); + CGContextSetLineCap(ctx, kCGLineCapRound); + } + + Float_t markerSize = attmark.GetMarkerSize() - TMath::Floor(TAttMarker::GetMarkerLineWidth(attmark.GetMarkerStyle())/2.)/4.; + markerSize *= scaleFactor; + switch (markerStyle) { case kDot: DrawMarkerDot(ctx, nPoints, xy, markerSize); @@ -1018,15 +1045,11 @@ void DrawPolyMarker(CGContextRef ctx, unsigned nPoints, const TPoint *xy, DrawMarkerFourSquaresPlus(ctx, nPoints, xy, markerSize); break; } -} - -//______________________________________________________________________________ -void DrawPolyMarker(CGContextRef ctx, const std::vector &xy, - Size_t markerSize, Style_t markerStyle) -{ - DrawPolyMarker(ctx, xy.size(), &xy[0], markerSize, markerStyle); + CGContextSetLineJoin(ctx, kCGLineJoinMiter); + CGContextSetLineCap(ctx, kCGLineCapButt); } + }//namespace Quartz }//namespace ROOT diff --git a/graf3d/gl/inc/TGLPadPainter.h b/graf3d/gl/inc/TGLPadPainter.h index b77c8a6178baf..082534627c988 100644 --- a/graf3d/gl/inc/TGLPadPainter.h +++ b/graf3d/gl/inc/TGLPadPainter.h @@ -43,13 +43,20 @@ class TGLPadPainter : public TPadPainterBase { Int_t fVp[4]; - std::vector fPoly; Bool_t fIsHollowArea; Bool_t fLocked; + Bool_t IsInvertMode(); + void SelectGLFont(Font_t font, Float_t size); + template + void DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y); + + template + void DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y); + template void DrawTextHelper(Double_t x, Double_t y, const Char_t *text, ETextMode mode); @@ -144,8 +151,6 @@ class TGLPadPainter : public TPadPainterBase { void SaveViewport(); void RestoreViewport(); - void DrawPolyMarker(); - //Aux. functions for a gradient and solid fill: void DrawPolygonWithGradient(Int_t n, const Double_t *x, const Double_t *y); // diff --git a/graf3d/gl/src/TGLPadPainter.cxx b/graf3d/gl/src/TGLPadPainter.cxx index 83e4ebca52504..58649477b6453 100644 --- a/graf3d/gl/src/TGLPadPainter.cxx +++ b/graf3d/gl/src/TGLPadPainter.cxx @@ -355,11 +355,10 @@ void TGLPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) //that TView3D wants to draw itself in a XOR mode, via //gVirtualX. // TODO: only here set line attributes to virtual x - if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) { + if (IsInvertMode()) gVirtualX->DrawLineW(fWinContext, gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1), gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2)); - } return; } @@ -395,13 +394,11 @@ void TGLPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) void TGLPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) { if (fLocked) { - // this code used when crosshair cursor is drawn - if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) { - // TODO: only here set line attributes to virtual x + // this code used when crosshair cursor is drawn or interactive objects move + if (IsInvertMode()) gVirtualX->DrawLineW(fWinContext, gPad->UtoAbsPixel(u1), gPad->VtoAbsPixel(v1), gPad->UtoAbsPixel(u2), gPad->VtoAbsPixel(v2)); - } return; } @@ -427,12 +424,11 @@ void TGLPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, //that TView3D wants to draw itself in a XOR mode, via //gVirtualX. // TODO: only here set line attributes to virtual x - if (fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert)) { + if (IsInvertMode()) gVirtualX->DrawBoxW(fWinContext, gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1), gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2), (TVirtualX::EBoxMode) mode); - } return; } @@ -445,11 +441,12 @@ void TGLPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, if (mode == kHollow) { const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, 0, fLimits.GetMaxLineWidth(), kTRUE, &GetAttLine()); - // - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glRectd(x1, y1, x2, y2); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glLineWidth(1.f); + glBegin(GL_LINE_LOOP); + glVertex2d(x1, y1); + glVertex2d(x2, y1); + glVertex2d(x2, y2); + glVertex2d(x1, y2); + glEnd(); } else { const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE, &fGlFillAtt);//Set filling parameters. glRectd(x1, y1, x2, y2); @@ -521,9 +518,20 @@ void TGLPadPainter::DrawFillArea(Int_t n, const Float_t *x, const Float_t *y) //////////////////////////////////////////////////////////////////////////////// ///Draw poly-line in user coordinates. -void TGLPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) +template +void TGLPadPainter::DrawPolyLineHelper(Int_t n, const ValueType *x, const ValueType *y) { - if (fLocked) return; + if (fLocked) { + if (IsInvertMode() && (n > 1)) { + std::vector xy(n); + for (Int_t i = 0; i < n; ++i) { + xy[i].fX = (SCoord_t) gPad->XtoAbsPixel(x[i]); + xy[i].fY = (SCoord_t) gPad->YtoAbsPixel(y[i]); + } + gVirtualX->DrawPolyLineW(fWinContext, xy.size(), xy.data()); + } + return; + } const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, GetAttLine().GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE, &GetAttLine()); @@ -556,25 +564,19 @@ void TGLPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) } //////////////////////////////////////////////////////////////////////////////// -///Never called? +/// Draw poly-line in user coordinates. -void TGLPadPainter::DrawPolyLine(Int_t n, const Float_t *x, const Float_t *y) +void TGLPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y) { - if (fLocked) return; - - const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, GetAttLine().GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE, &GetAttLine()); - - glBegin(GL_LINE_STRIP); - - for (Int_t i = 0; i < n; ++i) - glVertex2f(x[i], y[i]); + DrawPolyLineHelper(n, x, y); +} - if (fIsHollowArea) { - glVertex2f(x[0], y[0]); - fIsHollowArea = kFALSE; - } +//////////////////////////////////////////////////////////////////////////////// +/// Draw poly-line in user coordinates. - glEnd(); +void TGLPadPainter::DrawPolyLine(Int_t n, const Float_t *x, const Float_t *y) +{ + DrawPolyLineHelper(n, x, y); } //////////////////////////////////////////////////////////////////////////////// @@ -597,47 +599,45 @@ void TGLPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t * glEnd(); } -namespace { - -//Aux. function. -template -void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector & dst); - -} - //////////////////////////////////////////////////////////////////////////////// -///Poly-marker. +/// Returns true when invert mode is configured and painter in locked state +/// Used when non-opaque of objects moving is involved -void TGLPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) +Bool_t TGLPadPainter::IsInvertMode() { - if (fLocked) return; - - ConvertMarkerPoints(n, x, y, fPoly); - DrawPolyMarker(); + return fWinContext && (gVirtualX->GetDrawModeW(fWinContext) == TVirtualX::kInvert); } //////////////////////////////////////////////////////////////////////////////// -///Poly-marker. +///Poly-marker drawing -void TGLPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y) +template +void TGLPadPainter::DrawPolyMarkerHelper(Int_t n, const ValueType *x, const ValueType *y) { - if (fLocked) return; + std::vector poly(n); - ConvertMarkerPoints(n, x, y, fPoly); - DrawPolyMarker(); -} + if (fLocked) { + if (IsInvertMode()) { + for (Int_t i = 0; i < n; ++i) { + poly[i].fX = gPad->XtoAbsPixel(x[i]); + poly[i].fY = gPad->YtoAbsPixel(y[i]); + } + gVirtualX->DrawPolyMarkerW(fWinContext, poly.size(), poly.data()); + } + return; + } -//////////////////////////////////////////////////////////////////////////////// -///Poly-marker. + const UInt_t padH = gPad->GetPadHeight(); -void TGLPadPainter::DrawPolyMarker() -{ - if (fLocked) return; + for (Int_t i = 0; i < n; ++i) { + poly[i].fX = gPad->XtoPixel(x[i]); + poly[i].fY = padH - gPad->YtoPixel(y[i]); + } SaveProjectionMatrix(); glLoadIdentity(); // - glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.); + glOrtho(0, gPad->GetPadWidth(), 0, gPad->GetPadHeight(), -10., 10.); // glMatrixMode(GL_MODELVIEW); // @@ -648,127 +648,124 @@ void TGLPadPainter::DrawPolyMarker() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4fv(rgba); - const Width_t w = TMath::Max(1, Int_t(TAttMarker::GetMarkerLineWidth(GetAttMarker().GetMarkerStyle()))); glLineWidth(w > fLimits.GetMaxLineWidth() ? fLimits.GetMaxLineWidth() : !w ? 1.f : w); fMarker.SetMarkerSizeWidth(GetAttMarker().GetMarkerSize(), w); - const TPoint *xy = &fPoly[0]; const Style_t markerStyle = TAttMarker::GetMarkerStyleBase(GetAttMarker().GetMarkerStyle()); - const UInt_t n = UInt_t(fPoly.size()); switch (markerStyle) { case kDot: - fMarker.DrawDot(n, xy); + fMarker.DrawDot(n, poly.data()); break; case kPlus: - fMarker.DrawPlus(n, xy); + fMarker.DrawPlus(n, poly.data()); break; case kStar: case 31: - fMarker.DrawStar(n, xy); + fMarker.DrawStar(n, poly.data()); break; case kCircle: case kOpenCircle: - fMarker.DrawCircle(n, xy); + fMarker.DrawCircle(n, poly.data()); break; case kMultiply: - fMarker.DrawX(n, xy); + fMarker.DrawX(n, poly.data()); break; case kFullDotSmall://"Full dot small" - fMarker.DrawFullDotSmall(n, xy); + fMarker.DrawFullDotSmall(n, poly.data()); break; case kFullDotMedium: - fMarker.DrawFullDotMedium(n, xy); + fMarker.DrawFullDotMedium(n, poly.data()); break; case kFullDotLarge: case kFullCircle: - fMarker.DrawFullDotLarge(n, xy); + fMarker.DrawFullDotLarge(n, poly.data()); break; case kFullSquare: - fMarker.DrawFullSquare(n, xy); + fMarker.DrawFullSquare(n, poly.data()); break; case kFullTriangleUp: - fMarker.DrawFullTrianlgeUp(n, xy); + fMarker.DrawFullTrianlgeUp(n, poly.data()); break; case kFullTriangleDown: - fMarker.DrawFullTrianlgeDown(n, xy); + fMarker.DrawFullTrianlgeDown(n, poly.data()); break; case kOpenSquare: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - fMarker.DrawFullSquare(n, xy); + fMarker.DrawFullSquare(n, poly.data()); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case kOpenTriangleUp: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - fMarker.DrawFullTrianlgeUp(n, xy); + fMarker.DrawFullTrianlgeUp(n, poly.data()); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case kOpenDiamond: - fMarker.DrawDiamond(n, xy); + fMarker.DrawDiamond(n, poly.data()); break; case kOpenCross: - fMarker.DrawOpenCross(n, xy); + fMarker.DrawOpenCross(n, poly.data()); break; case kFullStar: - fMarker.DrawFullStar(n, xy); + fMarker.DrawFullStar(n, poly.data()); break; case kOpenStar: - fMarker.DrawOpenStar(n, xy); + fMarker.DrawOpenStar(n, poly.data()); break; case kOpenTriangleDown: - fMarker.DrawOpenTrianlgeDown(n, xy); + fMarker.DrawOpenTrianlgeDown(n, poly.data()); break; case kFullDiamond: - fMarker.DrawFullDiamond(n, xy); + fMarker.DrawFullDiamond(n, poly.data()); break; case kFullCross: - fMarker.DrawFullCross(n, xy); + fMarker.DrawFullCross(n, poly.data()); break; case kOpenDiamondCross: - fMarker.DrawOpenDiamondCross(n, xy); + fMarker.DrawOpenDiamondCross(n, poly.data()); break; case kOpenSquareDiagonal: - fMarker.DrawOpenSquareDiagonal(n, xy); + fMarker.DrawOpenSquareDiagonal(n, poly.data()); break; case kOpenThreeTriangles: - fMarker.DrawOpenThreeTriangles(n, xy); + fMarker.DrawOpenThreeTriangles(n, poly.data()); break; case kOctagonCross: - fMarker.DrawOctagonCross(n, xy); + fMarker.DrawOctagonCross(n, poly.data()); break; case kFullThreeTriangles: - fMarker.DrawFullThreeTriangles(n, xy); + fMarker.DrawFullThreeTriangles(n, poly.data()); break; case kOpenFourTrianglesX: - fMarker.DrawOpenFourTrianglesX(n, xy); + fMarker.DrawOpenFourTrianglesX(n, poly.data()); break; case kFullFourTrianglesX: - fMarker.DrawFullFourTrianglesX(n, xy); + fMarker.DrawFullFourTrianglesX(n, poly.data()); break; case kOpenDoubleDiamond: - fMarker.DrawOpenDoubleDiamond(n, xy); + fMarker.DrawOpenDoubleDiamond(n, poly.data()); break; case kFullDoubleDiamond: - fMarker.DrawFullDoubleDiamond(n, xy); + fMarker.DrawFullDoubleDiamond(n, poly.data()); break; case kOpenFourTrianglesPlus: - fMarker.DrawOpenFourTrianglesPlus(n, xy); + fMarker.DrawOpenFourTrianglesPlus(n, poly.data()); break; case kFullFourTrianglesPlus: - fMarker.DrawFullFourTrianglesPlus(n, xy); + fMarker.DrawFullFourTrianglesPlus(n, poly.data()); break; case kOpenCrossX: - fMarker.DrawOpenCrossX(n, xy); + fMarker.DrawOpenCrossX(n, poly.data()); break; case kFullCrossX: - fMarker.DrawFullCrossX(n, xy); + fMarker.DrawFullCrossX(n, poly.data()); break; case kFourSquaresX: - fMarker.DrawFourSquaresX(n, xy); + fMarker.DrawFourSquaresX(n, poly.data()); break; case kFourSquaresPlus: - fMarker.DrawFourSquaresPlus(n, xy); + fMarker.DrawFourSquaresPlus(n, poly.data()); break; } @@ -777,6 +774,22 @@ void TGLPadPainter::DrawPolyMarker() glLineWidth(1.f); } +//////////////////////////////////////////////////////////////////////////////// +///Poly-marker. + +void TGLPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) +{ + DrawPolyMarkerHelper(n, x, y); +} + +//////////////////////////////////////////////////////////////////////////////// +///Poly-marker. + +void TGLPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y) +{ + DrawPolyMarkerHelper(n, x, y); +} + //////////////////////////////////////////////////////////////////////////////// /// Select specified font/size @@ -1540,21 +1553,3 @@ void TGLPadPainter::DrawTesselation(Int_t n, const Double_t *x, const Double_t * gluEndPolygon(t); } - -//Aux. functions. -namespace { - -template -void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector & dst) -{ - const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh()); - - dst.resize(n); - for (Int_t i = 0; i < n; ++i) { - dst[i].fX = gPad->XtoPixel(x[i]); - dst[i].fY = padH - gPad->YtoPixel(y[i]); - } -} - -} - diff --git a/test/stressGraphics.ref b/test/stressGraphics.ref index 5b3d019887e4b..e1eff55bae501 100644 --- a/test/stressGraphics.ref +++ b/test/stressGraphics.ref @@ -9,7 +9,7 @@ piechart 67345 200 77066 200 32180 15000 29168 15000 66962 200 ttext1 1025 150 12862 200 33468 9900 30846 5000 1072 200 ttext2 430 50 12729 50 9558 100 5325 700 471 50 - tlatex0 6857 50 15580 50 47722 7000 64693 12000 6890 70 + tlatex0 9558 50 19030 70 47722 7000 64693 12000 9683 70 tlatex1 5130 50 14090 50 16143 1300 12230 500 5170 70 tlatex2 5442 80 13533 50 18430 700 12398 300 5469 80 tlatex3 9253 100 14437 150 19851 2400 12199 900 9283 100 diff --git a/test/stressGraphics_zlibng.ref b/test/stressGraphics_zlibng.ref index 5bd9ccf88228b..8fbf893487bec 100644 --- a/test/stressGraphics_zlibng.ref +++ b/test/stressGraphics_zlibng.ref @@ -9,7 +9,7 @@ piechart 67345 200 74560 3000 32180 15000 29168 15000 66962 200 ttext1 1025 150 12866 150 32266 9900 29901 5000 1072 200 ttext2 432 50 12743 50 9517 150 5306 700 473 50 - tlatex0 6857 50 15570 100 47722 7000 64693 12000 6890 70 + tlatex0 9558 50 19030 70 47722 7000 64693 12000 9683 70 tlatex1 5140 50 14050 50 16377 1300 12462 500 5170 70 tlatex2 5488 80 13507 100 18439 700 12061 500 5502 80 tlatex3 9154 100 14323 150 20441 2400 12143 900 9283 100 diff --git a/test/svg_ref/tlatex0.svg b/test/svg_ref/tlatex0.svg index 44ca63a6a96ea..891bbb0afb702 100644 --- a/test/svg_ref/tlatex0.svg +++ b/test/svg_ref/tlatex0.svg @@ -12,72 +12,120 @@ tlatex0.svg stroke-dasharray=" 1.000, 2.0"/> Font 42 - - + + Align 11 - - + + Align 21 - - + + Align 31 - - + + Align 12 - - + + Align 22 - - + + Align 32 - - + + Align 13 - - + + Align 23 - - + + Align 33 - - + + Align 11 - - + + Align 21 - - + + Align 31 @@ -88,72 +136,120 @@ tlatex0.svg stroke-dasharray=" 1.000, 2.0"/> Font 43 - - + + Align 11 - - + + Align 21 - - + + Align 31 - - + + Align 12 - - + + Align 22 - - + + Align 32 - - + + Align 13 - - + + Align 23 - - + + Align 33 - - + + Align 11 - - + + Align 21 - - + + Align 31 diff --git a/test/svg_ref/waves.svg b/test/svg_ref/waves.svg index 5376057b833e6..47a0d1e4546d9 100644 --- a/test/svg_ref/waves.svg +++ b/test/svg_ref/waves.svg @@ -40055,12 +40055,12 @@ waves.svg 350 - - - - - - + + + + + +