replacing @j2sNative with @j2sIgnore where appropriate - requires NEW
[jalview.git] / src / jalview / renderer / AnnotationRenderer.java
index 0aeb45a..548291c 100644 (file)
@@ -25,7 +25,6 @@ import jalview.analysis.CodingUtils;
 import jalview.analysis.Rna;
 import jalview.analysis.StructureFrequency;
 import jalview.api.AlignViewportI;
-import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
@@ -68,7 +67,7 @@ public class AnnotationRenderer
 
   private FontMetrics fm;
 
-  private final boolean MAC = Platform.isAMac();
+  private final boolean USE_FILL_ROUND_RECT = Platform.isAMacAndNotJS();
 
   boolean av_renderHistogram = true, av_renderProfile = true,
           av_normaliseProfile = false;
@@ -417,8 +416,6 @@ public class AnnotationRenderer
     return null;
   }
 
-  boolean rna = false;
-
   /**
    * Render the annotation rows associated with an alignment.
    * 
@@ -471,8 +468,6 @@ public class AnnotationRenderer
             .getAlignmentStrucConsensusAnnotation();
     final AlignmentAnnotation complementConsensusAnnot = av
             .getComplementConsensusAnnotation();
-    boolean renderHistogram = true, renderProfile = true,
-            normaliseProfile = false, isRNA = rna;
 
     BitSet graphGroupDrawn = new BitSet();
     int charOffset = 0; // offset for a label
@@ -483,32 +478,29 @@ public class AnnotationRenderer
     for (int i = 0; i < aa.length; i++)
     {
       AlignmentAnnotation row = aa[i];
-      isRNA = row.isRNA();
+      boolean renderHistogram = true;
+      boolean renderProfile = false;
+      boolean normaliseProfile = false;
+      boolean isRNA = row.isRNA();
+
+      // check if this is a consensus annotation row and set the display
+      // settings appropriately
+      // TODO: generalise this to have render styles for consensus/profile
+      // data
+      if (row.groupRef != null && row == row.groupRef.getConsensus())
       {
-        // check if this is a consensus annotation row and set the display
-        // settings appropriately
-        // TODO: generalise this to have render styles for consensus/profile
-        // data
-        if (row.groupRef != null && row == row.groupRef.getConsensus())
-        {
-          renderHistogram = row.groupRef.isShowConsensusHistogram();
-          renderProfile = row.groupRef.isShowSequenceLogo();
-          normaliseProfile = row.groupRef.isNormaliseSequenceLogo();
-        }
-        else if (row == consensusAnnot || row == structConsensusAnnot
-                || row == complementConsensusAnnot)
-        {
-          renderHistogram = av_renderHistogram;
-          renderProfile = av_renderProfile;
-          normaliseProfile = av_normaliseProfile;
-        }
-        else
-        {
-          renderHistogram = true;
-          // don't need to set render/normaliseProfile since they are not
-          // currently used in any other annotation track renderer
-        }
+        renderHistogram = row.groupRef.isShowConsensusHistogram();
+        renderProfile = row.groupRef.isShowSequenceLogo();
+        normaliseProfile = row.groupRef.isNormaliseSequenceLogo();
+      }
+      else if (row == consensusAnnot || row == structConsensusAnnot
+              || row == complementConsensusAnnot)
+      {
+        renderHistogram = av_renderHistogram;
+        renderProfile = av_renderProfile;
+        normaliseProfile = av_normaliseProfile;
       }
+
       Annotation[] row_annotations = row.annotations;
       if (!row.visible)
       {
@@ -651,7 +643,6 @@ public class AnnotationRenderer
                     && (displayChar.length() > 0))
             {
               Graphics2D gg = ((Graphics2D) g);
-              AffineTransform oldTransform = gg.getTransform();
               float fmWidth = fm.charsWidth(displayChar.toCharArray(), 0,
                       displayChar.length());
 
@@ -687,6 +678,10 @@ public class AnnotationRenderer
                */
               final int xPos = (x * charWidth) + charOffset;
               final int yPos = y + iconOffset;
+
+              /*
+               * translate to drawing position _before_ applying any scaling
+               */
               gg.translate(xPos, yPos);
               if (scaledToFit)
               {
@@ -709,8 +704,16 @@ public class AnnotationRenderer
               {
                 gg.drawString(displayChar, 0, 0);
               }
+              if (scaledToFit)
+              {
+                /*
+                 * undo scaling before translating back 
+                 * (restoring saved transform does NOT work in JS PDFGraphics!)
+                 */
+                gg.transform(AffineTransform
+                        .getScaleInstance(1D / fmScaling, 1.0));
+              }
               gg.translate(-xPos, -yPos);
-              gg.setTransform(oldTransform);
             }
           }
           if (row.hasIcons)
