diff --git a/core/base/inc/TVirtualPadPainter.h b/core/base/inc/TVirtualPadPainter.h index 830d0bc8acb4e..dcfb518b3d12b 100644 --- a/core/base/inc/TVirtualPadPainter.h +++ b/core/base/inc/TVirtualPadPainter.h @@ -15,6 +15,11 @@ #include "Rtypes.h" class TVirtualPad; +class TVirtualPS; +class TAttFill; +class TAttLine; +class TAttMarker; +class TAttText; class TVirtualPadPainter { public: @@ -75,6 +80,11 @@ class TVirtualPadPainter { virtual void SetMarkerStyle(Style_t /* mstyle */ = 1) {} virtual void SetMarkerSize(Size_t /* msize */ = 1) {} + virtual void SetAttFill(const TAttFill &att); + virtual void SetAttLine(const TAttLine &att); + virtual void SetAttMarker(const TAttMarker &att); + virtual void SetAttText(const TAttText &att); + //This part is an interface to X11 pixmap management and to save sub-pads off-screens for OpenGL. //Currently, must be implemented only for X11/GDI virtual Int_t CreateDrawable(UInt_t w, UInt_t h) = 0;//gVirtualX->OpenPixmap @@ -127,6 +137,7 @@ class TVirtualPadPainter { virtual Bool_t IsNative() const { return kFALSE; } virtual Bool_t IsCocoa() const { return kFALSE; } + virtual TVirtualPS *GetPS() const { return nullptr; } static TVirtualPadPainter *PadPainter(Option_t *opt = ""); diff --git a/core/base/inc/TVirtualX.h b/core/base/inc/TVirtualX.h index 6ab0aea521a81..c59de994b8bd8 100644 --- a/core/base/inc/TVirtualX.h +++ b/core/base/inc/TVirtualX.h @@ -67,13 +67,26 @@ class TVirtualX : public TNamed, public TAttLine, public TAttFill, public TAttTe virtual void CreateOpenGLContext(Int_t wid=0); virtual void DeleteOpenGLContext(Int_t wid=0); - //---- OpenGL related stuff, required only with R__HAS_COCOA ---- - virtual Double_t GetOpenGLScalingFactor(); - virtual Window_t CreateOpenGLWindow(Window_t parentID, UInt_t width, UInt_t height, const std::vector > &format); - virtual Handle_t CreateOpenGLContext(Window_t windowID, Handle_t sharedContext); - virtual Bool_t MakeOpenGLContextCurrent(Handle_t ctx, Window_t windowID); - virtual Handle_t GetCurrentOpenGLContext(); - virtual void FlushOpenGLBuffer(Handle_t ctx); + + //---- Old graphics interface ----- + + void SetFillColor(Color_t cindex) override; + void SetFillStyle(Style_t style) override; + void SetLineColor(Color_t cindex) override; + virtual void SetLineType(Int_t n, Int_t *dash); + void SetLineStyle(Style_t linestyle) override; + void SetLineWidth(Width_t width) override; + void SetMarkerColor(Color_t cindex) override; + void SetMarkerSize(Float_t markersize) override; + void SetMarkerStyle(Style_t markerstyle) override; + virtual void SetOpacity(Int_t percent); + virtual void SetRGB(Int_t cindex, Float_t r, Float_t g, Float_t b); + void SetTextAlign(Short_t talign=11) override; + void SetTextColor(Color_t cindex) override; + virtual Int_t SetTextFont(char *fontname, ETextSetMode mode); + void SetTextFont(Font_t fontnumber) override; + virtual void SetTextMagnitude(Float_t mgn); + void SetTextSize(Float_t textsize) override; virtual void DrawBox(Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode); virtual void DrawCellArray(Int_t x1, Int_t y1, Int_t x2, Int_t y2, @@ -87,6 +100,34 @@ class TVirtualX : public TNamed, public TAttLine, public TAttFill, public TAttTe ETextMode mode); virtual void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const wchar_t *text, ETextMode mode); + + //---- New graphics interface ----- + + virtual WinContext_t GetWindowContext(Int_t wid); + virtual void SetAttFill(WinContext_t wctxt, const TAttFill &att); + virtual void SetAttLine(WinContext_t wctxt, const TAttLine &att); + virtual void SetAttMarker(WinContext_t wctxt, const TAttMarker &att); + virtual void SetAttText(WinContext_t wctxt, const TAttText &att); + virtual void SetDrawModeW(WinContext_t wctxt, EDrawMode mode); + + virtual void DrawBoxW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode); + virtual void DrawFillAreaW(WinContext_t wctxt, Int_t n, TPoint *xy); + virtual void DrawLineW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2); + virtual void DrawPolyLineW(WinContext_t wctxt, Int_t n, TPoint *xy); + virtual void DrawLinesSegmentsW(WinContext_t wctxt, Int_t n, TPoint *xy); + virtual void DrawPolyMarkerW(WinContext_t wctxt, Int_t n, TPoint *xy); + virtual void DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode); + virtual void DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, const wchar_t *text, ETextMode mode); + + + //---- OpenGL related stuff, required only with R__HAS_COCOA ---- + virtual Double_t GetOpenGLScalingFactor(); + virtual Window_t CreateOpenGLWindow(Window_t parentID, UInt_t width, UInt_t height, const std::vector > &format); + virtual Handle_t CreateOpenGLContext(Window_t windowID, Handle_t sharedContext); + virtual Bool_t MakeOpenGLContextCurrent(Handle_t ctx, Window_t windowID); + virtual Handle_t GetCurrentOpenGLContext(); + virtual void FlushOpenGLBuffer(Handle_t ctx); + virtual UInt_t ExecCommand(TGWin32Command *code); virtual void GetCharacterUp(Float_t &chupx, Float_t &chupy); EDrawMode GetDrawMode() { return fDrawMode; } @@ -129,23 +170,6 @@ class TVirtualX : public TNamed, public TAttLine, public TAttFill, public TAttTe virtual void SetDoubleBufferOFF(); virtual void SetDoubleBufferON(); virtual void SetDrawMode(EDrawMode mode); - void SetFillColor(Color_t cindex) override; - void SetFillStyle(Style_t style) override; - void SetLineColor(Color_t cindex) override; - virtual void SetLineType(Int_t n, Int_t *dash); - void SetLineStyle(Style_t linestyle) override; - void SetLineWidth(Width_t width) override; - void SetMarkerColor(Color_t cindex) override; - void SetMarkerSize(Float_t markersize) override; - void SetMarkerStyle(Style_t markerstyle) override; - virtual void SetOpacity(Int_t percent); - virtual void SetRGB(Int_t cindex, Float_t r, Float_t g, Float_t b); - void SetTextAlign(Short_t talign=11) override; - void SetTextColor(Color_t cindex) override; - virtual Int_t SetTextFont(char *fontname, ETextSetMode mode); - void SetTextFont(Font_t fontnumber) override; - virtual void SetTextMagnitude(Float_t mgn); - void SetTextSize(Float_t textsize) override; virtual void Sync(Int_t mode); virtual void UpdateWindow(Int_t mode); virtual void Warp(Int_t ix, Int_t iy, Window_t id = 0); diff --git a/core/base/src/TAttFill.cxx b/core/base/src/TAttFill.cxx index c639697e0e9eb..63ad01200416b 100644 --- a/core/base/src/TAttFill.cxx +++ b/core/base/src/TAttFill.cxx @@ -224,10 +224,8 @@ void TAttFill::Modify() void TAttFill::ModifyOn(TVirtualPad *pad) { auto pp = pad ? pad->GetPainter() : nullptr; - if (!pp) - return; - pp->SetFillColor(fFillColor); - pp->SetFillStyle(fFillStyle); + if (pp) + pp->SetAttFill(*this); } //////////////////////////////////////////////////////////////////////////////// diff --git a/core/base/src/TAttLine.cxx b/core/base/src/TAttLine.cxx index 23dae3e5c3386..bc7cd57fafaf0 100644 --- a/core/base/src/TAttLine.cxx +++ b/core/base/src/TAttLine.cxx @@ -256,11 +256,21 @@ void TAttLine::ModifyOn(TVirtualPad *pad) auto pp = pad ? pad->GetPainter() : nullptr; if (!pp) return; - pp->SetLineColor(fLineColor); - pp->SetLineStyle((fLineStyle > 0 && fLineStyle < 30) ? fLineStyle : 1); - pp->SetLineWidth(std::abs(fLineWidth % 100)); -} + Bool_t normal_style = (fLineStyle > 0) && (fLineStyle < 30); + Bool_t normal_width = (fLineWidth >= 0) && (fLineWidth < 100); + + if (normal_style && normal_width) + pp->SetAttLine(*this); + else { + TAttLine att1(*this); + if (!normal_style) + att1.SetLineStyle(1); + if (!normal_width) + att1.SetLineWidth(std::abs(fLineWidth % 100)); + pp->SetAttLine(att1); + } +} //////////////////////////////////////////////////////////////////////////////// /// Reset this line attributes to default values. diff --git a/core/base/src/TAttMarker.cxx b/core/base/src/TAttMarker.cxx index da84a7266dc22..66af8d9945685 100644 --- a/core/base/src/TAttMarker.cxx +++ b/core/base/src/TAttMarker.cxx @@ -330,12 +330,8 @@ void TAttMarker::Modify() void TAttMarker::ModifyOn(TVirtualPad *pad) { auto pp = pad ? pad->GetPainter() : nullptr; - if (!pp) - return; - - pp->SetMarkerColor(fMarkerColor); - pp->SetMarkerSize (fMarkerSize); - pp->SetMarkerStyle(fMarkerStyle); + if (pp) + pp->SetAttMarker(*this); } diff --git a/core/base/src/TAttText.cxx b/core/base/src/TAttText.cxx index 2aee8a5a5cd78..352654c70aac0 100644 --- a/core/base/src/TAttText.cxx +++ b/core/base/src/TAttText.cxx @@ -329,7 +329,6 @@ void TAttText::Modify() ModifyOn(gPad); } - //////////////////////////////////////////////////////////////////////////////// /// Change current text attributes if necessary on specified pad. @@ -339,6 +338,7 @@ void TAttText::ModifyOn(TVirtualPad *pad) if (!pp) return; + Float_t tsize0 = fTextSize; Float_t tsize = fTextSize; // there was difference in text size handling, keep it in one place @@ -362,15 +362,12 @@ void TAttText::ModifyOn(TVirtualPad *pad) } } } - pp->SetTextAngle(fTextAngle); - if (pp->GetTextFont() != fTextFont) { - pp->SetTextFont(fTextFont); - pp->SetTextSize(tsize); - } else if (pp->GetTextSize() != tsize) { - pp->SetTextSize(tsize); - } - pp->SetTextAlign(fTextAlign); - pp->SetTextColor(fTextColor); + + fTextSize = tsize; + + pp->SetAttText(*this); + + fTextSize = tsize0; } diff --git a/core/base/src/TVirtualPadPainter.cxx b/core/base/src/TVirtualPadPainter.cxx index b8d5fe05fbe8a..7fab0ecb3f9a5 100644 --- a/core/base/src/TVirtualPadPainter.cxx +++ b/core/base/src/TVirtualPadPainter.cxx @@ -11,6 +11,10 @@ #include "TVirtualPadPainter.h" #include "TPluginManager.h" +#include "TAttFill.h" +#include "TAttLine.h" +#include "TAttMarker.h" +#include "TAttText.h" /** \class TVirtualPadPainter @@ -96,3 +100,44 @@ void TVirtualPadPainter::DrawTextUrl(Double_t x, Double_t y, const char *text, c { DrawText(x, y, text, kClear); } + +//////////////////////////////////////////////////////////////////////////////// +/// Set fill attributes + +void TVirtualPadPainter::SetAttFill(const TAttFill &att) +{ + SetFillColor(att.GetFillColor()); + SetFillStyle(att.GetFillStyle()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set line attributes + +void TVirtualPadPainter::SetAttLine(const TAttLine &att) +{ + SetLineColor(att.GetLineColor()); + SetLineStyle(att.GetLineStyle()); + SetLineWidth(att.GetLineWidth()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set marker attributes + +void TVirtualPadPainter::SetAttMarker(const TAttMarker &att) +{ + SetMarkerColor(att.GetMarkerColor()); + SetMarkerSize(att.GetMarkerSize()); + SetMarkerStyle(att.GetMarkerStyle()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set text attributes + +void TVirtualPadPainter::SetAttText(const TAttText &att) +{ + SetTextAlign(att.GetTextAlign()); + SetTextAngle(att.GetTextAngle()); + SetTextColor(att.GetTextColor()); + SetTextSize(att.GetTextSize()); + SetTextFont(att.GetTextFont()); +} diff --git a/core/base/src/TVirtualX.cxx b/core/base/src/TVirtualX.cxx index 3de70acf015be..1b9cbe1d8f912 100644 --- a/core/base/src/TVirtualX.cxx +++ b/core/base/src/TVirtualX.cxx @@ -378,6 +378,128 @@ void TVirtualX::DrawText(Int_t /*x*/, Int_t /*y*/, Float_t /*angle*/, { } +//////////////////////////////////////////////////////////////////////////////// +/// Get window drawing context +/// Should remain valid until window exists + +WinContext_t TVirtualX::GetWindowContext(Int_t /* wid */) +{ + return (WinContext_t) 0; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set fill attributes for specified window + +void TVirtualX::SetAttFill(WinContext_t /* wctxt */, const TAttFill &att) +{ + SetFillColor(att.GetFillColor()); + SetFillStyle(att.GetFillStyle()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set line attributes for specified window + +void TVirtualX::SetAttLine(WinContext_t /* wctxt */, const TAttLine &att) +{ + SetLineColor(att.GetLineColor()); + SetLineStyle(att.GetLineStyle()); + SetLineWidth(att.GetLineWidth()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set marker attributes for specified window + +void TVirtualX::SetAttMarker(WinContext_t /* wctxt */, const TAttMarker &att) +{ + SetMarkerColor(att.GetMarkerColor()); + SetMarkerSize(att.GetMarkerSize()); + SetMarkerStyle(att.GetMarkerStyle()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set text attributes for specified window + +void TVirtualX::SetAttText(WinContext_t /* wctxt */, const TAttText &att) +{ + SetTextAlign(att.GetTextAlign()); + SetTextAngle(att.GetTextAngle()); + SetTextColor(att.GetTextColor()); + SetTextSize(att.GetTextSize()); + SetTextFont(att.GetTextFont()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set window draw mode + +void TVirtualX::SetDrawModeW(WinContext_t /* wctxt */, EDrawMode mode) +{ + SetDrawMode(mode); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw box on specified window + +void TVirtualX::DrawBoxW(WinContext_t /* wctxt */, Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode) +{ + DrawBox(x1, y1, x2, y2, mode); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw fill area on specified window + +void TVirtualX::DrawFillAreaW(WinContext_t /* wctxt */, Int_t n, TPoint *xy) +{ + DrawFillArea(n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw line on specified window + +void TVirtualX::DrawLineW(WinContext_t /* wctxt */, Int_t x1, Int_t y1, Int_t x2, Int_t y2) +{ + DrawLine(x1, y1, x2, y2); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw poly line on specified window + +void TVirtualX::DrawPolyLineW(WinContext_t /* wctxt */, Int_t n, TPoint *xy) +{ + DrawPolyLine(n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw line segments on specified window + +void TVirtualX::DrawLinesSegmentsW(WinContext_t /* wctxt */, Int_t n, TPoint *xy) +{ + DrawLinesSegments(n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw poly marker on specified window + +void TVirtualX::DrawPolyMarkerW(WinContext_t /* wctxt */, Int_t n, TPoint *xy) +{ + DrawPolyMarker(n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw text on specified window + +void TVirtualX::DrawTextW(WinContext_t /* wctxt */, Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) +{ + DrawText(x, y, angle, mgn, text, mode); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw wtext on specified window + +void TVirtualX::DrawTextW(WinContext_t /* wctxt */, Int_t x, Int_t y, Float_t angle, Float_t mgn, const wchar_t *text, ETextMode mode) +{ + DrawText(x, y, angle, mgn, text, mode); +} + //////////////////////////////////////////////////////////////////////////////// /// Executes the command "code" coming from the other threads (Win32) diff --git a/core/gui/inc/GuiTypes.h b/core/gui/inc/GuiTypes.h index 41052a7a403de..ac522ea3702eb 100644 --- a/core/gui/inc/GuiTypes.h +++ b/core/gui/inc/GuiTypes.h @@ -27,6 +27,7 @@ typedef ULongptr_t Handle_t; ///< Generic resource handle typedef Handle_t Display_t; ///< Display handle typedef Handle_t Visual_t; ///< Visual handle typedef Handle_t Window_t; ///< Window handle +typedef Handle_t WinContext_t; ///< Window drawing context typedef Handle_t Pixmap_t; ///< Pixmap handle typedef Handle_t Drawable_t; ///< Drawable handle typedef Handle_t Region_t; ///< Region handle diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 6ea60a788019f..b35bcb14f81c1 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -1534,7 +1534,9 @@ void TASImage::Paint(Option_t *option) int tox = expand ? 0 : int(gPad->UtoPixel(1.) * gPad->GetLeftMargin()); int toy = expand ? 0 : int(gPad->VtoPixel(0.) * gPad->GetTopMargin()); - if (!gROOT->IsBatch()) { + auto ps = gPad->GetPainter()->GetPS(); + + if (!ps) { Window_t wid = (Window_t)gVirtualX->GetWindowID(gPad->GetPixmapID()); Image2Drawable(fScaledImage ? fScaledImage->fImage : fImage, wid, tox, toy); @@ -1559,15 +1561,13 @@ void TASImage::Paint(Option_t *option) pal_Xpos, gPad->AbsPixeltoY(pal_Ay + 1), min, max, ndiv, "+L"); } - } - - // loop over pixmap and draw image to PostScript - if (gVirtualPS) { + } else { + // loop over pixmap and draw image to PostScript Bool_t paint_as_png = kFALSE; - if (gVirtualPS->InheritsFrom("TImageDump")) { // PostScript is asimage - TImage *dump = (TImage *)gVirtualPS->GetStream(); + if (ps->InheritsFrom("TImageDump")) { // PostScript is asimage + TImage *dump = (TImage *)ps->GetStream(); if (!dump) return; dump->Merge(fScaledImage ? fScaledImage : this, "alphablend", gPad->XtoAbsPixel(0), gPad->YtoAbsPixel(1)); @@ -1589,15 +1589,15 @@ void TASImage::Paint(Option_t *option) min, max, ndiv, "+L"); } return; - } else if (gVirtualPS->InheritsFrom("TPDF")) { + } else if (ps->InheritsFrom("TPDF")) { Warning("Paint", "PDF not implemented yet"); return; - } else if (gVirtualPS->InheritsFrom("TSVG")) { + } else if (ps->InheritsFrom("TSVG")) { paint_as_png = kTRUE; } - Double_t dx = gPad->GetX2()-gPad->GetX1(); - Double_t dy = gPad->GetY2()-gPad->GetY1(); + Double_t dx = gPad->GetX2() - gPad->GetX1(); + Double_t dy = gPad->GetY2() - gPad->GetY1(); Double_t x1, x2, y1, y2; if (expand) { @@ -1613,10 +1613,10 @@ void TASImage::Paint(Option_t *option) } // get special color cell to be reused during image printing - gVirtualPS->SetFillColor(TColor::GetColor((Float_t) 1., (Float_t) 1., (Float_t) 1.)); - gVirtualPS->SetFillStyle(1001); + ps->SetFillColor(TColor::GetColor((Float_t) 1., (Float_t) 1., (Float_t) 1.)); + ps->SetFillStyle(1001); - gVirtualPS->CellArrayBegin(image->width, image->height, x1, x2, y1, y2); + ps->CellArrayBegin(image->width, image->height, x1, x2, y1, y2); if (paint_as_png) { char *buffer = nullptr; @@ -1628,7 +1628,7 @@ void TASImage::Paint(Option_t *option) if (!params.png.compression) params.png.compression = -1; if (ASImage2PNGBuff(image, (CARD8 **)&buffer, &size, ¶ms)) { - gVirtualPS->CellArrayPng(buffer, size); + ps->CellArrayPng(buffer, size); free(buffer); } } else { @@ -1638,13 +1638,13 @@ void TASImage::Paint(Option_t *option) for (Int_t yt = 0; yt < (Int_t)image->height; yt++) { imdec->decode_image_scanline(imdec); for (Int_t xt = 0; xt < (Int_t)image->width; xt++) - gVirtualPS->CellArrayFill(imdec->buffer.red[xt], - imdec->buffer.green[xt], - imdec->buffer.blue[xt]); + ps->CellArrayFill(imdec->buffer.red[xt], + imdec->buffer.green[xt], + imdec->buffer.blue[xt]); } stop_image_decoding(&imdec); } - gVirtualPS->CellArrayEnd(); + ps->CellArrayEnd(); // print the color bar if (grad_im) { @@ -1654,8 +1654,8 @@ void TASImage::Paint(Option_t *option) x2 = x1 + xconv; y2 = gPad->AbsPixeltoY(pal_Ay); y1 = y2 - yconv; - gVirtualPS->CellArrayBegin(grad_im->width, grad_im->height, - x1, x2, y1, y2); + ps->CellArrayBegin(grad_im->width, grad_im->height, + x1, x2, y1, y2); if (paint_as_png) { char *buffer = nullptr; @@ -1668,7 +1668,7 @@ void TASImage::Paint(Option_t *option) params.png.compression = -1; if (ASImage2PNGBuff(grad_im, (CARD8 **)&buffer, &size, ¶ms)) { - gVirtualPS->CellArrayPng(buffer, size); + ps->CellArrayPng(buffer, size); free(buffer); } } else { @@ -1678,13 +1678,13 @@ void TASImage::Paint(Option_t *option) for (Int_t yt = 0; yt < (Int_t)grad_im->height; yt++) { imdec->decode_image_scanline(imdec); for (Int_t xt = 0; xt < (Int_t)grad_im->width; xt++) - gVirtualPS->CellArrayFill(imdec->buffer.red[xt], - imdec->buffer.green[xt], - imdec->buffer.blue[xt]); + ps->CellArrayFill(imdec->buffer.red[xt], + imdec->buffer.green[xt], + imdec->buffer.blue[xt]); } stop_image_decoding(&imdec); } - gVirtualPS->CellArrayEnd(); + ps->CellArrayEnd(); // values of palette TGaxis axis; @@ -1693,6 +1693,7 @@ void TASImage::Paint(Option_t *option) double max = fMaxValue; axis.SetLineColor(1); // draw black ticks Double_t pal_Xpos = gPad->AbsPixeltoX(pal_Ax + pal_w); + // TODO: provide PaintAxisOn method axis.PaintAxis(pal_Xpos, gPad->AbsPixeltoY(pal_Ay + pal_h), pal_Xpos, gPad->AbsPixeltoY(pal_Ay + 1), min, max, ndiv, "+L"); diff --git a/graf2d/gpad/inc/TPadPainter.h b/graf2d/gpad/inc/TPadPainter.h index 24c762ed47ede..01465e2c9a1db 100644 --- a/graf2d/gpad/inc/TPadPainter.h +++ b/graf2d/gpad/inc/TPadPainter.h @@ -13,6 +13,7 @@ #define ROOT_TPadPainter #include "TVirtualPadPainter.h" +#include "GuiTypes.h" /* TVirtualPadPainter is an attempt to abstract @@ -24,6 +25,10 @@ or gl pad painter. class TVirtualPad; class TPadPainter : public TVirtualPadPainter { + WinContext_t fWinContext; + Int_t fSetLineWidth = 0; ///< remember set width to optimize some painting + Style_t fSetFillStyle = 0; ///< remember set fill style to optimize painting + public: TPadPainter(); //Final overriders for TVirtualPadPainter pure virtual functions. @@ -71,6 +76,12 @@ class TPadPainter : public TVirtualPadPainter { void SetMarkerStyle(Style_t mstyle) override; void SetMarkerSize(Size_t msize) override; + //Overall attributes + void SetAttFill(const TAttFill &att) override; + void SetAttLine(const TAttLine &att) override; + void SetAttMarker(const TAttMarker &att) override; + void SetAttText(const TAttText &att) override; + //2. "Off-screen management" part. Int_t CreateDrawable(UInt_t w, UInt_t h) override; void ClearDrawable() override; diff --git a/graf2d/gpad/inc/TPadPainterPS.h b/graf2d/gpad/inc/TPadPainterPS.h index 1a463af1ff214..9a37ec658d9ab 100644 --- a/graf2d/gpad/inc/TPadPainterPS.h +++ b/graf2d/gpad/inc/TPadPainterPS.h @@ -121,6 +121,9 @@ class TPadPainterPS : public TVirtualPadPainter { void OnPad(TVirtualPad *pad) override { fPad = pad; } + TVirtualPS *GetPS() const override { return fPS; } + + private: //Let's make this clear: TPadPainterPS(const TPadPainterPS &) = delete; diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx index 3f93d1e548dd6..3f4896031cfd8 100644 --- a/graf2d/gpad/src/TCanvas.cxx +++ b/graf2d/gpad/src/TCanvas.cxx @@ -1126,16 +1126,14 @@ void TCanvas::ExecuteEvent(Int_t event, Int_t px, Int_t py) void TCanvas::FeedbackMode(Bool_t set) { - if (IsWeb()) + if (IsWeb() || (fCanvasID == -1)) return; - if (set) { - SetDoubleBuffer(0); // turn off double buffer mode - gVirtualX->SetDrawMode(TVirtualX::kInvert); // set the drawing mode to XOR mode - } else { - SetDoubleBuffer(1); // turn on double buffer mode - gVirtualX->SetDrawMode(TVirtualX::kCopy); // set drawing mode back to normal (copy) mode - } + if (fPainter) + fPainter->SelectDrawable(fCanvasID); + gVirtualX->SetDrawMode(set ? TVirtualX::kInvert : TVirtualX::kCopy); // set the drawing mode to XOR mode + + SetDoubleBuffer(set ? 0 : 1); // switch double buffer } //////////////////////////////////////////////////////////////////////////////// @@ -2632,7 +2630,7 @@ Bool_t TCanvas::EnsurePSPainter(Bool_t create, TVirtualPadPainter *&oldp) return kFALSE; } - if (!gVirtualPS || !IsBatch()) + if (!gVirtualPS /* || !IsBatch() */) return kFALSE; diff --git a/graf2d/gpad/src/TPad.cxx b/graf2d/gpad/src/TPad.cxx index ca927656b89a6..3badc5ba720d6 100644 --- a/graf2d/gpad/src/TPad.cxx +++ b/graf2d/gpad/src/TPad.cxx @@ -46,6 +46,7 @@ #include "TMethod.h" #include "TDataType.h" #include "TFrame.h" +#include "TWbox.h" #include "TExec.h" #include "TDatime.h" #include "TColor.h" @@ -3828,99 +3829,20 @@ void TPad::PaintBorder(Color_t color, Bool_t /* tops */) if (IsTransparent()) return; - // then paint 3d frame (depending on bordermode) - // Paint a 3D frame around the pad. - if (fBorderMode == 0) return; - Int_t bordersize = fBorderSize; - if (bordersize <= 0) - bordersize = 2; - - Double_t ww = GetWw(), wh = GetWh(); - - if (!pp->IsNative()) { - // SL: need to calculate page size to get real coordiantes for border - // TODO: Code can be removed if border not need to be exact pixel size - Float_t xsize = 20, ysize = 26; - gStyle->GetPaperSize(xsize, ysize); - Double_t ratio = wh/ww; - if (xsize * ratio > ysize) - xsize = ysize/ratio; - else - ysize = xsize*ratio; - ww = 72 / 2.54 * xsize; - wh = 72 / 2.54 * ysize; - } - - const Double_t realBsX = bordersize / (GetAbsWNDC() * ww) * (fX2 - fX1); - const Double_t realBsY = bordersize / (GetAbsHNDC() * wh) * (fY2 - fY1); + // then paint 3d frame (depending on bordermode) + // Paint a 3D frame around the pad. - // GetColorDark() and GetColorBright() use GetFillColor() - Color_t oldfillcolor = pp->GetFillColor(); - Color_t light = !color ? 0 : TColor::GetColorBright(color); - Color_t dark = !color ? 0 : TColor::GetColorDark(color); - - Double_t xl, xt, yl, yt; - - // Compute real left bottom & top right of the box in pixels - if (XtoPixel(fX1) < XtoPixel(fX2)) { - xl = fX1; - xt = fX2; - } else { - xl = fX2; - xt = fX1; - } - if (YtoPixel(fY1) > YtoPixel(fY2)) { - yl = fY1; - yt = fY2; - } else { - yl = fY2; - yt = fY1; - } - - Double_t frameXs[7] = {}, frameYs[7] = {}; - - // Draw top&left part of the box - frameXs[0] = xl; frameYs[0] = yl; - frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY; - frameXs[2] = frameXs[1]; frameYs[2] = yt - realBsY; - frameXs[3] = xt - realBsX; frameYs[3] = frameYs[2]; - frameXs[4] = xt; frameYs[4] = yt; - frameXs[5] = xl; frameYs[5] = yt; - frameXs[6] = xl; frameYs[6] = yl; - - pp->SetFillColor(fBorderMode == -1 ? dark : light); - pp->DrawFillArea(7, frameXs, frameYs); - - // Draw bottom&right part of the box - frameXs[0] = xl; frameYs[0] = yl; - frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY; - frameXs[2] = xt - realBsX; frameYs[2] = frameYs[1]; - frameXs[3] = frameXs[2]; frameYs[3] = yt - realBsY; - frameXs[4] = xt; frameYs[4] = yt; - frameXs[5] = xt; frameYs[5] = yl; - frameXs[6] = xl; frameYs[6] = yl; - - pp->SetFillColor(fBorderMode == -1 ? light : dark); - pp->DrawFillArea(7, frameXs, frameYs); - - // If this pad is a button, highlight it - if (InheritsFrom(TButton::Class()) && fBorderMode == -1) { - if (TestBit(kFraming)) { // bit set in TButton::SetFraming - Color_t oldlinecolor = pp->GetLineColor(); - pp->SetLineColor(GetFillColor() != 2 ? 2 : 4); - pp->DrawBox(xl + realBsX, yl + realBsY, xt - realBsX, yt - realBsY, TVirtualPadPainter::kHollow); - pp->SetLineColor(oldlinecolor); - } - } - pp->SetFillColor(oldfillcolor); - - // No need to use PaintBorderPS, it is already performed via pad painter done! + TWbox box; + box.SetFillColor(color); + box.SetFillStyle(GetFillStyle()); + TAttLine::Copy(box); - //if (tops) - // PaintBorderPS(xl, yl, xt, yt, fBorderMode, bordersize, dark, light); + box.PaintBorderOn(this, fX1, fY1, fX2, fY2, + fBorderSize, fBorderMode, + InheritsFrom(TButton::Class()) && fBorderMode == -1 && TestBit(kFraming)); } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/gpad/src/TPadPainter.cxx b/graf2d/gpad/src/TPadPainter.cxx index 41dd510269633..59eab6f395dbe 100644 --- a/graf2d/gpad/src/TPadPainter.cxx +++ b/graf2d/gpad/src/TPadPainter.cxx @@ -47,13 +47,13 @@ void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, void ConvertPointsAndMergeInplacePassY(std::vector &dst); template -void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys); +void DrawFillAreaAux(TVirtualPad *pad, WinContext_t cont, Int_t nPoints, const T *xs, const T *ys, Bool_t close_path); template -void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys); +void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys); template -void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys); +void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys); } @@ -132,6 +132,7 @@ void TPadPainter::SetLineStyle(Style_t lstyle) void TPadPainter::SetLineWidth(Width_t lwidth) { + fSetLineWidth = lwidth; gVirtualX->SetLineWidth(lwidth); } @@ -178,6 +179,7 @@ void TPadPainter::SetFillColor(Color_t fcolor) void TPadPainter::SetFillStyle(Style_t fstyle) { + fSetFillStyle = fstyle; gVirtualX->SetFillStyle(fstyle); } @@ -404,6 +406,7 @@ void TPadPainter::DestroyDrawable(Int_t device) { gVirtualX->SelectWindow(device); gVirtualX->ClosePixmap(); + fWinContext = (WinContext_t) 0; } @@ -413,6 +416,7 @@ void TPadPainter::DestroyDrawable(Int_t device) void TPadPainter::SelectDrawable(Int_t device) { gVirtualX->SelectWindow(device); + fWinContext = gVirtualX->GetWindowContext(device); } //////////////////////////////////////////////////////////////////////////////// @@ -423,19 +427,53 @@ void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width { } +//////////////////////////////////////////////////////////////////////////////// +/// Set fill attributes + +void TPadPainter::SetAttFill(const TAttFill &att) +{ + fSetFillStyle = att.GetFillStyle(); + gVirtualX->SetAttFill(fWinContext, att); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set line attributes + +void TPadPainter::SetAttLine(const TAttLine &att) +{ + fSetLineWidth = att.GetLineWidth(); + gVirtualX->SetAttLine(fWinContext, att); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set marker attributes + +void TPadPainter::SetAttMarker(const TAttMarker &att) +{ + gVirtualX->SetAttMarker(fWinContext, att); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Set text attributes + +void TPadPainter::SetAttText(const TAttText &att) +{ + gVirtualX->SetAttText(fWinContext, att); +} //////////////////////////////////////////////////////////////////////////////// /// Paint a simple line. void TPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) { - if (GetLineWidth()<=0) return; + if (fSetLineWidth <= 0) + return; const Int_t px1 = gPad->XtoPixel(x1); const Int_t px2 = gPad->XtoPixel(x2); const Int_t py1 = gPad->YtoPixel(y1); const Int_t py2 = gPad->YtoPixel(y2); - gVirtualX->DrawLine(px1, py1, px2, py2); + gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2); } @@ -444,13 +482,14 @@ void TPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2) void TPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2) { - if (GetLineWidth()<=0) return; + if (fSetLineWidth <= 0) + return; const Int_t px1 = gPad->UtoPixel(u1); const Int_t py1 = gPad->VtoPixel(v1); const Int_t px2 = gPad->UtoPixel(u2); const Int_t py2 = gPad->VtoPixel(v2); - gVirtualX->DrawLine(px1, py1, px2, py2); + gVirtualX->DrawLineW(fWinContext, px1, py1, px2, py2); } @@ -459,7 +498,8 @@ void TPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2 void TPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode) { - if (GetLineWidth()<=0 && mode == TVirtualPadPainter::kHollow) return; + if (fSetLineWidth <= 0 && mode == TVirtualPadPainter::kHollow) + return; Int_t px1 = gPad->XtoPixel(x1); Int_t px2 = gPad->XtoPixel(x2); @@ -472,7 +512,7 @@ void TPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EB if (TMath::Abs(py1 - py2) < 1) py1 = py2 + 1; - gVirtualX->DrawBox(px1, py1, px2, py2, (TVirtualX::EBoxMode)mode); + gVirtualX->DrawBoxW(fWinContext, px1, py1, px2, py2, (TVirtualX::EBoxMode)mode); } //////////////////////////////////////////////////////////////////////////////// @@ -485,7 +525,7 @@ void TPadPainter::DrawFillArea(Int_t nPoints, const Double_t *xs, const Double_t return; } - DrawFillAreaAux(gPad, nPoints, xs, ys); + DrawFillAreaAux(gPad, fWinContext, nPoints, xs, ys, fSetFillStyle == 0); } @@ -499,7 +539,7 @@ void TPadPainter::DrawFillArea(Int_t nPoints, const Float_t *xs, const Float_t * return; } - DrawFillAreaAux(gPad, nPoints, xs, ys); + DrawFillAreaAux(gPad, fWinContext, nPoints, xs, ys, fSetFillStyle == 0); } //////////////////////////////////////////////////////////////////////////////// @@ -507,14 +547,15 @@ void TPadPainter::DrawFillArea(Int_t nPoints, const Float_t *xs, const Float_t * void TPadPainter::DrawPolyLine(Int_t n, const Double_t *xs, const Double_t *ys) { - if (GetLineWidth()<=0) return; + if (fSetLineWidth <= 0) + return; if (n < 2) { ::Error("TPadPainter::DrawPolyLine", "invalid number of points"); return; } - DrawPolyLineAux(gPad, n, xs, ys); + DrawPolyLineAux(gPad, fWinContext, n, xs, ys); } @@ -523,14 +564,15 @@ void TPadPainter::DrawPolyLine(Int_t n, const Double_t *xs, const Double_t *ys) void TPadPainter::DrawPolyLine(Int_t n, const Float_t *xs, const Float_t *ys) { - if (GetLineWidth()<=0) return; + if (fSetLineWidth <= 0) + return; if (n < 2) { ::Error("TPadPainter::DrawPolyLine", "invalid number of points"); return; } - DrawPolyLineAux(gPad, n, xs, ys); + DrawPolyLineAux(gPad, fWinContext, n, xs, ys); } @@ -539,7 +581,8 @@ void TPadPainter::DrawPolyLine(Int_t n, const Float_t *xs, const Float_t *ys) void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) { - if (GetLineWidth()<=0) return; + if (fSetLineWidth <= 0) + return; if (n < 2) { ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n); @@ -553,7 +596,7 @@ void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]); } - gVirtualX->DrawPolyLine(n, &xy[0]); + gVirtualX->DrawPolyLineW(fWinContext, n, &xy[0]); } //////////////////////////////////////////////////////////////////////////////// @@ -561,7 +604,7 @@ void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v) void TPadPainter::DrawSegments(Int_t n, Double_t *x, Double_t *y) { - if (GetLineWidth() <= 0) + if (fSetLineWidth <= 0) return; if (n < 1) { @@ -584,7 +627,7 @@ void TPadPainter::DrawSegments(Int_t n, Double_t *x, Double_t *y) } if (cnt > 1) - gVirtualX->DrawLinesSegments(cnt/2, &xy[0]); + gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]); } //////////////////////////////////////////////////////////////////////////////// @@ -592,7 +635,7 @@ void TPadPainter::DrawSegments(Int_t n, Double_t *x, Double_t *y) void TPadPainter::DrawSegmentsNDC(Int_t n, Double_t *u, Double_t *v) { - if (GetLineWidth() <= 0) + if (fSetLineWidth <= 0) return; if (n < 1) { @@ -615,7 +658,7 @@ void TPadPainter::DrawSegmentsNDC(Int_t n, Double_t *u, Double_t *v) } if (cnt > 1) - gVirtualX->DrawLinesSegments(cnt/2, &xy[0]); + gVirtualX->DrawLinesSegmentsW(fWinContext, cnt/2, &xy[0]); } @@ -630,7 +673,7 @@ void TPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y) return; } - DrawPolyMarkerAux(gPad, n, x, y); + DrawPolyMarkerAux(gPad, fWinContext, n, x, y); } @@ -644,7 +687,7 @@ void TPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y) return; } - DrawPolyMarkerAux(gPad, n, x, y); + DrawPolyMarkerAux(gPad, fWinContext, n, x, y); } @@ -657,7 +700,7 @@ void TPadPainter::DrawText(Double_t x, Double_t y, const char *text, ETextMode m const Int_t py = gPad->YtoPixel(y); const Double_t angle = GetTextAngle(); const Double_t mgn = GetTextMagnitude(); - gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); + gVirtualX->DrawTextW(fWinContext, px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); } @@ -670,7 +713,7 @@ void TPadPainter::DrawText(Double_t x, Double_t y, const wchar_t *text, ETextMod const Int_t py = gPad->YtoPixel(y); const Double_t angle = GetTextAngle(); const Double_t mgn = GetTextMagnitude(); - gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); + gVirtualX->DrawTextW(fWinContext, px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); } @@ -683,7 +726,7 @@ void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMod const Int_t py = gPad->VtoPixel(v); const Double_t angle = GetTextAngle(); const Double_t mgn = GetTextMagnitude(); - gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); + gVirtualX->DrawTextW(fWinContext, px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); } @@ -759,7 +802,7 @@ void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const wchar_t *text, EText const Int_t py = gPad->VtoPixel(v); const Double_t angle = GetTextAngle(); const Double_t mgn = GetTextMagnitude(); - gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); + gVirtualX->DrawTextW(fWinContext, px, py, angle, mgn, text, (TVirtualX::ETextMode)mode); } //Aux. private functions. @@ -962,7 +1005,7 @@ void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoint //////////////////////////////////////////////////////////////////////////////// template -void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys) +void DrawFillAreaAux(TVirtualPad *pad, WinContext_t cont, Int_t nPoints, const T *xs, const T *ys, Bool_t close_path) { std::vector xy; @@ -981,19 +1024,19 @@ void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys) ConvertPointsAndMerge(pad, threshold, nPoints, xs, ys, xy); //We close the 'polygon' and it'll be rendered as a polyline by gVirtualX. - if (!gVirtualX->GetFillStyle()) + if (close_path) xy.push_back(xy.front()); if (xy.size() > 2) - gVirtualX->DrawFillArea(xy.size(), &xy[0]); + gVirtualX->DrawFillAreaW(cont, xy.size(), &xy[0]); } //////////////////////////////////////////////////////////////////////////////// template -void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys) +void DrawPolyLineAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys) { - std::vector xy; + std::vector xy; const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(), pad->GetWh() * pad->GetAbsHNDC())) * 2; @@ -1009,14 +1052,14 @@ void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *y ConvertPointsAndMerge(pad, threshold, nPoints, xs, ys, xy); if (xy.size() > 1) - gVirtualX->DrawPolyLine(xy.size(), &xy[0]); + gVirtualX->DrawPolyLineW(cont, xy.size(), &xy[0]); } //////////////////////////////////////////////////////////////////////////////// template -void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys) +void DrawPolyMarkerAux(TVirtualPad *pad, WinContext_t cont, unsigned nPoints, const T *xs, const T *ys) { std::vector xy(nPoints); @@ -1025,7 +1068,7 @@ void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]); } - gVirtualX->DrawPolyMarker(nPoints, &xy[0]); + gVirtualX->DrawPolyMarkerW(cont, nPoints, &xy[0]); } } diff --git a/graf2d/graf/inc/TWbox.h b/graf2d/graf/inc/TWbox.h index 1890643c8178f..c194f3eb36e93 100644 --- a/graf2d/graf/inc/TWbox.h +++ b/graf2d/graf/inc/TWbox.h @@ -42,6 +42,9 @@ class TWbox : public TBox { Int_t GetDarkColor() const {return TColor::GetColorDark(GetFillColor());} Int_t GetLightColor() const {return TColor::GetColorBright(GetFillColor());} void Paint(Option_t *option="") override; + void PaintBorderOn(TVirtualPad *pad, + Double_t x1, Double_t y1,Double_t x2 ,Double_t y2, + Short_t bordersize, Short_t bordermode, Bool_t with_selection = kFALSE); virtual void PaintFrame(Double_t x1, Double_t y1,Double_t x2 ,Double_t y2, Color_t color, Short_t bordersize, Short_t bordermode, Bool_t tops); diff --git a/graf2d/graf/src/TArrow.cxx b/graf2d/graf/src/TArrow.cxx index 1138b1d35d5b7..b9f2ff414943f 100644 --- a/graf2d/graf/src/TArrow.cxx +++ b/graf2d/graf/src/TArrow.cxx @@ -13,8 +13,7 @@ #include "TMath.h" #include "TArrow.h" #include "TVirtualPad.h" -#include "TVirtualPS.h" -#include "TVirtualX.h" +#include "TVirtualPadPainter.h" Float_t TArrow::fgDefaultAngle = 60; Float_t TArrow::fgDefaultArrowSize = 0.05; @@ -296,8 +295,7 @@ void TArrow::PaintArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1; } if (opt.Contains("|>")) { - if (gVirtualX) gVirtualX->SetLineStyle(1); - if (gVirtualPS) gVirtualPS->SetLineStyle(1); + gPad->GetPainter()->SetLineStyle(1); if (GetFillColor()) { gPad->PaintFillArea(3,x2ar,y2ar); gPad->PaintPolyLine(4,x2ar,y2ar); @@ -326,8 +324,7 @@ void TArrow::PaintArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2, y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1; } if (opt.Contains("<|")) { - if (gVirtualX) gVirtualX->SetLineStyle(1); - if (gVirtualPS) gVirtualPS->SetLineStyle(1); + gPad->GetPainter()->SetLineStyle(1); if (GetFillColor()) { gPad->PaintFillArea(3,x1ar,y1ar); gPad->PaintPolyLine(4,x1ar,y1ar); diff --git a/graf2d/graf/src/TLatex.cxx b/graf2d/graf/src/TLatex.cxx index 5156438c6ae61..a7c9a691adb5c 100644 --- a/graf2d/graf/src/TLatex.cxx +++ b/graf2d/graf/src/TLatex.cxx @@ -15,8 +15,8 @@ #include "TMathText.h" #include "TMath.h" #include "TVirtualPad.h" +#include "TVirtualPadPainter.h" #include "TVirtualPS.h" -#include "TVirtualX.h" #include "snprintf.h" const Double_t kPI = TMath::Pi(); @@ -1357,13 +1357,13 @@ TLatex::TLatexFormSize TLatex::Analyse(Double_t x, Double_t y, const TextSpec_t result = fs1+fs2; } - else if (opSpec>-1) { + else if (opSpec > -1) { TextSpec_t newSpec = spec; newSpec.fFont = fItalic ? 152 : 122; char letter = '\243' + opSpec; if(opSpec == 75 || opSpec == 76) { newSpec.fFont = GetTextFont(); - if (gVirtualX->InheritsFrom("TGCocoa")) { + if (gPad->GetPainter()->IsCocoa()) { if (opSpec == 75) letter = '\201'; // AA Angstroem if (opSpec == 76) letter = '\214'; // aa Angstroem } else { @@ -1491,25 +1491,26 @@ TLatex::TLatexFormSize TLatex::Analyse(Double_t x, Double_t y, const TextSpec_t Double_t x2 = x+fs1.Width()/2, y2 = y -fs1.Over(); // tilde must be drawn separately on screen and on PostScript // because an adjustment is required along Y for PostScript. - TVirtualPS *saveps = gVirtualPS; - if (gVirtualPS) gVirtualPS = nullptr; - Double_t y22 = y2; - if (gVirtualX->InheritsFrom("TGCocoa")) y2 -= 4.7*sub; + Double_t xx, yy; - Rotate(gPad, spec.fAngle, x2, y2, xx, yy); - TText tilde; - tilde.SetTextFont(fTextFont); - tilde.SetTextColor(spec.fColor); - tilde.SetTextSize(0.9*spec.fSize); - tilde.SetTextAlign(22); - tilde.SetTextAngle(fTextAngle); - tilde.PaintText(xx,yy,"~"); - if (saveps) { - gVirtualPS = saveps; - if (!strstr(gVirtualPS->GetTitle(),"IMG")) y22 -= 4*sub; - Rotate(gPad, spec.fAngle, x2, y22, xx, yy); - gVirtualPS->SetTextAlign(22); - gVirtualPS->Text(xx, yy, "~"); + if (auto ps = gPad->GetPainter()->GetPS()) { + if (!strstr(ps->GetTitle(), "IMG")) + y2 -= 4*sub; + Rotate(gPad, spec.fAngle, x2, y2, xx, yy); + ps->SetTextAlign(22); + ps->Text(xx, yy, "~"); + } else { + if (gPad->GetPainter()->IsCocoa()) + y2 -= 4.7*sub; + Rotate(gPad, spec.fAngle, x2, y2, xx, yy); + // TODO: use pad painter SetAttText and DrawText directly + TText tilde; + tilde.SetTextFont(fTextFont); + tilde.SetTextColor(spec.fColor); + tilde.SetTextSize(0.9*spec.fSize); + tilde.SetTextAlign(22); + tilde.SetTextAngle(fTextAngle); + tilde.PaintText(xx,yy,"~"); } break; } @@ -2150,88 +2151,76 @@ void TLatex::PaintLatex(Double_t x, Double_t y, Double_t angle, Double_t size, c TAttText::Modify(); // Change text attributes only if necessary. - TVirtualPS *saveps = gVirtualPS; - - if (gVirtualPS) { - if (gVirtualPS->InheritsFrom("TTeXDump")) { - gVirtualPS->SetTextAngle(angle); - TString t(text1); - if (t.Index("#")>=0 || t.Index("^")>=0 || t.Index("\\")>=0) { - t.ReplaceAll("#LT","\\langle"); - t.ReplaceAll("#GT","\\rangle"); - t.ReplaceAll("#club","\\clubsuit"); - t.ReplaceAll("#spade","\\spadesuit"); - t.ReplaceAll("#heart","\\heartsuit"); - t.ReplaceAll("#diamond","\\diamondsuit"); - t.ReplaceAll("#voidn","\\wp"); - t.ReplaceAll("#voidb","f"); - t.ReplaceAll("#ocopyright","\\copyright"); - t.ReplaceAll("#trademark","TM"); - t.ReplaceAll("#void3","TM"); - t.ReplaceAll("#oright","R"); - t.ReplaceAll("#void1","R"); - t.ReplaceAll("#3dots","\\ldots"); - t.ReplaceAll("#lbar","\\mid"); - t.ReplaceAll("#bar","\\wwbar"); - t.ReplaceAll("#void8","\\mid"); - t.ReplaceAll("#divide","\\div"); - t.ReplaceAll("#Jgothic","\\Im"); - t.ReplaceAll("#Rgothic","\\Re"); - t.ReplaceAll("#doublequote","\""); - t.ReplaceAll("#plus","+"); - t.ReplaceAll("#minus","-"); - t.ReplaceAll("#/","/"); - t.ReplaceAll("#upoint","."); - t.ReplaceAll("#aa","\\mbox{\\aa}"); - t.ReplaceAll("#AA","\\mbox{\\AA}"); - - t.ReplaceAll("#omicron","o"); - t.ReplaceAll("#Alpha","A"); - t.ReplaceAll("#Beta","B"); - t.ReplaceAll("#Epsilon","E"); - t.ReplaceAll("#Zeta","Z"); - t.ReplaceAll("#Eta","H"); - t.ReplaceAll("#Iota","I"); - t.ReplaceAll("#Kappa","K"); - t.ReplaceAll("#Mu","M"); - t.ReplaceAll("#Nu","N"); - t.ReplaceAll("#Omicron","O"); - t.ReplaceAll("#Rho","P"); - t.ReplaceAll("#Tau","T"); - t.ReplaceAll("#Chi","X"); - t.ReplaceAll("#varomega","\\varpi"); - - t.ReplaceAll("#varUpsilon","?"); - t.ReplaceAll("#corner","?"); - t.ReplaceAll("#ltbar","?"); - t.ReplaceAll("#bottombar","?"); - t.ReplaceAll("#notsubset","?"); - t.ReplaceAll("#arcbottom","?"); - t.ReplaceAll("#cbar","?"); - t.ReplaceAll("#arctop","?"); - t.ReplaceAll("#topbar","?"); - t.ReplaceAll("#arcbar","?"); - t.ReplaceAll("#downleftarrow","?"); - t.ReplaceAll("#splitline","\\genfrac{}{}{0pt}{}"); - - t.ReplaceAll("#","\\"); - t.ReplaceAll("%","\\%"); - } - gVirtualPS->Text(x,y,t.Data()); - } else { - Bool_t saveb = gPad->IsBatch(); - gPad->SetBatch(kTRUE); - if (!PaintLatex1( x, y, angle, size, text1)) { - if (saveps) gVirtualPS = saveps; - return; - } - gPad->SetBatch(saveb); - } - gVirtualPS = nullptr; + auto ps = gPad->GetPainter()->GetPS(); + + if (ps && ps->InheritsFrom("TTeXDump")) { + TString t(text1); + if (t.Index("#")>=0 || t.Index("^")>=0 || t.Index("\\")>=0) { + t.ReplaceAll("#LT","\\langle"); + t.ReplaceAll("#GT","\\rangle"); + t.ReplaceAll("#club","\\clubsuit"); + t.ReplaceAll("#spade","\\spadesuit"); + t.ReplaceAll("#heart","\\heartsuit"); + t.ReplaceAll("#diamond","\\diamondsuit"); + t.ReplaceAll("#voidn","\\wp"); + t.ReplaceAll("#voidb","f"); + t.ReplaceAll("#ocopyright","\\copyright"); + t.ReplaceAll("#trademark","TM"); + t.ReplaceAll("#void3","TM"); + t.ReplaceAll("#oright","R"); + t.ReplaceAll("#void1","R"); + t.ReplaceAll("#3dots","\\ldots"); + t.ReplaceAll("#lbar","\\mid"); + t.ReplaceAll("#bar","\\wwbar"); + t.ReplaceAll("#void8","\\mid"); + t.ReplaceAll("#divide","\\div"); + t.ReplaceAll("#Jgothic","\\Im"); + t.ReplaceAll("#Rgothic","\\Re"); + t.ReplaceAll("#doublequote","\""); + t.ReplaceAll("#plus","+"); + t.ReplaceAll("#minus","-"); + t.ReplaceAll("#/","/"); + t.ReplaceAll("#upoint","."); + t.ReplaceAll("#aa","\\mbox{\\aa}"); + t.ReplaceAll("#AA","\\mbox{\\AA}"); + + t.ReplaceAll("#omicron","o"); + t.ReplaceAll("#Alpha","A"); + t.ReplaceAll("#Beta","B"); + t.ReplaceAll("#Epsilon","E"); + t.ReplaceAll("#Zeta","Z"); + t.ReplaceAll("#Eta","H"); + t.ReplaceAll("#Iota","I"); + t.ReplaceAll("#Kappa","K"); + t.ReplaceAll("#Mu","M"); + t.ReplaceAll("#Nu","N"); + t.ReplaceAll("#Omicron","O"); + t.ReplaceAll("#Rho","P"); + t.ReplaceAll("#Tau","T"); + t.ReplaceAll("#Chi","X"); + t.ReplaceAll("#varomega","\\varpi"); + + t.ReplaceAll("#varUpsilon","?"); + t.ReplaceAll("#corner","?"); + t.ReplaceAll("#ltbar","?"); + t.ReplaceAll("#bottombar","?"); + t.ReplaceAll("#notsubset","?"); + t.ReplaceAll("#arcbottom","?"); + t.ReplaceAll("#cbar","?"); + t.ReplaceAll("#arctop","?"); + t.ReplaceAll("#topbar","?"); + t.ReplaceAll("#arcbar","?"); + t.ReplaceAll("#downleftarrow","?"); + t.ReplaceAll("#splitline","\\genfrac{}{}{0pt}{}"); + + t.ReplaceAll("#","\\"); + t.ReplaceAll("%","\\%"); + } + ps->SetTextAngle(angle); + ps->Text(x, y, t.Data()); + } else { + PaintLatex1(x, y, angle, size, text1); } - - if (!gPad->IsBatch()) PaintLatex1( x, y, angle, size, text1); - if (saveps) gVirtualPS = saveps; } //////////////////////////////////////////////////////////////////////////////// @@ -2255,30 +2244,23 @@ Int_t TLatex::PaintLatex1(Double_t x, Double_t y, Double_t angle, Double_t size, // Do not use Latex if font is low precision. if (fTextFont % 10 < 2) { - if (gVirtualX) gVirtualX->SetTextAngle(angle); - if (gVirtualPS) gVirtualPS->SetTextAngle(angle); - gPad->PaintText(x,y,text1); + gPad->GetPainter()->SetTextAngle(angle); + gPad->PaintText(x, y, text1); return 1; } - Bool_t saveb = gPad->IsBatch(); // Paint the text using TMathText if contains a "\" if (strstr(text1,"\\")) { - TMathText tm; - tm.SetTextAlign(GetTextAlign()); - tm.SetTextFont(GetTextFont()); - tm.SetTextColor(GetTextColor()); - tm.PaintMathText(x, y, angle, size, text1); - // If PDF, paint using TLatex - if (gVirtualPS) { - if (gVirtualPS->InheritsFrom("TPDF") || - gVirtualPS->InheritsFrom("TSVG")) { - newText.ReplaceAll("\\","#"); - gPad->SetBatch(kTRUE); - } else { - return 1; - } + auto ps = gPad->GetPainter()->GetPS(); + // If PDF or SVG, paint using TLatex + if (ps && (ps->InheritsFrom("TPDF") || ps->InheritsFrom("TSVG"))) { + newText.ReplaceAll("\\","#"); } else { + TMathText tm; + tm.SetTextAlign(GetTextAlign()); + tm.SetTextFont(GetTextFont()); + tm.SetTextColor(GetTextColor()); + tm.PaintMathText(x, y, angle, size, text1); return 1; } } @@ -2334,7 +2316,6 @@ Int_t TLatex::PaintLatex1(Double_t x, Double_t y, Double_t angle, Double_t size, Analyse(x,y,newSpec,text,length); } - gPad->SetBatch(saveb); SetTextSize(saveSize); SetTextAngle(angle); SetTextFont(saveFont); diff --git a/graf2d/graf/src/TMathText.cxx b/graf2d/graf/src/TMathText.cxx index e907f7eb511ff..db37252c02cbc 100644 --- a/graf2d/graf/src/TMathText.cxx +++ b/graf2d/graf/src/TMathText.cxx @@ -18,8 +18,8 @@ #include "TMathText.h" #include "TMath.h" #include "TVirtualPad.h" +#include "TVirtualPadPainter.h" #include "TVirtualPS.h" -#include "TVirtualX.h" #include "TText.h" #include "../../../graf2d/mathtext/inc/mathtext.h" @@ -583,20 +583,13 @@ void TMathText::PaintMathText(Double_t x, Double_t y, Double_t angle, Short_t saveAlign = fTextAlign; TAttText::Modify(); - if (gVirtualPS) { // Initialise TMathTextRenderer - if (gPad->IsBatch()) { - if (gVirtualPS->InheritsFrom("TImageDump")) gPad->PaintText(0, 0, ""); - } + if (auto ps = gPad->GetPainter()->GetPS()) { // Initialise TMathTextRenderer + if (ps->InheritsFrom("TImageDump")) gPad->PaintText(0, 0, ""); } // Do not use Latex if font is low precision. if (fTextFont % 10 < 2) { - if (gVirtualX) { - gVirtualX->SetTextAngle(angle); - } - if (gVirtualPS) { - gVirtualPS->SetTextAngle(angle); - } + gPad->GetPainter()->SetTextAngle(angle); gPad->PaintText(x, y, text1); return; } diff --git a/graf2d/graf/src/TWbox.cxx b/graf2d/graf/src/TWbox.cxx index a4be334f69f5f..a2fb8b9bd8619 100644 --- a/graf2d/graf/src/TWbox.cxx +++ b/graf2d/graf/src/TWbox.cxx @@ -14,9 +14,9 @@ #include "Strlen.h" #include "TWbox.h" #include "TColor.h" +#include "TStyle.h" #include "TVirtualPad.h" -#include "TVirtualX.h" -#include "TPoint.h" +#include "TVirtualPadPainter.h" /** \class TWbox @@ -135,69 +135,115 @@ void TWbox::PaintWbox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, void TWbox::PaintFrame(Double_t x1, Double_t y1,Double_t x2, Double_t y2, Color_t color, Short_t bordersize, Short_t bordermode, - Bool_t tops) + Bool_t /* tops */) { - if (!gPad) return; - if (bordermode == 0) return; - if (bordersize <= 0) bordersize = 2; + if (bordermode == 0) + return; - Short_t pxl,pyl,pxt,pyt,px1,py1,px2,py2; - Double_t xl, xt, yl, yt; + auto oldcolor = GetFillColor(); + SetFillColor(color); - // Compute real left bottom & top right of the box in pixels - px1 = gPad->XtoPixel(x1); py1 = gPad->YtoPixel(y1); - px2 = gPad->XtoPixel(x2); py2 = gPad->YtoPixel(y2); - if (px1 < px2) {pxl = px1; pxt = px2; xl = x1; xt = x2; } - else {pxl = px2; pxt = px1; xl = x2; xt = x1;} - if (py1 > py2) {pyl = py1; pyt = py2; yl = y1; yt = y2;} - else {pyl = py2; pyt = py1; yl = y2; yt = y1;} - - if (!gPad->IsBatch()) { - TPoint frame[7]; - - // GetDarkColor() and GetLightColor() use GetFillColor() - Color_t oldcolor = GetFillColor(); - SetFillColor(color); - TAttFill::Modify(); - - // Draw top&left part of the box - frame[0].fX = pxl; frame[0].fY = pyl; - frame[1].fX = pxl + bordersize; frame[1].fY = pyl - bordersize; - frame[2].fX = frame[1].fX; frame[2].fY = pyt + bordersize; - frame[3].fX = pxt - bordersize; frame[3].fY = frame[2].fY; - frame[4].fX = pxt; frame[4].fY = pyt; - frame[5].fX = pxl; frame[5].fY = pyt; - frame[6].fX = pxl; frame[6].fY = pyl; - - if (bordermode == -1) gVirtualX->SetFillColor(GetDarkColor()); - else gVirtualX->SetFillColor(GetLightColor()); - gVirtualX->DrawFillArea(7, frame); - - // Draw bottom&right part of the box - frame[0].fX = pxl; frame[0].fY = pyl; - frame[1].fX = pxl + bordersize; frame[1].fY = pyl - bordersize; - frame[2].fX = pxt - bordersize; frame[2].fY = frame[1].fY; - frame[3].fX = frame[2].fX; frame[3].fY = pyt + bordersize; - frame[4].fX = pxt; frame[4].fY = pyt; - frame[5].fX = pxt; frame[5].fY = pyl; - frame[6].fX = pxl; frame[6].fY = pyl; - - if (bordermode == -1) gVirtualX->SetFillColor(TColor::GetColorBright(GetFillColor())); - else gVirtualX->SetFillColor(TColor::GetColorDark(GetFillColor())); - gVirtualX->DrawFillArea(7, frame); - - gVirtualX->SetFillColor(-1); - SetFillColor(oldcolor); + PaintBorderOn(gPad, x1, y1, x2, y2, bordersize, bordermode); + + SetFillColor(oldcolor); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Paint a 3D border around a box. +/// Used also by the pad painter + +void TWbox::PaintBorderOn(TVirtualPad *pad, + Double_t x1, Double_t y1,Double_t x2 ,Double_t y2, + Short_t bordersize, Short_t bordermode, Bool_t with_selection) +{ + if (bordermode == 0) + return; + if (bordersize <= 0) + bordersize = 2; + + auto pp = pad->GetPainter(); + if (!pp) + return; + + Double_t ww = pad->GetWw(), wh = pad->GetWh(); + + if (pp->GetPS()) { + // SL: need to calculate page size to get real coordiantes for border + // TODO: Code can be removed if border not need to be exact pixel size + Float_t xsize = 20, ysize = 26; + gStyle->GetPaperSize(xsize, ysize); + Double_t ratio = wh/ww; + if (xsize * ratio > ysize) + xsize = ysize/ratio; + else + ysize = xsize*ratio; + ww = 72 / 2.54 * xsize; + wh = 72 / 2.54 * ysize; } - if (!tops) return; + const Double_t realBsX = bordersize / (pad->GetAbsWNDC() * ww) * (pad->GetX2() - pad->GetX1()); + const Double_t realBsY = bordersize / (pad->GetAbsHNDC() * wh) * (pad->GetY2() - pad->GetY1()); + + // GetColorDark() and GetColorBright() use GetFillColor() + Color_t fillcolor = GetFillColor(); + Color_t light = !fillcolor ? 0 : GetLightColor(); + Color_t dark = !fillcolor ? 0 : GetDarkColor(); + + Double_t xl, xt, yl, yt; - // same for PostScript - // Double_t dx = (xt - xl) *Double_t(bordersize)/Double_t(pxt - pxl); - // Int_t border = gVirtualPS->XtoPS(xt) - gVirtualPS->XtoPS(xt-dx); + // Compute real left bottom & top right of the box in pixels + if (pad->XtoPixel(x1) < pad->XtoPixel(x2)) { + xl = x1; + xt = x2; + } else { + xl = x2; + xt = x1; + } + if (pad->YtoPixel(y1) > pad->YtoPixel(y2)) { + yl = y1; + yt = y2; + } else { + yl = y2; + yt = y1; + } - gPad->PaintBorderPS(xl, yl, xt, yt, bordermode, bordersize, - GetDarkColor(), GetLightColor()); + Double_t frameXs[7] = {}, frameYs[7] = {}; + + // Draw top&left part of the box + frameXs[0] = xl; frameYs[0] = yl; + frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY; + frameXs[2] = frameXs[1]; frameYs[2] = yt - realBsY; + frameXs[3] = xt - realBsX; frameYs[3] = frameYs[2]; + frameXs[4] = xt; frameYs[4] = yt; + frameXs[5] = xl; frameYs[5] = yt; + frameXs[6] = xl; frameYs[6] = yl; + + SetFillColor(bordermode == -1 ? dark : light); + pp->SetAttFill(*this); + pp->DrawFillArea(7, frameXs, frameYs); + + // Draw bottom&right part of the box + frameXs[0] = xl; frameYs[0] = yl; + frameXs[1] = xl + realBsX; frameYs[1] = yl + realBsY; + frameXs[2] = xt - realBsX; frameYs[2] = frameYs[1]; + frameXs[3] = frameXs[2]; frameYs[3] = yt - realBsY; + frameXs[4] = xt; frameYs[4] = yt; + frameXs[5] = xt; frameYs[5] = yl; + frameXs[6] = xl; frameYs[6] = yl; + + SetFillColor(bordermode == -1 ? light : dark); + pp->SetAttFill(*this); + pp->DrawFillArea(7, frameXs, frameYs); + + SetFillColor(fillcolor); + + if (with_selection) { + Color_t oldlinecolor = GetLineColor(); + SetLineColor(GetFillColor() != 2 ? 2 : 4); + pp->SetAttLine(*this); + pp->DrawBox(xl + realBsX, yl + realBsY, xt - realBsX, yt - realBsY, TVirtualPadPainter::kHollow); + SetLineColor(oldlinecolor); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/x11/inc/TGX11.h b/graf2d/x11/inc/TGX11.h index 17c524175761d..6285101f43f12 100644 --- a/graf2d/x11/inc/TGX11.h +++ b/graf2d/x11/inc/TGX11.h @@ -13,6 +13,8 @@ #define ROOT_TGX11 #include "TVirtualX.h" +#include +#include #ifdef Status // Convert Status from a CPP macro to a typedef: @@ -44,26 +46,6 @@ struct RXSetWindowAttributes; struct RXVisualInfo; struct RVisual; -/// Description of a X11 window. -struct XWindow_t { - Int_t fOpen; ///< 1 if the window is open, 0 if not - Int_t fDoubleBuffer; ///< 1 if the double buffer is on, 0 if not - Int_t fIsPixmap; ///< 1 if pixmap, 0 if not - Drawable fDrawing; ///< drawing area, equal to window or buffer - Drawable fWindow; ///< X11 window - Drawable fBuffer; ///< pixmap used for double buffer - UInt_t fWidth; ///< width of the window - UInt_t fHeight; ///< height of the window - Int_t fClip; ///< 1 if the clipping is on - Int_t fXclip; ///< x coordinate of the clipping rectangle - Int_t fYclip; ///< y coordinate of the clipping rectangle - UInt_t fWclip; ///< width of the clipping rectangle - UInt_t fHclip; ///< height of the clipping rectangle - ULong_t *fNewColors; ///< new image colors (after processing) - Int_t fNcolors; ///< number of different colors - Bool_t fShared; ///< notify when window is shared -}; - /// Description of a X11 color. struct XColor_t { ULong_t fPixel; ///< color pixel value @@ -76,25 +58,23 @@ struct XColor_t { class TExMap; +struct XWindow_t; + class TGX11 : public TVirtualX { private: - Int_t fMaxNumberOfWindows; ///< Maximum number of windows - XWindow_t *fWindows; ///< List of windows + std::unordered_map> fWindows; // map of windows TExMap *fColors; ///< Hash list of colors Cursor fCursors[kNumCursors]; ///< List of cursors void *fXEvent; ///< Current native (X11) event - void CloseWindow1(); - void ClearPixmap(Drawable *pix); - void CopyWindowtoPixmap(Drawable *pix, Int_t xpos, Int_t ypos); + Int_t AddWindowHandle(); void FindBestVisual(); void FindUsableVisual(RXVisualInfo *vlist, Int_t nitems); void PutImage(Int_t offset, Int_t itran, Int_t x0, Int_t y0, Int_t nx, Int_t ny, Int_t xmin, Int_t ymin, Int_t xmax, Int_t ymax, UChar_t *image, Drawable_t id); - void RemovePixmap(Drawable *pix); void SetColor(void *gc, Int_t ci); void SetFillStyleIndex(Int_t style, Int_t fasi); void SetInput(Int_t inp); @@ -132,7 +112,7 @@ class TGX11 : public TVirtualX { Int_t fScreenNumber; ///< Screen number Int_t fTextAlignH; ///< Text Alignment Horizontal Int_t fTextAlignV; ///< Text Alignment Vertical - Int_t fTextAlign; ///< Text alignment (set in SetTextAlign) + Int_t fTextAlign; ///< Text alignment (set in SetTextAlign) !!! conflict with TAttText Float_t fCharacterUpX; ///< Character Up vector along X Float_t fCharacterUpY; ///< Character Up vector along Y Float_t fTextMagnitude; ///< Text Magnitude @@ -150,11 +130,17 @@ class TGX11 : public TVirtualX { Bool_t AllocColor(Colormap cmap, RXColor *color); void QueryColors(Colormap cmap, RXColor *colors, Int_t ncolors); void *GetGC(Int_t which) const; + Window_t GetWindow(WinContext_t wctxt) const; + void *GetGCW(WinContext_t wctxt, Int_t which) const; + Int_t GetTextAlignW(WinContext_t wctxt) const; + XColor_t &GetColor(Int_t cid); + TGX11(TGX11 &&org); + TGX11(const TGX11 &org) = delete; + public: TGX11(); - TGX11(const TGX11 &org); TGX11(const char *name, const char *title); ~TGX11() override; @@ -163,15 +149,6 @@ class TGX11 : public TVirtualX { void ClosePixmap() override; void CloseWindow() override; void CopyPixmap(Int_t wid, Int_t xpos, Int_t ypos) override; - void DrawBox(Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode) override; - void DrawCellArray(Int_t x1, Int_t y1, Int_t x2, Int_t y2, Int_t nx, Int_t ny, Int_t *ic) override; - void DrawFillArea(Int_t n, TPoint *xy) override; - void DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2) override; - void DrawPolyLine(Int_t n, TPoint *xy) override; - void DrawLinesSegments(Int_t n, TPoint *xy) override; - void DrawPolyMarker(Int_t n, TPoint *xy) override; - void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) override; - void DrawText(Int_t, Int_t, Float_t, Float_t, const wchar_t *, ETextMode) override {} void GetCharacterUp(Float_t &chupx, Float_t &chupy) override; Int_t GetDoubleBuffer(Int_t wid) override; void GetGeometry(Int_t wid, Int_t &x, Int_t &y, UInt_t &w, UInt_t &h) override; @@ -208,12 +185,24 @@ class TGX11 : public TVirtualX { void SetDoubleBufferOFF() override; void SetDoubleBufferON() override; void SetDrawMode(EDrawMode mode) override; + void Sync(Int_t mode) override; + void UpdateWindow(Int_t mode) override; + void Warp(Int_t ix, Int_t iy, Window_t id = 0) override; + Int_t WriteGIF(char *name) override; + void WritePixmap(Int_t wid, UInt_t w, UInt_t h, char *pxname) override; + Window_t GetCurrentWindow() const override; + Int_t SupportsExtension(const char *ext) const override; + + //---- Methods used for old graphics ----- void SetFillColor(Color_t cindex) override; void SetFillStyle(Style_t style) override; + Style_t GetFillStyle() const override; void SetLineColor(Color_t cindex) override; void SetLineType(Int_t n, Int_t *dash) override; void SetLineStyle(Style_t linestyle) override; + Style_t GetLineStyle() const override; void SetLineWidth(Width_t width) override; + Width_t GetLineWidth() const override; void SetMarkerColor(Color_t cindex) override; void SetMarkerSize(Float_t markersize) override; void SetMarkerStyle(Style_t markerstyle) override; @@ -225,13 +214,32 @@ class TGX11 : public TVirtualX { void SetTextFont(Font_t fontnumber) override; void SetTextMagnitude(Float_t mgn=1) override { fTextMagnitude = mgn;} void SetTextSize(Float_t textsize) override; - void Sync(Int_t mode) override; - void UpdateWindow(Int_t mode) override; - void Warp(Int_t ix, Int_t iy, Window_t id = 0) override; - Int_t WriteGIF(char *name) override; - void WritePixmap(Int_t wid, UInt_t w, UInt_t h, char *pxname) override; - Window_t GetCurrentWindow() const override; - Int_t SupportsExtension(const char *ext) const override; + void DrawBox(Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode) override; + void DrawCellArray(Int_t x1, Int_t y1, Int_t x2, Int_t y2, Int_t nx, Int_t ny, Int_t *ic) override; + void DrawFillArea(Int_t n, TPoint *xy) override; + void DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2) override; + void DrawPolyLine(Int_t n, TPoint *xy) override; + void DrawLinesSegments(Int_t n, TPoint *xy) override; + void DrawPolyMarker(Int_t n, TPoint *xy) override; + void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) override; + void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const wchar_t *text, ETextMode mode) override; + + //---- Methods used for new graphics ----- + WinContext_t GetWindowContext(Int_t wid) override; + void SetAttFill(WinContext_t wctxt, const TAttFill &att) override; + void SetAttLine(WinContext_t wctxt, const TAttLine &att) override; + void SetAttMarker(WinContext_t wctxt, const TAttMarker &att) override; + void SetAttText(WinContext_t wctxt, const TAttText &att) override; + void SetDrawModeW(WinContext_t wctxt, EDrawMode mode) override; + + void DrawBoxW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode) override; + void DrawFillAreaW(WinContext_t wctxt, Int_t n, TPoint *xy) override; + void DrawLineW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2) override; + void DrawPolyLineW(WinContext_t wctxt, Int_t n, TPoint *xy) override; + void DrawLinesSegmentsW(WinContext_t wctxt, Int_t n, TPoint *xy) override; + void DrawPolyMarkerW(WinContext_t wctxt, Int_t n, TPoint *xy) override; + void DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) override; + void DrawTextW(WinContext_t, Int_t, Int_t, Float_t, Float_t, const wchar_t *, ETextMode) override {} //---- Methods used for GUI ----- void GetWindowAttributes(Window_t id, WindowAttributes_t &attr) override; diff --git a/graf2d/x11/src/TGX11.cxx b/graf2d/x11/src/TGX11.cxx index 9ba0fc6849e8f..235913943469f 100644 --- a/graf2d/x11/src/TGX11.cxx +++ b/graf2d/x11/src/TGX11.cxx @@ -76,30 +76,77 @@ extern int XRotDrawAlignedImageString(Display*, XFontStruct*, float, extern XPoint *XRotTextExtents(Display*, XFontStruct*, float, int, int, char*, int); -//---- globals - -static XWindow_t *gCws; // gCws: pointer to the current window -static XWindow_t *gTws; // gTws: temporary pointer -const Int_t kBIGGEST_RGB_VALUE = 65535; // // Primitives Graphic Contexts global for all windows // -const int kMAXGC = 7; -static GC gGClist[kMAXGC]; -static GC *gGCline = &gGClist[0]; // PolyLines -static GC *gGCmark = &gGClist[1]; // PolyMarker -static GC *gGCfill = &gGClist[2]; // Fill areas -static GC *gGCtext = &gGClist[3]; // Text -static GC *gGCinvt = &gGClist[4]; // Inverse text -static GC *gGCdash = &gGClist[5]; // Dashed lines -static GC *gGCpxmp = &gGClist[6]; // Pixmap management +const int kMAXGC = 7, + kGCline = 0, kGCmark = 1, kGCfill = 2, + kGCtext = 3, kGCinvt = 4, kGCdash = 5, kGCpxmp = 6; +// static GC gGClist[kMAXGC]; +// static GC *gGCline = &gGClist[kGCline]; // PolyLines +// static GC *gGCmark = &gGClist[kGCmark]; // PolyMarker +// static GC *gGCfill = &gGClist[kGCfill]; // Fill areas +// static GC *gGCtext = &gGClist[kGCtext]; // Text +// static GC *gGCinvt = &gGClist[kGCinvt]; // Inverse text +// static GC *gGCdash = &gGClist[kGCinvt]; // Dashed lines +// static GC *gGCpxmp = &gGClist[kGCpxmp]; // Pixmap management static GC gGCecho; // Input echo -static Int_t gFillHollow; // Flag if fill style is hollow -static Pixmap gFillPattern = 0; // Fill pattern + +/// Description of a X11 window. +struct XWindow_t { + Int_t fOpen = 0; ///< 1 if the window is open, 0 if not + Int_t fDoubleBuffer = 0; ///< 1 if the double buffer is on, 0 if not + Int_t fIsPixmap = 0; ///< 1 if pixmap, 0 if not + Drawable fDrawing = 0; ///< drawing area, equal to window or buffer + Drawable fWindow = 0; ///< X11 window + Drawable fBuffer = 0; ///< pixmap used for double buffer + UInt_t fWidth = 0; ///< width of the window + UInt_t fHeight = 0; ///< height of the window + Int_t fClip = 0; ///< 1 if the clipping is on + Int_t fXclip = 0; ///< x coordinate of the clipping rectangle + Int_t fYclip = 0; ///< y coordinate of the clipping rectangle + UInt_t fWclip = 0; ///< width of the clipping rectangle + UInt_t fHclip = 0; ///< height of the clipping rectangle + ULong_t *fNewColors = 0; ///< new image colors (after processing) + Int_t fNcolors = 0; ///< number of different colors + Bool_t fShared = 0; ///< notify when window is shared + GC fGClist[kMAXGC]; ///< list of GC object, individual for each window + TVirtualX::EDrawMode fDrawMode = TVirtualX::kCopy; ///< current draw mode + TAttLine fAttLine = {-1, -1, -1}; ///< current line attributes + Int_t lineWidth = 0; ///< X11 line width + Int_t lineStyle = LineSolid; ///< X11 line style + std::vector dashList; ///< X11 array for dashes + Int_t dashLength = 0; ///< total length of dashes + Int_t dashOffset = 0; ///< current dash offset + TAttFill fAttFill = {-1, -1}; ///< current fill attributes + Int_t fillHollow = 0; ///< X11 fill method + Int_t fillFasi = 0; ///< selected fasi pattern + Pixmap fillPattern = 0; ///< current initialized fill pattern + TAttMarker fAttMarker = { -1, -1, -1 }; ///< current marker attribute + Int_t markerType = 0; ///< 4 differen kinds of marker + Int_t markerSize = 0; ///< size of simple markers + std::vector markerShape; ///< marker shape points + Int_t markerLineWidth = 0; ///< line width used for marker + TAttText fAttText; ///< current text attribute + Int_t textAlign = 0; ///< selected text align + XFontStruct *textFont = nullptr; ///< selected text font +}; + + +//---- globals + +static XWindow_t *gCws; // gCws: pointer to the current window +static XWindow_t *gTws; // gTws: temporary pointer + +const Int_t kBIGGEST_RGB_VALUE = 65535; + + +// static Int_t gFillHollow; // Flag if fill style is hollow +// static Pixmap gFillPattern = 0; // Fill pattern // // Text management @@ -116,13 +163,13 @@ static Int_t gCurrentFontNumber = 0; // Current font number in gFont[] // // Markers // -const Int_t kMAXMK = 100; -static struct { - int type; - int n; - XPoint xy[kMAXMK]; -} gMarker; // Point list to draw marker -static int gMarkerLineWidth = 0; +// const Int_t kMAXMK = 100; +// static struct { +// int type; +// int n; +// XPoint xy[kMAXMK]; +// } gMarker; // Point list to draw marker +// static int gMarkerLineWidth = 0; static int gMarkerLineStyle = LineSolid; static int gMarkerCapStyle = CapRound; static int gMarkerJoinStyle = JoinRound; @@ -130,14 +177,14 @@ static int gMarkerJoinStyle = JoinRound; // // Keep style values for line GC // -static int gLineWidth = 0; -static int gLineStyle = LineSolid; +// static int gLineWidth = 0; +// static int gLineStyle = LineSolid; static int gCapStyle = CapButt; static int gJoinStyle = JoinMiter; -static char gDashList[10]; -static int gDashLength = 0; -static int gDashOffset = 0; -static int gDashSize = 0; +// static char gDashList[10]; +// static int gDashLength = 0; +// static int gDashOffset = 0; +// static int gDashSize = 0; // // Event masks @@ -180,7 +227,6 @@ TGX11::TGX11() fColormap = 0; fBlackPixel = 0; fWhitePixel = 0; - fWindows = nullptr; fColors = nullptr; fXEvent = new XEvent; fRedDiv = -1; @@ -194,7 +240,6 @@ TGX11::TGX11() fDepth = 0; fHasTTFonts = kFALSE; fHasXft = kFALSE; - fMaxNumberOfWindows = 10; fTextAlignH = 1; fTextAlignV = 1; fTextAlign = 7; @@ -229,17 +274,12 @@ TGX11::TGX11(const char *name, const char *title) : TVirtualX(name, title) fDepth = 0; fHasTTFonts = kFALSE; fHasXft = kFALSE; - fMaxNumberOfWindows = 10; fTextAlignH = 1; fTextAlignV = 1; fTextAlign = 7; fTextMagnitude = 1; - for (i = 0; i < kNumCursors; i++) fCursors[i] = 0; - - //fWindows = new XWindow_t[fMaxNumberOfWindows]; - fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t)); - for (i = 0; i < fMaxNumberOfWindows; i++) - fWindows[i].fOpen = 0; + for (i = 0; i < kNumCursors; i++) + fCursors[i] = 0; fColors = new TExMap; } @@ -247,10 +287,8 @@ TGX11::TGX11(const char *name, const char *title) : TVirtualX(name, title) //////////////////////////////////////////////////////////////////////////////// /// Copy constructor. Currently only used by TGX11TTF. -TGX11::TGX11(const TGX11 &org) : TVirtualX(org) +TGX11::TGX11(TGX11 &&org) : TVirtualX(org) { - int i; - fDisplay = org.fDisplay; fScreenNumber = org.fScreenNumber; fVisual = org.fVisual; @@ -275,45 +313,14 @@ TGX11::TGX11(const TGX11 &org) : TVirtualX(org) fGreenShift = org.fGreenShift; fBlueShift = org.fBlueShift; fDrawMode = org.fDrawMode; - fXEvent = new XEvent; - - fMaxNumberOfWindows = org.fMaxNumberOfWindows; - //fWindows = new XWindow_t[fMaxNumberOfWindows]; - fWindows = (XWindow_t*) TStorage::Alloc(fMaxNumberOfWindows*sizeof(XWindow_t)); - for (i = 0; i < fMaxNumberOfWindows; i++) { - fWindows[i].fOpen = org.fWindows[i].fOpen; - fWindows[i].fDoubleBuffer = org.fWindows[i].fDoubleBuffer; - fWindows[i].fIsPixmap = org.fWindows[i].fIsPixmap; - fWindows[i].fDrawing = org.fWindows[i].fDrawing; - fWindows[i].fWindow = org.fWindows[i].fWindow; - fWindows[i].fBuffer = org.fWindows[i].fBuffer; - fWindows[i].fWidth = org.fWindows[i].fWidth; - fWindows[i].fHeight = org.fWindows[i].fHeight; - fWindows[i].fClip = org.fWindows[i].fClip; - fWindows[i].fXclip = org.fWindows[i].fXclip; - fWindows[i].fYclip = org.fWindows[i].fYclip; - fWindows[i].fWclip = org.fWindows[i].fWclip; - fWindows[i].fHclip = org.fWindows[i].fHclip; - fWindows[i].fNewColors = org.fWindows[i].fNewColors; - fWindows[i].fNcolors = org.fWindows[i].fNcolors; - fWindows[i].fShared = org.fWindows[i].fShared; - } + fXEvent = org.fXEvent; org.fXEvent = nullptr; + fColors = org.fColors; org.fColors = nullptr; - for (i = 0; i < kNumCursors; i++) - fCursors[i] = org.fCursors[i]; + fWindows = std::move(org.fWindows); - fColors = new TExMap; - Long64_t key, value; - TExMapIter it(org.fColors); - while (it.Next(key, value)) { - XColor_t *colo = (XColor_t *) (Long_t)value; - XColor_t *col = new XColor_t; - col->fPixel = colo->fPixel; - col->fRed = colo->fRed; - col->fGreen = colo->fGreen; - col->fBlue = colo->fBlue; - col->fDefined = colo->fDefined; - fColors->Add(key, (Long_t) col); + for (int i = 0; i < kNumCursors; i++) { + fCursors[i] = org.fCursors[i]; + org.fCursors[i] = 0; } } @@ -322,17 +329,22 @@ TGX11::TGX11(const TGX11 &org) : TVirtualX(org) TGX11::~TGX11() { - delete (XEvent*)fXEvent; - if (fWindows) TStorage::Dealloc(fWindows); - - if (!fColors) return; - Long64_t key, value; - TExMapIter it(fColors); - while (it.Next(key, value)) { - XColor_t *col = (XColor_t *) (Long_t)value; - delete col; + if (fXEvent) + delete (XEvent*)fXEvent; + + if (fColors) { + Long64_t key, value; + TExMapIter it(fColors); + while (it.Next(key, value)) { + XColor_t *col = (XColor_t *) (Long_t)value; + delete col; + } + delete fColors; } - delete fColors; + + for (int i = 0; i < kNumCursors; i++) + if (fCursors[i]) + XFreeCursor((Display*)fDisplay, fCursors[i]); } //////////////////////////////////////////////////////////////////////////////// @@ -340,7 +352,8 @@ TGX11::~TGX11() Bool_t TGX11::Init(void *display) { - if (OpenDisplay(display) == -1) return kFALSE; + if (OpenDisplay(display) == -1) + return kFALSE; return kTRUE; } @@ -400,20 +413,6 @@ void TGX11::QueryColors(Colormap cmap, RXColor *color, Int_t ncolors) } } -//////////////////////////////////////////////////////////////////////////////// -/// Clear the pixmap pix. - -void TGX11::ClearPixmap(Drawable *pix) -{ - Window root; - int xx, yy; - unsigned int ww, hh, border, depth; - XGetGeometry((Display*)fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth); - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, *pix, *gGCpxmp, 0 ,0 ,ww ,hh); - SetColor(gGCpxmp, 1); - XFlush((Display*)fDisplay); -} //////////////////////////////////////////////////////////////////////////////// /// Clear current window. @@ -427,10 +426,10 @@ void TGX11::ClearWindow() XClearWindow((Display*)fDisplay, gCws->fDrawing); XFlush((Display*)fDisplay); } else { - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCpxmp, + SetColor(&gCws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gCws->fDrawing, gCws->fGClist[kGCpxmp], 0, 0, gCws->fWidth, gCws->fHeight); - SetColor(gGCpxmp, 1); + SetColor(&gCws->fGClist[kGCpxmp], 1); } } @@ -439,7 +438,7 @@ void TGX11::ClearWindow() void TGX11::ClosePixmap() { - CloseWindow1(); + CloseWindow(); } //////////////////////////////////////////////////////////////////////////////// @@ -447,48 +446,62 @@ void TGX11::ClosePixmap() void TGX11::CloseWindow() { - if (gCws->fShared) - gCws->fOpen = 0; - else - CloseWindow1(); + if (gCws->fShared) { + // case of Qt window + if (gCws->fBuffer) + XFreePixmap((Display*)fDisplay, gCws->fBuffer); - // Never close connection. TApplication takes care of that - // if (!gCws) Close(); // close X when no open window left -} + if (gCws->fNewColors) { + if (fRedDiv == -1) + XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0); + delete [] gCws->fNewColors; + gCws->fNewColors = nullptr; + } + } else { + if (gCws->fIsPixmap) + XFreePixmap((Display*)fDisplay, gCws->fWindow); + else + XDestroyWindow((Display*)fDisplay, gCws->fWindow); -//////////////////////////////////////////////////////////////////////////////// -/// Delete current window. + if (gCws->fBuffer) + XFreePixmap((Display*)fDisplay, gCws->fBuffer); -void TGX11::CloseWindow1() -{ - int wid; + if (gCws->fNewColors) { + if (fRedDiv == -1) + XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0); + delete [] gCws->fNewColors; + gCws->fNewColors = nullptr; + } - if (gCws->fIsPixmap) - XFreePixmap((Display*)fDisplay, gCws->fWindow); - else - XDestroyWindow((Display*)fDisplay, gCws->fWindow); + XFlush((Display*)fDisplay); + } - if (gCws->fBuffer) XFreePixmap((Display*)fDisplay, gCws->fBuffer); + for (int i = 0; i < kMAXGC; ++i) + XFreeGC((Display*)fDisplay, gCws->fGClist[i]); - if (gCws->fNewColors) { - if (fRedDiv == -1) - XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0); - delete [] gCws->fNewColors; - gCws->fNewColors = nullptr; + if (gCws->fillPattern != 0) { + XFreePixmap((Display*)fDisplay, gCws->fillPattern); + gCws->fillPattern = 0; } - XFlush((Display*)fDisplay); - gCws->fOpen = 0; - // make first window in list the current window - for (wid = 0; wid < fMaxNumberOfWindows; wid++) - if (fWindows[wid].fOpen) { - gCws = &fWindows[wid]; - return; + for (auto iter = fWindows.begin(); iter != fWindows.end(); ++iter) + if (iter->second.get() == gCws) { + fWindows.erase(iter); + gCws = nullptr; + break; } - gCws = nullptr; + if (gCws) + Fatal("CloseWindow", "Not found gCws in list of windows"); + + // select first from active windows + for (auto iter = fWindows.begin(); iter != fWindows.end(); ++iter) + if (iter->second->fOpen) { + gCws = iter->second.get(); + return; + } } //////////////////////////////////////////////////////////////////////////////// @@ -496,35 +509,34 @@ void TGX11::CloseWindow1() void TGX11::CopyPixmap(int wid, int xpos, int ypos) { - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); - XCopyArea((Display*)fDisplay, gTws->fDrawing, gCws->fDrawing, *gGCpxmp, 0, 0, gTws->fWidth, + XCopyArea((Display*)fDisplay, gTws->fDrawing, gCws->fDrawing, gTws->fGClist[kGCpxmp], 0, 0, gTws->fWidth, gTws->fHeight, xpos, ypos); XFlush((Display*)fDisplay); } //////////////////////////////////////////////////////////////////////////////// -/// Copy area of current window in the pixmap pix. +/// Draw a box. +/// +/// - mode=0 hollow (kHollow) +/// - mode=1 solid (kSolid) -void TGX11::CopyWindowtoPixmap(Drawable *pix, int xpos, int ypos ) +void TGX11::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode) { - Window root; - int xx, yy; - unsigned int ww, hh, border, depth; - - XGetGeometry((Display*)fDisplay, *pix, &root, &xx, &yy, &ww, &hh, &border, &depth); - XCopyArea((Display*)fDisplay, gCws->fDrawing, *pix, *gGCpxmp, xpos, ypos, ww, hh, 0, 0); - XFlush((Display*)fDisplay); + DrawBoxW((WinContext_t) gCws, x1, y1, x2, y2, mode); } //////////////////////////////////////////////////////////////////////////////// -/// Draw a box. +/// Draw a box on specified window /// /// - mode=0 hollow (kHollow) /// - mode=1 solid (kSolid) -void TGX11::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode) +void TGX11::DrawBoxW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2, EBoxMode mode) { + auto ctxt = (XWindow_t *) wctxt; + Int_t x = TMath::Min(x1, x2); Int_t y = TMath::Min(y1, y2); Int_t w = TMath::Abs(x2 - x1); @@ -533,11 +545,11 @@ void TGX11::DrawBox(int x1, int y1, int x2, int y2, EBoxMode mode) switch (mode) { case kHollow: - XDrawRectangle((Display*)fDisplay, gCws->fDrawing, *gGCline, x, y, w, h); + XDrawRectangle((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCline], x, y, w, h); break; case kFilled: - XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCfill, x, y, w, h); + XFillRectangle((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCfill], x, y, w, h); break; default: @@ -571,10 +583,10 @@ void TGX11::DrawCellArray(int x1, int y1, int x2, int y2, int nx, int ny, int *i for (j = 0; j < ny; j++) { icol = ic[i+(nx*j)]; if (icol != current_icol) { - XSetForeground((Display*)fDisplay, *gGCfill, GetColor(icol).fPixel); + XSetForeground((Display*)fDisplay, gCws->fGClist[kGCfill], GetColor(icol).fPixel); current_icol = icol; } - XFillRectangle((Display*)fDisplay, gCws->fDrawing, *gGCfill, ix, iy, w, h); + XFillRectangle((Display*)fDisplay, gCws->fDrawing, gCws->fGClist[kGCfill], ix, iy, w, h); iy = iy-h; } ix = ix+w; @@ -589,13 +601,25 @@ void TGX11::DrawCellArray(int x1, int y1, int x2, int y2, int nx, int ny, int *i void TGX11::DrawFillArea(int n, TPoint *xy) { - XPoint *xyp = (XPoint*)xy; + DrawFillAreaW((WinContext_t) gCws, n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Fill area described by polygon on specified window +/// +/// \param [in] n number of points +/// \param [in] xy list of points - if (gFillHollow) - XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCfill, xyp, n, CoordModeOrigin); +void TGX11::DrawFillAreaW(WinContext_t wctxt, Int_t n, TPoint *xy) +{ + auto ctxt = (XWindow_t *) wctxt; + XPoint *xyp = (XPoint *)xy; + + if (ctxt->fillHollow) + XDrawLines((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCfill], xyp, n, CoordModeOrigin); else { - XFillPolygon((Display*)fDisplay, gCws->fDrawing, *gGCfill, + XFillPolygon((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCfill], xyp, n, Nonconvex, CoordModeOrigin); } } @@ -608,11 +632,24 @@ void TGX11::DrawFillArea(int n, TPoint *xy) void TGX11::DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2) { - if (gLineStyle == LineSolid) - XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCline, x1, y1, x2, y2); + DrawLineW((WinContext_t) gCws, x1, y1, x2, y2); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw a line on specified window. +/// +/// \param [in] x1,y1 : begin of line +/// \param [in] x2,y2 : end of line + +void TGX11::DrawLineW(WinContext_t wctxt, Int_t x1, Int_t y1, Int_t x2, Int_t y2) +{ + auto ctxt = (XWindow_t *) wctxt; + + if (ctxt->lineStyle == LineSolid) + XDrawLine((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCline], x1, y1, x2, y2); else { - XSetDashes((Display*)fDisplay, *gGCdash, gDashOffset, gDashList, gDashSize); - XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCdash, x1, y1, x2, y2); + XSetDashes((Display*)fDisplay, ctxt->fGClist[kGCdash], ctxt->dashOffset, ctxt->dashList.data(), ctxt->dashList.size()); + XDrawLine((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCdash], x1, y1, x2, y2); } } @@ -624,6 +661,18 @@ void TGX11::DrawLine(Int_t x1, Int_t y1, Int_t x2, Int_t y2) void TGX11::DrawPolyLine(int n, TPoint *xy) { + DrawPolyLineW((WinContext_t) gCws, n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw a line through all points on specified window. +/// +/// \param [in] n number of points +/// \param [in] xy list of points + +void TGX11::DrawPolyLineW(WinContext_t wctxt, Int_t n, TPoint *xy) +{ + auto ctxt = (XWindow_t *) wctxt; XPoint *xyp = (XPoint*)xy; const Int_t kMaxPoints = 1000001; @@ -632,39 +681,36 @@ void TGX11::DrawPolyLine(int n, TPoint *xy) int ibeg = 0; int iend = kMaxPoints - 1; while (iend < n) { - DrawPolyLine( kMaxPoints, &xy[ibeg] ); + DrawPolyLineW(wctxt, kMaxPoints, &xy[ibeg]); ibeg = iend; iend += kMaxPoints - 1; } if (ibeg < n) { int npt = n - ibeg; - DrawPolyLine( npt, &xy[ibeg] ); + DrawPolyLineW(wctxt, npt, &xy[ibeg]); } } else if (n > 1) { - if (gLineStyle == LineSolid) - XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCline, xyp, n, CoordModeOrigin); + if (ctxt->lineStyle == LineSolid) + XDrawLines((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCline], xyp, n, CoordModeOrigin); else { - int i; - XSetDashes((Display*)fDisplay, *gGCdash, - gDashOffset, gDashList, gDashSize); - XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCdash, xyp, n, CoordModeOrigin); + XSetDashes((Display*)fDisplay, ctxt->fGClist[kGCdash], ctxt->dashOffset, ctxt->dashList.data(), ctxt->dashList.size()); + XDrawLines((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCdash], xyp, n, CoordModeOrigin); // calculate length of line to update dash offset - for (i = 1; i < n; i++) { + for (int i = 1; i < n; i++) { int dx = xyp[i].x - xyp[i-1].x; int dy = xyp[i].y - xyp[i-1].y; if (dx < 0) dx = - dx; if (dy < 0) dy = - dy; - gDashOffset += dx > dy ? dx : dy; + ctxt->dashOffset += dx > dy ? dx : dy; } - gDashOffset %= gDashLength; + ctxt->dashOffset %= ctxt->dashLength; } } else { - int px,py; - px=xyp[0].x; - py=xyp[0].y; - XDrawPoint((Display*)fDisplay, gCws->fDrawing, - gLineStyle == LineSolid ? *gGCline : *gGCdash, px, py); + int px = xyp[0].x; + int py = xyp[0].y; + XDrawPoint((Display*)fDisplay, ctxt->fDrawing, + ctxt->lineStyle == LineSolid ? ctxt->fGClist[kGCline] : ctxt->fGClist[kGCdash], px, py); } } @@ -676,21 +722,34 @@ void TGX11::DrawPolyLine(int n, TPoint *xy) void TGX11::DrawLinesSegments(Int_t n, TPoint *xy) { + DrawLinesSegmentsW((WinContext_t) gCws, n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draws N segments between provided points on specified windows +/// +/// \param [in] n number of segements +/// \param [in] xy list of points, size 2*n + +void TGX11::DrawLinesSegmentsW(WinContext_t wctxt, Int_t n, TPoint *xy) +{ + auto ctxt = (XWindow_t *) wctxt; + const Int_t kMaxSegments = 500000; if (n > kMaxSegments) { Int_t ibeg = 0; Int_t iend = kMaxSegments; while (ibeg < n) { - DrawLinesSegments(iend - ibeg, &xy[ibeg*2]); + DrawLinesSegmentsW(wctxt, iend - ibeg, &xy[ibeg*2]); ibeg = iend; iend = TMath::Min(n, iend + kMaxSegments); } } else if (n > 0) { - if (gLineStyle == LineSolid) - XDrawSegments((Display*)fDisplay, gCws->fDrawing, *gGCline, (XSegment *) xy, n); + if (ctxt->lineStyle == LineSolid) + XDrawSegments((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCline], (XSegment *) xy, n); else { - XSetDashes((Display*)fDisplay, *gGCdash, gDashOffset, gDashList, gDashSize); - XDrawSegments((Display*)fDisplay, gCws->fDrawing, *gGCdash, (XSegment *) xy, n); + XSetDashes((Display*)fDisplay, ctxt->fGClist[kGCdash], ctxt->dashOffset, ctxt->dashList.data(), ctxt->dashList.size()); + XDrawSegments((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCdash], (XSegment *) xy, n); } } } @@ -704,63 +763,69 @@ void TGX11::DrawLinesSegments(Int_t n, TPoint *xy) void TGX11::DrawPolyMarker(int n, TPoint *xy) { - XPoint *xyp = (XPoint*)xy; + DrawPolyMarkerW((WinContext_t) gCws, n, xy); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw n markers with the current attributes at position x, y on specified window. +/// +/// \param [in] n number of markers to draw +/// \param [in] xy x,y coordinates of markers + +void TGX11::DrawPolyMarkerW(WinContext_t wctxt, Int_t n, TPoint *xy) +{ + auto ctxt = (XWindow_t *) wctxt; + XPoint *xyp = (XPoint *) xy; - if (gMarker.n <= 0) { + if ((ctxt->markerShape.size() == 0) && (ctxt->markerSize <= 0)) { const int kNMAX = 1000000; int nt = n/kNMAX; for (int it=0;it<=nt;it++) { if (it < nt) { - XDrawPoints((Display*)fDisplay, gCws->fDrawing, *gGCmark, &xyp[it*kNMAX], kNMAX, CoordModeOrigin); + XDrawPoints((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], &xyp[it*kNMAX], kNMAX, CoordModeOrigin); } else { - XDrawPoints((Display*)fDisplay, gCws->fDrawing, *gGCmark, &xyp[it*kNMAX], n-it*kNMAX, CoordModeOrigin); + XDrawPoints((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], &xyp[it*kNMAX], n-it*kNMAX, CoordModeOrigin); } } } else { - int r = gMarker.n / 2; - int m; - - for (m = 0; m < n; m++) { - int hollow = 0; - - switch (gMarker.type) { - int i; - - case 0: // hollow circle - XDrawArc((Display*)fDisplay, gCws->fDrawing, *gGCmark, - xyp[m].x - r, xyp[m].y - r, gMarker.n, gMarker.n, 0, 360*64); - break; - - case 1: // filled circle - XFillArc((Display*)fDisplay, gCws->fDrawing, *gGCmark, - xyp[m].x - r, xyp[m].y - r, gMarker.n, gMarker.n, 0, 360*64); - break; - - case 2: // hollow polygon - hollow = 1; - case 3: // filled polygon - for (i = 0; i < gMarker.n; i++) { - gMarker.xy[i].x += xyp[m].x; - gMarker.xy[i].y += xyp[m].y; - } - if (hollow) - XDrawLines((Display*)fDisplay, gCws->fDrawing, *gGCmark, - gMarker.xy, gMarker.n, CoordModeOrigin); - else - XFillPolygon((Display*)fDisplay, gCws->fDrawing, *gGCmark, - gMarker.xy, gMarker.n, Nonconvex, CoordModeOrigin); - for (i = 0; i < gMarker.n; i++) { - gMarker.xy[i].x -= xyp[m].x; - gMarker.xy[i].y -= xyp[m].y; - } - break; - - case 4: // segmented line - for (i = 0; i < gMarker.n; i += 2) - XDrawLine((Display*)fDisplay, gCws->fDrawing, *gGCmark, - xyp[m].x + gMarker.xy[i].x, xyp[m].y + gMarker.xy[i].y, - xyp[m].x + gMarker.xy[i+1].x, xyp[m].y + gMarker.xy[i+1].y); - break; + int r = ctxt->markerSize / 2; + auto &shape = ctxt->markerShape; + + for (int m = 0; m < n; m++) { + if (ctxt->markerType == 0) { + // hollow circle + XDrawArc((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], + xyp[m].x - r, xyp[m].y - r, ctxt->markerSize, ctxt->markerSize, 0, 360*64); + } else if (ctxt->markerType == 1) { + // filled circle + XFillArc((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], + xyp[m].x - r, xyp[m].y - r, ctxt->markerSize, ctxt->markerSize, 0, 360*64); + } else { + for (size_t i = 0; i < shape.size(); i++) { + shape[i].x += xyp[m].x; + shape[i].y += xyp[m].y; + } + switch(ctxt->markerType) { + case 2: + // hollow polygon + XDrawLines((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], + shape.data(), shape.size(), CoordModeOrigin); + break; + case 3: + // filled polygon + XFillPolygon((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], + shape.data(), shape.size(), Nonconvex, CoordModeOrigin); + break; + case 4: + // segmented line + XDrawSegments((Display*)fDisplay, ctxt->fDrawing, ctxt->fGClist[kGCmark], + (XSegment *) shape.data(), shape.size()/2); + break; + } + for (size_t i = 0; i < shape.size(); i++) { + shape[i].x -= xyp[m].x; + shape[i].y -= xyp[m].y; + } } } } @@ -780,20 +845,57 @@ void TGX11::DrawPolyMarker(int n, TPoint *xy) void TGX11::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) { - XRotSetMagnification(mgn); + DrawTextW((WinContext_t) gCws, x, y, angle, mgn, text, mode); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw a text string using current font. +/// +/// \param [in] mode : drawing mode +/// - mode=0 : the background is not drawn (kClear) +/// - mode=1 : the background is drawn (kOpaque) +/// \param [in] x,y : text position +/// \param [in] angle : text angle +/// \param [in] mgn : magnification factor +/// \param [in] text : text string + +void TGX11::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, + const wchar_t *text, ETextMode mode) +{ + DrawTextW((WinContext_t) gCws, x, y, angle, mgn, text, mode); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Draw a text string using current font on specified window. +/// +/// \param [in] mode : drawing mode +/// - mode=0 : the background is not drawn (kClear) +/// - mode=1 : the background is drawn (kOpaque) +/// \param [in] x,y : text position +/// \param [in] angle : text angle +/// \param [in] mgn : magnification factor +/// \param [in] text : text string + +void TGX11::DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, + const char *text, ETextMode mode) +{ + auto ctxt = (XWindow_t *) wctxt; + + if (!text || !ctxt->textFont || ctxt->fAttText.GetTextSize() < 0) + return; - if (!text) return; + XRotSetMagnification(mgn); switch (mode) { case kClear: - XRotDrawAlignedString((Display*)fDisplay, gTextFont, angle, - gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign); + XRotDrawAlignedString((Display*)fDisplay, ctxt->textFont, angle, + ctxt->fDrawing, ctxt->fGClist[kGCtext], x, y, (char*)text, ctxt->textAlign); break; case kOpaque: - XRotDrawAlignedImageString((Display*)fDisplay, gTextFont, angle, - gCws->fDrawing, *gGCtext, x, y, (char*)text, fTextAlign); + XRotDrawAlignedImageString((Display*)fDisplay, ctxt->textFont, angle, + ctxt->fDrawing, ctxt->fGClist[kGCtext], x, y, (char*)text, ctxt->textAlign); break; default: @@ -946,7 +1048,7 @@ XColor_t &TGX11::GetColor(Int_t cid) } //////////////////////////////////////////////////////////////////////////////// -/// Return current window pointer. Protected method used by TGX11TTF. +/// Return current window pointer. Window_t TGX11::GetCurrentWindow() const { @@ -963,7 +1065,50 @@ void *TGX11::GetGC(Int_t which) const Error("GetGC", "trying to get illegal GC (which = %d)", which); return nullptr; } - return &gGClist[which]; + if (!gCws) { + Error("GetGC", "No current window selected"); + return nullptr; + } + return &gCws->fGClist[which]; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return X11 window for specified window context. +/// Protected method used by TGX11TTF. + +Window_t TGX11::GetWindow(WinContext_t wctxt) const +{ + auto ctxt = (XWindow_t *) wctxt; + return (Window_t) (ctxt ? ctxt->fDrawing : 0); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return X11 Graphics Context for specified window context. +/// Protected method used by TGX11TTF. + +void *TGX11::GetGCW(WinContext_t wctxt, Int_t which) const +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) { + Error("GetGC", "No window context specified"); + return nullptr; + } + + if (which >= kMAXGC || which < 0) { + Error("GetGC", "trying to get illegal GC (which = %d)", which); + return nullptr; + } + return &ctxt->fGClist[which]; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return text align value for specified window context. +/// Protected method used by TGX11TTF. + +Int_t TGX11::GetTextAlignW(WinContext_t wctxt) const +{ + auto ctxt = (XWindow_t *) wctxt; + return ctxt ? ctxt->textAlign : 0; } //////////////////////////////////////////////////////////////////////////////// @@ -971,7 +1116,7 @@ void *TGX11::GetGC(Int_t which) const Int_t TGX11::GetDoubleBuffer(int wid) { - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); if (!gTws->fOpen) return -1; else @@ -1001,7 +1146,7 @@ void TGX11::GetGeometry(int wid, int &x, int &y, unsigned int &w, unsigned int & unsigned int border, depth; unsigned int width, height; - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); XGetGeometry((Display*)fDisplay, gTws->fWindow, &root, &x, &y, &width, &height, &border, &depth); XTranslateCoordinates((Display*)fDisplay, gTws->fWindow, fRootWin, @@ -1096,7 +1241,7 @@ void TGX11::GetTextExtent(UInt_t &w, UInt_t &h, char *mess) Window_t TGX11::GetWindowID(int wid) { - return (Window_t) fWindows[wid].fWindow; + return (Window_t) fWindows[wid]->fWindow; } //////////////////////////////////////////////////////////////////////////////// @@ -1108,7 +1253,7 @@ Window_t TGX11::GetWindowID(int wid) void TGX11::MoveWindow(Int_t wid, Int_t x, Int_t y) { - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); if (!gTws->fOpen) return; XMoveWindow((Display*)fDisplay, gTws->fWindow, x, y); @@ -1142,9 +1287,10 @@ Int_t TGX11::OpenDisplay(void *disp) strlcpy(vendor, XServerVendor((Display*)fDisplay),132); // Create primitives graphic contexts - for (i = 0; i < kMAXGC; i++) - gGClist[i] = XCreateGC((Display*)fDisplay, fVisRootWin, 0, nullptr); + // for (i = 0; i < kMAXGC; i++) + // gGClist[i] = XCreateGC((Display*)fDisplay, fVisRootWin, 0, nullptr); +/* XGCValues values; if (XGetGCValues((Display*)fDisplay, *gGCtext, GCForeground|GCBackground, &values)) { XSetForeground((Display*)fDisplay, *gGCinvt, values.background); @@ -1152,11 +1298,7 @@ Int_t TGX11::OpenDisplay(void *disp) } else { Error("OpenDisplay", "cannot get GC values"); } - - // Turn-off GraphicsExpose and NoExpose event reporting for the pixmap - // manipulation GC, this to prevent these events from being stacked up - // without ever being processed and thereby wasting a lot of memory. - XSetGraphicsExposures((Display*)fDisplay, *gGCpxmp, False); +*/ // Create input echo graphic context XGCValues echov; @@ -1264,6 +1406,60 @@ Int_t TGX11::OpenDisplay(void *disp) return 0; } + +//////////////////////////////////////////////////////////////////////////////// +/// Add new window handle +/// Only for private usage + +Int_t TGX11::AddWindowHandle() +{ + Int_t maxid = 0; + for (auto & pair : fWindows) { + if (!pair.second->fOpen) { + pair.second->fOpen = 1; + return pair.first; + } + if (pair.first > maxid) + maxid = pair.first; + } + + if (fWindows.size() == (size_t) maxid) { + // all ids are in use - just add maximal+1 + maxid++; + } else + for (int id = 1; id < maxid; id++) { + if (fWindows.count(id) == 0) { + maxid = id; + break; + } + } + + fWindows.emplace(maxid, std::make_unique()); + + auto ctxt = fWindows[maxid].get(); + ctxt->fOpen = 1; + ctxt->fDrawMode = TVirtualX::kCopy; + for (int n = 0; n < kMAXGC; ++n) + ctxt->fGClist[n] = XCreateGC((Display*)fDisplay, fVisRootWin, 0, nullptr); + + XGCValues values; + if (XGetGCValues((Display*)fDisplay, ctxt->fGClist[kGCtext], GCForeground|GCBackground, &values)) { + XSetForeground((Display*)fDisplay, ctxt->fGClist[kGCinvt], values.background); + XSetBackground((Display*)fDisplay, ctxt->fGClist[kGCinvt], values.foreground); + } else { + Error("AddWindowHandle", "cannot get GC values"); + } + + // Turn-off GraphicsExpose and NoExpose event reporting for the pixmap + // manipulation GC, this to prevent these events from being stacked up + // without ever being processed and thereby wasting a lot of memory. + XSetGraphicsExposures((Display*)fDisplay, ctxt->fGClist[kGCpxmp], False); + + return maxid; +} + + + //////////////////////////////////////////////////////////////////////////////// /// Open a new pixmap. /// @@ -1273,40 +1469,26 @@ Int_t TGX11::OpenPixmap(unsigned int w, unsigned int h) { Window root; unsigned int wval, hval; - int xx, yy, i, wid; + int xx, yy; unsigned int ww, hh, border, depth; wval = w; hval = h; // Select next free window number - -again: - for (wid = 0; wid < fMaxNumberOfWindows; wid++) - if (!fWindows[wid].fOpen) { - fWindows[wid].fOpen = 1; - gCws = &fWindows[wid]; - break; - } - - if (wid == fMaxNumberOfWindows) { - int newsize = fMaxNumberOfWindows + 10; - fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t), - fMaxNumberOfWindows*sizeof(XWindow_t)); - for (i = fMaxNumberOfWindows; i < newsize; i++) - fWindows[i].fOpen = 0; - fMaxNumberOfWindows = newsize; - goto again; - } + int wid = AddWindowHandle(); + gCws = fWindows[wid].get(); gCws->fWindow = XCreatePixmap((Display*)fDisplay, fRootWin, wval, hval, fDepth); XGetGeometry((Display*)fDisplay, gCws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth); - for (i = 0; i < kMAXGC; i++) - XSetClipMask((Display*)fDisplay, gGClist[i], None); + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gCws->fGClist[i], None); + } - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, gCws->fWindow, *gGCpxmp, 0, 0, ww, hh); - SetColor(gGCpxmp, 1); + SetColor(&gCws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gCws->fWindow, gCws->fGClist[kGCpxmp], 0, 0, ww, hh); + SetColor(&gCws->fGClist[kGCpxmp], 1); // Initialise the window structure gCws->fDrawing = gCws->fWindow; @@ -1331,7 +1513,6 @@ Int_t TGX11::InitWindow(ULong_t win) { XSetWindowAttributes attributes; ULong_t attr_mask = 0; - int wid; int xval, yval; unsigned int wval, hval, border, depth; Window root; @@ -1342,24 +1523,9 @@ Int_t TGX11::InitWindow(ULong_t win) // Select next free window number -again: - for (wid = 0; wid < fMaxNumberOfWindows; wid++) - if (!fWindows[wid].fOpen) { - fWindows[wid].fOpen = 1; - fWindows[wid].fDoubleBuffer = 0; - gCws = &fWindows[wid]; - break; - } - - if (wid == fMaxNumberOfWindows) { - int newsize = fMaxNumberOfWindows + 10; - fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t), - fMaxNumberOfWindows*sizeof(XWindow_t)); - for (int i = fMaxNumberOfWindows; i < newsize; i++) - fWindows[i].fOpen = 0; - fMaxNumberOfWindows = newsize; - goto again; - } + int wid = AddWindowHandle(); + gCws = fWindows[wid].get(); + gCws->fDoubleBuffer = 0; // Create window @@ -1406,28 +1572,10 @@ Int_t TGX11::InitWindow(ULong_t win) Int_t TGX11::AddWindow(ULong_t qwid, UInt_t w, UInt_t h) { - Int_t wid; - // Select next free window number - -again: - for (wid = 0; wid < fMaxNumberOfWindows; wid++) - if (!fWindows[wid].fOpen) { - fWindows[wid].fOpen = 1; - fWindows[wid].fDoubleBuffer = 0; - gCws = &fWindows[wid]; - break; - } - - if (wid == fMaxNumberOfWindows) { - int newsize = fMaxNumberOfWindows + 10; - fWindows = (XWindow_t*) TStorage::ReAlloc(fWindows, newsize*sizeof(XWindow_t), - fMaxNumberOfWindows*sizeof(XWindow_t)); - for (int i = fMaxNumberOfWindows; i < newsize; i++) - fWindows[i].fOpen = 0; - fMaxNumberOfWindows = newsize; - goto again; - } + int wid = AddWindowHandle(); + gCws = fWindows[wid].get(); + gCws->fDoubleBuffer = 0; gCws->fWindow = qwid; @@ -1446,31 +1594,13 @@ Int_t TGX11::AddWindow(ULong_t qwid, UInt_t w, UInt_t h) } //////////////////////////////////////////////////////////////////////////////// -/// Remove a window created by Qt (like CloseWindow1()). +/// Remove a window created by Qt (like CloseWindow()). void TGX11::RemoveWindow(ULong_t qwid) { - SelectWindow((int)qwid); - - if (gCws->fBuffer) XFreePixmap((Display*)fDisplay, gCws->fBuffer); - - if (gCws->fNewColors) { - if (fRedDiv == -1) - XFreeColors((Display*)fDisplay, fColormap, gCws->fNewColors, gCws->fNcolors, 0); - delete [] gCws->fNewColors; - gCws->fNewColors = nullptr; - } - - gCws->fOpen = 0; - - // make first window in list the current window - for (Int_t wid = 0; wid < fMaxNumberOfWindows; wid++) - if (fWindows[wid].fOpen) { - gCws = &fWindows[wid]; - return; - } + SelectWindow((int) qwid); - gCws = nullptr; + CloseWindow(); } //////////////////////////////////////////////////////////////////////////////// @@ -1495,13 +1625,6 @@ void TGX11::QueryPointer(Int_t &ix, Int_t &iy) iy = root_y_return; } -//////////////////////////////////////////////////////////////////////////////// -/// Remove the pixmap pix. - -void TGX11::RemovePixmap(Drawable *pix) -{ - XFreePixmap((Display*)fDisplay,*pix); -} //////////////////////////////////////////////////////////////////////////////// /// Request Locator position. @@ -1740,11 +1863,11 @@ Int_t TGX11::RequestString(int x, int y, char *text) char nbytes; int dx; int i; - XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCtext, x, y, text, nt); - dx = XTextWidth(gTextFont, text, nt); - XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCtext, x + dx, y, " ", 1); - dx = pt == 0 ? 0 : XTextWidth(gTextFont, text, pt); - XDrawImageString((Display*)fDisplay, gCws->fWindow, *gGCinvt, + XDrawImageString((Display*)fDisplay, gCws->fWindow, gCws->fGClist[kGCtext], x, y, text, nt); + dx = XTextWidth(gCws->textFont, text, nt); + XDrawImageString((Display*)fDisplay, gCws->fWindow, gCws->fGClist[kGCtext], x + dx, y, " ", 1); + dx = pt == 0 ? 0 : XTextWidth(gCws->textFont, text, pt); + XDrawImageString((Display*)fDisplay, gCws->fWindow, gCws->fGClist[kGCinvt], x + dx, y, pt < len_text ? &text[pt] : " ", 1); XWindowEvent((Display*)fDisplay, gCws->fWindow, gKeybdMask, &event); switch (event.type) { @@ -1869,9 +1992,7 @@ Int_t TGX11::RequestString(int x, int y, char *text) void TGX11::RescaleWindow(int wid, unsigned int w, unsigned int h) { - int i; - - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); if (!gTws->fOpen) return; // don't do anything when size did not change @@ -1885,11 +2006,15 @@ void TGX11::RescaleWindow(int wid, unsigned int w, unsigned int h) XFreePixmap((Display*)fDisplay,gTws->fBuffer); gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin, w, h, fDepth); } - for (i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None); - SetColor(gGCpxmp, 0); - XFillRectangle( (Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, w, h); - SetColor(gGCpxmp, 1); - if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer; + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gTws->fGClist[i], None); + } + SetColor(&gTws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gTws->fBuffer, gTws->fGClist[kGCpxmp], 0, 0, w, h); + SetColor(&gTws->fGClist[kGCpxmp], 1); + if (gTws->fDoubleBuffer) + gTws->fDrawing = gTws->fBuffer; } gTws->fWidth = w; gTws->fHeight = h; @@ -1910,7 +2035,7 @@ int TGX11::ResizePixmap(int wid, unsigned int w, unsigned int h) wval = w; hval = h; - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); // don't do anything when size did not change // if (gTws->fWidth == wval && gTws->fHeight == hval) return 0; @@ -1927,12 +2052,14 @@ int TGX11::ResizePixmap(int wid, unsigned int w, unsigned int h) } XGetGeometry((Display*)fDisplay, gTws->fWindow, &root, &xx, &yy, &ww, &hh, &border, &depth); - for (i = 0; i < kMAXGC; i++) - XSetClipMask((Display*)fDisplay, gGClist[i], None); + for (i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gTws->fGClist[i], None); + } - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, gTws->fWindow, *gGCpxmp, 0, 0, ww, hh); - SetColor(gGCpxmp, 1); + SetColor(&gTws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gTws->fWindow, gTws->fGClist[kGCpxmp], 0, 0, ww, hh); + SetColor(&gTws->fGClist[kGCpxmp], 1); // Initialise the window structure gTws->fDrawing = gTws->fWindow; @@ -1947,12 +2074,11 @@ int TGX11::ResizePixmap(int wid, unsigned int w, unsigned int h) void TGX11::ResizeWindow(Int_t wid) { - int i; int xval=0, yval=0; Window win, root=0; unsigned int wval=0, hval=0, border=0, depth=0; - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); win = gTws->fWindow; @@ -1971,11 +2097,15 @@ void TGX11::ResizeWindow(Int_t wid) XFreePixmap((Display*)fDisplay,gTws->fBuffer); gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin, wval, hval, fDepth); } - for (i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None); - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, wval, hval); - SetColor(gGCpxmp, 1); - if (gTws->fDoubleBuffer) gTws->fDrawing = gTws->fBuffer; + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gTws->fGClist[i], None); + } + SetColor(&gTws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gTws->fBuffer, gTws->fGClist[kGCpxmp], 0, 0, wval, hval); + SetColor(&gTws->fGClist[kGCpxmp], 1); + if (gTws->fDoubleBuffer) + gTws->fDrawing = gTws->fBuffer; } gTws->fWidth = wval; gTws->fHeight = hval; @@ -1986,23 +2116,29 @@ void TGX11::ResizeWindow(Int_t wid) void TGX11::SelectWindow(int wid) { - XRectangle region; - int i; + if (fWindows.count(wid) == 0) + return; - if (wid < 0 || wid >= fMaxNumberOfWindows || !fWindows[wid].fOpen) return; + if (!fWindows[wid]->fOpen) + return; - gCws = &fWindows[wid]; + gCws = fWindows[wid].get(); if (gCws->fClip && !gCws->fIsPixmap && !gCws->fDoubleBuffer) { + XRectangle region; region.x = gCws->fXclip; region.y = gCws->fYclip; region.width = gCws->fWclip; region.height = gCws->fHclip; - for (i = 0; i < kMAXGC; i++) - XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded); + for (int i = 0; i < kMAXGC; i++) { + // XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded); + XSetClipRectangles((Display*)fDisplay, gCws->fGClist[i], 0, 0, ®ion, 1, YXBanded); + } } else { - for (i = 0; i < kMAXGC; i++) - XSetClipMask((Display*)fDisplay, gGClist[i], None); + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gCws->fGClist[i], None); + } } } @@ -2032,11 +2168,13 @@ void TGX11::SetCharacterUp(Float_t chupx, Float_t chupy) void TGX11::SetClipOFF(int wid) { - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); gTws->fClip = 0; - for (int i = 0; i < kMAXGC; i++) - XSetClipMask( (Display*)fDisplay, gGClist[i], None ); + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask( (Display*)fDisplay, gGClist[i], None ); + XSetClipMask( (Display*)fDisplay, gTws->fGClist[i], None ); + } } //////////////////////////////////////////////////////////////////////////////// @@ -2048,8 +2186,7 @@ void TGX11::SetClipOFF(int wid) void TGX11::SetClipRegion(int wid, int x, int y, unsigned int w, unsigned int h) { - - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); gTws->fXclip = x; gTws->fYclip = y; gTws->fWclip = w; @@ -2061,8 +2198,10 @@ void TGX11::SetClipRegion(int wid, int x, int y, unsigned int w, unsigned int h) region.y = gTws->fYclip; region.width = gTws->fWclip; region.height = gTws->fHclip; - for (int i = 0; i < kMAXGC; i++) - XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded); + for (int i = 0; i < kMAXGC; i++) { + // XSetClipRectangles((Display*)fDisplay, gGClist[i], 0, 0, ®ion, 1, YXBanded); + XSetClipRectangles((Display*)fDisplay, gTws->fGClist[i], 0, 0, ®ion, 1, YXBanded); + } } } @@ -2104,7 +2243,7 @@ void TGX11::SetColor(void *gci, int ci) void TGX11::SetCursor(Int_t wid, ECursor cursor) { - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); XDefineCursor((Display*)fDisplay, gTws->fWindow, fCursors[cursor]); } @@ -2120,8 +2259,8 @@ void TGX11::SetCursor(Int_t wid, ECursor cursor) void TGX11::SetDoubleBuffer(int wid, int mode) { if (wid == 999) { - for (int i = 0; i < fMaxNumberOfWindows; i++) { - gTws = &fWindows[i]; + for (auto & pair : fWindows) { + gTws = pair.second.get(); if (gTws->fOpen) { switch (mode) { case 1 : @@ -2134,8 +2273,9 @@ void TGX11::SetDoubleBuffer(int wid, int mode) } } } else { - gTws = &fWindows[wid]; - if (!gTws->fOpen) return; + gTws = fWindows[wid].get(); + if (!gTws->fOpen) + return; switch (mode) { case 1 : SetDoubleBufferON(); @@ -2162,15 +2302,19 @@ void TGX11::SetDoubleBufferOFF() void TGX11::SetDoubleBufferON() { - if (gTws->fDoubleBuffer || gTws->fIsPixmap) return; + if (gTws->fDoubleBuffer || gTws->fIsPixmap) + return; if (!gTws->fBuffer) { gTws->fBuffer = XCreatePixmap((Display*)fDisplay, fRootWin, gTws->fWidth, gTws->fHeight, fDepth); - SetColor(gGCpxmp, 0); - XFillRectangle((Display*)fDisplay, gTws->fBuffer, *gGCpxmp, 0, 0, gTws->fWidth, gTws->fHeight); - SetColor(gGCpxmp, 1); + SetColor(&gTws->fGClist[kGCpxmp], 0); + XFillRectangle((Display*)fDisplay, gTws->fBuffer, gTws->fGClist[kGCpxmp], 0, 0, gTws->fWidth, gTws->fHeight); + SetColor(&gTws->fGClist[kGCpxmp], 1); + } + for (int i = 0; i < kMAXGC; i++) { + // XSetClipMask((Display*)fDisplay, gGClist[i], None); + XSetClipMask((Display*)fDisplay, gTws->fGClist[i], None); } - for (int i = 0; i < kMAXGC; i++) XSetClipMask((Display*)fDisplay, gGClist[i], None); gTws->fDoubleBuffer = 1; gTws->fDrawing = gTws->fBuffer; } @@ -2187,19 +2331,28 @@ void TGX11::SetDoubleBufferON() void TGX11::SetDrawMode(EDrawMode mode) { - int i; - if (fDisplay) { + if (fDisplay && gCws) { + switch (mode) { case kCopy: - for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXcopy); + for (int i = 0; i < kMAXGC; i++) { + // XSetFunction((Display*)fDisplay, gGClist[i], GXcopy); + XSetFunction((Display*)fDisplay, gCws->fGClist[i], GXcopy); + } break; case kXor: - for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXxor); + for (int i = 0; i < kMAXGC; i++) { + // XSetFunction((Display*)fDisplay, gGClist[i], GXxor); + XSetFunction((Display*)fDisplay, gCws->fGClist[i], GXxor); + } break; case kInvert: - for (i = 0; i < kMAXGC; i++) XSetFunction((Display*)fDisplay, gGClist[i], GXinvert); + for (int i = 0; i < kMAXGC; i++) { + // XSetFunction((Display*)fDisplay, gGClist[i], GXinvert); + XSetFunction((Display*)fDisplay, gCws->fGClist[i], GXinvert); + } break; } } @@ -2211,6 +2364,14 @@ void TGX11::SetDrawMode(EDrawMode mode) void TGX11::SetFillColor(Color_t cindex) { + TAttFill::SetFillColor(cindex); + + TAttFill arg(gCws->fAttFill); + arg.SetFillColor(cindex); + + SetAttFill((WinContext_t) gCws, arg); + +/* if (!gStyle->GetFillColor() && cindex > 1) cindex = 0; if (cindex >= 0) SetColor(gGCfill, Int_t(cindex)); fFillColor = cindex; @@ -2220,6 +2381,7 @@ void TGX11::SetFillColor(Color_t cindex) XFreePixmap((Display*)fDisplay, gFillPattern); gFillPattern = 0; } + */ } //////////////////////////////////////////////////////////////////////////////// @@ -2230,18 +2392,36 @@ void TGX11::SetFillColor(Color_t cindex) void TGX11::SetFillStyle(Style_t fstyle) { - if (fFillStyle == fstyle) return; + TAttFill::SetFillStyle(fstyle); + + TAttFill arg(gCws->fAttFill); + arg.SetFillStyle(fstyle); + + SetAttFill((WinContext_t) gCws, arg); + +/* if (fFillStyle == fstyle) return; fFillStyle = fstyle; Int_t style = fstyle/1000; Int_t fasi = fstyle%1000; SetFillStyleIndex(style,fasi); + */ +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return current fill style +/// FIXME: Only as temporary solution while some code analyze current fill style + +Style_t TGX11::GetFillStyle() const +{ + return gCws ? gCws->fAttFill.GetFillStyle() : TAttFill::GetFillStyle(); } //////////////////////////////////////////////////////////////////////////////// /// Set fill area style index. -void TGX11::SetFillStyleIndex(Int_t style, Int_t fasi) +void TGX11::SetFillStyleIndex(Int_t /* style */, Int_t /* fasi */) { +/* static int current_fasi = 0; fFillStyle = 1000*style + fasi; @@ -2278,6 +2458,7 @@ void TGX11::SetFillStyleIndex(Int_t style, Int_t fasi) default: gFillHollow = 1; } +*/ } //////////////////////////////////////////////////////////////////////////////// @@ -2308,8 +2489,13 @@ void TGX11::SetLineColor(Color_t cindex) TAttLine::SetLineColor(cindex); - SetColor(gGCline, Int_t(cindex)); - SetColor(gGCdash, Int_t(cindex)); + TAttLine arg(gCws->fAttLine); + arg.SetLineColor(cindex); + + SetAttLine((WinContext_t) gCws, arg); + + //SetColor(gGCline, Int_t(cindex)); + //SetColor(gGCdash, Int_t(cindex)); } //////////////////////////////////////////////////////////////////////////////// @@ -2323,8 +2509,9 @@ void TGX11::SetLineColor(Color_t cindex) /// e.g. N=4,DASH=(6,3,1,3) gives a dashed-dotted line with dash length 6 /// and a gap of 7 between dashes -void TGX11::SetLineType(int n, int *dash) +void TGX11::SetLineType(int /* n */, int * /* dash */) { + /* if (n <= 0) { gLineStyle = LineSolid; XSetLineAttributes((Display*)fDisplay, *gGCline, gLineWidth, @@ -2344,6 +2531,7 @@ void TGX11::SetLineType(int n, int *dash) XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth, gLineStyle, gCapStyle, gJoinStyle); } + */ } //////////////////////////////////////////////////////////////////////////////// @@ -2351,6 +2539,14 @@ void TGX11::SetLineType(int n, int *dash) void TGX11::SetLineStyle(Style_t lstyle) { + TAttLine::SetLineStyle(lstyle); + + TAttLine arg(gCws->fAttLine); + arg.SetLineStyle(lstyle); + + SetAttLine((WinContext_t) gCws, arg); +/* + static Int_t dashed[2] = {3,3}; static Int_t dotted[2] = {1,2}; static Int_t dasheddotted[4] = {3,4,1,4}; @@ -2381,6 +2577,16 @@ void TGX11::SetLineStyle(Style_t lstyle) delete tokens; } } +*/ +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return current line style +/// FIXME: Only as temporary solution while some code analyze current line style + +Style_t TGX11::GetLineStyle() const +{ + return gCws ? gCws->fAttLine.GetLineStyle() : TAttLine::GetLineStyle(); } //////////////////////////////////////////////////////////////////////////////// @@ -2388,8 +2594,17 @@ void TGX11::SetLineStyle(Style_t lstyle) /// /// \param [in] width : line width in pixels -void TGX11::SetLineWidth(Width_t width ) +void TGX11::SetLineWidth(Width_t width) { + TAttLine::SetLineWidth(width); + + TAttLine arg(gCws->fAttLine); + arg.SetLineWidth(width); + + SetAttLine((WinContext_t) gCws, arg); + +/* + if (fLineWidth == width) return; fLineWidth = width; @@ -2402,6 +2617,16 @@ void TGX11::SetLineWidth(Width_t width ) gLineStyle, gCapStyle, gJoinStyle); XSetLineAttributes((Display*)fDisplay, *gGCdash, gLineWidth, gLineStyle, gCapStyle, gJoinStyle); +*/ +} + +//////////////////////////////////////////////////////////////////////////////// +/// Return current line width +/// FIXME: Only as temporary solution while some code analyze current line wide + +Width_t TGX11::GetLineWidth() const +{ + return gCws ? gCws->fAttLine.GetLineWidth() : TAttLine::GetLineWidth(); } //////////////////////////////////////////////////////////////////////////////// @@ -2413,7 +2638,10 @@ void TGX11::SetMarkerColor(Color_t cindex) TAttMarker::SetMarkerColor(cindex); - SetColor(gGCmark, Int_t(cindex)); + TAttMarker arg(gCws->fAttMarker); + arg.SetMarkerColor(cindex); + + SetAttMarker((WinContext_t) gCws, arg); } //////////////////////////////////////////////////////////////////////////////// @@ -2423,12 +2651,12 @@ void TGX11::SetMarkerColor(Color_t cindex) void TGX11::SetMarkerSize(Float_t msize) { - if (msize == fMarkerSize) return; + TAttMarker::SetMarkerSize(msize); - fMarkerSize = msize; - if (msize < 0) return; + TAttMarker arg(gCws->fAttMarker); + arg.SetMarkerSize(msize); - SetMarkerStyle(-fMarkerStyle); + SetAttMarker((WinContext_t) gCws, arg); } //////////////////////////////////////////////////////////////////////////////// @@ -2446,8 +2674,9 @@ void TGX11::SetMarkerSize(Float_t msize) /// - if TYPE == 4 marker is described by segmented line XY /// e.g. TYPE=4,N=4,XY=(-3,0,3,0,0,-3,0,3) sets a plus shape of 7x7 pixels -void TGX11::SetMarkerType(int type, int n, RXPoint *xy) +void TGX11::SetMarkerType(int /* type */, int /* n */, RXPoint * /* xy */) { + /* gMarker.type = type; gMarker.n = n < kMAXMK ? n : kMAXMK; if (gMarker.type >= 2) { @@ -2456,6 +2685,7 @@ void TGX11::SetMarkerType(int type, int n, RXPoint *xy) gMarker.xy[i].y = xy[i].y; } } + */ } //////////////////////////////////////////////////////////////////////////////// @@ -2463,6 +2693,14 @@ void TGX11::SetMarkerType(int type, int n, RXPoint *xy) void TGX11::SetMarkerStyle(Style_t markerstyle) { + TAttMarker::SetMarkerStyle(markerstyle); + + TAttMarker arg(gCws->fAttMarker); + arg.SetMarkerStyle(markerstyle); + + SetAttMarker((WinContext_t) gCws, arg); +/* + if (fMarkerStyle == markerstyle) return; static RXPoint shape[30]; fMarkerStyle = TMath::Abs(markerstyle); @@ -2485,7 +2723,6 @@ void TGX11::SetMarkerStyle(Style_t markerstyle) shape[1].x = im; shape[1].y = 0; shape[2].x = 0 ; shape[2].y = -im; shape[3].x = 0 ; shape[3].y = im; - SetMarkerType(4,4,shape); } else if (markerstyle == 3 || markerstyle == 31) { // * shaped marker shape[0].x = -im; shape[0].y = 0; @@ -2497,7 +2734,6 @@ void TGX11::SetMarkerStyle(Style_t markerstyle) shape[5].x = im; shape[5].y = im; shape[6].x = -im; shape[6].y = im; shape[7].x = im; shape[7].y = -im; - SetMarkerType(4,8,shape); } else if (markerstyle == 4 || markerstyle == 24) { // O shaped marker SetMarkerType(0,im*2,shape); @@ -2901,6 +3137,7 @@ void TGX11::SetMarkerStyle(Style_t markerstyle) // single dot SetMarkerType(0,0,shape); } +*/ } //////////////////////////////////////////////////////////////////////////////// @@ -2958,7 +3195,7 @@ void TGX11::SetOpacity(Int_t percent) } // put image back in pixmap on server - XPutImage((Display*)fDisplay, gCws->fDrawing, *gGCpxmp, image, 0, 0, 0, 0, + XPutImage((Display*)fDisplay, gCws->fDrawing, gCws->fGClist[kGCpxmp], image, 0, 0, 0, 0, gCws->fWidth, gCws->fHeight); XFlush((Display*)fDisplay); @@ -3096,7 +3333,7 @@ void TGX11::SetRGB(int cindex, float r, float g, float b) void TGX11::SetTextAlign(Short_t talign) { - Int_t txalh = talign/10; +/* Int_t txalh = talign/10; Int_t txalv = talign%10; fTextAlignH = txalh; fTextAlignV = txalv; @@ -3144,8 +3381,17 @@ void TGX11::SetTextAlign(Short_t talign) } break; } + */ + + TAttText::SetTextAlign(talign); + + TAttText arg(gCws->fAttText); + arg.SetTextAlign(talign); + + SetAttText((WinContext_t) gCws, arg); - TAttText::SetTextAlign(fTextAlign); + // FIXME: member fTextAlign conflicts with TAttText::fTextAlign + fTextAlign = gCws->textAlign; } //////////////////////////////////////////////////////////////////////////////// @@ -3157,6 +3403,12 @@ void TGX11::SetTextColor(Color_t cindex) TAttText::SetTextColor(cindex); + TAttText arg(gCws->fAttText); + arg.SetTextColor(cindex); + + SetAttText((WinContext_t) gCws, arg); + + /* SetColor(gGCtext, Int_t(cindex)); XGCValues values; @@ -3167,6 +3419,7 @@ void TGX11::SetTextColor(Color_t cindex) Error("SetTextColor", "cannot get GC values"); } XSetBackground((Display*)fDisplay, *gGCtext, GetColor(0).fPixel); + */ } //////////////////////////////////////////////////////////////////////////////// @@ -3184,14 +3437,16 @@ Int_t TGX11::SetTextFont(char *fontname, ETextSetMode mode) { char **fontlist; int fontcount; - int i; if (mode == kLoad) { - for (i = 0; i < kMAXFONT; i++) { + for (int i = 0; i < kMAXFONT; i++) { if (strcmp(fontname, gFont[i].name) == 0) { gTextFont = gFont[i].id; - XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid); - XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid); + if (gCws) { + gCws->textFont = gTextFont; + XSetFont((Display*)fDisplay, gCws->fGClist[kGCtext], gCws->textFont->fid); + XSetFont((Display*)fDisplay, gCws->fGClist[kGCinvt], gCws->textFont->fid); + } return 0; } } @@ -3204,8 +3459,6 @@ Int_t TGX11::SetTextFont(char *fontname, ETextSetMode mode) if (gFont[gCurrentFontNumber].id) XFreeFont((Display*)fDisplay, gFont[gCurrentFontNumber].id); gTextFont = XLoadQueryFont((Display*)fDisplay, fontlist[0]); - XSetFont((Display*)fDisplay, *gGCtext, gTextFont->fid); - XSetFont((Display*)fDisplay, *gGCinvt, gTextFont->fid); gFont[gCurrentFontNumber].id = gTextFont; strlcpy(gFont[gCurrentFontNumber].name,fontname,80); gCurrentFontNumber++; @@ -3223,7 +3476,12 @@ Int_t TGX11::SetTextFont(char *fontname, ETextSetMode mode) void TGX11::SetTextFont(Font_t fontnumber) { - fTextFont = fontnumber; + TAttText::SetTextFont(fontnumber); + + TAttText arg(gCws->fAttText); + arg.SetTextFont(fontnumber); + + SetAttText((WinContext_t) gCws, arg); } //////////////////////////////////////////////////////////////////////////////// @@ -3231,7 +3489,12 @@ void TGX11::SetTextFont(Font_t fontnumber) void TGX11::SetTextSize(Float_t textsize) { - fTextSize = textsize; + TAttText::SetTextSize(textsize); + + TAttText arg(gCws->fAttText); + arg.SetTextSize(textsize); + + SetAttText((WinContext_t) gCws, arg); } //////////////////////////////////////////////////////////////////////////////// @@ -3268,7 +3531,7 @@ void TGX11::UpdateWindow(int mode) { if (gCws->fDoubleBuffer) { XCopyArea((Display*)fDisplay, gCws->fDrawing, gCws->fWindow, - *gGCpxmp, 0, 0, gCws->fWidth, gCws->fHeight, 0, 0); + gCws->fGClist[kGCpxmp], 0, 0, gCws->fWidth, gCws->fHeight, 0, 0); } if (mode == 1) { XFlush((Display*)fDisplay); @@ -3310,7 +3573,7 @@ void TGX11::WritePixmap(int wid, unsigned int w, unsigned int h, char *pxname) wval = w; hval = h; - gTws = &fWindows[wid]; + gTws = fWindows[wid].get(); XWriteBitmapFile((Display*)fDisplay, pxname, gTws->fDrawing, wval, hval, -1, -1); } @@ -3475,6 +3738,7 @@ Int_t TGX11::WriteGIF(char *name) //////////////////////////////////////////////////////////////////////////////// /// Draw image. +/// Not used, keep for backward compatibility void TGX11::PutImage(Int_t offset,Int_t itran,Int_t x0,Int_t y0,Int_t nx,Int_t ny,Int_t xmin, Int_t ymin,Int_t xmax,Int_t ymax, UChar_t *image,Drawable_t wid) @@ -3485,11 +3749,14 @@ void TGX11::PutImage(Int_t offset,Int_t itran,Int_t x0,Int_t y0,Int_t nx,Int_t n int nlines[256]; XSegment lines[256][maxSegment]; Drawable_t id; + GC lineGC; if (wid) { id = wid; + lineGC = XCreateGC((Display*)fDisplay, fVisRootWin, 0, nullptr); } else { id = gCws->fDrawing; + lineGC = gCws->fGClist[kGCline]; } for (i = 0; i < 256; i++) nlines[i] = 0; @@ -3507,8 +3774,8 @@ void TGX11::PutImage(Int_t offset,Int_t itran,Int_t x0,Int_t y0,Int_t nx,Int_t n lines[icol][n].x1 = xcur; lines[icol][n].y1 = y; lines[icol][n].x2 = x-1; lines[icol][n].y2 = y; if (nlines[icol] == maxSegment) { - SetColor(gGCline,(int)icol+offset); - XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0], + SetColor(&lineGC, (int)icol+offset); + XDrawSegments((Display*)fDisplay,id,lineGC,&lines[icol][0], maxSegment); nlines[icol] = 0; } @@ -3521,8 +3788,8 @@ void TGX11::PutImage(Int_t offset,Int_t itran,Int_t x0,Int_t y0,Int_t nx,Int_t n lines[icol][n].x1 = xcur; lines[icol][n].y1 = y; lines[icol][n].x2 = x-1; lines[icol][n].y2 = y; if (nlines[icol] == maxSegment) { - SetColor(gGCline,(int)icol+offset); - XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[icol][0], + SetColor(&lineGC, (int)icol+offset); + XDrawSegments((Display*)fDisplay,id,lineGC,&lines[icol][0], maxSegment); nlines[icol] = 0; } @@ -3531,10 +3798,13 @@ void TGX11::PutImage(Int_t offset,Int_t itran,Int_t x0,Int_t y0,Int_t nx,Int_t n for (i = 0; i < 256; i++) { if (nlines[i] != 0) { - SetColor(gGCline,i+offset); - XDrawSegments((Display*)fDisplay,id,*gGCline,&lines[i][0],nlines[i]); + SetColor(&lineGC,i+offset); + XDrawSegments((Display*)fDisplay,id,lineGC,&lines[i][0],nlines[i]); } } + + if (wid) + XFreeGC((Display*)fDisplay, lineGC); } //////////////////////////////////////////////////////////////////////////////// @@ -3673,28 +3943,9 @@ Pixmap_t TGX11::CreatePixmapFromData(unsigned char * /*bits*/, UInt_t /*width*/, Int_t TGX11::AddPixmap(ULong_t pixid, UInt_t w, UInt_t h) { - Int_t wid = 0; - - // Select next free window number - for (; wid < fMaxNumberOfWindows; ++wid) - if (!fWindows[wid].fOpen) - break; - - if (wid == fMaxNumberOfWindows) { - Int_t newsize = fMaxNumberOfWindows + 10; - fWindows = (XWindow_t*) TStorage::ReAlloc( - fWindows, newsize * sizeof(XWindow_t), - fMaxNumberOfWindows*sizeof(XWindow_t) - ); - - for (Int_t i = fMaxNumberOfWindows; i < newsize; ++i) - fWindows[i].fOpen = 0; - - fMaxNumberOfWindows = newsize; - } + Int_t wid = AddWindowHandle(); - fWindows[wid].fOpen = 1; - gCws = fWindows + wid; + gCws = fWindows[wid].get(); gCws->fWindow = pixid; gCws->fDrawing = gCws->fWindow; gCws->fBuffer = 0; @@ -3725,3 +3976,704 @@ Int_t TGX11::SupportsExtension(const char *ext) const return -1; return XQueryExtension((Display*)fDisplay, ext, &major_opcode, &first_event, &first_error); } + + +WinContext_t TGX11::GetWindowContext(Int_t wid) +{ + return (WinContext_t) fWindows[wid].get(); +} + +void TGX11::SetAttFill(WinContext_t wctxt, const TAttFill &att) +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) + return; + + Int_t cindex = att.GetFillColor(); + if (!gStyle->GetFillColor() && cindex > 1) + cindex = 0; + if (cindex >= 0) + SetColor(&ctxt->fGClist[kGCfill], Int_t(cindex)); + ctxt->fAttFill.SetFillColor(cindex); + + Int_t style = att.GetFillStyle() / 1000; + Int_t fasi = att.GetFillStyle() % 1000; + Int_t stn = (fasi >= 1 && fasi <=25) ? fasi : 2; + ctxt->fAttFill.SetFillStyle(style * 1000 + fasi); + + switch (style) { + case 1: // solid + ctxt->fillHollow = 0; + XSetFillStyle((Display*)fDisplay, ctxt->fGClist[kGCfill], FillSolid); + break; + + case 2: // pattern + ctxt->fillHollow = 1; + break; + + case 3: // hatch + ctxt->fillHollow = 0; + XSetFillStyle((Display*)fDisplay, ctxt->fGClist[kGCfill], FillStippled); + + if (stn != ctxt->fillFasi) { + if (ctxt->fillPattern != 0) + XFreePixmap((Display*)fDisplay, ctxt->fillPattern); + + ctxt->fillPattern = XCreateBitmapFromData((Display*)fDisplay, fRootWin, + (const char*)gStipples[stn], 16, 16); + + XSetStipple((Display*)fDisplay, ctxt->fGClist[kGCfill], ctxt->fillPattern); + ctxt->fillFasi = stn; + } + break; + + default: + ctxt->fillHollow = 1; + } +} + +void TGX11::SetAttLine(WinContext_t wctxt, const TAttLine &att) +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) + return; + + if (ctxt->fAttLine.GetLineStyle() != att.GetLineStyle()) { //set style index only if different + if (att.GetLineStyle() <= 1) + ctxt->dashList.clear(); + else if (att.GetLineStyle() == 2) + ctxt->dashList = { 3, 3 }; + else if (att.GetLineStyle() == 3) + ctxt->dashList = { 1, 2 }; + else if (att.GetLineStyle() == 4) { + ctxt->dashList = { 3, 4, 1, 4} ; + } else { + TString st = (TString)gStyle->GetLineStyleString(att.GetLineStyle()); + auto tokens = st.Tokenize(" "); + Int_t nt = tokens->GetEntries(); + ctxt->dashList.resize(nt); + for (Int_t j = 0; j < nt; ++j) { + Int_t it; + sscanf(tokens->At(j)->GetName(), "%d", &it); + ctxt->dashList[j] = (Int_t) (it/4); + } + delete tokens; + } + ctxt->dashLength = 0; + for (auto elem : ctxt->dashList) + ctxt->dashLength += elem; + ctxt->dashOffset = 0; + ctxt->lineStyle = ctxt->dashList.size() == 0 ? LineSolid : LineOnOffDash; + } + + if (ctxt->fAttLine.GetLineWidth() != att.GetLineWidth()) { + ctxt->lineWidth = att.GetLineWidth(); + if (ctxt->lineStyle == LineSolid) { + if (ctxt->lineWidth == 1) + ctxt->lineWidth = 0; + } else { + if (ctxt->lineWidth == 0) + ctxt->lineWidth = 1; + } + } + + if (ctxt->lineWidth >= 0) { + XSetLineAttributes((Display*)fDisplay, ctxt->fGClist[kGCline], ctxt->lineWidth, + ctxt->lineStyle, gCapStyle, gJoinStyle); + if (ctxt->lineStyle == LineOnOffDash) + XSetLineAttributes((Display*)fDisplay, ctxt->fGClist[kGCdash], ctxt->lineWidth, + ctxt->lineStyle, gCapStyle, gJoinStyle); + } + + if (att.GetLineColor() >= 0) { + SetColor(&ctxt->fGClist[kGCline], (Int_t) att.GetLineColor()); + SetColor(&ctxt->fGClist[kGCdash], (Int_t) att.GetLineColor()); + } + + ctxt->fAttLine = att; +} + +void TGX11::SetAttMarker(WinContext_t wctxt, const TAttMarker &att) +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) + return; + + SetColor(&ctxt->fGClist[kGCmark], att.GetMarkerColor()); + + Bool_t changed = (att.GetMarkerSize() != ctxt->fAttMarker.GetMarkerSize()) || + (att.GetMarkerStyle() != ctxt->fAttMarker.GetMarkerStyle()); + + ctxt->fAttMarker = att; + + if (!changed) + return; + + Int_t markerstyle = TAttMarker::GetMarkerStyleBase(att.GetMarkerStyle()); + ctxt->markerLineWidth = TAttMarker::GetMarkerLineWidth(att.GetMarkerStyle()); + + // The fast pixel markers need to be treated separately + if (markerstyle == 1 || markerstyle == 6 || markerstyle == 7) { + XSetLineAttributes((Display*)fDisplay, ctxt->fGClist[kGCmark], 0, LineSolid, CapButt, JoinMiter); + } else { + XSetLineAttributes((Display*)fDisplay, ctxt->fGClist[kGCmark], ctxt->markerLineWidth, + gMarkerLineStyle, gMarkerCapStyle, gMarkerJoinStyle); + } + + Float_t MarkerSizeReduced = att.GetMarkerSize() - TMath::Floor(ctxt->markerLineWidth/2.)/4.; + Int_t im = Int_t(4*MarkerSizeReduced + 0.5); + auto &shape = ctxt->markerShape; + ctxt->markerSize = 0; + ctxt->markerType = 0; + if (markerstyle == 2) { + // + shaped marker + shape.resize(4); + shape[0].x = -im; shape[0].y = 0; + shape[1].x = im; shape[1].y = 0; + shape[2].x = 0 ; shape[2].y = -im; + shape[3].x = 0 ; shape[3].y = im; + ctxt->markerType = 4; + } else if (markerstyle == 3 || markerstyle == 31) { + // * shaped marker + shape.resize(8); + shape[0].x = -im; shape[0].y = 0; + shape[1].x = im; shape[1].y = 0; + shape[2].x = 0 ; shape[2].y = -im; + shape[3].x = 0 ; shape[3].y = im; + im = Int_t(0.707*Float_t(im) + 0.5); + shape[4].x = -im; shape[4].y = -im; + shape[5].x = im; shape[5].y = im; + shape[6].x = -im; shape[6].y = im; + shape[7].x = im; shape[7].y = -im; + ctxt->markerType = 4; + } else if (markerstyle == 4 || markerstyle == 24) { + // O shaped marker + ctxt->markerType = 0; + ctxt->markerSize = im*2; + } else if (markerstyle == 5) { + // X shaped marker + shape.resize(4); + im = Int_t(0.707*Float_t(im) + 0.5); + shape[0].x = -im; shape[0].y = -im; + shape[1].x = im; shape[1].y = im; + shape[2].x = -im; shape[2].y = im; + shape[3].x = im; shape[3].y = -im; + ctxt->markerType = 4; + } else if (markerstyle == 6) { + // + shaped marker (with 1 pixel) + shape.resize(4); + shape[0].x = -1 ; shape[0].y = 0; + shape[1].x = 1 ; shape[1].y = 0; + shape[2].x = 0 ; shape[2].y = -1; + shape[3].x = 0 ; shape[3].y = 1; + ctxt->markerType = 4; + } else if (markerstyle == 7) { + // . shaped marker (with 9 pixel) + shape.resize(6); + shape[0].x = -1 ; shape[0].y = 1; + shape[1].x = 1 ; shape[1].y = 1; + shape[2].x = -1 ; shape[2].y = 0; + shape[3].x = 1 ; shape[3].y = 0; + shape[4].x = -1 ; shape[4].y = -1; + shape[5].x = 1 ; shape[5].y = -1; + ctxt->markerType = 4; + } else if (markerstyle == 8 || markerstyle == 20) { + // O shaped marker (filled) + ctxt->markerType = 1; + ctxt->markerSize = im*2; + } else if (markerstyle == 21) { + // full square + shape.resize(5); + shape[0].x = -im; shape[0].y = -im; + shape[1].x = im; shape[1].y = -im; + shape[2].x = im; shape[2].y = im; + shape[3].x = -im; shape[3].y = im; + shape[4].x = -im; shape[4].y = -im; + ctxt->markerType = 3; + } else if (markerstyle == 22) { + // full triangle up + shape.resize(4); + shape[0].x = -im; shape[0].y = im; + shape[1].x = im; shape[1].y = im; + shape[2].x = 0; shape[2].y = -im; + shape[3].x = -im; shape[3].y = im; + ctxt->markerType = 3; + } else if (markerstyle == 23) { + // full triangle down + shape.resize(4); + shape[0].x = 0; shape[0].y = im; + shape[1].x = im; shape[1].y = -im; + shape[2].x = -im; shape[2].y = -im; + shape[3].x = 0; shape[3].y = im; + ctxt->markerType = 3; + } else if (markerstyle == 25) { + // open square + shape.resize(5); + shape[0].x = -im; shape[0].y = -im; + shape[1].x = im; shape[1].y = -im; + shape[2].x = im; shape[2].y = im; + shape[3].x = -im; shape[3].y = im; + shape[4].x = -im; shape[4].y = -im; + ctxt->markerType = 2; + } else if (markerstyle == 26) { + // open triangle up + shape.resize(4); + shape[0].x = -im; shape[0].y = im; + shape[1].x = im; shape[1].y = im; + shape[2].x = 0; shape[2].y = -im; + shape[3].x = -im; shape[3].y = im; + ctxt->markerType = 2; + } else if (markerstyle == 27) { + // open losange + shape.resize(5); + Int_t imx = Int_t(2.66*MarkerSizeReduced + 0.5); + shape[0].x =-imx; shape[0].y = 0; + shape[1].x = 0; shape[1].y = -im; + shape[2].x = imx; shape[2].y = 0; + shape[3].x = 0; shape[3].y = im; + shape[4].x =-imx; shape[4].y = 0; + ctxt->markerType = 2; + } else if (markerstyle == 28) { + // open cross + shape.resize(13); + Int_t imx = Int_t(1.33*MarkerSizeReduced + 0.5); + shape[0].x = -im; shape[0].y =-imx; + shape[1].x =-imx; shape[1].y =-imx; + shape[2].x =-imx; shape[2].y = -im; + shape[3].x = imx; shape[3].y = -im; + shape[4].x = imx; shape[4].y =-imx; + shape[5].x = im; shape[5].y =-imx; + shape[6].x = im; shape[6].y = imx; + shape[7].x = imx; shape[7].y = imx; + shape[8].x = imx; shape[8].y = im; + shape[9].x =-imx; shape[9].y = im; + shape[10].x=-imx; shape[10].y= imx; + shape[11].x= -im; shape[11].y= imx; + shape[12].x= -im; shape[12].y=-imx; + ctxt->markerType = 2; + } else if (markerstyle == 29) { + // full star pentagone + shape.resize(11); + Int_t im1 = Int_t(0.66*MarkerSizeReduced + 0.5); + Int_t im2 = Int_t(2.00*MarkerSizeReduced + 0.5); + Int_t im3 = Int_t(2.66*MarkerSizeReduced + 0.5); + Int_t im4 = Int_t(1.33*MarkerSizeReduced + 0.5); + shape[0].x = -im; shape[0].y = im4; + shape[1].x =-im2; shape[1].y =-im1; + shape[2].x =-im3; shape[2].y = -im; + shape[3].x = 0; shape[3].y =-im2; + shape[4].x = im3; shape[4].y = -im; + shape[5].x = im2; shape[5].y =-im1; + shape[6].x = im; shape[6].y = im4; + shape[7].x = im4; shape[7].y = im4; + shape[8].x = 0; shape[8].y = im; + shape[9].x =-im4; shape[9].y = im4; + shape[10].x= -im; shape[10].y= im4; + ctxt->markerType = 3; + } else if (markerstyle == 30) { + // open star pentagone + shape.resize(11); + Int_t im1 = Int_t(0.66*MarkerSizeReduced + 0.5); + Int_t im2 = Int_t(2.00*MarkerSizeReduced + 0.5); + Int_t im3 = Int_t(2.66*MarkerSizeReduced + 0.5); + Int_t im4 = Int_t(1.33*MarkerSizeReduced + 0.5); + shape[0].x = -im; shape[0].y = im4; + shape[1].x =-im2; shape[1].y =-im1; + shape[2].x =-im3; shape[2].y = -im; + shape[3].x = 0; shape[3].y =-im2; + shape[4].x = im3; shape[4].y = -im; + shape[5].x = im2; shape[5].y =-im1; + shape[6].x = im; shape[6].y = im4; + shape[7].x = im4; shape[7].y = im4; + shape[8].x = 0; shape[8].y = im; + shape[9].x =-im4; shape[9].y = im4; + shape[10].x= -im; shape[10].y= im4; + ctxt->markerType = 2; + } else if (markerstyle == 32) { + // open triangle down + shape.resize(4); + shape[0].x = 0; shape[0].y = im; + shape[1].x = im; shape[1].y = -im; + shape[2].x = -im; shape[2].y = -im; + shape[3].x = 0; shape[3].y = im; + ctxt->markerType = 2; + } else if (markerstyle == 33) { + // full losange + shape.resize(5); + Int_t imx = Int_t(2.66*MarkerSizeReduced + 0.5); + shape[0].x =-imx; shape[0].y = 0; + shape[1].x = 0; shape[1].y = -im; + shape[2].x = imx; shape[2].y = 0; + shape[3].x = 0; shape[3].y = im; + shape[4].x =-imx; shape[4].y = 0; + ctxt->markerType = 3; + } else if (markerstyle == 34) { + // full cross + shape.resize(13); + Int_t imx = Int_t(1.33*MarkerSizeReduced + 0.5); + shape[0].x = -im; shape[0].y =-imx; + shape[1].x =-imx; shape[1].y =-imx; + shape[2].x =-imx; shape[2].y = -im; + shape[3].x = imx; shape[3].y = -im; + shape[4].x = imx; shape[4].y =-imx; + shape[5].x = im; shape[5].y =-imx; + shape[6].x = im; shape[6].y = imx; + shape[7].x = imx; shape[7].y = imx; + shape[8].x = imx; shape[8].y = im; + shape[9].x =-imx; shape[9].y = im; + shape[10].x=-imx; shape[10].y= imx; + shape[11].x= -im; shape[11].y= imx; + shape[12].x= -im; shape[12].y=-imx; + ctxt->markerType = 3; + } else if (markerstyle == 35) { + // diamond with cross + shape.resize(8); + shape[0].x =-im; shape[0].y = 0; + shape[1].x = 0; shape[1].y = -im; + shape[2].x = im; shape[2].y = 0; + shape[3].x = 0; shape[3].y = im; + shape[4].x =-im; shape[4].y = 0; + shape[5].x = im; shape[5].y = 0; + shape[6].x = 0; shape[6].y = im; + shape[7].x = 0; shape[7].y =-im; + ctxt->markerType = 2; + } else if (markerstyle == 36) { + // square with diagonal cross + shape.resize(8); + shape[0].x = -im; shape[0].y = -im; + shape[1].x = im; shape[1].y = -im; + shape[2].x = im; shape[2].y = im; + shape[3].x = -im; shape[3].y = im; + shape[4].x = -im; shape[4].y = -im; + shape[5].x = im; shape[5].y = im; + shape[6].x = -im; shape[6].y = im; + shape[7].x = im; shape[7].y = -im; + ctxt->markerType = 2; + } else if (markerstyle == 37) { + // open three triangles + shape.resize(10); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = 0; + shape[1].x =-im2; shape[1].y = im; + shape[2].x = im2; shape[2].y = im; + shape[3].x = 0; shape[3].y = 0; + shape[4].x =-im2; shape[4].y = -im; + shape[5].x = -im; shape[5].y = 0; + shape[6].x = 0; shape[6].y = 0; + shape[7].x = im; shape[7].y = 0; + shape[8].x = im2; shape[8].y = -im; + shape[9].x = 0; shape[9].y = 0; + ctxt->markerType = 2; + } else if (markerstyle == 38) { + // + shaped marker with octagon + shape.resize(15); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = -im; shape[0].y = 0; + shape[1].x = -im; shape[1].y =-im2; + shape[2].x =-im2; shape[2].y = -im; + shape[3].x = im2; shape[3].y = -im; + shape[4].x = im; shape[4].y =-im2; + shape[5].x = im; shape[5].y = im2; + shape[6].x = im2; shape[6].y = im; + shape[7].x =-im2; shape[7].y = im; + shape[8].x = -im; shape[8].y = im2; + shape[9].x = -im; shape[9].y = 0; + shape[10].x = im; shape[10].y = 0; + shape[11].x = 0; shape[11].y = 0; + shape[12].x = 0; shape[12].y = -im; + shape[13].x = 0; shape[13].y = im; + shape[14].x = 0; shape[14].y = 0; + ctxt->markerType = 2; + } else if (markerstyle == 39) { + // filled three triangles + shape.resize(9); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = 0; + shape[1].x =-im2; shape[1].y = im; + shape[2].x = im2; shape[2].y = im; + shape[3].x = 0; shape[3].y = 0; + shape[4].x =-im2; shape[4].y = -im; + shape[5].x = -im; shape[5].y = 0; + shape[6].x = 0; shape[6].y = 0; + shape[7].x = im; shape[7].y = 0; + shape[8].x = im2; shape[8].y = -im; + ctxt->markerType = 3; + } else if (markerstyle == 40) { + // four open triangles X + shape.resize(13); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = 0; + shape[1].x = im2; shape[1].y = im; + shape[2].x = im; shape[2].y = im2; + shape[3].x = 0; shape[3].y = 0; + shape[4].x = im; shape[4].y = -im2; + shape[5].x = im2; shape[5].y = -im; + shape[6].x = 0; shape[6].y = 0; + shape[7].x = -im2; shape[7].y = -im; + shape[8].x = -im; shape[8].y = -im2; + shape[9].x = 0; shape[9].y = 0; + shape[10].x = -im; shape[10].y = im2; + shape[11].x = -im2; shape[11].y = im; + shape[12].x = 0; shape[12].y = 0; + ctxt->markerType = 2; + } else if (markerstyle == 41) { + // four filled triangles X + shape.resize(13); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = 0; + shape[1].x = im2; shape[1].y = im; + shape[2].x = im; shape[2].y = im2; + shape[3].x = 0; shape[3].y = 0; + shape[4].x = im; shape[4].y = -im2; + shape[5].x = im2; shape[5].y = -im; + shape[6].x = 0; shape[6].y = 0; + shape[7].x = -im2; shape[7].y = -im; + shape[8].x = -im; shape[8].y = -im2; + shape[9].x = 0; shape[9].y = 0; + shape[10].x = -im; shape[10].y = im2; + shape[11].x = -im2; shape[11].y = im; + shape[12].x = 0; shape[12].y = 0; + ctxt->markerType = 3; + } else if (markerstyle == 42) { + // open double diamonds + shape.resize(9); + Int_t imx = Int_t(MarkerSizeReduced + 0.5); + shape[0].x= 0; shape[0].y= im; + shape[1].x= -imx; shape[1].y= imx; + shape[2].x = -im; shape[2].y = 0; + shape[3].x = -imx; shape[3].y = -imx; + shape[4].x = 0; shape[4].y = -im; + shape[5].x = imx; shape[5].y = -imx; + shape[6].x = im; shape[6].y = 0; + shape[7].x= imx; shape[7].y= imx; + shape[8].x= 0; shape[8].y= im; + ctxt->markerType = 2; + } else if (markerstyle == 43) { + // filled double diamonds + shape.resize(9); + Int_t imx = Int_t(MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = im; + shape[1].x = -imx; shape[1].y = imx; + shape[2].x = -im; shape[2].y = 0; + shape[3].x = -imx; shape[3].y = -imx; + shape[4].x = 0; shape[4].y = -im; + shape[5].x = imx; shape[5].y = -imx; + shape[6].x = im; shape[6].y = 0; + shape[7].x = imx; shape[7].y = imx; + shape[8].x = 0; shape[8].y = im; + ctxt->markerType = 3; + } else if (markerstyle == 44) { + // open four triangles plus + shape.resize(11); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = 0; + shape[1].x = im2; shape[1].y = im; + shape[2].x = -im2; shape[2].y = im; + shape[3].x = im2; shape[3].y = -im; + shape[4].x = -im2; shape[4].y = -im; + shape[5].x = 0; shape[5].y = 0; + shape[6].x = im; shape[6].y = im2; + shape[7].x = im; shape[7].y = -im2; + shape[8].x = -im; shape[8].y = im2; + shape[9].x = -im; shape[9].y = -im2; + shape[10].x = 0; shape[10].y = 0; + ctxt->markerType = 2; + } else if (markerstyle == 45) { + // filled four triangles plus + shape.resize(13); + Int_t im0 = Int_t(0.4*MarkerSizeReduced + 0.5); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = im0; shape[0].y = im0; + shape[1].x = im2; shape[1].y = im; + shape[2].x = -im2; shape[2].y = im; + shape[3].x = -im0; shape[3].y = im0; + shape[4].x = -im; shape[4].y = im2; + shape[5].x = -im; shape[5].y = -im2; + shape[6].x = -im0; shape[6].y = -im0; + shape[7].x = -im2; shape[7].y = -im; + shape[8].x = im2; shape[8].y = -im; + shape[9].x = im0; shape[9].y = -im0; + shape[10].x = im; shape[10].y = -im2; + shape[11].x = im; shape[11].y = im2; + shape[12].x = im0; shape[12].y = im0; + ctxt->markerType = 3; + } else if (markerstyle == 46) { + // open four triangles X + shape.resize(13); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = im2; + shape[1].x = -im2; shape[1].y = im; + shape[2].x = -im; shape[2].y = im2; + shape[3].x = -im2; shape[3].y = 0; + shape[4].x = -im; shape[4].y = -im2; + shape[5].x = -im2; shape[5].y = -im; + shape[6].x = 0; shape[6].y = -im2; + shape[7].x = im2; shape[7].y = -im; + shape[8].x = im; shape[8].y = -im2; + shape[9].x = im2; shape[9].y = 0; + shape[10].x = im; shape[10].y = im2; + shape[11].x = im2; shape[11].y = im; + shape[12].x = 0; shape[12].y = im2; + ctxt->markerType = 2; + } else if (markerstyle == 47) { + // filled four triangles X + shape.resize(13); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = im2; + shape[1].x = -im2; shape[1].y = im; + shape[2].x = -im; shape[2].y = im2; + shape[3].x = -im2; shape[3].y = 0; + shape[4].x = -im; shape[4].y = -im2; + shape[5].x = -im2; shape[5].y = -im; + shape[6].x = 0; shape[6].y = -im2; + shape[7].x = im2; shape[7].y = -im; + shape[8].x = im; shape[8].y = -im2; + shape[9].x = im2; shape[9].y = 0; + shape[10].x = im; shape[10].y = im2; + shape[11].x = im2; shape[11].y = im; + shape[12].x = 0; shape[12].y = im2; + ctxt->markerType = 3; + } else if (markerstyle == 48) { + // four filled squares X + shape.resize(17); + Int_t im2 = Int_t(2.0*MarkerSizeReduced + 0.5); + shape[0].x = 0; shape[0].y = im2*1.005; + shape[1].x = -im2; shape[1].y = im; + shape[2].x = -im; shape[2].y = im2; + shape[3].x = -im2; shape[3].y = 0; + shape[4].x = -im; shape[4].y = -im2; + shape[5].x = -im2; shape[5].y = -im; + shape[6].x = 0; shape[6].y = -im2; + shape[7].x = im2; shape[7].y = -im; + shape[8].x = im; shape[8].y = -im2; + shape[9].x = im2; shape[9].y = 0; + shape[10].x = im; shape[10].y = im2; + shape[11].x = im2; shape[11].y = im; + shape[12].x = 0; shape[12].y = im2*0.995; + shape[13].x = im2*0.995; shape[13].y = 0; + shape[14].x = 0; shape[14].y = -im2*0.995; + shape[15].x = -im2*0.995; shape[15].y = 0; + shape[16].x = 0; shape[16].y = im2*0.995; + ctxt->markerType = 3; + } else if (markerstyle == 49) { + // four filled squares plus + shape.resize(17); + Int_t imx = Int_t(1.33*MarkerSizeReduced + 0.5); + shape[0].x =-imx; shape[0].y =-imx*1.005; + shape[1].x =-imx; shape[1].y = -im; + shape[2].x = imx; shape[2].y = -im; + shape[3].x = imx; shape[3].y =-imx; + shape[4].x = im; shape[4].y =-imx; + shape[5].x = im; shape[5].y = imx; + shape[6].x = imx; shape[6].y = imx; + shape[7].x = imx; shape[7].y = im; + shape[8].x =-imx; shape[8].y = im; + shape[9].x =-imx; shape[9].y = imx; + shape[10].x = -im; shape[10].y = imx; + shape[11].x = -im; shape[11].y =-imx; + shape[12].x =-imx; shape[12].y =-imx*0.995; + shape[13].x =-imx; shape[13].y = imx; + shape[14].x = imx; shape[14].y = imx; + shape[15].x = imx; shape[15].y =-imx; + shape[16].x =-imx; shape[16].y =-imx*1.005; + ctxt->markerType = 3; + } else { + // single dot + shape.resize(0); + ctxt->markerType = 0; + ctxt->markerSize = 0; + } +} + +void TGX11::SetAttText(WinContext_t wctxt, const TAttText &att) +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) + return; + + Int_t txalh = att.GetTextAlign() / 10; + Int_t txalv = att.GetTextAlign() % 10; + + switch (txalh) { + case 0 : + case 1 : + switch (txalv) { //left + case 1 : + ctxt->textAlign = 7; //bottom + break; + case 2 : + ctxt->textAlign = 4; //center + break; + case 3 : + ctxt->textAlign = 1; //top + break; + } + break; + case 2 : + switch (txalv) { //center + case 1 : + ctxt->textAlign = 8; //bottom + break; + case 2 : + ctxt->textAlign = 5; //center + break; + case 3 : + ctxt->textAlign = 2; //top + break; + } + break; + case 3 : + switch (txalv) { //right + case 1 : + ctxt->textAlign = 9; //bottom + break; + case 2 : + ctxt->textAlign = 6; //center + break; + case 3 : + ctxt->textAlign = 3; //top + break; + } + break; + } + + SetColor(&ctxt->fGClist[kGCtext], att.GetTextColor()); + + XGCValues values; + if (XGetGCValues((Display*)fDisplay, ctxt->fGClist[kGCtext], GCForeground | GCBackground, &values)) { + XSetForeground( (Display*)fDisplay, ctxt->fGClist[kGCinvt], values.background ); + XSetBackground( (Display*)fDisplay, ctxt->fGClist[kGCinvt], values.foreground ); + } else { + Error("SetAttText", "cannot get GC values"); + } + XSetBackground((Display*)fDisplay, ctxt->fGClist[kGCtext], GetColor(0).fPixel); + + // use first existing font + for (int i = 0; i < kMAXFONT; i++) + if (gFont[i].id) { + gCws->textFont = gFont[i].id; + XSetFont((Display*)fDisplay, gCws->fGClist[kGCtext], gCws->textFont->fid); + XSetFont((Display*)fDisplay, gCws->fGClist[kGCinvt], gCws->textFont->fid); + break; + } + + ctxt->fAttText = att; +} + + +void TGX11::SetDrawModeW(WinContext_t wctxt, EDrawMode mode) +{ + auto ctxt = (XWindow_t *) wctxt; + if (!ctxt) + return; + + auto gxmode = GXcopy; + if (mode == kXor) + gxmode = GXxor; + else if (mode == kInvert) + gxmode = GXinvert; + for (int i = 0; i < kMAXGC; i++) + XSetFunction((Display*)fDisplay, ctxt->fGClist[i], gxmode); + + ctxt->fDrawMode = mode; +} diff --git a/graf2d/x11ttf/inc/TGX11TTF.h b/graf2d/x11ttf/inc/TGX11TTF.h index 99b4dbae09486..b440f322b12e9 100644 --- a/graf2d/x11ttf/inc/TGX11TTF.h +++ b/graf2d/x11ttf/inc/TGX11TTF.h @@ -46,25 +46,30 @@ class TGX11TTF : public TGX11 { TXftFontHash *fXftFontHash; ///< hash table for Xft fonts #endif - void Align(void); + void Align(Int_t value); void DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back, RXImage *xim, Int_t bx, Int_t by); - Bool_t IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h); - RXImage *GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h); - void RenderString(Int_t x, Int_t y, ETextMode mode); + Bool_t IsVisible(WinContext_t wctxt, Int_t x, Int_t y, UInt_t w, UInt_t h); + RXImage *GetBackground(WinContext_t wctxt, Int_t x, Int_t y, UInt_t w, UInt_t h); + void RenderString(WinContext_t wctxt, Int_t x, Int_t y, ETextMode mode); public: - TGX11TTF(const TGX11 &org); + TGX11TTF(TGX11 &&org); ~TGX11TTF() override { } Bool_t Init(void *display) override; - void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, + + void DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, const char *text, ETextMode mode) override; - void DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, + void DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, const wchar_t *text, ETextMode mode) override; - void SetTextFont(Font_t fontnumber) override; + + using TGX11::SetTextFont; Int_t SetTextFont(char *fontname, ETextSetMode mode) override; - void SetTextSize(Float_t textsize) override; + + //---- Methods used for new graphics ----- + void SetAttText(WinContext_t wctxt, const TAttText &att) override; + #ifdef R__HAS_XFT //---- Methods used text/fonts handling via Xft ----- diff --git a/graf2d/x11ttf/src/TGX11TTF.cxx b/graf2d/x11ttf/src/TGX11TTF.cxx index b64bfe1b37cb0..7d68be43deb0d 100644 --- a/graf2d/x11ttf/src/TGX11TTF.cxx +++ b/graf2d/x11ttf/src/TGX11TTF.cxx @@ -148,7 +148,7 @@ static TTFX11Init gTTFX11Init; //////////////////////////////////////////////////////////////////////////////// /// Create copy of TGX11 but now use TrueType fonts. -TGX11TTF::TGX11TTF(const TGX11 &org) : TGX11(org) +TGX11TTF::TGX11TTF(TGX11 &&org) : TGX11(std::move(org)) { SetName("X11TTF"); SetTitle("ROOT interface to X11 with TrueType fonts"); @@ -170,9 +170,8 @@ TGX11TTF::TGX11TTF(const TGX11 &org) : TGX11(org) void TGX11TTF::Activate() { - if (gVirtualX && dynamic_cast(gVirtualX)) { - TGX11 *oldg = (TGX11 *) gVirtualX; - gVirtualX = new TGX11TTF(*oldg); + if (auto oldg = dynamic_cast(gVirtualX)) { + gVirtualX = new TGX11TTF(std::move(*oldg)); delete oldg; } } @@ -209,9 +208,9 @@ Bool_t TGX11TTF::Init(void *display) /// then the rotation is applied on the alignment variables. /// SetRotation and LayoutGlyphs should have been called before. -void TGX11TTF::Align(void) +void TGX11TTF::Align(Int_t value) { - EAlign align = (EAlign) fTextAlign; + EAlign align = (EAlign) value; // vertical alignment if (align == kTLeft || align == kTCenter || align == kTRight) { @@ -361,52 +360,52 @@ void TGX11TTF::DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back, //////////////////////////////////////////////////////////////////////////////// /// Draw text using TrueType fonts. If TrueType fonts are not available the -/// text is drawn with TGX11::DrawText. +/// text is drawn with TGX11::DrawTextW. -void TGX11TTF::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, - const char *text, ETextMode mode) +void TGX11TTF::DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, + const char *text, ETextMode mode) { if (!fHasTTFonts) { - TGX11::DrawText(x, y, angle, mgn, text, mode); + TGX11::DrawTextW(wctxt, x, y, angle, mgn, text, mode); } else { if (!TTF::fgInit) TTF::Init(); TTF::SetRotationMatrix(angle); TTF::PrepareString(text); TTF::LayoutGlyphs(); - Align(); - RenderString(x, y, mode); + Align(GetTextAlignW(wctxt)); + RenderString(wctxt, x, y, mode); } } //////////////////////////////////////////////////////////////////////////////// /// Draw text using TrueType fonts. If TrueType fonts are not available the -/// text is drawn with TGX11::DrawText. +/// text is drawn with TGX11::DrawTextW. -void TGX11TTF::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn, - const wchar_t *text, ETextMode mode) +void TGX11TTF::DrawTextW(WinContext_t wctxt, Int_t x, Int_t y, Float_t angle, Float_t mgn, + const wchar_t *text, ETextMode mode) { if (!fHasTTFonts) { - TGX11::DrawText(x, y, angle, mgn, text, mode); + TGX11::DrawTextW(wctxt, x, y, angle, mgn, text, mode); } else { if (!TTF::fgInit) TTF::Init(); TTF::SetRotationMatrix(angle); TTF::PrepareString(text); TTF::LayoutGlyphs(); - Align(); - RenderString(x, y, mode); + Align(GetTextAlignW(wctxt)); + RenderString(wctxt, x, y, mode); } } //////////////////////////////////////////////////////////////////////////////// /// Get the background of the current window in an XImage. -RXImage *TGX11TTF::GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h) +RXImage *TGX11TTF::GetBackground(WinContext_t wctxt, Int_t x, Int_t y, UInt_t w, UInt_t h) { - Window_t cws = GetCurrentWindow(); + Window_t cws = GetWindow(wctxt); UInt_t width; UInt_t height; Int_t xy; - gVirtualX->GetWindowSize(cws, xy, xy, width, height); + GetWindowSize(cws, xy, xy, width, height); if (x < 0) { w += x; @@ -420,32 +419,37 @@ RXImage *TGX11TTF::GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h) if (x+w > width) w = width - x; if (y+h > height) h = height - y; - return (RXImage*)XGetImage((Display*)fDisplay, cws, x, y, w, h, AllPlanes, ZPixmap); + return (RXImage *)XGetImage((Display*)fDisplay, cws, x, y, w, h, AllPlanes, ZPixmap); } //////////////////////////////////////////////////////////////////////////////// /// Test if there is really something to render. -Bool_t TGX11TTF::IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h) +Bool_t TGX11TTF::IsVisible(WinContext_t wctxt, Int_t x, Int_t y, UInt_t w, UInt_t h) { - Window_t cws = GetCurrentWindow(); + Window_t cws = GetWindow(wctxt); UInt_t width; UInt_t height; Int_t xy; - gVirtualX->GetWindowSize(cws, xy, xy, width, height); + GetWindowSize(cws, xy, xy, width, height); // If w or h is 0, very likely the string is only blank characters - if ((int)w == 0 || (int)h == 0) return kFALSE; + if ((int)w == 0 || (int)h == 0) + return kFALSE; // If string falls outside window, there is probably no need to draw it. - if (x + (int)w <= 0 || x >= (int)width) return kFALSE; - if (y + (int)h <= 0 || y >= (int)height) return kFALSE; + if (x + (int)w <= 0 || x >= (int)width) + return kFALSE; + if (y + (int)h <= 0 || y >= (int)height) + return kFALSE; // If w or h are much larger than the window size, there is probably no need // to draw it. Moreover a to large text size may produce a Seg Fault in // malloc in RenderString. - if (w > 10*width) return kFALSE; - if (h > 10*height) return kFALSE; + if (w > 10*width) + return kFALSE; + if (h > 10*height) + return kFALSE; return kTRUE; } @@ -454,7 +458,7 @@ Bool_t TGX11TTF::IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h) /// Perform the string rendering in the pad. /// LayoutGlyphs should have been called before. -void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode) +void TGX11TTF::RenderString(WinContext_t wctxt, Int_t x, Int_t y, ETextMode mode) { TTF::TTGlyph* glyph = TTF::fgGlyphs; @@ -466,7 +470,8 @@ void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode) Int_t x1 = x-Xoff-fAlign.x; Int_t y1 = y+Yoff+fAlign.y-h; - if (!IsVisible(x1, y1, w, h)) return; + if (!IsVisible(wctxt, x1, y1, w, h)) + return; // create the XImage that will contain the text UInt_t depth = fDepth; @@ -482,9 +487,9 @@ void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode) ULong_t bg; XGCValues values; - GC *gc = (GC*)GetGC(3); + auto gc = (GC *) GetGCW(wctxt, 3); if (!gc) { - Error("DrawText", "error getting Graphics Context"); + Error("RenderString", "error getting Graphics Context"); return; } XGetGCValues((Display*)fDisplay, *gc, GCForeground | GCBackground, &values); @@ -492,7 +497,7 @@ void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode) // get the background if (mode == kClear) { // if mode == kClear we need to get an image of the background - XImage *bim = GetBackground(x1, y1, w, h); + XImage *bim = GetBackground(wctxt, x1, y1, w, h); if (!bim) { Error("DrawText", "error getting background image"); return; @@ -534,22 +539,26 @@ void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode) } // put the Ximage on the screen - Window_t cws = GetCurrentWindow(); - gc = (GC*)GetGC(6); - if (gc) XPutImage((Display*)fDisplay, cws, *gc, xim, 0, 0, x1, y1, w, h); + Window_t cws = GetWindow(wctxt); + gc = (GC *) GetGCW(wctxt, 6); + if (gc) + XPutImage((Display*)fDisplay, cws, *gc, xim, 0, 0, x1, y1, w, h); XDestroyImage(xim); } //////////////////////////////////////////////////////////////////////////////// /// Set specified font. -void TGX11TTF::SetTextFont(Font_t fontnumber) + +void TGX11TTF::SetAttText(WinContext_t wctxt, const TAttText &att) { - fTextFont = fontnumber; - if (!fHasTTFonts) { - TGX11::SetTextFont(fontnumber); - } else { - TTF::SetTextFont(fontnumber); + // TODO: add to window context custom part for TTF, + // it can be allocated and provided via private interface + TGX11::SetAttText(wctxt, att); + + if (fHasTTFonts) { + TTF::SetTextFont(att.GetTextFont()); + TTF::SetTextSize(att.GetTextSize()); } } @@ -572,19 +581,6 @@ Int_t TGX11TTF::SetTextFont(char *fontname, ETextSetMode mode) } } -//////////////////////////////////////////////////////////////////////////////// -/// Set current text size. - -void TGX11TTF::SetTextSize(Float_t textsize) -{ - fTextSize = textsize; - if (!fHasTTFonts) { - TGX11::SetTextSize(textsize); - } else { - TTF::SetTextSize(textsize); - } -} - #ifdef R__HAS_XFT ///////////////////////////// Xft font methods ///////////////////////////////// diff --git a/graf3d/gl/src/TGLFontManager.cxx b/graf3d/gl/src/TGLFontManager.cxx index 58ea1188d5936..a5a708b861462 100644 --- a/graf3d/gl/src/TGLFontManager.cxx +++ b/graf3d/gl/src/TGLFontManager.cxx @@ -200,7 +200,7 @@ void TGLFont::RenderHelper(const Char *txt, Double_t x, Double_t y, Double_t ang //later gVirtualX->GetTextAling() will give you 7. Brilliant! //But with Cocoa you'll have 11. As it should be, of course. - if (gVirtualX->InheritsFrom("TGCocoa")) { + if (gVirtualX->InheritsFrom("TGCocoa") || true) { const UInt_t hAlign = UInt_t(align / 10); switch (hAlign) { case 1: diff --git a/test/stressGraphics.ref b/test/stressGraphics.ref index eec9f7d64dc73..6b74f24324e41 100644 --- a/test/stressGraphics.ref +++ b/test/stressGraphics.ref @@ -71,7 +71,7 @@ annotation3d 547845 3000 193367 3000 32383 12000 58073 20000 547493 3000 tgraph2d3 15025 3000 29289 500 42525 11300 33336 3900 14787 4000 ntuple1 254604 5000 383258 7000 55666 30400 46534 6500 259594 7000 - quarks 5045 150 14075 200 33239 600 25303 500 5076 150 + quarks 4846 150 14075 200 33239 600 25303 500 4877 150 timage 1435879 150000 12837 100 26170 100 365000 15000 1085792 250000 zoomtf1 5884 500 16577 200 40706 14000 30026 4000 5884 500 zoomfit 5723 700 15720 200 32236 11000 16916 3200 5670 800 diff --git a/test/stressGraphics_builtinzlib.ref b/test/stressGraphics_builtinzlib.ref index e0eac7809ed28..8cabb76b1ab5f 100644 --- a/test/stressGraphics_builtinzlib.ref +++ b/test/stressGraphics_builtinzlib.ref @@ -71,7 +71,7 @@ annotation3d 547845 3000 193367 3000 32383 12000 58073 20000 547493 3000 tgraph2d3 16675 3000 29481 500 40536 11300 33519 3900 16452 4000 ntuple1 256544 5000 381654 7000 54446 30400 45002 6500 261593 7000 - quarks 5045 150 14074 100 32913 600 25421 600 5076 150 + quarks 4846 150 14074 100 32913 600 25421 600 4877 150 timage 1442666 150000 12840 100 26100 100 374206 15000 1102279 250000 zoomtf1 6130 500 16468 200 49750 14000 29288 4000 6050 500 zoomfit 6200 700 15646 200 31219 11000 18280 3200 6113 800