Example #1
0
 def selection_draw_callback(self, ctx: cairo.Context, x: int, y: int):
     if self.interaction_mode == DrawerInteraction.CHUNKS:
         # Draw a chunk
         chunks_at_frame = self.animation_context.current()[self.edited_layer]
         ctx.set_source_surface(
             chunks_at_frame[self.interaction_chunks_selected_id], x, y
         )
         ctx.get_source().set_filter(cairo.Filter.NEAREST)
         ctx.paint()
     elif self.interaction_mode == DrawerInteraction.COL:
         # Draw collision
         if self.interaction_col_solid:
             ctx.set_source_rgba(1, 0, 0, 1)
             ctx.rectangle(
                 x, y,
                 BPC_TILE_DIM,
                 BPC_TILE_DIM
             )
             ctx.fill()
     elif self.interaction_mode == DrawerInteraction.DAT:
         # Draw data
         if self.interaction_dat_value > 0:
             ctx.select_font_face("monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
             ctx.set_font_size(6)
             ctx.set_source_rgb(1, 1, 1)
             ctx.move_to(x, y + BPC_TILE_DIM - 2)
             ctx.show_text(f"{self.interaction_dat_value:02x}")
Example #2
0
 def draw(self, wdg, ctx: cairo.Context, *args):
     if self.surface:
         ctx.fill()
         ctx.set_source_surface(self.surface, 0, 0)
         ctx.get_source().set_filter(cairo.Filter.NEAREST)
         ctx.paint()
     return True
Example #3
0
 def selection_draw_callback(self, ctx: cairo.Context, x: int, y: int):
     # Draw a chunk
     chunks_at_frame = self.animation_context.current()[0]
     ctx.set_source_surface(
         chunks_at_frame[self.interaction_chunks_selected_id], x, y)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
Example #4
0
 def draw(self, wdg, ctx: cairo.Context, *args):
     if self.surface:
         wdg.set_size_request(self.surface.get_width(),
                              self.surface.get_height())
         ctx.fill()
         ctx.set_source_surface(self.surface, 0, 0)
         ctx.get_source().set_filter(cairo.Filter.NEAREST)
         ctx.paint()
         entry_tree: Gtk.TreeView = self.builder.get_object('entry_tree')
         active_rows: List[Gtk.TreePath] = entry_tree.get_selection(
         ).get_selected_rows()[1]
         for x in active_rows:
             prop = self.entries[x.get_indices()[0]].get_properties()
             if self.font.get_entry_image_size() > 12:
                 ctx.set_line_width(4)
                 ctx.set_source_rgba(0, 0, 0, 1)
                 ctx.rectangle((prop["char"]%16)*self.font.get_entry_image_size()*IMAGE_ZOOM, \
                               (prop["char"]//16)*self.font.get_entry_image_size()*IMAGE_ZOOM, prop["width"]*IMAGE_ZOOM, self.font.get_entry_image_size()*IMAGE_ZOOM)
                 ctx.stroke()
             ctx.set_line_width(2)
             if self.font.get_entry_image_size() > 12:
                 ctx.set_source_rgba(1, 1, 1, 1)
             else:
                 ctx.set_source_rgba(1, 0, 0, 1)
             ctx.rectangle((prop["char"]%16)*self.font.get_entry_image_size()*IMAGE_ZOOM, \
                           (prop["char"]//16)*self.font.get_entry_image_size()*IMAGE_ZOOM, prop["width"]*IMAGE_ZOOM, self.font.get_entry_image_size()*IMAGE_ZOOM)
             ctx.stroke()
     return True
Example #5
0
 def _draw_object_sprite(self, ctx: cairo.Context, obj: SsaObject, x, y):
     """Draws the sprite for an object"""
     sprite = self.sprite_provider.get_for_object(obj.object.name, lambda: GLib.idle_add(self._redraw))[0]
     ctx.translate(x, y)
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.translate(-x, -y)
Example #6
0
 def draw(self, wdg, ctx: cairo.Context, *args):
     if self.surface:
         wdg.set_size_request(self.surface.get_width(), self.surface.get_height())
         ctx.fill()
         ctx.set_source_surface(self.surface, 0, 0)
         ctx.get_source().set_filter(cairo.Filter.NEAREST)
         ctx.paint()
     return True
Example #7
0
 def on_draw_icon_draw(self, widget: DrawingArea, ctx: cairo.Context):
     scale = 2
     ctx.scale(scale, scale)
     ctx.set_source_surface(self.icon_surface)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.scale(1 / scale, 1 / scale)
     return True
Example #8
0
 def on_draw(self, _widget: Gtk.Widget, cr: cairo.Context) -> bool:
     if not self.frozen:
         cr.set_source_rgba(self.color.red, self.color.green,
                            self.color.blue,
                            self.color.alpha - self.get_state())
         cr.set_operator(cairo.OPERATOR_OVER)
         cr.paint()
     return False
Example #9
0
 def on_draw(self, index: int, widget: Gtk.DrawingArea, ctx: cairo.Context):
     w16 = self._surfaces[index]
     ctx.set_source_rgb(0, 0, 0)
     ctx.rectangle(0, 0, *widget.get_size_request())
     ctx.fill()
     ctx.set_source_surface(w16)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
Example #10
0
    def draw(self, wdg, ctx: cairo.Context, do_translates=True):
        ctx.set_antialias(cairo.Antialias.NONE)
        ctx.scale(self.scale, self.scale)
        chunk_width = self.tiling_width * DPCI_TILE_DIM
        chunk_height = self.tiling_height * DPCI_TILE_DIM
        # Background
        if not self.use_pink_bg:
            ctx.set_source_rgb(0, 0, 0)
        else:
            ctx.set_source_rgb(1.0, 0, 1.0)
        ctx.rectangle(
            0, 0, self.width_in_chunks * self.tiling_width * DPCI_TILE_DIM,
            self.height_in_chunks * self.tiling_height * DPCI_TILE_DIM)
        ctx.fill()

        # Layers
        for chunks_at_frame in self.animation_context.current():
            for i, chunk_at_pos in enumerate(self.mappings):
                if 0 < chunk_at_pos < len(chunks_at_frame):
                    chunk = chunks_at_frame[chunk_at_pos]
                    ctx.set_source_surface(chunk, 0, 0)
                    ctx.get_source().set_filter(cairo.Filter.NEAREST)
                    ctx.paint()
                if (i + 1) % self.width_in_chunks == 0:
                    # Move to beginning of next line
                    if do_translates:
                        ctx.translate(
                            -chunk_width * (self.width_in_chunks - 1),
                            chunk_height)
                else:
                    # Move to next tile in line
                    if do_translates:
                        ctx.translate(chunk_width, 0)

            # Move back to beginning
            if do_translates:
                ctx.translate(0, -chunk_height * self.height_in_chunks)
            break

        size_w, size_h = self.draw_area.get_size_request()
        size_w /= self.scale
        size_h /= self.scale
        # Selection
        self.selection_plugin.set_size(self.tiling_width * DPCI_TILE_DIM,
                                       self.tiling_height * DPCI_TILE_DIM)
        self.selection_plugin.draw(ctx, size_w, size_h, self.mouse_x,
                                   self.mouse_y)

        # Tile Grid
        if self.draw_tile_grid:
            self.tile_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x,
                                       self.mouse_y)

        # Chunk Grid
        if self.draw_chunk_grid:
            self.chunk_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x,
                                        self.mouse_y)
        return True
Example #11
0
 def on_draw_example_placeholder_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context):
     sprite, x, y, w, h = self._sprite_provider.get_actor_placeholder(
         9999, 0, lambda: GLib.idle_add(lambda: self.builder.get_object('draw_example_placeholder').queue_draw())  # type: ignore
     )
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     if widget.get_size_request() != (w, h):
         widget.set_size_request(w, h)
Example #12
0
def draw_background(ctx: cairo.Context, width: int, height: int):
    # TODO: Add noise/cracks/stains
    bg_color = RadialGradient([Color(0.84, 0.81, 0.74), Color(0.55, 0.50, 0.36)])
    center_x = width / 2
    center_y = height / 2
    with source(ctx, bg_color.to_pattern(center_x, center_y, center_x)), operator(
        ctx, cairo.Operator.DARKEN
    ):
        ctx.paint()
Example #13
0
 def draw_icon(self, context: cairo.Context, icon: str, position: Tuple[int, int]):
     image = cairo.ImageSurface.create_from_png(
         os.path.join(os.path.dirname(__file__), "icons-7", f"{icon}.png")
     )
     context.save()
     context.translate(*position)
     context.set_source_surface(image)
     context.paint()
     context.restore()
Example #14
0
    def _surface_place_actor(self, ctx: cairo.Context, x, y, w, h):
        ctx.set_line_width(1)
        sprite_surface = self.sprite_provider.get_monster_outline(1, 1)[0]

        ctx.translate(x, y)
        ctx.set_source_surface(sprite_surface)
        ctx.get_source().set_filter(cairo.Filter.NEAREST)
        ctx.paint()
        self._draw_plus(ctx)
        ctx.translate(-x, -y)
Example #15
0
    def draw(self, wdg, ctx: cairo.Context):
        ctx.set_antialias(cairo.Antialias.NONE)
        ctx.scale(self.scale, self.scale)

        chunks_at_frame = self.animation_context.current()[0]
        if 0 <= self.chunkidx < len(chunks_at_frame):
            chunk = chunks_at_frame[self.chunkidx]
            ctx.set_source_surface(chunk, 0, 0)
            ctx.get_source().set_filter(cairo.Filter.NEAREST)
            ctx.paint()
Example #16
0
 def on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context):
     scale = 2
     sprite, x, y, w, h = self._sprite_provider.get_for_item(self.item_p, lambda: GLib.idle_add(widget.queue_draw))
     ctx.scale(scale, scale)
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.scale(1 / scale, 1 / scale)
     if widget.get_size_request() != (w, h):
         widget.set_size_request(w * scale, h * scale)
     return True
Example #17
0
 def on_draw_portrait_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context):
     scale = 2
     portrait = self._portrait_provider.get(self.entry.md_index - 1, 0,
                                            lambda: GLib.idle_add(widget.queue_draw), True)
     ctx.scale(scale, scale)
     ctx.set_source_surface(portrait)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.scale(1 / scale, 1 / scale)
     if widget.get_size_request() != (IMG_DIM * scale, IMG_DIM * scale):
         widget.set_size_request(IMG_DIM * scale, IMG_DIM * scale)
     return True
