[PCB Print] Added option to customize the page numbers

Related to #283
This commit is contained in:
Salvador E. Tropea 2022-09-08 07:24:56 -03:00
parent 2f37a5c6b4
commit 241eca63ff
6 changed files with 44 additions and 14 deletions

View File

@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Option to control the resolution (DPI). (See #259)
- Option to move the page number to the extension (page_number_as_extension)
(See #283)
- Option to customize the page numbers (See #283)
- Installation checker: option to show the tool paths.
### Fixed

View File

@ -2190,13 +2190,14 @@ Notes:
- **`format`**: [string='PDF'] [PDF,SVG,PNG,EPS,PS] Format for the output file/s.
Note that for PS you need `ghostscript` which isn't part of the default docker images.
- **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i=assembly, %x=pdf/ps)/(%i=assembly_page_NN, %x=svg/png/eps).
Consult the `page_number_as_extension`. Affected by global options.
Consult the `page_number_as_extension` and `page_id` options. Affected by global options.
- *output_name*: Alias for output.
- **`pages`**: [list(dict)] List of pages to include in the output document.
Each page contains one or more layers of the PCB.
* Valid keys:
- **`layers`**: [list(dict)|list(string)|string] List of layers printed in this page.
Order is important, the last goes on top.
You can reuse other layers lists, some options aren't used here, but they are valid.
* Valid keys:
- `color`: [string=''] Color used for this layer.
- `description`: [string=''] A description for the layer, for documentation purposes.
@ -2214,6 +2215,7 @@ Notes:
- `mirror`: [boolean=false] Print mirrored (X axis inverted).
- `monochrome`: [boolean=false] Print in gray scale.
- `negative_plot`: [boolean=false] Invert black and white. Only useful for a single layer.
- `page_id`: [string='%02d'] Text to differentiate the pages. Use %d (like in C) to get the page number.
- `sheet`: [string='Assembly'] Text to use for the `sheet` in the title block.
- `sheet_reference_color`: [string=''] Color to use for the frame and title block.
- `tent_vias`: [boolean=true] Cover the vias.
@ -2246,6 +2248,7 @@ Notes:
- `micro_via_color`: [string=''] Color used for micro `colored_vias`.
- `pad_color`: [string=''] Color used for `colored_pads`.
- `page_number_as_extension`: [boolean=false] When enabled the %i is always `assembly`, the %x will be NN.FORMAT (i.e. 01.png).
Note: page numbers can be customized using the `page_id` option for each page.
- `png_width`: [number=1280] [0,7680] Width of the PNG in pixels. Use 0 to use as many pixels as the DPI needs for the page size.
- `realistic_solder_mask`: [boolean=true] Try to draw the solder mask as a real solder mask, not the negative used for fabrication.
In order to get a good looking select a color with transparency, i.e. '#14332440'.

View File

@ -1117,12 +1117,13 @@ outputs:
# [string=''] Color used for micro `colored_vias`
micro_via_color: ''
# [string='%f-%i%I%v.%x'] Filename for the output (%i=assembly, %x=pdf/ps)/(%i=assembly_page_NN, %x=svg/png/eps).
# Consult the `page_number_as_extension`. Affected by global options
# Consult the `page_number_as_extension` and `page_id` options. Affected by global options
output: '%f-%i%I%v.%x'
# `output_name` is an alias for `output`
# [string=''] Color used for `colored_pads`
pad_color: ''
# [boolean=false] When enabled the %i is always `assembly`, the %x will be NN.FORMAT (i.e. 01.png)
# [boolean=false] When enabled the %i is always `assembly`, the %x will be NN.FORMAT (i.e. 01.png).
# Note: page numbers can be customized using the `page_id` option for each page
page_number_as_extension: false
# [list(dict)] List of pages to include in the output document.
# Each page contains one or more layers of the PCB
@ -1134,7 +1135,8 @@ outputs:
# [string='#000000'] Color used for the holes when `colored_holes` is enabled
holes_color: '#000000'
# [list(dict)|list(string)|string] List of layers printed in this page.
# Order is important, the last goes on top
# Order is important, the last goes on top.
# You can reuse other layers lists, some options aren't used here, but they are valid
layers:
# [string=''] Color used for this layer
- color: ''
@ -1158,6 +1160,8 @@ outputs:
monochrome: false
# [boolean=false] Invert black and white. Only useful for a single layer
negative_plot: false
# [string='%02d'] Text to differentiate the pages. Use %d (like in C) to get the page number
page_id: '%02d'
# [number=1.0] Scale factor (0 means autoscaling)
scaling: 1.0
# [string='Assembly'] Text to use for the `sheet` in the title block

View File

@ -189,7 +189,10 @@ class PagesOptions(Optionable):
""" *Try to sort the layers in the same order that uses KiCad for printing """
self.layers = LayerOptions
""" *[list(dict)|list(string)|string] List of layers printed in this page.
Order is important, the last goes on top """
Order is important, the last goes on top.
You can reuse other layers lists, some options aren't used here, but they are valid """
self.page_id = '%02d'
""" Text to differentiate the pages. Use %d (like in C) to get the page number """
self._scaling_example = 1.0
def config(self, parent):
@ -221,9 +224,10 @@ class PCB_PrintOptions(VariantOptions):
""" {output} """
self.output = GS.def_global_output
""" *Filename for the output (%i=assembly, %x=pdf/ps)/(%i=assembly_page_NN, %x=svg/png/eps).
Consult the `page_number_as_extension` """
Consult the `page_number_as_extension` and `page_id` options """
self.page_number_as_extension = False
""" When enabled the %i is always `assembly`, the %x will be NN.FORMAT (i.e. 01.png) """
""" When enabled the %i is always `assembly`, the %x will be NN.FORMAT (i.e. 01.png).
Note: page numbers can be customized using the `page_id` option for each page """
self.hide_excluded = False
""" Hide components in the Fab layer that are marked as excluded by a variant """
self.color_theme = '_builtin_classic'
@ -351,8 +355,12 @@ class PCB_PrintOptions(VariantOptions):
if self.hide_excluded:
self.restore_fab(GS.board, comps_hash)
def get_id_and_ext(self, n=None):
pn_str = '%02d' % (n+1) if n is not None else '%02d'
def get_id_and_ext(self, n=None, id='%02d'):
try:
pn_str = id % (n+1) if n is not None else id
except TypeError:
# If id doesn't contain %d we get this exception
pn_str = id
if self.page_number_as_extension:
return self._expand_id, pn_str+'.'+self._expand_ext
return self._expand_id+'_page_'+pn_str, self._expand_ext
@ -360,8 +368,8 @@ class PCB_PrintOptions(VariantOptions):
def get_targets(self, out_dir):
if self.format in ['SVG', 'PNG', 'EPS']:
files = []
for n in range(len(self.pages)):
id, ext = self.get_id_and_ext(n)
for n, p in enumerate(self.pages):
id, ext = self.get_id_and_ext(n, p.page_id)
files.append(self.expand_filename(out_dir, self.output, id, ext))
return files
return [self._parent.expand_filename(out_dir, self.output)]
@ -936,6 +944,15 @@ class PCB_PrintOptions(VariantOptions):
# if self.format == 'EPS':
# self.rsvg_command_eps = self.ensure_tool('rsvg2')
def rename_pages(self, output_dir):
for n, p in enumerate(self.pages):
id, ext = self.get_id_and_ext(n)
cur_name = self.expand_filename(output_dir, self.output, id, ext)
id, ext = self.get_id_and_ext(n, p.page_id)
user_name = self.expand_filename(output_dir, self.output, id, ext)
if cur_name != user_name and os.path.isfile(cur_name):
os.rename(cur_name, user_name)
def generate_output(self, output):
self.check_tools()
output_dir = os.path.dirname(output)
@ -1025,7 +1042,7 @@ class PCB_PrintOptions(VariantOptions):
filelist.append((GS.pcb_basename+"-frame.svg", color))
# 3) Stack all layers in one file
if self.format == 'SVG':
id, ext = self.get_id_and_ext(n)
id, ext = self.get_id_and_ext(n, p.page_id)
assembly_file = self.expand_filename(output_dir, self.output, id, ext)
else:
assembly_file = GS.pcb_basename+".svg"
@ -1056,6 +1073,7 @@ class PCB_PrintOptions(VariantOptions):
else:
# Use GS to create one PNG per page and then scale to the wanted width
self.pdf_to_png(pdf_file, out_file)
self.rename_pages(output_dir)
# Remove the temporal files
if not self.keep_temporal_files:
rmtree(temp_dir_base)

View File

@ -124,8 +124,8 @@ def test_pcb_print_simple_1(test_dir):
prj = 'light_control'
ctx = context.TestContext(test_dir, prj, 'pcb_print_2')
ctx.run()
ctx.expect_out_file(prj+'-assembly_page_01.png')
ctx.expect_out_file(prj+'-assembly_page_02.png')
ctx.expect_out_file(prj+'-F_Cu_mono.png')
ctx.expect_out_file(prj+'-F_Cu_color.png')
ctx.expect_out_file(prj+'-assembly_page_01.eps')
ctx.expect_out_file(prj+'-assembly_page_01.svg')
ctx.expect_out_file(prj+'-assembly.ps')

View File

@ -19,6 +19,8 @@ outputs:
# enable_ki6_frame_fix: true
add_background: true
background_image: "tests/data/confidential_optimized.svg"
output: '%f-%I%v%x'
page_number_as_extension: true
pages:
- layers:
- layer: F.Cu
@ -26,6 +28,7 @@ outputs:
color: '#14332440'
- layer: Edge.Cuts
color: "#004040"
page_id: F_Cu_color
- monochrome: true
layers:
- layer: F.Cu
@ -33,6 +36,7 @@ outputs:
color: '#14332440'
- layer: Edge.Cuts
color: "#004040"
page_id: F_Cu_mono
- name: 'print_bottom'
comment: "Experiment"