110259SAndrew.Bardsley@arm.com# Copyright (c) 2013 ARM Limited 210259SAndrew.Bardsley@arm.com# All rights reserved 310259SAndrew.Bardsley@arm.com# 410259SAndrew.Bardsley@arm.com# The license below extends only to copyright in the software and shall 510259SAndrew.Bardsley@arm.com# not be construed as granting a license to any other intellectual 610259SAndrew.Bardsley@arm.com# property including but not limited to intellectual property relating 710259SAndrew.Bardsley@arm.com# to a hardware implementation of the functionality of the software 810259SAndrew.Bardsley@arm.com# licensed hereunder. You may use the software subject to the license 910259SAndrew.Bardsley@arm.com# terms below provided that you ensure that this notice is replicated 1010259SAndrew.Bardsley@arm.com# unmodified and in its entirety in all distributions of the software, 1110259SAndrew.Bardsley@arm.com# modified or unmodified, in source code or in binary form. 1210259SAndrew.Bardsley@arm.com# 1310259SAndrew.Bardsley@arm.com# Redistribution and use in source and binary forms, with or without 1410259SAndrew.Bardsley@arm.com# modification, are permitted provided that the following conditions are 1510259SAndrew.Bardsley@arm.com# met: redistributions of source code must retain the above copyright 1610259SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer; 1710259SAndrew.Bardsley@arm.com# redistributions in binary form must reproduce the above copyright 1810259SAndrew.Bardsley@arm.com# notice, this list of conditions and the following disclaimer in the 1910259SAndrew.Bardsley@arm.com# documentation and/or other materials provided with the distribution; 2010259SAndrew.Bardsley@arm.com# neither the name of the copyright holders nor the names of its 2110259SAndrew.Bardsley@arm.com# contributors may be used to endorse or promote products derived from 2210259SAndrew.Bardsley@arm.com# this software without specific prior written permission. 2310259SAndrew.Bardsley@arm.com# 2410259SAndrew.Bardsley@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2510259SAndrew.Bardsley@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2610259SAndrew.Bardsley@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2710259SAndrew.Bardsley@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2810259SAndrew.Bardsley@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2910259SAndrew.Bardsley@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3010259SAndrew.Bardsley@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3110259SAndrew.Bardsley@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3210259SAndrew.Bardsley@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3310259SAndrew.Bardsley@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3410259SAndrew.Bardsley@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3510259SAndrew.Bardsley@arm.com# 3610259SAndrew.Bardsley@arm.com# Authors: Andrew Bardsley 3710259SAndrew.Bardsley@arm.com# 3810259SAndrew.Bardsley@arm.com# blobs.py: Blobs are the visual blocks, arrows and other coloured 3910259SAndrew.Bardsley@arm.com# objects on the visualiser. This file contains Blob definition and 4010259SAndrew.Bardsley@arm.com# their rendering instructions in pygtk/cairo. 4110259SAndrew.Bardsley@arm.com# 4210259SAndrew.Bardsley@arm.com 4310259SAndrew.Bardsley@arm.comimport pygtk 4410259SAndrew.Bardsley@arm.compygtk.require('2.0') 4510259SAndrew.Bardsley@arm.comimport gtk 4610259SAndrew.Bardsley@arm.comimport gobject 4710259SAndrew.Bardsley@arm.comimport cairo 4810259SAndrew.Bardsley@arm.comimport re 4910259SAndrew.Bardsley@arm.comimport math 5010259SAndrew.Bardsley@arm.com 5110259SAndrew.Bardsley@arm.comfrom point import Point 5210259SAndrew.Bardsley@arm.comimport parse 5310259SAndrew.Bardsley@arm.comimport colours 5410259SAndrew.Bardsley@arm.comfrom colours import backgroundColour, black 5510259SAndrew.Bardsley@arm.comimport model 5610259SAndrew.Bardsley@arm.com 5710259SAndrew.Bardsley@arm.comdef centre_size_to_sides(centre, size): 5810259SAndrew.Bardsley@arm.com """Returns a 4-tuple of the relevant ordinates of the left, 5910259SAndrew.Bardsley@arm.com right, top and bottom sides of the described rectangle""" 6010259SAndrew.Bardsley@arm.com (x, y) = centre.to_pair() 6110259SAndrew.Bardsley@arm.com (half_width, half_height) = (size.scale(0.5)).to_pair() 6210259SAndrew.Bardsley@arm.com left = x - half_width 6310259SAndrew.Bardsley@arm.com right = x + half_width 6410259SAndrew.Bardsley@arm.com top = y - half_height 6510259SAndrew.Bardsley@arm.com bottom = y + half_height 6610259SAndrew.Bardsley@arm.com return (left, right, top, bottom) 6710259SAndrew.Bardsley@arm.com 6810259SAndrew.Bardsley@arm.comdef box(cr, centre, size): 6910259SAndrew.Bardsley@arm.com """Draw a simple box""" 7010259SAndrew.Bardsley@arm.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 7110259SAndrew.Bardsley@arm.com cr.move_to(left, top) 7210259SAndrew.Bardsley@arm.com cr.line_to(right, top) 7310259SAndrew.Bardsley@arm.com cr.line_to(right, bottom) 7410259SAndrew.Bardsley@arm.com cr.line_to(left, bottom) 7510259SAndrew.Bardsley@arm.com cr.close_path() 7610259SAndrew.Bardsley@arm.com 7710259SAndrew.Bardsley@arm.comdef stroke_and_fill(cr, colour): 7810259SAndrew.Bardsley@arm.com """Stroke with the current colour then fill the same path with the 7910259SAndrew.Bardsley@arm.com given colour""" 8010259SAndrew.Bardsley@arm.com join = cr.get_line_join() 8110259SAndrew.Bardsley@arm.com cr.set_line_join(gtk.gdk.JOIN_ROUND) 8210259SAndrew.Bardsley@arm.com cr.close_path() 8310259SAndrew.Bardsley@arm.com cr.set_source_color(backgroundColour) 8410259SAndrew.Bardsley@arm.com cr.stroke_preserve() 8510259SAndrew.Bardsley@arm.com cr.set_source_color(colour) 8610259SAndrew.Bardsley@arm.com cr.fill() 8710259SAndrew.Bardsley@arm.com cr.set_line_join(join) 8810259SAndrew.Bardsley@arm.com 8910259SAndrew.Bardsley@arm.comdef striped_box(cr, centre, size, colours): 9010259SAndrew.Bardsley@arm.com """Fill a rectangle (without outline) striped with the colours given""" 9110259SAndrew.Bardsley@arm.com num_colours = len(colours) 9210259SAndrew.Bardsley@arm.com if num_colours == 0: 9310259SAndrew.Bardsley@arm.com box(cr, centre, size) 9410259SAndrew.Bardsley@arm.com cr.set_source_color(backgroundColour) 9510259SAndrew.Bardsley@arm.com cr.fill() 9610259SAndrew.Bardsley@arm.com elif num_colours == 1: 9710259SAndrew.Bardsley@arm.com box(cr, centre, size) 9810259SAndrew.Bardsley@arm.com stroke_and_fill(cr, colours[0]) 9910259SAndrew.Bardsley@arm.com else: 10010259SAndrew.Bardsley@arm.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 10110259SAndrew.Bardsley@arm.com (width, height) = size.to_pair() 10210259SAndrew.Bardsley@arm.com x_stripe_width = width / num_colours 10310259SAndrew.Bardsley@arm.com half_x_stripe_width = x_stripe_width / 2.0 10410259SAndrew.Bardsley@arm.com # Left triangle 10510259SAndrew.Bardsley@arm.com cr.move_to(left, bottom) 10610259SAndrew.Bardsley@arm.com cr.line_to(left + half_x_stripe_width, bottom) 10710259SAndrew.Bardsley@arm.com cr.line_to(left + x_stripe_width + half_x_stripe_width, top) 10810259SAndrew.Bardsley@arm.com cr.line_to(left, top) 10910259SAndrew.Bardsley@arm.com stroke_and_fill(cr, colours[0]) 11010259SAndrew.Bardsley@arm.com # Stripes 11110259SAndrew.Bardsley@arm.com for i in xrange(1, num_colours - 1): 11210259SAndrew.Bardsley@arm.com xOffset = x_stripe_width * i 11310259SAndrew.Bardsley@arm.com cr.move_to(left + xOffset - half_x_stripe_width, bottom) 11410259SAndrew.Bardsley@arm.com cr.line_to(left + xOffset + half_x_stripe_width, bottom) 11510259SAndrew.Bardsley@arm.com cr.line_to(left + xOffset + x_stripe_width + 11610259SAndrew.Bardsley@arm.com half_x_stripe_width, top) 11710259SAndrew.Bardsley@arm.com cr.line_to(left + xOffset + x_stripe_width - 11810259SAndrew.Bardsley@arm.com half_x_stripe_width, top) 11910259SAndrew.Bardsley@arm.com stroke_and_fill(cr, colours[i]) 12010259SAndrew.Bardsley@arm.com # Right triangle 12110259SAndrew.Bardsley@arm.com cr.move_to((right - x_stripe_width) - half_x_stripe_width, bottom) 12210259SAndrew.Bardsley@arm.com cr.line_to(right, bottom) 12310259SAndrew.Bardsley@arm.com cr.line_to(right, top) 12410259SAndrew.Bardsley@arm.com cr.line_to((right - x_stripe_width) + half_x_stripe_width, top) 12510259SAndrew.Bardsley@arm.com stroke_and_fill(cr, colours[num_colours - 1]) 12610259SAndrew.Bardsley@arm.com 12710259SAndrew.Bardsley@arm.comdef speech_bubble(cr, top_left, size, unit): 12810259SAndrew.Bardsley@arm.com """Draw a speech bubble with 'size'-sized internal space with its 12910259SAndrew.Bardsley@arm.com top left corner at Point(2.0 * unit, 2.0 * unit)""" 13010259SAndrew.Bardsley@arm.com def local_arc(centre, angleFrom, angleTo): 13110259SAndrew.Bardsley@arm.com cr.arc(centre.x, centre.y, unit, angleFrom * math.pi, 13210259SAndrew.Bardsley@arm.com angleTo * math.pi) 13310259SAndrew.Bardsley@arm.com 13410259SAndrew.Bardsley@arm.com cr.move_to(*top_left.to_pair()) 13510259SAndrew.Bardsley@arm.com cr.rel_line_to(unit * 2.0, unit) 13610259SAndrew.Bardsley@arm.com cr.rel_line_to(size.x, 0.0) 13710259SAndrew.Bardsley@arm.com local_arc(top_left + Point(size.x + unit * 2.0, unit * 2.0), -0.5, 0.0) 13810259SAndrew.Bardsley@arm.com cr.rel_line_to(0.0, size.y) 13910259SAndrew.Bardsley@arm.com local_arc(top_left + Point(size.x + unit * 2.0, size.y + unit * 2.0), 14010259SAndrew.Bardsley@arm.com 0, 0.5) 14110259SAndrew.Bardsley@arm.com cr.rel_line_to(-size.x, 0.0) 14210259SAndrew.Bardsley@arm.com local_arc(top_left + Point(unit * 2.0, size.y + unit * 2.0), 0.5, 1.0) 14310259SAndrew.Bardsley@arm.com cr.rel_line_to(0, -size.y) 14410259SAndrew.Bardsley@arm.com cr.close_path() 14510259SAndrew.Bardsley@arm.com 14610259SAndrew.Bardsley@arm.comdef open_bottom(cr, centre, size): 14710259SAndrew.Bardsley@arm.com """Draw a box with left, top and right sides""" 14810259SAndrew.Bardsley@arm.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 14910259SAndrew.Bardsley@arm.com cr.move_to(left, bottom) 15010259SAndrew.Bardsley@arm.com cr.line_to(left, top) 15110259SAndrew.Bardsley@arm.com cr.line_to(right, top) 15210259SAndrew.Bardsley@arm.com cr.line_to(right, bottom) 15310259SAndrew.Bardsley@arm.com 15410259SAndrew.Bardsley@arm.comdef fifo(cr, centre, size): 15510259SAndrew.Bardsley@arm.com """Draw just the vertical sides of a box""" 15610259SAndrew.Bardsley@arm.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 15710259SAndrew.Bardsley@arm.com cr.move_to(left, bottom) 15810259SAndrew.Bardsley@arm.com cr.line_to(left, top) 15910259SAndrew.Bardsley@arm.com cr.move_to(right, bottom) 16010259SAndrew.Bardsley@arm.com cr.line_to(right, top) 16110259SAndrew.Bardsley@arm.com 16210259SAndrew.Bardsley@arm.comdef cross(cr, centre, size): 16310259SAndrew.Bardsley@arm.com """Draw a cross parallel with the axes""" 16410259SAndrew.Bardsley@arm.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 16510259SAndrew.Bardsley@arm.com (x, y) = centre.to_pair() 16610259SAndrew.Bardsley@arm.com cr.move_to(left, y) 16710259SAndrew.Bardsley@arm.com cr.line_to(right, y) 16810259SAndrew.Bardsley@arm.com cr.move_to(x, top) 16910259SAndrew.Bardsley@arm.com cr.line_to(x, bottom) 17010259SAndrew.Bardsley@arm.com 17110259SAndrew.Bardsley@arm.comclass Blob(object): 17210259SAndrew.Bardsley@arm.com """Blob super class""" 17310259SAndrew.Bardsley@arm.com def __init__(self, picChar, unit, topLeft, colour, size = Point(1,1)): 17410259SAndrew.Bardsley@arm.com self.picChar = picChar 17510259SAndrew.Bardsley@arm.com self.unit = unit 17610259SAndrew.Bardsley@arm.com self.displayName = unit 17710259SAndrew.Bardsley@arm.com self.nameLoc = 'top' 17810259SAndrew.Bardsley@arm.com self.topLeft = topLeft 17910259SAndrew.Bardsley@arm.com self.colour = colour 18010259SAndrew.Bardsley@arm.com self.size = size 18110259SAndrew.Bardsley@arm.com self.border = 1.0 18210259SAndrew.Bardsley@arm.com self.dataSelect = model.BlobDataSelect() 18310259SAndrew.Bardsley@arm.com self.shorten = 0 18410259SAndrew.Bardsley@arm.com 18510259SAndrew.Bardsley@arm.com def render(self, cr, view, event, select, time): 18610259SAndrew.Bardsley@arm.com """Render this blob with the given event's data. Returns either 18710259SAndrew.Bardsley@arm.com None or a pair of (centre, size) in device coordinates for the drawn 18810259SAndrew.Bardsley@arm.com blob. The return value can be used to detect if mouse clicks on 18910259SAndrew.Bardsley@arm.com the canvas are within the blob""" 19010259SAndrew.Bardsley@arm.com return None 19110259SAndrew.Bardsley@arm.com 19210259SAndrew.Bardsley@arm.comclass Block(Blob): 19310259SAndrew.Bardsley@arm.com """Blocks are rectangular blogs colourable with a 2D grid of striped 19410259SAndrew.Bardsley@arm.com blocks. visualDecoder specifies how event data becomes this coloured 19510259SAndrew.Bardsley@arm.com grid""" 19610259SAndrew.Bardsley@arm.com def __init__(self, picChar, unit, topLeft=Point(0,0), 19710259SAndrew.Bardsley@arm.com colour=colours.black, 19810259SAndrew.Bardsley@arm.com size=Point(1,1)): 19910259SAndrew.Bardsley@arm.com super(Block,self).__init__(picChar, unit, topLeft, colour, 20010259SAndrew.Bardsley@arm.com size = size) 20110259SAndrew.Bardsley@arm.com # {horiz, vert} 20210259SAndrew.Bardsley@arm.com self.stripDir = 'horiz' 20310259SAndrew.Bardsley@arm.com # {LR, RL}: LR means the first strip will be on the left/top, 20410259SAndrew.Bardsley@arm.com # RL means the first strip will be on the right/bottom 20510259SAndrew.Bardsley@arm.com self.stripOrd = 'LR' 20610259SAndrew.Bardsley@arm.com # Number of blank strips if this is a frame 20710259SAndrew.Bardsley@arm.com self.blankStrips = 0 20810259SAndrew.Bardsley@arm.com # {box, fifo, openBottom} 20910259SAndrew.Bardsley@arm.com self.shape = 'box' 21010259SAndrew.Bardsley@arm.com self.visualDecoder = None 21110259SAndrew.Bardsley@arm.com 21210259SAndrew.Bardsley@arm.com def render(self, cr, view, event, select, time): 21310259SAndrew.Bardsley@arm.com # Find the right event, visuals and sizes for things 21410259SAndrew.Bardsley@arm.com if event is None or self.displayName.startswith('_'): 21510259SAndrew.Bardsley@arm.com event = model.BlobEvent(self.unit, time) 21610259SAndrew.Bardsley@arm.com 21710259SAndrew.Bardsley@arm.com if self.picChar in event.visuals: 21810259SAndrew.Bardsley@arm.com strips = event.visuals[self.picChar].to_striped_block( 21910259SAndrew.Bardsley@arm.com select & self.dataSelect) 22010259SAndrew.Bardsley@arm.com else: 22110259SAndrew.Bardsley@arm.com strips = [[[colours.unknownColour]]] 22210259SAndrew.Bardsley@arm.com 22310259SAndrew.Bardsley@arm.com if self.stripOrd == 'RL': 22410259SAndrew.Bardsley@arm.com strips.reverse() 22510259SAndrew.Bardsley@arm.com 22610259SAndrew.Bardsley@arm.com if len(strips) == 0: 22710259SAndrew.Bardsley@arm.com strips = [[colours.errorColour]] 22810259SAndrew.Bardsley@arm.com print 'Problem with the colour of event:', event 22910259SAndrew.Bardsley@arm.com 23010259SAndrew.Bardsley@arm.com num_strips = len(strips) 23110259SAndrew.Bardsley@arm.com strip_proportion = 1.0 / num_strips 23210259SAndrew.Bardsley@arm.com first_strip_offset = (num_strips / 2.0) - 0.5 23310259SAndrew.Bardsley@arm.com 23410259SAndrew.Bardsley@arm.com # Adjust blocks with 'shorten' attribute to the length of the data 23510259SAndrew.Bardsley@arm.com size = Point(*self.size.to_pair()) 23610259SAndrew.Bardsley@arm.com if self.shorten != 0 and self.size.x > (num_strips * self.shorten): 23710259SAndrew.Bardsley@arm.com size.x = num_strips * self.shorten 23810259SAndrew.Bardsley@arm.com 23910259SAndrew.Bardsley@arm.com box_size = size - view.blobIndentFactor.scale(2) 24010259SAndrew.Bardsley@arm.com 24110259SAndrew.Bardsley@arm.com # Now do cr sensitive things 24210259SAndrew.Bardsley@arm.com cr.save() 24310259SAndrew.Bardsley@arm.com cr.scale(*view.pitch.to_pair()) 24410259SAndrew.Bardsley@arm.com cr.translate(*self.topLeft.to_pair()) 24510259SAndrew.Bardsley@arm.com cr.translate(*(size - Point(1,1)).scale(0.5).to_pair()) 24610259SAndrew.Bardsley@arm.com 24710259SAndrew.Bardsley@arm.com translated_centre = Point(*cr.user_to_device(0.0, 0.0)) 24810259SAndrew.Bardsley@arm.com translated_size = \ 24910259SAndrew.Bardsley@arm.com Point(*cr.user_to_device_distance(*size.to_pair())) 25010259SAndrew.Bardsley@arm.com 25110259SAndrew.Bardsley@arm.com # The 2D grid is a grid of strips of blocks. Data [[1,2],[3]] 25210259SAndrew.Bardsley@arm.com # is 2 strips of 2 and 1 blocks respectively. 25310259SAndrew.Bardsley@arm.com # if stripDir == 'horiz', strips are stacked vertically 25410259SAndrew.Bardsley@arm.com # from top to bottom if stripOrd == 'LR' or bottom to top if 25510259SAndrew.Bardsley@arm.com # stripOrd == 'RL'. 25610259SAndrew.Bardsley@arm.com # if stripDir == 'vert', strips are stacked horizontally 25710259SAndrew.Bardsley@arm.com # from left to right if stripOf == 'LR' or right to left if 25810259SAndrew.Bardsley@arm.com # stripOrd == 'RL'. 25910259SAndrew.Bardsley@arm.com 26010259SAndrew.Bardsley@arm.com strip_is_horiz = self.stripDir == 'horiz' 26110259SAndrew.Bardsley@arm.com 26210259SAndrew.Bardsley@arm.com if strip_is_horiz: 26310259SAndrew.Bardsley@arm.com strip_step_base = Point(1.0,0.0) 26410259SAndrew.Bardsley@arm.com block_step_base = Point(0.0,1.0) 26510259SAndrew.Bardsley@arm.com else: 26610259SAndrew.Bardsley@arm.com strip_step_base = Point(0.0,1.0) 26710259SAndrew.Bardsley@arm.com block_step_base = Point(1.0,0.0) 26810259SAndrew.Bardsley@arm.com 26910259SAndrew.Bardsley@arm.com strip_size = (box_size * (strip_step_base.scale(strip_proportion) + 27010259SAndrew.Bardsley@arm.com block_step_base)) 27110259SAndrew.Bardsley@arm.com strip_step = strip_size * strip_step_base 27210259SAndrew.Bardsley@arm.com strip_centre = Point(0,0) - (strip_size * 27310259SAndrew.Bardsley@arm.com strip_step_base.scale(first_strip_offset)) 27410259SAndrew.Bardsley@arm.com 27510259SAndrew.Bardsley@arm.com cr.set_line_width(view.midLineWidth / view.pitch.x) 27610259SAndrew.Bardsley@arm.com 27710259SAndrew.Bardsley@arm.com # Draw the strips and their blocks 27810259SAndrew.Bardsley@arm.com for strip_index in xrange(0, num_strips): 27910259SAndrew.Bardsley@arm.com num_blocks = len(strips[strip_index]) 28010259SAndrew.Bardsley@arm.com block_proportion = 1.0 / num_blocks 28110259SAndrew.Bardsley@arm.com firstBlockOffset = (num_blocks / 2.0) - 0.5 28210259SAndrew.Bardsley@arm.com 28310259SAndrew.Bardsley@arm.com block_size = (strip_size * 28410259SAndrew.Bardsley@arm.com (block_step_base.scale(block_proportion) + 28510259SAndrew.Bardsley@arm.com strip_step_base)) 28610259SAndrew.Bardsley@arm.com block_step = block_size * block_step_base 28710259SAndrew.Bardsley@arm.com block_centre = (strip_centre + strip_step.scale(strip_index) - 28810259SAndrew.Bardsley@arm.com (block_size * block_step_base.scale(firstBlockOffset))) 28910259SAndrew.Bardsley@arm.com 29010259SAndrew.Bardsley@arm.com for block_index in xrange(0, num_blocks): 29110259SAndrew.Bardsley@arm.com striped_box(cr, block_centre + 29210259SAndrew.Bardsley@arm.com block_step.scale(block_index), block_size, 29310259SAndrew.Bardsley@arm.com strips[strip_index][block_index]) 29410259SAndrew.Bardsley@arm.com 29510259SAndrew.Bardsley@arm.com cr.set_font_size(0.7) 29610259SAndrew.Bardsley@arm.com if self.border > 0.5: 29710259SAndrew.Bardsley@arm.com weight = cairo.FONT_WEIGHT_BOLD 29810259SAndrew.Bardsley@arm.com else: 29910259SAndrew.Bardsley@arm.com weight = cairo.FONT_WEIGHT_NORMAL 30010259SAndrew.Bardsley@arm.com cr.select_font_face('Helvetica', cairo.FONT_SLANT_NORMAL, 30110259SAndrew.Bardsley@arm.com weight) 30210259SAndrew.Bardsley@arm.com 30310259SAndrew.Bardsley@arm.com xb, yb, width, height, dx, dy = cr.text_extents(self.displayName) 30410259SAndrew.Bardsley@arm.com 30510259SAndrew.Bardsley@arm.com text_comfort_space = 0.15 30610259SAndrew.Bardsley@arm.com 30710259SAndrew.Bardsley@arm.com if self.nameLoc == 'left': 30810259SAndrew.Bardsley@arm.com # Position text vertically along left side, top aligned 30910259SAndrew.Bardsley@arm.com cr.save() 31010259SAndrew.Bardsley@arm.com cr.rotate(- (math.pi / 2.0)) 31110259SAndrew.Bardsley@arm.com text_point = Point(size.y, size.x).scale(0.5) * Point(-1, -1) 31210259SAndrew.Bardsley@arm.com text_point += Point(max(0, size.y - width), 0) 31310259SAndrew.Bardsley@arm.com text_point += Point(-text_comfort_space, -text_comfort_space) 31410259SAndrew.Bardsley@arm.com else: # Including top 31510259SAndrew.Bardsley@arm.com # Position text above the top left hand corner 31610259SAndrew.Bardsley@arm.com text_point = size.scale(0.5) * Point(-1,-1) 31710259SAndrew.Bardsley@arm.com text_point += Point(0.00, -text_comfort_space) 31810259SAndrew.Bardsley@arm.com 31910259SAndrew.Bardsley@arm.com if (self.displayName != '' and 32010259SAndrew.Bardsley@arm.com not self.displayName.startswith('_')): 32110259SAndrew.Bardsley@arm.com cr.set_source_color(self.colour) 32210259SAndrew.Bardsley@arm.com cr.move_to(*text_point.to_pair()) 32310259SAndrew.Bardsley@arm.com cr.show_text(self.displayName) 32410259SAndrew.Bardsley@arm.com 32510259SAndrew.Bardsley@arm.com if self.nameLoc == 'left': 32610259SAndrew.Bardsley@arm.com cr.restore() 32710259SAndrew.Bardsley@arm.com 32810259SAndrew.Bardsley@arm.com # Draw the outline shape 32910259SAndrew.Bardsley@arm.com cr.save() 33010259SAndrew.Bardsley@arm.com if strip_is_horiz: 33110259SAndrew.Bardsley@arm.com cr.rotate(- (math.pi / 2.0)) 33210259SAndrew.Bardsley@arm.com box_size = Point(box_size.y, box_size.x) 33310259SAndrew.Bardsley@arm.com 33410259SAndrew.Bardsley@arm.com if self.stripOrd == "RL": 33510259SAndrew.Bardsley@arm.com cr.rotate(math.pi) 33610259SAndrew.Bardsley@arm.com 33710259SAndrew.Bardsley@arm.com if self.shape == 'box': 33810259SAndrew.Bardsley@arm.com box(cr, Point(0,0), box_size) 33910259SAndrew.Bardsley@arm.com elif self.shape == 'openBottom': 34010259SAndrew.Bardsley@arm.com open_bottom(cr, Point(0,0), box_size) 34110259SAndrew.Bardsley@arm.com elif self.shape == 'fifo': 34210259SAndrew.Bardsley@arm.com fifo(cr, Point(0,0), box_size) 34310259SAndrew.Bardsley@arm.com cr.restore() 34410259SAndrew.Bardsley@arm.com 34510259SAndrew.Bardsley@arm.com # Restore scale and stroke the outline 34610259SAndrew.Bardsley@arm.com cr.restore() 34710259SAndrew.Bardsley@arm.com cr.set_source_color(self.colour) 34810259SAndrew.Bardsley@arm.com cr.set_line_width(view.thickLineWidth * self.border) 34910259SAndrew.Bardsley@arm.com cr.stroke() 35010259SAndrew.Bardsley@arm.com 35110259SAndrew.Bardsley@arm.com # Return blob size/position 35210259SAndrew.Bardsley@arm.com if self.unit == '_': 35310259SAndrew.Bardsley@arm.com return None 35410259SAndrew.Bardsley@arm.com else: 35510259SAndrew.Bardsley@arm.com return (translated_centre, translated_size) 35610259SAndrew.Bardsley@arm.com 35710259SAndrew.Bardsley@arm.comclass Key(Blob): 35810259SAndrew.Bardsley@arm.com """Draw a key to the special (and numeric colours) with swatches of the 35910259SAndrew.Bardsley@arm.com colours half as wide as the key""" 36010259SAndrew.Bardsley@arm.com def __init__(self, picChar, unit, topLeft, colour=colours.black, 36110259SAndrew.Bardsley@arm.com size=Point(1,1)): 36210259SAndrew.Bardsley@arm.com super(Key,self).__init__(picChar, unit, topLeft, colour, size = size) 36310259SAndrew.Bardsley@arm.com self.colours = 'BBBB' 36410259SAndrew.Bardsley@arm.com self.displayName = unit 36510259SAndrew.Bardsley@arm.com 36610259SAndrew.Bardsley@arm.com def render(self, cr, view, event, select, time): 36710259SAndrew.Bardsley@arm.com cr.save() 36810259SAndrew.Bardsley@arm.com cr.scale(*view.pitch.to_pair()) 36910259SAndrew.Bardsley@arm.com cr.translate(*self.topLeft.to_pair()) 37010259SAndrew.Bardsley@arm.com # cr.translate(*(self.size - Point(1,1)).scale(0.5).to_pair()) 37110259SAndrew.Bardsley@arm.com half_width = self.size.x / 2.0 37210259SAndrew.Bardsley@arm.com cr.translate(*(self.size - Point(1.0 + half_width,1.0)).scale(0.5). 37310259SAndrew.Bardsley@arm.com to_pair()) 37410259SAndrew.Bardsley@arm.com 37510259SAndrew.Bardsley@arm.com num_colours = len(self.colours) 37610259SAndrew.Bardsley@arm.com cr.set_line_width(view.midLineWidth / view.pitch.x) 37710259SAndrew.Bardsley@arm.com 37810259SAndrew.Bardsley@arm.com blob_size = (Point(half_width,0.0) + 37910259SAndrew.Bardsley@arm.com (self.size * Point(0.0,1.0 / num_colours))) 38010259SAndrew.Bardsley@arm.com blob_step = Point(0.0,1.0) * blob_size 38110259SAndrew.Bardsley@arm.com first_blob_centre = (Point(0.0,0.0) - 38210259SAndrew.Bardsley@arm.com blob_step.scale((num_colours / 2.0) - 0.5)) 38310259SAndrew.Bardsley@arm.com 38410259SAndrew.Bardsley@arm.com cr.set_source_color(self.colour) 38510259SAndrew.Bardsley@arm.com cr.set_line_width(view.thinLineWidth / view.pitch.x) 38610259SAndrew.Bardsley@arm.com 38710259SAndrew.Bardsley@arm.com blob_proportion = 0.8 38810259SAndrew.Bardsley@arm.com 38910259SAndrew.Bardsley@arm.com real_blob_size = blob_size.scale(blob_proportion) 39010259SAndrew.Bardsley@arm.com 39110259SAndrew.Bardsley@arm.com cr.set_font_size(0.8 * blob_size.y * blob_proportion) 39210259SAndrew.Bardsley@arm.com cr.select_font_face('Helvetica', cairo.FONT_SLANT_NORMAL, 39310259SAndrew.Bardsley@arm.com cairo.FONT_WEIGHT_BOLD) 39410259SAndrew.Bardsley@arm.com 39510259SAndrew.Bardsley@arm.com for i in xrange(0, num_colours): 39610259SAndrew.Bardsley@arm.com centre = first_blob_centre + blob_step.scale(i) 39710259SAndrew.Bardsley@arm.com box(cr, centre, real_blob_size) 39810259SAndrew.Bardsley@arm.com 39910259SAndrew.Bardsley@arm.com colour_char = self.colours[i] 40010259SAndrew.Bardsley@arm.com if colour_char.isdigit(): 40110259SAndrew.Bardsley@arm.com cr.set_source_color(colours.number_to_colour( 40210259SAndrew.Bardsley@arm.com int(colour_char))) 40310259SAndrew.Bardsley@arm.com label = '...' + colour_char 40410259SAndrew.Bardsley@arm.com else: 40510259SAndrew.Bardsley@arm.com cr.set_source_color(model.special_state_colours[colour_char]) 40610259SAndrew.Bardsley@arm.com label = model.special_state_names[colour_char] 40710259SAndrew.Bardsley@arm.com 40810259SAndrew.Bardsley@arm.com cr.fill_preserve() 40910259SAndrew.Bardsley@arm.com cr.set_source_color(self.colour) 41010259SAndrew.Bardsley@arm.com cr.stroke() 41110259SAndrew.Bardsley@arm.com 41210259SAndrew.Bardsley@arm.com xb, yb, width, height, dx, dy = cr.text_extents(label) 41310259SAndrew.Bardsley@arm.com 41410259SAndrew.Bardsley@arm.com text_left = (centre + (Point(0.5,0.0) * blob_size) + 41510259SAndrew.Bardsley@arm.com Point(0.0, height / 2.0)) 41610259SAndrew.Bardsley@arm.com 41710259SAndrew.Bardsley@arm.com cr.move_to(*text_left.to_pair()) 41810259SAndrew.Bardsley@arm.com cr.show_text(label) 41910259SAndrew.Bardsley@arm.com 42010259SAndrew.Bardsley@arm.comclass Arrow(Blob): 42110259SAndrew.Bardsley@arm.com """Draw a left or right facing arrow""" 42210259SAndrew.Bardsley@arm.com def __init__(self, unit, topLeft, colour=colours.black, 42310259SAndrew.Bardsley@arm.com size=Point(1.0,1.0), direc='right'): 42410259SAndrew.Bardsley@arm.com super(Arrow,self).__init__(unit, unit, topLeft, colour, size = size) 42510259SAndrew.Bardsley@arm.com self.direc = direc 42610259SAndrew.Bardsley@arm.com 42710259SAndrew.Bardsley@arm.com def render(self, cr, view, event, select, time): 42810259SAndrew.Bardsley@arm.com cr.save() 42910259SAndrew.Bardsley@arm.com cr.scale(*view.pitch.to_pair()) 43010259SAndrew.Bardsley@arm.com cr.translate(*self.topLeft.to_pair()) 43110259SAndrew.Bardsley@arm.com cr.translate(*(self.size - Point(1,1)).scale(0.5).to_pair()) 43210259SAndrew.Bardsley@arm.com cr.scale(*self.size.to_pair()) 43310259SAndrew.Bardsley@arm.com (blob_indent_x, blob_indent_y) = \ 43410259SAndrew.Bardsley@arm.com (view.blobIndentFactor / self.size).to_pair() 43510259SAndrew.Bardsley@arm.com left = -0.5 - blob_indent_x 43610259SAndrew.Bardsley@arm.com right = 0.5 + blob_indent_x 43710259SAndrew.Bardsley@arm.com 43810259SAndrew.Bardsley@arm.com thickness = 0.2 43910259SAndrew.Bardsley@arm.com flare = 0.2 44010259SAndrew.Bardsley@arm.com 44110259SAndrew.Bardsley@arm.com if self.direc == 'left': 44210259SAndrew.Bardsley@arm.com cr.rotate(math.pi) 44310259SAndrew.Bardsley@arm.com 44410259SAndrew.Bardsley@arm.com cr.move_to(left, -thickness) 44510259SAndrew.Bardsley@arm.com cr.line_to(0.0, -thickness) 44610259SAndrew.Bardsley@arm.com cr.line_to(0.0, -(thickness + flare)) 44710259SAndrew.Bardsley@arm.com cr.line_to(right, 0) 44810259SAndrew.Bardsley@arm.com # Break arrow to prevent the point ruining the appearance of boxes 44910259SAndrew.Bardsley@arm.com cr.move_to(right, 0) 45010259SAndrew.Bardsley@arm.com cr.line_to(0.0, (thickness + flare)) 45110259SAndrew.Bardsley@arm.com cr.line_to(0.0, +thickness) 45210259SAndrew.Bardsley@arm.com cr.line_to(left, +thickness) 45310259SAndrew.Bardsley@arm.com 45410259SAndrew.Bardsley@arm.com cr.restore() 45510259SAndrew.Bardsley@arm.com 45610259SAndrew.Bardsley@arm.com # Draw arrow a bit more lightly than the standard line width 45710259SAndrew.Bardsley@arm.com cr.set_line_width(cr.get_line_width() * 0.75) 45810259SAndrew.Bardsley@arm.com cr.set_source_color(self.colour) 45910259SAndrew.Bardsley@arm.com cr.stroke() 46010259SAndrew.Bardsley@arm.com 46110259SAndrew.Bardsley@arm.com return None 462