def read_metric(ps_name): for afm in ps_to_filename[ps_name]: afm = afm + '.afm' filename = find_in_path(config.font_path, afm) if filename: if __debug__: import time start = time.clock() metric = read_afm_file(filename) if __debug__: pdebug('timing', 'time to read afm %s: %g', afm, time.clock() - start) return metric else: if not _warned_about_afm.get(afm): warn(USER, _("I cannot find the metrics for the font %(ps_name)s.\n" "The file %(afm)s is not in the font_path.\n" "I'll use the metrics for %(fallback)s instead."), ps_name = ps_name, afm = afm, fallback = config.preferences.fallback_font) _warned_about_afm[afm] = 1 if ps_name != config.preferences.fallback_font: return read_metric(config.preferences.fallback_font) else: raise SketchError("Can't load metrics for fallback font %s", config.preferences.fallback_font)
def Info(self): selected = 0 idx = None paths = self.paths for i in range(len(paths)): path = paths[i] count = path.selection_count() if count > 0: selected = selected + count idx = i if selected > 1: return _("%d nodes in PolyBezier") % selected else: if idx is not None: path = paths[idx] for i in range(path.len): if path.SegmentSelected(i): break else: warn(INTERNAL, 'Strange selection count') return _("PolyBezier") if i == 0: return _("First node of PolyBezier") elif i == path.len - 1: return _("Last node of PolyBezier") else: return _("1 node of PolyBezier") else: if self.selection_type == SelCurvePoint: return _("Point on curve at position %.2f") \ % self.selected_idx else: return _("No Node of PolyBezier")
def InitFromWidget(self, widget, files, basedir): for name in files: file_base = os.path.join(basedir, name) try: pixmap = widget.ReadBitmapFile(file_base + '.xbm')[2] setattr(self, name, pixmap) except IOError, info: warn(USER, "Warning: Can't load Pixmap from %s: %s", file_base + '.xbm', info)
def get_sensitive(self): #print 'get_sensitive', self if self.sensitive_cb: method = self.get_method(self.sensitive_cb) if method: return method() else: warn(INTERNAL, 'no method for sensitive_cb (%s)', self.sensitive_cb) return 0 return 1
def make_file_names(filenames, subdir = ''): default = 'error' # a standard Tk bitmap for name in filenames: fullname = os.path.join(config.pixmap_dir, subdir, name) if os.path.exists(fullname + '.gif'): setattr(PixmapTk, name, '*' + fullname + '.gif') elif os.path.exists(fullname + '.xbm'): setattr(PixmapTk, name, '@' + fullname + '.xbm') else: warn(USER, "Warning: no file %s substituting '%s'", fullname, default) setattr(PixmapTk, name, default)
def __getattr__(self, attr): # if a lazy attribute is accessed, compute it. method = self._lazy_attrs.get(attr) if method: getattr(self, method)() # now it should work... use self.__dict__ directly to avoid # recursion if the method is buggy try: return self.__dict__[attr] except KeyError, msg: warn(INTERNAL, '%s did not compute %s for %s.', method, attr, self)
def AddCommand(self, command): key_stroke = command.GetKeystroke() if key_stroke: if type(key_stroke) == StringType: key_stroke = (key_stroke,) for stroke in key_stroke: if self.map.has_key(stroke): # XXX: should be user visible if keybindings can be # changed by user warn(INTERNAL, 'Warning: Binding %s to %s replaces %s', command.name, stroke, self.map[stroke].name) self.map[stroke] = command
def convert_color(self, color_spec): try: c = self.color_cache.get(color_spec) if c: return c c = apply(CreateRGBColor, color_spec) self.color_cache[color_spec] = c except: # This should only happen if the color_spec is invalid type, value = sys.exc_info()[:2] warn(INTERNAL, 'Color allocation failed: %s: %s', type, value) c = StandardColors.black return c
def make_cursor_names(names): from Sketch import const default = 'X_cursor' # a standard X cursor for name in names: fullname = os.path.join(config.pixmap_dir, name + '.xbm') fullname_mask = os.path.join(config.pixmap_dir, name + '_mask.xbm') if os.path.exists(fullname) and os.path.exists(fullname_mask): setattr(const, name, ('@' + fullname, fullname_mask, 'black', 'white')) else: warn(USER, "Warning: no file %s (or *_mask) substituting '%s'", fullname, default) setattr(const, name, default)
def GetStandardPalette(): palette = read_standard_palette(config.preferences.palette) if not palette: warn(USER, _("Could not load palette %s; trying mini.spl..."), config.preferences.palette) palette = read_standard_palette('mini.spl') if not palette: warn(USER, _("Could not load palette mini.spl; reverting to black&white")) palette = RGBPalette() for r, g, b, name in _mini_pal: palette.AddEntry((r, g, b), name) return palette
def GetFont(fontname): if font_cache.has_key(fontname): return font_cache[fontname] if not fontmap.has_key(fontname): if not _warned_about_font.get(fontname): warn(USER, _("I can't find font %(fontname)s. " "I'll use %(fallback)s instead"), fontname = fontname, fallback = config.preferences.fallback_font) _warned_about_font[fontname] = 1 if fontname != config.preferences.fallback_font: return GetFont(config.preferences.fallback_font) raise ValueError, 'Cannot find font %s.' % fontname return Font(fontname)
def fill_colormap(cmap): max = 65535 colors = [] color_idx = [] failed = 0 shades_r, shades_g, shades_b, shades_gray = config.preferences.color_cube max_r = shades_r - 1 max_g = shades_g - 1 max_b = shades_b - 1 for red in range(shades_r): red = float_to_x(red / float(max_r)) for green in range(shades_g): green = float_to_x(green / float(max_g)) for blue in range(shades_b): blue = float_to_x(blue / float(max_b)) colors.append((red, green, blue)) for i in range(shades_gray): value = int((i / float(shades_gray - 1)) * max) colors.append((value, value, value)) for red, green, blue in colors: try: ret = cmap.AllocColor(red, green, blue) color_idx.append(ret[0]) except: color_idx.append(None) failed = 1 if failed: warn(USER, _("I can't alloc all needed colors. I'll use a private colormap")) warn(INTERNAL, "allocated colors without private colormap: %d", len(filter(lambda i: i is None, color_idx))) if config.preferences.reduce_color_flashing: #print 'reduce color flashing' cmap = cmap.CopyColormapAndFree() for idx in range(len(color_idx)): if color_idx[idx] is None: color_idx[idx] = apply(cmap.AllocColor, colors[idx])[0] else: #print "don't reduce color flashing" cmap = cmap.CopyColormapAndFree() cmap.FreeColors(filter(lambda i: i is not None, color_idx), 0) color_idx = [] for red, green, blue in colors: color_idx.append(cmap.AllocColor(red, green, blue)[0]) return cmap, color_idx
def Add(self, script, menu = ()): if type(menu) == StringType: menu = (menu,) self.registry[script.name] = script submenu = self.menu for item in menu: if submenu.has_key(item): if type(submenu[item]) != DictType: warn(USER, 'Replacing menu entry "%s" with a submenu', item) submenu[item] = {} else: submenu[item] = {} submenu = submenu[item] submenu[script.Title()] = script
def ReadRGBPaletteFile(filename): file = open(filename) line = file.readline() if line != magic_rgb_palette + '\n': file.close() raise ValueError, 'Invalid file type' palette = RGBPalette() linenr = 1 for line in file.readlines(): line = strip(line) linenr = linenr + 1 if not line or line[0] == '#': continue line = split(line, None, 3) if len(line) != 4: warn(INTERNAL, '%s:%d: wrong number of fields', filename, linenr) continue try: rgb = tuple(map(atof, line[:3])) except: warn(INTERNAL, '%s:%d: cannot parse rgb values', filename, linenr) continue for value in rgb: if value < 0 or value > 1.0: warn(INTERNAL, '%s:%d: value out of range', filename, linenr) continue name = strip(line[-1]) try: palette.AddEntry(rgb, name) except NameInUse: warn(INTERNAL, '%s:%d: color name already used', filename, linenr) continue except RGBAlreadyStored: warn(INTERNAL, '%s:%d: color already stored', filename, linenr) continue file.close() return palette
def init_var(self): lo, hi = self.range value = self.value if lo is None: if hi is not None: if value > hi: value = hi else: if hi is None: if value < lo: value = lo else: value = max(lo, min(hi, value)) if value != self.value: warn(USER, 'Initial value in parameter %s of plugin %s out of range', self.name, self.panel.title) self.var.set(value)
def bezier_load(self, line): bezier = self.object while 1: try: bezier.paths[-1].append_from_string(line) line = bezier.paths[-1].append_from_file(self.file) except: warn(INTERNAL, _("Error reading line %s"), `line`) line = self.file.readline() if line[:2] == 'bC': bezier.paths[-1].load_close() line = self.file.readline() if line[:2] == 'bn': bezier.paths = bezier.paths + (CreatePath(),) line = self.file.readline() else: break if line[:2] not in ('bs', 'bc'): break return line
def __getattr__(self, attr): try: access = self._object.script_access[attr] except KeyError: if not safe_special_methods.get(attr): warn(USER,'Cant access attribute %s of %s in safe user script', attr, self._object) raise AttributeError, attr if access == SCRIPT_UNDO: return UndoMethodWrapper(getattr(self._object, attr), self._document) elif access == SCRIPT_GET: return getattr(self._object, attr) elif access == SCRIPT_OBJECT: return ObjectMethodWrapper(getattr(self._object, attr), self._document) elif access == SCRIPT_OBJECTLIST: return ObjectListMethodWrapper(getattr(self._object, attr), self._document) else: raise AttributeError, attr
def CallObjectMethod(self, aclass, methodname, args): if len(self.objects) == 1: if self.editor is not None: obj = self.editor if not obj.compatible(aclass): warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'editor %s is not compatible with class %s', self.editor, aclass) return NullUndo else: obj = self.objects[0][-1] if not isinstance(obj, aclass): warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'object is not instance of %s', aclass) return NullUndo try: method = getattr(obj, methodname) except AttributeError: warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'no method %s for class %s', methodname, aclass) return NullUndo undo = apply(method, args) if undo is None: undo = NullUndo return undo return NullUndo
def CallObjectMethod(self, aclass, methodname, args): if len(self.objects) == 1: if self.editor is not None: obj = self.editor if not obj.compatible(aclass): warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'editor %s is not compatible with class %s', self.editor, aclass) return NullUndo else: obj = self.objects[0][-1] if not isinstance(obj, aclass): warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'object is not instance of %s', aclass) return NullUndo try: method = getattr(obj, methodname) except AttributeError: warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'no method %s for class %s', methodname, aclass) return NullUndo undo = apply(method, args) if undo is None: undo = NullUndo return undo return NullUndo
def __getattr__(self, attr): try: access = self._object.script_access[attr] except KeyError: if not safe_special_methods.get(attr): warn(USER, 'Cant access attribute %s of %s in safe user script', attr, self._object) raise AttributeError, attr if access == SCRIPT_UNDO: return UndoMethodWrapper(getattr(self._object, attr), self._document) elif access == SCRIPT_GET: return getattr(self._object, attr) elif access == SCRIPT_OBJECT: return ObjectMethodWrapper(getattr(self._object, attr), self._document) elif access == SCRIPT_OBJECTLIST: return ObjectListMethodWrapper(getattr(self._object, attr), self._document) else: raise AttributeError, attr
def build_dlg(self): top = self.top row = 0 for row in range(len(self.info.parameters)): name, type, value, prange, label = self.info.parameters[row] try: #print name, type, value, prange, label var = parameter_types[type](self, name, value, prange, label) var.build_widgets(top, row) self.vars.append(var) except KeyError: warn(USER, 'Unknown plugin parameter type %s' % type) continue row = row + 1 top.columnconfigure(0, weight = 0) top.columnconfigure(1, weight = 1) top.columnconfigure(2, weight = 0) top.columnconfigure(3, weight = 0) frame = self.create_std_buttons(top) frame.grid(row = row, columnspan = 4, sticky = 'ew')
def __init__(self, paths = None, properties = None, duplicate = None): if duplicate is not None: if paths is None: paths = [] for path in duplicate.paths: paths.append(path.Duplicate()) self.paths = tuple(paths) else: # This special case uses the properties kwarg now, I # hope. warn(INTERNAL, 'Bezier object created with paths and duplicte') print_stack() if type(paths) != type(()): paths = (paths,) self.paths = paths elif paths is not None: if type(paths) != type(()): paths = (paths,) self.paths = paths else: self.paths = (CreatePath(),) Primitive.__init__(self, properties = properties, duplicate=duplicate)
class Bounded: _lazy_attrs = { 'coord_rect': 'update_rects', 'bounding_rect': 'update_rects' } def __init__(self): pass def del_lazy_attrs(self): for key in self._lazy_attrs.keys(): try: delattr(self, key) except: pass def update_rects(self): # compute the various bounding rects and other attributes that # use `lazy evaluation'. This method MUST be implemented by # derived classes. It MUST set self.bounding_rect and # self.coord_rect and other attributes where appropriate. pass def __getattr__(self, attr): # if a lazy attribute is accessed, compute it. method = self._lazy_attrs.get(attr) if method: getattr(self, method)() # now it should work... use self.__dict__ directly to avoid # recursion if the method is buggy try: return self.__dict__[attr] except KeyError, msg: warn(INTERNAL, '%s did not compute %s for %s.', method, attr, self) if attr[:2] == attr[-2:] == '__': #if attr in ('__nonzero__', '__len__'): # print_stack() pass else: warn(INTERNAL, "%s instance doesn't have an attribute %s", self.__class__, attr) raise AttributeError, attr
def read_font_dirs(): #print 'read_font_dirs' if __debug__: import time start = time.clock() rx_sfd = re.compile(r'^.*\.sfd$') for directory in config.font_path: #print directory try: filenames = os.listdir(directory) except os.error, exc: warn(USER, _("Cannot list directory %s:%s\n" "ignoring it in font_path"), directory, str(exc)) continue dirfiles = filter(rx_sfd.match, filenames) for filename in dirfiles: filename = os.path.join(directory, filename) #print filename try: file = open(filename, 'r') line_nr = 0 for line in file.readlines(): line_nr = line_nr + 1 line = strip(line) if not line or line[0] == '#': continue info = map(intern, split(line, ',')) if len(info) == 6: psname = info[0] fontlist.append(tuple(info[:-1])) _add_ps_filename(psname, info[-1]) fontmap[psname] = tuple(info[1:-1]) elif len(info) == 2: psname, basename = info _add_ps_filename(psname, basename) else: warn(INTERNAL,'%s:%d: line must have exactly 6 fields', filename, line_nr) file.close() except IOError, value: warn(USER, _("Cannot load sfd file %(filename)s:%(message)s;" "ignoring it"), filename = filename, message = value.strerror)
def GetObjectMethod(self, aclass, method): if len(self.objects) == 1: if self.editor is not None: obj = self.editor if not obj.compatible(aclass): warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'editor is not compatible with class %s', aclass) return None else: obj = self.objects[0][-1] if not isinstance(obj, aclass): warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'object is not instance of %s', aclass) return None try: return getattr(obj, method) except AttributeError: warn(INTERNAL, 'EditSelection.GetObjectMethod: ' 'no method %s for class %s', method, aclass) pass return None
def GetObjectMethod(self, aclass, method): if len(self.objects) == 1: if self.editor is not None: obj = self.editor if not obj.compatible(aclass): warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'editor is not compatible with class %s', aclass) return None else: obj = self.objects[0][-1] if not isinstance(obj, aclass): warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'object is not instance of %s', aclass) return None try: return getattr(obj, method) except AttributeError: warn( INTERNAL, 'EditSelection.GetObjectMethod: ' 'no method %s for class %s', method, aclass) pass return None
tokenize = skread.tokenize_line self.document() self.layer(_("Layer 1")) try: self.read_header() line = self.readline() while line: tokens = tokenize(line, 1) if len(tokens) > 1: function, rest = tokens else: function = tokens[0] rest = "" if type(function) == type(0): function = funclist.get(function) if function: function(rest) line = self.readline() except SketchLoadError, value: warn_tb(INTERNAL) raise SketchLoadError("%d:%s" % (self.lineno, str(value))), None, sys.exc_traceback except: if load._dont_handle_exceptions: warn(INTERNAL, "XFigLoader: error reading line %d:%s", self.lineno, ` line `) raise raise SketchLoadError(_("error in line %d:\n%s") % (self.lineno, ` line `)), None, sys.exc_traceback self.end_all() self.object.load_Completed() return self.object
def Read_X_RGB_TXT(filename): file = open(filename) palette = RGBPalette() linenr = 0 color_num = 0 for line in file.readlines(): line = strip(line) linenr = linenr + 1 if not line or line[0] in ('#', '!'): # an empty line or an X-style comment (!) or a GIMP comment (#) # GIMP's palette files have practically the same format as rgb.txt continue line = split(line, None, 3) if len(line) == 3: # the name is missing while 1: name = 'color ' + str(color_num) try: palette[name] used = 1 except KeyError: used = 0 if not used: line.append(name) break color_num = color_num + 1 if len(line) != 4: warn(INTERNAL, '%s:%d: wrong number of fields', filename, linenr) continue try: values = map(atoi, line[:3]) except: warn(INTERNAL, '%s:%d: cannot parse rgb values', filename, linenr) continue rgb = [] for value in values: value = round(value / 255.0, 3) if value < 0: value = 0.0 elif value > 1.0: value = 1.0 rgb.append(value) rgb = tuple(rgb) name = strip(line[-1]) try: palette.AddEntry(rgb, name) except NameInUse: warn(INTERNAL, '%s:%d: color name already used', filename, linenr) continue except RGBAlreadyStored: warn(INTERNAL, '%s:%d: color already stored', filename, linenr) continue file.close() return palette
def __init__(self, master=None, orient = HORIZONTAL, canvas = None, **kw): apply(PyWidget.__init__, (self, master), kw) self.orient = orient self.canvas = canvas self.gcs_initialized = 0 self.gc = None self.positions = None self.SetRange(0.0, 1.0, force = 1) if orient == VERTICAL: self.text_type = config.preferences.ruler_text_type else: self.text_type = 'horizontal' font = None fontname = config.preferences.ruler_font try: font = self.tkwin.LoadQueryFont(fontname) except: # NLS warn(USER, 'Could not load font %s for ruler. using defaults.', `fontname`) font = self.tkwin.LoadQueryFont('fixed') self.font = font font = None if self.text_type == 'rotated': fontname = config.preferences.ruler_font_rotated try: font = self.tkwin.LoadQueryFont(fontname) except: # NLS warn(USER, 'Could not load font %s for ruler. using defaults.', `fontname`) self.rotated_font = font if not self.rotated_font and self.text_type == 'rotated': self.text_type = 'horizontal' border_width = self.option_get('borderWidth', 'BorderWidth') if border_width: self.border_width = atoi(border_width) else: self.border_width = 0 height = self.font.ascent + self.font.descent \ + self.border_width + tick_lengths[0] if orient == HORIZONTAL: self['height'] = height else: if self.text_type == 'rotated': self['width'] = height elif self.text_type == 'vertical': self['width'] = self.font.TextWidth('0') + self.border_width \ + tick_lengths[0] else: # horizontal width = self.font.TextWidth('000') + self.border_width \ + tick_lengths[0] self['width'] = width self.bind('<ButtonPress>', self.ButtonPressEvent) self.bind('<ButtonRelease>', self.ButtonReleaseEvent) self.bind('<Motion>', self.PointerMotionEvent) self.button_down = 0 self.forward_motion = 0 config.preferences.Subscribe(CHANGED, self.preference_changed)
def read_afm_file(filename): afm = streamfilter.LineDecode(open(filename, 'r')) attribs = {'ItalicAngle': 0.0} charmetrics = None font_encoding = [encoding.notdef] * 256 while 1: line = afm.readline() if not line: break try: [key, value] = split(line, None, 1) except ValueError: # this normally means that a line contained only a keyword # but no value or that the line was empty continue try: action = converters[key] except KeyError: continue if action: attribs[key] = action(value) elif key == 'StartCharMetrics': charmetrics, font_encoding = read_char_metrics(afm) break else: # EndFontMetrics break if not charmetrics: raise ValueError, \ 'AFM files without individual char metrics not yet supported.' if attribs.get('EncodingScheme', StandardEncoding) == StandardEncoding: enc = encoding.iso_latin_1 else: enc = font_encoding try: rescharmetrics = map(operator.getitem, [charmetrics] * len(enc), enc) except KeyError: # Some iso-latin-1 glyphs are not defined in the font. Try the # slower way and report missing glyphs. length = len(enc) rescharmetrics = [(0, 0,0,0,0)] * length for idx in range(length): name = enc[idx] try: rescharmetrics[idx] = charmetrics[name] except KeyError: # missing character... warn(INTERNAL, '%s: missing character %s', filename, name) # some fonts don't define ascender and descender (psyr.afm for # instance). use the values from the font bounding box instead. This # is not really a good idea, but how do we solve this? # # If psyr.afm is the only afm-file where these values are missing # (?) we could use the values from the file s050000l.afm shipped # with ghostscript (or replace psyr.afm with that file). # # This is a more general problem since many of the values Sketch # reads from afm files are only optional (including ascender and # descender). if not attribs.has_key('Ascender'): attribs['Ascender'] = attribs['FontBBox'][3] if not attribs.has_key('Descender'): attribs['Descender'] = attribs['FontBBox'][1] return (CreateFontMetric(attribs['Ascender'], attribs['Descender'], attribs['FontBBox'], attribs['ItalicAngle'], rescharmetrics), enc)
base_style.fill_pattern = EmptyPattern base_style.fill_transform = 1 base_style.line_pattern = SolidPattern(StandardColors.black) base_style.line_width = 0.0 base_style.line_join = const.JoinMiter base_style.line_cap = const.CapButt base_style.line_dashes = () base_style.line_arrow1 = None base_style.line_arrow2 = None base_style.font = None base_style.font_size = 12.0 # sanity check: does base_style have all properties? for key in dir(properties.factory_defaults): if not hasattr(base_style, key): warn(INTERNAL, 'added default for property %s', key) setattr(base_style, key, getattr(properties.factory_defaults, key)) papersizes = [# 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'letter', 'legal', 'executive', ] class SKLoader(GenericLoader): format_name = format_name base_style = base_style
base_style.fill_pattern = EmptyPattern base_style.fill_transform = 1 base_style.line_pattern = SolidPattern(StandardColors.black) base_style.line_width = 0.0 base_style.line_join = const.JoinMiter base_style.line_cap = const.CapButt base_style.line_dashes = () base_style.line_arrow1 = None base_style.line_arrow2 = None base_style.font = None base_style.font_size = 12.0 # sanity check: does base_style have all properties? for key in dir(properties.factory_defaults): if not hasattr(base_style, key): warn(INTERNAL, 'added default for property %s', key) setattr(base_style, key, getattr(properties.factory_defaults, key)) papersizes = [ # 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7', 'letter', 'legal', 'executive', ] class SKLoader(GenericLoader):