X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frenderer%2FAnnotationRenderer.java;h=6d001180ce1a851ec1dae1fbc95ed1a62648efca;hb=0184787284a60624bd112260c0318889ade9fd56;hp=90808def4fed87ef0f60554585ca59fb30096732;hpb=3e7ebcfda0bc54b3b91905e21835142bfd1fe8a0;p=jalview.git diff --git a/src/jalview/renderer/AnnotationRenderer.java b/src/jalview/renderer/AnnotationRenderer.java index 90808de..6d00118 100644 --- a/src/jalview/renderer/AnnotationRenderer.java +++ b/src/jalview/renderer/AnnotationRenderer.java @@ -35,16 +35,29 @@ import java.awt.Image; import java.awt.font.LineMetrics; import java.awt.geom.AffineTransform; import java.awt.image.ImageObserver; +import java.util.BitSet; import java.util.Hashtable; import com.stevesoft.pat.Regex; public class AnnotationRenderer { + /** + * flag indicating if timing and redraw parameter info should be output + */ + private final boolean debugRedraw; public AnnotationRenderer() { - // TODO Auto-generated constructor stub + this(false); + } + /** + * Create a new annotation Renderer + * @param debugRedraw flag indicating if timing and redraw parameter info should be output + */ + public AnnotationRenderer(boolean debugRedraw) + { + this.debugRedraw=debugRedraw; } public void drawStemAnnot(Graphics g, Annotation[] row_annotations, @@ -143,9 +156,25 @@ public class AnnotationRenderer * width of image to render in panel */ private int imgWidth; + /** + * offset to beginning of visible area + */ + private int sOffset; + /** + * offset to end of visible area + */ + private int visHeight; + /** + * indicate if the renderer should only render the visible portion of the annotation given the current view settings + */ + private boolean useClip=true; + /** + * master flag indicating if renderer should ever try to clip. not enabled for jalview 2.8.1 + */ + private boolean canClip=false; - public void drawNotCanonicalAnnot(Graphics g, Color nonCanColor, Annotation[] row_annotations, + public void drawPseudoNode(Graphics g, Color nonCanColor, Annotation[] row_annotations, int lastSSX, int x, int y, int iconOffset, int startRes, int column, boolean validRes, boolean validEnd) { @@ -155,7 +184,7 @@ public class AnnotationRenderer int sCol = (lastSSX / charWidth) + startRes; int x1 = lastSSX; int x2 = (x * charWidth); - Regex closeparen = new Regex("}|]|<|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"); + Regex closeparen = new Regex("}|]|<|[a-z]"); String dc = (column == 0 || row_annotations[column - 1] == null) ? "" : row_annotations[column - 1].displayCharacter; @@ -212,6 +241,22 @@ public class AnnotationRenderer annotationPanel = annotPanel; fadedImage = annotPanel.getFadedImage(); imgWidth = annotPanel.getFadedImageWidth(); + // visible area for rendering + int[] bounds=annotPanel.getVisibleVRange(); + if (bounds!=null) + { + sOffset = bounds[0]; + visHeight = bounds[1]; + if (visHeight==0) + { + useClip=false; + } else { + useClip=canClip; + } + } else { + useClip=false; + } + updateFromAlignViewport(av); } @@ -311,6 +356,7 @@ public class AnnotationRenderer AlignViewportI av, Graphics g, int activeRow, int startRes, int endRes) { + long stime=System.currentTimeMillis(); boolean usedFaded = false; // NOTES: // AnnotationPanel needs to implement: ImageObserver, access to @@ -318,7 +364,11 @@ public class AnnotationRenderer updateFromAwtRenderPanel(annotPanel, av); fm = g.getFontMetrics(); AlignmentAnnotation[] aa = av.getAlignment().getAlignmentAnnotation(); - + int temp = 0; + if (aa==null) + { + return false; + } int x = 0, y = 0; int column = 0; char lastSS; @@ -330,12 +380,16 @@ public class AnnotationRenderer boolean centreColLabels, centreColLabelsDef = av .getCentreColumnLabels(); boolean scaleColLabel = false; - boolean[] graphGroupDrawn = new boolean[aa.length]; + + BitSet graphGroupDrawn = new BitSet(); int charOffset = 0; // offset for a label float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a // column. Font ofont = g.getFont(); // \u03B2 \u03B1 + // debug ints + int yfrom=0,f_i=0,yto=0,f_to=0; + boolean clipst=false,clipend=false; for (int i = 0; i < aa.length; i++) { AlignmentAnnotation row = aa[i]; @@ -349,10 +403,20 @@ public class AnnotationRenderer scaleColLabel = row.scaleColLabel; lastSS = ' '; lastSSX = 0; + + if (!useClip || ((y-charHeight)=sOffset)) + {// if_in_visible_region + if (!clipst) + { + clipst=true; + yfrom=y; + f_i=i; + } + yto = y; + f_to=i; if (row.graph > 0) { - if (row.graphGroup > -1 && graphGroupDrawn[row.graphGroup]) - { + if (row.graphGroup > -1 && graphGroupDrawn.get(row.graphGroup)) { continue; } @@ -563,267 +627,50 @@ public class AnnotationRenderer } } - if (ss == 'A') + if (ss >=65) { + // System.out.println("ss="+ss); // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('a') > -1) + if (row_annotations[column].displayCharacter.indexOf(ss+32) > -1) { - ss = 'a'; + + ss = (char) (ss+32); } } + - if (ss == 'B') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('b') > -1) - { - ss = 'b'; - - } - } - - if (ss == 'C') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('c') > -1) - { - ss = 'c'; - - } - } - if (ss == 'D') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('d') > -1) - { - ss = 'd'; - - } - } - if (ss == '1') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('e') > -1) - { - ss = 'e'; - - } - } - if (ss == 'F') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('f') > -1) - { - ss = 'f'; - - } - } - if (ss == 'G') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('g') > -1) - { - ss = 'g'; - - } - } - if (ss == '2') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('h') > -1) - { - ss = 'h'; - - } - } - if (ss == 'I') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('i') > -1) - { - ss = 'i'; - - } - } - if (ss == 'J') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('j') > -1) - { - ss = 'j'; - - } - } - if (ss == 'K') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('k') > -1) - { - ss = 'k'; - - } - } - if (ss == 'L') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('l') > -1) - { - ss = 'l'; - - } - } - if (ss == 'M') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('m') > -1) - { - ss = 'm'; - - } - } - if (ss == 'N') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('n') > -1) - { - ss = 'n'; - - } - } - if (ss == 'O') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('o') > -1) - { - ss = 'o'; - - } - } - if (ss == 'P') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('p') > -1) - { - ss = 'p'; - - } - } - if (ss == 'Q') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('q') > -1) - { - ss = 'q'; - - } - } - if (ss == 'R') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('r') > -1) - { - ss = 'r'; - - } - } - if (ss == 'S') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('s') > -1) - { - ss = 's'; - - } - } - if (ss == 'T') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('t') > -1) - { - ss = 't'; - - } - } - if (ss == 'U') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('u') > -1) - { - ss = 'u'; - - } - } - if (ss == 'V') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('v') > -1) - { - ss = 'v'; - - } - } - if (ss == 'W') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('w') > -1) - { - ss = 'w'; - - } - } - if (ss == 'X') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('x') > -1) - { - ss = 'x'; - - } - } - if (ss == 'Y') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('y') > -1) - { - ss = 'y'; - - } - } - if (ss == 'Z') - { - // distinguish between forward/backward base-pairing - if (row_annotations[column].displayCharacter.indexOf('z') > -1) - { - ss = 'z'; - - } - } if (!validRes || (ss != lastSS)) { + + if (x > -1) { + + + int nb_annot=x-temp; + //System.out.println("\t type :"+lastSS+"\t x :"+x+"\t nbre annot :"+nb_annot); switch (lastSS) { - case 'H': - drawHelixAnnot(g, row_annotations, lastSSX, x, y, - iconOffset, startRes, column, validRes, validEnd); + + case '$': + drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); break; - case 'E': - drawSheetAnnot(g, row_annotations, lastSSX, x, y, - iconOffset, startRes, column, validRes, validEnd); + case 'µ': + drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); break; case '(': // Stem case for RNA secondary structure case ')': // and opposite direction + + drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, column, validRes, validEnd); -// case 'S': // Stem case for RNA secondary structure -// case 's': // and opposite direction -// drawStemAnnot(g, row_annotations, lastSSX, x, y, -// iconOffset, startRes, column, validRes, validEnd); + temp=x; break; case '{': case '}': @@ -839,13 +686,13 @@ public class AnnotationRenderer case 'c': case 'D': case 'd': - case '1': + case 'E': case 'e': case 'F': case 'f': case 'G': case 'g': - case '2': + case 'H': case 'h': case 'I': case 'i': @@ -883,16 +730,17 @@ public class AnnotationRenderer case 'y': case 'Z': case 'z': - //System.out.println(lastSS); + Color nonCanColor= getNotCanonicalColor(lastSS); - drawNotCanonicalAnnot(g, nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes, + drawPseudoNode(g, nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes, column, validRes, validEnd); + temp=x; break; default: g.setColor(Color.gray); g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2); - + temp=x; break; } } @@ -938,19 +786,21 @@ public class AnnotationRenderer { switch (lastSS) { - case 'H': - drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + case '$': + drawHelixAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); break; - case 'E': - drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + case 'µ': + drawSheetAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); break; case 's': case 'S': // Stem case for RNA secondary structure - drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + + drawStemAnnot(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); + break; case '{': case '}': @@ -966,13 +816,13 @@ public class AnnotationRenderer case 'c': case 'D': case 'd': - case '1': + case 'E': case 'e': case 'F': case 'f': case 'G': case 'g': - case '2': + case 'H': case 'h': case 'I': case 'i': @@ -1009,13 +859,16 @@ public class AnnotationRenderer case 'Z': case 'z': //System.out.println(lastSS); + Color nonCanColor = getNotCanonicalColor(lastSS); - drawNotCanonicalAnnot(g,nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes, + drawPseudoNode(g,nonCanColor, row_annotations, lastSSX, x, y, iconOffset, startRes, column, validRes, validEnd); + break; + default: - drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset, - startRes, column, validRes, validEnd); + drawGlyphLine(g, row_annotations, lastSSX, x, y, iconOffset, startRes, + column, validRes, validEnd); break; } } @@ -1024,8 +877,9 @@ public class AnnotationRenderer { if (row.graph == AlignmentAnnotation.LINE_GRAPH) { - if (row.graphGroup > -1 && !graphGroupDrawn[row.graphGroup]) + if (row.graphGroup > -1 && !graphGroupDrawn.get(row.graphGroup)) { + // TODO: JAL-1291 revise rendering model so the graphGroup map is computed efficiently for all visible labels float groupmax = -999999, groupmin = 9999999; for (int gg = 0; gg < aa.length; gg++) { @@ -1038,6 +892,7 @@ public class AnnotationRenderer { aa[gg].visible = false; } + if (aa[gg].graphMax > groupmax) { groupmax = aa[gg].graphMax; @@ -1052,26 +907,31 @@ public class AnnotationRenderer { if (aa[gg].graphGroup == row.graphGroup) { - drawLineGraph(g, aa[gg], aa[gg].annotations, startRes, - endRes, y, groupmin, groupmax, row.graphHeight); + drawLineGraph(g, aa[gg], aa[gg].annotations, startRes, endRes, y, groupmin, + groupmax, row.graphHeight); } } - graphGroupDrawn[row.graphGroup] = true; + graphGroupDrawn.set(row.graphGroup); } else { - drawLineGraph(g, row, row_annotations, startRes, endRes, y, - row.graphMin, row.graphMax, row.graphHeight); + drawLineGraph(g, row, row_annotations, startRes, endRes, y, row.graphMin, + row.graphMax, row.graphHeight); } } else if (row.graph == AlignmentAnnotation.BAR_GRAPH) { - drawBarGraph(g, row, row_annotations, startRes, endRes, - row.graphMin, row.graphMax, y); + drawBarGraph(g, row, row_annotations, startRes, endRes, row.graphMin, + row.graphMax, y); } } - + } else { + if (clipst && !clipend) + { + clipend = true; + } + }// end if_in_visible_region if (row.graph > 0 && row.hasText) { y += charHeight; @@ -1082,6 +942,27 @@ public class AnnotationRenderer y += aa[i].height; } } + if (debugRedraw) + { + if (canClip) + { + if (clipst) + { + System.err.println("Start clip at : " + yfrom + " (index " + f_i + + ")"); + } + if (clipend) + { + System.err.println("End clip at : " + yto + " (index " + f_to + + ")"); + } + } + ; + System.err.println("Annotation Rendering time:" + + (System.currentTimeMillis() - stime)); + } + ; + return !usedFaded; } @@ -1095,17 +976,18 @@ public class AnnotationRenderer private Color sdNOTCANONICAL_COLOUR; - public void drawGlyphLine(Graphics g, Annotation[] row, int lastSSX, - int x, int y, int iconOffset, int startRes, int column, - boolean validRes, boolean validEnd) + public void drawGlyphLine(Graphics g, Annotation[] row, + int lastSSX, int x, int y, int iconOffset, int startRes, + int column, boolean validRes, boolean validEnd) { g.setColor(GLYPHLINE_COLOR); g.fillRect(lastSSX, y + 6 + iconOffset, (x * charWidth) - lastSSX, 2); } - public void drawSheetAnnot(Graphics g, Annotation[] row, int lastSSX, - int x, int y, int iconOffset, int startRes, int column, - boolean validRes, boolean validEnd) + public void drawSheetAnnot(Graphics g, Annotation[] row, + + int lastSSX, int x, int y, int iconOffset, int startRes, + int column, boolean validRes, boolean validEnd) { g.setColor(SHEET_COLOUR); @@ -1483,122 +1365,122 @@ public class AnnotationRenderer { case '{': case '}': - return Color.cyan; + return new Color(255,125,5); case '[': case ']': - return Color.green; + return new Color(245,115,10); case '>': case '<': - return Color.magenta; + return new Color(235,135,15); case 'A': case 'a': - return Color.orange; + return new Color(225,105,20); case 'B': case 'b': - return Color.pink; + return new Color(215,145,30); case 'C': case 'c': - return Color.red; + return new Color(205,95,35); case 'D': case 'd': - return Color.yellow; + return new Color(195,155,45); - case '1': + case 'E': case 'e': - return Color.black; + return new Color(185,85,55); case 'F': case 'f': - return Color.darkGray; + return new Color(175,165,65); case 'G': case 'g': - return Color.gray; + return new Color(170,75,75); - case '2': + case 'H': case 'h': - return Color.lightGray; + return new Color(160,175,85); case 'I': case 'i': - return Color.white; + return new Color(150,65,95); case 'J': case 'j': - return Color.cyan; + return new Color(140,185,105); case 'K': case 'k': - return Color.magenta; + return new Color(130,55,110); case 'L': case 'l': - return Color.orange; + return new Color(120,195,120); case 'M': case 'm': - return Color.red; + return new Color(110,45,130); case 'N': case 'n': - return Color.yellow; + return new Color(100,205,140); case 'O': case 'o': - return Color.pink; + return new Color(90,35,150); case 'P': case 'p': - return Color.black; + return new Color(85,215,160); case 'Q': case 'q': - return Color.blue; + return new Color(75,25,170); case 'R': case 'r': - return Color.cyan; + return new Color(65,225,180); case 'S': case 's': - return Color.magenta; + return new Color(55,15,185); case 'T': case 't': - return Color.darkGray; + return new Color(45,235,195); case 'U': case 'u': - return Color.yellow; + return new Color(35,5,205); case 'V': case 'v': - return Color.blue; + return new Color(25,245,215); case 'W': case 'w': - return Color.orange; + return new Color(15,0,225); case 'X': case 'x': - return Color.magenta; + return new Color(10,255,235); case 'Y': case 'y': - return Color.blue; + return new Color(5,150,245); case 'Z': case 'z': - return Color.blue; + return new Color(0,80,255); default : - System.out.println("This is not a interaction"); + System.out.println("This is not a interaction : "+lastss); return null; }