Example #18
0
 def on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context):
     if self.entry.entid > 0:
         sprite, x, y, w, h = self._sprite_provider.get_monster(self.entry.md_index, 0,
                                                                lambda: GLib.idle_add(widget.queue_draw))
     else:
         sprite, x, y, w, h = self._sprite_provider.get_error()
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     if widget.get_size_request() != (w, h):
         widget.set_size_request(w, h)
     return True
Example #19
0
 def draw(self, da, ctx:cairo.Context):
     self.ctx = ctx
     print('ok')
     print(pixbuf)
     Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0)
     ctx.paint()
     ctx.set_source_rgb(255, 0, 0)
     ctx.set_line_width(SIZE / 4)
     ctx.set_tolerance(0.1)
     ctx.set_line_join(cairo.LINE_JOIN_ROUND)
     ctx.set_dash([SIZE / 4.0, SIZE / 4.0], 0)
     self.stroke_shapes(ctx, 0, 0)
Example #20
0
 def draw(self, da, ctx: cairo.Context):
     print('ok')
     print(pixbuf)
     Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0)
     ctx.paint()
     ctx.set_source_rgb(255, 0, 0)
     ctx.set_line_width(SIZE / 4)
     ctx.set_tolerance(0.1)
     ctx.set_line_join(cairo.LINE_JOIN_ROUND)
     ctx.set_dash([SIZE / 4.0, SIZE / 4.0], 0)
     self.stroke_shapes(ctx, 0, 0)
     ctx.get_target().write_to_png('./a.png')
     return True
