Calculate views bounds and scroll them according to the current index

@param paint
@return
332319
private ArrayList<Rect> calculateAllBounds(Paint paint) {
        ArrayList<Rect> list = new ArrayList<Rect>();
        //For each views (If no values then add a fake one)
        final int count = mRecyclerView.getAdapter().getItemCount();
        final int width = getWidth();
        final int halfWidth = width / 2;
        for (int i = 0; i < count; i++) {
            Rect bounds = calcBounds(i, paint);
            int w = bounds.right - bounds.left;
            int h = bounds.bottom - bounds.top;
            bounds.left = (int)(halfWidth - (w / 2f) + ((i - mCurrentPage - mPageOffset) * width));
            bounds.right = bounds.left + w;
            bounds.top = 0;
            bounds.bottom = h;
            list.add(bounds);
        }

        return list;
    }
1267795
@Override
    public boolean getScrollableTracksViewportWidth() {
        Component parent = getParent();
        ComponentUI myui = getUI();

        return parent == null || (myui.getPreferredSize(this).width <= parent.getSize().width);
    }
839865
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (mRecyclerView == null) {
            return;
        }
        final int count = mRecyclerView.getAdapter().getItemCount();
        if (count == 0) {
            return;
        }

        // mCurrentPage is -1 on first start and after orientation changed. If so, retrieve the correct index from viewpager.
        if (mCurrentPage == -1 && mRecyclerView != null) {
            mCurrentPage = ((RecyclerViewPager)mRecyclerView).getCurrentPosition();//.getCurrentItem();
        }

        //Calculate views bounds
        ArrayList<Rect> bounds = calculateAllBounds(mPaintText);
        final int boundsSize = bounds.size();

        //Make sure we're on a page that still exists
        if (mCurrentPage >= boundsSize) {
            setCurrentItem(boundsSize - 1);
            return;
        }

        final int countMinusOne = count - 1;
        final float halfWidth = getWidth() / 2f;
        final int left = getLeft();
        final float leftClip = left + mClipPadding;
        final int width = getWidth();
        int height = getHeight();
        final int right = left + width;
        final float rightClip = right - mClipPadding;

        int page = mCurrentPage;
        float offsetPercent;
        if (mPageOffset <= 0.5) {
            offsetPercent = mPageOffset;
        } else {
            page += 1;
            offsetPercent = 1 - mPageOffset;
        }
        final boolean currentSelected = (offsetPercent <= SELECTION_FADE_PERCENTAGE);
        final boolean currentBold = (offsetPercent <= BOLD_FADE_PERCENTAGE);
        final float selectedPercent = (SELECTION_FADE_PERCENTAGE - offsetPercent) / SELECTION_FADE_PERCENTAGE;

        //Verify if the current view must be clipped to the screen
        Rect curPageBound = bounds.get(mCurrentPage);
        float curPageWidth = curPageBound.right - curPageBound.left;
        if (curPageBound.left < leftClip) {
            //Try to clip to the screen (left side)
            clipViewOnTheLeft(curPageBound, curPageWidth, left);
        }
        if (curPageBound.right > rightClip) {
            //Try to clip to the screen (right side)
            clipViewOnTheRight(curPageBound, curPageWidth, right);
        }

        //Left views starting from the current position
        if (mCurrentPage > 0) {
            for (int i = mCurrentPage - 1; i >= 0; i--) {
                Rect bound = bounds.get(i);
                //Is left side is outside the screen
                if (bound.left < leftClip) {
                    int w = bound.right - bound.left;
                    //Try to clip to the screen (left side)
                    clipViewOnTheLeft(bound, w, left);
                    //Except if there's an intersection with the right view
                    Rect rightBound = bounds.get(i + 1);
                    //Intersection
                    if (bound.right + mTitlePadding > rightBound.left) {
                        bound.left = (int) (rightBound.left - w - mTitlePadding);
                        bound.right = bound.left + w;
                    }
                }
            }
        }
        //Right views starting from the current position
        if (mCurrentPage < countMinusOne) {
            for (int i = mCurrentPage + 1 ; i < count; i++) {
                Rect bound = bounds.get(i);
                //If right side is outside the screen
                if (bound.right > rightClip) {
                    int w = bound.right - bound.left;
                    //Try to clip to the screen (right side)
                    clipViewOnTheRight(bound, w, right);
                    //Except if there's an intersection with the left view
                    Rect leftBound = bounds.get(i - 1);
                    //Intersection
                    if (bound.left - mTitlePadding < leftBound.right) {
                        bound.left = (int) (leftBound.right + mTitlePadding);
                        bound.right = bound.left + w;
                    }
                }
            }
        }

        //Now draw views
        int colorTextAlpha = mColorText >>> 24;
        for (int i = 0; i < count; i++) {
            //Get the title
            Rect bound = bounds.get(i);
            //Only if one side is visible
            if ((bound.left > left && bound.left < right) || (bound.right > left && bound.right < right)) {
                final boolean currentPage = (i == page);
                final CharSequence pageTitle = getTitle(i);

                //Only set bold if we are within bounds
                mPaintText.setFakeBoldText(currentPage && currentBold && mBoldText);

                //Draw text as unselected
                mPaintText.setColor(mColorText);
                if(currentPage && currentSelected) {
                    //Fade out/in unselected text as the selected text fades in/out
                    mPaintText.setAlpha(colorTextAlpha - (int)(colorTextAlpha * selectedPercent));
                }

                //Except if there's an intersection with the right view
                if (i < boundsSize - 1)  {
                    Rect rightBound = bounds.get(i + 1);
                    //Intersection
                    if (bound.right + mTitlePadding > rightBound.left) {
                        int w = bound.right - bound.left;
                        bound.left = (int) (rightBound.left - w - mTitlePadding);
                        bound.right = bound.left + w;
                    }
                }
                canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);

                //If we are within the selected bounds draw the selected text
                if (currentPage && currentSelected) {
                    mPaintText.setColor(mColorSelected);
                    mPaintText.setAlpha((int)((mColorSelected >>> 24) * selectedPercent));
                    canvas.drawText(pageTitle, 0, pageTitle.length(), bound.left, bound.bottom + mTopPadding, mPaintText);
                }
            }
        }

        //If we want the line on the top change height to zero and invert the line height to trick the drawing code
        float footerLineHeight = mFooterLineHeight;
        float footerIndicatorLineHeight = mFooterIndicatorHeight;
        if (mLinePosition == LinePosition.Top) {
            height = 0;
            footerLineHeight = -footerLineHeight;
            footerIndicatorLineHeight = -footerIndicatorLineHeight;
        }

        //Draw the footer line
        mPath.reset();
        mPath.moveTo(0, height - footerLineHeight / 2f);
        mPath.lineTo(width, height - footerLineHeight / 2f);
        mPath.close();
        canvas.drawPath(mPath, mPaintFooterLine);

        float heightMinusLine = height - footerLineHeight;
        switch (mFooterIndicatorStyle) {
            case Triangle:
                mPath.reset();
                mPath.moveTo(halfWidth, heightMinusLine - footerIndicatorLineHeight);
                mPath.lineTo(halfWidth + footerIndicatorLineHeight, heightMinusLine);
                mPath.lineTo(halfWidth - footerIndicatorLineHeight, heightMinusLine);
                mPath.close();
                canvas.drawPath(mPath, mPaintFooterIndicator);
                break;

            case Underline:
                if (!currentSelected || page >= boundsSize) {
                    break;
                }

                Rect underlineBounds = bounds.get(page);
                final float rightPlusPadding = underlineBounds.right + mFooterIndicatorUnderlinePadding;
                final float leftMinusPadding = underlineBounds.left - mFooterIndicatorUnderlinePadding;
                final float heightMinusLineMinusIndicator = heightMinusLine - footerIndicatorLineHeight;

                mPath.reset();
                mPath.moveTo(leftMinusPadding, heightMinusLine);
                mPath.lineTo(rightPlusPadding, heightMinusLine);
                mPath.lineTo(rightPlusPadding, heightMinusLineMinusIndicator);
                mPath.lineTo(leftMinusPadding, heightMinusLineMinusIndicator);
                mPath.close();

                mPaintFooterIndicator.setAlpha((int)(0xFF * selectedPercent));
                canvas.drawPath(mPath, mPaintFooterIndicator);
                mPaintFooterIndicator.setAlpha(0xFF);
                break;
        }
    }
