diff --git a/core/base/inc/TVirtualPS.h b/core/base/inc/TVirtualPS.h index e722376e924a4..5cdc41ec0b6be 100644 --- a/core/base/inc/TVirtualPS.h +++ b/core/base/inc/TVirtualPS.h @@ -48,6 +48,7 @@ class TVirtualPS : public TNamed, public TAttLine, public TAttFill, public TAttM virtual ~TVirtualPS(); virtual void CellArrayBegin(Int_t W, Int_t H, Double_t x1, Double_t x2, Double_t y1, Double_t y2) = 0; virtual void CellArrayFill(Int_t r, Int_t g, Int_t b) = 0; + virtual void CellArrayPng(char * /* buffer */, int /* size */) {} virtual void CellArrayEnd() = 0; virtual void Close(Option_t *opt="") = 0; virtual void DrawBox(Double_t x1, Double_t y1,Double_t x2, Double_t y2) = 0; diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index efaaea8eeb6e5..6ea60a788019f 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -1337,6 +1337,7 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, if (gc) gVirtualX->ChangeGC(gc, &gv); } + //////////////////////////////////////////////////////////////////////////////// /// Draw image on the drawable wid (pixmap, window) at x,y position. /// @@ -1562,6 +1563,9 @@ void TASImage::Paint(Option_t *option) // loop over pixmap and draw image to PostScript if (gVirtualPS) { + + Bool_t paint_as_png = kFALSE; + if (gVirtualPS->InheritsFrom("TImageDump")) { // PostScript is asimage TImage *dump = (TImage *)gVirtualPS->GetStream(); if (!dump) return; @@ -1589,23 +1593,12 @@ void TASImage::Paint(Option_t *option) Warning("Paint", "PDF not implemented yet"); return; } else if (gVirtualPS->InheritsFrom("TSVG")) { - Warning("Paint", "SVG not implemented yet"); - return; + paint_as_png = kTRUE; } - // get special color cell to be reused during image printing - TObjArray *colors = (TObjArray*) gROOT->GetListOfColors(); - TColor *color = nullptr; - // Look for color by name - if ((color = (TColor*)colors->FindObject("Image_PS")) == nullptr) - color = new TColor(colors->GetEntries(), 1., 1., 1., "Image_PS"); - - gVirtualPS->SetFillColor(color->GetNumber()); - gVirtualPS->SetFillStyle(1001); - Double_t dx = gPad->GetX2()-gPad->GetX1(); Double_t dy = gPad->GetY2()-gPad->GetY1(); - Double_t x1,x2,y1,y2; + Double_t x1, x2, y1, y2; if (expand) { x1 = gPad->GetX1(); @@ -1619,19 +1612,38 @@ void TASImage::Paint(Option_t *option) y2 = y1+(dy*(1-gPad->GetTopMargin()-gPad->GetBottomMargin()))/image->height; } + // 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); + gVirtualPS->CellArrayBegin(image->width, image->height, x1, x2, y1, y2); - ASImageDecoder *imdec = start_image_decoding(fgVisual, image, SCL_DO_ALL, - 0, 0, image->width, image->height, nullptr); - if (!imdec) return; - 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]); + if (paint_as_png) { + char *buffer = nullptr; + int size = 0; + ASImageExportParams params; + params.png.type = ASIT_Png; + params.png.flags = EXPORT_ALPHA; + params.png.compression = GetImageCompression(); + if (!params.png.compression) + params.png.compression = -1; + if (ASImage2PNGBuff(image, (CARD8 **)&buffer, &size, ¶ms)) { + gVirtualPS->CellArrayPng(buffer, size); + free(buffer); + } + } else { + auto imdec = start_image_decoding(fgVisual, image, SCL_DO_ALL, + 0, 0, image->width, image->height, nullptr); + if (imdec) + 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]); + } + stop_image_decoding(&imdec); } - stop_image_decoding(&imdec); gVirtualPS->CellArrayEnd(); // print the color bar @@ -1645,18 +1657,33 @@ void TASImage::Paint(Option_t *option) gVirtualPS->CellArrayBegin(grad_im->width, grad_im->height, x1, x2, y1, y2); - imdec = start_image_decoding(fgVisual, grad_im, SCL_DO_ALL, - 0, 0, grad_im->width, grad_im->height, nullptr); - if (imdec) { - 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]); + if (paint_as_png) { + char *buffer = nullptr; + int size = 0; + ASImageExportParams params; + params.png.type = ASIT_Png; + params.png.flags = EXPORT_ALPHA; + params.png.compression = GetImageCompression(); + if (!params.png.compression) + params.png.compression = -1; + + if (ASImage2PNGBuff(grad_im, (CARD8 **)&buffer, &size, ¶ms)) { + gVirtualPS->CellArrayPng(buffer, size); + free(buffer); } + } else { + auto imdec = start_image_decoding(fgVisual, grad_im, SCL_DO_ALL, + 0, 0, grad_im->width, grad_im->height, nullptr); + if (imdec) + 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]); + } + stop_image_decoding(&imdec); } - stop_image_decoding(&imdec); gVirtualPS->CellArrayEnd(); // values of palette diff --git a/graf2d/postscript/inc/TSVG.h b/graf2d/postscript/inc/TSVG.h index d991aff64a904..bdc462977afff 100644 --- a/graf2d/postscript/inc/TSVG.h +++ b/graf2d/postscript/inc/TSVG.h @@ -42,6 +42,7 @@ class TSVG : public TVirtualPS { void CellArrayBegin(Int_t W, Int_t H, Double_t x1, Double_t x2, Double_t y1, Double_t y2) override; void CellArrayFill(Int_t r, Int_t g, Int_t b) override; + void CellArrayPng(char *buffer, int size) override; void CellArrayEnd() override; void Close(Option_t *opt="") override; Double_t CMtoSVG(Double_t u) { return 0.5 + 72*u/2.54; } diff --git a/graf2d/postscript/src/TSVG.cxx b/graf2d/postscript/src/TSVG.cxx index 8c3ab46b73349..1875a4c28aff6 100644 --- a/graf2d/postscript/src/TSVG.cxx +++ b/graf2d/postscript/src/TSVG.cxx @@ -21,6 +21,7 @@ #include "TROOT.h" #include "TDatime.h" +#include "TBase64.h" #include "TColor.h" #include "TVirtualPad.h" #include "TPoints.h" @@ -944,6 +945,55 @@ void TSVG::DrawPS(Int_t nn, Double_t *xw, Double_t *yw) PrintFast(2,"/>"); } +//////////////////////////////////////////////////////////////////////////////// +/// Begin the Cell Array painting + +void TSVG::CellArrayBegin(Int_t width, Int_t height, Double_t x1, Double_t x2, Double_t y1, Double_t y2) +{ + Double_t svgx1 = XtoSVG(x1); + Double_t svgx2 = XtoSVG(x1 + (x2 - x1) * width); + Double_t svgy1 = YtoSVG(y1); + Double_t svgy2 = YtoSVG(y1 - (y2 - y1) * height); + + PrintStr("@@"); + PrintStr(TString::Format("(buffer), size); + PrintFast(base64.Length(), base64.Data()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// End the Cell Array painting + +void TSVG::CellArrayEnd() +{ + PrintStr("\">@"); + PrintStr("@"); +} + //////////////////////////////////////////////////////////////////////////////// /// Initialize the SVG file. The main task of the function is to output the /// SVG header file which consist in ``, `<desc>` and `<defs>`. The @@ -1508,31 +1558,6 @@ Double_t TSVG::YtoSVG(Double_t y) return fYsizeSVG-VtoSVG(v); } -//////////////////////////////////////////////////////////////////////////////// -/// Begin the Cell Array painting - -void TSVG::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t, - Double_t) -{ - Warning("TSVG::CellArrayBegin", "not yet implemented"); -} - -//////////////////////////////////////////////////////////////////////////////// -/// Paint the Cell Array - -void TSVG::CellArrayFill(Int_t, Int_t, Int_t) -{ - Warning("TSVG::CellArrayFill", "not yet implemented"); -} - -//////////////////////////////////////////////////////////////////////////////// -/// End the Cell Array painting - -void TSVG::CellArrayEnd() -{ - Warning("TSVG::CellArrayEnd", "not yet implemented"); -} - //////////////////////////////////////////////////////////////////////////////// /// Not needed in SVG case diff --git a/test/svg_ref/timage.svg b/test/svg_ref/timage.svg index 10143cf6fd93b..f28853fec03c6 100644 --- a/test/svg_ref/timage.svg +++ b/test/svg_ref/timage.svg @@ -11,18 +11,31 @@ timage.svg <path d="M29,247l 2.0, -2.0h 166v -216l 2.0, -2.0v 220h -170z" fill="#a9a9a9"/> <rect x="46" y="49" width="136" height="176" fill="#f2f2f2"/> <rect x="46" y="49" width="136" height="176" fill="none" stroke="#f2f2f2"/> +<g transform="translate(46 49) scale(0.712 0.712)"> +<image width="191" height="247" href="data:image/png;base64,"></image> +</g> <rect x="312" y="82" width="227" height="165" fill="#f2f2f2"/> <path d="M312,247l 2.0, -2.0v -161h 223l 2.0, -2.0h -227v 165z" fill="white"/> <path d="M312,247l 2.0, -2.0h 223v -161l 2.0, -2.0v 165h -227z" fill="#a9a9a9"/> <rect x="335" y="99" width="181" height="132" fill="#f2f2f2"/> <rect x="335" y="99" width="181" height="132" fill="none" stroke="#f2f2f2"/> +<g transform="translate(335 99) scale(0.714 0.709)"> +<image width="254" height="186" href="data:image/png;base64,"></image> +</g> <rect x="312" y="302" width="170" height="220" fill="#f2f2f2"/> <path d="M312,522l 2.0, -2.0v -216h 166l 2.0, -2.0h -170v 220z" fill="white"/> <path d="M312,522l 2.0, -2.0h 166v -216l 2.0, -2.0v 220h -170z" fill="#a9a9a9"/> <rect x="329" y="324" width="136" height="176" fill="#f2f2f2"/> <rect x="329" y="324" width="136" height="176" fill="none" stroke="#f2f2f2"/> +<g transform="translate(329 324) scale(0.712 0.712)"> +<image width="191" height="247" href="data:image/png;base64,"></image> +</g> <rect x="29" y="357" width="227" height="165" fill="#f2f2f2"/> <path d="M29,522l 2.0, -2.0v -161h 223l 2.0, -2.0h -227v 165z" fill="white"/> <path d="M29,522l 2.0, -2.0h 223v -161l 2.0, -2.0v 165h -227z" fill="#a9a9a9"/> <rect x="52" y="374" width="181" height="132" fill="#f2f2f2"/> -<rect x="52" y="374" width="181" height="132" fill="none" stroke="#f2f2f2"/></svg> +<rect x="52" y="374" width="181" height="132" fill="none" stroke="#f2f2f2"/> +<g transform="translate(52 374) scale(0.714 0.709)"> +<image width="254" height="186" href="data:image/png;base64,"></image> +</g> +</svg>