예제 #1
0
 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 arrow_trafos(path, properties):
	dir1, dir2 = arrow_vectors(path, properties.line_arrow1,
								properties.line_arrow2)
	width = properties.line_width
	if width < 1.0:
		width = 1.0
	scale = Scale(width)
	t1 = t2 = None
	if dir1 is not None:
		t1 = Translation(path.Node(0))(Rotation(dir1.polar()[1]))(scale)
	if dir2 is not None:
		t2 = Translation(path.Node(-1))(Rotation(dir2.polar()[1]))(scale)
	return t1, t2
예제 #3
0
	def im(self, trafo, id):
		if len(trafo) == 2:
			trafo = Translation(trafo)
		else:
			trafo = apply(Trafo, trafo)
		if self.id_dict[id] is not None:
			self.append_object(image.Image(self.id_dict[id], trafo=trafo))
예제 #4
0
 def write_gradient(self, gradient, style):
     pattern, rect = gradient
     key = self.gradient_id(pattern)
     write = self.file.write
     #write('Bb\n')
     if pattern.is_AxialGradient:
         vx, vy = pattern.Direction()
         angle = atan2(vy, vx) - pi / 2
         center = rect.center()
         rot = Rotation(angle, center)
         left, bottom, right, top = rot(rect)
         height = (top - bottom) * (1.0 - pattern.Border())
         trafo = rot(Translation(center))
         start = trafo(0, height / 2)
         write("1 %s %g %g %g %g 1 0 0 1 0 0 Bg\n" %
               (key[0], start.x, start.y, atan2(-vy, -vx) * 180.0 / pi,
                height))
     elif pattern.is_RadialGradient:
         cx, cy = pattern.Center()
         cx = cx * rect.right + (1 - cx) * rect.left
         cy = cy * rect.top + (1 - cy) * rect.bottom
         radius = max(hypot(rect.left - cx, rect.top - cy),
                      hypot(rect.right - cx, rect.top - cy),
                      hypot(rect.right - cx, rect.bottom - cy),
                      hypot(rect.left - cx, rect.bottom - cy))
         radius = radius * (1.0 - pattern.Border())
         write("0 0 0 0 Bh\n")
         write("1 %s %g %g 0 %g 1 0 0 1 0 0 Bg\n" %
               (key[0], cx, cy, radius))
	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)
예제 #6
0
    def txt(self,
            readline,
            thetext,
            trafo,
            halign=text.ALIGN_LEFT,
            valign=text.ALIGN_BASE,
            chargap=1.0,
            wordgap=1.0,
            linegap=1.0):
        if type(thetext) == IntType:
            txt = ''
            for item in range(thetext):
                txt += readline()
            txt = txt.decode('utf-8')
        else:
            txt = self.unicode_decoder(thetext)

        if len(trafo) == 2:
            trafo = Translation(trafo)
        else:
            trafo = apply(Trafo, trafo)
        obj = text.SimpleText(text=txt,
                              trafo=trafo,
                              halign=halign,
                              valign=valign,
                              properties=self.get_prop_stack())

        obj.properties.SetProperty(align=halign,
                                   valign=valign,
                                   chargap=chargap,
                                   wordgap=wordgap,
                                   linegap=linegap)
        self.append_object(obj)
예제 #7
0
	def use(self, attrs):
		if self.in_use:
			return
		self.in_use = 1
		#print 'use', attrs.map
		if attrs.has_key('xlink:href'):
			name = attrs['xlink:href']
		else:
			name = attrs.get('href', '<none>')
		if name:
			data = self.elements_id[name]
			if data is not None:
				self.push_state()
				# FIXME: to add attributes width and height
				x, y = self.user_point(attrs.get('x', '0'), attrs.get('y', '0'))
				self.parse_attrs(attrs)
				self.trafo = self.trafo(Translation(x,y))
				cur_depth = self.depth
				while True:
					self.parseElements(self.elements[data])
					data += 1
					if cur_depth >= self.depth:
						break
				self.pop_state()
				
			#FIXME: '!!! PASS IN USE ELEMENT', name
		
		self.in_use = 0
    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)
예제 #9
0
 def GetObjectHandle(self, multiple):
     trafo = Translation(self._offset)
     handle = self._original.GetObjectHandle(multiple)
     if type(handle) == PointType:
         return trafo(handle)
     else:
         return map(trafo, handle)
예제 #10
0
	def txt(self, thetext, trafo, halign=text.ALIGN_LEFT,
			valign=text.ALIGN_BASE):
		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())
		self.append_object(object)
 def execute_axial_gradient(self, device, rect):
     vx, vy = self.direction
     angle = atan2(vy, vx) - pi / 2
     center = rect.center()
     rot = Rotation(angle, center)
     left, bottom, right, top = rot(rect)
     height = (top - bottom) * (1.0 - self.border)
     trafo = rot(Translation(center))
     device.AxialGradient(self.gradient, trafo(0, height / 2),
                          trafo(0, -height / 2))
