com.actelion.research.gui.wmf.WMFGraphics Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.actelion.research.gui.wmf;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.awt.image.PixelGrabber;
import java.text.AttributedCharacterIterator;
public class WMFGraphics extends Graphics
{
public static final int MM_ANISOTROPIC = 8;
private static final int BS_NULL = WMFConstants.BS_NULL;
public static final int SRC_AND = WMFConstants.SRCAND;// 0x8800c6;
public static final int SRC_PAINT = WMFConstants.SRCPAINT;// 0xee0086;
public static final int SRC_COPY = WMFConstants.SRCCOPY;// 0xcc0020;
private MetaFile wmf;
private Color foreground;
private Color background;
private Font font;
private int penstyle;
private int penwidth;
private int brushfillstyle;
private int brushhatch;
private int fontescapement;
private Image brushpattern;
private int penhandle;
private int brushhandle;
private int fonthandle;
private Rectangle clip;
private Point origin;
private GraphicsState state;
public WMFGraphics(MetaFile w, int width, int height, Color fg, Color bg)
{
font = new Font("Helvetica", 0, 12);
penstyle = 0;
penwidth = 1;
brushfillstyle = 0;
brushhatch = 0;
fontescapement = 0;
brushpattern = null;
origin = new Point(0, 0);
foreground = fg;
background = bg;
state = new GraphicsState();
state.increaseCount();
setWMF(w, width, height);
reset();
}
public Color getBackground()
{
return background;
}
public void setBackground(Color background)
{
this.background = background;
}
WMFGraphics(
MetaFile w, GraphicsState graphicsstate, Color fg, Color bg, Font font, int penstyle, int penwidth,
int brushFillStyle, int brushHatch, int fontEsc, Image image, Point origin, Rectangle rectangle)
{
this.font = new Font("Helvetica", 0, 12);
this.wmf = w;
this.state = graphicsstate;
graphicsstate.increaseCount();
this.foreground = fg;
this.background = bg;
this.font = font;
this.penstyle = penstyle;
this.penwidth = penwidth;
this.brushfillstyle = brushFillStyle;
this.brushhatch = brushHatch;
this.fontescapement = fontEsc;
this.brushpattern = image;
this.origin = new Point(origin.x, origin.y);
if (rectangle != null) {
clip = new Rectangle(rectangle);
}
createHandles();
setGDIPen();
setGDIHollowBrush();
setGDIFont();
}
public void GDIPolyPolygon(Polygon[] apolygon)
{
restore();
setGDIFillBrush();
wmf.polypolygon(apolygon);
setGDIHollowBrush();
}
@Override
public void clearRect(int i, int j, int k, int l)
{
restore();
Color color = foreground;
setColor(background);
fillRect(i, j, k, l);
setColor(color);
}
@Override
public void clipRect(int i, int j, int k, int l)
{
restore();
wmf.intersectClipRect(i, j, i + k + 1, j + l + 1);
Rectangle rectangle = new Rectangle(i, j, k, l);
if (clip != null) {
clip = clip.intersection(rectangle);
} else {
clip = rectangle;
}
state.setClip(clip);
}
@Override
public void copyArea(int i, int j, int k, int l, int i1, int j1)
{
System.err.println("copyArea not supported");
}
@Override
public Graphics create()
{
WMFGraphics wmfgraphics = new WMFGraphics(
wmf, state, foreground, background, font, penstyle, penwidth, brushfillstyle,
brushhatch, fontescapement, brushpattern, origin, clip);
return wmfgraphics;
}
public void createHandles()
{
penhandle = wmf.createPenIndirect(penstyle, penwidth, foreground);
wmf.selectObject(penhandle);
state.setPen(penhandle);
brushhandle = wmf.createBrushIndirect(BS_NULL, foreground, brushhatch);
wmf.selectObject(brushhandle);
state.setPen(brushhandle);
fonthandle = wmf.createFont(font, fontescapement, false, false);
wmf.selectObject(fonthandle);
state.setPen(fonthandle);
}
public void deleteHandles()
{
wmf.deleteObject(penhandle);
wmf.deleteObject(brushhandle);
wmf.deleteObject(fonthandle);
}
@Override
public void dispose()
{
state.decreaseCount();
}
@Override
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
{
restore();
int k1 = x + (width / 2);
int l1 = y + (height / 2);
wmf.arc(
x, y, x + width + 1, y + height + 1,
k1
+ (int) Math.round(
(double) width * Math.sin((2 * Math.PI * (double) (startAngle + 90)) / 360D)),
l1
+ (int) Math.round(
(double) height * Math.cos((2 * Math.PI * (double) (startAngle + 90)) / 360D)),
k1
+ (int) Math.round(
(double) width * Math.sin((2 * Math.PI * (double) (startAngle + arcAngle + 90)) / 360D)),
l1
+ (int) Math.round(
(double) height * Math.cos((2 * Math.PI * (double) (startAngle + arcAngle + 90)) / 360D)));
}
@Override
public boolean drawImage(
Image image, int leftD, int topD, int rightD, int bottomD, int leftS, int topS, int rightS, int bottomS, Color color,
ImageObserver imageobserver)
{
restore();
int imagewidth = image.getWidth(imageobserver);
int imageheight = image.getHeight(imageobserver);
int[] pixbuffer = new int[imagewidth * imageheight];
PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, imagewidth, imageheight, pixbuffer, 0, imagewidth);
try {
pixelgrabber.grabPixels();
} catch (InterruptedException _ex) {
return false;
}
if ((pixelgrabber.status() & 0x80) != 0) {
return false;
}
int diffx = rightD - leftD;
int diffy = bottomD - topD;
int sourcediffx = rightS - leftS;
int sourcediffy = bottomS - topS;
int k3 = bottomS;
bottomS = imageheight - topS;
topS = imageheight - k3;
if ((diffx < 0) != (sourcediffx < 0)) {
flipHorizontal(pixbuffer, imagewidth, imageheight);
if (sourcediffx < 0) {
leftS = imagewidth - leftS;
} else {
leftS = imagewidth - rightS;
}
}
if (diffx < 0) {
leftD = rightD;
if (sourcediffx < 0) {
leftS = rightS;
}
diffx = -diffx;
}
if (sourcediffx < 0) {
sourcediffx = -sourcediffx;
}
if ((diffy < 0) != (sourcediffy < 0)) {
flipVertical(pixbuffer, imagewidth, imageheight);
if (sourcediffy < 0) {
topS = imageheight - topS;
} else {
topS = imageheight - bottomS;
}
}
if (diffy < 0) {
topD = bottomD;
if (sourcediffy < 0) {
topS = bottomS;
}
diffy = -diffy;
}
if (sourcediffy < 0) {
sourcediffy = -sourcediffy;
}
int l3 = color.getRGB();
for (int i4 = 0; i4 < pixbuffer.length; i4++)
if ((pixbuffer[i4] & 0xff000000) == 0) {
pixbuffer[i4] = l3;
}
wmf.stretchBlt(leftD, topD, diffx, diffy, leftS, topS,
sourcediffx, sourcediffy, SRC_COPY, pixbuffer, imagewidth, imageheight);
return true;
}
@Override
public boolean drawImage(Image image,
int leftD, int topD, int rightD, int bottomD, int leftS, int topS, int rightS, int bottomS,
ImageObserver imageobserver)
{
restore();
int imagewidth = image.getWidth(imageobserver);
int imageheight = image.getHeight(imageobserver);
int[] pixarray = new int[imagewidth * imageheight];
PixelGrabber pixelgrabber = new PixelGrabber(image, 0, 0, imagewidth, imageheight, pixarray, 0, imagewidth);
try {
pixelgrabber.grabPixels();
} catch (InterruptedException _ex) {
return false;
}
if ((pixelgrabber.status() & 0x80) != 0) {
return false;
}
int ddiffx = rightD - leftD;
int ddiffy = bottomD - topD;
int sdiffx = rightS - leftS;
int sdiffy = bottomS - topS;
bottomS = imageheight - topS;
topS = imageheight - bottomS;
if ((ddiffx < 0) != (sdiffx < 0)) {
flipHorizontal(pixarray, imagewidth, imageheight);
if (sdiffx < 0) {
leftS = imagewidth - leftS;
} else {
leftS = imagewidth - rightS;
}
}
if (ddiffx < 0) {
leftD = rightD;
if (sdiffx < 0) {
leftS = rightS;
}
ddiffx = -ddiffx;
}
if (sdiffx < 0) {
sdiffx = -sdiffx;
}
if ((ddiffy < 0) != (sdiffy < 0)) {
flipVertical(pixarray, imagewidth, imageheight);
if (sdiffy < 0) {
topS = imageheight - topS;
} else {
topS = imageheight - bottomS;
}
}
if (ddiffy < 0) {
topD = bottomD;
if (sdiffy < 0) {
topS = bottomS;
}
ddiffy = -ddiffy;
}
if (sdiffy < 0) {
sdiffy = -sdiffy;
}
int[] ai1 = new int[pixarray.length];
boolean flag = false;
for (int l3 = 0; l3 < pixarray.length; l3++)
if ((pixarray[l3] & 0xff000000) == 0) {
ai1[l3] = -1;
pixarray[l3] = 0;
flag = true;
} else {
ai1[l3] = 0;
}
if (flag) {
wmf.stretchBlt(leftD, topD, ddiffx, ddiffy, leftS, topS, sdiffx, sdiffy, SRC_AND, ai1, imagewidth, imageheight);
wmf.stretchBlt(leftD, topD, ddiffx, ddiffy, leftS, topS, sdiffx, sdiffy, SRC_PAINT, pixarray, imagewidth, imageheight);
} else {
wmf.stretchBlt(leftD, topD, ddiffx, ddiffy, leftS, topS, sdiffx, sdiffy, SRC_COPY, pixarray, imagewidth, imageheight);
}
return true;
}
@Override
public boolean drawImage(
Image image, int left, int top, int width, int height, Color color, ImageObserver imageobserver)
{
restore();
return drawImage(
image, left, top, left + width, top + height, 0, 0, image.getWidth(imageobserver),
image.getHeight(imageobserver), color, imageobserver);
}
@Override
public boolean drawImage(Image image, int x, int y, int w, int h, ImageObserver imageobserver)
{
restore();
return drawImage(
image, x, y, x + w, y + h, 0, 0, image.getWidth(imageobserver),
image.getHeight(imageobserver), imageobserver);
}
@Override
public boolean drawImage(Image image, int x, int y, Color color, ImageObserver imageobserver)
{
restore();
return drawImage(
image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver), color,
imageobserver);
}
@Override
public boolean drawImage(Image image, int x, int y, ImageObserver imageobserver)
{
restore();
return drawImage(
image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver),
imageobserver);
}
@Override
public void drawLine(int x1, int y1, int x2, int y2)
{
restore();
wmf.moveTo(x1, y1);
wmf.lineTo(x2, y2);
wmf.setPixel(x2, y2, getColor());
}
@Override
public void drawOval(int x, int y, int width, int height)
{
restore();
wmf.ellipse(x, y, x + width + 1, y + height + 1);
}
@Override
public void drawPolygon(int[] ai, int[] ai1, int i)
{
restore();
wmf.polygon(ai, ai1, i);
}
@Override
public void drawPolyline(int[] xPoints, int[] yPoints, int i)
{
restore();
wmf.polyline(xPoints, yPoints, i);
wmf.setPixel(xPoints[i - 1], yPoints[i - 1], getColor());
}
@Override
public void drawRect(int x, int y, int width, int height)
{
restore();
wmf.rectangle(x, y, x + width + 1, y + height + 1);
}
@Override
public void drawRoundRect(int x, int y, int width, int height, int i1, int j1)
{
restore();
wmf.roundRect(x, y, x + width + 1, y + height + 1, i1, j1);
}
@Override
public void drawString(String s, int x, int y)
{
restore();
wmf.textOut(x, y, s);
}
@Override
public void drawString(AttributedCharacterIterator attributedcharacteriterator, int i, int j)
{
System.err.println("drawString(java.text.AttributedCharacterIterator,..) not supported");
}
@Override
public void fillArc(int x, int y, int width, int height, int startAngle, int endAngle)
{
restore();
setGDIFillBrush();
int cx = x + (width / 2);
int cy = y + (height / 2);
wmf.pie(
x, y, x + width + 1, y + height + 1,
cx
+ (int) Math.round(
(double) width * Math.sin((Math.PI * 2 * (double) (startAngle + 90)) / 360D)),
cy
+ (int) Math.round(
(double) height * Math.cos((Math.PI * 2 * (double) (startAngle + 90)) / 360D)),
cx
+ (int) Math.round(
(double) width * Math.sin((Math.PI * 2 * (double) (startAngle + endAngle + 90)) / 360D)),
cy
+ (int) Math.round(
(double) height * Math.cos((Math.PI * 2 * (double) (startAngle + endAngle + 90)) / 360D)));
setGDIHollowBrush();
}
@Override
public void fillOval(int x, int y, int rx, int ry)
{
restore();
setGDIFillBrush();
drawOval(x, y, rx - 1, ry - 1);
setGDIHollowBrush();
}
@Override
public void fillPolygon(int[] ai, int[] ai1, int i)
{
restore();
setGDIFillBrush();
drawPolygon(ai, ai1, i);
setGDIHollowBrush();
}
@Override
public void fillRect(int i, int j, int k, int l)
{
restore();
setGDIFillBrush();
drawRect(i, j, k - 1, l - 1);
setGDIHollowBrush();
}
@Override
public void fillRoundRect(int i, int j, int k, int l, int i1, int j1)
{
restore();
setGDIFillBrush();
drawRoundRect(i, j, k - 1, l - 1, i1, j1);
setGDIHollowBrush();
}
private void flipHorizontal(int[] ai, int i, int j)
{
for (int k = 0; k < j; k++) {
int l = k * j;
for (int i1 = 0; i1 < (i / 2); i1++) {
int j1 = ai[l + i1];
ai[l + i1] = ai[(l + i) - 1 - i1];
ai[(l + i) - 1 - i1] = j1;
}
}
}
private void flipVertical(int[] ai, int i, int j)
{
int[] ai1 = new int[i];
for (int k = 0; k < (j / 2); k++) {
System.arraycopy(ai, k * i, ai1, 0, i);
System.arraycopy(ai, (j - k - 1) * i, ai, k * i, i);
System.arraycopy(ai1, 0, ai, (j - k - 1) * i, i);
}
}
public int getBrushFillStyle()
{
return brushfillstyle;
}
public Shape getClip()
{
return getClipBounds();
}
public Rectangle getClipBounds()
{
if (clip != null) {
return new Rectangle(clip);
} else {
return null;
}
}
@Override
public Color getColor()
{
return foreground;
}
@Override
public Font getFont()
{
return font;
}
@Override
@SuppressWarnings("deprecation")
public FontMetrics getFontMetrics(Font font1)
{
return Toolkit.getDefaultToolkit().getFontMetrics(font1);
}
public int getPenStyle()
{
return penstyle;
}
private void reset()
{
setPenStyle(0);
setPenWidth(1);
setBrushFillStyle(0);
setBrushHatch(0);
setFontEscapement(0);
}
private void restore()
{
if (state.getCount() > 1) {
if (penhandle != state.getPen()) {
wmf.selectObject(penhandle);
state.setPen(penhandle);
}
if (brushhandle != state.getBrush()) {
wmf.selectObject(brushhandle);
state.setBrush(brushhandle);
}
if (fonthandle != state.getFont()) {
wmf.selectObject(fonthandle);
state.setFont(fonthandle);
}
if (clip != state.getClip()) {
setClip(clip);
state.setClip(clip);
}
if (!origin.equals(state.getOrigin())) {
translate(origin.x, origin.y);
state.setOrigin(origin);
}
}
}
public void setBrushFillStyle(int i)
{
brushfillstyle = i;
}
public void setBrushHatch(int i)
{
brushhatch = i;
}
public void setBrushPattern(Image image)
{
brushpattern = image;
}
@Override
public void setClip(int x, int y, int w, int h)
{
setClip(((new Rectangle(x, y, w, h))));
}
@Override
public void setClip(Shape shape)
{
wmf.setClipRgn();
clip = null;
if (shape != null) {
Rectangle rectangle = shape.getBounds();
clipRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
@Override
public void setColor(Color color)
{
restore();
foreground = color;
setGDIPen();
wmf.setTextColor(foreground);
}
@Override
public void setFont(Font font1)
{
restore();
font = font1;
setGDIFont();
}
public void setFontEscapement(int i)
{
fontescapement = i;
setGDIFont();
}
public int setGDIFillBrush()
{
int i = brushhandle;
if (brushfillstyle == 3) {
if (brushpattern != null) {
int j = brushpattern.getWidth(null);
int k = brushpattern.getHeight(null);
int[] ai = new int[j * k];
PixelGrabber pixelgrabber = new PixelGrabber(brushpattern, 0, 0, j, k, ai, 0, j);
try {
pixelgrabber.grabPixels();
if ((pixelgrabber.status() & 0x80) != 0) {
brushhandle = wmf.createBrushIndirect(0, foreground, brushhatch);
} else {
brushhandle = wmf.createPatternBrush(ai, j, k);
}
} catch (InterruptedException _ex) {
brushhandle = wmf.createBrushIndirect(0, foreground, brushhatch);
}
} else {
brushhandle = wmf.createBrushIndirect(0, foreground, brushhatch);
}
} else {
brushhandle = wmf.createBrushIndirect(brushfillstyle, foreground, brushhatch);
}
wmf.selectObject(brushhandle);
wmf.deleteObject(i);
state.setBrush(brushhandle);
return brushhandle;
}
public int setGDIFont()
{
int i = fonthandle;
fonthandle = wmf.createFont(font, fontescapement, false, false);
wmf.selectObject(fonthandle);
wmf.deleteObject(i);
state.setFont(fonthandle);
return fonthandle;
}
public int setGDIHollowBrush()
{
int i = brushhandle;
brushhandle = wmf.createBrushIndirect(1, foreground, brushhatch);
wmf.selectObject(brushhandle);
wmf.deleteObject(i);
state.setBrush(brushhandle);
return brushhandle;
}
public int setGDIPen()
{
int i = penhandle;
penhandle = wmf.createPenIndirect(penstyle, penwidth, foreground);
wmf.selectObject(penhandle);
wmf.deleteObject(i);
state.setPen(penhandle);
return penhandle;
}
@Override
public void setPaintMode()
{
System.err.println("setPaintMode not supported");
}
public void setPenStyle(int i)
{
penstyle = i;
setGDIPen();
}
public void setPenWidth(int i)
{
penwidth = i;
setGDIPen();
}
public void setWMF(MetaFile wmf1, int width, int height)
{
wmf = wmf1;
createHandles();
setup(width, height);
}
@Override
public void setXORMode(Color color)
{
System.err.println("setXORMode not supported");
}
public void setSize(int width, int height)
{
wmf.setWindowExt(width, height);
}
private void setup(int width, int height)
{
wmf.setMapMode(MM_ANISOTROPIC);
wmf.setWindowOrg(0, 0);
wmf.setWindowExt(width, height);
wmf.setViewportExt(width, height);
wmf.setTextAlign(24);
wmf.setBKMode(1);
wmf.setBKColor(background);
wmf.setTextColor(foreground);
wmf.setPolyFillMode(1);
wmf.setStretchBltMode(3);
wmf.setROP2(13);
wmf.setTextCharacterExtra(0);
}
@Override
public void translate(int i, int j)
{
origin.translate(i, j);
wmf.setWindowOrg(-origin.x, -origin.y);
state.setOrigin(origin);
}
public void setPolyFillMode(int alternate)
{
wmf.setPolyFillMode(alternate);
}
}