Java Code Examples for java.awt.Rectangle#intersection()

The following examples show how to use java.awt.Rectangle#intersection() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: blog-codes   File: mxUtils.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * 
 */
public static void fillClippedRect(Graphics g, int x, int y, int width,
		int height)
{
	Rectangle bg = new Rectangle(x, y, width, height);

	try
	{
		if (g.getClipBounds() != null)
		{
			bg = bg.intersection(g.getClipBounds());
		}
	}
	catch (Exception e)
	{
		log.log(Level.SEVERE, "Failed to compute intersection", e);
		// FIXME: Getting clipbounds sometimes throws an NPE
	}

	g.fillRect(bg.x, bg.y, bg.width, bg.height);
}
 
Example 2
private void checkPopup(int row, int column, Point point) {
    if (row < 0 || row >= table.getRowCount()) return;
    if (column < 0 || column >= table.getColumnCount()) return;
    
    if (point == null) point = currentPoint; else currentPoint = point;
    if (point == null) return;
    
    Rectangle cellRect = table.getCellRect(row, column, true);
    Rectangle rendererRect = getRendererRect(row, column);
    if (rendererRect == null) return;
    
    rendererRect.translate(cellRect.x, cellRect.y);
    if (cellRect.contains(rendererRect)) return; // Value fully visible
    
    Rectangle visibleRect = cellRect.intersection(rendererRect);
    if (visibleRect.contains(point)) // Mouse over partially visible value
        showPopup(new Painter(row, column, rendererRect), visibleRect);

}
 
Example 3
@Override
public void setBounds(Rectangle r) {
  // keep window on the screen
  Rectangle screenSize = ScreenUtils.getScreenVirtualSize();
  Rectangle result = r.intersection(screenSize);
  if (!result.isEmpty())
    super.setBounds(result);
}
 
Example 4
/**
 * Subtracts subtr from rect. If the result is rectangle
 * changes rect and returns true. Otherwise false.
 */
static boolean subtract(Rectangle rect, Rectangle subtr) {
    if (rect == null || subtr == null) {
        return true;
    }
    Rectangle common = rect.intersection(subtr);
    if (common.isEmpty()) {
        return true;
    }
    if (rect.x == common.x && rect.y == common.y) {
        if (rect.width == common.width) {
            rect.y += common.height;
            rect.height -= common.height;
            return true;
        } else
        if (rect.height == common.height) {
            rect.x += common.width;
            rect.width -= common.width;
            return true;
        }
    } else
    if (rect.x + rect.width == common.x + common.width
        && rect.y + rect.height == common.y + common.height)
    {
        if (rect.width == common.width) {
            rect.height -= common.height;
            return true;
        } else
        if (rect.height == common.height) {
            rect.width -= common.width;
            return true;
        }
    }
    return false;
}
 
Example 5
Source Project: netbeans   File: AxisComponent.java    License: Apache License 2.0 5 votes vote down vote up
protected void paintHorizontalBasis(Graphics g, Rectangle clip, Rectangle chartMask) {
    Rectangle dirty = clip.intersection(chartMask);
    g.setColor(getForeground());
    if (location == SwingConstants.NORTH) {
        g.drawLine(dirty.x - 1, getHeight() - 1, dirty.x + dirty.width, getHeight() - 1);
    } else {
        g.drawLine(dirty.x, 0, dirty.x + dirty.width, 0);
    }
}
 
Example 6
/**
 * Paints all the child peers in the straight z-order, so the
 * bottom-most ones are painted first.
 */
private void repaintChildren(final Rectangle r) {
    final Rectangle content = getContentSize();
    for (final LWComponentPeer<?, ?> child : getChildren()) {
        final Rectangle childBounds = child.getBounds();
        Rectangle toPaint = r.intersection(childBounds);
        toPaint = toPaint.intersection(content);
        toPaint.translate(-childBounds.x, -childBounds.y);
        child.repaintPeer(toPaint);
    }
}
 
Example 7
protected void paintHorizontalBasis(Graphics g, Rectangle clip, Rectangle chartMask) {
    Rectangle dirty = clip.intersection(chartMask);
    g.setColor(getForeground());
    if (location == SwingConstants.NORTH) {
        g.drawLine(dirty.x - 1, getHeight() - 1, dirty.x + dirty.width, getHeight() - 1);
    } else {
        g.drawLine(dirty.x, 0, dirty.x + dirty.width, 0);
    }
}
 
