1
- import numpy as np
1
+ import sys
2
2
import warnings
3
3
4
+ import numpy as np
5
+
4
6
from . import backend_agg , backend_cairo , backend_gtk3
5
7
from ._gtk3_compat import gi
6
8
from .backend_cairo import cairo
@@ -31,7 +33,7 @@ def _render_figure(self, width, height):
31
33
backend_agg .FigureCanvasAgg .draw (self )
32
34
33
35
def on_draw_event (self , widget , ctx ):
34
- """ GtkDrawable draw event, like expose_event in GTK 2.X
36
+ """GtkDrawable draw event, like expose_event in GTK 2.X.
35
37
"""
36
38
allocation = self .get_allocation ()
37
39
w , h = allocation .width , allocation .height
@@ -45,17 +47,29 @@ def on_draw_event(self, widget, ctx):
45
47
ctx = backend_cairo ._to_context (ctx )
46
48
47
49
for bbox in bbox_queue :
48
- area = self .copy_from_bbox (bbox )
49
- buf = np .fromstring (area .to_string_argb (), dtype = 'uint8' )
50
-
51
50
x = int (bbox .x0 )
52
51
y = h - int (bbox .y1 )
53
52
width = int (bbox .x1 ) - int (bbox .x0 )
54
53
height = int (bbox .y1 ) - int (bbox .y0 )
55
54
55
+ buf = (np .fromstring (self .copy_from_bbox (bbox ).to_string_argb (),
56
+ dtype = 'uint8' )
57
+ .reshape ((width , height , 4 )))
58
+ # cairo wants premultiplied alpha. Only bother doing the
59
+ # conversion when the alpha channel is not fully opaque, as the
60
+ # cost is not negligible. (The unsafe cast is needed to do the
61
+ # multiplication in-place in an integer buffer.)
62
+ if sys .byteorder == "little" :
63
+ rgb24 = buf [..., :- 1 ]
64
+ alpha8 = buf [..., - 1 :]
65
+ else :
66
+ alpha8 = buf [..., :1 ]
67
+ rgb24 = buf [..., 1 :]
68
+ if alpha8 .min () != 0xff :
69
+ np .multiply (rgb24 , alpha8 / 0xff , out = rgb24 , casting = "unsafe" )
70
+
56
71
image = cairo .ImageSurface .create_for_data (
57
- buf .ravel ().data , cairo .FORMAT_ARGB32 ,
58
- width , height , width * 4 )
72
+ buf .ravel ().data , cairo .FORMAT_ARGB32 , width , height )
59
73
ctx .set_source_surface (image , x , y )
60
74
ctx .paint ()
61
75
0 commit comments