--- cgmsaver.py 2002/11/08 12:33:52 1.1.2.8 +++ cgmsaver.py 2003/02/28 13:23:27 @@ -16,7 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -# $Id: cgmsaver.py,v 1.1.2.8 2002/11/08 12:33:52 apardon Exp $ +# $Id: cgmsaver.py,v 1.1.3.1 2003/02/28 13:20:00 apardon Exp apardon $ ###Sketch Config #type = Export @@ -32,6 +32,9 @@ from Sketch import Scale, Translation, Bezier, CreateRGBColor, EmptyPattern, \ Point + +import Sketch.warn + from math import sqrt, sin, cos # Fault Tolerance for flattening Beziers. @@ -84,12 +87,54 @@ # The midpoint is too far from base. N = B.normalized() - if (C1 * N) < -EPS or (C2 * N) > EPS or cr(C1,B)*cr(C2,B) < 0 or abs(cr(N,S)) > EPS: + if (C1 * N) < -EPS or (C2 * N) > EPS or cr(C1,B)*cr(C2,B) < 0 \ + or abs(cr(N,S)) > EPS: return FlattenPath(P0, P4, P7, P9) + FlattenPath(P9, P8, P6, P3) else: return (P9, P3) - +class Incr: + def __init__(self, Base = 0): + self.Value = Base + def __call__(self, delta = 1): + Result = self.Value + self.Value = self.Value + delta + return Result + +WarnTable = ["- CGM has no Bezier curves. These are flattened\n\n" , + "- CGM has no Gradients. These are filled black\n\n" , + "- cgmaver doesn't handle Hatchings. These are filled black\n\n" , + "- cgmaver doesn't handle Tiles. These are filled black\n\n" , + "- cgmaver doesn't handle images. These are omitted\n\n" , + "- cgmaver doesn't save text. Text is converted\n to Bezier curves"] + +Next = Incr() + +W_Bezier = Next() +W_Gradient = Next() +W_Hatched = Next() +W_Tiled = Next() +W_Image = Next() +W_Text = Next() + +class Warnings: + def __init__(self): + self.set = 0 + def Incl(self, num): + self.set = self.set | 1 << num + def show(self): + inx = 0 + msg = "" + while self.set != 0: + if self.set % 2 == 1: + msg = msg + WarnTable[inx] + inx = inx + 1 + self.set = self.set >> 1 + if msg != "": + msg = "The design you tried to save in CGM Version 1 format\n" + \ + "hit some limitations\n\n" + msg + Sketch.warn.warn(Sketch.warn.USER , msg) + class CGMSaver: def __init__(self, file, pathname, options): @@ -97,6 +142,8 @@ self.pathname = pathname self.options = options self.white = CreateRGBColor(1.0 , 1.0 , 1.0) + self.black = CreateRGBColor(0.0 , 0.0 , 0.0) + self.Msg = Warnings() def w(self, str): self.file.write(str) @@ -136,6 +183,7 @@ def close(self): + self.Msg.show() self.file.close() def PathToSeq(self, Path): @@ -143,6 +191,7 @@ for i in range(Path.len): type, control, p, cont = Path.Segment(i) if type == Bezier: + self.Msg.Incl(W_Bezier) p1 , p2 = control tmplst = FlattenPath(p0, p1, p2, p) for tp in tmplst: @@ -175,6 +224,18 @@ if fill_pattern is EmptyPattern: # Fill type is Hollow self.pack("!HH" , 0x52c2 , 0x0004) + elif fill_pattern.is_Gradient: + self.pack("!HH" , 0x52c2 , 0x0001) + self.putcol(0x52e3 , self.black) + self.Msg.Incl(W_Gradient) + elif fill_pattern.is_Hatching: + self.pack("!HH" , 0x52c2 , 0x0001) + self.putcol(0x52e3 , self.black) + self.Msg.Incl(W_Hatched) + elif fill_pattern.is_Tiled: + self.pack("!HH" , 0x52c2 , 0x0001) + self.putcol(0x52e3 , self.black) + self.Msg.Incl(W_Tiled) else: # Fill type is Solid self.pack("!HH" , 0x52c2 , 0x0001) @@ -247,7 +308,8 @@ self.FillStyle(rct.Properties()) P1 = trf(Point(0,0)) P2 = trf(Point(1,1)) - self.putlongseq(0x4160 , map(rndtoint , tuple(self.trafo(P1)) + tuple(self.trafo(P2)))) + self.putlongseq(0x4160 , map(rndtoint , tuple(self.trafo(P1)) \ + + tuple(self.trafo(P2)))) else: self.PolyBezier(rct.Paths(), rct.Properties()) @@ -259,7 +321,8 @@ self.FillStyle(ell.Properties()) C = trf(Point(0,0)) R = sqrt(trf.m11 * trf.m11 + trf.m12 * trf.m12) - self.putlongseq(0x4180 , map(rndtoint , tuple(self.trafo(C)) + (R * self.Scale,))) + self.putlongseq(0x4180 , map(rndtoint , tuple(self.trafo(C)) \ + + (R * self.Scale,))) else: C = trf(Point(0,0)) S = Point(cos(ell.start_angle) , sin(ell.start_angle)) @@ -271,9 +334,11 @@ S,E = trf.DTransform(E) , trf.DTransform(S) S = 1000000 * S / abs(S) E = 1000000 * E / abs(E) - if ell.arc_type == 0 and ell.Properties().fill_pattern == EmptyPattern: + if ell.arc_type == 0 \ + and ell.Properties().fill_pattern == EmptyPattern: self.LineStyle(ell.Properties()) - self.putlongseq(0x41e0 , map(rndtoint , tuple(self.trafo(C)) + tuple(S) + tuple(E) + (R * self.Scale,))) + self.putlongseq(0x41e0 , map(rndtoint , tuple(self.trafo(C)) \ + + tuple(S) + tuple(E) + (R * self.Scale,))) else: #self.PolyBezier(ell.Paths(), ell.Properties()) self.FillStyle(ell.Properties()) @@ -290,7 +355,8 @@ C = trf(Point(0,0)) P1 = trf(Point(1,0)) P2 = trf(Point(0,1)) - self.putlongseq(0x4220 , map(rndtoint , tuple(self.trafo(C)) + tuple(self.trafo(P1)) + tuple(self.trafo(P2)))) + self.putlongseq(0x4220 , map(rndtoint , tuple(self.trafo(C)) \ + + tuple(self.trafo(P1)) + tuple(self.trafo(P2)))) else: C = trf(Point(0,0)) P1 = trf(Point(1,0)) @@ -301,8 +367,9 @@ E = 1000000 * E / abs(E) if ell.arc_type == 0 and ell.Properties().fill_pattern == EmptyPattern: self.LineStyle(ell.Properties()) - self.putlongseq(0x4240 , map(rndtoint , tuple(self.trafo(C)) + tuple(self.trafo(P1)) \ - + tuple(self.trafo(P2)) + tuple(S) + tuple(E))) + self.putlongseq(0x4240 , map(rndtoint , tuple(self.trafo(C)) \ + + tuple(self.trafo(P1)) + tuple(self.trafo(P2)) + tuple(S) \ + + tuple(E))) else: #self.PolyBezier(ell.Paths(), ell.Properties()) self.FillStyle(ell.Properties()) @@ -311,10 +378,15 @@ else: cp = 2 - ell.arc_type Args = ["!HH10iH" , 0x4260 + 31 , 42] + map(rndtoint , tuple(self.trafo(C)) \ - + tuple(self.trafo(P1)) + tuple(self.trafo(P2)) + tuple(S) + tuple(E) + (cp,)) + + tuple(self.trafo(P1)) + tuple(self.trafo(P2)) + tuple(S) \ + + tuple(E) + (cp,)) apply(self.pack , Args) + def Image(self, object): + self.Msg.Incl(W_Image) + def Text(self, object): + self.Msg.Incl(W_Text) self.PolyBezier(object.Paths(), object.Properties()) def SaveObjects(self, Objects): @@ -326,6 +398,8 @@ self.Rectangle(object) elif object.is_Ellipse: self.Ellipse(object) + elif object.is_Image: + self.Image(object) elif object.is_Text: self.Text(object) elif object.is_curve: @@ -387,8 +461,8 @@ #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))) - + self.extend = map(rndtoint , \ + tuple(self.trafo(left,bottom)) + tuple(self.trafo(right,top))) # Begin Metafile filename = os.path.basename(self.pathname)