Example 8
/**
 * Paints all the child peers in the straight z-order, so the
 * bottom-most ones are painted first.
 */
private void repaintChildren(final Rectangle r) {
    final Rectangle content = getContentSize();
    for (final LWComponentPeer<?, ?> child : getChildren()) {
        final Rectangle childBounds = child.getBounds();
        Rectangle toPaint = r.intersection(childBounds);
        toPaint = toPaint.intersection(content);
        toPaint.translate(-childBounds.x, -childBounds.y);
        child.repaintPeer(toPaint);
    }
}
 
Example 9
/**
 * Sets a rectangular region of the image to the contents of the
 * specified <code>Raster</code> <code>r</code>, which is
 * assumed to be in the same coordinate space as the
 * <code>BufferedImage</code>. The operation is clipped to the bounds
 * of the <code>BufferedImage</code>.
 * @param r the specified <code>Raster</code>
 * @see #getData
 * @see #getData(Rectangle)
*/
public void setData(Raster r) {
    int width = r.getWidth();
    int height = r.getHeight();
    int startX = r.getMinX();
    int startY = r.getMinY();

    int[] tdata = null;

    // Clip to the current Raster
    Rectangle rclip = new Rectangle(startX, startY, width, height);
    Rectangle bclip = new Rectangle(0, 0, raster.width, raster.height);
    Rectangle intersect = rclip.intersection(bclip);
    if (intersect.isEmpty()) {
        return;
    }
    width = intersect.width;
    height = intersect.height;
    startX = intersect.x;
    startY = intersect.y;

    // remind use get/setDataElements for speed if Rasters are
    // compatible
    for (int i = startY; i < startY+height; i++)  {
        tdata = r.getPixels(startX,i,width,1,tdata);
        raster.setPixels(startX,i,width,1, tdata);
    }
}
 
Example 10
private Rectangle[] computePopups(int row, int column, Point point, Component renderer) {
    Rectangle rendererRect = getRendererRect(column, renderer);
    if (rendererRect == null) return null;
    
    Rectangle cellRect = table.getCellRect(row, column, true);
    rendererRect.translate(cellRect.x, cellRect.y);
    cellRect.width -= 1;
    if (cellRect.contains(rendererRect)) return null; // Value fully visible
    
    Rectangle visibleRect = cellRect.intersection(rendererRect);
    if (!visibleRect.contains(point)) return null; // Value fully invisible
    
    // Mouse over partially visible value
    Rectangle[] ret = new Rectangle[2];
    
    if (rendererRect.x < visibleRect.x) {
        Rectangle left = new Rectangle(rendererRect);
        left.width = visibleRect.x - left.x;
        ret[POPUP_LEFT] = left;
    }

    // rendererRect.x + rendererRect.width *- 1*: workaround for extra space for correctly right-aligned values
    if (rendererRect.x + rendererRect.width - 1 > visibleRect.x + visibleRect.width) {
        Rectangle right = new Rectangle(rendererRect);
        right.x = visibleRect.x + visibleRect.width;
        right.width = rendererRect.x + rendererRect.width - right.x;
        ret[POPUP_RIGHT] = right;
    }
    
    return ret;
}
 
Example 11
/**
 * Subtracts subtr from rect. If the result is rectangle
 * changes rect and returns true. Otherwise false.
 */
static boolean subtract(Rectangle rect, Rectangle subtr) {
    if (rect == null || subtr == null) {
        return true;
    }
    Rectangle common = rect.intersection(subtr);
    if (common.isEmpty()) {
        return true;
    }
    if (rect.x == common.x && rect.y == common.y) {
        if (rect.width == common.width) {
            rect.y += common.height;
            rect.height -= common.height;
            return true;
        } else
        if (rect.height == common.height) {
            rect.x += common.width;
            rect.width -= common.width;
            return true;
        }
    } else
    if (rect.x + rect.width == common.x + common.width
        && rect.y + rect.height == common.y + common.height)
    {
        if (rect.width == common.width) {
            rect.height -= common.height;
            return true;
        } else
        if (rect.height == common.height) {
            rect.width -= common.width;
            return true;
        }
    }
    return false;
}
 
