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 load_LTYPE(self):
        param = {
            '2': '',  # Linetype name
            '3': '',  # Descriptive text for linetype
            #'73': 0, # The number of linetype elements
            #'40': 0, # Total pattern length
            '49': [],  # Dash, dot or space length (one entry per element)
        }
        param = self.read_param(param, [0])

        name = upper(param['2'])
        if name:
            self.ltype_dict[name] = param
            dashes = []
            for i in xrange(len(param['49'])):
                dashes.append(abs(param['49'][i]) * self.unit_to_pt)

            name3 = param['3']
            #print name3, dashes
            if name3 and dashes:
                style = Style()
                style.line_dashes = tuple(dashes)
                style = style.AsDynamicStyle()
                style.SetName(name + name3)
                self.dynamic_style_dict[name] = style
	def __init__(self, file, filename, match):
		GenericLoader.__init__(self, file, filename, match)
		self.file = file
		self.curstyle = Style()
		self.verbosity = 0
		self.gdiobjects = []
		self.dcstack = []
		self.curpoint = Point(0, 0)
 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 get_prop_stack(self):
     stack = self.prop_stack
     if not self.style.IsEmpty():
         stack.load_AddStyle(self.style)
     stack.condense()
     if self.base_style is not None:
         self.prop_stack = PropertyStack(base=self.base_style.Duplicate())
     else:
         self.prop_stack = PropertyStack()
     self.style = Style()
     return stack
 def __init__(self, file, filename, match):
     LoaderWithComposites.__init__(self)
     self.file = file
     self.filename = filename
     self.match = match
     self.style = Style()
     if self.base_style is not None:
         self.prop_stack = PropertyStack(base=self.base_style.Duplicate())
     else:
         self.prop_stack = PropertyStack()
     self.messages = {}
Example #7
0
 def initialize(self):
     self.draw = 0
     self.scale = .283464566929
     self.cur_x = 0.0
     self.cur_y = 0.0
     self.palette = Palette(self.basename)
     self.path = CreatePath()
     self.cur_style = Style()
     self.cur_style.line_width = 0.6
     self.cur_style.line_join = const.JoinRound
     self.cur_style.line_cap = const.CapRound
     self.cur_style.line_pattern = self.palette.next_color(1)
    def __init__(self, file, filename, match):
        GenericLoader.__init__(self, file, filename, match)

        self.file = file

        self.DWGCODEPAGE = 'latin1'
        self.unit_to_pt = 2.83464566929
        self.dynamic_style_dict = {}
        self.style_dict = {}
        self.ltype_dict = {
            'CONTINUOUS': {
                '2': 'CONTINUOUS',  # Linetype name
                '3': 'Solid line',  # Descriptive text for linetype
                '49': [],  # Dash, dot or space length 
                #(one entry per element)
            }
        }
        self.layer_dict = {
            '0': {
                '2': '0',  # Layer name
                '6': 'CONTINUOUS',  #Linetype name
                '62': 0,  # Color number
                '370': None,  #Line weight
            }
        }
        self.block_dict = {}
        self.stack = []
        self.stack_trafo = []
        self.default_layer = '0'
        self.default_style = 'STANDARD'
        self.default_block = None
        self.default_line_width = 30
        self.EXTMIN = (1e+20, 1e+20)
        self.EXTMAX = (-1e+20, -1e+20)
        self.PEXTMIN = (1e+20, 1e+20)
        self.PEXTMAX = (-1e+20, -1e+20)

        self.general_param = {
            '8': self.default_layer,  # Layer name
            '6': 'BYLAYER',  # Linetype name 
            '62': 256,  # Color number 
            '48': 1.0,  # Linetype scale 
            #'60': 0, # Object visibility. If 1 Invisible
        }

        self.curstyle = Style()
        self.update_trafo()
 def initialize(self):
     self.curstyle = Style()
     self.curstyle.line_join = JoinRound
     self.curstyle.line_cap = CapRound
     self.cur_x = 0.0
     self.cur_y = 0.0
     self.draw = 0
     self.absolute = 1
     self.path = CreatePath()
     self.curpen = None
     self.penwidth = {}
     self.select_pen()
Example #10
0
	def get_line_style(self, **kw):
		if kw['8'] in self.layer_dict:
			self.default_layer = layer_name = kw['8']
		else:
			layer_name = self.default_layer

		linetype_name = upper(kw['6'])
		scale = kw['48']
		color_index = kw['62']
		
		
		style = Style()
		style.line_width = self.get_line_width()
		style.line_join = const.JoinRound
		style.line_cap = const.CapRound
		style.line_dashes = self.get_line_type(linetype_name = linetype_name, scale = scale, width = style.line_width)
		style.line_pattern = self.get_pattern(color_index)

		return style
Example #11
0
def styleFromFolder(path):
    print(path)
    assert (os.path.exists(path + "cfg.txt"))
    with open(path + "cfg.txt", "r") as f:
        lines = list(f)
        name = lines[0].strip()
        descr = lines[1].strip()
        if lines[2] == "CONV_NN":
            alg = Algorithms.Conv_NN
        else:
            alg = Algorithms.Cycle_GAN
        styleDir = path + lines[3].strip()
    styleImage = path + "style.jpg"
    if (os.path.exists(path + "preview.jpg")):
        previewImage = path + "preview.jpg"
    else:
        previewImage = None
    return Style(name=name,
                 descr=descr,
                 alg=alg,
                 styleDir=styleDir,
                 styleImage=styleImage,
                 computed=True,
                 previewImage=previewImage)
from app.io import load
from app.conf import const
from app.Graphics.color import ParseSketchColor, CreateCMYKColor, CreateRGBColor, CreateSPOTColor, \
   CreateRGBAColor, CreateCMYKAColor, CreateSPOTAColor
from app import SolidPattern, HatchingPattern,EmptyPattern, \
  LinearGradient, ConicalGradient, RadialGradient, ImageTilePattern, \
  Style, MultiGradient, Trafo, Translation, Point, \
  GridLayer, GuideLayer, GuideLine, Arrow, CreatePath, StandardColors, \
  GetFont

from app.io.load import GenericLoader

from app.Graphics import pagelayout, plugobj, blendgroup, text, image, eps,\
  properties

