def read_text(self, line): args = tokenize(line, 12) # don't tokenize the text itself if len(args) != 13: # including the unparsed rest of the line raise SketchLoadError('Invalid text specification') sub_type, color, depth, pen_style, font, size, angle, flags, \ height, length, x, y, rest = args self.fill(color, None) self.font(font, size * 0.9, flags) if len(rest) > 2: #at least a space and a newline # read the actual text. This implementation may fail in # certain cases! string = rest[1:] while string[-5:] != '\\001\n': line = self.readline() if not line: raise SketchLoadError('Premature end of string') string = string + line globals = {'__builtins__': {}} try: # using eval here might be a security hole! string = eval('"""' + string[:-5] + '"""', globals) except: string = eval("'''" + string[:-5] + "'''", globals) else: raise SketchLoadError('Invalid text string') trafo = Translation(self.trafo(x, y))(Rotation(angle)) self.simple_text(string, trafo = trafo, halign = align[sub_type]) self.set_depth(depth)
def read_polyline(self, line): readline = self.readline tokenize = skread.tokenize_line args = tokenize(line) if len(args) != 15: raise SketchLoadError('Invalid PolyLine specification') sub_type, line_style, thickness, pen_color, fill_color, depth, \ pen_style, area_fill, style, join, cap, \ radius, forward_arrow, backward_arrow, npoints = args self.fill(fill_color, area_fill) self.line(pen_color, thickness, join, cap, line_style, style) if forward_arrow: readline() # XXX: implement this if backward_arrow: readline() # XXX: implement this if sub_type == 5: readline() # imported picture ncoords = npoints * 2 pts = self.read_tokens(ncoords) if not pts: raise SketchLoadError('Missing points for polyline') if len(pts) > ncoords: del pts[ncoords:] trafo = self.trafo if sub_type in (1, 3, 5): path = CreatePath() map(path.AppendLine, coords_to_points(pts, trafo)) if sub_type == 3: path.load_close(1) self.bezier(paths=path) self.set_depth(depth) elif sub_type in (2, 4): wx, wy = trafo(pts[2], pts[3]) - trafo(pts[0], pts[1]) hx, hy = trafo(pts[4], pts[5]) - trafo(pts[2], pts[3]) x, y = trafo(pts[0], pts[1]) if sub_type == 4 and radius > 0: radius1 = (radius * 72.0 / 80.0) / max(abs(wx), abs(wy)) radius2 = (radius * 72.0 / 80.0) / max(abs(hx), abs(hy)) else: radius1 = radius2 = 0 self.rectangle(wx, wy, hx, hy, x, y, radius1=radius1, radius2=radius2) self.set_depth(depth)
def Load(self): file = self.file if type(file) == StringType: file = open(file, 'r') dict = self.get_func_dict() from app import skread parse = skread.parse_sk_line2 readline = file.readline bezier_load = self.bezier_load num = 1 line = '#' if __debug__: import time start_time = time.clock() try: line = readline() while line: num = num + 1 if line[0] == 'b' and line[1] in 'sc': line = bezier_load(line) continue #parse(line, dict) funcname, args, kwargs = parse(line) if funcname is not None: function = dict.get(funcname) if function is not None: try: apply(function, args, kwargs) except TypeError: tb = sys.exc_info()[2] try: if tb.tb_next is None: # the exception was raised by apply # and not within the function. Try to # invoke the function with fewer # arguments if call_function(function, args, kwargs): message = _("Omitted some arguments " "for function %s") else: message = _("Cannot call function %s") self.add_message(message % function.__name__) else: raise finally: del tb else: self.add_message(_("Unknown function %s") % funcname) line = readline() except (SketchLoadError, SyntaxError), value: # a loader specific error occurred warn_tb(INTERNAL, 'error in line %d', num) if load._dont_handle_exceptions: raise else: raise SketchLoadError('%d:%s' % (num, value))
def end_composite(self): if self.composite_class: args, kw = self.composite_args if not kw: kw = {} composite = apply(self.composite_class, args, kw) # We treat Plugins specially here and in check_object so # that we can be a bit more lenient with plugin objects. # They should not be empty (after all they'd be invisible # then) but they might. If they're empty they're simply # ignored if self.composite_items or composite.can_be_empty \ or composite.is_Plugin: append = composite.load_AppendObject for item in self.composite_items: if self.check_object(item): append(item) composite.load_Done() self.__pop() self.append_object(composite) else: self.__pop() #may be just pass the problem? #raise EmptyCompositeError else: raise SketchLoadError('no composite to end')
def read_arc(self, line): readline = self.readline; tokenize = skread.tokenize_line args = tokenize(line) if len(args) != 21: raise SketchLoadError('Invalid Arc specification') sub_type, line_style, thickness, pen_color, fill_color, depth, \ pen_style, area_fill, style, cap, direction, \ forward_arrow, backward_arrow, \ cx, cy, x1, y1, x2, y2, x3, y3 = args self.fill(fill_color, area_fill) self.line(pen_color, thickness, const.JoinMiter, cap, line_style, style) if forward_arrow: readline() # XXX: implement this if backward_arrow:readline() # XXX: implement this trafo = self.trafo center = trafo(cx, cy); start = trafo(x1, y1); end = trafo(x3, y3) radius = abs(start - center) start_angle = atan2(start.y - center.y, start.x - center.x) end_angle = atan2(end.y - center.y, end.x - center.x) if direction == 0: start_angle, end_angle = end_angle, start_angle if sub_type == 1: sub_type = const.ArcArc else: sub_type = const.ArcPieSlice self.ellipse(radius, 0, 0, radius, center.x, center.y, start_angle, end_angle, sub_type) self.set_depth(depth)
def Load(self): file = self.file funclist = self.get_compiled() # binding frequently used functions to local variables speeds up # the process considerably... readline = file.readline; 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
def dstyle(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) style = self.style.AsDynamicStyle() style.SetName(name) self.style_dict[name] = style self.style = Style()
def line(self, color, width, join, cap, style = 0, style_val = 0): if width: val = style_val / width width = width * 72.0/80.0 pattern = self.get_pattern(color) dashes = () if style == 1: # dashed dashes = (val, val) elif style == 2: # dotted dashes = (1 / width, val) elif style == 3: # dash-dot dashes = (val, 0.5 * val, 1 / width, 0.5 * val) elif style == 4: # dash-dot-dot dashes = (val, 0.45 * val, 1 / width, 0.333 * val, 1 / width, 0.45 * val) elif style == 5: # dash-dot-dot-dot dashes = (val, 0.4 * val, 1 / width, 0.333 * val, 1 / width, 0.333 * val, 1 / width, 0.4 * val) try: self.set_properties(line_pattern = pattern, line_width = width, line_join = xfig_join[join], line_cap = xfig_cap[cap], line_dashes = dashes) except: raise SketchLoadError("can't assign line style: %s:%s" % sys.exc_info()[:2]) else: self.empty_line()
def fill(self, color, style): pattern = self.get_pattern(color, style) try: self.set_properties(fill_pattern = pattern) except: raise SketchLoadError("can't assign fill style: %s:%s" % sys.exc_info()[:2])
def begin_layer_class(self, layer_class, args, kw=None): if issubclass(self.composite_class, layer.Layer): self.end_composite() if issubclass(self.composite_class, doc_class): self.begin_composite(layer_class, args, kw) else: raise SketchLoadError('self.composite_class is %s, not a document', self.composite_class)
def use_style(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) if not self.style.IsEmpty(): self.prop_stack.load_AddStyle(self.style) self.style = Style() style = self.style_dict[name] self.prop_stack.load_AddStyle(style)
def load_drawing(filename): if type(filename) == StringType: name = filename try: file = open(name, 'rb') except IOError, value: message = value.strerror raise SketchLoadError( _("Cannot open %(filename)s:\n%(message)s") % locals())
def parse_drawing(filename, output_filename): name = locale_utils.utf_to_locale(filename) try: file = open(name, 'rb') except IOError, value: message = value.strerror raise SketchLoadError( _("Cannot open %(filename)s:\n%(message)s") % locals())
def parse_drawing_from_file(file, filename, doc_class=None): line = file.readline() if line[:4] == 'RIFF' and len(line) < 12: line = line + file.read(12 - len(line)) for info in filters.parsing_plugins: match = info.rx_magic.match(line) if match: parser = info(file, filename, match) try: try: parser.Load() return except Exception, value: raise SketchLoadError(_("Parsing error: ") + str(value)) finally: info.UnloadPlugin() else: raise SketchLoadError(_("Unrecognised file type"))
def load_drawing_from_file(file, filename='', doc_class=None): # Note: the doc_class argument is only here for plugin interface # compatibility with 0.7 (especiall e.g. gziploader) line = file.readline() # XXX ugly hack for riff-based files, e.g. Corel's CMX. The length # might contain newline characters. if line[:4] == 'RIFF' and len(line) < 12: line = line + file.read(12 - len(line)) #print line for info in filters.import_plugins: match = info.rx_magic.match(line) if match: loader = info(file, filename, match) try: try: if do_profile: import profile warn(INTERNAL, 'profiling...') prof = profile.Profile() prof.runctx('loader.Load()', globals(), locals()) prof.dump_stats( os.path.join(info.dir, info.module_name + '.prof')) warn(INTERNAL, 'profiling... (done)') doc = loader.object else: #t = time.clock() doc = loader.Load() #print 'load in', time.clock() - t, 'sec.' messages = loader.Messages() if messages: doc.meta.load_messages = messages return doc except Exception, value: raise SketchLoadError(_("Parsing error: ") + str(value)) finally: info.UnloadPlugin() else: raise SketchLoadError(_("unrecognised file type"))
def read_header(self): format = orientation = None if self.format_version >= 3.0: line = strip(self.readline()) if line: # portrait/landscape if lower(line) == 'landscape': orientation = pagelayout.Landscape else: orientation = pagelayout.Portrait else: raise SketchLoadError('No format specification') line = strip(self.readline()) if line: # centering line = lower(line) if line == 'center' or line == 'flush left': line = lower(strip(self.readline())) if not line: raise SketchLoadError( 'No Center/Flushleft or Units specification') if line == 'metric': # ignore for now pass if self.format_version >= 3.2: self.readline() # papersize self.readline() # magnification self.readline() # pages self.readline() # transparent color line = strip(self.readline()) if line: try: ppi, coord = map(atoi, split(line)) except: raise SketchLoadError('Invalid Resolution specification') self.trafo = self.trafo(Scale(72.0 / ppi))
def Load(self): if self.filename: basename, ext = os.path.splitext(self.filename) if ext != '.gz': basename = self.filename stream = os.popen('gzip -d -c ' + sh_quote(self.filename)) doc = load.load_drawing_from_file(stream, basename, doc_class=self.doc_class) if doc: doc.meta.compressed = "gzip" doc.meta.compressed_file = self.filename self.messages = doc.meta.load_messages return doc raise SketchLoadError('gziploader must be instantiated with filename')
def read_ellipse(self, line): readline = self.readline; tokenize = skread.tokenize_line args = tokenize(line) if len(args) != 19: raise SketchLoadError('Invalid Ellipse specification') sub_type, line_style, thickness, pen_color, fill_color, depth, \ pen_style, area_fill, style, direction, angle, \ cx, cy, rx, ry, sx, sy, ex, ey = args self.fill(fill_color, area_fill) self.line(pen_color, thickness, const.JoinMiter, const.CapButt, line_style, style) center = self.trafo(cx, cy); radius = self.trafo.DTransform(rx, ry) trafo = Trafo(radius.x, 0, 0, radius.y) trafo = Rotation(angle)(trafo) trafo = Translation(center)(trafo) apply(self.ellipse, trafo.coeff()) self.set_depth(depth)
def Load(self): file = self.file if type(file) == StringType: file = open(file, 'r') dict = self.get_func_dict() from app import skread parse = skread.parse_sk_line2 readline = file.readline bezier_load = self.bezier_load num = 1 line = '#' fileinfo = os.stat(self.filename) totalsize = fileinfo[6] interval = int((totalsize / 200) / 10) + 1 interval_count = 0 if __debug__: import time start_time = time.clock() try: line = readline() parsed = int(file.tell() * 100 / totalsize) app.updateInfo(inf2='%u' % parsed + '% of file is parsed...', inf3=parsed) while line: num = num + 1 if line[0] == 'b' and line[1] in 'sc': line = bezier_load(line) continue funcname, args, kwargs = parse(line) if funcname is not None: function = dict.get(funcname) if function is not None: try: if line[:3] == 'txt': args = (readline, ) + args apply(function, args, kwargs) except TypeError: tb = sys.exc_info()[2] try: if tb.tb_next is None: # the exception was raised by apply # and not within the function. Try to # invoke the function with fewer # arguments if call_function(function, args, kwargs): message = _("Omitted some arguments " "for function %s") else: message = _("Cannot call function %s") self.add_message(message % function.__name__) else: raise finally: del tb else: self.add_message(_("Unknown function %s") % funcname) line = readline() interval_count += 1 if interval_count > interval: interval_count = 0 parsed = int(file.tell() * 100 / totalsize) app.updateInfo(inf2='%u' % parsed + '% of file is parsed...', inf3=parsed) except (SketchLoadError, SyntaxError), value: # a loader specific error occurred warn_tb(INTERNAL, 'error in line %d', num) if load._dont_handle_exceptions: raise else: raise SketchLoadError('%d:%s' % (num, value))
def pgc(self, cx, cy, dx, dy): if not self.gradient: raise SketchLoadError(_("No gradient for gradient pattern")) self.pattern = ConicalGradient(self.gradient, Point(cx, cy), Point(dx, dy))
def pgr(self, dx, dy, border=0): if not self.gradient: raise SketchLoadError(_("No gradient for gradient pattern")) self.pattern = RadialGradient(self.gradient, Point(dx, dy), border)
def read_spline(self, line): readline = self.readline; tokenize = skread.tokenize_line args = tokenize(line) if len(args) != 13: raise SketchLoadError('Invalid Spline specification') sub_type, line_style, thickness, pen_color, fill_color, depth, \ pen_style, area_fill, style, cap, \ forward_arrow, backward_arrow, npoints = args closed = sub_type & 1 if forward_arrow: readline() if backward_arrow:readline() # in 3.2 all splines are stored as x-splines... if self.format_version == 3.2: if sub_type in (0, 2): sub_type = 4 else: sub_type = 5 self.fill(fill_color, area_fill) self.line(pen_color, thickness, 0, cap, line_style, style) ncoords = npoints * 2 pts = self.read_tokens(ncoords) if not pts: raise SketchLoadError('Missing points for spline') if len(pts) > ncoords: del pts[ncoords:] pts = coords_to_points(pts, self.trafo) path = CreatePath() if sub_type in (2, 3): # interpolated spline, read 2 control points for each node ncontrols = 4 * npoints controls = self.read_tokens(ncontrols) if not controls: raise SketchLoadError('Missing control points for spline') if len(controls) > ncontrols: del controls[ncontrols:] controls = coords_to_points(controls[2:-2], self.trafo) path.AppendLine(pts[0]) ncontrols = 2 * (npoints - 1) controls = [controls] * (npoints - 1) map(path.AppendBezier, map(getitem, controls, range(0, ncontrols, 2)), map(getitem, controls, range(1, ncontrols, 2)), pts[1:]) elif sub_type in (0, 1): # approximated spline f13 = 1.0 / 3.0; f23 = 2.0 / 3.0 curve = path.AppendBezier straight = path.AppendLine last = pts[0] cur = pts[1] start = node = (last + cur) / 2 if closed: straight(node) else: straight(last) straight(node) last = cur for cur in pts[2:]: c1 = f13 * node + f23 * last node = (last + cur) / 2 c2 = f13 * node + f23 * last curve(c1, c2, node) last = cur if closed: curve(f13 * node + f23 * last, f13 * start + f23 * last, start) else: straight(last) elif sub_type in (4, 5): # An X-spline. Treat it like a polyline for now. # read and discard the control info self.read_tokens(npoints) self.add_message(_("X-Spline treated as PolyLine")) map(path.AppendLine, pts) if closed: path.AppendLine(path.Node(0)) if closed: path.load_close(1) self.bezier(paths = path) self.set_depth(depth)