# -*- coding: utf-8 -*- # Copyright (c) 2022 Salvador E. Tropea # Copyright (c) 2022 Instituto Nacional de TecnologĂ­a Industrial # License: GPL-3.0 # Project: KiBot (formerly KiPlot) """ KiCad 6 color theme loader """ import os import json from pcbnew import BOARD, PCBNEW_LAYER_ID_START, PCB_LAYER_ID_COUNT from ..gs import GS from ..misc import W_COLORTHEME, W_WRONGCOLOR from .config import KiConf from .. import log logger = log.get_logger() BUILT_IN = {'_builtin_classic', '_builtin_default'} KI6_KI5 = {'b_adhesive': 'b_adhes', 'f_adhesive': 'f_adhes', 'b_silkscreen': 'b_silks', 'f_silkscreen': 'f_silks', 'user_drawings': 'dwgs_user', 'user_comments': 'cmts_user', 'user_eco1': 'eco1_user', 'user_eco2': 'eco2_user', 'b_courtyard': 'b_crtyd', 'f_courtyard': 'f_crtyd'} CACHE = {} class KiCadColors(object): def __init__(self): self.layer_id2color = {} self.pcb_frame = "#480000" def parse_color(val): if val.startswith('rgb('): vals = val[4:-1].split(',') elif val.startswith('rgba('): vals = val[5:-1].split(',') else: logger.warning(W_WRONGCOLOR+"Wrong KiCad color: {}".format(val)) return "#000000" res = '#' for c, v in enumerate(vals): res += '%02X' % (int(v) if c < 3 else int(float(v)*255)) return res def load_color_theme(name): logger.debug('Looking for color theme `{}`'.format(name)) is_built_in = name in BUILT_IN if not is_built_in and GS.ki5(): logger.warning(W_COLORTHEME, "KiCad 5 doesn't support color themes ({})".format(name)) return None if is_built_in: fn = os.path.join(os.path.dirname(__file__), '..', 'kicad_colors', name+'.json') else: KiConf.init(GS.pcb_file) fn = os.path.join(KiConf.config_dir, 'colors', name+'.json') fn = os.path.abspath(fn) global CACHE if fn in CACHE: return CACHE[fn] if not os.path.isfile(fn): logger.warning(W_COLORTHEME, "Missing color theme: {}".format(fn)) return None with open(fn, 'rt') as f: text = f.read() data = json.loads(text) c = KiCadColors() cl = c.layer_id2color board = data['board'] copper = board['copper'] extra_debug = GS.debug_level >= 3 for id in range(PCBNEW_LAYER_ID_START, PCBNEW_LAYER_ID_START+PCB_LAYER_ID_COUNT): c_name = c_name_ori = BOARD.GetStandardLayerName(id) c_name = c_name.lower() if c_name == 'rescue': continue if c_name.endswith('.cu'): c_name = c_name[:-3] if c_name in copper: cl[id] = parse_color(copper[c_name]) else: logger.warning(W_WRONGCOLOR+"The `{}` theme doesn't define a color for the {} layer".format(name, c_name_ori)) else: c_name = c_name.replace('.', '_') c_name = KI6_KI5.get(c_name, c_name) if c_name in board: cl[id] = parse_color(board[c_name]) else: logger.warning(W_WRONGCOLOR+"The `{}` theme doesn't define a color for the {} layer".format(name, c_name_ori)) if extra_debug: logger.debug('- Color for layer {} ({}): {}'.format(c_name_ori, id, cl[id])) # Title block and frame color if 'worksheet' in board: c.pcb_frame = parse_color(board['worksheet']) CACHE[fn] = c return c