mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-28 00:00:03 -04:00
TMI-106, TMI-118: PICT JDK 8 fix + cleanup
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
/**
|
||||
* BitMap.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: BitMap.java,v 1.0 20/02/15 harald.kuhr Exp$
|
||||
*/
|
||||
final class BitMap {
|
||||
}
|
||||
+80
-13
@@ -29,10 +29,9 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* BitMapPattern
|
||||
@@ -43,22 +42,46 @@ import java.awt.image.Raster;
|
||||
*/
|
||||
final class BitMapPattern extends Pattern {
|
||||
|
||||
private final byte[] pattern;
|
||||
|
||||
BitMapPattern(final Paint pColor) {
|
||||
super(pColor);
|
||||
this(pColor, null);
|
||||
}
|
||||
|
||||
public BitMapPattern(final byte[] pPattern) {
|
||||
this(create8x8Pattern(pPattern));
|
||||
this(create8x8Pattern(pPattern), pPattern);
|
||||
}
|
||||
|
||||
private BitMapPattern(final Paint pColor, final byte[] pPattern) {
|
||||
super(pColor);
|
||||
|
||||
pattern = pPattern;
|
||||
}
|
||||
|
||||
// TODO: Refactor, don't need both BitMapPattern constructors and create8x8Pattern methods?
|
||||
public BitMapPattern(final byte[] pPattern, Color fg, Color bg) {
|
||||
this(create8x8Pattern(pPattern, fg, bg));
|
||||
}
|
||||
|
||||
BitMapPattern(final int pPattern) {
|
||||
this(create8x8Pattern(pPattern));
|
||||
}
|
||||
|
||||
private static TexturePaint create8x8Pattern(final int pPattern) {
|
||||
// TODO: Creating a special purpose Pattern might be faster than piggy-backing on TexturePaint
|
||||
WritableRaster raster = QuickDraw.MONOCHROME.createCompatibleWritableRaster(8, 8);
|
||||
byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
|
||||
private static Paint create8x8Pattern(final int pPattern) {
|
||||
// // TODO: Creating a special purpose Pattern might be faster than piggy-backing on TexturePaint
|
||||
// WritableRaster raster = QuickDraw.MONOCHROME.createCompatibleWritableRaster(8, 8);
|
||||
// byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
|
||||
//
|
||||
// for (int i = 0; i < data.length; i += 4) {
|
||||
// data[i ] = (byte) ((pPattern >> 24) & 0xFF);
|
||||
// data[i + 1] = (byte) ((pPattern >> 16) & 0xFF);
|
||||
// data[i + 2] = (byte) ((pPattern >> 8) & 0xFF);
|
||||
// data[i + 3] = (byte) ((pPattern ) & 0xFF);
|
||||
// }
|
||||
//
|
||||
// BufferedImage img = new BufferedImage(QuickDraw.MONOCHROME, raster, false, null);
|
||||
// return new TexturePaint(img, new Rectangle(8, 8));
|
||||
byte[] data = new byte[8];
|
||||
|
||||
for (int i = 0; i < data.length; i += 4) {
|
||||
data[i ] = (byte) ((pPattern >> 24) & 0xFF);
|
||||
@@ -67,13 +90,57 @@ final class BitMapPattern extends Pattern {
|
||||
data[i + 3] = (byte) ((pPattern ) & 0xFF);
|
||||
}
|
||||
|
||||
BufferedImage img = new BufferedImage(QuickDraw.MONOCHROME, raster, false, null);
|
||||
return new TexturePaint(img, new Rectangle(8, 8));
|
||||
return create8x8Pattern(data);
|
||||
}
|
||||
|
||||
private static TexturePaint create8x8Pattern(final byte[] pPattern) {
|
||||
private static Paint create8x8Pattern(final byte[] pPattern) {
|
||||
WritableRaster raster = Raster.createPackedRaster(new DataBufferByte(pPattern, 8), 8, 8, 1, new Point());
|
||||
BufferedImage img = new BufferedImage(QuickDraw.MONOCHROME, raster, false, null);
|
||||
return new TexturePaint(img, new Rectangle(8, 8));
|
||||
}
|
||||
|
||||
private static Paint create8x8Pattern(final byte[] pPattern, Color fg, Color bg) {
|
||||
switch (isSolid(pPattern)) {
|
||||
case 0: // 0x00
|
||||
return bg;
|
||||
case -1: // 0xff
|
||||
return fg;
|
||||
default:
|
||||
// Fall through
|
||||
}
|
||||
|
||||
WritableRaster raster = Raster.createPackedRaster(new DataBufferByte(pPattern, 8), 8, 8, 1, new Point());
|
||||
IndexColorModel cm = new IndexColorModel(1, 2, new int[] {bg.getRGB(), fg.getRGB()}, 0, false, -1, DataBuffer.TYPE_BYTE);
|
||||
BufferedImage img = new BufferedImage(cm, raster, false, null);
|
||||
return new TexturePaint(img, new Rectangle(8, 8));
|
||||
}
|
||||
|
||||
private static int isSolid(byte[] pPattern) {
|
||||
int prev = pPattern[0];
|
||||
|
||||
for (int i = 1; i < pPattern.length; i++) {
|
||||
if (prev != pPattern[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaintContext createContext(ColorModel pModel, Rectangle pDeviceBounds, Rectangle2D pUserBounds, AffineTransform pTransform, RenderingHints pHints) {
|
||||
// switch (isSolid(pattern)) {
|
||||
// }
|
||||
return super.createContext(pModel, pDeviceBounds, pUserBounds, pTransform, pHints);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern derive(final Color foreground, final Color background) {
|
||||
if (paint instanceof Color) {
|
||||
// TODO: This only holds for patterns that are already foregrounds...
|
||||
return new BitMapPattern(foreground);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,4 +175,41 @@ interface PICT {
|
||||
int OP_UNCOMPRESSED_QUICKTIME = 0x8201;
|
||||
|
||||
String APPLE_USE_RESERVED_FIELD = "Reserved for Apple use.";
|
||||
|
||||
/*
|
||||
* Picture comment 'kind' codes from: http://developer.apple.com/technotes/qd/qd_10.html
|
||||
int TextBegin = 150;
|
||||
int TextEnd = 151;
|
||||
int StringBegin = 152;
|
||||
int StringEnd = 153;
|
||||
int TextCenter = 154;
|
||||
int LineLayoutOff = 155;
|
||||
int LineLayoutOn = 156;
|
||||
int ClientLineLayout = 157;
|
||||
int PolyBegin = 160;
|
||||
int PolyEnd = 161;
|
||||
int PolyIgnore = 163;
|
||||
int PolySmooth = 164;
|
||||
int PolyClose = 165;
|
||||
int DashedLine = 180;
|
||||
int DashedStop = 181;
|
||||
int SetLineWidth = 182;
|
||||
int PostScriptBegin = 190;
|
||||
int PostScriptEnd = 191;
|
||||
int PostScriptHandle = 192;
|
||||
int PostScriptFile = 193;
|
||||
int TextIsPostScript = 194;
|
||||
int ResourcePS = 195;
|
||||
int PSBeginNoSave = 196;
|
||||
int SetGrayLevel = 197;
|
||||
int RotateBegin = 200;
|
||||
int RotateEnd = 201;
|
||||
int RotateCenter = 202;
|
||||
int FormsPrinting = 210;
|
||||
int EndFormsPrinting = 211;
|
||||
int ICC_Profile = 224;
|
||||
int Photoshop_Data = 498;
|
||||
int BitMapThinningOff = 1000;
|
||||
int BitMapThinningOn = 1001;
|
||||
*/
|
||||
}
|
||||
|
||||
+286
-546
File diff suppressed because it is too large
Load Diff
+8
-2
@@ -34,8 +34,8 @@ import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public class PICTImageReaderSpi extends ImageReaderSpi {
|
||||
else {
|
||||
// Skip header 512 bytes for file-based streams
|
||||
stream.reset();
|
||||
PICTImageReader.skipNullHeader(stream);
|
||||
skipNullHeader(stream);
|
||||
}
|
||||
|
||||
return isPICT(stream);
|
||||
@@ -98,6 +98,12 @@ public class PICTImageReaderSpi extends ImageReaderSpi {
|
||||
}
|
||||
}
|
||||
|
||||
static void skipNullHeader(final ImageInputStream pStream) throws IOException {
|
||||
// NOTE: Only skip if FILE FORMAT, not needed for Mac OS DnD
|
||||
// Spec says "platofrm dependent", may not be all nulls..
|
||||
pStream.skipBytes(PICT.PICT_NULL_HEADER_SIZE);
|
||||
}
|
||||
|
||||
private boolean isPICT(final ImageInputStream pStream) throws IOException {
|
||||
// Size may be 0, so we can't use this for validation...
|
||||
pStream.readUnsignedShort();
|
||||
|
||||
+1
-1
@@ -258,7 +258,7 @@ public class PICTImageWriter extends ImageWriterBase {
|
||||
// Treat the scanline.
|
||||
for (int j = 0; j < w; j++) {
|
||||
if (model instanceof ComponentColorModel && model.getColorSpace().getType() == ColorSpace.TYPE_RGB) {
|
||||
// NOTE: Assumes component order always (A)BGR
|
||||
// NOTE: Assumes component order always (A)BGR and sRGB
|
||||
// TODO: Alpha support
|
||||
scanlineBytes[x + j] = pixels[off + i * scansize * components + components * j + components - 1];
|
||||
scanlineBytes[x + w + j] = pixels[off + i * scansize * components + components * j + components - 2];
|
||||
|
||||
+23
-15
@@ -34,7 +34,8 @@ import java.awt.image.DataBuffer;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
/**
|
||||
* PICTUtil
|
||||
@@ -47,15 +48,14 @@ final class PICTUtil {
|
||||
|
||||
private static final String ENC_MAC_ROMAN = "MacRoman";
|
||||
|
||||
public static final String ENCODING = initEncoding();
|
||||
public static final Charset ENCODING = initEncoding();
|
||||
|
||||
private static String initEncoding() {
|
||||
private static Charset initEncoding() {
|
||||
try {
|
||||
new String("\uF8FF".getBytes(), ENC_MAC_ROMAN);
|
||||
return ENC_MAC_ROMAN;
|
||||
return Charset.forName(ENC_MAC_ROMAN);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
return "ISO-8859-1";
|
||||
catch (UnsupportedCharsetException e) {
|
||||
return Charset.forName("ISO-8859-1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,9 +86,9 @@ final class PICTUtil {
|
||||
* @throws java.io.IOException if an I/O error occurs during read
|
||||
*/
|
||||
public static Dimension readDimension(final DataInput pStream) throws IOException {
|
||||
final int h = pStream.readShort() ;
|
||||
final int v = pStream.readShort() ;
|
||||
return new Dimension(h,v);
|
||||
int h = pStream.readShort();
|
||||
int v = pStream.readShort();
|
||||
return new Dimension(h, v);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,8 +102,8 @@ final class PICTUtil {
|
||||
* @throws IOException if an I/O exception occurs during reading
|
||||
*/
|
||||
public static String readStr31(final DataInput pStream) throws IOException {
|
||||
String text = readPascalString(pStream);
|
||||
int length = 31 - text.length();
|
||||
String text = readPascalString(pStream);
|
||||
int length = 31 - text.length();
|
||||
if (length < 0) {
|
||||
throw new IOException("String length exceeds maximum (31): " + text.length());
|
||||
}
|
||||
@@ -112,7 +112,7 @@ final class PICTUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a Pascal String from the given strean.
|
||||
* Reads a Pascal String from the given stream.
|
||||
* The input stream must be positioned at the length byte of the text,
|
||||
* which can thus be a maximum of 255 characters long.
|
||||
*
|
||||
@@ -146,6 +146,14 @@ final class PICTUtil {
|
||||
return new BitMapPattern(data);
|
||||
}
|
||||
|
||||
// TODO: Refactor, don't need both readPattern methods
|
||||
public static Pattern readPattern(final DataInput pStream, final Color fg, final Color bg) throws IOException {
|
||||
// Get the data (8 bytes)
|
||||
byte[] data = new byte[8];
|
||||
pStream.readFully(data);
|
||||
return new BitMapPattern(data, fg, bg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a variable width {@link Pattern color pattern} from the given stream
|
||||
*
|
||||
@@ -221,7 +229,7 @@ final class PICTUtil {
|
||||
/**
|
||||
* Reads a {@code ColorTable} data structure from the given stream.
|
||||
*
|
||||
* @param pStream the input stream
|
||||
* @param pStream the input stream
|
||||
* @param pPixelSize the pixel size
|
||||
* @return the indexed color model created from the {@code ColorSpec} records read.
|
||||
*
|
||||
@@ -252,7 +260,7 @@ final class PICTUtil {
|
||||
|
||||
int[] colors = new int[size];
|
||||
|
||||
for (int i = 0; i < size ; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
// Read ColorSpec records
|
||||
int index = pStream.readUnsignedShort();
|
||||
Color color = readRGBColor(pStream);
|
||||
|
||||
+6
-4
@@ -29,9 +29,9 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ import java.util.Collections;
|
||||
* @version $Id: Pattern.java,v 1.0 Oct 9, 2007 1:21:38 AM haraldk Exp$
|
||||
*/
|
||||
abstract class Pattern implements Paint {
|
||||
private final Paint paint;
|
||||
protected final Paint paint;
|
||||
|
||||
Pattern(final Paint pPaint) {
|
||||
paint = pPaint;
|
||||
@@ -60,5 +60,7 @@ abstract class Pattern implements Paint {
|
||||
|
||||
public int getTransparency() {
|
||||
return paint.getTransparency();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Pattern derive(Color foreground, Color background);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.twelvemonkeys.imageio.plugins.pict;
|
||||
|
||||
/**
|
||||
* PixMap.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: harald.kuhr$
|
||||
* @version $Id: PixMap.java,v 1.0 20/02/15 harald.kuhr Exp$
|
||||
*/
|
||||
final class PixMap {
|
||||
}
|
||||
+6
-1
@@ -48,7 +48,12 @@ final class PixMapPattern extends Pattern {
|
||||
/**
|
||||
* @return the fallback B/W pattern
|
||||
*/
|
||||
public Pattern getPattern() {
|
||||
public Pattern getFallbackPattern() {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern derive(final Color foreground, final Color background) {
|
||||
return getFallbackPattern().derive(foreground, background);
|
||||
}
|
||||
}
|
||||
|
||||
+116
-20
@@ -31,8 +31,11 @@ package com.twelvemonkeys.imageio.plugins.pict;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
/**
|
||||
* Emulates an Apple QuickDraw rendering context, backed by a Java {@link Graphics2D}.
|
||||
@@ -121,9 +124,20 @@ class QuickDrawContext {
|
||||
private Dimension2D penSize = new Dimension();
|
||||
private int penMode;
|
||||
|
||||
QuickDrawContext(Graphics2D pGraphics) {
|
||||
// TODO: Make sure setting bgColor/fgColor does not reset pattern, and pattern not resetting bg/fg!
|
||||
private Color bgColor = Color.WHITE;
|
||||
private Color fgColor = Color.BLACK;
|
||||
|
||||
private int textMode;
|
||||
private Pattern textPattern = new BitMapPattern(Color.BLACK);
|
||||
private Pattern fillPattern;
|
||||
|
||||
QuickDrawContext(final Graphics2D pGraphics) {
|
||||
graphics = Validate.notNull(pGraphics, "graphics");
|
||||
|
||||
|
||||
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
setPenNormal();
|
||||
}
|
||||
|
||||
@@ -144,18 +158,34 @@ class QuickDrawContext {
|
||||
// Font number (sic), integer
|
||||
void setTextFont(int fontFamily) {
|
||||
// ..?
|
||||
System.err.println("QuickDrawContext.setTextFont");
|
||||
System.err.println("QuickDrawContext.setTextFont: " + fontFamily);
|
||||
}
|
||||
|
||||
public void setTextFont(final String fontName) {
|
||||
// TODO: Need mapping between known QD font names and Java font names?
|
||||
Font current = graphics.getFont();
|
||||
graphics.setFont(Font.decode(fontName).deriveFont(current.getStyle(), (float) current.getSize()));
|
||||
}
|
||||
|
||||
// Sets the text's font style (0..255)
|
||||
void setTextFace(int face) {
|
||||
// int?
|
||||
System.err.println("QuickDrawContext.setTextFace");
|
||||
void setTextFace(final int face) {
|
||||
int style = 0;
|
||||
if ((face & QuickDraw.TX_BOLD_MASK) > 0) {
|
||||
style |= Font.BOLD;
|
||||
}
|
||||
if ((face & QuickDraw.TX_ITALIC_MASK) > 0) {
|
||||
style |= Font.ITALIC;
|
||||
}
|
||||
|
||||
// TODO: Other face options, like underline, shadow, etc...
|
||||
|
||||
graphics.setFont(graphics.getFont().deriveFont(style));
|
||||
}
|
||||
|
||||
void setTextMode(int pSourceMode) {
|
||||
// ..?
|
||||
System.err.println("QuickDrawContext.setTextMode");
|
||||
textMode = pSourceMode;
|
||||
}
|
||||
|
||||
public void setTextSize(int pSize) {
|
||||
@@ -175,15 +205,24 @@ class QuickDrawContext {
|
||||
graphics.translate(pOrigin.getX(), pOrigin.getY());
|
||||
}
|
||||
|
||||
public void setForeground(Color pColor) {
|
||||
// TODO: Is this really correct? Or does it depend on pattern mode?
|
||||
public void setForeground(final Color pColor) {
|
||||
fgColor = pColor;
|
||||
penPattern = new BitMapPattern(pColor);
|
||||
}
|
||||
|
||||
public void setBackground(Color pColor) {
|
||||
Color getForeground() {
|
||||
return fgColor;
|
||||
}
|
||||
|
||||
public void setBackground(final Color pColor) {
|
||||
bgColor = pColor;
|
||||
background = new BitMapPattern(pColor);
|
||||
}
|
||||
|
||||
Color getBackground() {
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
/*
|
||||
// Pen management:
|
||||
// NOTE: The HidePen procedure is called by the OpenRgn, OpenPicture, and OpenPoly routines so that you can create regions, pictures, and polygons without drawing on the screen.
|
||||
@@ -306,10 +345,14 @@ class QuickDrawContext {
|
||||
BackPat // Used by the Erase* methods
|
||||
*BackPixPat
|
||||
*/
|
||||
public void setBackgroundPattern(Pattern pPaint) {
|
||||
public void setBackgroundPattern(final Pattern pPaint) {
|
||||
background = pPaint;
|
||||
}
|
||||
|
||||
public void setFillPattern(final Pattern fillPattern) {
|
||||
this.fillPattern = fillPattern;
|
||||
}
|
||||
|
||||
private Composite getCompositeFor(final int pMode) {
|
||||
switch (pMode & ~QuickDraw.DITHER_COPY) {
|
||||
// Boolean source transfer modes
|
||||
@@ -321,9 +364,10 @@ class QuickDrawContext {
|
||||
return AlphaComposite.Xor;
|
||||
case QuickDraw.SRC_BIC:
|
||||
return AlphaComposite.Clear;
|
||||
case QuickDraw.NOT_SRC_XOR:
|
||||
return new NotSrcXor();
|
||||
case QuickDraw.NOT_SRC_COPY:
|
||||
case QuickDraw.NOT_SRC_OR:
|
||||
case QuickDraw.NOT_SRC_XOR:
|
||||
case QuickDraw.NOT_SRC_BIC:
|
||||
throw new UnsupportedOperationException("Not implemented for mode " + pMode);
|
||||
// return null;
|
||||
@@ -349,6 +393,15 @@ class QuickDrawContext {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up context for text drawing.
|
||||
*/
|
||||
protected void setupForText() {
|
||||
graphics.setPaint(textPattern);
|
||||
graphics.setComposite(getCompositeFor(textMode));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets up context for line drawing/painting.
|
||||
*/
|
||||
@@ -415,9 +468,7 @@ class QuickDrawContext {
|
||||
|
||||
if (isPenVisible()) {
|
||||
// NOTE: Workaround for known Mac JDK bug: Paint, not frame
|
||||
//graphics.setStroke(getStroke(penSize)); // Make sure we have correct stroke
|
||||
paintShape(graphics.getStroke().createStrokedShape(line));
|
||||
|
||||
}
|
||||
|
||||
moveTo(pX, pY);
|
||||
@@ -811,13 +862,18 @@ class QuickDrawContext {
|
||||
|
||||
// TODO: All other operations can delegate to these! :-)
|
||||
private void frameShape(final Shape pShape) {
|
||||
setupForPaint();
|
||||
graphics.draw(pShape);
|
||||
if (isPenVisible()) {
|
||||
setupForPaint();
|
||||
|
||||
Stroke stroke = getStroke(penSize);
|
||||
Shape shape = stroke.createStrokedShape(pShape);
|
||||
graphics.draw(shape);
|
||||
}
|
||||
}
|
||||
|
||||
private void paintShape(final Shape pShape) {
|
||||
setupForPaint();
|
||||
graphics.fill(pShape);
|
||||
graphics.fill(pShape); // Yes, fill
|
||||
}
|
||||
|
||||
private void fillShape(final Shape pShape, final Pattern pPattern) {
|
||||
@@ -878,20 +934,22 @@ class QuickDrawContext {
|
||||
pSrcRect.y + pSrcRect.height,
|
||||
null
|
||||
);
|
||||
|
||||
setClipRegion(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* CopyMask
|
||||
*/
|
||||
public void copyMask(BufferedImage pSrcBitmap, BufferedImage pMaskBitmap, Rectangle pSrcRect, Rectangle pMaskRect, Rectangle pDstRect, int pSrcCopy, Shape pMaskRgn) {
|
||||
throw new UnsupportedOperationException("Method copyBits not implemented"); // TODO: Implement
|
||||
throw new UnsupportedOperationException("Method copyMask not implemented"); // TODO: Implement
|
||||
}
|
||||
|
||||
/**
|
||||
* CopyDeepMask -- available to basic QuickDraw only in System 7, combines the functionality of both CopyBits and CopyMask
|
||||
*/
|
||||
public void copyDeepMask(BufferedImage pSrcBitmap, BufferedImage pMaskBitmap, Rectangle pSrcRect, Rectangle pMaskRect, Rectangle pDstRect, int pSrcCopy, Shape pMaskRgn) {
|
||||
throw new UnsupportedOperationException("Method copyBits not implemented"); // TODO: Implement
|
||||
throw new UnsupportedOperationException("Method copyDeepMask not implemented"); // TODO: Implement
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -926,7 +984,8 @@ class QuickDrawContext {
|
||||
* @param pString a Pascal string (a string of length less than or equal to 255 chars).
|
||||
*/
|
||||
public void drawString(String pString) {
|
||||
graphics.drawString(pString, (float) getPenPosition().getX(), (float) getPenPosition().getY());
|
||||
setupForText();
|
||||
graphics.drawString(pString, (float) getPenPosition().getX(), (float) getPenPosition().getY());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1049,4 +1108,41 @@ class QuickDrawContext {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class NotSrcXor implements Composite {
|
||||
// TODO: Src can probably be any color model that can be encoded in PICT, dst is always RGB/TYPE_INT
|
||||
public CompositeContext createContext(final ColorModel srcColorModel, final ColorModel dstColorModel, RenderingHints hints) {
|
||||
{
|
||||
if (!srcColorModel.getColorSpace().isCS_sRGB() || !dstColorModel.getColorSpace().isCS_sRGB()) {
|
||||
throw new IllegalArgumentException("Only sRGB supported");
|
||||
}
|
||||
}
|
||||
|
||||
return new CompositeContext() {
|
||||
public void dispose() {
|
||||
|
||||
}
|
||||
|
||||
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
|
||||
// We always work in RGB, using DataBuffer.TYPE_INT transfer type.
|
||||
int[] srcData = null;
|
||||
int[] dstData = null;
|
||||
int[] resData = new int[src.getWidth() - src.getMinX()];
|
||||
|
||||
for (int y = src.getMinY(); y < src.getHeight(); y++) {
|
||||
srcData = (int[]) src.getDataElements(src.getMinX(), y, src.getWidth(), 1, srcData);
|
||||
dstData = (int[]) dstIn.getDataElements(src.getMinX(), y, src.getWidth(), 1, dstData);
|
||||
|
||||
for (int x = src.getMinX(); x < src.getWidth(); x++) {
|
||||
// TODO: Decide how to handle alpha (if at all)
|
||||
resData[x] = 0xff000000 | ((~ srcData[x] ^ dstData[x])) & 0xffffff ;
|
||||
// resData[x] = ~ srcData[x] ^ dstData[x];
|
||||
}
|
||||
|
||||
dstOut.setDataElements(src.getMinX(), y, src.getWidth(), 1, resData);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user