Compare commits
	
		
			2 Commits
		
	
	
		
			f5ddbf4a69
			...
			9a032b1ebd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9a032b1ebd | |||
| 946f4a3b5c | 
							
								
								
									
										29
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								main.py
									
									
									
									
									
								
							| @@ -1,6 +1,29 @@ | |||||||
|  | import argparse | ||||||
|  |  | ||||||
| from schema import InstructionSetSchema | from schema import InstructionSetSchema | ||||||
|  |  | ||||||
|  | description = """Examples: | ||||||
|  |     - Default theme (black on white): | ||||||
|  |         python main.py schema.xml -o out.jpg | ||||||
|  |  | ||||||
|  |     - Dark theme (white on black): | ||||||
|  |         python main.py schema.xml -o out.jpg -c dark.json | ||||||
|  |  | ||||||
|  |     - Blueprint theme (white on blue): | ||||||
|  |         python main.py schema.xml -o out.jpg -c blueprint.json | ||||||
|  |  | ||||||
|  |     - Transparent background: | ||||||
|  |         python main.py schema.xml -o out.png -c transparent.json | ||||||
|  | """ | ||||||
|  |  | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     schema = InstructionSetSchema("example1.yaml") |     parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter) | ||||||
|     schema.save("example1_v2.jpg") |     parser.add_argument("schema", help="Path to the schema description. Accepted formats are: YAML, JSON and XML") | ||||||
|     input() |     parser.add_argument("-o", "--output", help="Output path", default="out.jpg") | ||||||
|  |     parser.add_argument("-c", "--config", help="Path to the config file", default="config.json") | ||||||
|  |     parser.add_argument("-D", "--display", help="Enable pygame display of the result", action="store_true") | ||||||
|  |      | ||||||
|  |     args = parser.parse_args() | ||||||
|  |      | ||||||
|  |     schema = InstructionSetSchema(args.schema, args.config, args.display) | ||||||
|  |     schema.save(args.output) | ||||||
							
								
								
									
										45
									
								
								renderer.py
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								renderer.py
									
									
									
									
									
								
							| @@ -1,4 +1,5 @@ | |||||||
