From: gmungoc Date: Wed, 2 Aug 2017 12:51:02 +0000 (+0200) Subject: JAL-2609 further progress towards scroll right fast paint... X-Git-Tag: Release_2_10_3b1~91^2~6^2~21 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=f5be602fd7f0560f29d96748145aef5fa590beda;p=jalview.git JAL-2609 further progress towards scroll right fast paint... --- diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java index 9bab774..785b71d 100755 --- a/src/jalview/gui/SeqCanvas.java +++ b/src/jalview/gui/SeqCanvas.java @@ -120,17 +120,17 @@ public class SeqCanvas extends JComponent implements ViewportListenerI /** * Draws the scale above a region of a wrapped alignment, consisting of a - * column number every 10 columns. + * column number every major interval (10 columns). * * @param g * the graphics context to draw on, positioned at the start (bottom - * left) of the + * left) of the line on which to draw any scale marks * @param startx - * DOCUMENT ME! + * start alignment column (0..) * @param endx - * DOCUMENT ME! + * end alignment column (0..) * @param ypos - * DOCUMENT ME! + * y offset to draw at */ private void drawNorthScale(Graphics g, int startx, int endx, int ypos) { @@ -509,8 +509,10 @@ public class SeqCanvas extends JComponent implements ViewportListenerI /* * draw one width at a time (including any scales or annotation shown), * until we have run out of alignment or vertical space available + * (stop if not enough room left for at least one sequence) */ - while ((ypos <= canvasHeight) && (startRes < maxwidth)) + int yposMax = canvasHeight;// - hgap - charHeight + 1; + while ((ypos <= yposMax) && (startRes < maxwidth)) { drawWrappedWidth(g, startRes, canvasHeight, cWidth, maxwidth, ypos); @@ -1266,16 +1268,17 @@ public class SeqCanvas extends JComponent implements ViewportListenerI /* * add new columns (scale above, sequence, annotation) - * at top left if scrollX < 0 or bottom right if scrollX > 0 + * - at top left if scrollX < 0 + * - at right of last two widths if scrollX > 0 * also West scale top left or East scale bottom right if shown */ if (scrollX < 0) { - fastPaintWrappedTopLeft(-scrollX); + fastPaintWrappedAddLeft(-scrollX); } else { - // fastPaintWrappedBottomRight(scrollX); + fastPaintWrappedAddRight(scrollX); } repaint(); @@ -1284,42 +1287,128 @@ public class SeqCanvas extends JComponent implements ViewportListenerI /** * Draws the specified number of columns at the 'end' (bottom right) of a * wrapped alignment view, including scale above and right and annotations if - * shown + * shown. Also draws the same number of columns at the right hand end of the + * second last width shown, if the last width is not full height (so cannot + * simply be copied from the graphics image). * * @param columns */ - protected void fastPaintWrappedBottomRight(int columns) + protected void fastPaintWrappedAddRight(int columns) { if (columns == 0) { return; } + /* + * how many widths are visible? we will be adding + * columns to the last visible width, right hand end + */ int repeatHeight = getRepeatHeightWrapped(); - ViewportRanges ranges = av.getRanges(); - int visibleWidths = getHeight() / repeatHeight; - if (getHeight() % repeatHeight > 0) + int canvasHeight = getHeight(); + int visibleWidths = canvasHeight / repeatHeight; + int remainder = canvasHeight % repeatHeight; + int hgap = charHeight * (av.getScaleAboveWrapped() ? 2 : 1); + boolean lastWidthPartHeight = false; + if (remainder >= (hgap + charHeight)) { visibleWidths++; + lastWidthPartHeight = true; } + + /* + * limit visible widths to max widths of alignment + */ + ViewportRanges ranges = av.getRanges(); + int visibleAlignmentWidth = ranges.getVisibleAlignmentWidth(); int viewportWidth = ranges.getViewportWidth(); - int hgap = charHeight * (av.getScaleAboveWrapped() ? 2 : 1); + int maxWidths = visibleAlignmentWidth / viewportWidth; + if (visibleAlignmentWidth % viewportWidth > 0) + { + maxWidths++; + } + visibleWidths = Math.min(visibleWidths, maxWidths); + int widthInColumns = (getWidth() - labelWidthEast - labelWidthWest) + / charWidth; - int startRes = av.getRanges().getStartRes(); - int endx = startRes + columns - 1; - int ypos = charHeight * (av.getScaleAboveWrapped() ? 2 : 1); - ypos += repeatHeight * (visibleWidths - 1); + /** + * draw full height alignment in the second last row, last columns, if the + * last row was not full height + */ + if (lastWidthPartHeight) + { + int widthsAbove = visibleWidths - 2; + int ypos = repeatHeight * widthsAbove + hgap; + int endRes = ranges.getEndRes(); + endRes += widthsAbove * viewportWidth; + int startRes = endRes - columns; + int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth) + * charWidth; + gg.translate(xOffset, 0); + + /* + * white fill first to erase annotations + */ + gg.setColor(Color.white); + gg.fillRect(labelWidthWest, ypos, + (endRes - startRes + 1) * charWidth, repeatHeight); + + drawWrappedRegion(gg, startRes, endRes, canvasHeight, widthInColumns, + ypos); + gg.translate(-xOffset, 0); + } + + /* + * y-offset for drawing is height of widths above, + * plus one gap row + */ + int widthsAbove = visibleWidths - 1; + int ypos = repeatHeight * widthsAbove + hgap; + int endRes = ranges.getEndRes(); + endRes += widthsAbove * viewportWidth; + endRes = Math.min(endRes, ranges.getVisibleAlignmentWidth()); + + /* + * draw one extra column than strictly needed - this is a (harmless) + * fudge to ensure scale marks get drawn (JAL-2636) + */ + int startRes = endRes - columns; + + /* + * x-offset is x-start modulo viewport start residue; + * doesn't include label West (offset is applied in drawWrappedRegion) + */ + + int leftEndColumn = ranges.getStartRes() + widthsAbove + * ranges.getViewportWidth(); + // startRes = Math.max(startRes - 0, leftEndColumn); + int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth) + * charWidth; + gg.translate(xOffset, 0); + + /* + * white fill the region to be drawn including scale left or above; + * extend to right hand margin so as to erase scale above when + * scrolling right beyond end of alignment + */ + gg.setColor(Color.white); + int width = getWidth() - labelWidthWest - xOffset; + gg.fillRect(labelWidthWest, ypos - hgap, width, repeatHeight); gg.setFont(av.getFont()); gg.setColor(Color.black); - int cWidth = (getWidth() - labelWidthEast - labelWidthWest) / charWidth; - - drawWrappedRegion(gg, startRes, endx, getHeight(), cWidth, ypos); + drawWrappedRegion(gg, startRes, endRes, canvasHeight, widthInColumns, + ypos); + gg.translate(-xOffset, 0); + /* + * draw scale right if shown, passing in the start/end columns + * for the whole line, not just the last few columns + */ if (av.getScaleRightWrapped()) { - drawVerticalScale(gg, startRes, endx, ypos, false); + drawVerticalScale(gg, leftEndColumn, endRes, ypos, false); } } @@ -1330,7 +1419,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI * * @param columns */ - protected void fastPaintWrappedTopLeft(int columns) + protected void fastPaintWrappedAddLeft(int columns) { int startRes = av.getRanges().getStartRes(); @@ -1378,16 +1467,24 @@ public class SeqCanvas extends JComponent implements ViewportListenerI int repeatHeight = getRepeatHeightWrapped(); ViewportRanges ranges = av.getRanges(); + int xMax = ranges.getVisibleAlignmentWidth(); int widthToCopy = (ranges.getViewportWidth() - Math.abs(positions)) * charWidth; - int visibleWidths = getHeight() / repeatHeight; - if (getHeight() % repeatHeight > 0) + int canvasHeight = getHeight(); + int visibleWidths = canvasHeight / repeatHeight; + if (canvasHeight % repeatHeight > 0) { visibleWidths++; } int viewportWidth = ranges.getViewportWidth(); int hgap = charHeight * (av.getScaleAboveWrapped() ? 2 : 1); + int remainder = canvasHeight % repeatHeight; + if (remainder >= (hgap + charHeight)) + { + visibleWidths++; + } + if (positions > 0) { /* @@ -1402,13 +1499,12 @@ public class SeqCanvas extends JComponent implements ViewportListenerI /* * get y-offset of last wrapped width */ - int y = getHeight() / repeatHeight * repeatHeight; + int y = canvasHeight / repeatHeight * repeatHeight; int copyFromLeftStart = labelWidthWest; int copyFromRightStart = copyFromLeftStart + widthToCopy; while (y >= 0) { - // todo limit repeatHeight for a last part height width? gg.copyArea(copyFromLeftStart, y, widthToCopy, repeatHeight, positions * charWidth, 0); if (y > 0) @@ -1445,12 +1541,12 @@ public class SeqCanvas extends JComponent implements ViewportListenerI int y = 0; int copyFromRightStart = labelWidthWest - positions * charWidth; - while (y < getHeight()) + while (y < canvasHeight) { - // todo limit repeatHeight for a last part height width? gg.copyArea(copyFromRightStart, y, widthToCopy, repeatHeight, positions * charWidth, 0); - if (y + repeatHeight < getHeight()) + if (y + repeatHeight < canvasHeight - repeatHeight + && (xpos + viewportWidth <= xMax)) { gg.copyArea(labelWidthWest, y + repeatHeight, -positions * charWidth, repeatHeight, widthToCopy, -repeatHeight); @@ -1466,7 +1562,7 @@ public class SeqCanvas extends JComponent implements ViewportListenerI } y += repeatHeight; - xpos += ranges.getViewportWidth(); + xpos += viewportWidth; } } }