base_style = 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):
class WMFLoader(GenericLoader):

	def __init__(self, file, filename, match):
		GenericLoader.__init__(self, file, filename, match)
		self.file = file
		self.curstyle = Style()
		self.verbosity = 0
		self.gdiobjects = []
		self.dcstack = []
		self.curpoint = Point(0, 0)

	def _print(self, format, *args, **kw):
		if self.verbosity:
			try:
				if kw:
					text = format % kw
				elif args:
					text = format % args
				else:
					text = format
			except:
				text = string.join([format] + map(str, args))
			if text[-1] != '\n':
				text = text + '\n'
			sys.stdout.write(text)

	def get_struct(self, format):
		size = calcsize(format)
		return unpack(format, self.file.read(size))

	def get_int16(self):
		return self.get_struct('<h')[0]

	def get_int32(self):
		return self.get_struct('<i')[0]

	def read_headers(self):
		self.file.seek(0)
		placeable = self.file.read(calcsize(struct_placeable_header))
		key, handle, left, top, right, bottom, inch, reserved, checksum\
				= unpack(struct_placeable_header, placeable)
		if key != rx_magic:
			raise SketchLoadError(_("The file is not a placeable "
									"windows metafile"))
			self._print("The file is not a placeable windows metafile")
		sum = 0
		for word in unpack('<10h', placeable[:20]):
			sum = sum ^ word
		if sum != checksum:
			#raise SketchLoadError(_("The file has an incorrect checksum"))
			self._print("The file has an incorrect checksum")

		self.inch = inch
		self.bbox = (left, top, right, bottom)
		factor = 72.0 / self.inch
		self.wx = self.wy = 0
		self.wwidth = right - left
		self.wheight = bottom - top
		self.vx = self.vy = 0
		self.vwidth = self.wwidth
		self.vheight = self.wheight
		self.base_trafo = Trafo(factor, 0, 0, -factor,
								0, factor * self.vheight)
		self.update_trafo()

		header = self.file.read(calcsize(struct_wmf_header))
		filetype, headersize, version, filesize, numobj, maxrecord, numparams\
					= unpack(struct_wmf_header, header)

		self._print('\nHeader\n------\n')
		fmt = '% 10s: %s\n'
		self._print(fmt, 'inch', self.inch)
		self._print(fmt, 'bbox', self.bbox)
		self._print(fmt, 'headersize', headersize)
		self._print(fmt, 'version', version)
		self._print(fmt, 'numobj', numobj)
		self._print(fmt, 'numparams', numparams)
		self._print(fmt, 'maxrecord', maxrecord)
		self._print('\n')

	def update_trafo(self):
		wt = Translation(-self.wx, -self.wy)
		vt = Translation(self.vx, self.vy)
		scale = Scale(float(self.vwidth) / self.wwidth,
						float(self.vheight) / self.wheight)
		self.trafo = self.base_trafo(vt(scale(wt)))

	def add_gdiobject(self, object):
		try:
			idx = self.gdiobjects.index(None)
		except ValueError:
			self.gdiobjects.append(object)
		else:
			self.gdiobjects[idx] = object

	def delete_gdiobject(self, idx):
		self.gdiobjects[idx] = None

	def SelectObject(self):
		idx = self.get_int16()
		try:
			object = self.gdiobjects[idx]
		except IndexError:
			print 'Index Error:', idx, self.gdiobjects
			raise
		for property, value in object:
			setattr(self.curstyle, property, value)
		self._print('->', idx, object)

	def DeleteObject(self):
		idx = self.get_int16()
		self.delete_gdiobject(idx)
		self._print('->', idx)

	def get_dc(self):
		return self.curstyle.Duplicate(), self.trafo, self.curpoint

	def set_dc(self, dc):
		self.curstyle, self.trafo, self.curpoint = dc

	def SaveDC(self):
		self.dcstack.append(self.get_dc())

	def RestoreDC(self):
		self.set_dc(self.dcstack[-1])
		del self.dcstack[-1]

	def SetMapMode(self):
		mode = self.get_int16()
		self._print('->', mode)

	def SetWindowOrg(self):
		self.wy, self.wx = self.get_struct('<hh')
		self.update_trafo()
		self._print('->', self.wx, self.wy)

	def SetWindowExt(self):
		self.wheight, self.wwidth = self.get_struct('<hh')
		self.update_trafo()
		self._print('->', self.wwidth, self.wheight)

	def SetPolyFillMode(self):
		mode = self.get_int16()
		self._print('->', mode)

	SetBkMode = noop
	SetBkColor = noop
	SetROP2 = noop

	def CreateBrushIndirect(self):
		style, r, g, b, hatch = self.get_struct('<hBBBxh')
		if style == 1:
			pattern = EmptyPattern
		else:
			pattern = SolidPattern(CreateRGBColor(r/255.0, g/255.0, b/255.0))
		self.add_gdiobject((('fill_pattern', pattern),))

		self._print('->', style, r, g, b, hatch)

	def DibCreatePatternBrush(self):
		self.add_message(_("Bitmap brushes not yet implemented. Using black"))
		pattern = SolidPattern(StandardColors.black)
		self.add_gdiobject((('fill_pattern', pattern),))

	def CreatePenIndirect(self):
		style, widthx, widthy, r, g, b = self.get_struct('<hhhBBBx')
		cap = (style & 0x0F00) >> 8
		join = (style & 0x00F0) >> 4
		style = style & 0x000F
		if style == 5:
			pattern = EmptyPattern
		else:
			pattern = SolidPattern(CreateRGBColor(r/255.0, g/255.0, b/255.0))
		width = abs(widthx * self.trafo.m11)
		self.add_gdiobject((('line_pattern', pattern,),
							('line_width',  width)))
		self._print('->', style, widthx, widthy, r, g, b, cap, join)

	def CreatePalette(self):
		self.add_gdiobject((('ignore', None),))

	def CreateRegion(self):
		self.add_gdiobject((('ignore', None),))

	CreateFontIndirect = CreatePalette
	SelectPalette = noop
	RealizePalette = noop
	
	SetTextColor = noop
	SetTextAlign = noop
	SetTextJustification = noop

	SetStretchBltMode = noop
	
	def read_points(self, num):
		coords = self.get_struct('<' + num * 'hh')
		points = [];
		append = points.append
		trafo = self.trafo
		for i in range(0, 2 * num, 2):
			append(trafo(coords[i], coords[i + 1]))
		return points

	def Polyline(self):
		points = self.read_points(self.get_int16())
		if points:
			path = CreatePath()
			map(path.AppendLine, points)
			self.prop_stack.AddStyle(self.curstyle.Duplicate())
			self.prop_stack.SetProperty(fill_pattern = EmptyPattern)
			self.bezier((path,))

		#for i in range(len(points)):
		#    self._print('->', points[i])

	def Polygon(self):
		points = self.read_points(self.get_int16())
		if points:
			path = CreatePath()
			map(path.AppendLine, points)
			if path.Node(-1) != path.Node(0):
				#print 'correct polygon'
				path.AppendLine(path.Node(0))
			path.load_close()
			self.prop_stack.AddStyle(self.curstyle.Duplicate())
			self.bezier((path,))

		#for i in range(len(points)):
		#    self._print('->', points[i])

	def PolyPolygon(self):
		nr_of_polygons = self.get_int16()
		nr_of_points = []
		for i in range(nr_of_polygons):
			nr_of_points.append(self.get_int16())
		path = ()
		for i in nr_of_points:
			points = self.read_points(i)
			if points:
				subpath = CreatePath()
				map(subpath.AppendLine, points)
				if subpath.Node(-1) != subpath.Node(0):
					subpath.AppendLine(subpath.Node(0))
				subpath.load_close()
				path = path + (subpath,)
		if path:
			self.prop_stack.AddStyle(self.curstyle.Duplicate())
			self.bezier(path)

	def MoveTo(self):
		y, x = self.get_struct('<hh')
		self.curpoint = self.trafo(x, y)
		self._print('->', self.curpoint)
	
	def LineTo(self):
		y, x = self.get_struct('<hh')
		p = self.trafo(x, y)
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		self.prop_stack.SetProperty(fill_pattern = EmptyPattern)
		path = CreatePath()
		path.AppendLine(self.curpoint)
		path.AppendLine(p)
		self.bezier((path,))
		self.curpoint = p
		self._print('->', self.curpoint)

	def Ellipse(self):
		bottom, right, top, left = self.get_struct('<hhhh')
		left, top = self.trafo(left, top)
		right, bottom = self.trafo(right, bottom)
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		self.ellipse((right - left) / 2, 0, 0, (bottom - top) / 2,
						(right + left) / 2, (top + bottom) / 2)

	def Arc(self, arc_type = const.ArcArc):
		ye, xe, ys, xs, bottom, right, top, left = self.get_struct('<hhhhhhhh')
		left, top = self.trafo(left, top)
		right, bottom = self.trafo(right, bottom)
		xs, ys = self.trafo(xs, ys)
		xe, ye = self.trafo(xe, ye)
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		if arc_type == const.ArcArc:
			self.prop_stack.SetProperty(fill_pattern = EmptyPattern)
		if left != right and top != bottom:
			t = Trafo((right - left) / 2, 0, 0, (bottom - top) / 2,
						(right + left) / 2, (top + bottom) / 2).inverse()
			# swap start and end-angle
			end_angle = t(xs, ys).polar()[1]
			start_angle = t(xe, ye).polar()[1]
		else:
			start_angle = end_angle = 0.0
		self.ellipse((right - left) / 2, 0, 0, (bottom - top) / 2,
						(right + left) / 2, (top + bottom) / 2,
						start_angle = start_angle, end_angle = end_angle,
						arc_type = arc_type)
	def Pie(self):
		self.Arc(const.ArcPieSlice)

	def Rectangle(self):
		bottom, right, top, left = self.get_struct('<hhhh')
		left, top = self.trafo(left, top)
		right, bottom = self.trafo(right, bottom)
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		self.rectangle(right - left, 0, 0, bottom - top, left, top)

	def RoundRect(self):
		ellh, ellw, bottom, right, top, left = self.get_struct('<hhhhhh')
		left, top = self.trafo(left, top)
		right, bottom = self.trafo(right, bottom)
		ellw, ellh = self.trafo.DTransform(ellw, ellh)
		self._print('->', left, top, right, bottom, ellw, ellh)
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		self.rectangle(right - left, 0, 0, bottom - top, left, top,
						radius1 = abs(ellw / (right - left)),
						radius2 = abs(ellh / (bottom - top)))
		

	def Escape(self):
		pass

	def interpret(self):
		tell = self.file.tell
		function = -1
		while function:
			pos = tell()
			size, function = self.get_struct('<ih')
			self._print('%5d: %4x: %s' % (size, function,
											wmf_functions.get(function, '')))
			if hasattr(self, wmf_functions.get(function, '')):
				getattr(self, wmf_functions[function])()
			else:
				if function:
					self.file.read(2 * (size - 3))
					self._print('*** unimplemented:',
								wmf_functions.get(function, ''))
			pos = pos + 2 * size
			if tell() < pos:
				self.file.read(pos - tell())
			elif tell() > pos:
				self._print('read too many bytes')
				self.file.seek(pos - tell(), 1)

	def Load(self):
		self.document()
		self.layer(name = _("WMF objects"))
		self.read_headers()
		self.interpret()
		self.end_all()
		self.object.load_Completed()
		return self.object
