blobs.py revision 10259:ebb376f73dd2
12929Sktlim@umich.edu# Copyright (c) 2013 ARM Limited 22929Sktlim@umich.edu# All rights reserved 32932Sktlim@umich.edu# 42929Sktlim@umich.edu# The license below extends only to copyright in the software and shall 52929Sktlim@umich.edu# not be construed as granting a license to any other intellectual 62929Sktlim@umich.edu# property including but not limited to intellectual property relating 72929Sktlim@umich.edu# to a hardware implementation of the functionality of the software 82929Sktlim@umich.edu# licensed hereunder. You may use the software subject to the license 92929Sktlim@umich.edu# terms below provided that you ensure that this notice is replicated 102929Sktlim@umich.edu# unmodified and in its entirety in all distributions of the software, 112929Sktlim@umich.edu# modified or unmodified, in source code or in binary form. 122929Sktlim@umich.edu# 132929Sktlim@umich.edu# Redistribution and use in source and binary forms, with or without 142929Sktlim@umich.edu# modification, are permitted provided that the following conditions are 152929Sktlim@umich.edu# met: redistributions of source code must retain the above copyright 162929Sktlim@umich.edu# notice, this list of conditions and the following disclaimer; 172929Sktlim@umich.edu# redistributions in binary form must reproduce the above copyright 182929Sktlim@umich.edu# notice, this list of conditions and the following disclaimer in the 192929Sktlim@umich.edu# documentation and/or other materials provided with the distribution; 202929Sktlim@umich.edu# neither the name of the copyright holders nor the names of its 212929Sktlim@umich.edu# contributors may be used to endorse or promote products derived from 222929Sktlim@umich.edu# this software without specific prior written permission. 232929Sktlim@umich.edu# 242929Sktlim@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 252929Sktlim@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 262929Sktlim@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 272929Sktlim@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 282932Sktlim@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 292932Sktlim@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 302932Sktlim@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 312929Sktlim@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 326007Ssteve.reinhardt@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 337735SAli.Saidi@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 342929Sktlim@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 352929Sktlim@umich.edu# 362929Sktlim@umich.edu# Authors: Andrew Bardsley 372929Sktlim@umich.edu# 382929Sktlim@umich.edu# blobs.py: Blobs are the visual blocks, arrows and other coloured 392929Sktlim@umich.edu# objects on the visualiser. This file contains Blob definition and 402929Sktlim@umich.edu# their rendering instructions in pygtk/cairo. 418947Sandreas.hansson@arm.com# 428947Sandreas.hansson@arm.com 438947Sandreas.hansson@arm.comimport pygtk 442929Sktlim@umich.edupygtk.require('2.0') 452929Sktlim@umich.eduimport gtk 462929Sktlim@umich.eduimport gobject 472929Sktlim@umich.eduimport cairo 482929Sktlim@umich.eduimport re 492929Sktlim@umich.eduimport math 506007Ssteve.reinhardt@amd.com 516007Ssteve.reinhardt@amd.comfrom point import Point 526007Ssteve.reinhardt@amd.comimport parse 536007Ssteve.reinhardt@amd.comimport colours 546007Ssteve.reinhardt@amd.comfrom colours import backgroundColour, black 556007Ssteve.reinhardt@amd.comimport model 566007Ssteve.reinhardt@amd.com 576007Ssteve.reinhardt@amd.comdef centre_size_to_sides(centre, size): 586007Ssteve.reinhardt@amd.com """Returns a 4-tuple of the relevant ordinates of the left, 596007Ssteve.reinhardt@amd.com right, top and bottom sides of the described rectangle""" 606007Ssteve.reinhardt@amd.com (x, y) = centre.to_pair() 616007Ssteve.reinhardt@amd.com (half_width, half_height) = (size.scale(0.5)).to_pair() 626007Ssteve.reinhardt@amd.com left = x - half_width 636007Ssteve.reinhardt@amd.com right = x + half_width 646007Ssteve.reinhardt@amd.com top = y - half_height 656007Ssteve.reinhardt@amd.com bottom = y + half_height 666007Ssteve.reinhardt@amd.com return (left, right, top, bottom) 676007Ssteve.reinhardt@amd.com 686007Ssteve.reinhardt@amd.comdef box(cr, centre, size): 696007Ssteve.reinhardt@amd.com """Draw a simple box""" 706007Ssteve.reinhardt@amd.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 716007Ssteve.reinhardt@amd.com cr.move_to(left, top) 726007Ssteve.reinhardt@amd.com cr.line_to(right, top) 736007Ssteve.reinhardt@amd.com cr.line_to(right, bottom) 746007Ssteve.reinhardt@amd.com cr.line_to(left, bottom) 756007Ssteve.reinhardt@amd.com cr.close_path() 766007Ssteve.reinhardt@amd.com 776007Ssteve.reinhardt@amd.comdef stroke_and_fill(cr, colour): 786007Ssteve.reinhardt@amd.com """Stroke with the current colour then fill the same path with the 792929Sktlim@umich.edu given colour""" 802929Sktlim@umich.edu join = cr.get_line_join() 812929Sktlim@umich.edu cr.set_line_join(gtk.gdk.JOIN_ROUND) 826007Ssteve.reinhardt@amd.com cr.close_path() 836007Ssteve.reinhardt@amd.com cr.set_source_color(backgroundColour) 846007Ssteve.reinhardt@amd.com cr.stroke_preserve() 856007Ssteve.reinhardt@amd.com cr.set_source_color(colour) 866007Ssteve.reinhardt@amd.com cr.fill() 876007Ssteve.reinhardt@amd.com cr.set_line_join(join) 882929Sktlim@umich.edu 892929Sktlim@umich.edudef striped_box(cr, centre, size, colours): 902929Sktlim@umich.edu """Fill a rectangle (without outline) striped with the colours given""" 912929Sktlim@umich.edu num_colours = len(colours) 922929Sktlim@umich.edu if num_colours == 0: 936011Ssteve.reinhardt@amd.com box(cr, centre, size) 946007Ssteve.reinhardt@amd.com cr.set_source_color(backgroundColour) 956007Ssteve.reinhardt@amd.com cr.fill() 966007Ssteve.reinhardt@amd.com elif num_colours == 1: 976007Ssteve.reinhardt@amd.com box(cr, centre, size) 986007Ssteve.reinhardt@amd.com stroke_and_fill(cr, colours[0]) 996007Ssteve.reinhardt@amd.com else: 1006007Ssteve.reinhardt@amd.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 1016007Ssteve.reinhardt@amd.com (width, height) = size.to_pair() 1026007Ssteve.reinhardt@amd.com x_stripe_width = width / num_colours 1036007Ssteve.reinhardt@amd.com half_x_stripe_width = x_stripe_width / 2.0 1046007Ssteve.reinhardt@amd.com # Left triangle 1056007Ssteve.reinhardt@amd.com cr.move_to(left, bottom) 1066007Ssteve.reinhardt@amd.com cr.line_to(left + half_x_stripe_width, bottom) 1076007Ssteve.reinhardt@amd.com cr.line_to(left + x_stripe_width + half_x_stripe_width, top) 1087735SAli.Saidi@ARM.com cr.line_to(left, top) 1096011Ssteve.reinhardt@amd.com stroke_and_fill(cr, colours[0]) 1106007Ssteve.reinhardt@amd.com # Stripes 1116007Ssteve.reinhardt@amd.com for i in xrange(1, num_colours - 1): 1126007Ssteve.reinhardt@amd.com xOffset = x_stripe_width * i 1136007Ssteve.reinhardt@amd.com cr.move_to(left + xOffset - half_x_stripe_width, bottom) 1147735SAli.Saidi@ARM.com cr.line_to(left + xOffset + half_x_stripe_width, bottom) 1157735SAli.Saidi@ARM.com cr.line_to(left + xOffset + x_stripe_width + 1167735SAli.Saidi@ARM.com half_x_stripe_width, top) 1177735SAli.Saidi@ARM.com cr.line_to(left + xOffset + x_stripe_width - 1187735SAli.Saidi@ARM.com half_x_stripe_width, top) 1197735SAli.Saidi@ARM.com stroke_and_fill(cr, colours[i]) 1207735SAli.Saidi@ARM.com # Right triangle 1217735SAli.Saidi@ARM.com cr.move_to((right - x_stripe_width) - half_x_stripe_width, bottom) 1227735SAli.Saidi@ARM.com cr.line_to(right, bottom) 1237735SAli.Saidi@ARM.com cr.line_to(right, top) 1247735SAli.Saidi@ARM.com cr.line_to((right - x_stripe_width) + half_x_stripe_width, top) 1257735SAli.Saidi@ARM.com stroke_and_fill(cr, colours[num_colours - 1]) 1267735SAli.Saidi@ARM.com 1277735SAli.Saidi@ARM.comdef speech_bubble(cr, top_left, size, unit): 1286007Ssteve.reinhardt@amd.com """Draw a speech bubble with 'size'-sized internal space with its 1298599Ssteve.reinhardt@amd.com top left corner at Point(2.0 * unit, 2.0 * unit)""" 1308599Ssteve.reinhardt@amd.com def local_arc(centre, angleFrom, angleTo): 1318599Ssteve.reinhardt@amd.com cr.arc(centre.x, centre.y, unit, angleFrom * math.pi, 1326007Ssteve.reinhardt@amd.com angleTo * math.pi) 1336011Ssteve.reinhardt@amd.com 1346007Ssteve.reinhardt@amd.com cr.move_to(*top_left.to_pair()) 1356007Ssteve.reinhardt@amd.com cr.rel_line_to(unit * 2.0, unit) 1366007Ssteve.reinhardt@amd.com cr.rel_line_to(size.x, 0.0) 1376007Ssteve.reinhardt@amd.com local_arc(top_left + Point(size.x + unit * 2.0, unit * 2.0), -0.5, 0.0) 1386007Ssteve.reinhardt@amd.com cr.rel_line_to(0.0, size.y) 1396007Ssteve.reinhardt@amd.com local_arc(top_left + Point(size.x + unit * 2.0, size.y + unit * 2.0), 1406011Ssteve.reinhardt@amd.com 0, 0.5) 1416007Ssteve.reinhardt@amd.com cr.rel_line_to(-size.x, 0.0) 1426007Ssteve.reinhardt@amd.com local_arc(top_left + Point(unit * 2.0, size.y + unit * 2.0), 0.5, 1.0) 1436007Ssteve.reinhardt@amd.com cr.rel_line_to(0, -size.y) 1446007Ssteve.reinhardt@amd.com cr.close_path() 1456007Ssteve.reinhardt@amd.com 1466008Ssteve.reinhardt@amd.comdef open_bottom(cr, centre, size): 1476007Ssteve.reinhardt@amd.com """Draw a box with left, top and right sides""" 1486008Ssteve.reinhardt@amd.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 1496008Ssteve.reinhardt@amd.com cr.move_to(left, bottom) 1506008Ssteve.reinhardt@amd.com cr.line_to(left, top) 1516008Ssteve.reinhardt@amd.com cr.line_to(right, top) 1526008Ssteve.reinhardt@amd.com cr.line_to(right, bottom) 1536008Ssteve.reinhardt@amd.com 1546008Ssteve.reinhardt@amd.comdef fifo(cr, centre, size): 1556007Ssteve.reinhardt@amd.com """Draw just the vertical sides of a box""" 1566007Ssteve.reinhardt@amd.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 1576007Ssteve.reinhardt@amd.com cr.move_to(left, bottom) 1586007Ssteve.reinhardt@amd.com cr.line_to(left, top) 1596007Ssteve.reinhardt@amd.com cr.move_to(right, bottom) 1602929Sktlim@umich.edu cr.line_to(right, top) 1612929Sktlim@umich.edu 1622929Sktlim@umich.edudef cross(cr, centre, size): 1632929Sktlim@umich.edu """Draw a cross parallel with the axes""" 1646007Ssteve.reinhardt@amd.com (left, right, top, bottom) = centre_size_to_sides(centre, size) 1656007Ssteve.reinhardt@amd.com (x, y) = centre.to_pair() 1662929Sktlim@umich.edu cr.move_to(left, y) 1672929Sktlim@umich.edu cr.line_to(right, y) 1682929Sktlim@umich.edu cr.move_to(x, top) 1692929Sktlim@umich.edu cr.line_to(x, bottom) 1706007Ssteve.reinhardt@amd.com 1716007Ssteve.reinhardt@amd.comclass Blob(object): 1722929Sktlim@umich.edu """Blob super class""" 1732929Sktlim@umich.edu def __init__(self, picChar, unit, topLeft, colour, size = Point(1,1)): 1746007Ssteve.reinhardt@amd.com self.picChar = picChar 1752929Sktlim@umich.edu self.unit = unit 1762929Sktlim@umich.edu self.displayName = unit 1778947Sandreas.hansson@arm.com self.nameLoc = 'top' 1788947Sandreas.hansson@arm.com self.topLeft = topLeft 1798947Sandreas.hansson@arm.com self.colour = colour 1808947Sandreas.hansson@arm.com self.size = size 1818947Sandreas.hansson@arm.com self.border = 1.0 1828947Sandreas.hansson@arm.com self.dataSelect = model.BlobDataSelect() 1838947Sandreas.hansson@arm.com self.shorten = 0 1848947Sandreas.hansson@arm.com 1858947Sandreas.hansson@arm.com def render(self, cr, view, event, select, time): 1868947Sandreas.hansson@arm.com """Render this blob with the given event's data. Returns either 1878947Sandreas.hansson@arm.com None or a pair of (centre, size) in device coordinates for the drawn 1888947Sandreas.hansson@arm.com blob. The return value can be used to detect if mouse clicks on 1898947Sandreas.hansson@arm.com the canvas are within the blob""" 1908947Sandreas.hansson@arm.com return None 1918947Sandreas.hansson@arm.com 1928947Sandreas.hansson@arm.comclass Block(Blob): 1938947Sandreas.hansson@arm.com """Blocks are rectangular blogs colourable with a 2D grid of striped 1948947Sandreas.hansson@arm.com blocks. visualDecoder specifies how event data becomes this coloured 1958947Sandreas.hansson@arm.com grid""" 1968947Sandreas.hansson@arm.com def __init__(self, picChar, unit, topLeft=Point(0,0), 1972929Sktlim@umich.edu colour=colours.black, 1982929Sktlim@umich.edu size=Point(1,1)): 1992929Sktlim@umich.edu super(Block,self).__init__(picChar, unit, topLeft, colour, 2002929Sktlim@umich.edu size = size) 2014937Sstever@gmail.com # {horiz, vert} 2024937Sstever@gmail.com self.stripDir = 'horiz' 2034937Sstever@gmail.com # {LR, RL}: LR means the first strip will be on the left/top, 2044937Sstever@gmail.com # RL means the first strip will be on the right/bottom 2058120Sgblack@eecs.umich.edu self.stripOrd = 'LR' 2064937Sstever@gmail.com # Number of blank strips if this is a frame 2074937Sstever@gmail.com self.blankStrips = 0 2084937Sstever@gmail.com # {box, fifo, openBottom} 2094937Sstever@gmail.com self.shape = 'box' 2105773Snate@binkert.org self.visualDecoder = None 2114937Sstever@gmail.com 2124937Sstever@gmail.com def render(self, cr, view, event, select, time): 2134937Sstever@gmail.com # Find the right event, visuals and sizes for things 2142929Sktlim@umich.edu if event is None or self.displayName.startswith('_'): 2152929Sktlim@umich.edu event = model.BlobEvent(self.unit, time) 2162929Sktlim@umich.edu 2175773Snate@binkert.org if self.picChar in event.visuals: 2182929Sktlim@umich.edu strips = event.visuals[self.picChar].to_striped_block( 2192929Sktlim@umich.edu select & self.dataSelect) 2202929Sktlim@umich.edu else: 2212929Sktlim@umich.edu strips = [[[colours.unknownColour]]] 2222929Sktlim@umich.edu 2232929Sktlim@umich.edu if self.stripOrd == 'RL': 2244937Sstever@gmail.com strips.reverse() 2254937Sstever@gmail.com 2264937Sstever@gmail.com if len(strips) == 0: 2274937Sstever@gmail.com strips = [[colours.errorColour]] 2284937Sstever@gmail.com print 'Problem with the colour of event:', event 2294937Sstever@gmail.com 2304937Sstever@gmail.com num_strips = len(strips) 2314937Sstever@gmail.com strip_proportion = 1.0 / num_strips 2324937Sstever@gmail.com first_strip_offset = (num_strips / 2.0) - 0.5 2334937Sstever@gmail.com 2344937Sstever@gmail.com # Adjust blocks with 'shorten' attribute to the length of the data 2354937Sstever@gmail.com size = Point(*self.size.to_pair()) 2364937Sstever@gmail.com if self.shorten != 0 and self.size.x > (num_strips * self.shorten): 2374937Sstever@gmail.com size.x = num_strips * self.shorten 2384937Sstever@gmail.com 2392929Sktlim@umich.edu box_size = size - view.blobIndentFactor.scale(2) 2402929Sktlim@umich.edu 2412929Sktlim@umich.edu # Now do cr sensitive things 2422929Sktlim@umich.edu cr.save() 2432929Sktlim@umich.edu cr.scale(*view.pitch.to_pair()) 2442929Sktlim@umich.edu cr.translate(*self.topLeft.to_pair()) 2452929Sktlim@umich.edu cr.translate(*(size - Point(1,1)).scale(0.5).to_pair()) 2466011Ssteve.reinhardt@amd.com 2472929Sktlim@umich.edu translated_centre = Point(*cr.user_to_device(0.0, 0.0)) 2482929Sktlim@umich.edu translated_size = \ 2492929Sktlim@umich.edu Point(*cr.user_to_device_distance(*size.to_pair())) 2502929Sktlim@umich.edu 2512929Sktlim@umich.edu # The 2D grid is a grid of strips of blocks. Data [[1,2],[3]] 2522929Sktlim@umich.edu # is 2 strips of 2 and 1 blocks respectively. 2532929Sktlim@umich.edu # if stripDir == 'horiz', strips are stacked vertically 2542929Sktlim@umich.edu # from top to bottom if stripOrd == 'LR' or bottom to top if 2552997Sstever@eecs.umich.edu # stripOrd == 'RL'. 2562997Sstever@eecs.umich.edu # if stripDir == 'vert', strips are stacked horizontally 2572929Sktlim@umich.edu # from left to right if stripOf == 'LR' or right to left if 2588802Sgblack@eecs.umich.edu # stripOrd == 'RL'. 2592997Sstever@eecs.umich.edu 2602929Sktlim@umich.edu strip_is_horiz = self.stripDir == 'horiz' 2612997Sstever@eecs.umich.edu 2622997Sstever@eecs.umich.edu if strip_is_horiz: 2638802Sgblack@eecs.umich.edu strip_step_base = Point(1.0,0.0) 2642929Sktlim@umich.edu block_step_base = Point(0.0,1.0) 2652997Sstever@eecs.umich.edu else: 2662997Sstever@eecs.umich.edu strip_step_base = Point(0.0,1.0) 2672997Sstever@eecs.umich.edu block_step_base = Point(1.0,0.0) 2682997Sstever@eecs.umich.edu 2695773Snate@binkert.org strip_size = (box_size * (strip_step_base.scale(strip_proportion) + 2705773Snate@binkert.org block_step_base)) 2712997Sstever@eecs.umich.edu strip_step = strip_size * strip_step_base 2722997Sstever@eecs.umich.edu strip_centre = Point(0,0) - (strip_size * 2736007Ssteve.reinhardt@amd.com strip_step_base.scale(first_strip_offset)) 2746007Ssteve.reinhardt@amd.com 2752997Sstever@eecs.umich.edu cr.set_line_width(view.midLineWidth / view.pitch.x) 2762929Sktlim@umich.edu 2772997Sstever@eecs.umich.edu # Draw the strips and their blocks 2788120Sgblack@eecs.umich.edu for strip_index in xrange(0, num_strips): 2792997Sstever@eecs.umich.edu num_blocks = len(strips[strip_index]) 2802997Sstever@eecs.umich.edu block_proportion = 1.0 / num_blocks 2812997Sstever@eecs.umich.edu firstBlockOffset = (num_blocks / 2.0) - 0.5 2822997Sstever@eecs.umich.edu 2832997Sstever@eecs.umich.edu block_size = (strip_size * 2842929Sktlim@umich.edu (block_step_base.scale(block_proportion) + 2852997Sstever@eecs.umich.edu strip_step_base)) 2862929Sktlim@umich.edu block_step = block_size * block_step_base 2872929Sktlim@umich.edu block_centre = (strip_centre + strip_step.scale(strip_index) - 2883005Sstever@eecs.umich.edu (block_size * block_step_base.scale(firstBlockOffset))) 2893005Sstever@eecs.umich.edu 2908802Sgblack@eecs.umich.edu for block_index in xrange(0, num_blocks): 2918802Sgblack@eecs.umich.edu striped_box(cr, block_centre + 2928802Sgblack@eecs.umich.edu block_step.scale(block_index), block_size, 2938802Sgblack@eecs.umich.edu strips[strip_index][block_index]) 2948802Sgblack@eecs.umich.edu 2958802Sgblack@eecs.umich.edu cr.set_font_size(0.7) 2968802Sgblack@eecs.umich.edu if self.border > 0.5: 2978802Sgblack@eecs.umich.edu weight = cairo.FONT_WEIGHT_BOLD 2988802Sgblack@eecs.umich.edu else: 2998802Sgblack@eecs.umich.edu weight = cairo.FONT_WEIGHT_NORMAL 3008802Sgblack@eecs.umich.edu cr.select_font_face('Helvetica', cairo.FONT_SLANT_NORMAL, 3018802Sgblack@eecs.umich.edu weight) 3028889Sgeoffrey.blake@arm.com 3038889Sgeoffrey.blake@arm.com xb, yb, width, height, dx, dy = cr.text_extents(self.displayName) 3048889Sgeoffrey.blake@arm.com 3058802Sgblack@eecs.umich.edu text_comfort_space = 0.15 3068802Sgblack@eecs.umich.edu 3078802Sgblack@eecs.umich.edu if self.nameLoc == 'left': 3088802Sgblack@eecs.umich.edu # Position text vertically along left side, top aligned 3098889Sgeoffrey.blake@arm.com cr.save() 3108802Sgblack@eecs.umich.edu cr.rotate(- (math.pi / 2.0)) 3118802Sgblack@eecs.umich.edu text_point = Point(size.y, size.x).scale(0.5) * Point(-1, -1) 3128802Sgblack@eecs.umich.edu text_point += Point(max(0, size.y - width), 0) 3138802Sgblack@eecs.umich.edu text_point += Point(-text_comfort_space, -text_comfort_space) 3148802Sgblack@eecs.umich.edu else: # Including top 3153691Shsul@eecs.umich.edu # Position text above the top left hand corner 3168802Sgblack@eecs.umich.edu text_point = size.scale(0.5) * Point(-1,-1) 3178802Sgblack@eecs.umich.edu text_point += Point(0.00, -text_comfort_space) 3188802Sgblack@eecs.umich.edu 3193005Sstever@eecs.umich.edu if (self.displayName != '' and 3208492Snilay@cs.wisc.edu not self.displayName.startswith('_')): 3216928SBrad.Beckmann@amd.com cr.set_source_color(self.colour) 3226928SBrad.Beckmann@amd.com cr.move_to(*text_point.to_pair()) 3236928SBrad.Beckmann@amd.com cr.show_text(self.displayName) 3246928SBrad.Beckmann@amd.com 3256166Ssteve.reinhardt@amd.com if self.nameLoc == 'left': 3262929Sktlim@umich.edu cr.restore() 3272929Sktlim@umich.edu 3283005Sstever@eecs.umich.edu # Draw the outline shape 3298802Sgblack@eecs.umich.edu cr.save() 3302997Sstever@eecs.umich.edu if strip_is_horiz: 3316293Ssteve.reinhardt@amd.com cr.rotate(- (math.pi / 2.0)) 3326293Ssteve.reinhardt@amd.com box_size = Point(box_size.y, box_size.x) 3332929Sktlim@umich.edu 334 if self.stripOrd == "RL": 335 cr.rotate(math.pi) 336 337 if self.shape == 'box': 338 box(cr, Point(0,0), box_size) 339 elif self.shape == 'openBottom': 340 open_bottom(cr, Point(0,0), box_size) 341 elif self.shape == 'fifo': 342 fifo(cr, Point(0,0), box_size) 343 cr.restore() 344 345 # Restore scale and stroke the outline 346 cr.restore() 347 cr.set_source_color(self.colour) 348 cr.set_line_width(view.thickLineWidth * self.border) 349 cr.stroke() 350 351 # Return blob size/position 352 if self.unit == '_': 353 return None 354 else: 355 return (translated_centre, translated_size) 356 357class Key(Blob): 358 """Draw a key to the special (and numeric colours) with swatches of the 359 colours half as wide as the key""" 360 def __init__(self, picChar, unit, topLeft, colour=colours.black, 361 size=Point(1,1)): 362 super(Key,self).__init__(picChar, unit, topLeft, colour, size = size) 363 self.colours = 'BBBB' 364 self.displayName = unit 365 366 def render(self, cr, view, event, select, time): 367 cr.save() 368 cr.scale(*view.pitch.to_pair()) 369 cr.translate(*self.topLeft.to_pair()) 370 # cr.translate(*(self.size - Point(1,1)).scale(0.5).to_pair()) 371 half_width = self.size.x / 2.0 372 cr.translate(*(self.size - Point(1.0 + half_width,1.0)).scale(0.5). 373 to_pair()) 374 375 num_colours = len(self.colours) 376 cr.set_line_width(view.midLineWidth / view.pitch.x) 377 378 blob_size = (Point(half_width,0.0) + 379 (self.size * Point(0.0,1.0 / num_colours))) 380 blob_step = Point(0.0,1.0) * blob_size 381 first_blob_centre = (Point(0.0,0.0) - 382 blob_step.scale((num_colours / 2.0) - 0.5)) 383 384 cr.set_source_color(self.colour) 385 cr.set_line_width(view.thinLineWidth / view.pitch.x) 386 387 blob_proportion = 0.8 388 389 real_blob_size = blob_size.scale(blob_proportion) 390 391 cr.set_font_size(0.8 * blob_size.y * blob_proportion) 392 cr.select_font_face('Helvetica', cairo.FONT_SLANT_NORMAL, 393 cairo.FONT_WEIGHT_BOLD) 394 395 for i in xrange(0, num_colours): 396 centre = first_blob_centre + blob_step.scale(i) 397 box(cr, centre, real_blob_size) 398 399 colour_char = self.colours[i] 400 if colour_char.isdigit(): 401 cr.set_source_color(colours.number_to_colour( 402 int(colour_char))) 403 label = '...' + colour_char 404 else: 405 cr.set_source_color(model.special_state_colours[colour_char]) 406 label = model.special_state_names[colour_char] 407 408 cr.fill_preserve() 409 cr.set_source_color(self.colour) 410 cr.stroke() 411 412 xb, yb, width, height, dx, dy = cr.text_extents(label) 413 414 text_left = (centre + (Point(0.5,0.0) * blob_size) + 415 Point(0.0, height / 2.0)) 416 417 cr.move_to(*text_left.to_pair()) 418 cr.show_text(label) 419 420class Arrow(Blob): 421 """Draw a left or right facing arrow""" 422 def __init__(self, unit, topLeft, colour=colours.black, 423 size=Point(1.0,1.0), direc='right'): 424 super(Arrow,self).__init__(unit, unit, topLeft, colour, size = size) 425 self.direc = direc 426 427 def render(self, cr, view, event, select, time): 428 cr.save() 429 cr.scale(*view.pitch.to_pair()) 430 cr.translate(*self.topLeft.to_pair()) 431 cr.translate(*(self.size - Point(1,1)).scale(0.5).to_pair()) 432 cr.scale(*self.size.to_pair()) 433 (blob_indent_x, blob_indent_y) = \ 434 (view.blobIndentFactor / self.size).to_pair() 435 left = -0.5 - blob_indent_x 436 right = 0.5 + blob_indent_x 437 438 thickness = 0.2 439 flare = 0.2 440 441 if self.direc == 'left': 442 cr.rotate(math.pi) 443 444 cr.move_to(left, -thickness) 445 cr.line_to(0.0, -thickness) 446 cr.line_to(0.0, -(thickness + flare)) 447 cr.line_to(right, 0) 448 # Break arrow to prevent the point ruining the appearance of boxes 449 cr.move_to(right, 0) 450 cr.line_to(0.0, (thickness + flare)) 451 cr.line_to(0.0, +thickness) 452 cr.line_to(left, +thickness) 453 454 cr.restore() 455 456 # Draw arrow a bit more lightly than the standard line width 457 cr.set_line_width(cr.get_line_width() * 0.75) 458 cr.set_source_color(self.colour) 459 cr.stroke() 460 461 return None 462