Example #21
0
def load_image_at_size(name, width, height):
    """Loads an image file at the specified size. Does NOT handle
    exceptions!"""

    from gi.repository import GdkPixbuf, Gdk
    from cairo import ImageSurface, FORMAT_ARGB32, Context

    pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(name, width, height)
    surface = ImageSurface(FORMAT_ARGB32, width, height)
    ctx = Context(surface)
    Gdk.cairo_set_source_pixbuf(ctx, pixbuf, 0, 0)
    ctx.paint()

    return surface
Example #22
0
 def on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context):
     if not self._drawing_is_active:
         return True
     scale = 4
     sprite, x, y, w, h = self._get_sprite_anim()
     ctx.scale(scale, scale)
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ww, wh = widget.get_size_request()
     if ww < w or wh < h:
         widget.set_size_request(w * scale, h * scale)
     ctx.scale(1 / scale, 1 / scale)
     return True
Example #23
0
 def _draw_actor_sprite(self, ctx: cairo.Context, actor: SsaActor, x, y):
     """Draws the sprite for an actor"""
     if actor.actor.entid == 0:
         sprite = self.sprite_provider.get_actor_placeholder(
             actor.actor.id, actor.pos.direction.id, self._redraw)[0]
     else:
         sprite = self.sprite_provider.get_monster(
             actor.actor.entid, actor.pos.direction.id,
             lambda: GLib.idle_add(self._redraw))[0]
     ctx.translate(x, y)
     ctx.set_source_surface(sprite)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.translate(-x, -y)
