+ return new int[] { -1 };
+ }
+ int pixel = 0;
+ a[pixel++] = (int) offset;
+ // for example, say we have 10 pixels per column:
+ // ...............xxxxxxxx....xxxxxx.........xxxxxx......
+ // nextSet(i).....^...........^..............^...........
+ // nextClear..............^.........^..............^.....
+ // run lengths....|--n1--|....|-n2-|.........|-n3-|......
+ // 10 pixel/col...|---pixel1---||-----pixel2------|......
+ // pixel..........^0............^1.......................
+ for (int i, iClear = -1; pixel < w
+ && (i = bscol.nextSetBit(iClear + 1)) >= 0;)
+ {
+ // find the next clear bit
+ iClear = bscol.nextClearBit(i + 1);
+ // add the run length n1, n2, n3 to grow the column buffer
+ colBuffer += iClear - i; // n1, n2, etc.
+ // add columns if we have accumulated enough pixels
+
+ while (colBuffer > colsPerPixel && pixel < w)
+ {
+ colBuffer -= colsPerPixel;
+ offset += colsPerPixel;
+ a[pixel++] = i + (int) offset;
+ }
+ // set back column pointer relative to the next run
+ offset = -colBuffer;
+ }
+ // add a terminator
+ a[pixel] = -1;
+ return a;
+ }
+
+ /**
+ * The next column is either a precalculated pixel (when there are multiple
+ * pixels per column) or the next set bit for the column that aligns with the
+ * next pixel (when there are more columns than pixels).
+ *
+ * When columns are hidden, this value is precalculated; otherwise it is
+ * calculated here.
+ *
+ * @param icol
+ * @param pixel
+ * pixel pointer into columnsToShow
+ * @return
+ */
+ private int getNextCol(int icol, int pixel)
+ {
+ return (skippingColumns ? columnsToShow[pixel]
+ : bscol.nextSetBit(icol + 1));
+ }
+
+ /**
+ * Derive the next pixel from either as the given pixel (when we are skipping
+ * columns because this is a dense overview and the pixel known), or from the
+ * current column based on pixels/column. The latter is used for drawing the
+ * hidden-column mask or for overviews that have more pixels across than
+ * columns.
+ *
+ * @param icol
+ * @param pixel
+ * @return
+ */
+ private int getNextPixel(int icol, int pixel)
+ {
+ return Math.min(skippingColumns && pixel > 0 ? pixel
+ : Math.round(icol * pixelsPerCol), w);
+ }
+
+ private boolean loop()
+ {
+ if (delay <= 0)
+ {
+ return false;
+ }
+ if (timer == null)
+ {
+ timer = new Timer(delay, new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ mainLoop();
+ }
+ });
+ timer.setRepeats(false);
+ timer.start();