import struct
import operator
import copy
import types

from app import _, Trafo, Scale, Translation, Point, Polar, CreatePath, \
		CreateRGBColor, SolidPattern, EmptyPattern, LinearGradient, \
		MultiGradient, Style, const, StandardColors, GridLayer, GetFont, \
		HatchingPattern

from app.events.warn import INTERNAL, warn_tb
from app.io.load import GenericLoader, SketchLoadError
import uniconvertor
from app.Graphics import text

basestyle = Style()
basestyle.fill_pattern = EmptyPattern
basestyle.fill_transform = 1
basestyle.line_pattern = EmptyPattern
basestyle.line_width = 1.0
basestyle.line_join = const.JoinMiter
basestyle.line_cap = const.CapButt
basestyle.line_dashes = ()
basestyle.line_arrow1 = None
basestyle.line_arrow2 = None
basestyle.font = None
basestyle.font_size = 12.0


CGM_ID = {
	0x0020: 'BEGMF',
Example #15
0
class DSTLoader(GenericLoader):
    def __init__(self, file, filename, match):
        GenericLoader.__init__(self, file, filename, match)
        self.file = file
        self.basename, self.ext = os.path.splitext(filename)

    def initialize(self):
        self.draw = 0
        self.scale = .283464566929
        self.cur_x = 0.0
        self.cur_y = 0.0
        self.palette = Palette(self.basename)
        self.path = CreatePath()
        self.cur_style = Style()
        self.cur_style.line_width = 0.6
        self.cur_style.line_join = const.JoinRound
        self.cur_style.line_cap = const.CapRound
        self.cur_style.line_pattern = self.palette.next_color(1)

    def readInt32(self, file):
        try:
            data = unpack('<I', file.read(4))[0]
        except:
            data = None
        return data

    def readInt8(self, file):
        try:
            data = int(unpack('B', file.read(1))[0])
        except:
            data = None
        return data

    def get_position(self, x=None, y=None):
        if x is None:
            x = self.cur_x
        else:
            x = float(x) * self.scale + self.cur_x
        if y is None:
            y = self.cur_y
        else:
            y = float(y) * self.scale + self.cur_y
        return x, y

    def bezier(self):
        if self.path.len > 1:
            self.prop_stack.AddStyle(self.cur_style.Duplicate())
            GenericLoader.bezier(self, paths=(self.path, ))
        self.path = CreatePath()

    def jump(self, x, y):
        x, y = self.get_position(x, y)
        self.cur_x = x
        self.cur_y = y

    def needle_move(self, x, y):
        if self.draw == 1:
            self.path.AppendLine(x, y)
        else:
            self.bezier()
            self.path.AppendLine(x, y)
        self.cur_x = x
        self.cur_y = y

    def needle_down(self, x=None, y=None):
        self.draw = 1
        x, y = self.get_position(x, y)
        self.needle_move(x, y)

    def needle_up(self, x=None, y=None):
        if self.draw == 1:
            self.bezier()
        self.draw = 0
        x, y = self.get_position(x, y)
        self.needle_move(x, y)

    def decode_x(self, d1, d2, d3):
        x = 1 * byte(d1, 7) - 1 * byte(d1, 6) + 9 * byte(d1, 5) - 9 * byte(
            d1, 4)
        x += 3 * byte(d2, 7) - 3 * byte(d2, 6) + 27 * byte(d2, 5) - 27 * byte(
            d2, 4)
        x += 81 * byte(d3, 5) - 81 * byte(d3, 4)
        return x

    def decode_y(self, d1, d2, d3):
        y = 1 * byte(d1, 0) - 1 * byte(d1, 1) + 9 * byte(d1, 2) - 9 * byte(
            d1, 3)
        y += 3 * byte(d2, 0) - 3 * byte(d2, 1) + 27 * byte(d2, 2) - 27 * byte(
            d2, 3)
        y += 81 * byte(d3, 2) - 81 * byte(d3, 3)
        return y

    def decode_flag(self, d3):
        if d3 == 243:
            return END
        if d3 & 195 == 3:
            return NORMAL
        elif d3 & 195 == 131:
            return JUMP
        elif d3 & 195 == 195:
            return CHANGECOLOR
        else:
            return UNKNOWN

    def readheader(self, file):
        file.seek(0)
        header = file.read(512).split('\r')
        dict = {}
        for i in header:
            if i[2] == ':':
                dict[i[0:2]] = i[3:].replace(' ', '')
        x = int(dict['-X'])
        y = int(dict['-Y'])
        self.jump(x, y)

    def Load(self):
        file = self.file
        fileinfo = os.stat(self.filename)
        totalsize = fileinfo[6]
        self.initialize()
        self.readheader(file)
        self.document()
        self.layer(name=_("DST_objects"))
        parsed = 0
        parsed_interval = totalsize / 99 + 1
        flag = UNKNOWN
        while 1:

            interval_count = file.tell() / parsed_interval
            if interval_count > parsed:
                parsed += 10  # 10% progress
                app.updateInfo(inf2='%u' % parsed + '% of file is parsed...',
                               inf3=parsed)

            data = file.read(3)
            if len(data) < 3 or flag == 'END':
                self.needle_up()
                ## END INTERPRETATION
                app.updateInfo(inf2=_('Parsing is finished'), inf3=100)
                break

            d1, d2, d3 = unpack('BBB', data)
            x = self.decode_x(d1, d2, d3)
            y = self.decode_y(d1, d2, d3)
            #XXX swap coordinate
            x, y = y, x

            flag = self.decode_flag(d3)
            if flag == NORMAL:
                self.needle_down(x, y)
            elif flag == CHANGECOLOR:
                self.needle_up(x, y)
                self.cur_style.line_pattern = self.palette.next_color()
            elif flag == JUMP:
                #self.bezier() # cut the rope
                self.jump(x, y)

        self.end_all()
        self.object.load_Completed()
        return self.object
class GenericLoader(LoaderWithComposites):

    format_name = ''

    base_style = None

    def __init__(self, file, filename, match):
        LoaderWithComposites.__init__(self)
        self.file = file
        self.filename = filename
        self.match = match
        self.style = Style()
        if self.base_style is not None:
            self.prop_stack = PropertyStack(base=self.base_style.Duplicate())
        else:
            self.prop_stack = PropertyStack()
        self.messages = {}

    def get_prop_stack(self):
        stack = self.prop_stack
        if not self.style.IsEmpty():
            stack.load_AddStyle(self.style)
        stack.condense()
        if self.base_style is not None:
            self.prop_stack = PropertyStack(base=self.base_style.Duplicate())
        else:
            self.prop_stack = PropertyStack()
        self.style = Style()
        return stack

    def set_prop_stack(self, stack):
        self.prop_stack = stack

    def document(self, *args, **kw):
        self.begin_composite(doc_class, args, kw)

    def layer(self, *args, **kw):
        self.begin_layer_class(layer.Layer, args, kw)

    def masterlayer(self, *args, **kw):
        kw['is_MasterLayer'] = 1
        self.begin_layer_class(layer.Layer, args, kw)

    def page(self, *args, **kw):
        kw['is_Page'] = 1
        self.begin_layer_class(layer.Layer, args, kw)

    def end_layer(self):
        self.end_composite()

    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 bezier(self, paths=None):
        self.append_object(
            PolyBezier(paths=paths, properties=self.get_prop_stack()))

    def rectangle(self, m11, m21, m12, m22, v1, v2, radius1=0, radius2=0):
        trafo = Trafo(m11, m21, m12, m22, v1, v2)
        self.append_object(
            Rectangle(trafo,
                      radius1=radius1,
                      radius2=radius2,
                      properties=self.get_prop_stack()))

    def ellipse(self,
                m11,
                m21,
                m12,
                m22,
                v1,
                v2,
                start_angle=0.0,
                end_angle=0.0,
                arc_type=ArcPieSlice):
        self.append_object(
            Ellipse(Trafo(m11, m21, m12, m22, v1, v2),
                    start_angle,
                    end_angle,
                    arc_type,
                    properties=self.get_prop_stack()))

    def simple_text(self,
                    str,
                    trafo=None,
                    valign=text.ALIGN_BASE,
                    halign=text.ALIGN_LEFT):
        if type(trafo) == TupleType:
            if len(trafo) == 2:
                trafo = apply(Translation, trafo)
            else:
                raise TypeError, "trafo must be a Trafo-object or a 2-tuple"
        self.append_object(
            text.SimpleText(text=str,
                            trafo=trafo,
                            valign=valign,
                            halign=halign,
                            properties=self.get_prop_stack()))

    def image(self, image, trafo):
        if type(trafo) == TupleType:
            if len(trafo) == 2:
                trafo = apply(Translation, trafo)
            else:
                raise TypeError, "trafo must be a Trafo-object or a 2-tuple"
        image = ImageData(image)
        self.append_object(Image(image, trafo=trafo))

    def begin_group(self, *args, **kw):
        self.begin_composite(group.Group, args, kw)

    def end_group(self):
        self.end_composite()

    def guess_cont(self):
        self.guess_continuity = 1

    def end_composite(self):
        isdoc = self.composite_class is doc_class
        LoaderWithComposites.end_composite(self)
        if isdoc:
            self.add_meta(self.object)

    def add_meta(self, doc):
        doc.meta.fullpathname = self.filename
        dir, name = os.path.split(self.filename)
        doc.meta.directory = dir
        doc.meta.filename = name
        doc.meta.native_format = 0
        doc.meta.format_name = self.format_name

    def add_message(self, message):
        pdebug(('load', 'echo_messages'), message)
        self.messages[message] = self.messages.get(message, 0) + 1

    def Messages(self):
        messages = self.messages.items()
        list = []
        for message, count in messages:
            if count > 1:
                list.append(_("%(message)s (%(count)d times)") % locals())
            else:
                list.append(message)
        list.sort()
        return string.join(list, '\n')
class SKLoader(GenericLoader):

    format_name = format_name

    base_style = base_style

    functions = [
        'document', 'layer', 'masterlayer', 'page', ('bezier', 'b'),
        ('rectangle', 'r'), ('ellipse', 'e'), 'group', ('group', 'G'),
        'endgroup', ('endgroup', 'G_'), 'guess_cont'
    ]

    def __init__(self, file, filename, match):
        GenericLoader.__init__(self, file, filename, match)
        if atoi(match.group('minor')) > 2:
            self.add_message(
                _("The file was created by a newer version"
                  " of sK1, there might be inaccuracies."))
        if self.filename:
            self.directory = os.path.split(filename)[0]
        else:
            self.directory = ''
        self.style_dict = {}
        self.id_dict = {}
        self.page_layout = None
        self.pattern = None
        self.gradient = None
        self.arrow1 = None
        self.arrow2 = None
        self.font = None
        self.font_size = 1.0
        self.color_cache = {}

    def __del__(self):
        pass

    def warn(self, level, *args, **kw):
        message = apply(warn, (level, ) + args, kw)
        self.add_message(message)

    def get_func_dict(self):
        func_dict = {}
        for name in self.functions:
            if type(name) == StringType:
                func_dict[name] = getattr(self, name)
            else:
                func_dict[name[1]] = getattr(self, name[0])
        return func_dict

    functions.append('layout')

    def layout(self, format, orientation):
        if type(format) == StringType:
            if format not in papersizes:
                # The format is given by name but it's not one of the
                # standard papersizes. The file may be corrupted.
                self.add_message(
                    _("Unknown paper format '%s', "
                      "using A4 instead") % format)
                format = "A4"
            layout = pagelayout.PageLayout(format, orientation=orientation)
        else:
            w, h = format
            layout = pagelayout.PageLayout(width=w,
                                           height=h,
                                           orientation=orientation)
        self.page_layout = layout

    functions.append('grid')

    def grid(self, geometry, visible=0, color=None, name=None):
        if name is None:
            name = _("Grid")
        self.begin_layer_class(
            GridLayer, (geometry, visible, self.convert_color(color), name))
        self.end_composite()

    def convert_color(self, color_spec):
        try:
            c = self.color_cache.get(color_spec)
            if c:
                return c
            if color_spec[0] == 'RGB' and len(color_spec) == 4:
                c = CreateRGBColor(color_spec[1], color_spec[2], color_spec[3])
            elif color_spec[0] == 'RGB' and len(color_spec) == 5:
                c = CreateRGBAColor(color_spec[1], color_spec[2],
                                    color_spec[3], color_spec[4])
            elif color_spec[0] == 'CMYK' and len(color_spec) == 5:
                c = CreateCMYKColor(color_spec[1], color_spec[2],
                                    color_spec[3], color_spec[4])
            elif color_spec[0] == 'CMYK' and len(color_spec) == 6:
                c = CreateCMYKAColor(color_spec[1], color_spec[2],
                                     color_spec[3], color_spec[4],
                                     color_spec[5])
            elif color_spec[0] == 'SPOT' and len(color_spec) == 10:
                c = CreateSPOTColor(color_spec[3], color_spec[4],
                                    color_spec[5], color_spec[6],
                                    color_spec[7], color_spec[8],
                                    color_spec[9], color_spec[2],
                                    color_spec[1])
            elif color_spec[0] == 'SPOT' and len(color_spec) == 11:
                c = CreateSPOTAColor(color_spec[3], color_spec[4],
                                     color_spec[5], color_spec[6],
                                     color_spec[7], color_spec[8],
                                     color_spec[9], color_spec[10],
                                     color_spec[2], color_spec[1])
            else:
                c = apply(ParseSketchColor, 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

    functions.append('gl')

    def gl(self, colors):
        c = []
        for pos, color in colors:
            c.append((pos, self.convert_color(color)))
        self.gradient = MultiGradient(c)

    functions.append('pe')

    def pe(self):
        self.pattern = EmptyPattern

    functions.append('ps')

    def ps(self, color):
        self.pattern = SolidPattern(self.convert_color(color))

    functions.append('pgl')

    def pgl(self, dx, dy, border=0):
        if not self.gradient:
            raise SketchLoadError(_("No gradient for gradient pattern"))
        self.pattern = LinearGradient(self.gradient, Point(dx, dy), border)

    functions.append('pgr')

    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)

    functions.append('pgc')

    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))

    functions.append('phs')

    def phs(self, color, background, dx, dy, dist, width):
        self.pattern = HatchingPattern(self.convert_color(color),
                                       self.convert_color(background),
                                       Point(dx, dy), dist, width)

    functions.append('pit')

    def pit(self, id, trafo):
        trafo = apply(Trafo, trafo)
        self.pattern = ImageTilePattern(self.id_dict[id], trafo)

    functions.append('fp')

    def fp(self, color=None):
        if color is None:
            self.style.fill_pattern = self.pattern
        else:
            self.style.fill_pattern = SolidPattern(self.convert_color(color))

    functions.append('fe')

    def fe(self):
        self.style.fill_pattern = EmptyPattern

    functions.append('ft')

    def ft(self, bool):
        self.style.fill_transform = bool

    functions.append('lp')

    def lp(self, color=None):
        if color is None:
            self.style.line_pattern = self.pattern
        else:
            self.style.line_pattern = SolidPattern(self.convert_color(color))

    functions.append('le')

    def le(self):
        self.style.line_pattern = EmptyPattern

    functions.append('lw')

    def lw(self, width):
        self.style.line_width = width

    functions.append('lj')

    def lj(self, join):
        self.style.line_join = join

    functions.append('lc')

    def lc(self, cap):
        if not 1 <= cap <= 3:
            self.add_message('line cap corrected from %d to 1' % cap)
            cap = 1
        self.style.line_cap = cap

    functions.append('ld')

    def ld(self, dashes):
        self.style.line_dashes = dashes

    functions.append('la1')

    def la1(self, args=None):
        if args is not None:
            self.style.line_arrow1 = apply(Arrow, args)
        else:
            self.style.line_arrow1 = None

    functions.append('la2')

    def la2(self, args=None):
        if args is not None:
            self.style.line_arrow2 = apply(Arrow, args)
        else:
            self.style.line_arrow2 = None

    functions.append('dstyle')

    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()

    functions.append(('use_style', 'style'))

    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)

    functions.append('Fn')

    def Fn(self, name):
        self.style.font = GetFont(name)

    functions.append('Fs')

    def Fs(self, size):
        self.style.font_size = size

    functions.append('guide')

    def guide(self, pos, horizontal):
        if horizontal:
            p = Point(0, pos)
        else:
            p = Point(pos, 0)
        self.append_object(GuideLine(p, horizontal))

    functions.append('guidelayer')

    def guidelayer(self, *args, **kw):
        self.begin_layer_class(GuideLayer, args, kw)

    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

    functions.append('txt')

    def txt(self,
            thetext,
            trafo,
            halign=text.ALIGN_LEFT,
            valign=text.ALIGN_BASE,
            chargap=1.0,
            wordgap=1.0,
            linegap=1.0):
        thetext = self.unicode_decoder(thetext)
        if len(trafo) == 2:
            trafo = Translation(trafo)
        else:
            trafo = apply(Trafo, trafo)
        object = text.SimpleText(text=thetext,
                                 trafo=trafo,
                                 halign=halign,
                                 valign=valign,
                                 properties=self.get_prop_stack())

        object.properties.SetProperty(align=halign,
                                      valign=valign,
                                      chargap=chargap,
                                      wordgap=wordgap,
                                      linegap=linegap)
        self.append_object(object)

    def unicode_decoder(self, text):
        output = ''
        for word in text.split('\u')[1:]:
            num = int(word, 16)
            if num > 256:
                output += ('\u' + word).decode('raw_unicode_escape')
            else:
                output += chr(int(num)).decode('latin1')
        return output

    functions.append('im')

    def im(self, trafo, id):
        if len(trafo) == 2:
            trafo = Translation(trafo)
        else:
            trafo = apply(Trafo, trafo)
        self.append_object(image.Image(self.id_dict[id], trafo=trafo))

    functions.append('bm')

    def bm(self, id, filename=None):
        if filename is None:
            from streamfilter import Base64Decode, SubFileDecode
            decoder = Base64Decode(SubFileDecode(self.file, '-'))
            data = image.load_image(decoder)
        else:
            data = image.load_image(os.path.join(self.directory, filename))
        self.id_dict[id] = data

    functions.append('eps')

    def eps(self, trafo, filename):
        if len(trafo) == 2:
            trafo = Translation(trafo)
        else:
            trafo = apply(Trafo, trafo)
        if not os.path.isabs(filename):
            if self.directory:
                filename = os.path.join(self.directory, filename)
            else:
                filename = os.path.join(os.getcwd(), filename)
        self.append_object(eps.EpsImage(filename=filename, trafo=trafo))

    functions.append('B')

    def B(self, *args, **kw):
        self.begin_composite(blendgroup.BlendGroup, args, kw)

    functions.append('B_')

    def B_(self):
        self.end_composite()

    functions.append('Bi')

    def Bi(self, *args, **kw):
        self.begin_composite(blendgroup.BlendInterpolation, args, kw)
        self.end_composite()

    group = GenericLoader.begin_group
    endgroup = GenericLoader.end_group

    functions.append('M')

    def M(self, *args, **kw):
        from app.Graphics import maskgroup
        self.begin_composite(maskgroup.MaskGroup, args, kw)

    functions.append('M_')

    def M_(self):
        self.end_composite()

    functions.append('PT')

    def PT(self, *args, **kw):
        self.begin_composite(text.PathText, args, kw)

    functions.append('pt')

    def pt(self, thetext, *args):
        matrix = ()
        model = text.PATHTEXT_ROTATE
        start_pos = 0.0
        if args:
            if type(args[0]) == TupleType:
                matrix = args[0]
                args = args[1:]
            if args:
                model = args[0]
                if len(args) > 1:
                    start_pos = args[1]

        if matrix:
            trafo = apply(Trafo, matrix)
        else:
            trafo = None

        self.append_object(
            text.InternalPathText(thetext,
                                  trafo=trafo,
                                  model=model,
                                  start_pos=start_pos,
                                  properties=self.get_prop_stack()))

    functions.append('PT_')

    def PT_(self):
        self.end_composite()

    functions.append('PC')

    def PC(self, class_name, *args, **kw):
        kw['loading'] = 1
        info = filters.find_object_plugin(class_name)
        if info is not None:
            try:
                theclass = info.Constructor()
                self.begin_composite(theclass, args, kw)
                return
            except SketchError:
                pass
        # constructing the plugin object failed. Use an UnknownPlugin
        # object.
        self.add_message(_("Unknown Plugin: %s") % class_name)
        self.begin_composite(plugobj.UnknownPlugin, (class_name, ) + args, kw)

    functions.append('PC_')

    def PC_(self):
        self.end_composite()

    #
    #	The loader driver
    #

    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
                #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()
                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))
        except:
Example #18
0
class DXFLoader(GenericLoader):

	functions={	"POP_TRAFO": 'pop_trafo',
				"TABLE": 'load_TABLE',
				"BLOCK": 'load_BLOCK',
				"LINE": 'load_line',
				"LWPOLYLINE": 'load_lwpolyline',
				"POLYLINE": 'load_polyline',
				"SEQEND": 'load_seqend',
				"VERTEX": 'load_vertex',
				"CIRCLE": 'load_circle',
				"ARC": 'load_arc',
				"ELLIPSE": 'load_ellips',
				"POINT": 'load_point',
				"SOLID": 'load_solid',
				"INSERT": 'load_insert',
				"TEXT": 'load_text',
				#"MTEXT": 'load_text',
				"3DFACE": 'load_3dface',
				"SPLINE": 'load_spline',
				"VIEWPORT": 'load_bypass',
				
					}

	def __init__(self, file, filename, match):
		GenericLoader.__init__(self, file, filename, match)
		
		self.file = file
		
		self.DWGCODEPAGE = 'latin1'
		self.unit_to_pt = 2.83464566929
		self.dynamic_style_dict = {}
		self.style_dict = {}
		self.ltype_dict = {'CONTINUOUS': { '2': 'CONTINUOUS', # Linetype name
											'3': 'Solid line', # Descriptive text for linetype
											'49': [], # Dash, dot or space length 
													  #(one entry per element)
										  }
						  }
		self.layer_dict = {'0': { '2': '0', # Layer name
								  '6': 'CONTINUOUS', #Linetype name
								  '62': 0, # Color number
								  '370': None, #Line weight
								  }
							}
		self.block_dict = {}
		self.stack = []
		self.stack_trafo = []
		self.default_layer = '0'
		self.default_style = 'STANDARD'
		self.default_block = None
		self.default_line_width = 30
		self.EXTMIN = (1e+20, 1e+20)
		self.EXTMAX = (-1e+20, -1e+20)
		self.PEXTMIN = (1e+20, 1e+20)
		self.PEXTMAX = (-1e+20, -1e+20)
		
		self.general_param = {
				'8': self.default_layer, # Layer name
				'6': 'BYLAYER', # Linetype name 
				'62': 256, # Color number 
				'48': 1.0, # Linetype scale 
				#'60': 0, # Object visibility. If 1 Invisible
				}
		
		self.curstyle = Style()
		self.update_trafo()


	def update_trafo(self, scale = 1):
		EXT_hight = self.EXTMAX[0] - self.EXTMIN[0]
		EXT_width = self.EXTMAX[1] - self.EXTMIN[1]
		PEXT_hight = self.PEXTMAX[0] - self.PEXTMIN[0]
		PEXT_width = self.PEXTMAX[1] - self.PEXTMIN[1]
		
		if EXT_hight > 0:
			scale = 840 / max(EXT_hight, EXT_width)
			self.unit_to_pt = scale
			x = self.EXTMIN[0] * scale
			y = self.EXTMIN[1] * scale
		elif PEXT_hight > 0:
			scale = 840 / max(PEXT_hight, PEXT_width)
			self.unit_to_pt = scale
			x = self.PEXTMIN[0] * scale
			y = self.PEXTMIN[1] * scale
		else:
			x = 0
			y = 0
		self.trafo = Trafo(scale, 0, 0, scale, -x, -y)

	def push_trafo(self, trafo = None):
		# save trafo in stack_trafo
		if trafo is None:
			trafo = self.trafo
		self.stack_trafo.append(trafo)

	def pop_trafo(self):
		self.trafo = self.stack_trafo.pop()

	def get_pattern(self, color_index):
		# 0 = Color BYBLOCK
		if color_index == 0:
			block_name = self.default_block
			if block_name is None:
				layer_name = '0'
			else:
				layer_name = self.block_dict[block_name]['8']
			color_index = self.layer_dict[layer_name]['62']
		# 256 = Color BYLAYER
		if  color_index == 256 or color_index is None:
			layer_name = self.default_layer
			color_index = self.layer_dict[layer_name]['62']
		## FIXMY 257 = Color BYENTITY
		
		if color_index < 0:
			pattern = EmptyPattern
		else:
			pattern = SolidPattern(colors[color_index])
		
		return pattern


	def get_line_width(self, layer_name = None):
		if layer_name is None:
			layer_name = self.default_layer
		layer = self.layer_dict[layer_name]
		if '370' in layer:
			width = layer['370']
		if width == -3 or width is None:
			width = self.default_line_width
		
		width = width * 72.0 / 2.54 /1000 # th 100 mm to pt
		if width <= 0.0: # XXX
			width = 0.1
		return width 


	def get_line_type(self, linetype_name = None, scale = 1.0, width = 1.0, layer_name = None):
		#if linetype_name == 'BYBLOCK':
			#block_name = self.default_block
			#layer_name = self.block_dict[block_name]['8']

		if layer_name is None:
			layer_name = self.default_layer

		if linetype_name is None or linetype_name == 'BYLAYER' or linetype_name == 'BYBLOCK': 
			linetype_name = self.layer_dict[layer_name]['6']
		
		linetype = self.ltype_dict[upper(linetype_name)]['49']
		
		lscale = scale * self.unit_to_pt / width 
		dashes = map(lambda i : abs(linetype[i]) * lscale, xrange(len(linetype)))
		
		return tuple(dashes)


	def get_line_style(self, **kw):
		if kw['8'] in self.layer_dict:
			self.default_layer = layer_name = kw['8']
		else:
			layer_name = self.default_layer

		linetype_name = upper(kw['6'])
		scale = kw['48']
		color_index = kw['62']
		
		
		style = Style()
		style.line_width = self.get_line_width()
		style.line_join = const.JoinRound
		style.line_cap = const.CapRound
		style.line_dashes = self.get_line_type(linetype_name = linetype_name, scale = scale, width = style.line_width)
		style.line_pattern = self.get_pattern(color_index)

		return style

	################
	# HEADER Section
	#
	def load_HEADER(self):
		return_code = False
		header_dict = {}
		variable = None
		params = {}
		line1, line2 = self.read_record()
		while line1 or line2:
			if variable and (line1 == '9' or line1 == '0'):
				header_dict[variable] = params
			else:
				params[line1] = line2
			
			if line1 == '0' and line2 == 'ENDSEC':
				return_code = True
				break
			elif line1 == '9':
				params = {}
				variable = line2
			line1, line2 = self.read_record()
		return return_code, header_dict


	def process_header(self, header):
		
		if '$DWGCODEPAGE' in header:
			self.DWGCODEPAGE = 'cp'+ upper(header['$DWGCODEPAGE']['3']).replace('ANSI_', '').replace('DOS','')
		
		if '$INSUNITS' in header:
			INSUNITS = convert('70', header['$INSUNITS']['70'])
			if INSUNITS in unit:
				self.unit_to_pt = unit[INSUNITS]
				
		if '$EXTMIN' in header:
				param10 = convert('10', header['$EXTMIN']['10'])
				param20 = convert('20', header['$EXTMIN']['20'])
				self.EXTMIN = (param10, param20)
				
		if '$EXTMAX' in header:
				param10 = convert('10', header['$EXTMAX']['10'])
				param20 = convert('20', header['$EXTMAX']['20'])
				self.EXTMAX = (param10, param20)
				
		if '$PEXTMIN' in header:
				param10 = convert('10', header['$PEXTMIN']['10'])
				param20 = convert('20', header['$PEXTMIN']['20'])
				self.PEXTMIN = (param10, param20)

		if '$PEXTMAX' in header:
				param10 = convert('10', header['$PEXTMAX']['10'])
				param20 = convert('20', header['$PEXTMAX']['20'])
				self.PEXTMAX = (param10, param20)
		
		self.update_trafo()
		
		if '$CLAYER' in header:
				self.default_layer = convert('8', header['$CLAYER']['8'], self.DWGCODEPAGE)

	
	################
	# TABLES Section
	#

	def load_TABLE(self):
		param={	'2': '', # Table name
				'70': 0 # Maximum number of entries in table
				}
		param = self.read_param(param)
		table_name = param['2']
		table_number = param['70']
		print '****', table_name, table_number
		
		line1, line2 = self.read_record()
		while line1 or line2:
			if line1 == '0' and line2 == 'ENDTAB':
				break
			if table_name == 'LTYPE':
				self.load_LTYPE()
			elif table_name == 'LAYER':
				self.load_LAYER()
			elif table_name == 'STYLE':
				self.load_STYLE()
			line1, line2 = self.read_record()


	def load_LTYPE(self):
		param={ '2': '', # Linetype name
				'3': '', # Descriptive text for linetype
				#'73': 0, # The number of linetype elements
				#'40': 0, # Total pattern length
				'49': [], # Dash, dot or space length (one entry per element)
				}
		param = self.read_param(param, [0])
		
		name = upper(param['2'])
		if name:
			self.ltype_dict[name] = param
			dashes = []
			for i in xrange(len(param['49'])):
				dashes.append(abs(param['49'][i]) * self.unit_to_pt)
			
			name3 = param['3']
			#print name3, dashes
			if name3 and dashes:
				style = Style()
				style.line_dashes = tuple(dashes)
				style = style.AsDynamicStyle()
				style.SetName(name + name3)
				self.dynamic_style_dict[name] = style


	def load_LAYER(self):
		param={ '2': None, # Layer name
				'6': None, #Linetype name
				'62': 0, # Color number
				'370': None, #Line weight
				}
		param = self.read_param(param, [0])

		layer_name = param['2']
		if layer_name:
			self.layer_dict[layer_name]=param
			self.layer(name = layer_name)


	def load_STYLE(self):
		param={ '2': None, # Style name
				'70': 0, # Flag
				'40': 0.0, # Fixed text height; 0 if not fixed
				'41': 0.0, # Width factor
				'42': 0.0, # Last height used
				'50': 0.0, # Oblique angle
				'71': 0, # Text generation flags
				'3': None, # Primary font file name
				'4': None, # Bigfont file name
				'1000': None,
				}
		param = self.read_param(param, [0])

		style_name = upper(param['2'])
		self.style_dict[style_name] = param


	################
	# BLOCKS Section
	#
	
	def load_BLOCK(self):
		param={	'2': '', # Block name
				'10': 0.0, # X Base point
				'20': 0.0, # Y Base point
				#'30': 0.0, # Z Base point 
				'8': self.default_layer, # Layer name
				'data': [], # block data
				}
		param = self.read_param(param)
		block_name = param['2']
		print '****', block_name
		
		line1, line2 = self.read_record()
		while line1 or line2:
			if line1 == '0' and line2 == 'ENDBLK':
				param = self.read_param(param)
				break
			param['data'].append(line1)
			param['data'].append(line2)
			
			line1, line2 = self.read_record()
		
		param['data'].reverse()
		self.block_dict[block_name] = param