Example #24
0
File: canvas.py Project: benley/kye
    def drawcell(self, cairo_ctx: cairo.Context, i, j):
        """Draw the cell at i, j, using the supplied graphics context."""
        tile = self.showboard[i + j * xsize]

        i = i * self.tilesize
        j = j * self.tilesize

        if (tile == "blank"):
            cairo_ctx.set_source_rgb(1, 1, 1)
            cairo_ctx.rectangle(i, j, self.tilesize, self.tilesize)
            cairo_ctx.fill()
        else:
            Gdk.cairo_set_source_pixbuf(cairo_ctx, self.get_image(tile), i, j)
            cairo_ctx.paint()
Example #25
0
    def do_draw(self,
                cr: cairo.Context,
                width: int = 0,
                height: int = 0) -> bool:
        if not self._model:
            return False

        if not self._back_buffer:
            return False

        cr.set_source_surface(self._back_buffer, 0, 0)
        cr.paint()

        return False
Example #26
0
 def on_draw(self, subindex: int, widget: Gtk.DrawingArea,
             ctx: cairo.Context):
     scale = 2
     portrait = self._portrait_provider.get(
         self.item_id, subindex, lambda: GLib.idle_add(widget.queue_draw),
         False)
     ctx.set_source_rgb(1, 1, 1)
     ctx.rectangle(0, 0, *widget.get_size_request())
     ctx.fill()
     ctx.scale(scale, scale)
     ctx.set_source_surface(portrait)
     ctx.get_source().set_filter(cairo.Filter.NEAREST)
     ctx.paint()
     ctx.scale(1 / scale, 1 / scale)
     return True
Example #27
0
    def _do_draw(self, cr: cairo.Context) -> None:
        pixbuf = self.props.pixbuf
        if pixbuf is None:
            return

        scale = self._parent._widget_dist_from_canvas((1, 1))
        offset = self._parent._widget_coord_from_canvas((0, 0))

        with cairo_saved(cr):
            cr.translate(*offset)
            cr.scale(*scale)

            Gdk.cairo_set_source_pixbuf(cr, pixbuf, pixbuf_x=0, pixbuf_y=0)
            cr.get_source().set_filter(cairo.Filter.FAST)
            cr.paint()
Example #28
0
class MapSurface(object):
    """wrapper to render the map to svg/png"""

    def __init__(self, hexmap=None, filename=None, width=None, height=None, size=None):
        self.hexmap = hexmap
        if self.hexmap is None:
            raise ValueError("No map was passed to {}".format(self.__class__.__name__))
        self.surface_name = filename or "test.svg"
        self.size = size or 32.0
        self.surface_width = width
        if self.surface_width is None:
            self.surface_width = (self.hexmap.map.cols + .5) * self.size * SQRT3
        self.surface_height = height
        if self.surface_height is None:
            self.surface_height = (self.hexmap.map.rows * 1.5 + .25) * self.size
        self.layer = []

        # build base map
        self.surface = SVGSurface(self.surface_name + ".svg", self.surface_width, self.surface_height)
        self.context = Context(self.surface)
        # background: magenta
        self.context.save()
        self.context.set_source_rgb(1.0, 0.0, 1.0)
        self.context.paint()
        self.context.restore()

    def add_layer(self, renderer_cls, position=None):
        if not position:
            self.layer.append(renderer_cls(self))
        else:
            self.layer.insert(position, renderer_cls(self))

    def render(self):
        print "Rendering {} ({}x{})".format(self.surface_name, self.surface_width, self.surface_height)
        for renderer in self.layer:
            renderer.render()

    def finalise(self, with_png=False):
        print "finalising:"
        if with_png is True:
            print "PNG"
            self.surface.write_to_png(self.surface_name + ".png")
        print "SVG"
        self.surface.finish()
        print "DONE!"