예제 #12
0
	def RemoveTransformation(self):
		if self.trafo.matrix() != IdentityMatrix:
			trafo = self.trafo
			try:
				undostyle = Primitive.Transform(self, trafo.inverse())
			except SingularMatrix:
				undostyle = None
			undotrafo = self.set_transformation(Translation(trafo.offset()))
			return CreateMultiUndo(undostyle, undotrafo)
		return NullUndo
 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))
예제 #14
0
    def svgView(self, attrs):
        self._print("basetrafo", self.basetrafo)
        viewbox = attrs.get("viewBox", "")
        if viewbox:
            # In early viewPort = viewBox
            self._print('viewBox', viewbox)
            viewbox = viewbox.replace(',', ' ')
            self.viewPort = map(float, split(viewbox))

        x, y = self.user_point(attrs.get('x', '0'), attrs.get('y', '0'))
        width, height = self.user_point(attrs.get('width', '100%'), \
                   attrs.get('height', '100%'))
        self._print('svgView', x, y, width, height)

        if self.loader.page_layout is None:
            self.loader.page_layout = pagelayout.PageLayout(width=width * 0.8,
                                                            height=height *
                                                            0.8)

        if self.trafo is None:
            # adjustment of the coordinate system and taking into account
            # the difference between 90dpi in svg against 72dpi in sk1
            self.trafo = self.basetrafo = Trafo(0.8, 0, 0, -0.8, 0,
                                                height * 0.8)
            # initial values of x and y are ignored
            x = y = 0

        # adjust to the values x, y in self.trafo
        self.trafo = self.trafo(Translation(x, y))
        # evaluate viewBox
        # FIXME: Handle preserveAspectRatio as well
        if viewbox:
            t = Scale(width / self.viewPort[2], height / self.viewPort[3])
            t = t(Translation(-self.viewPort[0], -self.viewPort[1]))
            self.trafo = self.trafo(t)
        # set viewPort taking into account the transformation
        self.viewPort = (x, y, width/(self.trafo.m11/self.basetrafo.m11),\
            height/(self.trafo.m22/self.basetrafo.m22))

        self._print("trafo", self.trafo)
        self._print("viewPort", self.viewPort)
 def RemoveTransformation(self):
     if self.trafo.matrix() != IdentityMatrix:
         a = self.properties
         trafo = self.trafo
         llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size, a)
         try:
             undostyle = Primitive.Transform(self, trafo.inverse())
         except SingularMatrix:
             undostyle = None
         undotrafo = self.set_transformation(Translation(trafo.offset()))
         return CreateMultiUndo(undostyle, undotrafo)
     return NullUndo
예제 #16
0
    def SaveDocument(self, doc):

        # A dillema
        # Should the design fill the CGM-file or
        # Should it be placed approximately in
        # the same place as it is put on the page.
        if 0:
            left, bottom, right, top = doc.BoundingRect()
            width = right - left
            hight = top - bottom
        else:
            left, bottom = 0, 0
            width = doc.page_layout.width
            hight = doc.page_layout.height
            right, top = width, hight
        #sc = 65534 / max(width , hight)
        sc = 1000
        #self.trafo = Translation(-32767,-32767)(Scale(sc)(Translation(-left , -bottom)))
        self.trafo = Scale(sc)(Translation(-left, -bottom))
        self.Scale = sc
        self.extend = map(rndtoint , \
             tuple(self.trafo(left,bottom)) + tuple(self.trafo(right,top)))

        # Begin Metafile
        filename = os.path.basename(self.pathname)
        title = filename + " generated by sK1"
        self.putstr(0x0020, title)

        # Metafile Version
        self.pack("!H", 0x1022)
        self.pack("!H", 0x0001)

        # Metafile Description
        self.putstr(0x1040, filename + " created by sk1")

        # Metafile Element List
        self.pack("!HHHH", 0x1166, 0x0001, 0xffff, 0x0001)

        # Default Replacements
        self.pack("!H", 0x1184)
        # VDC Integer precision 32 bits
        self.pack("!Hh", 0x3022, 32)

        #Font List
        #

        self.SaveLayers(doc.Layers())

        # End Meta File
        self.pack("!H", 0x0040)
