#!/usr/bin/env python # -*- coding: utf-8 -*- """ $Id$ Copyright 2010 Lars Kruse This file is part of PyCAM. PyCAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PyCAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PyCAM. If not, see . """ import pycam.Utils.log import os DEFAULT_NAMES = ("normal", "default", "standard") log = pycam.Utils.log.get_logger() class FontCache(object): """ The FontCache gradually loads fonts. This is more efficient than an immeadiate initialization of all fonts for the DXF importer. Use "get_font" for loading (incrementally) fonts until the requested font name was found. The functions "get_names" and "len()" trigger an immediate initialization of all available fonts. """ def __init__(self, font_dir=None, core=None): self.font_dir = font_dir self.fonts = {} self.core = core self._unused_font_files = list(self._get_font_files()) def is_loading_complete(self): return len(self._unused_font_files) == 0 def _get_font_files(self): if self.font_dir is None: return [] log.info("Font directory: %s" % self.font_dir) result = [] files = os.listdir(self.font_dir) for fname in files: filename = os.path.join(self.font_dir, fname) if filename.lower().endswith(".cxf") and os.path.isfile(filename): result.append(filename) result.sort() return result def __len__(self): self._load_all_files() return len(self.fonts) def _get_font_without_loading(self, name): for font_name in self.fonts: if font_name.lower() == name.lower(): return self.fonts[font_name] else: return None def get_font_names(self): self._load_all_files() return self.fonts.keys() def get_font(self, name): font = self._get_font_without_loading(name) while not font and not self.is_loading_complete(): self._load_next_file() font = self._get_font_without_loading(name) if font: return font else: # no font with that name is available for other_name in DEFAULT_NAMES: font = self._get_font_without_loading(other_name) if font: return font else: if self.fonts: # return the first (random) font in the dictionary return self.fonts.values()[0] def _load_all_files(self): if self.core: progress = self.core.get("progress") progress.set_multiple(len(self._unused_font_files), "Loading font") else: progress = None while not self.is_loading_complete(): self._load_next_file(progress=progress) if progress: progress.update_multiple() if progress: progress.finish() def _load_next_file(self, progress=None): if self.is_loading_complete(): return filename = self._unused_font_files.pop(0) if progress: callback = progress.update progress.update(text="Loading font file %s" % \ os.path.basename(filename)) else: callback = None charset = pycam.Importers.CXFImporter.import_font(filename, callback=callback) if not charset is None: for name in charset.get_names(): self.fonts[name] = charset