Example 12
Source Project: wandora   File: AWTWrapper.java    License: GNU General Public License v3.0 5 votes vote down vote up
private void resizeHeavy(Rectangle newRec) {
    final Rectangle myBounds = new Rectangle(0, 0, prefSize.width, prefSize.height);
    if(newRec.contains(myBounds)) {
        heavyContainer.setBounds(myBounds);
    }
    else {
        final Rectangle heavyBounds = newRec.intersection(myBounds);
        heavyContainer.setBounds(heavyBounds);
        innerPanel.getGui().setLocation(-heavyBounds.x, -heavyBounds.y);
    }
}
 
Example 13
public void test(Rectangle srcRect, Rectangle dstRect) {
    int w = getWidth();
    int h = getHeight();
    Toolkit.getDefaultToolkit().sync();
    try {
        Thread.sleep(2000);
    } catch (InterruptedException ex) {}
    Point p = getLocationOnScreen();
    grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h));

    // calculate the destination rectangle
    Rectangle srcBounds = srcRect.intersection(IMAGE_BOUNDS);
    int trX = dstRect.x - srcRect.x;
    int trY = dstRect.y - srcRect.y;
    Rectangle newDstRect = (Rectangle)dstRect.clone();
    newDstRect.translate(-trX, -trY);
    Rectangle.intersect(newDstRect, srcBounds, newDstRect);
    newDstRect.translate(trX, trY);
    Rectangle.intersect(newDstRect, new Rectangle(0, 0, w, h), newDstRect);

    System.out.println("calculated dest rect:" + newDstRect);

    // we do implicit clipping of the destination surface
    // by only checking pixels within its bounds
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int rgb = 0;
            if (newDstRect.contains(x, y)) {
                rgb = Color.red.getRGB();
            } else {
                rgb = Color.green.getRGB();
            }
            if (grabbedBI.getRGB(x, y) != rgb) {
                String msg1 = "Test failed at x="+x+" y="+y;
                System.out.println(msg1);
                System.out.println(" expected: "+Integer.toHexString(rgb)+
                        " got:"+Integer.toHexString(grabbedBI.getRGB(x, y)));
                throw new RuntimeException(msg1);
            }
        }
    }
    System.out.println("subtest passed");
}
 
Example 14
/**
 * Returns a rectangle in image coordinates that may be required
 * in order to draw the given image into the given clipping region
 * through a pair of AffineTransforms.  In addition, horizontal and
 * vertical padding factors for antialising and interpolation may
 * be used.
 */
private static Rectangle getImageRegion(RenderedImage img,
                                        Region compClip,
                                        AffineTransform transform,
                                        AffineTransform xform,
                                        int padX, int padY) {
    Rectangle imageRect =
        new Rectangle(img.getMinX(), img.getMinY(),
                      img.getWidth(), img.getHeight());

    Rectangle result = null;
    try {
        double p[] = new double[8];
        p[0] = p[2] = compClip.getLoX();
        p[4] = p[6] = compClip.getHiX();
        p[1] = p[5] = compClip.getLoY();
        p[3] = p[7] = compClip.getHiY();

        // Inverse transform the output bounding rect
        transform.inverseTransform(p, 0, p, 0, 4);
        xform.inverseTransform(p, 0, p, 0, 4);

        // Determine a bounding box for the inverse transformed region
        double x0,x1,y0,y1;
        x0 = x1 = p[0];
        y0 = y1 = p[1];

        for (int i = 2; i < 8; ) {
            double pt = p[i++];
            if (pt < x0)  {
                x0 = pt;
            } else if (pt > x1) {
                x1 = pt;
            }
            pt = p[i++];
            if (pt < y0)  {
                y0 = pt;
            } else if (pt > y1) {
                y1 = pt;
            }
        }

        // This is padding for anti-aliasing and such.  It may
        // be more than is needed.
        int x = (int)x0 - padX;
        int w = (int)(x1 - x0 + 2*padX);
        int y = (int)y0 - padY;
        int h = (int)(y1 - y0 + 2*padY);

        Rectangle clipRect = new Rectangle(x,y,w,h);
        result = clipRect.intersection(imageRect);
    } catch (NoninvertibleTransformException nte) {
        // Worst case bounds are the bounds of the image.
        result = imageRect;
    }

    return result;
}
 
