Skip to content
Merged
5 changes: 5 additions & 0 deletions core/base/inc/TVirtualPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#include "TAttText.h"
#include "TAttMarker.h"

class TImage;

class TVirtualPS : public TNamed, public TAttLine, public TAttFill, public TAttMarker, public TAttText {

private:
Expand Down Expand Up @@ -54,6 +56,9 @@ class TVirtualPS : public TNamed, public TAttLine, public TAttFill, public TAttM
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 DrawImage(TImage * /* img */, Int_t /* x */, Int_t /* y */ , Int_t /* flags */ = 0) {}

virtual void Close(Option_t *opt="") = 0;
virtual void DrawBox(Double_t x1, Double_t y1,Double_t x2, Double_t y2) = 0;
virtual void DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt,
Expand Down
3 changes: 3 additions & 0 deletions core/base/inc/TVirtualPadPainter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

class TVirtualPad;
class TVirtualPS;
class TImage;
class TAttFill;
class TAttLine;
class TAttMarker;
Expand Down Expand Up @@ -151,6 +152,8 @@ class TVirtualPadPainter {

virtual void DrawTextUrl(Double_t x, Double_t y, const char *text, const char *url);

virtual void DrawImage(TImage *img, Int_t x, Int_t y, Int_t flags = 0);

//gif, jpg, png, bmp output.
virtual void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const = 0;

Expand Down
7 changes: 7 additions & 0 deletions core/base/src/TVirtualPadPainter.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,10 @@ void TVirtualPadPainter::SetCursor(Int_t device, ECursor cursor)
gVirtualX->SetCursor(device, cursor);
}


////////////////////////////////////////////////////////////////////////////////
/// Draw image, need to be implemented in correspondent

void TVirtualPadPainter::DrawImage(TImage *, Int_t, Int_t, Int_t)
{
}
231 changes: 48 additions & 183 deletions graf2d/asimage/src/TASImage.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ ROOT tutorials: `$ROOTSYS/tutorials/visualisation/image/`
#include "TVirtualX.h"

#include <iostream>
#include <vector>
#include <memory>

#include "snprintf.h"
Expand Down Expand Up @@ -1230,13 +1231,13 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y,
Int_t xsrc, Int_t ysrc, UInt_t wsrc, UInt_t hsrc,
Option_t *opt)
{
if (!im) return;
if (!im)
return;

wsrc = wsrc ? wsrc : im->width;
hsrc = hsrc ? hsrc : im->height;

static int x11 = -1;
if (x11 < 0) x11 = gVirtualX->InheritsFrom("TGX11");
static int x11 = gVirtualX->InheritsFrom("TGX11");

Pixmap_t mask = kNone;

Expand All @@ -1245,21 +1246,18 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y,
UInt_t ow = wsrc%8;
UInt_t ww = wsrc - ow + (ow ? 8 : 0);

UInt_t bit = 0;
int i = 0;
UInt_t yy = 0;
UInt_t xx = 0;
UInt_t bit = 0, i = 0;

char *bits = new char[ww*hh]; //an array of bits
std::vector<char> bits(ww*hh); //an array of bits

ASImageDecoder *imdec = start_image_decoding(fgVisual, im, SCL_DO_ALPHA,
xsrc, ysrc, ww, 0, nullptr);
if (imdec) {
for (yy = 0; yy < hh; yy++) {
for (UInt_t yy = 0; yy < hh; yy++) {
imdec->decode_image_scanline(imdec);
CARD32 *a = imdec->buffer.alpha;

for (xx = 0; xx < ww; xx++) {
for (UInt_t xx = 0; xx < ww; xx++) {
if (a[xx]) {
SETBIT(bits[i], bit);
} else {
Expand All @@ -1277,8 +1275,7 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y,
stop_image_decoding(&imdec);

mask = gVirtualX->CreateBitmap(gVirtualX->GetDefaultRootWindow(),
(const char *)bits, ww, hh);
delete [] bits;
bits.data(), ww, hh);
}

GCValues_t gv;
Expand All @@ -1295,7 +1292,7 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y,
gVirtualX->ChangeGC(gc, &gv);
}

if (x11 && (!gPad || gPad->GetGLDevice() == -1)) { //use built-in optimized version
if (x11) { //use built-in optimized version
asimage2drawable(fgVisual, wid, im, (GC)gc, xsrc, ysrc, x, y, wsrc, hsrc, 1);
} else {
ASImage *img = nullptr;
Expand All @@ -1311,33 +1308,29 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y,
TString option(opt);
option.ToLower();

if (gPad && gPad->GetGLDevice() != -1) {
if (TVirtualPadPainter *painter = gPad->GetPainter())
painter->DrawPixels(bits, wsrc, hsrc, x, y, !option.Contains("opaque"));
} else {
Pixmap_t pic = gVirtualX->CreatePixmapFromData(bits, wsrc, hsrc);
if (pic) {
if (!option.Contains("opaque")) {
SETBIT(wsrc,31);
SETBIT(hsrc,31);
}
gVirtualX->CopyArea(pic, wid, gc, 0, 0, wsrc, hsrc, x, y);
gVirtualX->DeletePixmap(pic);
Pixmap_t pic = gVirtualX->CreatePixmapFromData(bits, wsrc, hsrc);
if (pic) {
if (!option.Contains("opaque")) {
SETBIT(wsrc,31);
SETBIT(hsrc,31);
}
gVirtualX->CopyArea(pic, wid, gc, 0, 0, wsrc, hsrc, x, y);
gVirtualX->DeletePixmap(pic);
}
}

if (img) {
if (img)
destroy_asimage(&img);
}
}

// free mask pixmap
if (gv.fClipMask != kNone) gVirtualX->DeletePixmap(gv.fClipMask);
if (mask != kNone)
gVirtualX->DeletePixmap(mask);

gv.fMask = kGCClipMask;
gv.fClipMask = kNone;
if (gc) gVirtualX->ChangeGC(gc, &gv);
if (gc)
gVirtualX->ChangeGC(gc, &gv);
}


Expand Down Expand Up @@ -1411,6 +1404,9 @@ void TASImage::Paint(Option_t *option)
}
}

// opaque flag used in some X11
Int_t flags = opt.Contains("opaque") ? 0 : 1;

ASImage *image = fImage;

// Get geometry of pad
Expand Down Expand Up @@ -1536,173 +1532,42 @@ 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());

auto ps = gPad->GetPainter()->GetPS();
auto pp = gPad->GetPainter();

if (!ps) {
Window_t wid = (Window_t)gVirtualX->GetWindowID(gPad->GetPixmapID());
Image2Drawable(fScaledImage ? fScaledImage->fImage : fImage, wid, tox, toy);
pp->DrawImage(fScaledImage ? fScaledImage : this, tox, toy, flags);

if (grad_im && fPaletteEnabled) {
// draw color bar
Image2Drawable(grad_im, wid, pal_x, pal_y);
if (grad_im && fPaletteEnabled) {
TASImage pimg;
pimg.fImage = grad_im;
grad_im = nullptr; // will be delete with pimg destructor

// values of palette
TGaxis axis;
Int_t ndiv = 510;
double min = fMinValue;
double max = fMaxValue;
// draw color bar
pp->DrawImage(&pimg, pal_x, pal_y, flags);

// values of palette
TGaxis axis;
Int_t ndiv = 510;
Double_t min = fMinValue;
Double_t max = fMaxValue;
Double_t pal_Xpos = gPad->AbsPixeltoX(pal_Ax + pal_w);
if (!pp->GetPS()) {
// TODO: check why here special drawing for none-PS
axis.SetLineColor(0); // draw white ticks
Double_t pal_Xpos = gPad->AbsPixeltoX(pal_Ax + pal_w);
axis.PaintAxis(pal_Xpos, gPad->PixeltoY(pal_Ay + pal_h - 1),
pal_Xpos, gPad->PixeltoY(pal_Ay),
min, max, ndiv, "+LU");
min = fMinValue;
max = fMaxValue;
axis.SetLineColor(1); // draw black ticks
axis.PaintAxis(pal_Xpos, gPad->AbsPixeltoY(pal_Ay + pal_h),
pal_Xpos, gPad->AbsPixeltoY(pal_Ay + 1),
min, max, ndiv, "+L");
}
} else {
// loop over pixmap and draw image to PostScript

Bool_t paint_as_png = kFALSE;

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));

if (grad_im) {
TASImage tgrad;
tgrad.fImage = grad_im;
dump->Merge(&tgrad, "alphablend", pal_Ax, pal_Ay);

// values of palette
TGaxis axis;
Int_t ndiv = 510;
double min = fMinValue;
double max = fMaxValue;
axis.SetLineColor(1); // draw black ticks
Double_t pal_Xpos = gPad->AbsPixeltoX(pal_Ax + pal_w);
axis.PaintAxis(pal_Xpos, gPad->AbsPixeltoY(pal_Ay + pal_h),
pal_Xpos, gPad->AbsPixeltoY(pal_Ay + 1),
min, max, ndiv, "+L");
}
return;
} 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 x1, x2, y1, y2;

if (expand) {
x1 = gPad->GetX1();
x2 = x1+dx/image->width;
y1 = gPad->GetY2();
y2 = y1+dy/image->height;
} else {
x1 = gPad->GetX1()+dx*gPad->GetLeftMargin();
x2 = x1+(dx*(1-gPad->GetRightMargin()-gPad->GetLeftMargin()))/image->width;
y1 = gPad->GetY2()-dy*gPad->GetTopMargin();
y2 = y1+(dy*(1-gPad->GetTopMargin()-gPad->GetBottomMargin()))/image->height;
}

// get special color cell to be reused during image printing
ps->SetFillColor(TColor::GetColor((Float_t) 1., (Float_t) 1., (Float_t) 1.));
ps->SetFillStyle(1001);

ps->CellArrayBegin(image->width, image->height, x1, x2, y1, y2);

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, &params)) {
ps->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++)
ps->CellArrayFill(imdec->buffer.red[xt],
imdec->buffer.green[xt],
imdec->buffer.blue[xt]);
}
stop_image_decoding(&imdec);
}
ps->CellArrayEnd();

