def _cache_bg_for_state(self, state):
a = self.get_allocation()
# tmp surface on which we render the button bg as per the gtk
# theme engine
_surf = cairo.ImageSurface(cairo.FORMAT_ARGB32,
a.width, a.height)
cr = cairo.Context(_surf)
context = self.get_style_context()
context.save()
context.set_state(state)
Gtk.render_background(context, cr,
-5, -5, a.width + 10, a.height + 10)
Gtk.render_frame(context, cr,
-5, -5, a.width + 10, a.height + 10)
del cr
# new surface which will be cached which
surf = cairo.ImageSurface(cairo.FORMAT_ARGB32,
a.width, a.height)
cr = cairo.Context(surf)
# gradient for masking
lin = cairo.LinearGradient(0, 0, 0, a.height)
lin.add_color_stop_rgba(0.0, 1, 1, 1, 0.1)
lin.add_color_stop_rgba(0.25, 1, 1, 1, 0.7)
lin.add_color_stop_rgba(0.5, 1, 1, 1, 1.0)
lin.add_color_stop_rgba(0.75, 1, 1, 1, 0.7)
lin.add_color_stop_rgba(1.0, 1, 1, 1, 0.1)
cr.set_source_surface(_surf, 0, 0)
cr.mask(lin)
del cr
# cache the resulting surf...
self._bg_cache[state] = surf
python类ImageSurface()的实例源码
def setup_context(width, height, out_width=0):
scale = 1
if out_width >= MIN_WIDTH:
scale = out_width / width
surface = cairo.ImageSurface(
cairo.FORMAT_ARGB32, int(round(width * scale)), int(round(height * scale)))
ctx = cairo.Context(surface)
ctx.scale(scale, scale)
ctx.set_source_rgba(0, 0, 0, 0) # transparent bg
ctx.paint()
return (ctx, surface)
def main():
# make the canvas
sur = cairo.ImageSurface(cairo.FORMAT_ARGB32, SIZE, SIZE)
ctx = cairo.Context(sur)
# scale canvas so that x and y ranges from 0 to 1.
ctx.scale(SIZE, SIZE)
# set the background color of the canvas
ctx.set_source_rgba(*BACK)
ctx.rectangle(0.0, 0.0, 1.0, 1.0)
ctx.fill()
ctx.set_line_width(LINEWIDTH)
circles = []
add_new_circles(NEW_COUNT, circles)
for i in xrange(STEPS):
increase_radius(circles)
ok_count = test(circles)
if ok_count < 1:
add_new_circles(NEW_COUNT, circles)
print(i, 'adding new circles, total count: ' + str(len(circles)))
show(ctx, circles)
sur.write_to_png(RES)
def do_draw(self, cr):
Gtk.Window.do_draw(self, cr)
if (self.transparent):
width, height = self.get_size()
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)
self.webview.draw(cr)
region = cairo_region_create_from_surface(surface, mask_accuracy)
self.input_shape_combine_region(None)
self.input_shape_combine_region(region)
def cairo_region_create_from_surface(surface, mask_accuracy):
rect = cairo.RectangleInt()
extents = _cairo_surface_extents(surface)
if extents != False:
if surface.get_content() == cairo.CONTENT_COLOR:
return cairo.Region(extents)
if type(surface) != cairo.ImageSurface or surface.get_format != cairo.FORMAT_A1:
image = cairo.ImageSurface(cairo.FORMAT_A1, extents.width, extents.height)
cr = cairo.Context(image)
cr.set_source_surface(surface, -extents.x, -extents.y)
cr.paint()
else:
image = surface
image.flush()
data = image.get_data()
stride = image.get_stride()
region = cairo.Region()
for y in range(0, extents.height, mask_accuracy):
for x in range(0, extents.width, mask_accuracy):
x0 = x;
while x < extents.width:
if sys.byteorder == 'little':
if ((data[y*stride+x//8] >> (x%8)) & 1) == 0:
break
if sys.byteorder == 'big':
if ((data[y*stride+x//8] >> (7-(x%8))) & 1) == 0:
break
x += mask_accuracy
if x > x0:
rect.x = x0
rect.width = x - x0
rect.y = y
rect.height = mask_accuracy
region.union(rect)
region.translate(extents.x, extents.y)
return region
def layout(self, width):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
ctx = cairo.Context(surface)
max_text_height = ctx.text_extents("ABCDEFGHIJKLMNOPQRSTUVWXYZabcedefghijklmnopqrstuvwxyz0123456789")[3]
left_width = 0
right_width = 0
left_n_lines = 0
range_n = 0
eventint_n = 0
eventstr_n = 0
for timeline in self.timelines.get_all():
left_n_lines += 1
t_width = ctx.text_extents(timeline.name)[2]
left_width = max(left_width, t_width)
for rang in timeline.get_ranges():
t_width = ctx.text_extents(rang.name)[2]
right_width = max(right_width, t_width)
range_n += 1
for events_int in timeline.get_events_int():
t_width = ctx.text_extents(events_int.name)[2]
right_width = max(right_width, t_width)
eventint_n += 1
for events_str in timeline.get_events_str():
t_width = ctx.text_extents(events_str.name)[2]
right_width = max(right_width, t_width)
eventstr_n += 1
left_height = left_n_lines * max_text_height + (left_n_lines - 1) * self.padding
right_n_lines = range_n + eventint_n + eventstr_n
right_height = (right_n_lines - 1) * self.padding + right_n_lines * max_text_height
right_data_height = (eventint_n + eventstr_n) * (max_text_height + 5) + range_n * 10
right_data_height += (right_n_lines - 1) * self.padding
height = max(left_height, right_height)
height = max(height, right_data_height)
self.left_width = left_width
self.right_width = right_width
self.max_text_height = max_text_height
self.width = width
self.height = height + self.padding
def expose(self, widget, event):
if self.__force_full_redraw:
self.__buffer_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
self.__data.get_width(),
self.__data.get_height())
ctx = cairo.Context(self.__buffer_surface)
self.__data.draw(ctx)
self.__force_full_redraw = False
ctx = widget.window.cairo_create()
ctx.rectangle(event.area.x, event.area.y,
event.area.width, event.area.height)
ctx.clip()
ctx.set_source_surface(self.__buffer_surface)
ctx.paint()
(x, y, width, height) = self.__data.get_selection_rectangle()
if self.__moving_left:
ctx.move_to(max(self.__moving_left_cur, 2), y)
ctx.rel_line_to(0, height)
ctx.close_path()
ctx.set_line_width(1)
ctx.set_source_rgb(0, 0, 0)
ctx.stroke()
if self.__moving_right:
ctx.move_to(min(self.__moving_right_cur, self.__width - 2), y)
ctx.rel_line_to(0, height)
ctx.close_path()
ctx.set_line_width(1)
ctx.set_source_rgb(0, 0, 0)
ctx.stroke()
if self.__moving_both:
delta_x = self.__moving_both_cur - self.__moving_both_start
left_x = x + delta_x
ctx.move_to(x + delta_x, y)
ctx.rel_line_to(0, height)
ctx.close_path()
ctx.move_to(x + width + delta_x, y)
ctx.rel_line_to(0, height)
ctx.close_path()
ctx.set_source_rgb(0, 0, 0)
ctx.set_line_width(1)
ctx.stroke()
return False
def drag_begin(self, widget, drag_context, data):
self.dnd_data_received = False
# get x,y co-ords of source square
x, y = data
if gv.verbose:
print("in drag begin")
print("data=", data)
print("widget_name=", widget.get_name())
print("source sq=", x, y)
stm = gv.jcchess.get_side_to_move()
# convert the x, y co-ords into the shogi representation
# (e.g. 8, 6 is 1g)
sq = gv.board.get_square_posn(x, y)
self.src = sq
if gv.verbose:
print("source square: (x, y) = (", x, ",", y, ") ", sq)
self.src_x = x
self.src_y = y
# set the icon for the drag and drop to the piece that is being
# dragged
self.piece = gv.board.get_piece(x, y)
# get width/height of board square
a = gv.gui.get_event_box(x, y).get_allocation()
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, a.width, a.height)
svghandle = gv.board.get_piece_handle(x, y)
dim = svghandle.get_dimensions()
cr = cairo.Context(surface)
sfw = (a.width * 1.0 / dim.width) * SCALE
sfh = (a.height * 1.0 / dim.height) * SCALE
cr.scale(sfw, sfh)
svghandle.render_cairo(cr)
# set mouse pointer to be in middle of drag icon
surface.set_device_offset(-a.width/2, -a.height/2)
Gtk.drag_set_icon_surface(drag_context, surface)
# clear the square where the piece is being moved from
gv.board.set_square_as_unoccupied(x, y)
def cairo_render_string(s,fontname=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
# make a guess at the size
w = max(100,int(size*len(s)))
h = max(100,int(size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
cr.select_font_face(fontname)
if size is not None:
cr.set_font_size(size)
xbear,ybear,tw,th = cr.text_extents(s)[:4]
tw += 2*pad
th += 2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
return a
def pango_render_string(s,spec=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5,
markup=1,scale=2.0,aspect=1.0,rotation=0.0):
"""Render a string using Cairo and the Pango text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. (Currently unimplemented.)"""
S = pango.SCALE
face = None
if fontfile is not None: raise Exception("can't load ttf file into Pango yet; use fontname")
# make a guess at the size
w = max(100,int(scale*size*len(s)))
h = max(100,int(scale*size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if spec is not None: fd = pango.FontDescription(spec)
else: fd = pango.FontDescription()
if size is not None: fd.set_size(int(scale*size*S))
pcr = pangocairo.CairoContext(cr)
layout = pcr.create_layout()
layout.set_font_description(fd)
if not markup:
layout.set_text(s)
else:
layout.set_markup(s)
((xbear,ybear,tw,th),_) = layout.get_pixel_extents()
# print(xbear, ybear, tw, th)
tw = tw+2*pad
th = th+2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
pcr.show_layout(layout)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
if rotation!=0.0: a = rotate(a,rotation,order=1)
a = zoom(a,(aspect/scale,1.0/scale/aspect,1.0),order=1)
return a
def cairo_render_at(s,loc=None,shape=None,
fontname=None,fontfile=None,size=None,
slant=cairo.FONT_SLANT_NORMAL,
weight=cairo.FONT_WEIGHT_NORMAL,
bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9)):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
assert loc is not None
assert shape is not None
assert size is not None
w,h = shape
x,y = loc
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
if type(slant)==str:
if slant[0]=="i": slant = cairo.FONT_SLANT_ITALIC
elif slant[0]=="o": slant = cairo.FONT_SLANT_OBLIQUE
elif slant[0]=="n": slant = cairo.FONT_SLANT_NORMAL
else: raise Exception("bad font slant specification (use n/i/o)")
if type(weight)==str:
if weight[0]=="b": weight = cairo.FONT_WEIGHT_BOLD
elif weight[0]=="n": weight = cairo.FONT_WEIGHT_NORMAL
else: raise Exception("bad font weight specification (use b/n)")
cr.select_font_face(fontname,slant,weight)
if size is not None:
cr.set_font_size(size)
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(x,y)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:,:,:3]
a = a[:,:,::-1]
return a
def cairo_render_string(s,fontname=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
# make a guess at the size
w = max(100,int(size*len(s)))
h = max(100,int(size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
cr.select_font_face(fontname)
if size is not None:
cr.set_font_size(size)
xbear,ybear,tw,th = cr.text_extents(s)[:4]
tw += 2*pad
th += 2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
return a
def pango_render_string(s,spec=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5,
markup=1,scale=2.0,aspect=1.0,rotation=0.0):
"""Render a string using Cairo and the Pango text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. (Currently unimplemented.)"""
S = pango.SCALE
face = None
if fontfile is not None: raise Exception("can't load ttf file into Pango yet; use fontname")
# make a guess at the size
w = max(100,int(scale*size*len(s)))
h = max(100,int(scale*size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if spec is not None: fd = pango.FontDescription(spec)
else: fd = pango.FontDescription()
if size is not None: fd.set_size(int(scale*size*S))
pcr = pangocairo.CairoContext(cr)
layout = pcr.create_layout()
layout.set_font_description(fd)
if not markup:
layout.set_text(s)
else:
layout.set_markup(s)
((xbear,ybear,tw,th),_) = layout.get_pixel_extents()
# print(xbear, ybear, tw, th)
tw = tw+2*pad
th = th+2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
pcr.show_layout(layout)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
if rotation!=0.0: a = rotate(a,rotation,order=1)
a = zoom(a,(aspect/scale,1.0/scale/aspect,1.0),order=1)
return a
def cairo_render_at(s,loc=None,shape=None,
fontname=None,fontfile=None,size=None,
slant=cairo.FONT_SLANT_NORMAL,
weight=cairo.FONT_WEIGHT_NORMAL,
bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9)):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
assert loc is not None
assert shape is not None
assert size is not None
w,h = shape
x,y = loc
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
if type(slant)==str:
if slant[0]=="i": slant = cairo.FONT_SLANT_ITALIC
elif slant[0]=="o": slant = cairo.FONT_SLANT_OBLIQUE
elif slant[0]=="n": slant = cairo.FONT_SLANT_NORMAL
else: raise Exception("bad font slant specification (use n/i/o)")
if type(weight)==str:
if weight[0]=="b": weight = cairo.FONT_WEIGHT_BOLD
elif weight[0]=="n": weight = cairo.FONT_WEIGHT_NORMAL
else: raise Exception("bad font weight specification (use b/n)")
cr.select_font_face(fontname,slant,weight)
if size is not None:
cr.set_font_size(size)
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(x,y)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:,:,:3]
a = a[:,:,::-1]
return a
def cairo_render_string(s,fontname=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
# make a guess at the size
w = max(100,int(size*len(s)))
h = max(100,int(size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
cr.select_font_face(fontname)
if size is not None:
cr.set_font_size(size)
xbear,ybear,tw,th = cr.text_extents(s)[:4]
tw += 2*pad
th += 2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
return a
def pango_render_string(s,spec=None,fontfile=None,size=None,bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9),pad=5,
markup=1,scale=2.0,aspect=1.0,rotation=0.0):
"""Render a string using Cairo and the Pango text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. (Currently unimplemented.)"""
S = pango.SCALE
face = None
if fontfile is not None: raise Exception("can't load ttf file into Pango yet; use fontname")
# make a guess at the size
w = max(100,int(scale*size*len(s)))
h = max(100,int(scale*size*1.5))
# possibly run through twice to make sure we get the right size buffer
for round in range(2):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if spec is not None: fd = pango.FontDescription(spec)
else: fd = pango.FontDescription()
if size is not None: fd.set_size(int(scale*size*S))
pcr = pangocairo.CairoContext(cr)
layout = pcr.create_layout()
layout.set_font_description(fd)
if not markup:
layout.set_text(s)
else:
layout.set_markup(s)
((xbear,ybear,tw,th),_) = layout.get_pixel_extents()
# print(xbear, ybear, tw, th)
tw = tw+2*pad
th = th+2*pad
if tw<=w and th<=h: break
w = tw
h = th
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(-xbear+pad,-ybear+pad)
cr.set_source_rgb(*fg)
pcr.show_layout(layout)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:th,:tw,:3]
a = a[:,:,::-1]
if rotation!=0.0: a = rotate(a,rotation,order=1)
a = zoom(a,(aspect/scale,1.0/scale/aspect,1.0),order=1)
return a
def cairo_render_at(s,loc=None,shape=None,
fontname=None,fontfile=None,size=None,
slant=cairo.FONT_SLANT_NORMAL,
weight=cairo.FONT_WEIGHT_NORMAL,
bg=(0.0,0.0,0.0),fg=(0.9,0.9,0.9)):
"""Render a string using Cairo and the Cairo text rendering interface. Fonts can either be given
as a fontfile or as a fontname. Size should be in pixels (?). You can specify a background and
foreground color as RGB floating point triples. Images are padded by pad pixels on all sides."""
assert loc is not None
assert shape is not None
assert size is not None
w,h = shape
x,y = loc
face = None
if fontfile is not None:
# "/usr/share/fonts/truetype/msttcorefonts/comic.ttf"
if fontfile in facecache:
face = facecache[fontfile]
else:
face = create_cairo_font_face_for_file(fontfile,0)
facecache[fontfile] = face
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,w,h)
cr = cairo.Context(surface)
if face is not None:
cr.set_font_face(face)
else:
if fontname is None: fontname = "Helvetica"
if type(slant)==str:
if slant[0]=="i": slant = cairo.FONT_SLANT_ITALIC
elif slant[0]=="o": slant = cairo.FONT_SLANT_OBLIQUE
elif slant[0]=="n": slant = cairo.FONT_SLANT_NORMAL
else: raise Exception("bad font slant specification (use n/i/o)")
if type(weight)==str:
if weight[0]=="b": weight = cairo.FONT_WEIGHT_BOLD
elif weight[0]=="n": weight = cairo.FONT_WEIGHT_NORMAL
else: raise Exception("bad font weight specification (use b/n)")
cr.select_font_face(fontname,slant,weight)
if size is not None:
cr.set_font_size(size)
cr.set_source_rgb(*bg)
cr.rectangle(0,0,w,h)
cr.fill()
cr.move_to(x,y)
cr.set_source_rgb(*fg)
cr.show_text(s)
data = surface.get_data()
data = bytearray(data)
a = array(data,'B')
a.shape = (h,w,4)
a = a[:,:,:3]
a = a[:,:,::-1]
return a
def render(self, canvas, transparent=False):
x0,y0,x1,y1 = canvas.bbox('all')
self.markers = canvas.markers
W = int((x1 - x0 + 2*self.padding) * self.scale)
H = int((y1 - y0 + 2*self.padding) * self.scale)
ext = os.path.splitext(self.fname)[1].lower()
if ext == '.svg':
surf = cairo.SVGSurface(self.fname, W, H)
elif ext == '.pdf':
surf = cairo.PDFSurface(self.fname, W, H)
elif ext in ('.ps', '.eps'):
surf = cairo.PSSurface(self.fname, W, H)
if ext == '.eps':
surf.set_eps(True)
else: # Bitmap
surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, W, H)
self.ctx = cairo.Context(surf)
ctx = self.ctx
if not transparent:
# Fill background
ctx.rectangle(0,0, W,H)
ctx.set_source_rgba(1.0,1.0,1.0)
ctx.fill()
ctx.scale(self.scale, self.scale)
ctx.translate(-x0 + self.padding, -y0 + self.padding)
if self.draw_bbox:
last = len(canvas.shapes)
for s in canvas.shapes[:last]:
bbox = s.bbox
r = canvas.create_rectangle(*bbox, line_color=(255,0,0, 127), fill=(0,255,0,90))
for s in canvas.shapes:
self.draw_shape(s)
if ext in ('.svg', '.pdf', '.ps', '.eps'):
surf.show_page()
else:
surf.write_to_png(self.fname)
def cairo_text_bbox(text, font_params, spacing=0, scale=1.0):
surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, 8, 8)
ctx = cairo.Context(surf)
# The scaling must match the final context.
# If not there can be a mismatch between the computed extents here
# and those generated for the final render.
ctx.scale(scale, scale)
font = cairo_font(font_params)
if use_pygobject:
status, attrs, plain_text, _ = pango.parse_markup(text, len(text), '\0')
layout = pangocairo.create_layout(ctx)
pctx = layout.get_context()
fo = cairo.FontOptions()
fo.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
pangocairo.context_set_font_options(pctx, fo)
layout.set_font_description(font)
layout.set_spacing(spacing * pango.SCALE)
layout.set_text(plain_text, len(plain_text))
layout.set_attributes(attrs)
li = layout.get_iter() # Get first line of text
baseline = li.get_baseline() / pango.SCALE
re = layout.get_pixel_extents()[1] # Get logical extents
extents = (re.x, re.y, re.x + re.width, re.y + re.height)
else: # pyGtk
attrs, plain_text, _ = pango.parse_markup(text)
pctx = pangocairo.CairoContext(ctx)
pctx.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
layout = pctx.create_layout()
layout.set_font_description(font)
layout.set_spacing(spacing * pango.SCALE)
layout.set_text(plain_text)
layout.set_attributes(attrs)
li = layout.get_iter() # Get first line of text
baseline = li.get_baseline() / pango.SCALE
#print('@@ EXTENTS:', layout.get_pixel_extents()[1], spacing)
extents = layout.get_pixel_extents()[1] # Get logical extents
return [extents[0], extents[1], extents[2], extents[3], baseline]
def renderTile(tx, ty, zoom, polygons, borders = True, width = 256, height = 256):
"""
renderTile -- return a numpy array of uint32
tx -- tile x coord
ty -- tile y coord
zoom -- tile zoom
polygon -- a polygon locator
"""
# FORMAT_ARGB32 is premultiplied, which results in loss of precision and thus cannot be used.
# FORMAT_RGB30 offers up 30bits, (1 billion uniques),
# but isn't available until 1.12 (we have 1.10)
# FORMAT_RGB24 will have to be used.
# Another option would be to render a 2nd channel with the alpha info.
#borders = False
surface = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height)
ctx = getContext(surface, tx, ty, zoom)
bsurface = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height)
ctx2 = getContext(bsurface, tx, ty, zoom)
simple_level = zoom if zoom < 10 else -1
extents = ctx.clip_extents()
for pid in polygons.overlapping(extents):
polygon = polygons.source.get(pid)
if simple_level > -1:
polygon = simple(polygon, zoom)
drawPoly(ctx, ctx2, polygon, pid)
#if borders:
# for width in range(10,0,-1):
# ctx2.set_source_rgb(0.0,0.0,width/256.)
# width = width/ctx2.get_matrix()[0]
# ctx2.set_line_width(width)
# ctx2.stroke_preserve()
surface.flush() #make sure operations are finished
#surface.write_to_png ("example.png") # Output to PNG
a = numpy.frombuffer(surface.get_data(), 'uint32') & 0x00ffffff
surface.finish()
if borders:
bsurface.flush()
b = numpy.frombuffer(bsurface.get_data(), 'uint32') & 0x00ffffff
#bsurface.write_to_png ("example2.png") # Output to PNG
bsurface.finish()
return a,b
# get_data returns buffer
# FORMAT_RGB24 consists of 32bit pixel in system byteorder
# as A,R,G,B values.
# The Alpha channel is present but unused, however
# it still contains data and must be zeroed.
return a,None