From 33e801c9240c1abb3f8d7bdfb6d5bff789c79688 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 12:33:01 +0100 Subject: [PATCH 1/9] [asimage] introduce internal ASVisualHolder It is thread_local and correctly cleanup when thread or process is closed. It only should be used for batch (without disaplay) operation First use for paint and assign image --- graf2d/asimage/src/TASImage.cxx | 60 ++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 38f4dc5b31b3c..6988e7e147c35 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -170,6 +170,40 @@ typedef struct { }\ + + +//////////////////////////////////////////////////////////////////////////////// +/// Holder of batch ASVisual instance, destroyed when thread or application closed +/// Only this instance must be used in all applications +class BatchASVisualHolder { + ASVisual *fVisual = nullptr; + +public: + + ASVisual *operator()() + { + if (!fVisual) { + fVisual = create_asvisual(nullptr, 0, 0, nullptr); + fVisual->dpy = nullptr; // fake (not used) + } + return fVisual; + } + + ~BatchASVisualHolder() + { + if (fVisual) { + destroy_asvisual(fVisual, 0); + fVisual = nullptr; + } + } +}; + +namespace { + +thread_local BatchASVisualHolder bholder; + +} + //////////////////////////////////////////////////////////////////////////////// /// Destroy image. @@ -1001,7 +1035,8 @@ void TASImage::SetImage(const Double_t *imageData, UInt_t width, UInt_t height, { TAttImage::SetPalette(palette); - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("SetImage", "Visual not initiated"); return; } @@ -1022,8 +1057,7 @@ void TASImage::SetImage(const Double_t *imageData, UInt_t width, UInt_t height, ASVectorPalette asPalette; asPalette.npoints = pal.fNumPoints; - Int_t col; - for (col = 0; col < 4; col++) + for (Int_t col = 0; col < 4; col++) asPalette.channels[col] = new UShort_t[asPalette.npoints]; memcpy(asPalette.channels[0], pal.fColorBlue, pal.fNumPoints * sizeof(UShort_t)); @@ -1035,12 +1069,12 @@ void TASImage::SetImage(const Double_t *imageData, UInt_t width, UInt_t height, for (Int_t point = 0; point < Int_t(asPalette.npoints); point++) asPalette.points[point] = fMinValue + (fMaxValue - fMinValue) * pal.fPoints[point]; - fImage = create_asimage_from_vector(fgVisual, (Double_t*)imageData, width, + fImage = create_asimage_from_vector(vis, (Double_t*)imageData, width, height, &asPalette, ASA_ASImage, GetImageCompression(), GetImageQuality()); delete [] asPalette.points; - for (col = 0; col < 4; col++) + for (Int_t col = 0; col < 4; col++) delete [] asPalette.channels[col]; fZoomUpdate = 0; @@ -1342,7 +1376,9 @@ void TASImage::Paint(Option_t *option) return; } - if (!InitVisual()) { + auto vis = bholder(); + + if (!vis) { Warning("Paint", "Visual not initiated"); return; } @@ -1434,7 +1470,7 @@ void TASImage::Paint(Option_t *option) (((ARGB32)(pal.fColorAlpha[oldPt] & 0xff00)) << 16); } - grad_im = make_gradient(fgVisual, &grad , UInt_t(pal_w), + grad_im = make_gradient(vis, &grad , UInt_t(pal_w), pal_h, SCL_DO_COLOR, ASA_ARGB32, GetImageCompression(), GetImageQuality()); @@ -1446,7 +1482,7 @@ void TASImage::Paint(Option_t *option) DestroyScaledImage(); fScaledImage = (TASImage*) TImage::Create(); if (!fScaledImage) return; - fScaledImage->fImage = tile_asimage(fgVisual, fImage, tile_x, tile_y, + fScaledImage->fImage = tile_asimage(vis, fImage, tile_x, tile_y, to_w, to_h, tile_tint, ASA_ASImage, GetImageCompression(), GetImageQuality()); image = fScaledImage->fImage; @@ -1473,20 +1509,20 @@ void TASImage::Paint(Option_t *option) if (fZoomWidth && fZoomHeight && ((fImage->width != fZoomWidth) || (fImage->height != fZoomHeight))) { // zoom and scale image - ASImage *tmpImage = tile_asimage(fgVisual, fImage, fZoomOffX, + ASImage *tmpImage = tile_asimage(vis, fImage, fZoomOffX, fImage->height - fZoomHeight - fZoomOffY, fZoomWidth, fZoomHeight, 0, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (tmpImage) { - fScaledImage->fImage = scale_asimage(fgVisual, tmpImage, to_w, to_h, + fScaledImage->fImage = scale_asimage(vis, tmpImage, to_w, to_h, ASA_ASImage, GetImageCompression(), - GetImageQuality()); + GetImageQuality()); destroy_asimage(&tmpImage); } } else { // scale image, no zooming - fScaledImage->fImage = scale_asimage(fgVisual, fImage, to_w, to_h, + fScaledImage->fImage = scale_asimage(vis, fImage, to_w, to_h, ASA_ASImage, GetImageCompression(), GetImageQuality()); } From 1b895daf8bc2f3a809192b604ba7454b949bc829 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 13:19:37 +0100 Subject: [PATCH 2/9] [asimage] use new batch visual in several operations --- graf2d/asimage/src/TASImage.cxx | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 6988e7e147c35..6d9badd4bade1 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -1760,7 +1760,8 @@ void TASImage::SetPalette(const TImagePalette *palette) { TAttImage::SetPalette(palette); - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("SetPalette", "Visual not initiated"); return; } @@ -1792,7 +1793,7 @@ void TASImage::SetPalette(const TImagePalette *palette) asPalette.points[point] = fMinValue + (fMaxValue - fMinValue) * pal.fPoints[point]; // use the new palette in this image - colorize_asimage_vector(fgVisual, fImage, &asPalette, ASA_ASImage, GetImageQuality()); + colorize_asimage_vector(vis, fImage, &asPalette, ASA_ASImage, GetImageQuality()); delete [] asPalette.points; for (Int_t col = 0; col < 4; col++) @@ -1817,7 +1818,8 @@ void TASImage::Scale(UInt_t toWidth, UInt_t toHeight) return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Scale", "Visual not initiated"); return; } @@ -1831,7 +1833,7 @@ void TASImage::Scale(UInt_t toWidth, UInt_t toHeight) if (toHeight > 30000) toHeight = 30000; - ASImage *img = scale_asimage(fgVisual, fImage, toWidth, toHeight, + ASImage *img = scale_asimage(vis, fImage, toWidth, toHeight, ASA_ASImage, GetImageCompression(), GetImageQuality()); DestroyImage(); @@ -1852,7 +1854,8 @@ void TASImage::Slice(UInt_t xStart, UInt_t xEnd, UInt_t yStart, UInt_t yEnd, return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Slice", "Visual not initiated"); return; } @@ -1866,7 +1869,7 @@ void TASImage::Slice(UInt_t xStart, UInt_t xEnd, UInt_t yStart, UInt_t yEnd, if (toHeight > 30000) toHeight = 30000; - ASImage *img = slice_asimage(fgVisual, fImage, xStart, xEnd, + ASImage *img = slice_asimage(vis, fImage, xStart, xEnd, yStart, yEnd, toWidth, toHeight, ASA_ASImage, GetImageCompression(), GetImageQuality()); @@ -1887,7 +1890,8 @@ void TASImage::Tile(UInt_t toWidth, UInt_t toHeight) return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Tile", "Visual not initiated"); return; } @@ -1901,7 +1905,7 @@ void TASImage::Tile(UInt_t toWidth, UInt_t toHeight) if (toHeight > 30000) toHeight = 30000; - ASImage *img = tile_asimage(fgVisual, fImage, 0, 0, toWidth, toHeight, 0, + ASImage *img = tile_asimage(vis, fImage, 0, 0, toWidth, toHeight, 0, ASA_ASImage, GetImageCompression(), GetImageQuality()); DestroyImage(); fImage = img; @@ -1975,7 +1979,8 @@ void TASImage::Flip(Int_t flip) Warning("Flip", "Image not valid"); return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Flip", "Visual not initiated"); return; } @@ -1995,7 +2000,7 @@ void TASImage::Flip(Int_t flip) h = fImage->width; } - ASImage *img = flip_asimage(fgVisual, fImage, 0, 0, w, h, rflip, + ASImage *img = flip_asimage(vis, fImage, 0, 0, w, h, rflip, ASA_ASImage, GetImageCompression(), GetImageQuality()); DestroyImage(); @@ -2023,7 +2028,7 @@ void TASImage::Mirror(Bool_t vert) return; } - auto vis = InitVisual(true); + auto vis = bholder(); if (!vis) { Warning("Mirror", "Visual not initiated"); return; @@ -2221,7 +2226,8 @@ Pixmap_t TASImage::GetPixmap() Bool_t TASImage::GetMaskBits(UInt_t &width, UInt_t &height, std::vector &bits) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("GetMaskBits", "Visual not initiated"); return kFALSE; } @@ -2237,7 +2243,7 @@ Bool_t TASImage::GetMaskBits(UInt_t &width, UInt_t &height, std::vector &b UInt_t ow = img->width % 8; width = img->width - ow + (ow ? 8 : 0); - ASImageDecoder *imdec = start_image_decoding(fgVisual, img, SCL_DO_ALPHA, + ASImageDecoder *imdec = start_image_decoding(vis, img, SCL_DO_ALPHA, 0, 0, width, 0, nullptr); if (!imdec) return kFALSE; From 2171f47dd3e1f80a6d1dea465720f5fac92ff3f7 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 13:56:19 +0100 Subject: [PATCH 3/9] [asimage] use holder to preserve font manager When painting text, asimage create font manager. It need to be correctly destroyed at the end --- graf2d/asimage/src/TASImage.cxx | 40 ++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 6d9badd4bade1..4c349347ae5c4 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -121,7 +121,6 @@ ASVisual *TASImage::fgBatchVisual = nullptr; Bool_t TASImage::fgInit = kFALSE; Bool_t TASImage::fgBatch = kFALSE; -static ASFontManager *gFontManager = nullptr; static unsigned long kAllPlanes = ~0; THashTable *TASImage::fgPlugList = new THashTable(50); @@ -177,7 +176,7 @@ typedef struct { /// Only this instance must be used in all applications class BatchASVisualHolder { ASVisual *fVisual = nullptr; - + ASFontManager *fFontManager = nullptr; public: ASVisual *operator()() @@ -189,12 +188,25 @@ class BatchASVisualHolder { return fVisual; } + ASFontManager *font_manager() + { + if (!fFontManager) + fFontManager = create_font_manager(nullptr, nullptr, nullptr); + return fFontManager; + } + ~BatchASVisualHolder() { if (fVisual) { destroy_asvisual(fVisual, 0); fVisual = nullptr; } + + if (fFontManager) { + destroy_font_manager(fFontManager, 0); + fFontManager = nullptr; + } + } }; @@ -2150,7 +2162,7 @@ ASVisual *TASImage::InitVisual(Bool_t plain) /// Static function to initialize the image. Bool_t TASImage::InitImage(const char *caller) { - if (!InitVisual()) { + if (!bholder()) { Warning(caller, "Visual not initiated"); return false; } @@ -2515,9 +2527,8 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, ASImage *text_im = nullptr; Bool_t ttfont = kFALSE; - if (!InitImage("DrawText")) { + if (!InitImage("DrawText")) return; - } TString fn = font_name; fn.Strip(); @@ -2544,19 +2555,16 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, return; } - if (!gFontManager) { - gFontManager = create_font_manager(fgVisual->dpy, nullptr, nullptr); - } - - if (!gFontManager) { - Warning("DrawText", "cannot create Font Manager"); + auto font_manager = bholder.font_manager(); + if (!font_manager) { + Warning("DrawText", "Fail to create font manager missing"); return; } - ASFont *font = fn.IsNull() ? nullptr : get_asfont(gFontManager, fn.Data(), 0, size, ASF_GuessWho); + ASFont *font = fn.IsNull() ? nullptr : get_asfont(font_manager, fn.Data(), 0, size, ASF_GuessWho); if (!font) { - font = get_asfont(gFontManager, "fixed", 0, size, ASF_GuessWho); + font = get_asfont(font_manager, "fixed", 0, size, ASF_GuessWho); if (!font) { Warning("DrawText", "cannot find a font %s", font_name); return; @@ -2567,7 +2575,7 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, if (!fImage) { fImage = create_asimage(width, height, 0); - fill_asimage(fgVisual, fImage, 0, 0, width, height, 0xFFFFFFFF); + fill_asimage(bholder(), fImage, 0, 0, width, height, 0xFFFFFFFF); } text_im = draw_text(text, font, (ASText3DType)type, 0); @@ -2578,7 +2586,7 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, ASImage *tmp = file2ASImage(fore_file, 0xFFFFFFFF, SCREEN_GAMMA, 0, 0); if (tmp) { if ((tmp->width != width) || (tmp->height != height)) { - fore_im = tile_asimage(fgVisual, tmp, 0, 0, width, height, 0, + fore_im = tile_asimage(bholder(), tmp, 0, 0, width, height, 0, ASA_ASImage, GetImageCompression(), GetImageQuality()); } destroy_asimage(&tmp); @@ -2614,7 +2622,7 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, layers[1].clip_width = fore_im->width; layers[1].clip_height = fore_im->height; - rendered_im = merge_layers(fgVisual, &(layers[0]), 2, rimg->width, rimg->height, + rendered_im = merge_layers(bholder(), &(layers[0]), 2, rimg->width, rimg->height, ASA_ASImage, GetImageCompression(), GetImageQuality()); destroy_asimage(&fore_im); From 01cdc458818c596c03270029d50a93fc9b7adb0b Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 14:23:35 +0100 Subject: [PATCH 4/9] [asimage] use new holder in most of drawing operations --- graf2d/asimage/src/TASImage.cxx | 60 +++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 4c349347ae5c4..0c6ba2773cd0a 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -3452,22 +3452,21 @@ void TASImage::Append(const TImage *im, const char *option, const char *color ) void TASImage::BeginPaint(Bool_t mode) { - if (!InitVisual()) { - Warning("BeginPaint", "Visual not initiated"); + if (!fImage) return; - } - - if (!fImage) { - return; - } fPaintMode = mode; - if (!fPaintMode || fImage->alt.argb32) { + if (!fPaintMode || fImage->alt.argb32) + return; + + auto vis = bholder(); + if (!vis) { + Warning("BeginPaint", "Visual not initiated"); return; } - ASImage *img = tile_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, + ASImage *img = tile_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, 0, ASA_ARGB32, 0, ASIMAGE_QUALITY_DEFAULT); if (!img) { @@ -3489,9 +3488,10 @@ void TASImage::EndPaint() return; } - if (!fImage->alt.argb32) return; + if (!fImage->alt.argb32) + return; - ASImage *img = tile_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, + ASImage *img = tile_asimage(bholder(), fImage, 0, 0, fImage->width, fImage->height, 0, ASA_ASImage, 0, ASIMAGE_QUALITY_DEFAULT); if (!img) { @@ -3591,7 +3591,13 @@ UInt_t *TASImage::GetScanline(UInt_t y) return nullptr; } - ASImageDecoder *imdec = start_image_decoding(fgVisual, img, SCL_DO_ALL, + auto vis = bholder(); + if (!vis) { + Warning("GetScanline", "no visual"); + return nullptr; + } + + ASImageDecoder *imdec = start_image_decoding(vis, img, SCL_DO_ALL, 0, y, img->width, 1, nullptr); if (!imdec) { @@ -3682,7 +3688,7 @@ void TASImage::FillRectangleInternal(UInt_t col, Int_t x, Int_t y, UInt_t width, height = y + height > fImage->height ? fImage->height - y : height; if (!fImage->alt.argb32) { - fill_asimage(fgVisual, fImage, x, y, width, height, color); + fill_asimage(bholder(), fImage, x, y, width, height, color); } else { int yyy = y*fImage->width; if (!has_alpha) { // use faster memset @@ -5782,7 +5788,8 @@ void TASImage::CreateThumbnail() return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("CreateThumbnail", "Visual not initiated"); return; } @@ -5802,7 +5809,7 @@ void TASImage::CreateThumbnail() w = w < 8 ? 8 : w; h = h < 8 ? 8 : h; - img = scale_asimage(fgVisual, fImage, w, h, ASA_ASImage, + img = scale_asimage(vis, fImage, w, h, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (!img) { return; @@ -5824,7 +5831,7 @@ void TASImage::CreateThumbnail() layers[1].clip_width = img->width; layers[1].clip_height = img->height; layers[1].merge_scanlines = blend_scanlines_name2func("tint"); - rendered_im = merge_layers(fgVisual, &(layers[0]), 2, img->width, img->height, + rendered_im = merge_layers(vis, &(layers[0]), 2, img->width, img->height, ASA_ASImage, GetImageCompression(), GetImageQuality()); destroy_asimage(&img); img = rendered_im; @@ -5835,11 +5842,11 @@ void TASImage::CreateThumbnail() if (w == sz) { d = (sz - h) >> 1; - padimg = pad_asimage(fgVisual, img, 0, d, sz, sz, 0x00ffffff, + padimg = pad_asimage(vis, img, 0, d, sz, sz, 0x00ffffff, ASA_ASImage, GetImageCompression(), GetImageQuality()); } else { d = (sz - w) >> 1; - padimg = pad_asimage(fgVisual, img, d, 0, sz, sz, 0x00ffffff, + padimg = pad_asimage(vis, img, d, 0, sz, sz, 0x00ffffff, ASA_ASImage, GetImageCompression(), GetImageQuality()); } @@ -6234,7 +6241,8 @@ void TASImage::Gray(Bool_t on) return; } - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Gray", "Visual not initiated"); return; } @@ -6260,7 +6268,7 @@ void TASImage::Gray(Bool_t on) UInt_t i, j; if (fImage->alt.argb32) { - fGrayImage = tile_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, + fGrayImage = tile_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, 0, ASA_ARGB32, 0, ASIMAGE_QUALITY_DEFAULT); for (i = 0; i < fImage->height; i++) { @@ -6278,7 +6286,7 @@ void TASImage::Gray(Bool_t on) } else { fGrayImage = create_asimage(fImage->width, fImage->height, 0); - ASImageDecoder *imdec = start_image_decoding(fgVisual, fImage, SCL_DO_ALL, + ASImageDecoder *imdec = start_image_decoding(vis, fImage, SCL_DO_ALL, 0, 0, fImage->width, fImage->height, nullptr); if (!imdec) { @@ -6287,7 +6295,7 @@ void TASImage::Gray(Bool_t on) #ifdef HAVE_MMX mmx_init(); #endif - ASImageOutput *imout = start_image_output(fgVisual, fGrayImage, ASA_ASImage, + ASImageOutput *imout = start_image_output(vis, fGrayImage, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (!imout) { Warning("ToGray", "Failed to start image output"); @@ -6302,7 +6310,7 @@ void TASImage::Gray(Bool_t on) CARD32 *bb = imdec->buffer.blue; ASScanline result; - prepare_scanline(fImage->width, 0, &result, fgVisual->BGR_mode); + prepare_scanline(fImage->width, 0, &result, vis->BGR_mode); for (i = 0; i < fImage->height; i++) { imdec->decode_image_scanline(imdec); @@ -6421,10 +6429,12 @@ void TASImage::FromGradient(ASGradient *as_gradient, UInt_t width, UInt_t height DestroyImage(); DestroyScaledImage(); - if (!InitVisual()) + auto vis = bholder(); + + if (!vis) Warning("FromGradient", "Visual not initiated"); else - fImage = make_gradient(fgVisual, as_gradient, width, height, SCL_DO_COLOR, ASA_ARGB32, 0, GetImageQuality()); + fImage = make_gradient(vis, as_gradient, width, height, SCL_DO_COLOR, ASA_ARGB32, 0, GetImageQuality()); } From 489b7621f1d338d22e60ad955a37dccb99bfcb23 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 14:33:34 +0100 Subject: [PATCH 5/9] [asimage] use new holder in all other not-deprecated methods --- graf2d/asimage/src/TASImage.cxx | 79 +++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 0c6ba2773cd0a..0b72916b87a9d 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -1243,6 +1243,7 @@ void TASImage::Draw(Option_t *option) } //////////////////////////////////////////////////////////////////////////////// +/// DEPRECATED. Will be removed in ROOT7. Use TASUtils::PaintImage() instead /// Draw asimage on drawable. void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, @@ -2655,14 +2656,16 @@ void TASImage::DrawText(Int_t x, Int_t y, const char *text, Int_t size, void TASImage::Merge(const TImage *im, const char *op, Int_t x, Int_t y) { - if (!im) return; + auto asimg = dynamic_cast(im); + if (!asimg) + return; - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Merge", "Visual not initiated"); return; } - ASImage *rendered_im; ASImageLayer layers[2]; init_image_layers(&(layers[0]), 2); @@ -2672,15 +2675,15 @@ void TASImage::Merge(const TImage *im, const char *op, Int_t x, Int_t y) layers[0].clip_width = fImage->width; layers[0].clip_height = fImage->height; layers[0].bevel = nullptr; - layers[1].im = ((TASImage*)im)->fImage; + layers[1].im = asimg->fImage; layers[1].dst_x = x; layers[1].dst_y = y; - layers[1].clip_width = im->GetWidth(); - layers[1].clip_height = im->GetHeight(); + layers[1].clip_width = asimg->GetWidth(); + layers[1].clip_height = asimg->GetHeight(); layers[1].merge_scanlines = blend_scanlines_name2func(op ? op : "add"); - rendered_im = merge_layers(fgVisual, &(layers[0]), 2, fImage->width, fImage->height, - ASA_ASImage, GetImageCompression(), GetImageQuality()); + ASImage *rendered_im = merge_layers(vis, &(layers[0]), 2, fImage->width, fImage->height, + ASA_ASImage, GetImageCompression(), GetImageQuality()); DestroyImage(); fImage = rendered_im; @@ -2694,7 +2697,8 @@ void TASImage::Merge(const TImage *im, const char *op, Int_t x, Int_t y) void TASImage::Blur(Double_t hr, Double_t vr) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Blur", "Visual not initiated"); return; } @@ -2707,10 +2711,10 @@ void TASImage::Blur(Double_t hr, Double_t vr) return; } - fill_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); + fill_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); } - ASImage *rendered_im = blur_asimage_gauss(fgVisual, fImage, hr > 0 ? hr : 3, + ASImage *rendered_im = blur_asimage_gauss(vis, fImage, hr > 0 ? hr : 3, vr > 0 ? vr : 3, SCL_DO_ALL, ASA_ASImage, GetImageCompression(), GetImageQuality()); DestroyImage(); @@ -2744,7 +2748,8 @@ TObject *TASImage::Clone(const char *newname) const Double_t *TASImage::Vectorize(UInt_t max_colors, UInt_t dither, Int_t opaque_threshold) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Vectorize", "Visual not initiated"); return nullptr; } @@ -2757,16 +2762,15 @@ Double_t *TASImage::Vectorize(UInt_t max_colors, UInt_t dither, Int_t opaque_thr return nullptr; } - fill_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); + fill_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); } ASColormap cmap; - int *res; - UInt_t r=0, g=0, b=0; + UInt_t r = 0, g = 0, b = 0; dither = dither > 7 ? 7 : dither; - res = colormap_asimage(fImage, &cmap, max_colors, dither, opaque_threshold); + int *res = colormap_asimage(fImage, &cmap, max_colors, dither, opaque_threshold); Double_t *vec = new Double_t[fImage->height*fImage->width]; UInt_t v; @@ -2813,7 +2817,8 @@ Double_t *TASImage::Vectorize(UInt_t max_colors, UInt_t dither, Int_t opaque_thr fImage->alt.vector = vec; UnZoom(); // ROOT-7647: res is allocated with `safemalloc` by colormap_asimage - if (res) safefree(res); + if (res) + safefree(res); return (Double_t*)fImage->alt.vector; } @@ -2858,8 +2863,9 @@ Double_t *TASImage::Vectorize(UInt_t max_colors, UInt_t dither, Int_t opaque_thr void TASImage::HSV(UInt_t hue, UInt_t radius, Int_t H, Int_t S, Int_t V, Int_t x, Int_t y, UInt_t width, UInt_t height) { - if (!InitVisual()) { - Warning("HSV", "Visual not initiated"); + auto vis = bholder(); + if (!vis) { + Warning("HSV", "Visual not initiated"); return; } @@ -2873,7 +2879,7 @@ void TASImage::HSV(UInt_t hue, UInt_t radius, Int_t H, Int_t S, Int_t V, x = 0; y = 0; - fill_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); + fill_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); } width = !width ? fImage->width : width; @@ -2882,7 +2888,7 @@ void TASImage::HSV(UInt_t hue, UInt_t radius, Int_t H, Int_t S, Int_t V, ASImage *rendered_im = nullptr; if (H || S || V) { - rendered_im = adjust_asimage_hsv(fgVisual, fImage, x, y, width, height, + rendered_im = adjust_asimage_hsv(vis, fImage, x, y, width, height, hue, radius, H, S, V, ASA_ASImage, 100, ASIMAGE_QUALITY_TOP); } @@ -2921,10 +2927,12 @@ void TASImage::HSV(UInt_t hue, UInt_t radius, Int_t H, Int_t S, Int_t V, /// \param[in] y y position coordinate /// \param[in] width image width, if 0, it will be read from fImage /// \param[in] height image height, if 0, it will be read from fImage + void TASImage::Gradient(UInt_t angle, const char *colors, const char *offsets, Int_t x, Int_t y, UInt_t width, UInt_t height) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Gradient", "Visual not initiated"); return; } @@ -3048,7 +3056,7 @@ void TASImage::Gradient(UInt_t angle, const char *colors, const char *offsets, gradient.offset[i] = 1.0 - gradient.offset[i]; } } - rendered_im = make_gradient(fgVisual, &gradient, width, height, SCL_DO_ALL, + rendered_im = make_gradient(vis, &gradient, width, height, SCL_DO_ALL, ASA_ASImage, GetImageCompression(), GetImageQuality()); delete [] gradient.color; @@ -3081,7 +3089,7 @@ void TASImage::Gradient(UInt_t angle, const char *colors, const char *offsets, layers[1].clip_height = height; layers[1].merge_scanlines = alphablend_scanlines; - ASImage *merge_im = merge_layers(fgVisual, &(layers[0]), 2, fImage->width, fImage->height, + ASImage *merge_im = merge_layers(vis, &(layers[0]), 2, fImage->width, fImage->height, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (!merge_im) { Warning("Gradient", "Failed to create merged image"); @@ -3165,7 +3173,8 @@ void TASImage::Bevel(Int_t x, Int_t y, UInt_t width, UInt_t height, const char *hi_color, const char *lo_color, UShort_t thick, Bool_t reverse) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Bevel", "Visual not initiated"); return; } @@ -3223,7 +3232,7 @@ void TASImage::Bevel(Int_t x, Int_t y, UInt_t width, UInt_t height, x = 0; y = 0; - fill_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, fill); + fill_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, fill); } width = !width ? fImage->width : width; @@ -3249,7 +3258,7 @@ void TASImage::Bevel(Int_t x, Int_t y, UInt_t width, UInt_t height, } layers[1].im = bevel_im; - fill_asimage(fgVisual, bevel_im, 0, 0, w, h, fill); + fill_asimage(vis, bevel_im, 0, 0, w, h, fill); layers[1].dst_x = x; layers[1].dst_y = y; @@ -3258,7 +3267,7 @@ void TASImage::Bevel(Int_t x, Int_t y, UInt_t width, UInt_t height, layers[1].bevel = &bevel; layers[1].merge_scanlines = alphablend_scanlines; - merge_im = merge_layers(fgVisual, &(layers[0]), 2, fImage->width, fImage->height, + merge_im = merge_layers(vis, &(layers[0]), 2, fImage->width, fImage->height, ASA_ASImage, GetImageCompression(), GetImageQuality()); destroy_asimage(&bevel_im); @@ -3282,7 +3291,8 @@ void TASImage::Pad(const char *col, UInt_t l, UInt_t r, UInt_t t, UInt_t b) Int_t x, y; UInt_t w, h; - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Pad", "Visual not initiated"); return; } @@ -3295,7 +3305,7 @@ void TASImage::Pad(const char *col, UInt_t l, UInt_t r, UInt_t t, UInt_t b) return; } - fill_asimage(fgVisual, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); + fill_asimage(vis, fImage, 0, 0, fImage->width, fImage->height, ARGB32_White); } ARGB32 color = ARGB32_White; @@ -3306,7 +3316,7 @@ void TASImage::Pad(const char *col, UInt_t l, UInt_t r, UInt_t t, UInt_t b) w = l + fImage->width + r; h = t + fImage->height + b; - ASImage *img = pad_asimage(fgVisual, fImage, x, y, w, h, color, + ASImage *img = pad_asimage(vis, fImage, x, y, w, h, color, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (!img) { @@ -3326,7 +3336,8 @@ void TASImage::Pad(const char *col, UInt_t l, UInt_t r, UInt_t t, UInt_t b) void TASImage::Crop(Int_t x, Int_t y, UInt_t width, UInt_t height) { - if (!InitVisual()) { + auto vis = bholder(); + if (!vis) { Warning("Crop", "Visual not initiated"); return; } @@ -3352,7 +3363,7 @@ void TASImage::Crop(Int_t x, Int_t y, UInt_t width, UInt_t height) return; } - ASImageDecoder *imdec = start_image_decoding(fgVisual, fImage, SCL_DO_ALL, + ASImageDecoder *imdec = start_image_decoding(vis, fImage, SCL_DO_ALL, x, y, width, height, nullptr); if (!imdec) { @@ -3368,7 +3379,7 @@ void TASImage::Crop(Int_t x, Int_t y, UInt_t width, UInt_t height) return; } - ASImageOutput *imout = start_image_output(fgVisual, img, ASA_ASImage, + ASImageOutput *imout = start_image_output(vis, img, ASA_ASImage, GetImageCompression(), GetImageQuality()); if (!imout) { From 73e4a716c3438d88086af8ae17cad7b4e7d8d208 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 14:41:21 +0100 Subject: [PATCH 6/9] [asimg] use InitVisual only in deprecated methods --- graf2d/asimage/src/TASImage.cxx | 49 ++++++++------------------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 0b72916b87a9d..13b79c7bcd465 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -539,11 +539,6 @@ const char *TASImage::TypeFromMagicNumber(const char *file) void TASImage::ReadImage(const char *filename, EImageFileTypes /*type*/) { - if (!InitVisual()) { - Warning("ReadImage", "Visual not initiated"); - return; - } - Bool_t xpm = filename && (filename[0] == '/' && filename[1] == '*') && filename[2] == ' '; @@ -1135,11 +1130,6 @@ void TASImage::FromPad(TVirtualPad *pad, Int_t /* x */, Int_t /* y */, UInt_t /* return; } - if (!InitVisual()) { - Warning("FromPad", "Visual not initiated"); - return; - } - SetName(pad->GetName()); DestroyImage(); @@ -3420,12 +3410,8 @@ void TASImage::Crop(Int_t x, Int_t y, UInt_t width, UInt_t height) void TASImage::Append(const TImage *im, const char *option, const char *color ) { - if (!im) return; - - if (!InitVisual()) { - Warning("Append", "Visual not initiated"); + if (!im) return; - } if (!fImage) { // if image not exists - just clone data from source image @@ -3734,16 +3720,10 @@ void TASImage::FillRectangleInternal(UInt_t col, Int_t x, Int_t y, UInt_t width, void TASImage::FillRectangle(const char *col, Int_t x, Int_t y, UInt_t width, UInt_t height) { - if (!InitVisual()) { - Warning("FillRectangle", "Visual not initiated"); - return; - } - ARGB32 color = ARGB32_White; - if (col) { + if (col) parse_argb_color(col, &color); - } if (!fImage) { fImage = create_asimage(width ? width : 20, height ? height : 20, 0); @@ -3996,11 +3976,6 @@ void TASImage::DrawLineInternal(UInt_t x1, UInt_t y1, UInt_t x2, UInt_t y2, void TASImage::DrawRectangle(UInt_t x, UInt_t y, UInt_t w, UInt_t h, const char *col, UInt_t thick) { - if (!InitVisual()) { - Warning("DrawRectangle", "Visual not initiated"); - return; - } - if (!fImage) { w = w ? w : 20; h = h ? h : 20; @@ -4847,18 +4822,16 @@ void TASImage::CropSpans(UInt_t npt, TPoint *ppt, UInt_t *widths) void TASImage::CopyArea(TImage *dst, Int_t xsrc, Int_t ysrc, UInt_t w, UInt_t h, Int_t xdst, Int_t ydst, Int_t gfunc, EColorChan) { - if (!InitVisual()) { - Warning("CopyArea", "Visual not initiated"); - return; - } - if (!fImage) { Warning("CopyArea", "no image"); return; } - if (!dst) return; - ASImage *out = ((TASImage*)dst)->GetImage(); + auto dstimg = dynamic_cast (dst); + if (!dstimg) + return; + + ASImage *out = dstimg->GetImage(); int x = 0; int y = 0; @@ -4873,12 +4846,12 @@ void TASImage::CopyArea(TImage *dst, Int_t xsrc, Int_t ysrc, UInt_t w, UInt_t h h = ysrc + h > fImage->height ? fImage->height - ysrc : h; UInt_t yy = (ysrc + y)*fImage->width; - if (!fImage->alt.argb32) { + if (!fImage->alt.argb32) BeginPaint(); - } + if (!out->alt.argb32) { - dst->BeginPaint(); - out = ((TASImage*)dst)->GetImage(); + dstimg->BeginPaint(); + out = dstimg->GetImage(); } if (fImage->alt.argb32 && out->alt.argb32) { From 49d976905644f75bd12ba0dbaac004563ddfad48 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 15:39:45 +0100 Subject: [PATCH 7/9] [asimage] remove all global fgVisual-related pointer Static method InitVisual() holds own static pointer, which returned from the method. All methods where InitVisual() is used are deprecated, correspondent docu refer also on alternative methods from TASUtils which can be used. --- graf2d/asimage/inc/TASImage.h | 9 +-- graf2d/asimage/src/TASImage.cxx | 104 ++++++++++++++++---------------- 2 files changed, 55 insertions(+), 58 deletions(-) diff --git a/graf2d/asimage/inc/TASImage.h b/graf2d/asimage/inc/TASImage.h index d14af09359688..78b0e54086b24 100644 --- a/graf2d/asimage/inc/TASImage.h +++ b/graf2d/asimage/inc/TASImage.h @@ -78,16 +78,11 @@ friend class TASUtils; // to implement gVirtualX-specific methods Bool_t fIsGray; ///dpy was set to nullptr - EImageFileTypes GetFileType(const char *ext); void MapFileTypes(EImageFileTypes &type, UInt_t &astype, Bool_t toas = kTRUE); void MapQuality(EImageQuality &quality, UInt_t &asquality, Bool_t toas = kTRUE); - static ASVisual *InitVisual(Bool_t plain = kFALSE); + static ASVisual *InitVisual(); Bool_t InitImage(const char *caller); void FromGradient(struct ASGradient *as_gradient, UInt_t width, UInt_t height); @@ -218,7 +213,7 @@ friend class TASUtils; // to implement gVirtualX-specific methods void SetPaletteEnabled(Bool_t on = kTRUE) override; // *TOGGLE* void SavePrimitive(std::ostream &out, Option_t *option = "") override; - static const ASVisual *GetVisual(); + static const ASVisual * R__DEPRECATED(7,00, "No longer provided") GetVisual(); static UInt_t AlphaBlend(UInt_t bot, UInt_t top); static void Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, Int_t xsrc = 0, Int_t ysrc = 0, UInt_t wsrc = 0, UInt_t hsrc = 0, Option_t *opt = ""); diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 13b79c7bcd465..debf7376759f0 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -116,11 +116,6 @@ extern "C" { #include "TASPolyUtils.c" -ASVisual *TASImage::fgVisual = nullptr; -ASVisual *TASImage::fgBatchVisual = nullptr; -Bool_t TASImage::fgInit = kFALSE; -Bool_t TASImage::fgBatch = kFALSE; - static unsigned long kAllPlanes = ~0; THashTable *TASImage::fgPlugList = new THashTable(50); @@ -267,9 +262,11 @@ void TASImage::SetDefaults() fIsGray = kFALSE; fPaletteEnabled = kFALSE; + static bool fgInit = false; + if (!fgInit) { set_application_name((char*)(gProgName ? gProgName : "ROOT")); - fgInit = kTRUE; + fgInit = true; } } @@ -1233,7 +1230,9 @@ void TASImage::Draw(Option_t *option) } //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED. Will be removed in ROOT7. Use TASUtils::PaintImage() instead +/// @deprecated +/// Will be removed in ROOT7. +/// Use TASUtils::PaintImage() instead /// Draw asimage on drawable. void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, @@ -1248,6 +1247,8 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, static int x11 = gVirtualX->InheritsFrom("TGX11"); + auto vis = InitVisual(); + Pixmap_t mask = kNone; if (x11) { @@ -1259,7 +1260,7 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, std::vector bits(ww*hh); //an array of bits - ASImageDecoder *imdec = start_image_decoding(fgVisual, im, SCL_DO_ALPHA, + ASImageDecoder *imdec = start_image_decoding(vis, im, SCL_DO_ALPHA, xsrc, ysrc, ww, 0, nullptr); if (imdec) { for (UInt_t yy = 0; yy < hh; yy++) { @@ -1302,12 +1303,12 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, } if (x11) { //use built-in optimized version - asimage2drawable(fgVisual, wid, im, (GC)gc, xsrc, ysrc, x, y, wsrc, hsrc, 1); + asimage2drawable(vis, wid, im, (GC)gc, xsrc, ysrc, x, y, wsrc, hsrc, 1); } else { ASImage *img = nullptr; unsigned char *bits = (unsigned char *)im->alt.argb32; if (!bits) { - img = tile_asimage(fgVisual, im, xsrc, ysrc, wsrc, hsrc, + img = tile_asimage(vis, im, xsrc, ysrc, wsrc, hsrc, 0, ASA_ARGB32, 0, ASIMAGE_QUALITY_DEFAULT); if (img) bits = (unsigned char *)img->alt.argb32; @@ -2100,22 +2101,21 @@ void TASImage::GetZoomPosition(UInt_t &x, UInt_t &y, UInt_t &w, UInt_t &h) const } //////////////////////////////////////////////////////////////////////////////// +/// @deprecated +/// Will be removed in ROOT7 /// Static internal method to initialize the ASVisual -/// Many operations do not require X11 display so plain "batch" visual can be used -ASVisual *TASImage::InitVisual(Bool_t plain) +ASVisual *TASImage::InitVisual() { - // this is new API, means return value must be used - if (fgBatchVisual && plain) - return fgBatchVisual; + Bool_t noX = gROOT->IsBatch() || !gVirtualX->InheritsFrom("TGX11"); - Bool_t noX = plain || gROOT->IsBatch() || !gVirtualX->InheritsFrom("TGX11"); + if (noX) + return bholder(); - if (fgVisual && !noX && !fgBatch) - return fgVisual; + static ASVisual *gVis = nullptr; - fgVisual = nullptr; - fgBatch = false; + if (gVis) + return gVis; #ifndef WIN32 #ifndef R__HAS_COCOA @@ -2125,28 +2125,16 @@ ASVisual *TASImage::InitVisual(Bool_t plain) Visual *vis = (Visual*) gVirtualX->GetVisual(); Colormap cmap = (Colormap) gVirtualX->GetColormap(); - static ASVisual *vis_x = nullptr; - - if (vis && cmap && !noX) { - if (!vis_x) - vis_x = create_asvisual_for_id(disp, screen, depth, + if (vis && cmap) + gVis = create_asvisual_for_id(disp, screen, depth, XVisualIDFromVisual(vis), cmap, nullptr); - fgVisual = vis_x; - } #endif #endif - if (!fgVisual) { - if (!fgBatchVisual) { - // create dummy visual for batch mode - fgBatchVisual = create_asvisual(nullptr, 0, 0, nullptr); - fgBatchVisual->dpy = nullptr; // fake (not used) - } - fgVisual = fgBatchVisual; - fgBatch = true; - } + if (gVis) + return gVis; - return fgVisual; + return bholder(); } //////////////////////////////////////////////////////////////////////////////// @@ -2194,13 +2182,17 @@ void TASImage::StartPaletteEditor() //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED. Method left for backward compatibility and will be removed in ROOT7! +/// @deprecated +/// Method left for backward compatibility and will be removed in ROOT7! +/// Use TASUtils::GetPixmap() instead /// Returns image pixmap. /// The pixmap must deleted by user. Pixmap_t TASImage::GetPixmap() { - if (!InitVisual()) { + auto vis = InitVisual(); + + if (!vis) { Warning("GetPixmap", "Visual not initiated"); return 0; } @@ -2210,7 +2202,7 @@ Pixmap_t TASImage::GetPixmap() if (x11) { ASImage *img = fScaledImage ? fScaledImage->fImage : fImage; - return (Pixmap_t)asimage2pixmap(fgVisual, gVirtualX->GetDefaultRootWindow(), img, nullptr, kTRUE); + return (Pixmap_t)asimage2pixmap(vis, gVirtualX->GetDefaultRootWindow(), img, nullptr, kTRUE); } auto argb = GetArgbArray(); @@ -2277,7 +2269,9 @@ Bool_t TASImage::GetMaskBits(UInt_t &width, UInt_t &height, std::vector &b } //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED! Method left for backward compatibility and will be removed in ROOT7! +/// @deprecated +/// Method left for backward compatibility and will be removed in ROOT7! +/// Use TASUtils::GetMask instead /// Returns image mask pixmap (alpha channel). /// The pixmap must deleted by user. @@ -2294,12 +2288,15 @@ Pixmap_t TASImage::GetMask() } //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED. Method left for backward compatibility and will be removed in ROOT7! +/// @deprecated +/// Method left for backward compatibility and will be removed in ROOT7! +/// Use Use TASUtils::FromPixmap() instead /// Create image from pixmap. void TASImage::SetImage(Pixmap_t pxm, Pixmap_t mask) { - if (!InitVisual()) { + auto vis = InitVisual(); + if (!vis) { Warning("SetImage", "Visual not initiated"); return; } @@ -2317,7 +2314,7 @@ void TASImage::SetImage(Pixmap_t pxm, Pixmap_t mask) static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); if (x11) { //use built-in optimized version - fImage = picture2asimage(fgVisual, pxm, mask, 0, 0, w, h, kAllPlanes, 1, 0); + fImage = picture2asimage(vis, pxm, mask, 0, 0, w, h, kAllPlanes, 1, 0); } else { unsigned char *bits = gVirtualX->GetColorBits(pxm, 0, 0, w, h); if (!bits) { // error @@ -4969,11 +4966,13 @@ UInt_t TASImage::AlphaBlend(UInt_t bot, UInt_t top) } //////////////////////////////////////////////////////////////////////////////// +/// @deprecated +/// Will be removed in ROOT7 /// Return visual. const ASVisual *TASImage::GetVisual() { - return fgVisual; + return InitVisual(); } //////////////////////////////////////////////////////////////////////////////// @@ -6325,7 +6324,9 @@ void TASImage::Gray(Bool_t on) } //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED. Method left for backward compatibility and will be removed in ROOT7! +/// @deprecated +/// Method left for backward compatibility and will be removed in ROOT7! +/// Use TASUtils::FromWindow() instead /// Create an image (screenshot) from specified window. void TASImage::FromWindow(Drawable_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h) @@ -6352,7 +6353,8 @@ void TASImage::FromWindow(Drawable_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h) return; } - if (!InitVisual()) { + auto vis = InitVisual(); + if (!vis) { Warning("FromWindow", "Visual not initiated"); return; } @@ -6364,20 +6366,20 @@ void TASImage::FromWindow(Drawable_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h) if (x11 < 0) x11 = gVirtualX->InheritsFrom("TGX11"); if (x11) { //use built-in optimized version - fImage = pixmap2asimage(fgVisual, wid, x, y, w, h, kAllPlanes, 0, 0); + fImage = pixmap2asimage(vis, wid, x, y, w, h, kAllPlanes, 0, 0); } else { unsigned char *bits = gVirtualX->GetColorBits(wid, 0, 0, w, h); - if (!bits) { // error + if (!bits) // error return; - } fImage = bitmap2asimage(bits, w, h, 0, nullptr); delete [] bits; } } //////////////////////////////////////////////////////////////////////////////// -/// DEPRECATED. Method left for backward compatibility and will be removed in ROOT7! +/// @deprecated +/// Method left for backward compatibility and will be removed in ROOT7! /// Creates an image (screenshot) from a RGBA buffer provided by GL. void TASImage::FromGLBuffer(UChar_t* buf, UInt_t w, UInt_t h) From aa8dd5ef8010db064ed4f4786b9eee41715d1736 Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 16:13:26 +0100 Subject: [PATCH 8/9] [asutils] move ASVisual holder inside GetX11Visual method It will return not-null value only for X11-based disaplays in not-batch mode. In all other cases alternative methods should be used. Intention to move all asimage calls only inside TASImage class to avoid different linking side-effects observed on Windows --- graf2d/asimage/inc/TASUtils.h | 3 + graf2d/asimage/src/TASUtils.cxx | 131 +++++++++++--------------------- 2 files changed, 47 insertions(+), 87 deletions(-) diff --git a/graf2d/asimage/inc/TASUtils.h b/graf2d/asimage/inc/TASUtils.h index 90dbf6fb2bc57..0508e2b99f0e6 100644 --- a/graf2d/asimage/inc/TASUtils.h +++ b/graf2d/asimage/inc/TASUtils.h @@ -27,6 +27,9 @@ class TImage; class TASUtils { + + static struct ASVisual *GetX11Visual(); + public: static Pixmap_t GetPixmap(TImage *timg); static Pixmap_t GetMask(TImage *timg); diff --git a/graf2d/asimage/src/TASUtils.cxx b/graf2d/asimage/src/TASUtils.cxx index b368536361acc..8475ef1da8432 100644 --- a/graf2d/asimage/src/TASUtils.cxx +++ b/graf2d/asimage/src/TASUtils.cxx @@ -21,6 +21,11 @@ #include "TImage.h" +ASVisual *TASUtils::GetX11Visual() +{ + return nullptr; +} + Pixmap_t TASUtils::GetPixmap(TImage *) { @@ -79,18 +84,25 @@ std::unique_ptr TASUtils::FromPixmap(Pixmap_t, Pixmap_t) const unsigned long kAllPlanes = ~0; #endif -// Holder of ASVisual instance, destroyed when application closed -class ASVisualHolder { - ASVisual *fVisual = nullptr; +ASVisual *TASUtils::GetX11Visual() +{ +#ifndef X_DISPLAY_MISSING -public: + thread_local struct ASHolder { + ASVisual *fVisual = nullptr; + ~ASHolder() + { + if (fVisual) { + destroy_asvisual(fVisual, 0); + fVisual = nullptr; + } + } + } holder; - GContext_t fGC = 0; // context used in PaintImage + static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); - ASVisual *operator()() - { -#ifndef X_DISPLAY_MISSING - if (!fVisual) { + if (x11) { + if (!holder.fVisual) { Display *disp = (Display*) gVirtualX->GetDisplay(); Int_t screen = gVirtualX->GetScreen(); Int_t depth = gVirtualX->GetDepth(); @@ -98,34 +110,16 @@ class ASVisualHolder { Colormap cmap = (Colormap) gVirtualX->GetColormap(); if (vis && cmap) - fVisual = create_asvisual_for_id(disp, screen, depth, XVisualIDFromVisual(vis), cmap, nullptr); + holder.fVisual = create_asvisual_for_id(disp, screen, depth, XVisualIDFromVisual(vis), cmap, nullptr); } -#endif - if (!fVisual) { - fVisual = create_asvisual(nullptr, 0, 0, nullptr); - fVisual->dpy = nullptr; // fake (not used) - } - - return fVisual; + return holder.fVisual; } - ~ASVisualHolder() - { - if (fVisual) { - destroy_asvisual(fVisual, 0); - fVisual = nullptr; - } - if (fGC && gVirtualX) - gVirtualX->DeleteGC(fGC); - } -}; - -namespace { - -thread_local ASVisualHolder holder; - +#endif + return nullptr; } + //////////////////////////////////////////////////////////////////////////////// /// Returns image pixmap. /// The pixmap must deleted by user. @@ -138,30 +132,19 @@ Pixmap_t TASUtils::GetPixmap(TImage *timg) ::Error("TASUtils::GetPixmap", "Image not provided"); return 0; } - static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); - if (x11) { -#ifndef X_DISPLAY_MISSING + auto vis = GetX11Visual(); + + if (vis) { auto asimg = dynamic_cast(timg); if (!asimg) { ::Warning("TASUtils::GetPixmap", "ASImage not provided"); return 0; } - auto vis = holder(); - - if (!vis) { - ::Warning("TASUtils::GetPixmap", "Visual not initiated"); - return 0; - } - ASImage *img = asimg->fScaledImage ? asimg->fScaledImage->fImage : asimg->fImage; return (Pixmap_t)asimage2pixmap(vis, gVirtualX->GetDefaultRootWindow(), img, nullptr, kTRUE); -#else - ::Error("TASUtils::GetPixmap", "Invoke X11-specific methods on unsupported platform"); - return 0; -#endif } auto argb = timg->GetArgbArray(); @@ -213,21 +196,10 @@ Bool_t TASUtils::FillImageFromWindow(TImage *img, Window_t wid, Int_t width, Int gSystem->ProcessEvents(); } - static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); - - if (x11) { - auto vis = holder(); + auto vis = GetX11Visual(); - if (!vis) { - ::Error("TASUtils::FillImageFromWindow", "Visual not initiated"); - return kFALSE; - } - -#ifndef X_DISPLAY_MISSING + if (vis) { asimg->fImage = pixmap2asimage(vis, wid, 0, 0, width, height, kAllPlanes, 0, 0); -#else - ::Error("TASUtils::FillImageFromWindow", "Invoke X11-specific methods on unsupported platform"); -#endif } else { unsigned char *bits = gVirtualX->GetColorBits(wid, 0, 0, width, height); if (!bits) { @@ -278,19 +250,10 @@ std::unique_ptr TASUtils::FromPixmap(Pixmap_t pxm, Pixmap_t mask) asimg->SetName(TString::Format("img_%dx%d",w, h)); - if (gVirtualX->InheritsFrom("TGX11")) { //use built-in optimized version - auto vis = holder(); - - if (!vis) { - ::Warning("TASUtils::FromPixmap", "Visual not initiated"); - return nullptr; - } + auto vis = GetX11Visual(); -#ifndef X_DISPLAY_MISSING + if (vis) { //use built-in optimized version asimg->fImage = picture2asimage(vis, pxm, mask, 0, 0, w, h, kAllPlanes, 1, 0); -#else - ::Error("TASUtils::FromPixmap", "Invoke X11-specific methods on unsupported platform"); -#endif } else { unsigned char *bits = gVirtualX->GetColorBits(pxm, 0, 0, w, h); if (!bits) // error @@ -339,29 +302,21 @@ Bool_t TASUtils::PaintImage(TImage *timg, Drawable_t wid, Int_t x, Int_t y, Bool gv.fClipXOrigin = x; gv.fClipYOrigin = y; - if (!holder.fGC) { - holder.fGC = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &gv); - } else { - gVirtualX->ChangeGC(holder.fGC, &gv); - } + GContext_t fGC = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &gv); UInt_t width = asimg->GetScaledWidth(); UInt_t height = asimg->GetScaledHeight(); Bool_t res = kTRUE; - if (isX11) { //use built-in optimized version - #ifndef X_DISPLAY_MISSING + auto vis = GetX11Visual(); + + if (isX11 && vis) { //use built-in optimized version ASImage *im = asimg->fScaledImage ? asimg->fScaledImage->fImage : asimg->fImage; - auto vis = holder(); - if (vis && im) - asimage2drawable(vis, wid, im, (GC)holder.fGC, 0, 0, x, y, width, height, 1); + if (im) + asimage2drawable(vis, wid, im, (GC)fGC, 0, 0, x, y, width, height, 1); else res = kFALSE; - #else - ::Error("TASUtils::PaintImage", "Invoke X11-specific methods on unsupported platform"); - res = kFALSE; - #endif } else { auto argb = asimg->GetArgbArray(); @@ -372,7 +327,7 @@ Bool_t TASUtils::PaintImage(TImage *timg, Drawable_t wid, Int_t x, Int_t y, Bool SETBIT(width, 31); SETBIT(height, 31); } - gVirtualX->CopyArea(pic, wid, holder.fGC, 0, 0, width, height, x, y); + gVirtualX->CopyArea(pic, wid, fGC, 0, 0, width, height, x, y); gVirtualX->DeletePixmap(pic); } else res = kFALSE; @@ -384,8 +339,10 @@ Bool_t TASUtils::PaintImage(TImage *timg, Drawable_t wid, Int_t x, Int_t y, Bool gv.fMask = kGCClipMask; gv.fClipMask = kNone; - if (holder.fGC) - gVirtualX->ChangeGC(holder.fGC, &gv); + if (fGC) { + gVirtualX->ChangeGC(fGC, &gv); + gVirtualX->DeleteGC(fGC); + } return res; } From 79f74679ac6e656b5fffcb25c71d4eb8c874f87a Mon Sep 17 00:00:00 2001 From: Sergey Linev Date: Thu, 29 Oct 2026 16:25:00 +0100 Subject: [PATCH 9/9] [asutils] move all libAfterImage calls to ASImage Provide several static private methods for such redirection. Link libAfterImage only with TASImage class, trying to avoid any future conflicts with Windows linker Simultaneous link of same static library with two shared libraries can be a problem --- graf2d/asimage/CMakeLists.txt | 3 -- graf2d/asimage/inc/TASImage.h | 7 +++ graf2d/asimage/src/TASImage.cxx | 93 ++++++++++++++++++++++++++------- graf2d/asimage/src/TASUtils.cxx | 49 +++++------------ 4 files changed, 95 insertions(+), 57 deletions(-) diff --git a/graf2d/asimage/CMakeLists.txt b/graf2d/asimage/CMakeLists.txt index a0e3ea33e25ca..9610a02dfffe0 100644 --- a/graf2d/asimage/CMakeLists.txt +++ b/graf2d/asimage/CMakeLists.txt @@ -53,11 +53,8 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ASImageUtils Gpad ) - if(asimage) - target_link_libraries(ASImageUtils PRIVATE libAfterImage) - target_link_libraries(ASImageUtils PUBLIC ASImage) ROOT_STANDARD_LIBRARY_PACKAGE(ASImageGui diff --git a/graf2d/asimage/inc/TASImage.h b/graf2d/asimage/inc/TASImage.h index 78b0e54086b24..4ceb35fa369b2 100644 --- a/graf2d/asimage/inc/TASImage.h +++ b/graf2d/asimage/inc/TASImage.h @@ -87,6 +87,13 @@ friend class TASUtils; // to implement gVirtualX-specific methods void FromGradient(struct ASGradient *as_gradient, UInt_t width, UInt_t height); + static struct ASVisual *CreateX11Visual(Display_t display, Int_t screen, Int_t depth, Visual_t visual, Colormap_t cmap); + static void DestroyVisual(struct ASVisual *visual); + static Pixmap_t ASImage2Pixmap(struct ASVisual *visual, Window_t root_window, ASImage *image); + static ASImage *Pixmap2ASImage(struct ASVisual *visual, Window_t wid, Int_t x, Int_t y, UInt_t width, UInt_t height); + static ASImage *Picture2ASImage(struct ASVisual *visual, Pixmap_t pxm, Pixmap_t mask, UInt_t width, UInt_t height); + static void ASImage2Drawable(struct ASVisual *visual, ASImage *image, Drawable_t wid, GContext_t gc, Int_t xsrc, Int_t ysrc, Int_t x, Int_t y, UInt_t width, UInt_t height); + public: TASImage(); TASImage(UInt_t w, UInt_t h); diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index debf7376759f0..746019ecfc450 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -1303,7 +1303,7 @@ void TASImage::Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, } if (x11) { //use built-in optimized version - asimage2drawable(vis, wid, im, (GC)gc, xsrc, ysrc, x, y, wsrc, hsrc, 1); + ASImage2Drawable(vis, im, wid, gc, xsrc, ysrc, x, y, wsrc, hsrc); } else { ASImage *img = nullptr; unsigned char *bits = (unsigned char *)im->alt.argb32; @@ -2100,6 +2100,72 @@ void TASImage::GetZoomPosition(UInt_t &x, UInt_t &y, UInt_t &w, UInt_t &h) const h = fZoomHeight; } +//////////////////////////////////////////////////////////////////////////////// +/// Create ASVisual for X11 display +/// For internal use in TASUtils class + +ASVisual *TASImage::CreateX11Visual(Display_t display, Int_t screen, Int_t depth, Visual_t visual, Colormap_t cmap) +{ +#ifndef X_DISPLAY_MISSING + if (visual && cmap) + return create_asvisual_for_id((Display *)display, screen, depth, XVisualIDFromVisual((Visual *) visual), (Colormap) cmap, nullptr); +#else + (void)display; + (void)screen; + (void)depth; + (void)visual; + (void)cmap; +#endif + return nullptr; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Destroy ASVisual for X11 display +/// For internal use in TASUtils class + +void TASImage::DestroyVisual(ASVisual *visual) +{ + if (visual) + destroy_asvisual(visual, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Convert ASImage to pixmap for X11 +/// For internal use in TASUtils class + +Pixmap_t TASImage::ASImage2Pixmap(struct ASVisual *visual, Window_t root_window, ASImage *image) +{ + return (Pixmap_t)asimage2pixmap(visual, root_window, image, nullptr, kTRUE); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Convert region of X11 window to ASImage +/// For internal use in TASUtils class + +ASImage *TASImage::Pixmap2ASImage(struct ASVisual *visual, Window_t wid, Int_t x, Int_t y, UInt_t width, UInt_t height) +{ + return pixmap2asimage(visual, wid, x, y, width, height, kAllPlanes, 0, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Convert picture (X11 pixmap with mask) to ASImage +/// For internal use in TASUtils class + +ASImage *TASImage::Picture2ASImage(struct ASVisual *visual, Pixmap_t pxm, Pixmap_t mask, UInt_t width, UInt_t height) +{ + return picture2asimage(visual, pxm, mask, 0, 0, width, height, kAllPlanes, 1, 0); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Output ASImage on X11 drawable +/// For internal use in TASUtils class + +void TASImage::ASImage2Drawable(struct ASVisual *visual, ASImage *image, Drawable_t wid, GContext_t gc, Int_t xsrc, Int_t ysrc, Int_t x, Int_t y, UInt_t width, UInt_t height) +{ + asimage2drawable(visual, wid, image, (GC)gc, xsrc, ysrc, x, y, width, height, 1); +} + + //////////////////////////////////////////////////////////////////////////////// /// @deprecated /// Will be removed in ROOT7 @@ -2119,22 +2185,12 @@ ASVisual *TASImage::InitVisual() #ifndef WIN32 #ifndef R__HAS_COCOA - Display *disp = (Display*) gVirtualX->GetDisplay(); - Int_t screen = gVirtualX->GetScreen(); - Int_t depth = gVirtualX->GetDepth(); - Visual *vis = (Visual*) gVirtualX->GetVisual(); - Colormap cmap = (Colormap) gVirtualX->GetColormap(); - - if (vis && cmap) - gVis = create_asvisual_for_id(disp, screen, depth, - XVisualIDFromVisual(vis), cmap, nullptr); + gVis = CreateX11Visual(gVirtualX->GetDisplay(), gVirtualX->GetScreen(), gVirtualX->GetDepth(), + gVirtualX->GetVisual(), gVirtualX->GetColormap()); #endif #endif - if (gVis) - return gVis; - - return bholder(); + return gVis ? gVis : bholder(); } //////////////////////////////////////////////////////////////////////////////// @@ -2202,7 +2258,7 @@ Pixmap_t TASImage::GetPixmap() if (x11) { ASImage *img = fScaledImage ? fScaledImage->fImage : fImage; - return (Pixmap_t)asimage2pixmap(vis, gVirtualX->GetDefaultRootWindow(), img, nullptr, kTRUE); + return ASImage2Pixmap(vis, gVirtualX->GetDefaultRootWindow(), img); } auto argb = GetArgbArray(); @@ -2314,7 +2370,7 @@ void TASImage::SetImage(Pixmap_t pxm, Pixmap_t mask) static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); if (x11) { //use built-in optimized version - fImage = picture2asimage(vis, pxm, mask, 0, 0, w, h, kAllPlanes, 1, 0); + fImage = Picture2ASImage(vis, pxm, mask, w, h); } else { unsigned char *bits = gVirtualX->GetColorBits(pxm, 0, 0, w, h); if (!bits) { // error @@ -6362,11 +6418,10 @@ void TASImage::FromWindow(Drawable_t wid, Int_t x, Int_t y, UInt_t w, UInt_t h) DestroyImage(); DestroyScaledImage(); - static int x11 = -1; - if (x11 < 0) x11 = gVirtualX->InheritsFrom("TGX11"); + static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); if (x11) { //use built-in optimized version - fImage = pixmap2asimage(vis, wid, x, y, w, h, kAllPlanes, 0, 0); + fImage = Pixmap2ASImage(vis, wid, x, y, w, h); } else { unsigned char *bits = gVirtualX->GetColorBits(wid, 0, 0, w, h); diff --git a/graf2d/asimage/src/TASUtils.cxx b/graf2d/asimage/src/TASUtils.cxx index 8475ef1da8432..ee449d3835dc8 100644 --- a/graf2d/asimage/src/TASUtils.cxx +++ b/graf2d/asimage/src/TASUtils.cxx @@ -67,33 +67,17 @@ std::unique_ptr TASUtils::FromPixmap(Pixmap_t, Pixmap_t) #include "TASImage.h" -#ifdef WIN32 -#define X_DISPLAY_MISSING 1 -#include "Windows4root.h" -#else -#ifdef R__HAS_COCOA -#define X_DISPLAY_MISSING 1 -#endif -#endif - -#include "afterbase.h" -#include "afterimage.h" -#include "bmp.h" - -#ifndef X_DISPLAY_MISSING -const unsigned long kAllPlanes = ~0; -#endif - ASVisual *TASUtils::GetX11Visual() { -#ifndef X_DISPLAY_MISSING +#ifndef WIN32 +#ifndef R__HAS_COCOA thread_local struct ASHolder { ASVisual *fVisual = nullptr; ~ASHolder() { if (fVisual) { - destroy_asvisual(fVisual, 0); + TASImage::DestroyVisual(fVisual); fVisual = nullptr; } } @@ -102,19 +86,14 @@ ASVisual *TASUtils::GetX11Visual() static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); if (x11) { - if (!holder.fVisual) { - Display *disp = (Display*) gVirtualX->GetDisplay(); - Int_t screen = gVirtualX->GetScreen(); - Int_t depth = gVirtualX->GetDepth(); - Visual *vis = (Visual*) gVirtualX->GetVisual(); - Colormap cmap = (Colormap) gVirtualX->GetColormap(); - - if (vis && cmap) - holder.fVisual = create_asvisual_for_id(disp, screen, depth, XVisualIDFromVisual(vis), cmap, nullptr); - } + if (!holder.fVisual) + holder.fVisual = + TASImage::CreateX11Visual(gVirtualX->GetDisplay(), gVirtualX->GetScreen(), gVirtualX->GetDepth(), + gVirtualX->GetVisual(), gVirtualX->GetColormap()); return holder.fVisual; } +#endif #endif return nullptr; } @@ -144,7 +123,7 @@ Pixmap_t TASUtils::GetPixmap(TImage *timg) ASImage *img = asimg->fScaledImage ? asimg->fScaledImage->fImage : asimg->fImage; - return (Pixmap_t)asimage2pixmap(vis, gVirtualX->GetDefaultRootWindow(), img, nullptr, kTRUE); + return TASImage::ASImage2Pixmap(vis, gVirtualX->GetDefaultRootWindow(), img); } auto argb = timg->GetArgbArray(); @@ -182,7 +161,7 @@ Pixmap_t TASUtils::GetMask(TImage *img) Bool_t TASUtils::FillImageFromWindow(TImage *img, Window_t wid, Int_t width, Int_t height) { auto asimg = dynamic_cast (img); - if (!asimg) + if (!asimg || (width < 0) || (height < 0)) return kFALSE; asimg->DestroyImage(); @@ -199,7 +178,7 @@ Bool_t TASUtils::FillImageFromWindow(TImage *img, Window_t wid, Int_t width, Int auto vis = GetX11Visual(); if (vis) { - asimg->fImage = pixmap2asimage(vis, wid, 0, 0, width, height, kAllPlanes, 0, 0); + asimg->fImage = TASImage::Pixmap2ASImage(vis, wid, 0, 0, width, height); } else { unsigned char *bits = gVirtualX->GetColorBits(wid, 0, 0, width, height); if (!bits) { @@ -253,7 +232,7 @@ std::unique_ptr TASUtils::FromPixmap(Pixmap_t pxm, Pixmap_t mask) auto vis = GetX11Visual(); if (vis) { //use built-in optimized version - asimg->fImage = picture2asimage(vis, pxm, mask, 0, 0, w, h, kAllPlanes, 1, 0); + asimg->fImage = TASImage::Picture2ASImage(vis, pxm, mask, w, h); } else { unsigned char *bits = gVirtualX->GetColorBits(pxm, 0, 0, w, h); if (!bits) // error @@ -314,7 +293,7 @@ Bool_t TASUtils::PaintImage(TImage *timg, Drawable_t wid, Int_t x, Int_t y, Bool if (isX11 && vis) { //use built-in optimized version ASImage *im = asimg->fScaledImage ? asimg->fScaledImage->fImage : asimg->fImage; if (im) - asimage2drawable(vis, wid, im, (GC)fGC, 0, 0, x, y, width, height, 1); + TASImage::ASImage2Drawable(vis, im, wid, fGC, 0, 0, x, y, width, height); else res = kFALSE; } else { @@ -347,4 +326,4 @@ Bool_t TASUtils::PaintImage(TImage *timg, Drawable_t wid, Int_t x, Int_t y, Bool return res; } -#endif // NO_ASIMAGE \ No newline at end of file +#endif // NO_ASIMAGE