/** * Propagate dirty region of the layer to other layers in the stack. The method should be called * for dirty layers only. The dirty layer can be invisible in the case it has been hidden since * the previous paint. * * <p>IMPL_NOTE: The layer been removed or set to invisible state since the previous paint is * considered as "hidden", thus it should be entirely dirty and must affect other visible layers * accordingly. * * @param le dirty layer element to be propagated to other layers * @param hidden indicates whether the dirty layer has been hidden since the previous repaint * @return the highest layer element above le with modified dirty region, or null if none */ private CLayerElement sweepAndMarkDirtyLayer(CLayerElement le, boolean hidden) { if (CGraphicsQ.DEBUG) { System.err.println("Sweep and mark dirty layer: " + le.getLayer()); } CLayer l2; CLayerElement res = null; CLayer l = le.getLayer(); // Prepare absolute dirty region coordinates of layer l int dx = l.bounds[X]; int dy = l.bounds[Y]; int dh, dw; if (l.isEmptyDirtyRegions()) { dw = l.bounds[W]; dh = l.bounds[H]; } else { dx += l.dirtyBounds[X]; dy += l.dirtyBounds[Y]; dw = l.dirtyBounds[W]; dh = l.dirtyBounds[H]; } // Sweep dirty region to upper layers for (CLayerElement le2 = le.getUpper(); le2 != null; le2 = le2.getUpper()) { l2 = le2.getLayer(); if (l2.visible) { if (l2.addDirtyRegion(dx - l2.bounds[X], dy - l2.bounds[Y], dw, dh)) { // Remember the highest changed layer res = le2; } } } // Sweep non-opaque dirty region to undelying layers if (!l.opaque || hidden) { for (CLayerElement le2 = le.getLower(); le2 != null; le2 = le2.getLower()) { l2 = le2.getLayer(); if (l2.visible) { l2.addDirtyRegion(dx - l2.bounds[X], dy - l2.bounds[Y], dw, dh); } } // A newly hidden layer should be dirty only for the first // succeeded paint, it should be cleaned as soon as underlying // layers are properly marked as dirty. if (hidden) { l.cleanDirty(); } } return res; }