reportlab: make anchor/preserveAspectRatio cooperate
authorrgbecker
Thu, 25 May 2006 13:04:56 +0000
changeset 2639 9ff3bbcf3282
parent 2638 ee3e8ad6c3cb
child 2640 3b9f819abb41
reportlab: make anchor/preserveAspectRatio cooperate
reportlab/lib/boxstuff.py
reportlab/pdfgen/canvas.py
reportlab/pdfgen/pdfimages.py
--- a/reportlab/lib/boxstuff.py	Wed May 24 16:02:56 2006 +0000
+++ b/reportlab/lib/boxstuff.py	Thu May 25 13:04:56 2006 +0000
@@ -4,9 +4,9 @@
 def anchorAdjustXY(anchor,x,y,width,height):
     if anchor not in ('sw','s','se'):
         if anchor in ('e','c','w'):
-            y += height/2.
+            y -= height/2.
         else:
-            y += height
+            y -= height
     if anchor not in ('nw','w','sw'):
         if anchor in ('n','c','s'):
             x -= width/2.
@@ -14,13 +14,35 @@
             x -= width
     return x,y
 
-def aspectRatioFix(preserve,width,height,imWidth,imHeight):
+def aspectRatioFix(preserve,anchor,x,y,width,height,imWidth,imHeight):
     if width is None:
         width = imWidth
     if height is None:
         height = imHeight
+    if width<0:
+        width = -width
+        x -= width
+    if height<0:
+        height = -height
+        y -= height
     if preserve:
+        imWidth = abs(imWidth)
+        imHeight = abs(imHeight)
         scale = min(width/float(imWidth),height/float(imHeight))
+        owidth = width
+        oheight = height
         width = scale*imWidth-1e-8
         height = scale*imHeight-1e-8
-    return width, height
+        if anchor not in ('n','c','s'):
+            dx = 0.5*(owidth-width)
+            if anchor in ('ne','e','se'):
+                x -= dx
+            else:
+                x += dx
+        if anchor not in ('e','c','w'):
+            dy = 0.5*(oheight-height)
+            if anchor in ('nw','n','ne'):
+                y -= dy
+            else:
+                y += dy
+    return x,y, width, height
--- a/reportlab/pdfgen/canvas.py	Wed May 24 16:02:56 2006 +0000
+++ b/reportlab/pdfgen/canvas.py	Thu May 25 13:04:56 2006 +0000
@@ -535,7 +535,7 @@
         #
         ######################################################
 
-    def drawInlineImage(self, image, x,y, width=None,height=None,preserveAspectRatio=False,boxAnchor='sw'):
+    def drawInlineImage(self, image, x,y, width=None,height=None,preserveAspectRatio=False,anchor='sw'):
         """Draw an Image into the specified rectangle.  If width and
         height are omitted, they are calculated from the image size.
         Also allow file names as well as images.  The size in pixels
@@ -543,11 +543,11 @@
 
         self._currentPageHasImages = 1
         from pdfimages import PDFImage
-        img_obj = PDFImage(image, x,y, width, height,preserveAspectRatio=preserveAspectRatio)
-        img_obj.drawInlineImage(self,boxAnchor=boxAnchor)
+        img_obj = PDFImage(image, x,y, width, height)
+        img_obj.drawInlineImage(self,anchor=anchor,preserveAspectRatio=preserveAspectRatio)
         return (img_obj.width, img_obj.height)
 
-    def drawImage(self, image, x, y, width=None, height=None, mask=None, preserveAspectRatio=False, boxAnchor='sw'):
+    def drawImage(self, image, x, y, width=None, height=None, mask=None, preserveAspectRatio=False, anchor='sw'):
         """Draws the image (ImageReader object or filename) as specified.
 
         "image" may be an image filename or a ImageReader object.  If width
@@ -596,8 +596,8 @@
             self._doc.addForm(name, imgObj)
 
         # ensure we have a size, as PDF will make it 1x1 pixel otherwise!
