From 10ca32c260c945a5393b6a0a2816d7fa6a982e71 Mon Sep 17 00:00:00 2001 From: Olivier Couet Date: Mon, 11 May 2026 14:00:51 +0200 Subject: [PATCH] TCanvas drawing area size --- core/base/inc/TStyle.h | 5 ++++- core/base/src/TStyle.cxx | 3 +++ graf2d/gpad/src/TCanvas.cxx | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/core/base/inc/TStyle.h b/core/base/inc/TStyle.h index 4dc3dff2f4fd4..ee515c93cd45d 100644 --- a/core/base/inc/TStyle.h +++ b/core/base/inc/TStyle.h @@ -89,6 +89,7 @@ class TStyle : public TNamed, public TAttLine, public TAttFill, public TAttMarke Int_t fCanvasDefW; ///< Default canvas width Int_t fCanvasDefX; ///< Default canvas top X position Int_t fCanvasDefY; ///< Default canvas top Y position + Bool_t fCanvasSizeIsDrawingArea; ///< If true, TCanvas ctor sizes define the drawing area instead of the window size. Default is false. Color_t fPadColor; ///< Pad color Width_t fPadBorderSize; ///< Pad border size Int_t fPadBorderMode; ///< Pad border mode @@ -194,6 +195,7 @@ class TStyle : public TNamed, public TAttLine, public TAttFill, public TAttMarke Int_t GetCanvasDefW() const {return fCanvasDefW;} Int_t GetCanvasDefX() const {return fCanvasDefX;} Int_t GetCanvasDefY() const {return fCanvasDefY;} + Bool_t GetCanvasSizeIsDrawingArea() const {return fCanvasSizeIsDrawingArea;} Int_t GetColorPalette(Int_t i) const; Int_t GetColorModelPS() const {return fColorModelPS;} Float_t GetDateX() const {return fDateX;} @@ -351,6 +353,7 @@ class TStyle : public TNamed, public TAttLine, public TAttFill, public TAttMarke void SetCanvasDefW(Int_t w=700) {fCanvasDefW = w;} void SetCanvasDefX(Int_t topx=10) {fCanvasDefX = topx;} void SetCanvasDefY(Int_t topy=10) {fCanvasDefY = topy;} + void SetCanvasSizeIsDrawingArea(Int_t da =kFALSE) {fCanvasSizeIsDrawingArea = da;} void SetLegendBorderSize(Width_t size=4) {fLegendBorderSize = size;} void SetLegendFillColor(Color_t color=0) {fLegendFillColor = color;} void SetLegendFillStyle(Style_t style=1001) {fLegendFillStyle = style;} @@ -435,7 +438,7 @@ class TStyle : public TNamed, public TAttLine, public TAttFill, public TAttMarke void SavePrimitive(std::ostream &out, Option_t * = "") override; void SaveSource(const char *filename, Option_t *option = nullptr); - ClassDefOverride(TStyle, 24); //A collection of all graphics attributes + ClassDefOverride(TStyle, 25); //A collection of all graphics attributes }; diff --git a/core/base/src/TStyle.cxx b/core/base/src/TStyle.cxx index 9b9d3b32cf2b4..c63ef394f3919 100644 --- a/core/base/src/TStyle.cxx +++ b/core/base/src/TStyle.cxx @@ -567,6 +567,7 @@ void TStyle::Copy(TObject &obj) const ((TStyle&)obj).fCanvasDefW = fCanvasDefW; ((TStyle&)obj).fCanvasDefX = fCanvasDefX; ((TStyle&)obj).fCanvasDefY = fCanvasDefY; + ((TStyle&)obj).fCanvasSizeIsDrawingArea = fCanvasSizeIsDrawingArea; ((TStyle&)obj).fPadColor = fPadColor; ((TStyle&)obj).fPadBorderSize = fPadBorderSize; ((TStyle&)obj).fPadBorderMode = fPadBorderMode; @@ -713,6 +714,7 @@ void TStyle::Reset(Option_t *opt) fCanvasDefW = 700; fCanvasDefX = 10; fCanvasDefY = 10; + fCanvasSizeIsDrawingArea = kFALSE; fPadColor = fCanvasColor; fPadBorderSize = fCanvasBorderSize; fPadBorderMode = fCanvasBorderMode; @@ -2149,6 +2151,7 @@ void TStyle::SavePrimitive(std::ostream &out, Option_t * /*= ""*/) out << prefix << "SetCanvasDefW(" << GetCanvasDefW() << ");\n"; out << prefix << "SetCanvasDefX(" << GetCanvasDefX() << ");\n"; out << prefix << "SetCanvasDefY(" << GetCanvasDefY() << ");\n"; + out << prefix << "SetCanvasSizeIsDrawingArea(" << GetCanvasSizeIsDrawingArea() << ");\n"; out << prefix << "SetPadColor(" << TColor::SavePrimitiveColor(GetPadColor()) << ");\n"; out << prefix << "SetPadBorderSize(" << GetPadBorderSize() << ");\n"; out << prefix << "SetPadBorderMode(" << GetPadBorderMode() << ");\n"; diff --git a/graf2d/gpad/src/TCanvas.cxx b/graf2d/gpad/src/TCanvas.cxx index be3908b3b363e..1b668c5abbfd8 100644 --- a/graf2d/gpad/src/TCanvas.cxx +++ b/graf2d/gpad/src/TCanvas.cxx @@ -138,6 +138,27 @@ Following example shows how to proceed. c->SetWindowSize(500, 500); } ~~~ + +\since **ROOT version 6.41/02:** + +When SetCanvasSizeIsDrawingArea(kTRUE) is enabled, the width and height passed to the TCanvas +constructor define the size of the drawable area, rather than the full window size. + +Enabling this option makes the canvas behave consistently with typical image/output use cases, +where the requested size should match the final rendered content. + +Example: +~~~ {.cpp} +{ + gStyle->SetCanvasSizeIsDrawingArea(kTRUE); + Double_t w = 600; + Double_t h = 600; + auto c = new TCanvas("c", "c", w, h); + c->SaveAs("c.png"); +} +~~~ + +In this example, the saved PNG will have exactly 600×600 pixels of drawable content. */ //////////////////////////////////////////////////////////////////////////////// @@ -666,6 +687,10 @@ void TCanvas::Build() if (TestBit(kShowEditor)) fCanvasImp->ShowEditor(kTRUE); if (TestBit(kShowToolTips)) fCanvasImp->ShowToolTips(kTRUE); } + if (gStyle->GetCanvasSizeIsDrawingArea()) { + SetWindowSize(fWindowWidth + (fWindowWidth - GetWw()), + fWindowHeight + (fWindowHeight - GetWh())); + } } ////////////////////////////////////////////////////////////////////////////////