X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frenderer%2FAnnotationRenderer.java;h=ea5439341d465727fd52de0e896a604f50c6206f;hb=03bc8848382795bda548083f0bc3202dfe6a9b8b;hp=3faddb76368b2e728318e06823acc900fdba0545;hpb=84d14b33c57f3c33d30f6de60c3245896f91801d;p=jalview.git diff --git a/src/jalview/renderer/AnnotationRenderer.java b/src/jalview/renderer/AnnotationRenderer.java index 3faddb7..ea54393 100644 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@ -28,11 +28,15 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; +import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.awt.image.ImageObserver; import java.util.BitSet; import java.util.Hashtable; +import org.jfree.graphics2d.svg.SVGGraphics2D; +import org.jibble.epsgraphics.EpsGraphics2D; + import jalview.analysis.AAFrequency; import jalview.analysis.CodingUtils; import jalview.analysis.Rna; @@ -91,6 +95,10 @@ public class AnnotationRenderer private boolean av_ignoreGapsConsensus; + private boolean vectorRendition = false; + + private boolean glyphLineDrawn = false; + /** * attributes set from AwtRenderPanelI */ @@ -254,8 +262,7 @@ public class AnnotationRenderer if (diffupstream || diffdownstream) { // draw glyphline under arrow - this.drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + drawGlyphLine(g, lastSSX, x, y, iconOffset); } g.setColor(nonCanColor); if (column > 0 && Rna.isClosingParenthesis(dc)) @@ -460,16 +467,11 @@ public class AnnotationRenderer AlignViewportI av, Graphics g, int activeRow, int startRes, int endRes) { - Graphics2D g2d = (Graphics2D) g; - /* - if (Cache.getDefault("ANTI_ALIAS", true)) + if (g instanceof EpsGraphics2D || g instanceof SVGGraphics2D) { - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, - RenderingHints.VALUE_STROKE_PURE); + this.setVectorRendition(true); } - */ + Graphics2D g2d = (Graphics2D) g; long stime = System.currentTimeMillis(); boolean usedFaded = false; @@ -616,6 +618,7 @@ public class AnnotationRenderer * * continue; } */ + // first pass sets up state for drawing continuation from left-hand // column // of startRes @@ -905,13 +908,17 @@ public class AnnotationRenderer // temp = x; break; default: - unsetAntialias(g); - g.setColor(GLYPHLINE_COLOR); - g.fillRect(lastSSX, y + 6 + iconOffset, - (x * charWidth) - lastSSX, 2); - g.drawRect(lastSSX, y + 6 + iconOffset, - (x * charWidth) - lastSSX - 1, 2); - // temp = x; + if (isVectorRendition()) + { + // draw single full width glyphline + drawGlyphLine(g, lastSSX, endRes - x, y, iconOffset); + // disable more glyph lines + this.glyphLineDrawn = true; + } + else + { + drawGlyphLine(g, lastSSX, x, y, iconOffset); + } break; } } @@ -1042,8 +1049,17 @@ public class AnnotationRenderer x, y, iconOffset, startRes, column, validRes, validEnd); break; default: - drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + if (isVectorRendition()) + { + // draw single full width glyphline + drawGlyphLine(g, lastSSX, endRes - x, y, iconOffset); + // disable more glyph lines + this.glyphLineDrawn = true; + } + else + { + drawGlyphLine(g, lastSSX, x, y, iconOffset); + } break; } } @@ -1178,15 +1194,23 @@ public class AnnotationRenderer // private Color sdNOTCANONICAL_COLOUR; - void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX, int x, - int y, int iconOffset, int startRes, int column, boolean validRes, - boolean validEnd) + void drawGlyphLine(Graphics g, int lastSSX, int x, int y, int iconOffset) { + if (glyphLineDrawn) + { + // if we've drawn a single long glyphline for an export, don't draw the + // bits + return; + } unsetAntialias(g); g.setColor(GLYPHLINE_COLOR); - g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2); - g.drawRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX - 1, + g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX - 1, 2); + if (!isVectorRendition()) + { + g.drawRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX - 1, + 2); + } } void drawSheetAnnot(Graphics g, Annotation[] row, @@ -1198,11 +1222,11 @@ public class AnnotationRenderer || row[column].secondaryStructure != 'E') { // draw the glyphline underneath - drawGlyphLine(g, row, lastSSX, x, y, iconOffset, startRes, column, - validRes, validEnd); + drawGlyphLine(g, lastSSX, x, y, iconOffset); + g.setColor(SHEET_COLOUR); fillRect(g, lastSSX, y + 4 + iconOffset, - (x * charWidth) - lastSSX - 4, 6); + (x * charWidth) - lastSSX - 4, isVectorRendition() ? 6 : 7); fillPolygon(g, new int[] { (x * charWidth) - 6, (x * charWidth) - 6, @@ -1215,7 +1239,8 @@ public class AnnotationRenderer else { g.setColor(SHEET_COLOUR); - fillRect(g, lastSSX, y + 4 + iconOffset, x * charWidth - lastSSX, 6); + fillRect(g, lastSSX, y + 4 + iconOffset, x * charWidth - lastSSX, + isVectorRendition() ? 6 : 7); } } @@ -1223,21 +1248,22 @@ public class AnnotationRenderer int y, int iconOffset, int startRes, int column, boolean validRes, boolean validEnd) { - g.setColor(HELIX_COLOUR); - int sCol = (lastSSX / charWidth) + hiddenColumns.visibleToAbsoluteColumn(startRes); int x1 = lastSSX; int x2 = (x * charWidth); - y--; - - if (USE_FILL_ROUND_RECT) + if (USE_FILL_ROUND_RECT || isVectorRendition()) { + // draw glyph line behind helix (visible in EPS or SVG output) + drawGlyphLine(g, lastSSX, x, y, iconOffset); + + g.setColor(HELIX_COLOUR); + setAntialias(g); int ofs = charWidth / 2; // Off by 1 offset when drawing rects and ovals // to offscreen image on the MAC - fillRoundRect(g, lastSSX, y + 4 + iconOffset, x2 - x1 - 1, 8, 8, 8); + fillRoundRect(g, lastSSX, y + 3 + iconOffset, x2 - x1 - 1, 8, 8, 8); if (sCol == 0 || row[sCol - 1] == null || row[sCol - 1].secondaryStructure != 'H') { @@ -1245,7 +1271,7 @@ public class AnnotationRenderer else { // g.setColor(Color.orange); - fillRoundRect(g, lastSSX, y + 4 + iconOffset, x2 - x1 - ofs, 8, 0, + fillRoundRect(g, lastSSX, y + 3 + iconOffset, x2 - x1 - ofs, 8, 0, 0); } if (!validRes || row[column] == null @@ -1256,30 +1282,38 @@ public class AnnotationRenderer else { // g.setColor(Color.magenta); - fillRoundRect(g, lastSSX + ofs, y + 4 + iconOffset, x2 - x1 - ofs, + fillRoundRect(g, lastSSX + ofs, y + 3 + iconOffset, x2 - x1 - ofs, 8, 0, 0); - } return; } - if (sCol == 0 || row[sCol - 1] == null - || row[sCol - 1].secondaryStructure != 'H') + boolean leftEnd = sCol == 0 || row[sCol - 1] == null + || row[sCol - 1].secondaryStructure != 'H'; + boolean rightEnd = !validRes || row[column] == null + || row[column].secondaryStructure != 'H'; + + if (leftEnd || rightEnd) + { + drawGlyphLine(g, lastSSX, x, y, iconOffset); + } + g.setColor(HELIX_COLOUR); + + if (leftEnd) { - fillArc(g, lastSSX, y + 4 + iconOffset, charWidth, 8, 90, 180); + fillArc(g, lastSSX, y + 3 + iconOffset, charWidth, 8, 90, 180); x1 += charWidth / 2; } - if (!validRes || row[column] == null - || row[column].secondaryStructure != 'H') + if (rightEnd) { - fillArc(g, (x * charWidth) - charWidth - 1, y + 4 + iconOffset, + fillArc(g, (x * charWidth) - charWidth - 1, y + 3 + iconOffset, charWidth, 8, 270, 180); x2 -= charWidth / 2; } - fillRect(g, x1, y + 4 + iconOffset, x2 - x1, 8); + fillRect(g, x1, y + 3 + iconOffset, x2 - x1, 8); } void drawLineGraph(Graphics g, AlignmentAnnotation _aa, @@ -1290,6 +1324,13 @@ public class AnnotationRenderer { return; } + Stroke roundStroke = new BasicStroke(1, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND); + Stroke squareStroke = new BasicStroke(1, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_MITER); + Graphics2D g2d = (Graphics2D) g; + Stroke prevStroke = g2d.getStroke(); + g2d.setStroke(roundStroke); int x = 0; @@ -1315,9 +1356,9 @@ public class AnnotationRenderer y2 = y - (int) ((0 - min / range) * graphHeight); } - setAntialias(g); g.setColor(Color.gray); - g.drawLine(x - charWidth, y2, (eRes - sRes + 1) * charWidth, y2); + drawLine(g, squareStroke, x * charWidth - charWidth, y2, + (eRes - sRes) * charWidth, y2); eRes = Math.min(eRes, aa_annotations.length); @@ -1359,7 +1400,7 @@ public class AnnotationRenderer // standalone value y1 = y - (int) (((aa_annotations[column].value - min) / range) * graphHeight); - g.drawLine(x * charWidth + charWidth / 4, y1, + drawLine(g, x * charWidth + charWidth / 4, y1, x * charWidth + 3 * charWidth / 4, y1); x++; continue; @@ -1376,7 +1417,7 @@ public class AnnotationRenderer y2 = y - (int) (((aa_annotations[column].value - min) / range) * graphHeight); - g.drawLine(x * charWidth - charWidth / 2, y1, + drawLine(g, (x - 1) * charWidth + charWidth / 2, y1, x * charWidth + charWidth / 2, y2); x++; } @@ -1385,14 +1426,14 @@ public class AnnotationRenderer { g.setColor(_aa.threshold.colour); Graphics2D g2 = (Graphics2D) g; - g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE, + Stroke s = 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) * graphHeight); - g.drawLine(0, y2, (eRes - sRes) * charWidth, y2); - g2.setStroke(new BasicStroke()); + drawLine(g, s, 0, y2, (eRes - sRes) * charWidth, y2); } + g2d.setStroke(prevStroke); } @SuppressWarnings("unused") @@ -1419,7 +1460,7 @@ public class AnnotationRenderer g.setColor(Color.gray); - g.drawLine(x, y2, (eRes - sRes) * charWidth, y2); + drawLine(g, x, y2, (eRes - sRes) * charWidth, y2); int column; int aaMax = aa_annotations.length - 1; @@ -1618,15 +1659,13 @@ public class AnnotationRenderer if (_aa.threshold != null) { g.setColor(_aa.threshold.colour); - Graphics2D g2 = (Graphics2D) g; - g2.setStroke(new BasicStroke(1, BasicStroke.CAP_SQUARE, + Stroke s = 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); - g.drawLine(0, y2, (eRes - sRes) * charWidth, y2); - g2.setStroke(new BasicStroke()); + drawLine(g, s, 0, y2, (eRes - sRes) * charWidth, y2); } } @@ -1793,40 +1832,78 @@ public class AnnotationRenderer } } - private static void fillPolygon(Graphics g, int[] xpoints, int[] ypoints, - int n) + private void fillPolygon(Graphics g, int[] xpoints, int[] ypoints, int n) { unsetAntialias(g); g.fillPolygon(xpoints, ypoints, n); - setAntialias(g); - g.fillPolygon(xpoints, ypoints, n); - g.drawPolygon(xpoints, ypoints, n); + if (!isVectorRendition()) + { + setAntialias(g); + g.fillPolygon(xpoints, ypoints, n); + g.drawPolygon(xpoints, ypoints, n); + } } - private static void fillRect(Graphics g, int a, int b, int c, int d) + /* + private void fillRect(Graphics g, int a, int b, int c, int d) + { + fillRect(g, false, a, b, c, d); + }*/ + + private void fillRect(Graphics g, int a, int b, int c, int d) { g.fillRect(a, b, c, d); - g.drawRect(a, b, c, d); + /* + if (false && !isVectorRendition() && drawRect) + { + g.drawRect(a, b, c, d); + } + */ } - private static void fillRoundRect(Graphics g, int a, int b, int c, int d, - int e, int f) + private void fillRoundRect(Graphics g, int a, int b, int c, int d, int e, + int f) { setAntialias(g); g.fillRoundRect(a, b, c, d, e, f); - g.drawRoundRect(a, b, c, d, e, f); + if (!isVectorRendition()) + { + g.drawRoundRect(a, b, c, d, e, f); + } } - private static void fillArc(Graphics g, int a, int b, int c, int d, int e, - int f) + private void fillArc(Graphics g, int a, int b, int c, int d, int e, int f) { setAntialias(g); g.fillArc(a, b, c, d, e, f); - g.drawArc(a, b, c, d, e, f); + if (!isVectorRendition()) + { + g.drawArc(a, b, c, d, e, f); + } } - private static void setAntialias(Graphics g) + private void drawLine(Graphics g, Stroke s, int a, int b, int c, int d) { + Graphics2D g2d = (Graphics2D) g; + Stroke p = g2d.getStroke(); + g2d.setStroke(s); + drawLine(g, a, b, c, d); + g2d.setStroke(p); + } + + private void drawLine(Graphics g, int a, int b, int c, int d) + { + setAntialias(g); + g.drawLine(a, b, c, d); + } + + private void setAntialias(Graphics g) + { + if (isVectorRendition()) + { + // no need to antialias vector drawings + return; + } if (Cache.getDefault("ANTI_ALIAS", true)) { Graphics2D g2d = (Graphics2D) g; @@ -1835,10 +1912,25 @@ public class AnnotationRenderer } } - private static void unsetAntialias(Graphics g) + private void unsetAntialias(Graphics g) { + if (isVectorRendition()) + { + // no need to antialias vector drawings + return; + } Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } + + public void setVectorRendition(boolean b) + { + vectorRendition = b; + } + + public boolean isVectorRendition() + { + return vectorRendition; + } }