Example 15
protected final void paintComponent(Graphics g, Rectangle invalidArea) {
    int shiftX = 0;
    int shiftY = 0;

    contentsWillBeUpdated(offsetX, offsetY, scaleX, scaleY,
                          lastOffsetX, lastOffsetY, lastScaleX, lastScaleY);

    if (!translationPending()) {
        // No translation
        paintContents(g, invalidArea);
    } else {
        // Translation
        int width = getWidth();
        int height = getHeight();

        if (Math.abs(dx) >= width || Math.abs(dy) >= height) {
            // Translation outside of visible area
            paintContents(g, new Rectangle(0, 0, width, height));
        } else {
            // Translation in visible area
            int idx = rightBased ? -(int)dx : (int)dx;
            int idy = bottomBased ? -(int)dy : (int)dy;

            // Total component area
            int total = width * height;
            // Area of the contents saved by shift
            int shiftedSaved = (width - Math.abs(idx)) * (height - Math.abs(idy));

            if (idx != 0 && idy != 0 && shiftedSaved < total * DIAGONAL_SHIFT_ACCEL_LIMIT) {
                // DIAGONAL_SHIFT_ACCEL_LIMIT not met for diagonal shift
                paintContents(g, new Rectangle(0, 0, width, height));
            } else {
                // Saved rectangle
                Rectangle viewport = new Rectangle(idx, idy, width, height);
                Rectangle savedRect = viewport.intersection(
                        new Rectangle(0, 0, width, height));

                // InvalidArea to repaint
                Rectangle invalidRect = invalidArea.intersection(savedRect);

                // Area of invalidRect
                int invalidAfterShift = invalidRect.isEmpty() ? 0 :
                                     invalidRect.width * invalidRect.height;

                // Total saved area
                int savedTotal = shiftedSaved - invalidAfterShift;

                if (savedTotal < total * SHIFT_ACCEL_LIMIT) {
                    // SHIFT_ACCEL_LIMIT not met for shift
                    paintContents(g, new Rectangle(0, 0, width, height));
                } else {
                    // Shift
                    shift(g, idx, idy, width, height);

                    // Repaint original invalidArea if needed
                    if (invalidAfterShift != 0) paintContents(g, invalidRect);

                    shiftX = idx;
                    shiftY = idy;
                }
            }
        }
    }

    contentsUpdated(offsetX, offsetY, scaleX, scaleY, lastOffsetX, lastOffsetY,
                    lastScaleX, lastScaleY, shiftX, shiftY);

    dx = 0;
    dy = 0;
    lastOffsetX = offsetX;
    lastOffsetY = offsetY;
    lastScaleX = scaleX;
    lastScaleY = scaleY;
}
 
Example 16
/**
 * Returns a rectangle in image coordinates that may be required
 * in order to draw the given image into the given clipping region
 * through a pair of AffineTransforms.  In addition, horizontal and
 * vertical padding factors for antialising and interpolation may
 * be used.
 */
private static Rectangle getImageRegion(RenderedImage img,
                                        Region compClip,
                                        AffineTransform transform,
                                        AffineTransform xform,
                                        int padX, int padY) {
    Rectangle imageRect =
        new Rectangle(img.getMinX(), img.getMinY(),
                      img.getWidth(), img.getHeight());

    Rectangle result = null;
    try {
        double p[] = new double[8];
        p[0] = p[2] = compClip.getLoX();
        p[4] = p[6] = compClip.getHiX();
        p[1] = p[5] = compClip.getLoY();
        p[3] = p[7] = compClip.getHiY();

        // Inverse transform the output bounding rect
        transform.inverseTransform(p, 0, p, 0, 4);
        xform.inverseTransform(p, 0, p, 0, 4);

        // Determine a bounding box for the inverse transformed region
        double x0,x1,y0,y1;
        x0 = x1 = p[0];
        y0 = y1 = p[1];

        for (int i = 2; i < 8; ) {
            double pt = p[i++];
            if (pt < x0)  {
                x0 = pt;
            } else if (pt > x1) {
                x1 = pt;
            }
            pt = p[i++];
            if (pt < y0)  {
                y0 = pt;
            } else if (pt > y1) {
                y1 = pt;
            }
        }

        // This is padding for anti-aliasing and such.  It may
        // be more than is needed.
        int x = (int)x0 - padX;
        int w = (int)(x1 - x0 + 2*padX);
        int y = (int)y0 - padY;
        int h = (int)(y1 - y0 + 2*padY);

        Rectangle clipRect = new Rectangle(x,y,w,h);
        result = clipRect.intersection(imageRect);
    } catch (NoninvertibleTransformException nte) {
        // Worst case bounds are the bounds of the image.
        result = imageRect;
    }

    return result;
}
 
