From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#38109: Updated Emacs to HEAD, consistently not scaling now Date: Sun, 24 Nov 2019 17:26:12 +0000 Message-ID: <20191124172612.GA5665@breton.holly.idiocy.org> References: <8736ew1zp0.fsf@tullinup.koldfront.dk> <87sgmwvgmd.fsf@tullinup.koldfront.dk> <87d0e0ve29.fsf@tullinup.koldfront.dk> <20191110171241.GA60416@breton.holly.idiocy.org> <875zjj4vb7.fsf@tullinup.koldfront.dk> <20191117172208.GA63158@breton.holly.idiocy.org> <87tv72bbuz.fsf@tullinup.koldfront.dk> <87pnhq5odn.fsf@tullinup.koldfront.dk> <20191117190105.GB63158@breton.holly.idiocy.org> <87blt38no5.fsf@tullinup.koldfront.dk> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="bp/iNruPH9dso1Pn" Content-Transfer-Encoding: 8bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="119772"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mutt/1.12.0 (2019-05-25) Cc: 38109@debbugs.gnu.org To: Adam =?UTF-8?Q?Sj=C3=B8gren?= Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Nov 25 14:30:15 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iZERR-000Uzt-AI for geb-bug-gnu-emacs@m.gmane.org; Mon, 25 Nov 2019 14:30:13 +0100 Original-Received: from localhost ([::1]:43954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iZERQ-000586-6r for geb-bug-gnu-emacs@m.gmane.org; Mon, 25 Nov 2019 08:30:12 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42782) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iZERJ-00057u-2b for bug-gnu-emacs@gnu.org; Mon, 25 Nov 2019 08:30:06 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iZERH-0004F3-7u for bug-gnu-emacs@gnu.org; Mon, 25 Nov 2019 08:30:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:41979) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iZERG-0004Dx-VU for bug-gnu-emacs@gnu.org; Mon, 25 Nov 2019 08:30:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1iZERG-0006OY-Sc for bug-gnu-emacs@gnu.org; Mon, 25 Nov 2019 08:30:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 25 Nov 2019 13:30:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 38109 X-GNU-PR-Package: emacs Original-Received: via spool by 38109-submit@debbugs.gnu.org id=B38109.157468857424520 (code B ref 38109); Mon, 25 Nov 2019 13:30:02 +0000 Original-Received: (at 38109) by debbugs.gnu.org; 25 Nov 2019 13:29:34 +0000 Original-Received: from localhost ([127.0.0.1]:47952 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iZEQo-0006NP-79 for submit@debbugs.gnu.org; Mon, 25 Nov 2019 08:29:34 -0500 Original-Received: from mail-wm1-f48.google.com ([209.85.128.48]:55514) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1iZEQm-0006N9-NF for 38109@debbugs.gnu.org; Mon, 25 Nov 2019 08:29:33 -0500 Original-Received: by mail-wm1-f48.google.com with SMTP id b11so15423922wmb.5 for <38109@debbugs.gnu.org>; Mon, 25 Nov 2019 05:29:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=BzdHG4t77pdxRgaQFfzGoY0rHiOjttkPqvGy+dWkEUA=; b=J6WdCOXnhLZKFllD0X+gCtFrukfF1yaOrwUTWBNz8o7PfTFV4c8a1OR2KEJ3wliXAG 6q6iEwyOSYDUNATUfQI3LpMGeA0ZNdmbIVqjS1I0LHWb9WCcnSog6d+H/IdvnpGKW+06 pK4Q5duoEsK2v0VFRXohpBpAY5QEMLqQeBWOuB86oPlJErhrYaLoIteqyA3I9X36RY5/ 3kK6Ew8hhqIC2sXwoD2v7XiRac3S9q1bdXGpUcL950CmI41KvcT31ZkDSdN2JuV5+41n 8OCSdZwFo61mjICO3qQrdmHaDjpI/eKOFmbilX7f93klcaCUdcgx2a6dqIhaG7IjNsEt POsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=BzdHG4t77pdxRgaQFfzGoY0rHiOjttkPqvGy+dWkEUA=; b=KICVfnpM1YbDMf9Cld+pcmXt57Z7NrFpoRd1oymeE/TEQasUgcc1S5g6gZMfGNOFRG /lMLy47Js+sWac+6myt5NnnPQHa8Og0blEyud12V7DhtSGbr2oyTtuB08xIvbXqGkpd/ RuyKDIaKKT5hjAChQdFXopkd8icC96tvQXjZZH4tID857WcXM7/obhjS49TuyBHo0TVw GLtBjKOgaJcqN+X8+A6Uj3MQJ0AdV9m3sM404xJX4Rsef1U03YTlyPMSTMssWimQQCBr 2oy57zDWKomwnfiOMcVbJjUpgc+nU/DshN/vc0M25CV6YfU8+O1Om8LuZQQ4Sh+Bp2c8 ZTkw== X-Gm-Message-State: APjAAAWd5vlgw+0svXVPBN27qFFnw2GjnftHDBbdIrQF46iy6FTKfNji n1dbNESwvuqJAvCisFd1LWn8Iad1A14= X-Google-Smtp-Source: APXvYqyGeXhPAUteRJhHjZBgRZ5pmjtA7CCNF3TVkyjDTlbM0sGe63+zG2uNkwPLxCLcLcoWUhnDng== X-Received: by 2002:a05:600c:2102:: with SMTP id u2mr25139034wml.49.1574616376229; Sun, 24 Nov 2019 09:26:16 -0800 (PST) Original-Received: from breton.holly.idiocy.org (ip6-2001-08b0-03f8-8129-d485-68d2-2174-d65b.holly.idiocy.org. [2001:8b0:3f8:8129:d485:68d2:2174:d65b]) by smtp.gmail.com with ESMTPSA id u16sm6846832wrr.65.2019.11.24.09.26.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 24 Nov 2019 09:26:14 -0800 (PST) Content-Disposition: inline In-Reply-To: <87blt38no5.fsf@tullinup.koldfront.dk> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:172362 Archived-At: --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On Sat, Nov 23, 2019 at 01:02:50AM +0100, Adam Sjøgren wrote: > > Note, though, how the RGB image looks different than the two others, it > has a border added. This is caused by the smoothing of the image. After a LOT of searching around I found out we need to set the repeat value for the Picture to pad so that when it’s applying the filter and looking outside the image bounds it will look for the nearest real pixel rather than inventing a transparent black one. Patch attached. > I have run Gnus in Emacs for around an hour now without any crashes, > with this patch. Thanks! -- Alan Third --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v4-0001-Fix-image-scaling-with-masks-bug-38109.patch" >From 4efbc28e264e2045d4836492bd7fe388e42da055 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 9 Nov 2019 17:04:25 +0000 Subject: [PATCH v4] Fix image scaling with masks (bug#38109) * src/image.c (lookup_image): Move call to image_set_transform after postprocess_image. (image_create_x_image_and_pixmap_1): Use new function. (image_set_transform): Apply the transform to the mask too. (x_create_xrender_picture): New function. (Create_Pixmap_From_Bitmap_Data): (xpm_load): Use new function. * src/xterm.c (x_composite_image): Use PictOpOver when there is a mask so the transparency is honoured. (x_draw_image_foreground_1): Use x_composite_image. --- src/image.c | 147 ++++++++++++++++++++++++++++++++++++---------------- src/xterm.c | 11 ++-- 2 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/image.c b/src/image.c index 870f008b14..70d932f9ed 100644 --- a/src/image.c +++ b/src/image.c @@ -2244,6 +2244,14 @@ image_set_transform (struct frame *f, struct image *img) XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture, FilterBest, 0, 0); XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat); + + if (img->mask_picture) + { + XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture, + FilterBest, 0, 0); + XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture, + &tmat); + } } # elif defined HAVE_NTGUI /* Store the transform matrix for application at draw time. */ @@ -2313,10 +2321,6 @@ lookup_image (struct frame *f, Lisp_Object spec) Lisp_Object ascent, margin, relief, bg; int relief_bound; -#ifdef HAVE_NATIVE_TRANSFORMS - image_set_transform (f, img); -#endif - ascent = image_spec_value (spec, QCascent, NULL); if (FIXNUMP (ascent)) img->ascent = XFIXNUM (ascent); @@ -2357,6 +2361,13 @@ lookup_image (struct frame *f, Lisp_Object spec) don't have the image yet. */ if (!EQ (builtin_lisp_symbol (img->type->type), Qpostscript)) postprocess_image (f, img); + + /* postprocess_image above may modify the image or the mask, + relying on the image's real width and height, so + image_set_transform must be called after it. */ +#ifdef HAVE_NATIVE_TRANSFORMS + image_set_transform (f, img); +#endif } unblock_input (); @@ -2527,6 +2538,61 @@ x_destroy_x_image (XImage *ximg) } } +# if !defined USE_CAIRO && defined HAVE_XRENDER +/* Create and return an XRender Picture for XRender transforms. */ +static Picture +x_create_xrender_picture (struct frame *f, Emacs_Pixmap pixmap, int depth) +{ + Picture p; + Display *display = FRAME_X_DISPLAY (f); + int event_basep, error_basep; + + if (XRenderQueryExtension (display, &event_basep, &error_basep)) + { + if (depth <= 0) + depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); + if (depth == 32 || depth == 24 || depth == 8 || depth == 4 || depth == 1) + { + /* FIXME: Do we need to handle all possible bit depths? + XRenderFindStandardFormat supports PictStandardARGB32, + PictStandardRGB24, PictStandardA8, PictStandardA4, + PictStandardA1, and PictStandardNUM (what is this?!). + + XRenderFindFormat may support more, but I don't + understand the documentation. */ + XRenderPictFormat *format; + format = XRenderFindStandardFormat (display, + depth == 32 ? PictStandardARGB32 + : depth == 24 ? PictStandardRGB24 + : depth == 8 ? PictStandardA8 + : depth == 4 ? PictStandardA4 + : PictStandardA1); + + /* Set the Picture repeat to "pad". This means when + operations look at pixels outside the image area they + will use the value of the nearest real pixel instead of + using a transparent black pixel. */ + XRenderPictureAttributes attr; + unsigned long attr_mask = CPRepeat; + attr.repeat = RepeatPad; + + p = XRenderCreatePicture (display, pixmap, format, attr_mask, &attr); + } + else + { + image_error ("Specified image bit depth is not supported by XRender"); + return 0; + } + } + else + { + /* XRender not supported on this display. */ + return 0; + } + + return p; +} +# endif /* !defined USE_CAIRO && defined HAVE_XRENDER */ #endif /* HAVE_X_WINDOWS */ /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the @@ -2579,36 +2645,8 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap)) return 0; # ifdef HAVE_XRENDER - Display *display = FRAME_X_DISPLAY (f); - int event_basep, error_basep; - if (picture && XRenderQueryExtension (display, &event_basep, &error_basep)) - { - if (depth <= 0) - depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f)); - if (depth == 32 || depth == 24 || depth == 8) - { - XRenderPictFormat *format; - XRenderPictureAttributes attr; - - /* FIXME: Do we need to handle all possible bit depths? - XRenderFindStandardFormat supports PictStandardARGB32, - PictStandardRGB24, PictStandardA8, PictStandardA4, - PictStandardA1, and PictStandardNUM (what is this?!). - - XRenderFindFormat may support more, but I don't - understand the documentation. */ - format = XRenderFindStandardFormat (display, - depth == 32 ? PictStandardARGB32 - : depth == 24 ? PictStandardRGB24 - : PictStandardA8); - *picture = XRenderCreatePicture (display, *pixmap, format, 0, &attr); - } - else - { - image_error ("Specified image bit depth is not supported by XRender"); - *picture = 0; - } - } + if (picture) + *picture = x_create_xrender_picture (f, *pixmap, depth); # endif return 1; @@ -3387,6 +3425,11 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, img->width, img->height, fg, bg, DefaultDepthOfScreen (FRAME_X_SCREEN (f))); +# if !defined USE_CAIRO && defined HAVE_XRENDER + if (img->pixmap) + img->picture = x_create_xrender_picture (f, img->pixmap, 0); +# endif + #elif defined HAVE_NTGUI img->pixmap = w32_create_pixmap_from_bitmap_data (img->width, img->height, data); @@ -4359,18 +4402,30 @@ xpm_load (struct frame *f, struct image *img) image_clear_image (f, img); rc = XpmNoMemory; } - else if (img->mask_img) - { - img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), - img->mask_img->width, - img->mask_img->height, - img->mask_img->depth); - if (img->mask == NO_PIXMAP) - { - image_clear_image (f, img); - rc = XpmNoMemory; - } - } + else + { +# if !defined USE_CAIRO && defined HAVE_XRENDER + img->picture = x_create_xrender_picture (f, img->pixmap, + img->ximg->depth); +# endif + if (img->mask_img) + { + img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), + img->mask_img->width, + img->mask_img->height, + img->mask_img->depth); + if (img->mask == NO_PIXMAP) + { + image_clear_image (f, img); + rc = XpmNoMemory; + } +# if !defined USE_CAIRO && defined HAVE_XRENDER + else + img->mask_picture = x_create_xrender_picture + (f, img->mask, img->mask_img->depth); +# endif + } + } } #endif diff --git a/src/xterm.c b/src/xterm.c index d55bc3890d..9a6eda4488 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3049,14 +3049,12 @@ x_composite_image (struct glyph_string *s, Pixmap dest, XRenderPictFormat *default_format; XRenderPictureAttributes attr; - /* FIXME: Should we do this each time or would it make sense to - store destination in the frame struct? */ default_format = XRenderFindVisualFormat (display, DefaultVisual (display, 0)); destination = XRenderCreatePicture (display, dest, default_format, 0, &attr); - XRenderComposite (display, PictOpSrc, + XRenderComposite (display, s->img->mask_picture ? PictOpOver : PictOpSrc, s->img->picture, s->img->mask_picture, destination, srcX, srcY, srcX, srcY, @@ -3315,6 +3313,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap) trust on the shape extension to be available (XShapeCombineRegion). So, compute the rectangle to draw manually. */ + /* FIXME: Do we need to do this when using XRender compositing? */ unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin | GCFunction); XGCValues xgcv; @@ -3325,9 +3324,9 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap) xgcv.function = GXcopy; XChangeGC (display, s->gc, mask, &xgcv); - XCopyArea (display, s->img->pixmap, pixmap, s->gc, - s->slice.x, s->slice.y, - s->slice.width, s->slice.height, x, y); + x_composite_image (s, pixmap, + s->slice.x, s->slice.y, + x, y, s->slice.width, s->slice.height); XSetClipMask (display, s->gc, None); } else -- 2.21.0 --bp/iNruPH9dso1Pn--