// print the color bar
if (grad_im) {
Double_t xconv = (gPad->AbsPixeltoX(pal_Ax + pal_w) - gPad->AbsPixeltoX(pal_Ax)) / grad_im->width;
Double_t yconv = (gPad->AbsPixeltoY(pal_Ay - pal_h) - gPad->AbsPixeltoY(pal_Ay)) / grad_im->height;
x1 = gPad->AbsPixeltoX(pal_Ax);
x2 = x1 + xconv;
y2 = gPad->AbsPixeltoY(pal_Ay);
y1 = y2 - yconv;
ps->CellArrayBegin(grad_im->width, grad_im->height,
x1, x2, y1, y2);

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, &params)) {
ps->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++)
ps->CellArrayFill(imdec->buffer.red[xt],
imdec->buffer.green[xt],
imdec->buffer.blue[xt]);
}
stop_image_decoding(&imdec);
}
ps->CellArrayEnd();

// values of palette
TGaxis axis;
Int_t ndiv = 510;
double min = fMinValue;
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");

}
axis.SetLineColor(1); // draw black ticks
axis.PaintAxis(pal_Xpos, gPad->AbsPixeltoY(pal_Ay + pal_h),
pal_Xpos, gPad->AbsPixeltoY(pal_Ay + 1),
min, max, ndiv, "+L");
}