| from __future__ import annotations | from __future__ import annotations | ||||||
|  | import os | ||||||
| from typing import TYPE_CHECKING | from typing import TYPE_CHECKING | ||||||
| if TYPE_CHECKING: | if TYPE_CHECKING: | ||||||
|     from config import Config |     from config import Config | ||||||
| @@ -14,25 +15,33 @@ class Renderer: | |||||||
|     WIDTH = 1200 |     WIDTH = 1200 | ||||||
|     HEIGHT = 800 |     HEIGHT = 800 | ||||||
|      |      | ||||||
|     def __init__(self, config: Config) -> None: |     def __init__(self, config: Config, display: bool = False) -> None: | ||||||
|         self.config = config |         self.config = config | ||||||
|  |         self.display = display | ||||||
|         pygame.init() |         pygame.init() | ||||||
|         self.win = pygame.display.set_mode([Renderer.WIDTH, Renderer.HEIGHT]) |         if self.display: | ||||||
|  |             self.win = pygame.display.set_mode([Renderer.WIDTH, Renderer.HEIGHT]) | ||||||
|  |          | ||||||
|  |         self.surf = pygame.Surface([Renderer.WIDTH, Renderer.HEIGHT], pygame.SRCALPHA) | ||||||
|         self.font = pygame.font.SysFont(self.config.DEFAULT_FONT_FAMILY, self.config.DEFAULT_FONT_SIZE) |         self.font = pygame.font.SysFont(self.config.DEFAULT_FONT_FAMILY, self.config.DEFAULT_FONT_SIZE) | ||||||
|         self.italicFont = pygame.font.SysFont(self.config.ITALIC_FONT_FAMILY, self.config.ITALIC_FONT_SIZE, italic=True) |         self.italicFont = pygame.font.SysFont(self.config.ITALIC_FONT_FAMILY, self.config.ITALIC_FONT_SIZE, italic=True) | ||||||
|          |          | ||||||
|         self.margins = self.config.MARGINS |         self.margins = self.config.MARGINS | ||||||
|      |      | ||||||
|     def render(self, schema: InstructionSetSchema) -> None: |     def render(self, schema: InstructionSetSchema) -> None: | ||||||
|          |         self.surf.fill(self.config.BACKGROUND_COLOR) | ||||||
|         self.win.fill(self.config.BACKGROUND_COLOR) |  | ||||||
|          |          | ||||||
|         self.drawStructure(schema.structures["main"], schema.structures, self.margins[3], self.margins[0]) |         self.drawStructure(schema.structures["main"], schema.structures, self.margins[3], self.margins[0]) | ||||||
|          |          | ||||||
|         pygame.display.flip() |         if self.display: | ||||||
|  |             name = os.path.basename(schema.path) | ||||||
|  |             pygame.display.set_caption(f"Rivet - {name}") | ||||||
|  |             self.win.fill(self.config.BACKGROUND_COLOR) | ||||||
|  |             self.win.blit(self.surf, [0, 0]) | ||||||
|  |             pygame.display.flip() | ||||||
|      |      | ||||||
|     def save(self, path: str) -> None: |     def save(self, path: str) -> None: | ||||||
|         pygame.image.save(self.win, path) |         pygame.image.save(self.surf, path) | ||||||
|      |      | ||||||
|     def drawStructure(self, |     def drawStructure(self, | ||||||
|                       struct: Structure, |                       struct: Structure, | ||||||
| @@ -52,20 +61,20 @@ class Renderer: | |||||||
|         startBit = struct.start |         startBit = struct.start | ||||||
|          |          | ||||||
|         # Draw rectangle around structure |         # Draw rectangle around structure | ||||||
|         pygame.draw.rect(self.win, borderCol, [bitsX, bitsY, bitsWidth, bitH], 2) |         pygame.draw.rect(self.surf, borderCol, [bitsX, bitsY, bitsWidth, bitH], 2) | ||||||
|          |          | ||||||
|         for i in range(struct.bits): |         for i in range(struct.bits): | ||||||
|             bitX = ox + i * bitW |             bitX = ox + i * bitW | ||||||
|              |              | ||||||
|             bitITxt = self.font.render(str(struct.bits - i - 1 + startBit), True, txtCol) |             bitITxt = self.font.render(str(struct.bits - i - 1 + startBit), True, txtCol) | ||||||
|             self.win.blit(bitITxt, [ |             self.surf.blit(bitITxt, [ | ||||||
|                 bitX + (bitW - bitITxt.get_width())/2, |                 bitX + (bitW - bitITxt.get_width())/2, | ||||||
|                 oy + (bitH - bitITxt.get_height())/2 |                 oy + (bitH - bitITxt.get_height())/2 | ||||||
|             ]) |             ]) | ||||||
|              |              | ||||||
|             # Draw separator |             # Draw separator | ||||||
|             if i != 0: |             if i != 0: | ||||||
|                 pygame.draw.line(self.win, borderCol, [bitX, bitsY], [bitX, bitsY + bitH]) |                 pygame.draw.line(self.surf, borderCol, [bitX, bitsY], [bitX, bitsY + bitH]) | ||||||
|          |          | ||||||
|         ranges = struct.getSortedRanges() |         ranges = struct.getSortedRanges() | ||||||
|         descX = ox + max(0, (struct.bits-12) * bitW) |         descX = ox + max(0, (struct.bits-12) * bitW) | ||||||
| @@ -81,8 +90,8 @@ class Renderer: | |||||||
|             nameTxt = self.font.render(range_.name, True, txtCol) |             nameTxt = self.font.render(range_.name, True, txtCol) | ||||||
|             nameX = rStartX + (rWidth - nameTxt.get_width())/2 |             nameX = rStartX + (rWidth - nameTxt.get_width())/2 | ||||||
|             nameY = bitsY + (bitH - nameTxt.get_height())/2 |             nameY = bitsY + (bitH - nameTxt.get_height())/2 | ||||||
|             pygame.draw.rect(self.win, bgCol, [rStartX + bitW/2, nameY, rWidth - bitW, nameTxt.get_height()], 0) |             pygame.draw.rect(self.surf, bgCol, [rStartX + bitW/2, nameY, rWidth - bitW, nameTxt.get_height()], 0) | ||||||
|             self.win.blit(nameTxt, [nameX, nameY]) |             self.surf.blit(nameTxt, [nameX, nameY]) | ||||||
|  |  | ||||||
|             if range_.description: |             if range_.description: | ||||||
|                 descX, descY = self.drawDescription(range_, rStartX, bitsY, rWidth, descX, descY) |                 descX, descY = self.drawDescription(range_, rStartX, bitsY, rWidth, descX, descY) | ||||||
| @@ -103,7 +112,7 @@ class Renderer: | |||||||
|         y0 = bitsY + bitH * 1.25 |         y0 = bitsY + bitH * 1.25 | ||||||
|         y1 = bitsY + bitH * 1.5 |         y1 = bitsY + bitH * 1.5 | ||||||
|          |          | ||||||
|         pygame.draw.lines(self.win, self.config.LINK_COLOR, False, [ |         pygame.draw.lines(self.surf, self.config.LINK_COLOR, False, [ | ||||||
|             [x0, y0], |             [x0, y0], | ||||||
|             [x0, y1], |             [x0, y1], | ||||||
|             [x1, y1], |             [x1, y1], | ||||||
| @@ -114,7 +123,7 @@ class Renderer: | |||||||
|         bitH = self.config.BIT_HEIGHT |         bitH = self.config.BIT_HEIGHT | ||||||
|         arrowMargin = self.config.ARROW_MARGIN |         arrowMargin = self.config.ARROW_MARGIN | ||||||
|          |          | ||||||
|         pygame.draw.lines(self.win, self.config.LINK_COLOR, False, [ |         pygame.draw.lines(self.surf, self.config.LINK_COLOR, False, [ | ||||||
|             [startX, startY + bitH*1.5], |             [startX, startY + bitH*1.5], | ||||||
|             [startX, endY + bitH/2], |             [startX, endY + bitH/2], | ||||||
|             [endX - arrowMargin, endY + bitH/2] |             [endX - arrowMargin, endY + bitH/2] | ||||||
| @@ -139,7 +148,7 @@ class Renderer: | |||||||
|         self.drawLink(midX, rStartY, descX, descY) |         self.drawLink(midX, rStartY, descX, descY) | ||||||
|          |          | ||||||
|         descTxt = self.font.render(range_.description, True, self.config.TEXT_COLOR) |         descTxt = self.font.render(range_.description, True, self.config.TEXT_COLOR) | ||||||
|         self.win.blit(descTxt, [descX, descY + (bitH - descTxt.get_height())/2]) |         self.surf.blit(descTxt, [descX, descY + (bitH - descTxt.get_height())/2]) | ||||||
|          |          | ||||||
|         descY += descTxt.get_height() |         descY += descTxt.get_height() | ||||||
|          |          | ||||||
| @@ -158,7 +167,7 @@ class Renderer: | |||||||
|         for val, desc in sorted(values.items(), key=lambda vd: vd[0]): |         for val, desc in sorted(values.items(), key=lambda vd: vd[0]): | ||||||
|             descY += gap |             descY += gap | ||||||
|             valTxt = self.italicFont.render(f"{val} = {desc}", True, textCol) |             valTxt = self.italicFont.render(f"{val} = {desc}", True, textCol) | ||||||
|             self.win.blit(valTxt, [descX + bitW/2, descY]) |             self.surf.blit(valTxt, [descX + bitW/2, descY]) | ||||||
|             descY += valTxt.get_height() |             descY += valTxt.get_height() | ||||||
|          |          | ||||||
|         return (descX, descY) |         return (descX, descY) | ||||||
| @@ -243,21 +252,21 @@ class Renderer: | |||||||
|         for i in range(dashes): |         for i in range(dashes): | ||||||
|             a = start + d * i * (dashLen + dashSpace) |             a = start + d * i * (dashLen + dashSpace) | ||||||
|             b = a + d*dashLen |             b = a + d*dashLen | ||||||
|             pygame.draw.line(self.win, linkCol, [a.x, a.y], [b.x, b.y]) |             pygame.draw.line(self.surf, linkCol, [a.x, a.y], [b.x, b.y]) | ||||||
|          |          | ||||||
|         n = Vec(d.y, -d.x) |         n = Vec(d.y, -d.x) | ||||||
|          |          | ||||||
|         width = arrowSize / 1.5 |         width = arrowSize / 1.5 | ||||||
|         p1 = end - d * arrowSize + n * width |         p1 = end - d * arrowSize + n * width | ||||||
|         p2 = end - d * arrowSize - n * width |         p2 = end - d * arrowSize - n * width | ||||||
|         pygame.draw.polygon(self.win, linkCol, [ |         pygame.draw.polygon(self.surf, linkCol, [ | ||||||
|             [end.x, end.y], |             [end.x, end.y], | ||||||
|             [p1.x, p1.y], |             [p1.x, p1.y], | ||||||
|             [p2.x, p2.y]], 0) |             [p2.x, p2.y]], 0) | ||||||
|          |          | ||||||
|         if label: |         if label: | ||||||
|             txt = self.italicFont.render(label, True, textCol) |             txt = self.italicFont.render(label, True, textCol) | ||||||
|             self.win.blit(txt, [ |             self.surf.blit(txt, [ | ||||||
|                 (start.x + end.x - txt.get_width())/2, |                 (start.x + end.x - txt.get_width())/2, | ||||||
|                 (start.y + end.y)/2 + arrowLabelDist |                 (start.y + end.y)/2 + arrowLabelDist | ||||||
|             ]) |             ]) | ||||||
| @@ -13,8 +13,9 @@ class UnsupportedFormatException(Exception): | |||||||
| class InstructionSetSchema: | class InstructionSetSchema: | ||||||
|     VALID_EXTENSIONS = ("yaml", "json", "xml") |     VALID_EXTENSIONS = ("yaml", "json", "xml") | ||||||
|      |      | ||||||
|     def __init__(self, path: str, configPath: str = "config.json") -> None: |     def __init__(self, path: str, configPath: str = "config.json", display: bool = False) -> None: | ||||||
|         self.config = Config(configPath) |         self.config = Config(configPath) | ||||||
|  |         self.display = display | ||||||
|         self.path = path |         self.path = path | ||||||
|         self.load() |         self.load() | ||||||
|      |      | ||||||
| @@ -43,6 +44,8 @@ class InstructionSetSchema: | |||||||
|             self.structures[id_] = Structure.load(id_, data) |             self.structures[id_] = Structure.load(id_, data) | ||||||
|      |      | ||||||
|     def save(self, path: str) -> None: |     def save(self, path: str) -> None: | ||||||
|         renderer = Renderer(self.config) |         renderer = Renderer(self.config, self.display) | ||||||
|         renderer.render(self) |         renderer.render(self) | ||||||
|         renderer.save(path) |         renderer.save(path) | ||||||
|  |         if self.display: | ||||||
|  |             input("Press ENTER to quit") | ||||||
							
								
								
									
										7
									
								
								transparent.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								transparent.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | { | ||||||
|  |     "backgroundColor": [0, 0, 0, 0], | ||||||
|  |     "textColor": [128, 128, 128], | ||||||
|  |     "linkColor": [128, 128, 128], | ||||||
|  |     "bitIColor": [128, 128, 128], | ||||||
|  |     "borderColor": [128, 128, 128] | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user