@@ -1158,7 +1161,7 @@ public class AnnotationRenderer
     int x1 = lastSSX;
     int x2 = (x * charWidth);
 
-    if (MAC)
+    if (USE_FILL_ROUND_RECT)
     {
       int ofs = charWidth / 2;
       // Off by 1 offset when drawing rects and ovals
@@ -1386,7 +1389,8 @@ public class AnnotationRenderer
           boolean isStructureProfile = profl[0] == AlignmentAnnotation.STRUCTURE_PROFILE;
           boolean isCdnaProfile = profl[0] == AlignmentAnnotation.CDNA_PROFILE;
           float ht = normaliseProfile ? y - _aa.graphHeight : y1;
-          double htn = normaliseProfile ? _aa.graphHeight : (y2 - y1);// aa.graphHeight;
+          final double normaliseFactor = normaliseProfile ? _aa.graphHeight
+                  : (y2 - y1);
 
           /**
            * Render a single base for a sequence profile, a base pair for
@@ -1437,8 +1441,14 @@ public class AnnotationRenderer
               s = new String(dc);
             }
             // next profl[] position is profile % for the character(s)
-            
-            double newHeight = htn * scale * profl[c++];
+
+            int percent = profl[c++];
+            if (percent == 0)
+            {
+              // failsafe in case a count rounds down to 0%
+              continue;
+            }
+            double newHeight = normaliseFactor * scale * percent;
 
             /*
              * Set character colour as per alignment colour scheme; use the
@@ -1464,9 +1474,9 @@ public class AnnotationRenderer
             // (int)(scl));
             // g.setColor(profcolour.findColour(dc[0]).darker());
 
-            double sx = 1f * charWidth / fm.charsWidth(dc, 0, dc.length);            
+            double sx = 1f * charWidth / fm.charsWidth(dc, 0, dc.length);
             double sy = newHeight / asc;
-            double newAsc = asc * sy; 
+            double newAsc = asc * sy;
             double newDec = dec * sy;
             // it is not necessary to recalculate lm for the new font.
             // note: lm.getBaselineOffsets()[lm.getBaselineIndex()]) must be 0
@@ -1474,7 +1484,7 @@ public class AnnotationRenderer
             // int hght = (int) (ht + (newAsc - newDec);
             // - lm.getBaselineOffsets()[lm.getBaselineIndex()]));
 
-            if (Jalview.isJS())
+            if (Platform.isJS())
             {
               /*
                * SwingJS does not implement font.deriveFont()
@@ -1482,17 +1492,24 @@ public class AnnotationRenderer
                * this is off by a very small amount
                */
               final int hght = (int) (ht2 + (newAsc - newDec));
-              Graphics2D gg = (Graphics2D) g.create();
-              gg.setFont(ofont);
-              int xShift = (int) (x * charWidth / sx);
-              int yShift = (int) (hght / sy);
+              Graphics2D gg = (Graphics2D) g;
+              int xShift = (int) Math.round(x * charWidth / sx);
+              int yShift = (int) Math.round(hght / sy);
               gg.transform(AffineTransform.getScaleInstance(sx, sy));
               gg.drawString(s, xShift, yShift);
-              gg.dispose();
+              gg.transform(
+                      AffineTransform.getScaleInstance(1D / sx, 1D / sy));
               ht2 += newHeight;
             }
             else
+            /**
+             * Java only
+             * 
+             * @j2sIgnore
+             */
             {
+              // Java ('normal') method is to scale the font to fit
+
               final int hght = (int) (ht + (newAsc - newDec));
               Font font = ofont
                       .deriveFont(AffineTransform.getScaleInstance(sx, sy));
@@ -1501,7 +1518,6 @@ public class AnnotationRenderer
               ht += newHeight;
             }
           }
-          g.setFont(ofont);
         }
       }
       x++;
@@ -1512,7 +1528,7 @@ public class AnnotationRenderer
       Graphics2D g2 = (Graphics2D) g;
       g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_ROUND, 3f, new float[]
-      { 5f, 3f }, 0f));
+              { 5f, 3f }, 0f));
 
       y2 = (int) (y
               - ((_aa.threshold.value - min) / range) * _aa.graphHeight);