예제 #17
0
	def mktrafo(self, extend):
		if reff.scale.mode == 0:
			left, bottom = extend[0]
			right, top = extend[1]
			width = right - left
			height = top - bottom
			sc = 841 / (1.0 * max(abs(width) , abs(height)))
		else:
			left = 0
			bottom = 0
			width = 1
			height = 1
			sc = reff.scale.metric * 72 / 25.4
		self.Scale = sc
		self.trafo = Scale(sign(width) * sc , sign(height) * sc)(Translation(-left , -bottom))
def create_text(context):
    # Create the text 'xyzzy' at 100,100. The first parameter to the
    # constructor is an affine transformation.
    text = SimpleText(Translation(100, 100), "xyzzy")

    # Set the font to 36pt Times-Bold and fill with solid green.
    # The text object is modified by this method, but the text object is
    # not yet part of the document, so we don't have to deal with undo
    # here.
    text.SetProperties(fill_pattern=SolidPattern(StandardColors.green),
                       font=GetFont('Times-Bold'),
                       font_size=36)
    # Finally, insert the text object at the top of the current layer
    # and select it. Like all public document methods that modify the
    # document, the Insert method takes care of undo information itself.
    context.document.Insert(text)
예제 #19
0
	def TEXT(self, size):
		P = self.Pnt()
		F = self.Enum()
		S = self.getstr()
		T = Translation(self.trafo(P))
		Py = Point(reff.text.orientation[0]).normalized()
		Px = Point(reff.text.orientation[1]).normalized()
		B = transform_base(Point(0.0, 0.0) , reff.text.expansion * Px , Py)
		self.style = basestyle.Duplicate()
		self.style.font = GetFont(fntlst[self.fntmap[reff.text.fontindex]])
		self.style.font_size = reff.text.height * self.Scale
		self.style.fill_pattern = SolidPattern(apply(CreateRGBColor , reff.text.color))
		O = text.SimpleText(text=S, trafo=T(B),
							halign=text.ALIGN_LEFT, valign=text.ALIGN_BASE,
							properties=self.get_prop_stack())
		self.append_object(O)
    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 axial_gradient(self, properties, rect):
     pattern = properties.fill_pattern
     vx, vy = pattern.Direction()
     angle = atan2(vy, vx) - pi / 2
     center = rect.center()
     rot = Rotation(angle, center)
     left, bottom, right, top = rot(rect)
     trafo = rot(Translation(center))
     image = PIL.Image.new('RGB', (1, 200))
     border = int(round(100 * pattern.Border()))
     _sketch.fill_axial_gradient(image.im,
                                 pattern.Gradient().Colors(), 0, border, 0,
                                 200 - border)
     self.pdf.saveState()
     apply(self.pdf.transform, trafo.coeff())
     self.pdf.drawInlineImage(image, (left - right) / 2, (bottom - top) / 2,
                              right - left, top - bottom)
     self.pdf.restoreState()
	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)
예제 #24
0
 def parse_transform(self, trafo_string):
     trafo = self.trafo
     trafo_string = as_latin1(trafo_string)
     while trafo_string:
         match = rx_trafo.match(trafo_string)
         if match:
             function = match.group(1)
             args = argsf = string.translate(match.group(2), commatospace)
             args = map(str, split(args))
             trafo_string = trafo_string[match.end(0):]
             if function == 'matrix':
                 args = map(float, split(argsf))
                 trafo = trafo(apply(Trafo, tuple(args)))
             elif function == 'scale':
                 if len(args) == 1:
                     sx = sy = args[0]
                 else:
                     sx, sy = args
                 sx, sy = self.user_point(sx, sy)
                 trafo = trafo(Scale(sx, sy))
             elif function == 'translate':
                 if len(args) == 1:
                     dx, dy = args[0], '0'
                 else:
                     dx, dy = args
                 dx, dy = self.user_point(dx, dy)
                 trafo = trafo(Translation(dx, dy))
             elif function == 'rotate':
                 if len(args) == 1:
                     trafo = trafo(Rotation(float(args[0]) * degrees))
                 else:
                     angle, cx, cy = args
                     cx, cy = self.user_point(cx, cy)
                     trafo = trafo(
                         Rotation(float(angle) * degrees, Point(cx, cy)))
             elif function == 'skewX':
                 trafo = trafo(
                     Trafo(1, 0, tan(float(args[0]) * degrees), 1, 0, 0))
             elif function == 'skewY':
                 trafo = trafo(
                     Trafo(1, tan(float(args[0]) * degrees), 0, 1, 0, 0))
         else:
             trafo_string = ''
     self.trafo = trafo
