src/solaris/classes/sun/java2d/xr/XRPMBlitLoops.java

Print this page




 208                                                                                  * required
 209                                                                                  * :
 210                                                                                  * -
 211                                                                                  * /
 212                                                                                  * ?
 213                                                                                  * ?
 214                                                                                  */
 215             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
 216         } finally {
 217             SunToolkit.awtUnlock();
 218         }
 219     }
 220 }
 221 
 222 /**
 223  * Called also if scale+transform is set
 224  *
 225  * @author Clemens Eisserer
 226  */
 227 class XRPMTransformedBlit extends TransformBlit {



 228 
 229     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
 230         super(srcType, CompositeType.AnyAlpha, dstType);
 231     }
 232 
 233     /*
 234      * Calculates the composite-rectangle required for transformed blits. This
 235      * method is functionally equal to: Shape shp =
 236      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
 237      * but performs significantly better.

 238      */
 239     public Rectangle getCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
 240         double[] compBounds = new double[8];
 241         compBounds[0] = dstx;
 242         compBounds[1] = dsty;
 243         compBounds[2] = dstx + width;
 244         compBounds[3] = dsty;
 245         compBounds[4] = dstx + width;
 246         compBounds[5] = dsty + height;
 247         compBounds[6] = dstx;
 248         compBounds[7] = dsty + height;
 249 
 250         tr.transform(compBounds, 0, compBounds, 0, 4);
 251 
 252         double minX = Math.min(compBounds[0], Math.min(compBounds[2], Math.min(compBounds[4], compBounds[6])));
 253         double minY = Math.min(compBounds[1], Math.min(compBounds[3], Math.min(compBounds[5], compBounds[7])));
 254         double maxX = Math.max(compBounds[0], Math.max(compBounds[2], Math.max(compBounds[4], compBounds[6])));
 255         double maxY = Math.max(compBounds[1], Math.max(compBounds[3], Math.max(compBounds[5], compBounds[7])));
 256 
 257         minX = Math.floor(minX);
 258         minY = Math.floor(minY);
 259         maxX = Math.ceil(maxX);
 260         maxY = Math.ceil(maxY);




 261 
 262         return new Rectangle((int) minX, (int) minY, (int) (maxX - minX), (int) (maxY - minY));



 263     }
 264 
 265     public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, int hint, int srcx, int srcy,
 266             int dstx, int dsty, int width, int height) {
 267         try {
 268             SunToolkit.awtLock();
 269 



 270             int filter = XRUtils.ATransOpToXRQuality(hint);

 271 
 272             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 273             x11sdDst.validateAsDestination(null, clip);
 274             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 275             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 276 
 277             Rectangle bounds = getCompositeBounds(xform, dstx, dsty, width, height);
 278 
 279             AffineTransform trx = AffineTransform.getTranslateInstance((-bounds.x), (-bounds.y));
 280             trx.concatenate(xform);
 281             AffineTransform maskTX = (AffineTransform) trx.clone();
 282 
 283             trx.translate(-srcx, -srcy);
 284 
 285             try {
 286                 trx.invert();
 287             } catch (NoninvertibleTransformException ex) {
 288                 trx.setToIdentity();
 289                 System.err.println("Reseted to identity!");
 290             }
 291 
 292             boolean omitMask = isMaskOmittable(trx, comp, filter);

 293 
 294             if (!omitMask) {
 295                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
 296 
 297                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
 298                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
 299                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
 300                         0, 0, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
 301             } else {
 302                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
 303 
 304                 x11sdSrc.validateAsSource(trx, repeat, filter);
 305                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height);
 306             }
 307         } finally {
 308             SunToolkit.awtUnlock();
 309         }
 310     }
 311 
 312     /* TODO: Is mask ever omitable??? ... should be for 90 degree rotation and no shear, but we always need to use RepeatPad */
 313     protected static boolean isMaskOmittable(AffineTransform trx, Composite comp, int filter) {
 314         return (filter == XRUtils.FAST || trx.getTranslateX() == (int) trx.getTranslateX() /*
 315                                                                                             * If
 316                                                                                             * translate
 317                                                                                             * is
 318                                                                                             * integer
 319                                                                                             * only
 320                                                                                             */
 321                 && trx.getTranslateY() == (int) trx.getTranslateY() && (trx.getShearX() == 0 && trx.getShearY() == 0 // Only
 322                 // 90 degree
 323                 // rotation
 324                 || trx.getShearX() == -trx.getShearY())) && ((AlphaComposite) comp).getAlpha() == 1.0f; // No
 325         // ExtraAlpha!=1
 326     }
 327 }
 328 
 329 class XrSwToPMBlit extends Blit {
 330     Blit pmToSurfaceBlit;
 331 
 332     XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {
 333         super(srcType, CompositeType.AnyAlpha, dstType);
 334         pmToSurfaceBlit = new XRPMBlit(dstType, dstType);
 335     }
 336 
 337     public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
 338         /*
 339          * If the blit is write-only (putimge), no need for a temporary VI.
 340          */
 341         if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {
 342             Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());
 343             opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
 344         } else {
 345             try {




 208                                                                                  * required
 209                                                                                  * :
 210                                                                                  * -
 211                                                                                  * /
 212                                                                                  * ?
 213                                                                                  * ?
 214                                                                                  */
 215             x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, (int) sx1, (int) sy1, (int) dx1, (int) dy1, (int) (dx2 - dx1), (int) (dy2 - dy1));
 216         } finally {
 217             SunToolkit.awtUnlock();
 218         }
 219     }
 220 }
 221 
 222 /**
 223  * Called also if scale+transform is set
 224  *
 225  * @author Clemens Eisserer
 226  */
 227 class XRPMTransformedBlit extends TransformBlit {
 228     final Rectangle compositeBounds = new Rectangle();
 229     final double[] srcCoords = new double[8];
 230     final double[] dstCoords = new double[8];
 231     
 232     public XRPMTransformedBlit(SurfaceType srcType, SurfaceType dstType) {
 233         super(srcType, CompositeType.AnyAlpha, dstType);
 234     }
 235 
 236     /*
 237      * Calculates the composite-rectangle required for transformed blits. This
 238      * method is functionally equal to: Shape shp =
 239      * xform.createTransformedShape(rect); Rectangle bounds = shp.getBounds();
 240      * but performs significantly better.
 241      * Returns true if the destination shape is parallel to x/y axis
 242      */
 243     protected boolean adjustCompositeBounds(AffineTransform tr, int dstx, int dsty, int width, int height) {
 244         srcCoords[0] = dstx;
 245         srcCoords[1] = dsty;
 246         srcCoords[2] = dstx + width;
 247         srcCoords[3] = dsty;
 248         srcCoords[4] = dstx + width;
 249         srcCoords[5] = dsty + height;
 250         srcCoords[6] = dstx;
 251         srcCoords[7] = dsty + height;
 252 
 253         tr.transform(srcCoords, 0, dstCoords, 0, 4);
 254 
 255         double minX = Math.min(dstCoords[0], Math.min(dstCoords[2], Math.min(dstCoords[4], dstCoords[6])));
 256         double minY = Math.min(dstCoords[1], Math.min(dstCoords[3], Math.min(dstCoords[5], dstCoords[7])));
 257         double maxX = Math.max(dstCoords[0], Math.max(dstCoords[2], Math.max(dstCoords[4], dstCoords[6])));
 258         double maxY = Math.max(dstCoords[1], Math.max(dstCoords[3], Math.max(dstCoords[5], dstCoords[7])));
 259 
 260         minX = Math.round(minX);
 261         minY = Math.round(minY);
 262         maxX = Math.round(maxX);
 263         maxY = Math.round(maxY);
 264 
 265         compositeBounds.x = (int) minX;
 266         compositeBounds.y = (int) minY;
 267         compositeBounds.width = (int) (maxX - minX);
 268         compositeBounds.height = (int) (maxY - minY);
 269 
 270         boolean is0or180 = (dstCoords[1] == dstCoords[3]) && (dstCoords[2] == dstCoords[4]);
 271         boolean is90or270 = (dstCoords[0] == dstCoords[2]) && (dstCoords[3] == dstCoords[5]);
 272         
 273         return is0or180 || is90or270;
 274     }
 275 
 276     public void Transform(SurfaceData src, SurfaceData dst, Composite comp, Region clip, AffineTransform xform, 
 277             int hint, int srcx, int srcy, int dstx, int dsty, int width, int height) {
 278         try {
 279             SunToolkit.awtLock();
 280 
 281             XRSurfaceData x11sdDst = (XRSurfaceData) dst;
 282             XRSurfaceData x11sdSrc = (XRSurfaceData) src;
 283             
 284             int filter = XRUtils.ATransOpToXRQuality(hint);
 285             boolean isAxisAligned = adjustCompositeBounds(xform, dstx, dsty, width, height);
 286             

 287             x11sdDst.validateAsDestination(null, clip);

 288             x11sdDst.maskBuffer.validateCompositeState(comp, null, null, null);
 289 
 290             AffineTransform trx = AffineTransform.getTranslateInstance(-compositeBounds.x, -compositeBounds.y);


 291             trx.concatenate(xform);
 292             AffineTransform maskTX = (AffineTransform) trx.clone();

 293             trx.translate(-srcx, -srcy);
 294 
 295             try {
 296                 trx.invert();
 297             } catch (NoninvertibleTransformException ex) {
 298                 trx.setToIdentity();

 299             }
 300 
 301             boolean omitMask = (filter == XRUtils.FAST) 
 302                     || (isAxisAligned && ((AlphaComposite) comp).getAlpha() == 1.0f);
 303 
 304             if (!omitMask) {
 305                 XRMaskImage mask = x11sdSrc.maskBuffer.getMaskImage();
 306 
 307                 x11sdSrc.validateAsSource(trx, XRUtils.RepeatPad, filter);
 308                 int maskPicture = mask.prepareBlitMask(x11sdDst, maskTX, width, height);
 309                 x11sdDst.maskBuffer.con.renderComposite(XRCompositeManager.getInstance(x11sdSrc).getCompRule(), x11sdSrc.picture, maskPicture, x11sdDst.picture,
 310                         0, 0, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
 311             } else {
 312                 int repeat = filter == XRUtils.FAST ? XRUtils.RepeatNone : XRUtils.RepeatPad;
 313 
 314                 x11sdSrc.validateAsSource(trx, repeat, filter);
 315                 x11sdDst.maskBuffer.compositeBlit(x11sdSrc, x11sdDst, 0, 0, compositeBounds.x, compositeBounds.y, compositeBounds.width, compositeBounds.height);
 316             }
 317         } finally {
 318             SunToolkit.awtUnlock();
 319         }
















 320     }
 321 }
 322 
 323 class XrSwToPMBlit extends Blit {
 324     Blit pmToSurfaceBlit;
 325 
 326     XrSwToPMBlit(SurfaceType srcType, SurfaceType dstType) {
 327         super(srcType, CompositeType.AnyAlpha, dstType);
 328         pmToSurfaceBlit = new XRPMBlit(dstType, dstType);
 329     }
 330 
 331     public void Blit(SurfaceData src, SurfaceData dst, Composite comp, Region clip, int sx, int sy, int dx, int dy, int w, int h) {
 332         /*
 333          * If the blit is write-only (putimge), no need for a temporary VI.
 334          */
 335         if (CompositeType.SrcOverNoEa.equals(comp) && (src.getTransparency() == Transparency.OPAQUE)) {
 336             Blit opaqueSwToSurfaceBlit = Blit.getFromCache(src.getSurfaceType(), CompositeType.SrcNoEa, dst.getSurfaceType());
 337             opaqueSwToSurfaceBlit.Blit(src, dst, comp, clip, sx, sy, dx, dy, w, h);
 338         } else {
 339             try {