Example 17
/**
 * Returns a rectangle in image coordinates that may be required
 * in order to draw the given image into the given clipping region
 * through a pair of AffineTransforms.  In addition, horizontal and
 * vertical padding factors for antialising and interpolation may
 * be used.
 */
private static Rectangle getImageRegion(RenderedImage img,
                                        Region compClip,
                                        AffineTransform transform,
                                        AffineTransform xform,
                                        int padX, int padY) {
    Rectangle imageRect =
        new Rectangle(img.getMinX(), img.getMinY(),
                      img.getWidth(), img.getHeight());

    Rectangle result = null;
    try {
        double p[] = new double[8];
        p[0] = p[2] = compClip.getLoX();
        p[4] = p[6] = compClip.getHiX();
        p[1] = p[5] = compClip.getLoY();
        p[3] = p[7] = compClip.getHiY();

        // Inverse transform the output bounding rect
        transform.inverseTransform(p, 0, p, 0, 4);
        xform.inverseTransform(p, 0, p, 0, 4);

        // Determine a bounding box for the inverse transformed region
        double x0,x1,y0,y1;
        x0 = x1 = p[0];
        y0 = y1 = p[1];

        for (int i = 2; i < 8; ) {
            double pt = p[i++];
            if (pt < x0)  {
                x0 = pt;
            } else if (pt > x1) {
                x1 = pt;
            }
            pt = p[i++];
            if (pt < y0)  {
                y0 = pt;
            } else if (pt > y1) {
                y1 = pt;
            }
        }

        // This is padding for anti-aliasing and such.  It may
        // be more than is needed.
        int x = (int)x0 - padX;
        int w = (int)(x1 - x0 + 2*padX);
        int y = (int)y0 - padY;
        int h = (int)(y1 - y0 + 2*padY);

        Rectangle clipRect = new Rectangle(x,y,w,h);
        result = clipRect.intersection(imageRect);
    } catch (NoninvertibleTransformException nte) {
        // Worst case bounds are the bounds of the image.
        result = imageRect;
    }

    return result;
}
 
Example 18
public void test(Rectangle srcRect, Rectangle dstRect) {
    int w = getWidth();
    int h = getHeight();
    Toolkit.getDefaultToolkit().sync();
    try {
        Thread.sleep(2000);
    } catch (InterruptedException ex) {}
    Point p = getLocationOnScreen();
    grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h));

    // calculate the destination rectangle
    Rectangle srcBounds = srcRect.intersection(IMAGE_BOUNDS);
    int trX = dstRect.x - srcRect.x;
    int trY = dstRect.y - srcRect.y;
    Rectangle newDstRect = (Rectangle)dstRect.clone();
    newDstRect.translate(-trX, -trY);
    Rectangle.intersect(newDstRect, srcBounds, newDstRect);
    newDstRect.translate(trX, trY);
    Rectangle.intersect(newDstRect, new Rectangle(0, 0, w, h), newDstRect);

    System.out.println("calculated dest rect:" + newDstRect);

    // we do implicit clipping of the destination surface
    // by only checking pixels within its bounds
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int rgb = 0;
            if (newDstRect.contains(x, y)) {
                rgb = Color.red.getRGB();
            } else {
                rgb = Color.green.getRGB();
            }
            if (grabbedBI.getRGB(x, y) != rgb) {
                String msg1 = "Test failed at x="+x+" y="+y;
                System.out.println(msg1);
                System.out.println(" expected: "+Integer.toHexString(rgb)+
                        " got:"+Integer.toHexString(grabbedBI.getRGB(x, y)));
                throw new RuntimeException(msg1);
            }
        }
    }
    System.out.println("subtest passed");
}
 