Example #29
0
    def draw(self, wdg, ctx: cairo.Context):
        ctx.set_antialias(cairo.Antialias.NONE)
        ctx.scale(self.scale, self.scale)
        # Background
        if self.map_bg is not None:
            if self.level_id == WORLD_MAP_DEFAULT_ID:
                # We display the bottom right of the map.
                ctx.set_source_surface(self.map_bg, -504, -1008)
            else:
                ctx.set_source_surface(self.map_bg, 0, 0)
            ctx.get_source().set_filter(cairo.Filter.NEAREST)
            ctx.paint()

        size_w, size_h = self.draw_area.get_size_request()
        size_w /= self.scale
        size_h /= self.scale

        # Tile Grid
        if self.draw_tile_grid:
            self.tile_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x,
                                       self.mouse_y)

        # Selection
        self._handle_selection(ctx)

        # RENDER MARKERS
        self.markers_at_pos = {}
        for i, marker in enumerate(self.markers):
            if marker != self._editing and marker != self._hide and marker.level_id == self.level_id and marker.reference_id <= -1:
                self._draw_marker(ctx, marker)

        if self._editing:
            # Black out
            ctx.set_source_rgba(0, 0, 0, 0.5)
            ctx.rectangle(0, 0, size_w, size_h)
            ctx.fill()
            # Render editing marker
            self._draw_marker(ctx, self._editing)

        # nah, too crowded.
        #for (x, y), list_of_markers in self.markers_at_pos.items():
        #    ms = [self.markers.index(m) for m in list_of_markers]
        #    self._draw_name(ctx, ms, x, y)
        return True
Example #30
0
 def paint_image(self, img, x, y, w, h):
     #roundtrip via png (yuk)
     from io import BytesIO
     png = BytesIO()
     img.save(png, format="PNG")
     reader = BytesIO(png.getvalue())
     png.close()
     img = ImageSurface.create_from_png(reader)
     gc = Context(self.backing)
     gc.rectangle(x, y, w, h)
     gc.clip()
     gc.set_operator(OPERATOR_CLEAR)
     gc.rectangle(x, y, w, h)
     gc.fill()
     gc.set_operator(OPERATOR_SOURCE)
     gc.translate(x, y)
     gc.rectangle(0, 0, w, h)
     gc.set_source_surface(img, x, y)
     gc.paint()
Example #31
0
    def screen(self, base_w, base_h, ctx: cairo.Context, display_id: int):
        if display_id == 0:
            self.decode_screen()

        ctx.translate(base_w * self._scale / 2, base_h * self._scale / 2)
        ctx.rotate(-radians(self._screen_rotation_degrees))
        if self._screen_rotation_degrees == 90 or self._screen_rotation_degrees == 270:
            ctx.translate(-base_h * self._scale / 2, -base_w * self._scale / 2)
        else:
            ctx.translate(-base_w * self._scale / 2, -base_h * self._scale / 2)
        ctx.scale(self._scale, self._scale)
        if display_id == 0:
            ctx.set_source_surface(self._upper_image)
        else:
            ctx.set_source_surface(self._lower_image)
        ctx.get_source().set_filter(cairo.Filter.NEAREST)
        ctx.paint()

        if self._after_render_hook:
            self._after_render_hook(ctx, display_id)
