def _bracepath(self, x0_pt, y0_pt, x1_pt, y1_pt): # <<< height_pt = unit.topt(self.totalheight) totallength_pt = math.hypot(x1_pt - x0_pt, y1_pt - y0_pt) leftlength_pt = self.middlerelpos * totallength_pt rightlength_pt = totallength_pt - leftlength_pt ithick_pt = unit.topt(self.innerstrokesthickness) othick_pt = unit.topt(self.outerstrokesthickness) bthick_pt = unit.topt(self.barthickness) # create the left halfbrace with positive slanting # because we will mirror this part cos_iangle = math.cos( math.radians(0.5 * self.innerstrokesangle - self.slantstrokesangle)) sin_iangle = math.sin( math.radians(0.5 * self.innerstrokesangle - self.slantstrokesangle)) cos_oangle = math.cos( math.radians(self.outerstrokesangle - self.slantstrokesangle)) sin_oangle = math.sin( math.radians(self.outerstrokesangle - self.slantstrokesangle)) cos_slangle = math.cos(math.radians(-self.slantstrokesangle)) sin_slangle = math.sin(math.radians(-self.slantstrokesangle)) ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle bracepath = self._halfbracepath_pt( leftlength_pt, height_pt, ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle, sin_iangle, cos_oangle, sin_oangle, cos_slangle, sin_slangle).reversed().transformed(trafo.mirror(90)) # create the right halfbrace with negative slanting cos_iangle = math.cos( math.radians(0.5 * self.innerstrokesangle + self.slantstrokesangle)) sin_iangle = math.sin( math.radians(0.5 * self.innerstrokesangle + self.slantstrokesangle)) cos_oangle = math.cos( math.radians(self.outerstrokesangle + self.slantstrokesangle)) sin_oangle = math.sin( math.radians(self.outerstrokesangle + self.slantstrokesangle)) cos_slangle = math.cos(math.radians(-self.slantstrokesangle)) sin_slangle = math.sin(math.radians(-self.slantstrokesangle)) ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle bracepath = bracepath << self._halfbracepath_pt( rightlength_pt, height_pt, ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle, sin_iangle, cos_oangle, sin_oangle, cos_slangle, sin_slangle) return bracepath.transformed( # two trafos for matching the given endpoints trafo.translate_pt(x0_pt, y0_pt) * trafo.rotate_pt( math.degrees(math.atan2(y1_pt - y0_pt, x1_pt - x0_pt))) * # one trafo to move the brace's left outer stroke to zero trafo.translate_pt(leftlength_pt, 0))
def _bracepath(self, x0_pt, y0_pt, x1_pt, y1_pt): # <<< height_pt = unit.topt(self.totalheight) totallength_pt = math.hypot(x1_pt - x0_pt, y1_pt - y0_pt) leftlength_pt = self.middlerelpos * totallength_pt rightlength_pt = totallength_pt - leftlength_pt ithick_pt = unit.topt(self.innerstrokesthickness) othick_pt = unit.topt(self.outerstrokesthickness) bthick_pt = unit.topt(self.barthickness) # create the left halfbrace with positive slanting # because we will mirror this part cos_iangle = math.cos(math.radians(0.5*self.innerstrokesangle - self.slantstrokesangle)) sin_iangle = math.sin(math.radians(0.5*self.innerstrokesangle - self.slantstrokesangle)) cos_oangle = math.cos(math.radians(self.outerstrokesangle - self.slantstrokesangle)) sin_oangle = math.sin(math.radians(self.outerstrokesangle - self.slantstrokesangle)) cos_slangle = math.cos(math.radians(-self.slantstrokesangle)) sin_slangle = math.sin(math.radians(-self.slantstrokesangle)) ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle bracepath = self._halfbracepath_pt(leftlength_pt, height_pt, ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle, sin_iangle, cos_oangle, sin_oangle, cos_slangle, sin_slangle).reversed().transformed(trafo.mirror(90)) # create the right halfbrace with negative slanting cos_iangle = math.cos(math.radians(0.5*self.innerstrokesangle + self.slantstrokesangle)) sin_iangle = math.sin(math.radians(0.5*self.innerstrokesangle + self.slantstrokesangle)) cos_oangle = math.cos(math.radians(self.outerstrokesangle + self.slantstrokesangle)) sin_oangle = math.sin(math.radians(self.outerstrokesangle + self.slantstrokesangle)) cos_slangle = math.cos(math.radians(-self.slantstrokesangle)) sin_slangle = math.sin(math.radians(-self.slantstrokesangle)) ilength_pt = self.innerstrokesrelheight * height_pt / cos_iangle olength_pt = self.outerstrokesrelheight * height_pt / cos_oangle bracepath = bracepath << self._halfbracepath_pt(rightlength_pt, height_pt, ilength_pt, olength_pt, ithick_pt, othick_pt, bthick_pt, cos_iangle, sin_iangle, cos_oangle, sin_oangle, cos_slangle, sin_slangle) return bracepath.transformed( # two trafos for matching the given endpoints trafo.translate_pt(x0_pt, y0_pt) * trafo.rotate_pt(math.degrees(math.atan2(y1_pt-y0_pt, x1_pt-x0_pt))) * # one trafo to move the brace's left outer stroke to zero trafo.translate_pt(leftlength_pt, 0))
def genericalignequal_pt(method, polygons, a, dx, dy): vec = None for p in polygons: v = method(p, a, dx, dy) if vec is None or vec[0] * dx + vec[1] * dy < v[0] * dx + v[1] * dy: vec = v for p in polygons: p.transform(trafo.translate_pt(*vec))
def tile_pt(polygons, a, dx, dy): maxextent = polygons[0].extent_pt(dx, dy) for p in polygons[1:]: extent = p.extent_pt(dx, dy) if extent > maxextent: maxextent = extent delta = maxextent + a d = 0 for p in polygons: p.transform(trafo.translate_pt(d*dx, d*dy)) d += delta return delta
def tile_pt(polygons, a, dx, dy): maxextent = polygons[0].extent_pt(dx, dy) for p in polygons[1:]: extent = p.extent_pt(dx, dy) if extent > maxextent: maxextent = extent delta = maxextent + a d = 0 for p in polygons: p.transform(trafo.translate_pt(d * dx, d * dy)) d += delta return delta
def __init__(self, x, y, filename, width=None, height=None, scale=None, align="bl", clip=1, translatebbox=1, bbox=None, kpsearch=0): """inserts epsfile Object for an EPS file named filename at position (x,y). Width, height, scale and aligment can be adjusted by the corresponding parameters. If clip is set, the result gets clipped to the bbox of the EPS file. If translatebbox is not set, the EPS graphics is not translated to the corresponding origin. If bbox is not None, it overrides the bounding box in the epsfile itself. If kpsearch is set then filename is searched using the kpathsea library. """ self.x_pt = unit.topt(x) self.y_pt = unit.topt(y) self.filename = filename self.kpsearch = kpsearch if bbox: self.mybbox = bbox else: epsfile = self.open() self.mybbox = _readbbox(epsfile) epsfile.close() # determine scaling in x and y direction self.scalex = self.scaley = scale if width is not None or height is not None: if scale is not None: raise ValueError("cannot set both width and/or height and scale simultaneously") if height is not None: self.scaley = unit.topt(height)/(self.mybbox.ury_pt-self.mybbox.lly_pt) if width is not None: self.scalex = unit.topt(width)/(self.mybbox.urx_pt-self.mybbox.llx_pt) if self.scalex is None: self.scalex = self.scaley if self.scaley is None: self.scaley = self.scalex # set the actual width and height of the eps file (after a # possible scaling) self.width_pt = self.mybbox.urx_pt-self.mybbox.llx_pt if self.scalex: self.width_pt *= self.scalex self.height_pt = self.mybbox.ury_pt-self.mybbox.lly_pt if self.scaley: self.height_pt *= self.scaley # take alignment into account self.align = align if self.align[0]=="b": pass elif self.align[0]=="c": self.y_pt -= self.height_pt/2.0 elif self.align[0]=="t": self.y_pt -= self.height_pt else: raise ValueError("vertical alignment can only be b (bottom), c (center), or t (top)") if self.align[1]=="l": pass elif self.align[1]=="c": self.x_pt -= self.width_pt/2.0 elif self.align[1]=="r": self.x_pt -= self.width_pt else: raise ValueError("horizontal alignment can only be l (left), c (center), or r (right)") self.clip = clip self.translatebbox = translatebbox self.trafo = trafo.translate_pt(self.x_pt, self.y_pt) if self.scalex is not None: self.trafo = self.trafo * trafo.scale_pt(self.scalex, self.scaley) if translatebbox: self.trafo = self.trafo * trafo.translate_pt(-self.mybbox.llx_pt, -self.mybbox.lly_pt)
def reltransform(self, *trafos): if self.center is not None: trafos = ([trafo.translate_pt(-self.center[0], -self.center[1])] + list(trafos) + [trafo.translate_pt(self.center[0], self.center[1])]) self.transform(*trafos)
def linealign_pt(self, *args): self.transform(trafo.translate_pt(*self.linealignvector_pt(*args))) return self
def processPS(self, file, writer, context, registry, bbox): mode, data, alpha, palettemode, palettedata = self.imagedata(True) pstrafo = trafo.translate_pt(0, -1.0).scaled( self.imagewidth, -self.imageheight) * self.pdftrafo.inverse() PSsinglestring = self.PSstoreimage and len(data) < self.PSmaxstrlen if PSsinglestring: PSimagename = "image-%d-%s-singlestring" % (id( self.image), self.compressmode) else: PSimagename = "image-%d-%s-stringarray" % (id( self.image), self.compressmode) if self.PSstoreimage and not PSsinglestring: registry.add( pswriter.PSdefinition( "imagedataaccess", "{ /imagedataindex load " # get list index "dup 1 add /imagedataindex exch store " # store increased index "/imagedataid load exch get }") ) # select string from array if self.PSstoreimage: registry.add( PSimagedata(PSimagename, data, PSsinglestring, self.PSmaxstrlen)) bbox += self.bbox() file.write("gsave\n") if palettedata is not None: file.write("[ /Indexed %s %i\n" % (devicenames[palettemode], len(palettedata) / 3 - 1)) file.write("%%%%BeginData: %i ASCII Lines\n" % ascii85lines(len(palettedata))) file.write("<~") ascii85stream(file, palettedata) file.write("~>\n" "%%EndData\n") file.write("] setcolorspace\n") else: file.write("%s setcolorspace\n" % devicenames[mode]) if self.PSstoreimage and not PSsinglestring: file.write( "/imagedataindex 0 store\n" # not use the stack since interpreters differ in their stack usage "/imagedataid %s store\n" % PSimagename) file.write("<<\n") if alpha: file.write("/ImageType 3\n" "/DataDict\n" "<<\n") file.write("/ImageType 1\n" "/Width %i\n" % self.imagewidth) file.write("/Height %i\n" % self.imageheight) file.write("/BitsPerComponent 8\n" "/ImageMatrix %s\n" % pstrafo) file.write("/Decode %s\n" % decodestrings[mode]) file.write("/DataSource ") if self.PSstoreimage: if PSsinglestring: file.write("/%s load" % PSimagename) else: file.write( "/imagedataaccess load" ) # some printers do not allow for inline code here -> we store it in a resource else: if self.PSbinexpand == 2: file.write("currentfile /ASCIIHexDecode filter") else: file.write("currentfile /ASCII85Decode filter") if self.compressmode or self.imagecompressed: file.write(" /%sDecode filter" % (self.compressmode or self.imagecompressed)) file.write("\n") file.write(">>\n") if alpha: file.write("/MaskDict\n" "<<\n" "/ImageType 1\n" "/Width %i\n" % self.imagewidth) file.write("/Height %i\n" % self.imageheight) file.write("/BitsPerComponent 8\n" "/ImageMatrix %s\n" % pstrafo) file.write("/Decode [1 0]\n" ">>\n" "/InterleaveType 1\n" ">>\n") if self.PSstoreimage: file.write("image\n") else: if self.PSbinexpand == 2: file.write("%%%%BeginData: %i ASCII Lines\n" "image\n" % (asciihexlines(len(data)) + 1)) asciihexstream(file, data) file.write(">\n") else: # the datasource is currentstream (plus some filters) file.write("%%%%BeginData: %i ASCII Lines\n" "image\n" % (ascii85lines(len(data)) + 1)) ascii85stream(file, data) file.write("~>\n") file.write("%%EndData\n") file.write("grestore\n")
def processPS(self, file, writer, context, registry, bbox): mode, data, alpha, palettemode, palettedata = self.imagedata(True) pstrafo = trafo.translate_pt(0, -1.0).scaled(self.imagewidth, -self.imageheight)*self.pdftrafo.inverse() PSsinglestring = self.PSstoreimage and len(data) < self.PSmaxstrlen if PSsinglestring: PSimagename = "image-%d-%s-singlestring" % (id(self.image), self.compressmode) else: PSimagename = "image-%d-%s-stringarray" % (id(self.image), self.compressmode) if self.PSstoreimage and not PSsinglestring: registry.add(pswriter.PSdefinition("imagedataaccess", "{ /imagedataindex load " # get list index "dup 1 add /imagedataindex exch store " # store increased index "/imagedataid load exch get }")) # select string from array if self.PSstoreimage: registry.add(PSimagedata(PSimagename, data, PSsinglestring, self.PSmaxstrlen)) bbox += self.bbox() file.write("gsave\n") if palettedata is not None: file.write("[ /Indexed %s %i\n" % (devicenames[palettemode], len(palettedata)/3-1)) file.write("%%%%BeginData: %i ASCII Lines\n" % ascii85lines(len(palettedata))) file.write("<~") ascii85stream(file, palettedata) file.write("~>\n" "%%EndData\n") file.write("] setcolorspace\n") else: file.write("%s setcolorspace\n" % devicenames[mode]) if self.PSstoreimage and not PSsinglestring: file.write("/imagedataindex 0 store\n" # not use the stack since interpreters differ in their stack usage "/imagedataid %s store\n" % PSimagename) file.write("<<\n") if alpha: file.write("/ImageType 3\n" "/DataDict\n" "<<\n") file.write("/ImageType 1\n" "/Width %i\n" % self.imagewidth) file.write("/Height %i\n" % self.imageheight) file.write("/BitsPerComponent 8\n" "/ImageMatrix %s\n" % pstrafo) file.write("/Decode %s\n" % decodestrings[mode]) file.write("/DataSource ") if self.PSstoreimage: if PSsinglestring: file.write("/%s load" % PSimagename) else: file.write("/imagedataaccess load") # some printers do not allow for inline code here -> we store it in a resource else: if self.PSbinexpand == 2: file.write("currentfile /ASCIIHexDecode filter") else: file.write("currentfile /ASCII85Decode filter") if self.compressmode or self.imagecompressed: file.write(" /%sDecode filter" % (self.compressmode or self.imagecompressed)) file.write("\n") file.write(">>\n") if alpha: file.write("/MaskDict\n" "<<\n" "/ImageType 1\n" "/Width %i\n" % self.imagewidth) file.write("/Height %i\n" % self.imageheight) file.write("/BitsPerComponent 8\n" "/ImageMatrix %s\n" % pstrafo) file.write("/Decode [1 0]\n" ">>\n" "/InterleaveType 1\n" ">>\n") if self.PSstoreimage: file.write("image\n") else: if self.PSbinexpand == 2: file.write("%%%%BeginData: %i ASCII Lines\n" "image\n" % (asciihexlines(len(data)) + 1)) asciihexstream(file, data) file.write(">\n") else: # the datasource is currentstream (plus some filters) file.write("%%%%BeginData: %i ASCII Lines\n" "image\n" % (ascii85lines(len(data)) + 1)) ascii85stream(file, data) file.write("~>\n") file.write("%%EndData\n") file.write("grestore\n")