Example 19
/**
 * Precise overlap implementation between notes, based on their pitch value.
 * <p>
 * TODO: A clean overlap check might use true distance tables around each of the heads.
 * For the time being, we simply play with the width and area of intersection rectangle.
 *
 * @param that another inter (perhaps a note)
 * @return true if overlap is detected
 * @throws DeletedInterException when an Inter instance no longer exists in its SIG
 */
@Override
public boolean overlaps (Inter that)
        throws DeletedInterException
{
    // Specific between notes
    if (that instanceof HeadInter) {
        if (this.isVip() && ((HeadInter) that).isVip()) {
            logger.info("HeadInter checking overlaps between {} and {}", this, that);
        }

        HeadInter thatHead = (HeadInter) that;

        // Check vertical distance
        if (this.getStaff() == that.getStaff()) {
            if (Math.abs(thatHead.getIntegerPitch() - getIntegerPitch()) > 1) {
                return false;
            }
        } else {
            // We have two note heads from different staves and with overlapping bounds!
            fixDuplicateWith(thatHead); // Throws DeletedInterException when fixed

            return true;
        }

        // Check horizontal distance
        Rectangle thisBounds = this.getBounds();
        Rectangle thatBounds = thatHead.getBounds();
        Rectangle common = thisBounds.intersection(thatBounds);

        if (common.width <= 0) {
            return false;
        }

        int thisArea = thisBounds.width * thisBounds.height;
        int thatArea = thatBounds.width * thatBounds.height;
        int minArea = Math.min(thisArea, thatArea);
        int commonArea = common.width * common.height;
        double areaRatio = (double) commonArea / minArea;
        boolean res = (common.width > (constants.maxOverlapDxRatio.getValue()
                                               * thisBounds.width)) && (areaRatio
                                                                                > constants.maxOverlapAreaRatio
                        .getValue());

        return res;

        //        } else if (that instanceof StemInter) {
        //            // Head with respect to a stem
        //            // First, standard check
        //            if (!Glyphs.intersect(this.getGlyph(), that.getGlyph(), false)) {
        //                return false;
        //            }
        //
        //            // Second, limit stem vertical range to connection points of ending heads if any
        //            // (Assuming wrong-side ending heads have been pruned beforehand)
        //            StemInter stem = (StemInter) that;
        //            Line2D line = stem.computeAnchoredLine();
        //            int top = (int) Math.ceil(line.getY1());
        //            int bottom = (int) Math.floor(line.getY2());
        //            Rectangle box = stem.getBounds();
        //            Rectangle anchorRect = new Rectangle(box.x, top, box.width, bottom - top + 1);
        //
        //            return this.getCoreBounds().intersects(anchorRect);
    }

    // Basic test
    return super.overlaps(that);
}
 
Example 20
/**
 * Compute the source region and destination dimensions taking any
 * parameter settings into account.
 */
private static void computeRegions(Rectangle sourceBounds,
                                   Dimension destSize,
                                   ImageWriteParam p) {
    ImageWriteParam param;
    int periodX = 1;
    int periodY = 1;
    if (p != null) {
        int[] sourceBands = p.getSourceBands();
        if (sourceBands != null &&
            (sourceBands.length != 1 ||
             sourceBands[0] != 0)) {
            throw new IllegalArgumentException("Cannot sub-band image!");
        }

        // Get source region and subsampling factors
        Rectangle sourceRegion = p.getSourceRegion();
        if (sourceRegion != null) {
            // Clip to actual image bounds
            sourceRegion = sourceRegion.intersection(sourceBounds);
            sourceBounds.setBounds(sourceRegion);
        }

        // Adjust for subsampling offsets
        int gridX = p.getSubsamplingXOffset();
        int gridY = p.getSubsamplingYOffset();
        sourceBounds.x += gridX;
        sourceBounds.y += gridY;
        sourceBounds.width -= gridX;
        sourceBounds.height -= gridY;

        // Get subsampling factors
        periodX = p.getSourceXSubsampling();
        periodY = p.getSourceYSubsampling();
    }

    // Compute output dimensions
    destSize.setSize((sourceBounds.width + periodX - 1)/periodX,
                     (sourceBounds.height + periodY - 1)/periodY);
    if (destSize.width <= 0 || destSize.height <= 0) {
        throw new IllegalArgumentException("Empty source region!");
    }
}