/* * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.java2d.pipe; import java.lang.ref.WeakReference;import java.awt.Rectangle;import java.awt.Shape;import java.awt.PaintContext;import java.awt.Transparency;import java.awt.image.ColorModel;import java.awt.image.Raster;import java.awt.image.WritableRaster;import java.awt.image.BufferedImage;import sun.awt.image.BufImgSurfaceData;import sun.java2d.SunGraphics2D;import sun.java2d.SurfaceData;import sun.java2d.loops.Blit;import sun.java2d.loops.MaskBlit;import sun.java2d.loops.CompositeType;import sun.java2d.loops.GraphicsPrimitiveMgr; /** * This class implements a CompositePipe that renders path alpha tiles * into a destination according to the Composite attribute of a * SunGraphics2D. */public class AlphaPaintPipe implements CompositePipe { static WeakReference cachedLastRaster; static WeakReference cachedLastColorModel; static WeakReference cachedLastData; static class TileContext { SunGraphics2D sunG2D; PaintContext paintCtxt; ColorModel paintModel; WeakReference lastRaster; WeakReference lastData; MaskBlit lastMask; Blit lastBlit; SurfaceData dstData; public TileContext(SunGraphics2D sg, PaintContext pc) { sunG2D = sg; paintCtxt = pc; paintModel = pc.getColorModel(); dstData = sg.getSurfaceData(); synchronized (AlphaPaintPipe.class) { if (cachedLastColorModel != null && cachedLastColorModel.get() == paintModel) { this.lastRaster = cachedLastRaster; this.lastData = cachedLastData; } } } } public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR, int[] abox) { PaintContext paintContext = sg.paint.createContext(sg.getDeviceColorModel(), devR, s.getBounds2D(), sg.cloneTransform(), sg.getRenderingHints()); return new TileContext(sg, paintContext); } public boolean needTile(Object context, int x, int y, int w, int h) { return true; } private static final int TILE_SIZE = 32; public void renderPathTile(Object ctx, byte[] atile, int offset, int tilesize, int x, int y, int w, int h) { TileContext context = (TileContext) ctx; PaintContext paintCtxt = context.paintCtxt; SunGraphics2D sg = context.sunG2D; SurfaceData dstData = context.dstData; SurfaceData srcData = null; Raster lastRas = null; if (context.lastData != null && context.lastRaster != null) { srcData = (SurfaceData) context.lastData.get(); lastRas = (Raster) context.lastRaster.get(); if (srcData == null || lastRas == null) { srcData = null; lastRas = null; } } ColorModel paintModel = context.paintModel; for (int rely = 0; rely < h; rely += TILE_SIZE) { int ty = y + rely; int th = Math.min(h-rely, TILE_SIZE); for (int relx = 0; relx < w; relx += TILE_SIZE) { int tx = x + relx; int tw = Math.min(w-relx, TILE_SIZE); Raster srcRaster = paintCtxt.getRaster(tx, ty, tw, th); if ((srcRaster.getMinX() != 0) || (srcRaster.getMinY() != 0)) { srcRaster = srcRaster.createTranslatedChild(0, 0); } if (lastRas != srcRaster) { lastRas = srcRaster; context.lastRaster = new WeakReference(lastRas); // REMIND: This will fail for a non-Writable raster! BufferedImage bImg = new BufferedImage(paintModel, (WritableRaster) srcRaster, paintModel.isAlphaPremultiplied(), null); srcData = BufImgSurfaceData.createData(bImg); context.lastData = new WeakReference(srcData); context.lastMask = null; context.lastBlit = null; } if (atile == null) { if (context.lastBlit == null) { CompositeType comptype = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comptype) && paintModel.getTransparency() == Transparency.OPAQUE) { comptype = CompositeType.SrcNoEa; } context.lastBlit = Blit.getFromCache(srcData.getSurfaceType(), comptype, dstData.getSurfaceType()); } context.lastBlit.Blit(srcData, dstData, sg.composite, null, 0, 0, tx, ty, tw, th); } else { if (context.lastMask == null) { CompositeType comptype = sg.imageComp; if (CompositeType.SrcOverNoEa.equals(comptype) && paintModel.getTransparency() == Transparency.OPAQUE) { comptype = CompositeType.SrcNoEa; } context.lastMask = MaskBlit.getFromCache(srcData.getSurfaceType(), comptype, dstData.getSurfaceType()); } int toff = offset + rely * tilesize + relx; context.lastMask.MaskBlit(srcData, dstData, sg.composite, null, 0, 0, tx, ty, tw, th, atile, toff, tilesize); } } } } public void skipTile(Object context, int x, int y) { return; } public void endSequence(Object ctx) { TileContext context = (TileContext) ctx; if (context.paintCtxt != null) { context.paintCtxt.dispose(); } synchronized (AlphaPaintPipe.class) { if (context.lastData != null) { cachedLastRaster = context.lastRaster; if (cachedLastColorModel == null || cachedLastColorModel.get() != context.paintModel) { // Avoid creating new WeakReference if possible cachedLastColorModel = new WeakReference(context.paintModel); } cachedLastData = context.lastData; } } }}
/*
* Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.java2d.pipe;
import java.lang.ref.WeakReference;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.PaintContext;
import java.awt.Transparency;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.BufferedImage;
import sun.awt.image.BufImgSurfaceData;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.java2d.loops.Blit;
import sun.java2d.loops.MaskBlit;
import sun.java2d.loops.CompositeType;
import sun.java2d.loops.GraphicsPrimitiveMgr;
/**
* This class implements a CompositePipe that renders path alpha tiles
* into a destination according to the Composite attribute of a
* SunGraphics2D.
*/
public class AlphaPaintPipe implements CompositePipe {
static WeakReference cachedLastRaster;
static WeakReference cachedLastColorModel;
static WeakReference cachedLastData;
static class TileContext {
SunGraphics2D sunG2D;
PaintContext paintCtxt;
ColorModel paintModel;
WeakReference lastRaster;
WeakReference lastData;
MaskBlit lastMask;
Blit lastBlit;
SurfaceData dstData;
public TileContext(SunGraphics2D sg, PaintContext pc) {
sunG2D = sg;
paintCtxt = pc;
paintModel = pc.getColorModel();
dstData = sg.getSurfaceData();
synchronized (AlphaPaintPipe.class) {
if (cachedLastColorModel != null &&
cachedLastColorModel.get() == paintModel)
{
this.lastRaster = cachedLastRaster;
this.lastData = cachedLastData;
}
}
}
}
public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,
int[] abox) {
PaintContext paintContext =
sg.paint.createContext(sg.getDeviceColorModel(),
devR,
s.getBounds2D(),
sg.cloneTransform(),
sg.getRenderingHints());
return new TileContext(sg, paintContext);
}
public boolean needTile(Object context, int x, int y, int w, int h) {
return true;
}
private static final int TILE_SIZE = 32;
public void renderPathTile(Object ctx,
byte[] atile, int offset, int tilesize,
int x, int y, int w, int h) {
TileContext context = (TileContext) ctx;
PaintContext paintCtxt = context.paintCtxt;
SunGraphics2D sg = context.sunG2D;
SurfaceData dstData = context.dstData;
SurfaceData srcData = null;
Raster lastRas = null;
if (context.lastData != null && context.lastRaster != null) {
srcData = (SurfaceData) context.lastData.get();
lastRas = (Raster) context.lastRaster.get();
if (srcData == null || lastRas == null) {
srcData = null;
lastRas = null;
}
}
ColorModel paintModel = context.paintModel;
for (int rely = 0; rely < h; rely += TILE_SIZE) {
int ty = y + rely;
int th = Math.min(h-rely, TILE_SIZE);
for (int relx = 0; relx < w; relx += TILE_SIZE) {
int tx = x + relx;
int tw = Math.min(w-relx, TILE_SIZE);
Raster srcRaster = paintCtxt.getRaster(tx, ty, tw, th);
if ((srcRaster.getMinX() != 0) || (srcRaster.getMinY() != 0)) {
srcRaster = srcRaster.createTranslatedChild(0, 0);
}
if (lastRas != srcRaster) {
lastRas = srcRaster;
context.lastRaster = new WeakReference(lastRas);
// REMIND: This will fail for a non-Writable raster!
BufferedImage bImg =
new BufferedImage(paintModel,
(WritableRaster) srcRaster,
paintModel.isAlphaPremultiplied(),
null);
srcData = BufImgSurfaceData.createData(bImg);
context.lastData = new WeakReference(srcData);
context.lastMask = null;
context.lastBlit = null;
}
if (atile == null) {
if (context.lastBlit == null) {
CompositeType comptype = sg.imageComp;
if (CompositeType.SrcOverNoEa.equals(comptype) &&
paintModel.getTransparency() == Transparency.OPAQUE)
{
comptype = CompositeType.SrcNoEa;
}
context.lastBlit =
Blit.getFromCache(srcData.getSurfaceType(),
comptype,
dstData.getSurfaceType());
}
context.lastBlit.Blit(srcData, dstData,
sg.composite, null,
0, 0, tx, ty, tw, th);
} else {
if (context.lastMask == null) {
CompositeType comptype = sg.imageComp;
if (CompositeType.SrcOverNoEa.equals(comptype) &&
paintModel.getTransparency() == Transparency.OPAQUE)
{
comptype = CompositeType.SrcNoEa;
}
context.lastMask =
MaskBlit.getFromCache(srcData.getSurfaceType(),
comptype,
dstData.getSurfaceType());
}
int toff = offset + rely * tilesize + relx;
context.lastMask.MaskBlit(srcData, dstData,
sg.composite, null,
0, 0, tx, ty, tw, th,
atile, toff, tilesize);
}
}
}
}
public void skipTile(Object context, int x, int y) {
return;
}
public void endSequence(Object ctx) {
TileContext context = (TileContext) ctx;
if (context.paintCtxt != null) {
context.paintCtxt.dispose();
}
synchronized (AlphaPaintPipe.class) {
if (context.lastData != null) {
cachedLastRaster = context.lastRaster;
if (cachedLastColorModel == null ||
cachedLastColorModel.get() != context.paintModel)
{
// Avoid creating new WeakReference if possible
cachedLastColorModel =
new WeakReference(context.paintModel);
}
cachedLastData = context.lastData;
}
}
}
}