Skip to content

Commit

Permalink
let MemoryRegion create its own images
Browse files Browse the repository at this point in the history
  • Loading branch information
cracked-machine committed Feb 9, 2024
1 parent 79b36ae commit 0ce59a2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 43 deletions.
10 changes: 5 additions & 5 deletions doc/example/report.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
![memory map diagram](report.png)
|name|origin|size|remaining|collisions
|:-|:-|:-|:-|:-|
|<span style='color:darkblue'>kernel</span>|0x10|0x50|-0x10|{'rootfs': '0x50'}|
|<span style='color:rebeccapurple'>uboot</span>|0xD0|0x50|-0x10|{'uboot-scr': '0x110'}|
|<span style='color:slategray'>rootfs</span>|0x50|0x30|0x10|{'kernel': '0x50'}|
|<span style='color:mediumaquamarine'>dtb</span>|0x90|0x30|0x10|{}|
|<span style='color:deepskyblue'>uboot-scr</span>|0x110|0x30|0x50|{'uboot': '0x110'}|
|<span style='color:cornflowerblue'>kernel</span>|0x10|0x50|-0x10|{'rootfs': '0x50'}|
|<span style='color:limegreen'>uboot</span>|0xD0|0x50|-0x10|{'uboot-scr': '0x110'}|
|<span style='color:lightskyblue'>rootfs</span>|0x50|0x30|0x10|{'kernel': '0x50'}|
|<span style='color:mediumspringgreen'>dtb</span>|0x90|0x30|0x10|{}|
|<span style='color:lawngreen'>uboot-scr</span>|0x110|0x30|0x50|{'uboot': '0x110'}|
Binary file modified doc/example/report.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 6 additions & 37 deletions mm/diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
@typeguard.typechecked
class MemoryMap:

height = 400
height: int = 400
"""height of the diagram image"""
width = 400
width: int = 400
"""width of the diagram image"""
bgcolour = "oldlace"

Expand Down Expand Up @@ -64,41 +64,10 @@ def _create_diagram(self, region_list: List[mm.types.MemoryRegion]):
# to the main image object (img_main)
for region in region_list:

logging.info(region)
if not region.size:
logging.warning("Zero size region skipped")
region.create_img(img_width=MemoryMap.width - self._legend_width)
if not region.img:
continue

# MemoryRegion Blocks and text
region_img = PIL.Image.new("RGBA", (MemoryMap.width - self._legend_width, region.size), color=(255, 255, 0, 5))
region_canvas = PIL.ImageDraw.Draw(region_img)

region_canvas.rectangle(
(0, 0, MemoryMap.width - 1, region.size - 1),
fill=region.colour,
outline="black",
width=1,
)

# draw name text
ntext_img_width = 60
ntext_img_height = 7
ntext_font = PIL.ImageFont.load_default(ntext_img_height)
ntext_img = PIL.Image.new("RGB", (ntext_img_width, ntext_img_height), color=MemoryMap.bgcolour)

ntext_canvas = PIL.ImageDraw.Draw(ntext_img)

_, _, ntext_width, ntext_height = ntext_canvas.textbbox(
(0, 0), region.name, font=ntext_font)

ntext_canvas.text(((ntext_img_width-ntext_width)/2,
(ntext_img_height-ntext_height)/2-1),
region.name, fill="black",
font=ntext_font)

ntext_img = ntext_img.rotate(180)
region_img.paste(ntext_img, (5, 5))

# Address Text
addr_text_font = PIL.ImageFont.load_default(8)
# add text for the region origin
Expand All @@ -118,9 +87,9 @@ def _create_diagram(self, region_list: List[mm.types.MemoryRegion]):
for x in range(40, 90, 4):
line_canvas.line((x, endaddr - line_width, x+2, endaddr - line_width), fill="black", width=line_width)
line_canvas.line((x, region.origin - line_width, x+2, region.origin - line_width), fill="black", width=1)

# paste all the layers onto the main image
img_main.paste(region_img, (self._legend_width + region.draw_indent, region.origin), region_img)
img_main.paste(region.img, (self._legend_width + region.draw_indent, region.origin), region.img)
img_main.paste(endaddr_text_img, (0, endaddr - 6))
img_main.paste(origin_text_img, (0, region.origin - 4))

Expand Down
54 changes: 53 additions & 1 deletion mm/types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import typeguard
import random
import PIL.Image
import PIL.ImageDraw
import PIL.ImageColor
from typing import List, Dict
import logging
Expand All @@ -21,11 +23,19 @@ def __init__(self, name: str, origin: str, size: str):
"""size in bytes"""
self.colour = self._pick_available_colour()
"""random colour for region block"""
self.bordercolour = "black"
"""The border colour to use for the region"""
self.remain: str = None
"""Number of bytes until next region block"""
self.collisons: Dict(str, str) = {}
"""Map of collision regions by name (str) and distance (hex)"""
self.draw_indent = 0
"""Index counter for incrementally shrinking the drawing indent"""
self.txtlbl_bgcolour = "oldlace"
"""The background colour to use for the region text label"""
self.txtlbl_fgcolour = "black"
"""The foreground colour to use for the region text label"""
self.img: PIL.Image

# both 'lightslategray' and 'lightslategrey' are the same colour
# and we don't want duplicate colours in our diagram
Expand Down Expand Up @@ -131,9 +141,51 @@ def calc_nearest_region(self, region_list: List['MemoryRegion']):

@typeguard.typechecked
class MemoryRegion(Region):
pass

def create_img(self, img_width: int):

logging.info(self)
if not self.size:
logging.warning("Zero size region skipped")
return None

# MemoryRegion Blocks and text
region_img = PIL.Image.new("RGBA", (img_width, self.size), color="white")
self.region_canvas = PIL.ImageDraw.Draw(region_img)

# height is -1 to avoid clipping the top border
self.region_canvas.rectangle(
(0, 0, img_width, self.size - 1),
fill=self.colour,
outline=self.bordercolour,
width=1,
)

# draw name text
ntext_img_width = 60
ntext_img_height = 7
ntext_font = PIL.ImageFont.load_default(ntext_img_height)
ntext_img = PIL.Image.new("RGB", (ntext_img_width, ntext_img_height), color=self.txtlbl_bgcolour)

ntext_canvas = PIL.ImageDraw.Draw(ntext_img)

_, _, ntext_width, ntext_height = ntext_canvas.textbbox(
(0, 0), self.name, font=ntext_font)

ntext_canvas.text(((ntext_img_width-ntext_width)/2,
(ntext_img_height-ntext_height)/2-1),
self.name, fill=self.txtlbl_fgcolour,
font=ntext_font)

ntext_img = ntext_img.rotate(180)
region_img.paste(ntext_img, (5, 5))

self.img = region_img


@typeguard.typechecked
class SkippableRegion(Region):
pass



0 comments on commit 0ce59a2

Please sign in to comment.