JAL-4381 Plausibly better division of line segment -- looks much better in SVG. Tidy...
authorBen Soares <b.soares@dundee.ac.uk>
Mon, 26 Feb 2024 11:07:01 +0000 (11:07 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Mon, 26 Feb 2024 11:07:01 +0000 (11:07 +0000)
src/jalview/renderer/AnnotationRenderer.java

index a4c339e..9c8a7c1 100644 (file)
@@ -30,6 +30,7 @@ import java.awt.Image;
 import java.awt.RenderingHints;
 import java.awt.Stroke;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
 import java.awt.image.ImageObserver;
 import java.util.BitSet;
 import java.util.Collections;
@@ -1592,14 +1593,43 @@ public class AnnotationRenderer
       // not enough vertical difference for one of the halves, split
       // horizontally
       int x1 = (x0 + x2) / 2;
-      drawHorizontallyClippedLineSegment(g, col0, x0, y0, x1, x2, y2, true);
-      drawHorizontallyClippedLineSegment(g, col2, x0, y0, x1, x2, y2,
-              false);
+      // drawHorizontallyClippedLineSegment(g, col0, x0, y0, x1, x2, y2, true);
+      // drawHorizontallyClippedLineSegment(g, col2, x0, y0, x1, x2, y2, false);
+      drawHalfClippedLineSegment(g, col0, x0, y0, x2, y2, true);
+      drawHalfClippedLineSegment(g, col2, x0, y0, x2, y2, false);
       return;
     }
 
-    drawVerticallyClippedLineSegment(g, col0, x0, y0, y1, x2, y2, true);
-    drawVerticallyClippedLineSegment(g, col2, x0, y0, y1, x2, y2, false);
+    // drawVerticallyClippedLineSegment(g, col0, x0, y0, y1, x2, y2, true);
+    // drawVerticallyClippedLineSegment(g, col2, x0, y0, y1, x2, y2, false);
+    drawHalfClippedLineSegment(g, col0, x0, y0, x2, y2, true);
+    drawHalfClippedLineSegment(g, col2, x0, y0, x2, y2, false);
+  }
+
+  private void drawHalfClippedLineSegment(Graphics g, Color col, int x0,
+          int y0, int x2, int y2, boolean firstPart)
+  {
+    int w = x2 - x0;
+    int h = y2 - y0;
+    if (w == 0 || h == 0)
+    {
+      return;
+    }
+    double d = Math.sqrt(h * h + w * w);
+    Graphics2D g2d = (Graphics2D) g.create();
+    int surround = 1;
+    double a = Math.atan2(-h, w); // -h because pixel increase is downwards
+    g2d.translate(x0, y0);
+    g2d.rotate(-a);
+    g2d.setColor(col);
+    Rectangle2D clipRect = new Rectangle2D.Double(
+            firstPart ? -surround : d / 2, -surround, d / 2 + surround,
+            2 * surround);
+    g2d.setClip(clipRect);
+    g2d.rotate(a);
+    g2d.translate(-x0, -y0);
+    g2d.drawLine(x0, y0, x2, y2);
+    g2d.dispose();
   }
 
   private void drawVerticallyClippedLineSegment(Graphics g, Color col,
@@ -1631,6 +1661,7 @@ public class AnnotationRenderer
     gCopy.setClip(clipX, clipY, clipW, clipH);
     gCopy.setColor(col);
     drawLine(gCopy, x0, y0, x2, y2);
+    gCopy.dispose();
   }
 
   private void drawHorizontallyClippedLineSegment(Graphics g, Color col,
@@ -1662,9 +1693,10 @@ public class AnnotationRenderer
     gCopy.setClip(clipX, clipY, clipW, clipH);
     gCopy.setColor(col);
     drawLine(gCopy, x0, y0, x2, y2);
+    gCopy.dispose();
   }
 
-  private void drawSegmentedLine(Graphics g,
+  private void drawHorizontallyClippedSegmentedLine(Graphics g,
           List<Map.Entry<Float, Color>> valCols, int x1, int y1, int x2,
           int y2)
   {
@@ -1694,13 +1726,13 @@ public class AnnotationRenderer
     yy1 = reverse ? (int) Math.ceil(y1 + firstVal * yd)
             : (int) Math.floor(y1 + firstVal * yd);
     Color thisCol = firstCol;
+    int clipX = x1 - 1;
+    int clipW = x2 - x1 + 2;
     for (int i = 0; i < valCols.size(); i++)
     {
       Map.Entry<Float, Color> valCol = valCols.get(i);
       float val = valCol.getKey();
       Color col = valCol.getValue();
-      int clipX = x1 - 1;
-      int clipW = x2 - x1 + 2;
       int clipY = 0;
       int clipH = 0;
       int yy2 = 0;