Example #32
0
    def do_draw(self, context: cairo.Context) -> bool:
        if not self.adjustment or self.adjustment.get_upper() <= 0:
            return False

        height = self.get_allocated_height()
        width = self.get_allocated_width()

        if width <= 0 or height <= 0:
            return False

        base_bg, base_outline, handle_overdraw, handle_outline = (
            self.get_map_base_colors())

        x0 = self.overdraw_padding + 0.5
        x1 = width - 2 * x0
        height_scale = height * self.get_height_scale()

        if self._cached_map is None:
            surface = cairo.Surface.create_similar(
                context.get_target(), cairo.CONTENT_COLOR_ALPHA, width, height)
            cache_ctx = cairo.Context(surface)
            cache_ctx.set_line_width(1)

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_bg)
            cache_ctx.fill()

            # We get drawing coordinates by tag to minimise our source
            # colour setting, and make this loop slightly cleaner.
            tagged_diffs = self.chunk_coords_by_tag()

            for tag, diffs in tagged_diffs.items():
                cache_ctx.set_source_rgba(*self.fill_colors[tag])
                for y0, y1 in diffs:
                    y0 = round(y0 * height_scale) + 0.5
                    y1 = round(y1 * height_scale) - 0.5
                    cache_ctx.rectangle(x0, y0, x1, y1 - y0)
                cache_ctx.fill_preserve()
                cache_ctx.set_source_rgba(*self.line_colors[tag])
                cache_ctx.stroke()

            cache_ctx.rectangle(x0, -0.5, x1, height_scale + 0.5)
            cache_ctx.set_source_rgba(*base_outline)
            cache_ctx.stroke()

            self._cached_map = surface

        context.set_source_surface(self._cached_map, 0, 0)
        context.paint()

        # Draw our scroll position indicator
        context.set_line_width(1)
        context.set_source_rgba(*handle_overdraw)
        adj_y = self.adjustment.get_value() / self.adjustment.get_upper()
        adj_h = self.adjustment.get_page_size() / self.adjustment.get_upper()
        context.rectangle(
            x0 - self.overdraw_padding, round(height_scale * adj_y) + 0.5,
            x1 + 2 * self.overdraw_padding, round(height_scale * adj_h) - 1,
        )
        context.fill_preserve()
        context.set_source_rgba(*handle_outline)
        context.stroke()

        return True
Example #33
0
def make_label(text, filename, size=12, angle=0):
    '''
    Parameters:
    -----------
    text : string
        Text to be displayed
    filename : string
        Path to a font
    size : int
        Font size in 1/64th points
    angle : float
        Text angle in degrees
    '''
    face = Face(filename)
    face.set_char_size( size*64 )
    # FT_Angle is a 16.16 fixed-point value expressed in degrees.
    angle = FT_Angle(angle * 65536)
    matrix  = FT_Matrix( FT_Cos( angle ),
                         - FT_Sin( angle ),
                         FT_Sin( angle ) ,
                         FT_Cos( angle ) )
    flags = FT_LOAD_RENDER
    pen = FT_Vector(0,0)
    FT_Set_Transform( face._FT_Face, byref(matrix), byref(pen) )
    previous = 0
    xmin, xmax = 0, 0
    ymin, ymax = 0, 0
    for c in text:
        face.load_char(c, flags)
        kerning = face.get_kerning(previous, c)
        previous = c
        bitmap = face.glyph.bitmap
        pitch  = face.glyph.bitmap.pitch
        width  = face.glyph.bitmap.width
        rows   = face.glyph.bitmap.rows
        top    = face.glyph.bitmap_top
        left   = face.glyph.bitmap_left
        pen.x += kerning.x
        x0 = (pen.x >> 6) + left
        x1 = x0 + width
        y0 = (pen.y >> 6) - (rows - top)
        y1 = y0 + rows
        xmin, xmax = min(xmin, x0),  max(xmax, x1)
        ymin, ymax = min(ymin, y0), max(ymax, y1)
        pen.x += face.glyph.advance.x
        pen.y += face.glyph.advance.y

    L = ImageSurface(FORMAT_A8, xmax-xmin, ymax-ymin)
    previous = 0
    pen.x, pen.y = 0, 0
    ctx = Context(L)
    for c in text:
        face.load_char(c, flags)
        kerning = face.get_kerning(previous, c)
        previous = c
        bitmap = face.glyph.bitmap
        pitch  = face.glyph.bitmap.pitch
        width  = face.glyph.bitmap.width
        rows   = face.glyph.bitmap.rows
        top    = face.glyph.bitmap_top
        left   = face.glyph.bitmap_left
        pen.x += kerning.x
        x = (pen.x >> 6) - xmin + left
        y = - (pen.y >> 6) + ymax - top
        if (width > 0):
            glyph_surface = make_image_surface(face.glyph.bitmap)
            ctx.set_source_surface(glyph_surface, x, y)
            ctx.paint()
        pen.x += face.glyph.advance.x
        pen.y += face.glyph.advance.y

    L.flush()
    return L