-        width,height = aspectRatioFix(preserveAspectRatio,width,height,imgObj.width,imgObj.height)
-        x,y = anchorAdjustXY(boxAnchor,x,y,width,height)
+        x,y,width,height = aspectRatioFix(preserveAspectRatio,anchor,x,y,width,height,imgObj.width,imgObj.height)
+        x,y = anchorAdjustXY(anchor,x,y,width,height)
 
         # scale and draw
         self.saveState()
--- a/reportlab/pdfgen/pdfimages.py	Wed May 24 16:02:56 2006 +0000
+++ b/reportlab/pdfgen/pdfimages.py	Thu May 25 13:04:56 2006 +0000
@@ -23,10 +23,12 @@
     an image we previously cached (optimisation, hardly used these
     days) or a JPEG (which PDF supports natively)."""
 
-    def __init__(self, image, x,y, width=None, height=None, caching=0, preserveAspectRatio=False):
+    def __init__(self, image, x,y, width=None, height=None, caching=0):
         self.image = image
-        self.point = (x,y)
-        self.dimensions = (width, height)
+        self.x = x
+        self.y = y
+        self.width = width
+        self.height = height
         self.filename = None
         self.imageCaching = caching
         # the following facts need to be determined,
@@ -36,7 +38,7 @@
         self.bitsPerComponent = 8
         self.filters = []
         self.source = None # JPEG or PIL, set later
-        self.getImageData(preserveAspectRatio=preserveAspectRatio)
+        self.getImageData()
 
     def jpg_imagedata(self):
         #directly process JPEG files
@@ -112,7 +114,6 @@
     def getImageData(self,preserveAspectRatio=False):
         "Gets data, height, width - whatever type of image"
         image = self.image
-        (width, height) = self.dimensions
 
         if type(image) == StringType:
             self.filename = image
@@ -123,7 +124,6 @@
                     imagedata = pdfutils.cacheImageFile(image,returnInMemory=1)
                 else:
                     imagedata = self.cache_imagedata()
-                #parse line two for width, height
                 words = string.split(imagedata[1])
                 imgwidth = string.atoi(words[1])
                 imgheight = string.atoi(words[3])
@@ -134,16 +134,22 @@
                 (imagedata, imgwidth, imgheight) = self.JAVA_imagedata()
             else:
                 (imagedata, imgwidth, imgheight) = self.PIL_imagedata()
-        self.width,self.height = aspectRatioFix(preserveAspectRatio,width,height,imgwidth,imgheight)
         self.imageData = imagedata
+        self.imgwidth = imgwidth
+        self.imgheight = imgheight
+        self.width = self.width or imgwidth
+        self.height = self.height or imgheight
 
-    def drawInlineImage(self, canvas, boxAnchor='sw'): #, image, x,y, width=None,height=None):
+    def drawInlineImage(self, canvas, preserveAspectRatio=False,anchor='sw'): #, image, x,y, width=None,height=None):
         """Draw an Image into the specified rectangle.  If width and
         height are omitted, they are calculated from the image size.
         Also allow file names as well as images.  This allows a
         caching mechanism"""
-        if self.width<1e-6 or self.height<1e-6: return False
-        x,y = anchorAdjustXY(boxAnchor,self.point[0],self.point[1],self.width,self.height)
+        width = self.width
+        height = self.height
+        if width<1e-6 or height<1e-6: return False
+        x,y,self.width,self.height = aspectRatioFix(preserveAspectRatio,anchor,self.x,self.y,width,height,self.imgwidth,self.imgheight)
+        x,y = anchorAdjustXY(anchor,x,y,self.width,self.height)
         # this says where and how big to draw it
         if not canvas.bottomup: y = y+height
         canvas._code.append('q %s 0 0 %s cm' % (fp_str(self.width), fp_str(self.height, x, y)))