590408
public void setBounds(int x, int y, int w, int h) {

        super.setBounds(x, y, w, h);

        iSbHeight = sbHoriz.getPreferredSize().height;
        iSbWidth  = sbVert.getPreferredSize().width;
        iHeight   = h - iSbHeight;
        iWidth    = w - iSbWidth;

        sbHoriz.setBounds(0, iHeight, iWidth, iSbHeight);
        sbVert.setBounds(iWidth, 0, iSbWidth, iHeight);
        adjustScroll();

        iImage = null;

        repaint();
    }
729785
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // If the API level is less than 11, we can't rely on the view animation system to
        // do the scrolling animation. Need to tick it here and call postInvalidate() until the scrolling is done.
        if (Build.VERSION.SDK_INT < 11) {
            tickScrollAnimation();
            if (!mScroller.isFinished()) {
                mGraph.postInvalidate();
            }
        }
    }
906831
public void drawTop(View view, Canvas c) {
        int left = view.getLeft() - mWidth;
        int top = view.getTop() - mHeight;
        int right = view.getRight() + mWidth;
        int bottom = top + mHeight;
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
1247469
public BufferedImage drawTileQueryIndex(int x, int y, int zoom) {

		// Get the web mercator bounding box
		BoundingBox webMercatorBoundingBox = TileBoundingBoxUtils
				.getWebMercatorBoundingBox(x, y, zoom);

		BufferedImage image = null;

		// Query for the geometry count matching the bounds in the index
		long tileCount = queryIndexedFeaturesCount(webMercatorBoundingBox);

		// Draw if at least one geometry exists
		if (tileCount > 0) {

			// Query for geometries matching the bounds in the index
			CloseableIterator<GeometryIndex> results = queryIndexedFeatures(webMercatorBoundingBox);

			try {

				if (maxFeaturesPerTile == null
						|| tileCount <= maxFeaturesPerTile.longValue()) {

					// Draw the tile image
					image = drawTile(zoom, webMercatorBoundingBox, results);

				} else if (maxFeaturesTileDraw != null) {

					// Draw the max features tile
					image = maxFeaturesTileDraw.drawTile(tileWidth, tileHeight,
							tileCount, results);
				}
			} finally {
				try {
					results.close();
				} catch (IOException e) {
					LOGGER.log(Level.WARNING,
							"Failed to close result set for query on x: " + x
									+ ", y: " + y + ", zoom: " + zoom, e);
				}
			}
		}

		return image;
	}
921637
def scroll_x(self, pixels, relative=True):
        '''
        
        '''
        if relative:
            self.offset.x += int(pixels)
        else:
            self.offset.x = int(pixels)
        self._update()
1239092
function(bounds) {
        this.events.triggerEvent("retile");

        // work out mininum number of rows and columns; this is the number of
        // tiles required to cover the viewport plus at least one for panning

        var viewSize = this.map.getSize();
        
        var origin = this.getTileOrigin();
        var resolution = this.map.getResolution(),
            serverResolution = this.getServerResolution(),
            ratio = resolution / serverResolution,
            tileSize = {
                w: this.tileSize.w / ratio,
                h: this.tileSize.h / ratio
            };

        var minRows = Math.ceil(viewSize.h/tileSize.h) + 
                      2 * this.buffer + 1;
        var minCols = Math.ceil(viewSize.w/tileSize.w) +
                      2 * this.buffer + 1;

        var tileLayout = this.calculateGridLayout(bounds, origin, serverResolution);
        this.gridLayout = tileLayout;
        
        var tilelon = tileLayout.tilelon;
        var tilelat = tileLayout.tilelat;
        
        var layerContainerDivLeft = this.map.layerContainerOriginPx.x;
        var layerContainerDivTop = this.map.layerContainerOriginPx.y;

        var tileBounds = this.getTileBoundsForGridIndex(0, 0);
        var startPx = this.map.getViewPortPxFromLonLat(
            new OpenLayers.LonLat(tileBounds.left, tileBounds.top)
        );
        startPx.x = Math.round(startPx.x) - layerContainerDivLeft;
        startPx.y = Math.round(startPx.y) - layerContainerDivTop;

        var tileData = [], center = this.map.getCenter();

        var rowidx = 0;
        do {
            var row = this.grid[rowidx];
            if (!row) {
                row = [];
                this.grid.push(row);
            }
            
            var colidx = 0;
            do {
                tileBounds = this.getTileBoundsForGridIndex(rowidx, colidx);
                var px = startPx.clone();
                px.x = px.x + colidx * Math.round(tileSize.w);
                px.y = px.y + rowidx * Math.round(tileSize.h);
                var tile = row[colidx];
                if (!tile) {
                    tile = this.addTile(tileBounds, px);
                    this.addTileMonitoringHooks(tile);
                    row.push(tile);
                } else {
                    tile.moveTo(tileBounds, px, false);
                }
                var tileCenter = tileBounds.getCenterLonLat();
                tileData.push({
                    tile: tile,
                    distance: Math.pow(tileCenter.lon - center.lon, 2) +
                        Math.pow(tileCenter.lat - center.lat, 2)
                });
     
                colidx += 1;
            } while ((tileBounds.right <= bounds.right + tilelon * this.buffer)
                     || colidx < minCols);
             
            rowidx += 1;
        } while((tileBounds.bottom >= bounds.bottom - tilelat * this.buffer)
                || rowidx < minRows);
        
        //shave off exceess rows and colums
        this.removeExcessTiles(rowidx, colidx);

        var resolution = this.getServerResolution();
        // store the resolution of the grid
        this.gridResolution = resolution;

        //now actually draw the tiles
        tileData.sort(function(a, b) {
            return a.distance - b.distance; 
        });
        for (var i=0, ii=tileData.length; i<ii; ++i) {
            tileData[i].tile.draw();
        }
    }
961655
function() {
        const bounds = this._pixelBounds();
        const pixelSize = (bounds.max.x - bounds.min.x) / this._field.nCols;

        var stride = Math.max(
            1,
            Math.floor(1.2 * this.options.vectorSize / pixelSize)
        );

        const ctx = this._getDrawingContext();
        ctx.strokeStyle = this.options.color;

        var currentBounds = this._map.getBounds();

        for (var y = 0; y < this._field.height; y = y + stride) {
            for (var x = 0; x < this._field.width; x = x + stride) {
                let [lon, lat] = this._field._lonLatAtIndexes(x, y);
                let v = this._field.valueAt(lon, lat);
                let center = L.latLng(lat, lon);
                if (v !== null && currentBounds.contains(center)) {
                    let cell = new Cell(
                        center,
                        v,
                        this.cellXSize,
                        this.cellYSize
                    );
                    this._drawArrow(cell, ctx);
                }
            }
        }
    }
410611
@Override
    public void draw(@NonNull Canvas canvas) {
        pruneRipples();

        // Clip to the dirty bounds, which will be the drawable bounds if we
        // have a mask or content and the ripple bounds if we're projecting.
        final Rect bounds = getDirtyBounds();
        final int saveCount = canvas.save();
        canvas.clipRect(bounds);

        drawContent(canvas);
        drawBackgroundAndRipples(canvas);

        canvas.restoreToCount(saveCount);
    }
270534
synchronized void paintComponent(Graphics componentGraphics) {
        int width = getWidth();
        int height = getHeight();

        this.scrollController.updateModel(
                virtualTerminal.getBufferLineCount() * getFontHeight(),
                height);

        boolean needToUpdateBackBuffer =
                // User has used the scrollbar, we need to update the back buffer to reflect this
                lastBufferUpdateScrollPosition != scrollController.getScrollingOffset() ||
                        // There is blinking text to update
                        hasBlinkingText ||
                        // We simply have a hint that we should update everything
                        needFullRedraw;

        // Detect resize
        if(width != lastComponentWidth || height != lastComponentHeight) {
            int columns = width / getFontWidth();
            int rows = height / getFontHeight();
            TerminalSize terminalSize = virtualTerminal.getTerminalSize().withColumns(columns).withRows(rows);
            virtualTerminal.setTerminalSize(terminalSize);

            // Back buffer needs to be updated since the component size has changed
            needToUpdateBackBuffer = true;
        }

        if(needToUpdateBackBuffer) {
            updateBackBuffer(scrollController.getScrollingOffset());
        }

        ensureGraphicBufferHasRightSize();
        Rectangle clipBounds = componentGraphics.getClipBounds();
        if(clipBounds == null) {
            clipBounds = new Rectangle(0, 0, getWidth(), getHeight());
        }
        componentGraphics.drawImage(
                backbuffer,
                // Destination coordinates
                clipBounds.x,
                clipBounds.y,
                clipBounds.width,
                clipBounds.height,
                // Source coordinates
                clipBounds.x,
                clipBounds.y,
                clipBounds.width,
                clipBounds.height,
                null);

        // Take care of the left-over area at the bottom and right of the component where no character can fit
        //int leftoverHeight = getHeight() % getFontHeight();
        int leftoverWidth = getWidth() % getFontWidth();
        componentGraphics.setColor(Color.BLACK);
        if(leftoverWidth > 0) {
            componentGraphics.fillRect(getWidth() - leftoverWidth, 0, leftoverWidth, getHeight());
        }

        //0, 0, getWidth(), getHeight(), 0, 0, getWidth(), getHeight(), null);
        this.lastComponentWidth = width;
        this.lastComponentHeight = height;
        componentGraphics.dispose();
        notifyAll();
    }
937796
public void accept(PainterVisitor visitor, Object group, Bbox bounds, boolean recursive) {
		map.getVectorContext().drawGroup(group, this);

		Coordinate c = getUpperLeftCorner();
		PictureStyle pictureStyle = new PictureStyle(1);
		pictureStyle.setClassName("gm-ZoomStepControl");
		map.getVectorContext().drawImage(this, "bg", Geomajas.getIsomorphicDir() + "geomajas/mapaddon/zoombg.png",
				new Bbox(c.getX(), c.getY(), 20, 60), pictureStyle);

		pictureStyle = new PictureStyle(1);
		pictureStyle.setClassName("gm-ZoomStepControl-zoomIn");
		map.getVectorContext().drawImage(this, "plus", Geomajas.getIsomorphicDir() + "geomajas/mapaddon/zoomPlus.png",
				new Bbox(c.getX(), c.getY(), 20, 20), pictureStyle);
		map.getVectorContext().setCursor(this, "plus", Cursor.POINTER.getValue());

		pictureStyle = new PictureStyle(1);
		pictureStyle.setClassName("gm-ZoomStepControl-zoomOut");
		map.getVectorContext().drawImage(this, "minus",
				Geomajas.getIsomorphicDir() + "geomajas/mapaddon/zoomMinus.png",
				new Bbox(c.getX(), c.getY() + 40, 20, 20), pictureStyle);
		map.getVectorContext().setCursor(this, "minus", Cursor.POINTER.getValue());

		pictureStyle = new PictureStyle(1);
		pictureStyle.setClassName("gm-ZoomStepControl-zoomMax");
		map.getVectorContext().drawImage(this, "max", Geomajas.getIsomorphicDir() + "geomajas/mapaddon/maxextent.png",
				new Bbox(c.getX(), c.getY() + 20, 20, 20), pictureStyle);
		map.getVectorContext().setCursor(this, "max", Cursor.POINTER.getValue());

		if (firstTime) {
			map.getVectorContext().setController(this, "plus", new ZoomController(map, 2), Event.MOUSEEVENTS);
			map.getVectorContext().setCursor(this, "plus", Cursor.POINTER.getValue());

			map.getVectorContext().setController(this, "minus", new ZoomController(map, 0.5), Event.MOUSEEVENTS);
			map.getVectorContext().setCursor(this, "minus", Cursor.POINTER.getValue());

			map.getVectorContext().setController(this, "max", new MaxExtentController(map), Event.MOUSEEVENTS);
			map.getVectorContext().setCursor(this, "max", Cursor.POINTER.getValue());
		}
		firstTime = false;
	}
427809
function(viewport) {
      var dt = viewport.currentDisplayTransform;
      var containerToTrack = viewport.containerToTrackMap;
      var viewX = dt.xWorldToView(this.xWorld_);

      var viewY = -1;
      for (var index in this.yComponents_) {
        var yComponent = this.yComponents_[index];
        var track = containerToTrack.getTrackByStableId(yComponent.stableId);
        if (track !== undefined) {
          var boundRect = track.getBoundingClientRect();
          viewY = yComponent.yPercentOffset * boundRect.height + boundRect.top;
          break;
        }
      }

      return {
        viewX: viewX,
        viewY: viewY
      };
    }
246701
public MapBounds expand(final int margin, final Rectangle paintArea) {
        final double size;
        if (this.bbox.getHeight() == 0 ||
                this.bbox.getWidth() / this.bbox.getHeight() > paintArea.getWidth() / paintArea.getHeight()) {
            // it's the width of the feature that is a limiting factor
            size = paintArea.getWidth();
        } else {
            // it's the height of the feature that is a limiting factor
            size = paintArea.getHeight();
        }
        final double factor = size / (size - 2.0 * margin);

        final double destWidth = this.bbox.getWidth() * factor;
        final double destHeight = this.bbox.getHeight() * factor;

        final double centerX = this.bbox.centre().x;
        final double centerY = this.bbox.centre().y;

        final double minGeoX = centerX - destWidth / 2.0;
        final double maxGeoX = centerX + destWidth / 2.0;
        final double minGeoY = centerY - destHeight / 2.0;
        final double maxGeoY = centerY + destHeight / 2.0;

        return new BBoxMapBounds(getProjection(),
                                 minGeoX, minGeoY, maxGeoX, maxGeoY);
    }
554954
protected void onDrawFrame( SurfaceView view , Canvas canvas ) {

		// Code below is usefull when debugging display issues
//		Paint paintFill = new Paint();
//		paintFill.setColor(Color.RED);
//		paintFill.setStyle(Paint.Style.FILL);
//		Paint paintBorder = new Paint();
//		paintBorder.setColor(Color.BLUE);
//		paintBorder.setStyle(Paint.Style.STROKE);
//		paintBorder.setStrokeWidth(6*displayMetrics.density);
//
//		Rect r = new Rect(0,0,view.getWidth(),view.getHeight());
//		canvas.drawRect(r,paintFill);
//		canvas.drawRect(r,paintBorder);
		switch( bitmapMode) {
			case UNSAFE:
				canvas.drawBitmap(this.bitmap, imageToView, null);
				break;

			case DOUBLE_BUFFER:
				bitmapLock.lock();
				try{
					canvas.drawBitmap(this.bitmap, imageToView, null);
				} finally {
					bitmapLock.unlock();
				}
				break;
		}
	}
1034052
@Nullable
  public Drawable getDrawable(int index) {
    Preconditions.checkArgument(index >= 0);
    Preconditions.checkArgument(index < mLayers.length);
    return mLayers[index];
  }