java.awt.Rectangle#intersection ( )源码实例Demo

下面列出了java.awt.Rectangle#intersection ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: blog-codes   文件: mxUtils.java
/**
 * 
 */
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);
}
 
源代码2 项目: visualvm   文件: ProfilerTableHover.java
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);

}
 
源代码3 项目: netcdf-java   文件: IndependentWindow.java
@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);
}
 
源代码4 项目: jdk8u-jdk   文件: RepaintArea.java
/**
 * 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;
}
 
源代码5 项目: netbeans   文件: AxisComponent.java
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);
    }
}
 
源代码6 项目: jdk8u_jdk   文件: LWContainerPeer.java
/**
 * 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);
    }
}
 
源代码7 项目: visualvm   文件: AxisComponent.java
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);
    }
}
 
源代码8 项目: dragonwell8_jdk   文件: LWContainerPeer.java
/**
 * 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);
    }
}
 
源代码9 项目: jdk8u-jdk   文件: BufferedImage.java
/**
 * 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);
    }
}
 
源代码10 项目: visualvm   文件: ProfilerTableHovers.java
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;
}
 
源代码11 项目: jdk8u-dev-jdk   文件: RepaintArea.java
/**
 * 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;
}
 
源代码12 项目: wandora   文件: AWTWrapper.java
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);
    }
}
 
源代码13 项目: TencentKona-8   文件: SourceClippingBlitTest.java
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");
}
 
源代码14 项目: jdk8u-dev-jdk   文件: SunGraphics2D.java
/**
 * 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;
}
 
源代码15 项目: visualvm   文件: TransformableCanvasComponent.java
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;
}
 
源代码16 项目: openjdk-jdk8u-backup   文件: SunGraphics2D.java
/**
 * 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;
}
 
源代码17 项目: jdk8u-jdk   文件: SunGraphics2D.java
/**
 * 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;
}
 
源代码18 项目: dragonwell8_jdk   文件: SourceClippingBlitTest.java
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");
}
 
源代码19 项目: audiveris   文件: HeadInter.java
/**
 * 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);
}
 
源代码20 项目: openjdk-jdk8u-backup   文件: GIFImageWriter.java
/**
 * 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!");
    }
}