JAL-4274 Use Cache BITMAP_* if no other image restrictions given
[jalview.git] / src / jalview / util / ImageMaker.java
index 016feee..fa473f3 100755 (executable)
@@ -34,7 +34,9 @@ import org.jfree.graphics2d.svg.SVGGraphics2D;
 import org.jfree.graphics2d.svg.SVGHints;
 import org.jibble.epsgraphics.EpsGraphics2D;
 
+import jalview.bin.Console;
 import jalview.io.JalviewFileChooser;
+import jalview.util.imagemaker.BitmapImageSizing;
 
 public class ImageMaker
 {
@@ -114,8 +116,8 @@ public class ImageMaker
    * @throws IOException
    */
   public ImageMaker(TYPE imageType, int width, int height, File file,
-          String fileTitle, boolean useLineart, float bitmapscale,
-          int bitmapwidth, int bitmapheight) throws IOException
+          String fileTitle, boolean useLineart, BitmapImageSizing userBis)
+          throws IOException
   {
     this.type = imageType;
 
@@ -129,7 +131,7 @@ public class ImageMaker
       setupEPS(width, height, fileTitle, useLineart);
       break;
     case PNG:
-      setupPNG(width, height, bitmapscale, bitmapwidth, bitmapheight);
+      setupPNG(width, height, userBis);
       break;
     default:
     }
@@ -180,50 +182,26 @@ public class ImageMaker
    * @param height
    * @param scale
    */
-  protected void setupPNG(int width, int height, float scale,
-          int bitmapwidth, int bitmapheight)
+  protected void setupPNG(int width, int height, BitmapImageSizing userBis)
   {
     if (width == 0 || height == 0)
       return;
 
-    float usescale = 0.0f;
-    int usewidth = width;
-    int useheight = height;
+    BitmapImageSizing bis = ImageMaker.getScaleWidthHeight(width, height,
+            userBis);
+    float usescale = bis.scale();
+    int usewidth = bis.width();
+    int useheight = bis.height();
 
-    // use the smallest positive scale (i.e. fit in the box)
-    if (scale > 0.0f)
-    {
-      usescale = scale;
-      usewidth = Math.round(scale * width);
-      useheight = Math.round(scale * height);
-    }
-    if (bitmapwidth > 0)
-    {
-      float wscale = (float) bitmapwidth / width;
-      if (wscale > 0.0f && (usescale == 0.0f || wscale < usescale))
-      {
-        usescale = wscale;
-        usewidth = bitmapwidth;
-        useheight = Math.round(usescale * height);
-      }
-    }
-    if (bitmapheight > 0)
-    {
-      float hscale = (float) bitmapheight / height;
-      if (hscale > 0.0f && (usescale == 0.0f || hscale < usescale))
-      {
-        usescale = hscale;
-        usewidth = Math.round(usescale * width);
-        useheight = bitmapheight;
-      }
-    }
     bi = new BufferedImage(usewidth, useheight, BufferedImage.TYPE_INT_RGB);
     graphics = bi.getGraphics();
     Graphics2D ig2 = (Graphics2D) graphics;
     ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             RenderingHints.VALUE_ANTIALIAS_ON);
     if (usescale > 0.0f)
+    {
       ig2.scale(usescale, usescale);
+    }
   }
 
   /**
@@ -267,4 +245,142 @@ public class ImageMaker
     pg.setAccurateTextMode(useLineart);
     graphics = pg;
   }
+
+  /**
+   * Takes initial width and height, and suggested float scale, int width, int
+   * height and create a bounding box returned as a BitmapImageSizing object
+   * with consistent scale, width, height fields.
+   * 
+   * @param width
+   *          The unscaled image width
+   * @param height
+   *          The unscaled image height
+   * @param scale
+   *          The suggested scaling
+   * @param bitmapwidth
+   *          The suggested width
+   * @param bitmapheight
+   *          The suggested height
+   * @return BitmapImageSizing A consistent scale,width and height for the final
+   *         image
+   */
+  public static BitmapImageSizing getScaleWidthHeight(int width, int height,
+          float scale, int bitmapwidth, int bitmapheight)
+  {
+    float usescale = 0.0f;
+    int usewidth = width;
+    int useheight = height;
+
+    if ((width == 0 && bitmapwidth > 0)
+            || (height == 0 && bitmapheight > 0))
+    {
+      // original image is zero sized! Avoid dividing by zero!
+      return BitmapImageSizing.nullBitmapImageSizing();
+    }
+
+    // use the smallest positive scale (i.e. fit in the box)
+    if (scale > 0.0f)
+    {
+      usescale = scale;
+      usewidth = Math.round(scale * width);
+      useheight = Math.round(scale * height);
+    }
+    if (bitmapwidth > 0)
+    {
+      float wscale = (float) bitmapwidth / width;
+      if (wscale > 0.0f && (usescale == 0.0f || wscale < usescale))
+      {
+        usescale = wscale;
+        usewidth = bitmapwidth;
+        useheight = Math.round(usescale * height);
+      }
+    }
+    if (bitmapheight > 0)
+    {
+      float hscale = (float) bitmapheight / height;
+      if (hscale > 0.0f && (usescale == 0.0f || hscale < usescale))
+      {
+        usescale = hscale;
+        usewidth = Math.round(usescale * width);
+        useheight = bitmapheight;
+      }
+    }
+    return new BitmapImageSizing(usescale, usewidth, useheight, false);
+  }
+
+  /**
+   * Takes suggested scale, width, height as a BitmapImageSizing object and
+   * create a bounding box returned as a BitmapImageSizing object with
+   * consistent scale, width, height fields.
+   * 
+   * @param bis
+   * @return BitmapImageSizing
+   */
+  public static BitmapImageSizing getScaleWidthHeight(int width, int height,
+          BitmapImageSizing bis)
+  {
+    return ImageMaker.getScaleWidthHeight(width, height, bis.scale(),
+            bis.width(), bis.height());
+  }
+
+  /**
+   * Takes String versions of suggested float scale, int width, int height and
+   * create a bounding box returned as a BitmapImageSizing object with
+   * consistent scale, width, height fields.
+   * 
+   * @param scaleS
+   * @param widthS
+   * @param heightS
+   * @return BitmapImageSizing
+   */
+  public static BitmapImageSizing parseScaleWidthHeightStrings(
+          String scaleS, String widthS, String heightS)
+  {
+    if (scaleS == null && widthS == null && heightS == null)
+    {
+      // if all items are null (i.e. not provided) we use the dynamic
+      // preferences set BIS
+      return BitmapImageSizing.defaultBitmapImageSizing();
+    }
+
+    float scale = 0.0f;
+    int width = 0;
+    int height = 0;
+
+    if (scaleS != null)
+    {
+      try
+      {
+        scale = Float.parseFloat(scaleS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand scale '" + scaleS
+                + "', won't be used.");
+      }
+    }
+    if (widthS != null)
+    {
+      try
+      {
+        width = Integer.parseInt(widthS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand width '" + widthS
+                + "', won't be used.");
+      }
+    }
+    if (heightS != null)
+    {
+      try
+      {
+        height = Integer.parseInt(heightS);
+      } catch (NumberFormatException e)
+      {
+        Console.warn("Did not understand height '" + heightS
+                + "', won't be used.");
+      }
+    }
+
+    return new BitmapImageSizing(scale, width, height, false);
+  }
 }