예제 #25
0
def pathtext(path, start_pos, text, font, size, type, properties):
	metric = font.metric
	lengths = path.arc_lengths(start_pos)
	scale = Scale(size); factor = size / 2000.0
	pos = font.TypesetText(text, properties)
	pos = map(scale, pos)
	trafos = []
	for idx in range(len(text)):
		char = text[idx]
		width2 = metric.char_width(ord(char)) * factor
		x = pos[idx].x + width2
		trafo = coord_sys_at(lengths, x, type)
		if trafo is not None:
			trafos.append(trafo(Translation(-width2, 0)))
		else:
			# we've reached the end of the path. Ignore all following
			# characters
			break
	return trafos
예제 #26
0
    def start_linearGradient(self, attrs):
        if attrs.has_key('xlink:href') or attrs.has_key('x2'):
            x2 = atof(attrs['x2'])
            x1 = atof(attrs['x1'])
            y2 = atof(attrs['y2'])
            y1 = atof(attrs['y1'])
            point1 = Point(x1, y1)
            point2 = Point(x2, y2)

            trafo = None
            if attrs.has_key('xlink:href'):
                id = attrs['xlink:href'][1:]
            else:
                id = None

            if attrs.has_key('gradientTransform'):
                #				trafo=parse_transform(attrs['gradientTransform'])
                trafo_str = attrs['gradientTransform']
                if trafo_str[:9] == 'translate':
                    trafo = attrs['gradientTransform']
                    parts = filter(None,
                                   map(strip, split(trafo_str[10:-1], ',')))
                    trafo = Translation(atof(parts[1]), atof(parts[0]))
                if trafo_str[:6] == 'matrix':
                    parts = filter(None, map(strip,
                                             split(trafo_str[7:-1], ',')))
                    trafo = Trafo(atof(parts[0]), atof(parts[1]),
                                  atof(parts[2]), atof(parts[3]),
                                  atof(parts[4]), atof(parts[5]))

            if not trafo is None:
                point1 = trafo(point1)
                point2 = trafo(point2)

            grad = ['LinearGradient', id, (point1, point2)]
            self.grad_patters[attrs['id']] = grad

            if not attrs.has_key('xlink:href'):
                self.current_gradient = grad
        else:
            self.current_gradient = attrs['id']
예제 #27
0
    def start_radialGradient(self, attrs):
        if attrs.has_key('xlink:href') or attrs.has_key('cx'):
            fx = atof(attrs['fx'])
            cx = atof(attrs['cx'])
            fy = atof(attrs['fy'])
            cy = atof(attrs['cy'])
            point1 = Point(cx, cy)
            point2 = Point(fx, fy)
            r = atof(attrs['r'])

            if attrs.has_key('xlink:href'):
                id = attrs['xlink:href'][1:]
            else:
                id = None

            trafo = None
            if attrs.has_key('gradientTransform'):
                #				trafo=parse_transform(attrs['gradientTransform'])
                trafo_str = attrs['gradientTransform']
                if trafo_str[:9] == 'translate':
                    parts = filter(None,
                                   map(strip, split(trafo_str[10:-1], ',')))
                    trafo = Translation(atof(parts[1]), atof(parts[0]))
                if trafo_str[:6] == 'matrix':
                    parts = filter(None, map(strip,
                                             split(trafo_str[7:-1], ',')))
                    trafo = Trafo(atof(parts[0]), atof(parts[1]),
                                  atof(parts[2]), atof(parts[3]),
                                  atof(parts[4]), atof(parts[5]))

            if not trafo is None:
                point1 = trafo(point1)
                point2 = trafo(point2)

            grad = ['RadialGradient', id, (point1, point2), r]
            self.grad_patters[attrs['id']] = grad

            if not attrs.has_key('xlink:href'):
                self.current_gradient = grad
        else:
            self.current_gradient = attrs['id']
 def update_atrafo(self):
     #		a = self.properties
     #		llx, lly, urx, ury = a.font.TextCoordBox(self.text, a.font_size, a)
     #		hj = self.halign
     #		if hj == ALIGN_RIGHT:
     #			xoff = llx - urx
     #		elif hj == ALIGN_CENTER:
     #			xoff = (llx - urx) / 2
     #		else:
     #			xoff = 0
     xoff = 0
     yoff = 0
     #		vj = self.valign
     #		if vj == ALIGN_TOP:
     #			yoff = -ury
     #		elif vj == ALIGN_CENTER:
     #			yoff = (lly - ury) / 2 - lly
     #		elif vj == ALIGN_BOTTOM:
     #			yoff = -lly
     #		else:
     #			yoff = 0
     self.atrafo = Translation(xoff, yoff)
    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 CreatedObject(self):
     trafo = Translation(self.start)
     r, phi = (self.drag_cur - self.start).polar()
     if r:
         trafo = trafo(Rotation(phi))
     return SimpleText(trafo=trafo, properties=DefaultTextProperties())