#		print self.block_dict[block_name]


	################
	#  ENTITIES Section
	#
	
	def load_line(self):
		param={	'10': None, # X coordinat
				'20': None, # y coordinat
				#'30': None, # Z coordinat
				
				'11': None, # X coordinat endpoint
				'21': None, # y coordinat endpoint
				#'31': None, # z coordinat endpoint
				}
		param.update(self.general_param)
		param = self.read_param(param)
		self.path = CreatePath()
		self.path.AppendLine(self.trafo(param['10'], param['20']))
		self.path.AppendLine(self.trafo(param['11'], param['21']))
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		self.bezier(self.path,)


	def load_lwpolyline(self):
		param={ '90': 0, # Number of vertices
				'70': 0, # bit codes for Polyline entity
				'40': None, # Starting width
				'43': 0,
				'370': None, #Line weight
				}
		param.update(self.general_param)
		param = self.read_param(param,[10,20,42])
		
		if param['40'] is not None:
			line_width = param['40'] * self.unit_to_pt
		else:
			line_width = param['43'] * self.unit_to_pt
			
		if param['370'] is not None:
			line_width = param['370'] * self.unit_to_pt * 72.0 / 2.54 /1000
		
		self.curstyle = self.get_line_style(**param)
		
		# if Group 70 Flag bit value set 1 This is a closed Polyline
		path_flag = param['70']
		vertex_path = []
		for i in xrange(param['90']):
			vertex={ '10': None, # X coordinat
					'20': None, # Y coordinat
					'42': 0.0  # Bulge 
					}
			# 10
			line1, line2 = self.read_record()
			vertex[line1] = convert(line1, line2, self.DWGCODEPAGE)
			# 20
			line1, line2 = self.read_record()
			vertex[line1] = convert(line1, line2, self.DWGCODEPAGE)
			# 42
			line1, line2 = self.read_record()
			if line1 == '42':
				vertex[line1] = convert(line1, line2, self.DWGCODEPAGE)
			else:
				self.push_record(line1, line2)
			
			vertex_path.append((vertex['10'], vertex['20'], vertex['42']))
			
		self.load_seqend(vertex_path, path_flag)


	def load_polyline(self):
		param={	'70': 0, # bit codes for Polyline entity
				'40': 0.01, #XXX FIXMY
				}
		param.update(self.general_param)
		param = self.read_param(param)
		self.vertex_path = []
		self.curstyle.line_width=param['40'] * 72 # XXX self.unit_to_pt
		self.curstyle.line_pattern = self.get_pattern(param['62'])
		
		# if Group 70 Flag bit value set 1 This is a closed Polyline
		self.path_flag = param['70']


	def load_vertex(self):
		param={#'62': 7, # color
				#'6': 'CONTINUOUS', # style
				'10': None, # X coordinat
				'20': None, # Y coordinat
				'42': 0.0  # Bulge 
				}
		param = self.read_param(param)
		self.vertex_path.append((param['10'], param['20'], param['42']))


	def load_seqend(self, line = None, path_flag = None):
		if line is None:
			line = self.vertex_path
		
		if  path_flag is None:
			path_flag = self.path_flag
		
		if path_flag > 1:
			print 'FIXMY. Curves and smooth surface type', path_flag
		
		close_path = path_flag & 1 == 1
		
		path = CreatePath()
		if len(line):
			for i in line:
				x, y, bulge = i
				#print x, y, bulge
				path.AppendLine(self.trafo(x, y))
		
		if close_path:
			if path.Node(0) != path.Node(-1):
				path.AppendLine(path.Node(0))
				path.ClosePath()
		self.prop_stack.AddStyle(self.curstyle.Duplicate())
		self.bezier(path,)


	def load_circle(self):
		param={	'10': None, # X coordinat center
				'20': None, # Y coordinat center
				#'30': None, # Z coordinat center
				'40': 0.0  # radius
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		x = param['10']
		y = param['20']
		r = param['40']
		
		t = self.trafo(Trafo(r,0,0,r,x,y))
		
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		
		apply(self.ellipse, t.coeff())


	def load_arc(self):
		param={	'10': None, # X coordinat center
				'20': None, # Y coordinat center
				#'30': None, # Z coordinat center
				'40': 0.0, # radius
				'50': 0.0, # Start angle
				'51': 0.0 # End angle
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		cx = param['10']
		cy = param['20']
		rx = ry = param['40']
		start_angle = param['50'] * degrees
		end_angle = param['51'] * degrees
		
		trafo = self.trafo(Trafo(rx, 0, 0, ry, cx, cy))
		rx, w1, w2, ry, cx, cy = trafo.coeff()
		
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		
		apply(self.ellipse, (rx, w1, w2, ry, cx, cy, start_angle, end_angle, ArcArc))
		

	def load_ellips(self):
		param={	'10': 0.0, # X coordinat center
				'20': 0.0, # Y coordinat center
				#'30': 0.0, # Z coordinat center
				'11': 0.0, # Endpoint of major axis, relative to the center
				'21': 0.0,
				#'31': 0.0,
				'40': 0.0, # Ratio of minor axis to major axis
				'41': 0.0, # Start parameter (this value is 0.0 for a full ellipse)
				'42': 0.0, # End parameter (this value is 2pi for a full ellipse)
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		cx = param['10']
		cy = param['20']
		
		rx = sqrt(param['21']**2 + param['11']**2)
		ry = rx * param['40']
		
		start_angle = param['41']
		end_angle = param['42']
		
		angle=atan2(param['21'], param['11'])
		
		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)
		rx, w1, w2, ry, cx, cy = trafo.coeff()
		
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		
		apply(self.ellipse, (rx, w1, w2, ry, cx, cy, start_angle, end_angle, ArcArc))


	def load_point(self):
		param={	'10': None, # X coordinat center
				'20': None, # Y coordinat center
				#'30': None, # Z coordinat center
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		x = param['10']
		y = param['20']
		r = 0.3
		
		t = self.trafo(Trafo(r,0,0,r,x,y))
		
		style = self.curstyle.Duplicate()
		style.line_pattern = EmptyPattern
		style.fill_pattern = self.get_pattern(param['62'])
		
		self.prop_stack.AddStyle(style.Duplicate())
		apply(self.ellipse, t.coeff())


	def load_solid(self):
		param={	'10': None, 
				'20': None, 
				#'30': None, 
				'11': None, 
				'21': None, 
				#'31': None,
				'12': None, 
				'22': None, 
				#'32': None,
				'13': None, 
				'23': None,
				#'33': None, 
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		style = self.curstyle.Duplicate()
		style.line_pattern = EmptyPattern
		style.fill_pattern = self.get_pattern(param['62'])
		
		self.path = CreatePath()
		self.path.AppendLine(self.trafo(param['10'], param['20']))
		self.path.AppendLine(self.trafo(param['11'], param['21']))
		self.path.AppendLine(self.trafo(param['12'], param['22']))
		self.path.AppendLine(self.trafo(param['13'], param['23']))
		
		self.path.ClosePath()
		
		self.prop_stack.AddStyle(style.Duplicate())
		self.bezier(self.path,)


	def load_insert(self):
		param={ '2': None, # Block name
				'10': 0.0, # X coordinat
				'20': 0.0, # Y coordinat
				#'30': 0.0, # Z coordinat
				'41': 1.0, # X scale factor 
				'42': 1.0, # Y scale factor 
				#'43': 1.0, # Z scale factor 
				'50': 0.0, # Rotation angle
				'66': 0, # Attributes-follow flag
				}
		param = self.read_param(param)
		
		block_name = self.default_block = param['2']
		
		if block_name:
			self.stack +=  ['POP_TRAFO', '0'] + self.block_dict[block_name]['data'] 
			self.push_trafo()
			
			x = param['10']
			y = param['20']
			block_x = self.block_dict[block_name]['10']
			block_y = self.block_dict[block_name]['20']
			
			scale_x = param['41'] * self.trafo.m11
			scale_y = param['42'] * self.trafo.m22
			angle = param['50'] * degrees
			
			translate = self.trafo(x, y)
			trafo = Trafo(1, 0, 0, 1, -block_x, -block_y)
			trafo = Scale(scale_x,scale_y)(trafo)
			trafo = Rotation(angle)(trafo)
			trafo = Translation(translate)(trafo)
			self.trafo = trafo
			
		if param['66'] != 0:
			line1, line2 = self.read_record()
			while line1 or line2:
				if line1 == '0' and line2 == 'SEQEND':
					break
				else:
					if line1 == '0':
						self.run(line2)
				line1, line2 = self.read_record()


	def load_text(self):
		param={ '10': 0.0, 
				'20': 0.0, 
				'40': None, # Text height
				'1': '', # Default value
				'50': 0, # Text rotation
				'41': 1, # Relative X scale factor—width
#				'8': self.default_layer, # Layer name
				'7': self.default_style, # Style name
				'72': 0, #Horizontal text justification type
				}
		param.update(self.general_param)
		param = self.read_param(param)
		

		x = param['10']
		y = param['20']
		scale_x = param['41']
		scale_y = 1
		angle = param['50'] * pi / 180
		font_size = param['40'] * self.trafo.m11
		

		halign = [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, \
					ALIGN_LEFT, ALIGN_LEFT, ALIGN_LEFT][param['72']]
		text = unicode_decoder(param['1'], self.DWGCODEPAGE)
		#style = self.style_dict[param['7']]
#		print style
		
		style_text = self.curstyle.Duplicate()
		style_text.line_pattern = EmptyPattern
		style_text.fill_pattern = self.get_pattern(param['62'])
		style_name = upper(param['7'])
		style = self.style_dict[style_name]
		font_name = style['1000']
		if font_name == 'Arial': # XXX
			font_name = 'ArialMT'
		style_text.font = GetFont(font_name)
#		print style_text.font
		style_text.font_size = font_size
		
		trafo_text = Translation(self.trafo(x, y))(Rotation(angle))(Scale(scale_x, scale_y))
		self.prop_stack.AddStyle(style_text.Duplicate())
		self.simple_text(strip(text), trafo_text, halign = halign)
		
	def load_3dface(self):
		param={	'10': None, 
				'20': None, 
				#'30': None, 
				'11': None, 
				'21': None, 
				#'31': None,
				'12': None, 
				'22': None, 
				#'32': None,
				'13': None, 
				'23': None,
				#'33': None, 
				'70': 0, # Invisible edge flags
				
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		self.path = CreatePath()
		if param['70'] != 0:
			print 'FIXMY. 3dface Invisible edge flags', param['70']
		self.path.AppendLine(self.trafo(param['10'], param['20']))
		self.path.AppendLine(self.trafo(param['11'], param['21']))
		self.path.AppendLine(self.trafo(param['12'], param['22']))
		self.path.AppendLine(self.trafo(param['13'], param['23']))
		
		self.path.ClosePath()
		
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		
		self.bezier(self.path,)

	def load_spline(self):
		param={	'70': 0, # Spline flag 
				'71': 0, # Degree of the spline curve
				'72': 0, # Number of knots
				'73': 0, # Number of control points
				'74': 0, # Number of fit points
				'40': [], # Knot value 
				'10': [], # Control points X
				'20': [], # Control points Y
				#'30': [], # Control points Z
				}
		param.update(self.general_param)
		param = self.read_param(param)
		
		closed = param['70']  & 1
		
		path = CreatePath()
		f13 = 1.0 / 3.0
		f23 = 2.0 / 3.0
		curve = path.AppendBezier
		straight = path.AppendLine

		pts = map(lambda x, y: self.trafo(x, y), param['10'],param['20'])
		print 'SPLINE', param['70'], len(pts)

		#for i in range(0, len(pts)-1):
			#self.ellipse(.2, 0, 0, .2, pts[i][0],pts[i][1])

		
		if param['70'] <= 1:
			
			straight(pts[0])
			for i in range(1, len(pts) / 4):
				node = pts[i * 4]
				c1 = pts[i * 4 - 3]
				c2 = pts[i * 4 - 2]
				print c1, c2, node

				curve(c1, c2, node)
				#straight(node)
			if closed:
				curve(pts[-3], pts[-2], pts[0])
			else:
				curve(pts[-4], pts[-4], pts[-1])

		if param['70'] & 4 == 4:
			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)

		if param['70'] & 8 == 8:
			node = pts[0]
			c1 = pts[1]
			c2 = pts[2]
			# first node
			straight(node)
			
			if len(pts) > 4:
				c2 = (pts[2] + pts[1]) / 2
				c3 = pts[3] * f13 + pts[2] * f23
				node = (c3 + c2) / 2
				curve(c1, c2, node)
				c1 = c3
				for i in range(3, len(pts) - 3):
					c2 = pts[i - 1] * f13 + pts[i] * f23
					c3 = pts[i] * f23 + pts[i + 1] * f13
					node = (c3 + c2) / 2
					curve(c1, c2, node)
					c1 = c3

				c2 = pts[-4] * f13 + pts[-3] * f23
				c3 = (pts[-3]  + pts[-2]) / 2 
				node = (c3 + c2) / 2
				curve(c1, c2, node)
				c1 = c3
			
			# last node
			curve(c1, pts[-2], pts[-1])
			
		style = self.get_line_style(**param)
		self.prop_stack.AddStyle(style.Duplicate())
		self.bezier(path,)
			

	def load_bypass(self):
		pass

###########################################################################

	def get_compiled(self):
		funclist={}
		for char, name in self.functions.items():
			method = getattr(self, name)
			argc = method.im_func.func_code.co_argcount - 1
			funclist[char] = (method, argc)
		return funclist

	def push_record(self, line1, line2):
		# save data in stack
		self.stack.append(line2)
		self.stack.append(line1)
		

	def read_record(self):
		# if the stack is empty read two lines from a file
		if self.stack:
			line1 = self.stack.pop()
			line2 = self.stack.pop()
		else:
			line1 = self.file.readline().strip()
			line2 = self.file.readline().strip()
		return line1, line2

	def read_param(self, param, stop=None):
		# read data and fill in the dictionary
		if stop is None:
			stop = [0, 9]
		line1, line2 = self.read_record()
		while line1 or line2:
			if int(line1) in stop:
				self.push_record(line1, line2)
				return param
			else:
				if line1 in param:
					value = convert(line1, line2, self.DWGCODEPAGE)
					if type(param[line1]) == list:
						param[line1].append(value)
					else:
						param[line1] = value
			line1,line2 = self.read_record()
		return False

	def find_record(self, code1, code2):
		# read data until to not overlap line1 == code1 and line2 == code2
		# return True
		# else return False
		
		line1, line2 = self.read_record()
		while line1 or line2:
			if line1 == code1 and line2 == code2:
				return True
			line1, line2 = self.read_record()
		return False


	def load_section(self):
		return_code = False
		file = self.file
		parsed = self.parsed
		parsed_interval = self.parsed_interval
		line1, line2 = self.read_record()
		while line1 or line2:
			interval_count = file.tell() / parsed_interval
			if interval_count > parsed:
				parsed += 10 # 10% progress
				app.updateInfo(inf2 = '%u' % parsed + _('% of file is parsed...'), inf3 = parsed)
				
			if line1 == '0' and line2 == 'ENDSEC':
				return_code = True
				break
			elif line1 == '0':
				self.run(line2)
			line1, line2 = self.read_record()
		self.parsed = parsed
		return return_code
	

	def load_sections(self):
		return_code = False
		param={	'2': '', # name section
				}
		param = self.read_param(param)
		name=param['2']
		print '**',name
		if name == 'HEADER':
			return_code, header_dict = self.load_HEADER()
			self.process_header(header_dict)
		elif name == 'CLASSES':
			return_code = self.find_record('0','ENDSEC')
		elif name == 'OBJECTS':
			return_code = self.find_record('0','ENDSEC')
		elif name == 'THUMBNAILIMAGE':
			return_code = self.find_record('0','ENDSEC')
		else:
			return_code = self.load_section()
		
		return return_code


	def interpret(self):
		file = self.file
		if type(file) == StringType:
			file = open(file, 'r')
		file.seek(0)
		readline = file.readline
		fileinfo = os.stat(self.filename)
		totalsize = fileinfo[6]
		self.parsed = 0
		self.parsed_interval = totalsize / 99 + 1
		
		line1, line2 = self.read_record()
		while line1 or line2:
			if line1 == '0':
				if line2 == 'EOF':
					break
				elif not self.load_sections():
					warn_tb(INTERNAL, _('DXFLoader: error. Non find end of sections'))
			line1, line2 = self.read_record()


	def run(self,keyword, *args):
		if keyword is None:
			return
		return_code = False
		unknown_operator = (None, None)
		funclist = self.funclist
		if keyword is not None:
			method, argc = funclist.get(keyword, unknown_operator)
			if method is not None:
				try:
					##print '******', keyword
					if len(args):
						i = 0
						while i<len(args):
							return_code = apply(method, args[i:argc+i])
							i+=argc
					else:
						return_code = method()
						
				except:
					warn_tb(INTERNAL, 'DXFLoader: error')
			else:
				self.add_message(_('Not interpreted %s') % keyword)
		return return_code



	def Load(self):
		import time
		start_time = time.clock()
		#print '		************ "DXF_objects" **************'
		self.funclist = self.get_compiled()
		self.document()
		self.layer(name = _("DXF_objects"))
		self.interpret()
		self.end_all()
		for style in self.dynamic_style_dict.values():
			self.object.load_AddStyle(style)
		self.object.load_Completed()
		print 'times',time.clock() - start_time
		return self.object