Example #34
0
def generateOverlay(text,
                    font,
                    showFlumotion,
                    showCC,
                    showXiph,
                    width, height):
    """Generate an transparent image with text + logotypes rendered on top
    of it suitable for mixing into a video stream
    @param text: text to put in the top left corner
    @type text: str
    @param font: font description used to render the text
    @type: str
    @param showFlumotion: if we should show the flumotion logo
    @type showFlumotion: bool
    @param showCC: if we should show the Creative Common logo
    @type showCC: bool
    @param showXiph: if we should show the xiph logo
    @type showXiph: bool
    @param width: width of the image to generate
    @type width: int
    @param height: height of the image to generate
    @type height: int
    @returns: raw image and if images or if text overflowed
    @rtype: 3 sized tuple of string and 2 booleans
    """
    from cairo import ImageSurface
    from cairo import Context

    image = ImageSurface(cairo.FORMAT_ARGB32, width, height)
    context = Context(image)

    subImages = []
    if showXiph:
        subImages.append(os.path.join(configure.imagedir, '36x36', 'xiph.png'))
    if showCC:
        subImages.append(os.path.join(configure.imagedir, '36x36', 'cc.png'))
    if showFlumotion:
        subImages.append(os.path.join(configure.imagedir, '36x36',
                                      'fluendo.png'))

    imagesOverflowed = False

    offsetX = BORDER
    for subPath in subImages:
        sub = ImageSurface.create_from_png(subPath)
        subX = sub.get_width()
        subY = sub.get_height()
        offsetY = height - subY - BORDER
        context.set_source_surface(sub, offsetX, offsetY)
        context.paint()
        if (offsetX + subX) > width:
            imagesOverflowed = True
        offsetX += subX + BORDER

    textOverflowed = False
    if text:
        pcContext = pangocairo.CairoContext(context)
        pangoLayout = pcContext.create_layout()
        if font is not None:
            font = pango.FontDescription(font)
            if not font.get_family() or \
               not font.get_family().lower() in [family.get_name().lower()
                    for family in pangoLayout.get_context().list_families()]:
                font.set_family(FONT)
            if font.get_size() == 0:
                font.set_size(FONT_SIZE)
        else:
            font = pango.FontDescription('%s %s' % (FONT, FONT_PROPS))
        pangoLayout.set_font_description(font)

        context.move_to(TEXT_XOFFSET+2, TEXT_YOFFSET+2)
        pangoLayout.set_markup('<span foreground="black" >%s</span>' % text)
        pcContext.show_layout(pangoLayout)
        context.move_to(TEXT_XOFFSET, TEXT_YOFFSET)
        pangoLayout.set_markup('<span foreground="white" >%s</span>' % text)
        pcContext.show_layout(pangoLayout)

        textWidth, textHeight = pangoLayout.get_pixel_size()
        if textWidth > width:
            textOverflowed = True

    if cairo.version < '1.2.6':
        buf = image.get_data_as_rgba()
    else:
        buf = image.get_data()

    return buf, imagesOverflowed, textOverflowed
Example #35
0
    raise RuntimeError('pitch != width * 4 for color bitmap: Please report this.')
bitmap = np.array(bitmap.buffer, dtype=np.uint8).reshape((bitmap.rows,bitmap.width,4))

I = ImageSurface(FORMAT_ARGB32, width, rows)
try:
    ndI = np.ndarray(shape=(rows,width), buffer=I.get_data(),
                     dtype=np.uint32, order='C',
                     strides=[I.get_stride(), 4])
except NotImplementedError:
    raise SystemExit("For python 3.x, you need pycairo >= 1.11+ (from https://github.com/pygobject/pycairo)")

# Although both are 32-bit, cairo is host-order while
# freetype is small endian.
ndI[:,:] = bitmap[:,:,3] * 2**24 + bitmap[:,:,2] * 2**16 + bitmap[:,:,1] * 2**8 + bitmap[:,:,0]
I.mark_dirty()

surface = ImageSurface(FORMAT_ARGB32, 2*width, rows)
ctx = Context(surface)

ctx.set_source_surface(I, 0, 0)
ctx.paint()

ctx.set_source_surface(I, width/2, 0)
ctx.paint()

ctx.set_source_surface(I, width , 0)
ctx.paint()

surface.write_to_png("emoji-color-cairo.png")
Image.open("emoji-color-cairo.png").show()