if (grad_im) {
if (grad_im)
destroy_asimage(&grad_im);
}
}

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -5773,7 +5638,7 @@ void TASImage::DrawTextTTF(Int_t x, Int_t y, const char *text, Int_t size,
ttf.PrepareString(text);
ttf.LayoutGlyphs();

if (ttf.ApplyAlignRotate(x, y, 11, GetWidth(), GetHeight()))
if (ttf.ApplyAlignRotate(x, y, 13, GetWidth(), GetHeight()))
DrawFTGlyphs(ttf, color, x, y);
}

Expand Down
2 changes: 2 additions & 0 deletions graf2d/gpad/inc/TPadPainter.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class TPadPainter : public TPadPainterBase {

void DrawTTFglyphs(Int_t x, Int_t y, TTFhandle &ttf, ETextMode mode) override;

void DrawImage(TImage *img, Int_t x, Int_t y, Int_t flags = 0) override;

//jpg, png, bmp, gif output.
void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const override;

Expand Down
2 changes: 2 additions & 0 deletions graf2d/gpad/inc/TPadPainterPS.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class TPadPainterPS : public TPadPainterBase {

void DrawTextUrl(Double_t x, Double_t y, const char *text, const char *url) override;

void DrawImage(TImage *img, Int_t x, Int_t y, Int_t flags = 0) override;

//jpg, png, bmp, gif output.
void SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const override;

Expand Down
Loading
Loading