diff --git a/doc/example/report.md b/doc/example/report.md
index 47f9455..62c79d3 100644
--- a/doc/example/report.md
+++ b/doc/example/report.md
@@ -1,8 +1,8 @@
![memory map diagram](report.png)
|name|origin|size|remaining|collisions
|:-|:-|:-|:-|:-|
-|kernel|0x10|0x50|-0x10|{'rootfs': '0x50'}|
-|uboot|0xD0|0x50|-0x10|{'uboot-scr': '0x110'}|
-|rootfs|0x50|0x30|0x10|{'kernel': '0x50'}|
-|dtb|0x90|0x30|0x10|{}|
-|uboot-scr|0x110|0x30|0x50|{'uboot': '0x110'}|
+|kernel|0x10|0x50|-0x10|{'rootfs': '0x50'}|
+|uboot|0xD0|0x50|-0x10|{'uboot-scr': '0x110'}|
+|rootfs|0x50|0x30|0x10|{'kernel': '0x50'}|
+|dtb|0x90|0x30|0x10|{}|
+|uboot-scr|0x110|0x30|0x50|{'uboot': '0x110'}|
diff --git a/doc/example/report.png b/doc/example/report.png
index 2a6951f..a5560a1 100644
Binary files a/doc/example/report.png and b/doc/example/report.png differ
diff --git a/mm/diagram.py b/mm/diagram.py
index be2ce6e..c9d304c 100644
--- a/mm/diagram.py
+++ b/mm/diagram.py
@@ -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"
@@ -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
@@ -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))
diff --git a/mm/types.py b/mm/types.py
index 93c19f2..b0d711c 100644
--- a/mm/types.py
+++ b/mm/types.py
@@ -1,5 +1,7 @@
import typeguard
import random
+import PIL.Image
+import PIL.ImageDraw
import PIL.ImageColor
from typing import List, Dict
import logging
@@ -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
@@ -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
+
+
+